- add sources.
[platform/framework/web/crosswalk.git] / src / content / browser / resolve_proxy_msg_helper_unittest.cc
1 // Copyright (c) 2011 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.
4
5 #include "content/browser/resolve_proxy_msg_helper.h"
6
7 #include "content/browser/browser_thread_impl.h"
8 #include "content/common/view_messages.h"
9 #include "ipc/ipc_test_sink.h"
10 #include "net/base/net_errors.h"
11 #include "net/proxy/mock_proxy_resolver.h"
12 #include "net/proxy/proxy_config_service.h"
13 #include "net/proxy/proxy_service.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace content {
17
18 // This ProxyConfigService always returns "http://pac" as the PAC url to use.
19 class MockProxyConfigService : public net::ProxyConfigService {
20  public:
21   virtual void AddObserver(Observer* observer) OVERRIDE {}
22   virtual void RemoveObserver(Observer* observer) OVERRIDE {}
23   virtual ConfigAvailability GetLatestProxyConfig(
24       net::ProxyConfig* results) OVERRIDE {
25     *results = net::ProxyConfig::CreateFromCustomPacURL(GURL("http://pac"));
26     return CONFIG_VALID;
27   }
28 };
29
30 class TestResolveProxyMsgHelper : public ResolveProxyMsgHelper {
31  public:
32   TestResolveProxyMsgHelper(
33       net::ProxyService* proxy_service,
34       IPC::Listener* listener)
35       : ResolveProxyMsgHelper(proxy_service),
36         listener_(listener) {}
37   virtual bool Send(IPC::Message* message) OVERRIDE {
38     listener_->OnMessageReceived(*message);
39     delete message;
40     return true;
41   }
42
43  protected:
44   virtual ~TestResolveProxyMsgHelper() {}
45
46   IPC::Listener* listener_;
47 };
48
49 class ResolveProxyMsgHelperTest : public testing::Test, public IPC::Listener {
50  public:
51   struct PendingResult {
52     PendingResult(bool result,
53                   const std::string& proxy_list)
54         : result(result), proxy_list(proxy_list) {
55     }
56
57     bool result;
58     std::string proxy_list;
59   };
60
61   ResolveProxyMsgHelperTest()
62       : resolver_(new net::MockAsyncProxyResolver),
63         service_(
64             new net::ProxyService(new MockProxyConfigService, resolver_, NULL)),
65         helper_(new TestResolveProxyMsgHelper(service_.get(), this)),
66         message_loop_(base::MessageLoop::TYPE_IO),
67         io_thread_(BrowserThread::IO, &message_loop_) {
68     test_sink_.AddFilter(this);
69   }
70
71  protected:
72   const PendingResult* pending_result() const { return pending_result_.get(); }
73
74   void clear_pending_result() {
75     pending_result_.reset();
76   }
77
78   IPC::Message* GenerateReply() {
79     bool temp_bool;
80     std::string temp_string;
81     ViewHostMsg_ResolveProxy message(GURL(), &temp_bool, &temp_string);
82     return IPC::SyncMessage::GenerateReply(&message);
83   }
84
85   net::MockAsyncProxyResolver* resolver_;
86   scoped_ptr<net::ProxyService> service_;
87   scoped_refptr<ResolveProxyMsgHelper> helper_;
88   scoped_ptr<PendingResult> pending_result_;
89
90  private:
91   virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE {
92     TupleTypes<ViewHostMsg_ResolveProxy::ReplyParam>::ValueTuple reply_data;
93     EXPECT_TRUE(ViewHostMsg_ResolveProxy::ReadReplyParam(&msg, &reply_data));
94     DCHECK(!pending_result_.get());
95     pending_result_.reset(new PendingResult(reply_data.a, reply_data.b));
96     test_sink_.ClearMessages();
97     return true;
98   }
99
100   base::MessageLoop message_loop_;
101   BrowserThreadImpl io_thread_;
102   IPC::TestSink test_sink_;
103 };
104
105 // Issue three sequential requests -- each should succeed.
106 TEST_F(ResolveProxyMsgHelperTest, Sequential) {
107   GURL url1("http://www.google1.com/");
108   GURL url2("http://www.google2.com/");
109   GURL url3("http://www.google3.com/");
110
111   // Messages are deleted by the sink.
112   IPC::Message* msg1 = GenerateReply();
113   IPC::Message* msg2 = GenerateReply();
114   IPC::Message* msg3 = GenerateReply();
115
116   // Execute each request sequentially (so there are never 2 requests
117   // outstanding at the same time).
118
119   helper_->OnResolveProxy(url1, msg1);
120
121   // Finish ProxyService's initialization.
122   resolver_->pending_set_pac_script_request()->CompleteNow(net::OK);
123
124   ASSERT_EQ(1u, resolver_->pending_requests().size());
125   EXPECT_EQ(url1, resolver_->pending_requests()[0]->url());
126   resolver_->pending_requests()[0]->results()->UseNamedProxy("result1:80");
127   resolver_->pending_requests()[0]->CompleteNow(net::OK);
128
129   // Check result.
130   EXPECT_EQ(true, pending_result()->result);
131   EXPECT_EQ("PROXY result1:80", pending_result()->proxy_list);
132   clear_pending_result();
133
134   helper_->OnResolveProxy(url2, msg2);
135
136   ASSERT_EQ(1u, resolver_->pending_requests().size());
137   EXPECT_EQ(url2, resolver_->pending_requests()[0]->url());
138   resolver_->pending_requests()[0]->results()->UseNamedProxy("result2:80");
139   resolver_->pending_requests()[0]->CompleteNow(net::OK);
140
141   // Check result.
142   EXPECT_EQ(true, pending_result()->result);
143   EXPECT_EQ("PROXY result2:80", pending_result()->proxy_list);
144   clear_pending_result();
145
146   helper_->OnResolveProxy(url3, msg3);
147
148   ASSERT_EQ(1u, resolver_->pending_requests().size());
149   EXPECT_EQ(url3, resolver_->pending_requests()[0]->url());
150   resolver_->pending_requests()[0]->results()->UseNamedProxy("result3:80");
151   resolver_->pending_requests()[0]->CompleteNow(net::OK);
152
153   // Check result.
154   EXPECT_EQ(true, pending_result()->result);
155   EXPECT_EQ("PROXY result3:80", pending_result()->proxy_list);
156   clear_pending_result();
157 }
158
159 // Issue a request while one is already in progress -- should be queued.
160 TEST_F(ResolveProxyMsgHelperTest, QueueRequests) {
161   GURL url1("http://www.google1.com/");
162   GURL url2("http://www.google2.com/");
163   GURL url3("http://www.google3.com/");
164
165   IPC::Message* msg1 = GenerateReply();
166   IPC::Message* msg2 = GenerateReply();
167   IPC::Message* msg3 = GenerateReply();
168
169   // Start three requests. Since the proxy resolver is async, all the
170   // requests will be pending.
171
172   helper_->OnResolveProxy(url1, msg1);
173
174   // Finish ProxyService's initialization.
175   resolver_->pending_set_pac_script_request()->CompleteNow(net::OK);
176
177   helper_->OnResolveProxy(url2, msg2);
178   helper_->OnResolveProxy(url3, msg3);
179
180   // ResolveProxyHelper only keeps 1 request outstanding in ProxyService
181   // at a time.
182   ASSERT_EQ(1u, resolver_->pending_requests().size());
183   EXPECT_EQ(url1, resolver_->pending_requests()[0]->url());
184
185   resolver_->pending_requests()[0]->results()->UseNamedProxy("result1:80");
186   resolver_->pending_requests()[0]->CompleteNow(net::OK);
187
188   // Check result.
189   EXPECT_EQ(true, pending_result()->result);
190   EXPECT_EQ("PROXY result1:80", pending_result()->proxy_list);
191   clear_pending_result();
192
193   ASSERT_EQ(1u, resolver_->pending_requests().size());
194   EXPECT_EQ(url2, resolver_->pending_requests()[0]->url());
195
196   resolver_->pending_requests()[0]->results()->UseNamedProxy("result2:80");
197   resolver_->pending_requests()[0]->CompleteNow(net::OK);
198
199   // Check result.
200   EXPECT_EQ(true, pending_result()->result);
201   EXPECT_EQ("PROXY result2:80", pending_result()->proxy_list);
202   clear_pending_result();
203
204   ASSERT_EQ(1u, resolver_->pending_requests().size());
205   EXPECT_EQ(url3, resolver_->pending_requests()[0]->url());
206
207   resolver_->pending_requests()[0]->results()->UseNamedProxy("result3:80");
208   resolver_->pending_requests()[0]->CompleteNow(net::OK);
209
210   // Check result.
211   EXPECT_EQ(true, pending_result()->result);
212   EXPECT_EQ("PROXY result3:80", pending_result()->proxy_list);
213   clear_pending_result();
214 }
215
216 // Delete the helper while a request is in progress, and others are pending.
217 TEST_F(ResolveProxyMsgHelperTest, CancelPendingRequests) {
218   GURL url1("http://www.google1.com/");
219   GURL url2("http://www.google2.com/");
220   GURL url3("http://www.google3.com/");
221
222   // They will be deleted by the request's cancellation.
223   IPC::Message* msg1 = GenerateReply();
224   IPC::Message* msg2 = GenerateReply();
225   IPC::Message* msg3 = GenerateReply();
226
227   // Start three requests. Since the proxy resolver is async, all the
228   // requests will be pending.
229
230   helper_->OnResolveProxy(url1, msg1);
231
232   // Finish ProxyService's initialization.
233   resolver_->pending_set_pac_script_request()->CompleteNow(net::OK);
234
235   helper_->OnResolveProxy(url2, msg2);
236   helper_->OnResolveProxy(url3, msg3);
237
238   // ResolveProxyHelper only keeps 1 request outstanding in ProxyService
239   // at a time.
240   ASSERT_EQ(1u, resolver_->pending_requests().size());
241   EXPECT_EQ(url1, resolver_->pending_requests()[0]->url());
242
243   // Delete the underlying ResolveProxyMsgHelper -- this should cancel all
244   // the requests which are outstanding.
245   helper_ = NULL;
246
247   // The pending requests sent to the proxy resolver should have been cancelled.
248
249   EXPECT_EQ(0u, resolver_->pending_requests().size());
250
251   EXPECT_TRUE(pending_result() == NULL);
252
253   // It should also be the case that msg1, msg2, msg3 were deleted by the
254   // cancellation. (Else will show up as a leak in Valgrind).
255 }
256
257 }  // namespace content