Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / net / proxy / proxy_list_unittest.cc
blobe98d9c519771f3b9f4b341bfb255d1932e498ca9
1 // Copyright (c) 2006-2008 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/proxy_list.h"
7 #include <vector>
9 #include "net/base/net_errors.h"
10 #include "net/log/net_log.h"
11 #include "net/proxy/proxy_retry_info.h"
12 #include "net/proxy/proxy_server.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 namespace net {
17 namespace {
19 // Test parsing from a PAC string.
20 TEST(ProxyListTest, SetFromPacString) {
21 const struct {
22 const char* pac_input;
23 const char* pac_output;
24 } tests[] = {
25 // Valid inputs:
26 { "PROXY foopy:10",
27 "PROXY foopy:10",
29 { " DIRECT", // leading space.
30 "DIRECT",
32 { "PROXY foopy1 ; proxy foopy2;\t DIRECT",
33 "PROXY foopy1:80;PROXY foopy2:80;DIRECT",
35 { "proxy foopy1 ; SOCKS foopy2",
36 "PROXY foopy1:80;SOCKS foopy2:1080",
38 // Try putting DIRECT first.
39 { "DIRECT ; proxy foopy1 ; DIRECT ; SOCKS5 foopy2;DIRECT ",
40 "DIRECT;PROXY foopy1:80;DIRECT;SOCKS5 foopy2:1080;DIRECT",
42 // Try putting DIRECT consecutively.
43 { "DIRECT ; proxy foopy1:80; DIRECT ; DIRECT",
44 "DIRECT;PROXY foopy1:80;DIRECT;DIRECT",
47 // Invalid inputs (parts which aren't understood get
48 // silently discarded):
50 // If the proxy list string parsed to empty, automatically fall-back to
51 // DIRECT.
52 { "PROXY-foopy:10",
53 "DIRECT",
55 { "PROXY",
56 "DIRECT",
58 { "PROXY foopy1 ; JUNK ; JUNK ; SOCKS5 foopy2 ; ;",
59 "PROXY foopy1:80;SOCKS5 foopy2:1080",
63 for (size_t i = 0; i < arraysize(tests); ++i) {
64 ProxyList list;
65 list.SetFromPacString(tests[i].pac_input);
66 EXPECT_EQ(tests[i].pac_output, list.ToPacString());
67 EXPECT_FALSE(list.IsEmpty());
71 TEST(ProxyListTest, RemoveProxiesWithoutScheme) {
72 const struct {
73 const char* pac_input;
74 int filter;
75 const char* filtered_pac_output;
76 } tests[] = {
77 { "PROXY foopy:10 ; SOCKS5 foopy2 ; SOCKS foopy11 ; PROXY foopy3 ; DIRECT",
78 // Remove anything that isn't HTTP or DIRECT.
79 ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_HTTP,
80 "PROXY foopy:10;PROXY foopy3:80;DIRECT",
82 { "PROXY foopy:10 ; SOCKS5 foopy2",
83 // Remove anything that isn't HTTP or SOCKS5.
84 ProxyServer::SCHEME_DIRECT | ProxyServer::SCHEME_SOCKS4,
85 "",
89 for (size_t i = 0; i < arraysize(tests); ++i) {
90 ProxyList list;
91 list.SetFromPacString(tests[i].pac_input);
92 list.RemoveProxiesWithoutScheme(tests[i].filter);
93 EXPECT_EQ(tests[i].filtered_pac_output, list.ToPacString());
97 TEST(ProxyListTest, DeprioritizeBadProxies) {
98 // Retry info that marks a proxy as being bad for a *very* long time (to avoid
99 // the test depending on the current time.)
100 ProxyRetryInfo proxy_retry_info;
101 proxy_retry_info.bad_until =
102 base::TimeTicks::Now() + base::TimeDelta::FromDays(1);
104 // Call DeprioritizeBadProxies with an empty map -- should have no effect.
106 ProxyList list;
107 list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
109 ProxyRetryInfoMap retry_info_map;
110 list.DeprioritizeBadProxies(retry_info_map);
111 EXPECT_EQ("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80",
112 list.ToPacString());
115 // Call DeprioritizeBadProxies with 2 of the three proxies marked as bad.
116 // These proxies should be retried last.
118 ProxyList list;
119 list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
121 ProxyRetryInfoMap retry_info_map;
122 retry_info_map["foopy1:80"] = proxy_retry_info;
123 retry_info_map["foopy3:80"] = proxy_retry_info;
124 retry_info_map["socks5://localhost:1080"] = proxy_retry_info;
126 list.DeprioritizeBadProxies(retry_info_map);
128 EXPECT_EQ("PROXY foopy2:80;PROXY foopy1:80;PROXY foopy3:80",
129 list.ToPacString());
132 // Call DeprioritizeBadProxies where ALL of the proxies are marked as bad.
133 // This should have no effect on the order.
135 ProxyList list;
136 list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
138 ProxyRetryInfoMap retry_info_map;
139 retry_info_map["foopy1:80"] = proxy_retry_info;
140 retry_info_map["foopy2:80"] = proxy_retry_info;
141 retry_info_map["foopy3:80"] = proxy_retry_info;
143 list.DeprioritizeBadProxies(retry_info_map);
145 EXPECT_EQ("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80",
146 list.ToPacString());
149 // Call DeprioritizeBadProxies with 2 of the three proxies marked as bad. Of
150 // the 2 bad proxies, one is to be reconsidered and should be retried last.
151 // The other is not to be reconsidered and should be removed from the list.
153 ProxyList list;
154 list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
156 ProxyRetryInfoMap retry_info_map;
157 // |proxy_retry_info.reconsider defaults to true.
158 retry_info_map["foopy1:80"] = proxy_retry_info;
159 proxy_retry_info.try_while_bad = false;
160 retry_info_map["foopy3:80"] = proxy_retry_info;
161 proxy_retry_info.try_while_bad = true;
162 retry_info_map["socks5://localhost:1080"] = proxy_retry_info;
164 list.DeprioritizeBadProxies(retry_info_map);
166 EXPECT_EQ("PROXY foopy2:80;PROXY foopy1:80",
167 list.ToPacString());
171 TEST(ProxyListTest, UpdateRetryInfoOnFallback) {
172 ProxyRetryInfo proxy_retry_info;
173 // Retrying should put the first proxy on the retry list.
175 ProxyList list;
176 ProxyRetryInfoMap retry_info_map;
177 BoundNetLog net_log;
178 ProxyServer proxy_server(
179 ProxyServer::FromURI("foopy1:80", ProxyServer::SCHEME_HTTP));
180 std::vector<ProxyServer> bad_proxies;
181 bad_proxies.push_back(proxy_server);
182 list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
183 list.UpdateRetryInfoOnFallback(
184 &retry_info_map, base::TimeDelta::FromSeconds(60), true, bad_proxies,
185 ERR_PROXY_CONNECTION_FAILED, net_log);
186 EXPECT_TRUE(retry_info_map.end() != retry_info_map.find("foopy1:80"));
187 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED,
188 retry_info_map[proxy_server.ToURI()].net_error);
189 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy2:80"));
190 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy3:80"));
192 // Retrying should put the first proxy on the retry list, even if there
193 // was no network error.
195 ProxyList list;
196 ProxyRetryInfoMap retry_info_map;
197 BoundNetLog net_log;
198 ProxyServer proxy_server(
199 ProxyServer::FromURI("foopy1:80", ProxyServer::SCHEME_HTTP));
200 std::vector<ProxyServer> bad_proxies;
201 bad_proxies.push_back(proxy_server);
202 list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
203 list.UpdateRetryInfoOnFallback(&retry_info_map,
204 base::TimeDelta::FromSeconds(60), true,
205 bad_proxies, OK, net_log);
206 EXPECT_TRUE(retry_info_map.end() != retry_info_map.find("foopy1:80"));
207 EXPECT_EQ(OK, retry_info_map[proxy_server.ToURI()].net_error);
208 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy2:80"));
209 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy3:80"));
211 // Including another bad proxy should put both the first and the specified
212 // proxy on the retry list.
214 ProxyList list;
215 ProxyRetryInfoMap retry_info_map;
216 BoundNetLog net_log;
217 ProxyServer proxy_server = ProxyServer::FromURI("foopy3:80",
218 ProxyServer::SCHEME_HTTP);
219 std::vector<ProxyServer> bad_proxies;
220 bad_proxies.push_back(proxy_server);
221 list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
222 list.UpdateRetryInfoOnFallback(
223 &retry_info_map, base::TimeDelta::FromSeconds(60), true, bad_proxies,
224 ERR_NAME_RESOLUTION_FAILED, net_log);
225 EXPECT_TRUE(retry_info_map.end() != retry_info_map.find("foopy1:80"));
226 EXPECT_EQ(ERR_NAME_RESOLUTION_FAILED,
227 retry_info_map[proxy_server.ToURI()].net_error);
228 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy2:80"));
229 EXPECT_TRUE(retry_info_map.end() != retry_info_map.find("foopy3:80"));
231 // If the first proxy is DIRECT, nothing is added to the retry list, even
232 // if another bad proxy is specified.
234 ProxyList list;
235 ProxyRetryInfoMap retry_info_map;
236 BoundNetLog net_log;
237 ProxyServer proxy_server = ProxyServer::FromURI("foopy2:80",
238 ProxyServer::SCHEME_HTTP);
239 std::vector<ProxyServer> bad_proxies;
240 bad_proxies.push_back(proxy_server);
241 list.SetFromPacString("DIRECT;PROXY foopy2:80;PROXY foopy3:80");
242 list.UpdateRetryInfoOnFallback(&retry_info_map,
243 base::TimeDelta::FromSeconds(60), true,
244 bad_proxies, OK, net_log);
245 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy2:80"));
246 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy3:80"));
248 // If the bad proxy is already on the retry list, and the old retry info would
249 // cause the proxy to be retried later than the newly specified retry info,
250 // then the old retry info should be kept.
252 ProxyList list;
253 ProxyRetryInfoMap retry_info_map;
254 BoundNetLog net_log;
255 list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
257 // First, mark the proxy as bad for 60 seconds.
258 list.UpdateRetryInfoOnFallback(
259 &retry_info_map, base::TimeDelta::FromSeconds(60), true,
260 std::vector<ProxyServer>(), ERR_PROXY_CONNECTION_FAILED, net_log);
261 // Next, mark the same proxy as bad for 1 second. This call should have no
262 // effect, since this would cause the bad proxy to be retried sooner than
263 // the existing retry info.
264 list.UpdateRetryInfoOnFallback(&retry_info_map,
265 base::TimeDelta::FromSeconds(1), false,
266 std::vector<ProxyServer>(), OK, net_log);
267 EXPECT_TRUE(retry_info_map.end() != retry_info_map.find("foopy1:80"));
268 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED,
269 retry_info_map["foopy1:80"].net_error);
270 EXPECT_TRUE(retry_info_map["foopy1:80"].try_while_bad);
271 EXPECT_EQ(base::TimeDelta::FromSeconds(60),
272 retry_info_map["foopy1:80"].current_delay);
273 EXPECT_GT(retry_info_map["foopy1:80"].bad_until,
274 base::TimeTicks::Now() + base::TimeDelta::FromSeconds(30));
275 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy2:80"));
276 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy3:80"));
278 // If the bad proxy is already on the retry list, and the newly specified
279 // retry info would cause the proxy to be retried later than the old retry
280 // info, then the old retry info should be replaced with the new retry info.
282 ProxyList list;
283 ProxyRetryInfoMap retry_info_map;
284 BoundNetLog net_log;
285 list.SetFromPacString("PROXY foopy1:80;PROXY foopy2:80;PROXY foopy3:80");
287 // First, mark the proxy as bad for 1 second.
288 list.UpdateRetryInfoOnFallback(&retry_info_map,
289 base::TimeDelta::FromSeconds(1), false,
290 std::vector<ProxyServer>(), OK, net_log);
291 // Next, mark the same proxy as bad for 60 seconds. This call should replace
292 // the existing retry info with the new 60 second retry info.
293 list.UpdateRetryInfoOnFallback(
294 &retry_info_map, base::TimeDelta::FromSeconds(60), true,
295 std::vector<ProxyServer>(), ERR_PROXY_CONNECTION_FAILED, net_log);
297 EXPECT_TRUE(retry_info_map.end() != retry_info_map.find("foopy1:80"));
298 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED,
299 retry_info_map["foopy1:80"].net_error);
300 EXPECT_TRUE(retry_info_map["foopy1:80"].try_while_bad);
301 EXPECT_EQ(base::TimeDelta::FromSeconds(60),
302 retry_info_map["foopy1:80"].current_delay);
303 EXPECT_GT(retry_info_map["foopy1:80"].bad_until,
304 base::TimeTicks::Now() + base::TimeDelta::FromSeconds(30));
305 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy2:80"));
306 EXPECT_TRUE(retry_info_map.end() == retry_info_map.find("foopy3:80"));
310 } // namesapce
312 } // namespace net