1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/proxy/mojo_proxy_resolver_factory_impl.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "net/base/test_completion_callback.h"
9 #include "net/proxy/mock_proxy_resolver.h"
10 #include "net/proxy/proxy_resolver_v8_tracing.h"
11 #include "net/test/event_waiter.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
18 const char kScriptData
[] = "FooBarBaz";
20 class FakeProxyResolver
: public ProxyResolverV8Tracing
{
22 explicit FakeProxyResolver(const base::Closure
& on_destruction
)
23 : on_destruction_(on_destruction
) {}
25 ~FakeProxyResolver() override
{ on_destruction_
.Run(); }
28 // ProxyResolverV8Tracing overrides.
29 void GetProxyForURL(const GURL
& url
,
31 const CompletionCallback
& callback
,
32 ProxyResolver::RequestHandle
* request
,
33 scoped_ptr
<Bindings
> bindings
) override
{}
35 void CancelRequest(ProxyResolver::RequestHandle request
) override
{}
37 LoadState
GetLoadState(ProxyResolver::RequestHandle request
) const override
{
38 return LOAD_STATE_RESOLVING_PROXY_FOR_URL
;
41 const base::Closure on_destruction_
;
51 class TestProxyResolverFactory
: public ProxyResolverV8TracingFactory
{
53 struct PendingRequest
{
54 scoped_ptr
<ProxyResolverV8Tracing
>* resolver
;
55 CompletionCallback callback
;
58 explicit TestProxyResolverFactory(EventWaiter
<Event
>* waiter
)
61 void CreateProxyResolverV8Tracing(
62 const scoped_refptr
<ProxyResolverScriptData
>& pac_script
,
63 scoped_ptr
<ProxyResolverV8Tracing::Bindings
> bindings
,
64 scoped_ptr
<ProxyResolverV8Tracing
>* resolver
,
65 const CompletionCallback
& callback
,
66 scoped_ptr
<ProxyResolverFactory::Request
>* request
) override
{
68 waiter_
->NotifyEvent(RESOLVER_CREATED
);
69 EXPECT_EQ(base::ASCIIToUTF16(kScriptData
), pac_script
->utf16());
70 EXPECT_TRUE(resolver
);
71 pending_request_
.reset(new PendingRequest
);
72 pending_request_
->resolver
= resolver
;
73 pending_request_
->callback
= callback
;
75 ASSERT_TRUE(bindings
);
77 bindings
->Alert(base::ASCIIToUTF16("alert"));
78 bindings
->OnError(10, base::ASCIIToUTF16("error"));
79 EXPECT_TRUE(bindings
->GetHostResolver());
82 size_t requests_handled() { return requests_handled_
; }
83 const PendingRequest
* pending_request() { return pending_request_
.get(); }
86 EventWaiter
<Event
>* waiter_
;
87 size_t requests_handled_
= 0;
88 scoped_ptr
<PendingRequest
> pending_request_
;
93 class MojoProxyResolverFactoryImplTest
94 : public testing::Test
,
95 public interfaces::ProxyResolverFactoryRequestClient
{
97 void SetUp() override
{
98 mock_factory_
= new TestProxyResolverFactory(&waiter_
);
99 new MojoProxyResolverFactoryImpl(make_scoped_ptr(mock_factory_
),
100 mojo::GetProxy(&factory_
));
103 void OnConnectionError() { waiter_
.NotifyEvent(CONNECTION_ERROR
); }
105 void OnFakeProxyInstanceDestroyed() {
106 instances_destroyed_
++;
107 waiter_
.NotifyEvent(RESOLVER_DESTROYED
);
110 void ReportResult(int32_t error
) override
{ create_callback_
.Run(error
); }
112 void Alert(const mojo::String
& message
) override
{}
114 void OnError(int32_t line_number
, const mojo::String
& message
) override
{}
116 void ResolveDns(interfaces::HostResolverRequestInfoPtr request_info
,
117 interfaces::HostResolverRequestClientPtr client
) override
{}
120 scoped_ptr
<TestProxyResolverFactory
> mock_factory_owner_
;
121 TestProxyResolverFactory
* mock_factory_
;
122 interfaces::ProxyResolverFactoryPtr factory_
;
124 int instances_destroyed_
= 0;
125 CompletionCallback create_callback_
;
127 EventWaiter
<Event
> waiter_
;
130 TEST_F(MojoProxyResolverFactoryImplTest
, DisconnectProxyResolverClient
) {
131 interfaces::ProxyResolverPtr proxy_resolver
;
132 interfaces::ProxyResolverFactoryRequestClientPtr client_ptr
;
133 mojo::Binding
<ProxyResolverFactoryRequestClient
> client_binding(
134 this, mojo::GetProxy(&client_ptr
));
135 factory_
->CreateResolver(mojo::String::From(kScriptData
),
136 mojo::GetProxy(&proxy_resolver
), client_ptr
.Pass());
137 proxy_resolver
.set_connection_error_handler(
138 base::Bind(&MojoProxyResolverFactoryImplTest::OnConnectionError
,
139 base::Unretained(this)));
140 waiter_
.WaitForEvent(RESOLVER_CREATED
);
141 EXPECT_EQ(0, instances_destroyed_
);
142 ASSERT_EQ(1u, mock_factory_
->requests_handled());
143 TestCompletionCallback create_callback
;
144 create_callback_
= create_callback
.callback();
145 ASSERT_TRUE(mock_factory_
->pending_request());
146 mock_factory_
->pending_request()->resolver
->reset(
147 new FakeProxyResolver(base::Bind(
148 &MojoProxyResolverFactoryImplTest::OnFakeProxyInstanceDestroyed
,
149 base::Unretained(this))));
150 mock_factory_
->pending_request()->callback
.Run(OK
);
151 EXPECT_EQ(OK
, create_callback
.WaitForResult());
152 proxy_resolver
.reset();
153 waiter_
.WaitForEvent(RESOLVER_DESTROYED
);
154 EXPECT_EQ(1, instances_destroyed_
);
157 TEST_F(MojoProxyResolverFactoryImplTest
, Error
) {
158 interfaces::ProxyResolverPtr proxy_resolver
;
159 interfaces::ProxyResolverFactoryRequestClientPtr client_ptr
;
160 mojo::Binding
<ProxyResolverFactoryRequestClient
> client_binding(
161 this, mojo::GetProxy(&client_ptr
));
162 factory_
->CreateResolver(mojo::String::From(kScriptData
),
163 mojo::GetProxy(&proxy_resolver
), client_ptr
.Pass());
164 proxy_resolver
.set_connection_error_handler(
165 base::Bind(&MojoProxyResolverFactoryImplTest::OnConnectionError
,
166 base::Unretained(this)));
167 waiter_
.WaitForEvent(RESOLVER_CREATED
);
168 EXPECT_EQ(0, instances_destroyed_
);
169 ASSERT_EQ(1u, mock_factory_
->requests_handled());
170 TestCompletionCallback create_callback
;
171 create_callback_
= create_callback
.callback();
172 ASSERT_TRUE(mock_factory_
->pending_request());
173 mock_factory_
->pending_request()->callback
.Run(ERR_PAC_SCRIPT_FAILED
);
174 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED
, create_callback
.WaitForResult());
177 TEST_F(MojoProxyResolverFactoryImplTest
,
178 DisconnectClientDuringResolverCreation
) {
179 interfaces::ProxyResolverPtr proxy_resolver
;
180 interfaces::ProxyResolverFactoryRequestClientPtr client_ptr
;
181 mojo::Binding
<ProxyResolverFactoryRequestClient
> client_binding(
182 this, mojo::GetProxy(&client_ptr
));
183 factory_
->CreateResolver(mojo::String::From(kScriptData
),
184 mojo::GetProxy(&proxy_resolver
), client_ptr
.Pass());
185 proxy_resolver
.set_connection_error_handler(
186 base::Bind(&MojoProxyResolverFactoryImplTest::OnConnectionError
,
187 base::Unretained(this)));
188 waiter_
.WaitForEvent(RESOLVER_CREATED
);
189 EXPECT_EQ(0, instances_destroyed_
);
190 ASSERT_EQ(1u, mock_factory_
->requests_handled());
191 client_binding
.Close();
192 waiter_
.WaitForEvent(CONNECTION_ERROR
);
195 TEST_F(MojoProxyResolverFactoryImplTest
,
196 DisconnectFactoryDuringResolverCreation
) {
197 interfaces::ProxyResolverPtr proxy_resolver
;
198 interfaces::ProxyResolverFactoryRequestClientPtr client_ptr
;
199 mojo::Binding
<ProxyResolverFactoryRequestClient
> client_binding(
200 this, mojo::GetProxy(&client_ptr
));
201 factory_
->CreateResolver(mojo::String::From(kScriptData
),
202 mojo::GetProxy(&proxy_resolver
), client_ptr
.Pass());
203 proxy_resolver
.set_connection_error_handler(
204 base::Bind(&MojoProxyResolverFactoryImplTest::OnConnectionError
,
205 base::Unretained(this)));
206 client_binding
.set_connection_error_handler(
207 base::Bind(&MojoProxyResolverFactoryImplTest::OnConnectionError
,
208 base::Unretained(this)));
209 waiter_
.WaitForEvent(RESOLVER_CREATED
);
210 EXPECT_EQ(0, instances_destroyed_
);
211 ASSERT_EQ(1u, mock_factory_
->requests_handled());
213 waiter_
.WaitForEvent(CONNECTION_ERROR
);