xref: /aosp_15_r20/external/cronet/net/base/proxy_chain_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2023 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/base/proxy_chain.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <optional>
8*6777b538SAndroid Build Coastguard Worker #include <sstream>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/test/gtest_util.h"
12*6777b538SAndroid Build Coastguard Worker #include "net/base/proxy_server.h"
13*6777b538SAndroid Build Coastguard Worker #include "net/base/proxy_string_util.h"
14*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker namespace net {
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker namespace {
19*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,DefaultConstructor)20*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, DefaultConstructor) {
21*6777b538SAndroid Build Coastguard Worker   ProxyChain proxy_chain;
22*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(proxy_chain.IsValid());
23*6777b538SAndroid Build Coastguard Worker }
24*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,ConstructorsAndAssignmentOperators)25*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, ConstructorsAndAssignmentOperators) {
26*6777b538SAndroid Build Coastguard Worker   std::vector proxy_servers = {
27*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:555", ProxyServer::SCHEME_HTTPS),
28*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:666", ProxyServer::SCHEME_HTTPS)};
29*6777b538SAndroid Build Coastguard Worker 
30*6777b538SAndroid Build Coastguard Worker   ProxyChain proxy_chain = ProxyChain(proxy_servers);
31*6777b538SAndroid Build Coastguard Worker 
32*6777b538SAndroid Build Coastguard Worker   ProxyChain copy_constructed(proxy_chain);
33*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(proxy_chain, copy_constructed);
34*6777b538SAndroid Build Coastguard Worker 
35*6777b538SAndroid Build Coastguard Worker   ProxyChain copy_assigned = proxy_chain;
36*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(proxy_chain, copy_assigned);
37*6777b538SAndroid Build Coastguard Worker 
38*6777b538SAndroid Build Coastguard Worker   ProxyChain move_constructed{std::move(copy_constructed)};
39*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(proxy_chain, move_constructed);
40*6777b538SAndroid Build Coastguard Worker 
41*6777b538SAndroid Build Coastguard Worker   ProxyChain move_assigned = std::move(copy_assigned);
42*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(proxy_chain, move_assigned);
43*6777b538SAndroid Build Coastguard Worker }
44*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,DirectProxy)45*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, DirectProxy) {
46*6777b538SAndroid Build Coastguard Worker   ProxyChain proxy_chain1 = ProxyChain::Direct();
47*6777b538SAndroid Build Coastguard Worker   ProxyChain proxy_chain2 = ProxyChain(std::vector<ProxyServer>());
48*6777b538SAndroid Build Coastguard Worker   std::vector<ProxyServer> proxy_servers = {};
49*6777b538SAndroid Build Coastguard Worker 
50*6777b538SAndroid Build Coastguard Worker   // Equal and valid proxy chains.
51*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(proxy_chain1, proxy_chain2);
52*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(proxy_chain1.IsValid());
53*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(proxy_chain2.IsValid());
54*6777b538SAndroid Build Coastguard Worker 
55*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(proxy_chain1.is_direct());
56*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(proxy_chain1.is_single_proxy());
57*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(proxy_chain1.is_multi_proxy());
58*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(proxy_chain1.length(), 0u);
59*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(proxy_chain1.proxy_servers(), proxy_servers);
60*6777b538SAndroid Build Coastguard Worker }
61*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,Ostream)62*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, Ostream) {
63*6777b538SAndroid Build Coastguard Worker   ProxyChain proxy_chain =
64*6777b538SAndroid Build Coastguard Worker       ProxyChain::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTP, "foo", 80);
65*6777b538SAndroid Build Coastguard Worker   std::ostringstream out;
66*6777b538SAndroid Build Coastguard Worker   out << proxy_chain;
67*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(out.str(), "[foo:80]");
68*6777b538SAndroid Build Coastguard Worker }
69*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,ToDebugString)70*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, ToDebugString) {
71*6777b538SAndroid Build Coastguard Worker   ProxyChain proxy_chain1 =
72*6777b538SAndroid Build Coastguard Worker       ProxyChain(ProxyUriToProxyServer("foo:333", ProxyServer::SCHEME_SOCKS5));
73*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(proxy_chain1.ToDebugString(), "[socks5://foo:333]");
74*6777b538SAndroid Build Coastguard Worker 
75*6777b538SAndroid Build Coastguard Worker   ProxyChain proxy_chain2 =
76*6777b538SAndroid Build Coastguard Worker       ProxyChain({ProxyUriToProxyServer("foo:444", ProxyServer::SCHEME_HTTPS),
77*6777b538SAndroid Build Coastguard Worker                   ProxyUriToProxyServer("foo:555", ProxyServer::SCHEME_HTTPS)});
78*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(proxy_chain2.ToDebugString(), "[https://foo:444, https://foo:555]");
79*6777b538SAndroid Build Coastguard Worker 
80*6777b538SAndroid Build Coastguard Worker   ProxyChain direct_proxy_chain = ProxyChain::Direct();
81*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(direct_proxy_chain.ToDebugString(), "[direct://]");
82*6777b538SAndroid Build Coastguard Worker 
83*6777b538SAndroid Build Coastguard Worker   ProxyChain ip_protection_proxy_chain = ProxyChain::ForIpProtection(
84*6777b538SAndroid Build Coastguard Worker       {ProxyUriToProxyServer("foo:444", ProxyServer::SCHEME_HTTPS),
85*6777b538SAndroid Build Coastguard Worker        ProxyUriToProxyServer("foo:555", ProxyServer::SCHEME_HTTPS)});
86*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ip_protection_proxy_chain.ToDebugString(),
87*6777b538SAndroid Build Coastguard Worker             "[https://foo:444, https://foo:555] (IP Protection)");
88*6777b538SAndroid Build Coastguard Worker 
89*6777b538SAndroid Build Coastguard Worker   ProxyChain invalid_proxy_chain = ProxyChain();
90*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(invalid_proxy_chain.ToDebugString(), "INVALID PROXY CHAIN");
91*6777b538SAndroid Build Coastguard Worker }
92*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,FromSchemeHostAndPort)93*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, FromSchemeHostAndPort) {
94*6777b538SAndroid Build Coastguard Worker   const struct {
95*6777b538SAndroid Build Coastguard Worker     const ProxyServer::Scheme input_scheme;
96*6777b538SAndroid Build Coastguard Worker     const char* const input_host;
97*6777b538SAndroid Build Coastguard Worker     const std::optional<uint16_t> input_port;
98*6777b538SAndroid Build Coastguard Worker     const char* const input_port_str;
99*6777b538SAndroid Build Coastguard Worker     const char* const expected_host;
100*6777b538SAndroid Build Coastguard Worker     const uint16_t expected_port;
101*6777b538SAndroid Build Coastguard Worker   } tests[] = {
102*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_HTTP, "foopy", 80, "80", "foopy", 80},
103*6777b538SAndroid Build Coastguard Worker 
104*6777b538SAndroid Build Coastguard Worker       // Non-standard port
105*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_HTTP, "foopy", 10, "10", "foopy", 10},
106*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_HTTP, "foopy", 0, "0", "foopy", 0},
107*6777b538SAndroid Build Coastguard Worker 
108*6777b538SAndroid Build Coastguard Worker       // Hostname canonicalization
109*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_HTTP, "FoOpY", 80, "80", "foopy", 80},
110*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_HTTP, "f\u00fcpy", 80, "80", "xn--fpy-hoa", 80},
111*6777b538SAndroid Build Coastguard Worker 
112*6777b538SAndroid Build Coastguard Worker       // IPv4 literal
113*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_HTTP, "1.2.3.4", 80, "80", "1.2.3.4", 80},
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker       // IPv4 literal canonicalization
116*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_HTTP, "127.1", 80, "80", "127.0.0.1", 80},
117*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_HTTP, "0x7F.0x1", 80, "80", "127.0.0.1", 80},
118*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_HTTP, "0177.01", 80, "80", "127.0.0.1", 80},
119*6777b538SAndroid Build Coastguard Worker 
120*6777b538SAndroid Build Coastguard Worker       // IPv6 literal
121*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_HTTP, "[3ffe:2a00:100:7031::1]", 80, "80",
122*6777b538SAndroid Build Coastguard Worker        "[3ffe:2a00:100:7031::1]", 80},
123*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_HTTP, "3ffe:2a00:100:7031::1", 80, "80",
124*6777b538SAndroid Build Coastguard Worker        "[3ffe:2a00:100:7031::1]", 80},
125*6777b538SAndroid Build Coastguard Worker 
126*6777b538SAndroid Build Coastguard Worker       // IPv6 literal canonicalization
127*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_HTTP, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", 80,
128*6777b538SAndroid Build Coastguard Worker        "80", "[fedc:ba98:7654:3210:fedc:ba98:7654:3210]", 80},
129*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_HTTP, "::192.9.5.5", 80, "80", "[::c009:505]", 80},
130*6777b538SAndroid Build Coastguard Worker 
131*6777b538SAndroid Build Coastguard Worker       // Other schemes
132*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_HTTPS, "foopy", 111, "111", "foopy", 111},
133*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_SOCKS4, "foopy", 111, "111", "foopy", 111},
134*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_SOCKS5, "foopy", 111, "111", "foopy", 111},
135*6777b538SAndroid Build Coastguard Worker 
136*6777b538SAndroid Build Coastguard Worker       // Default ports
137*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_HTTP, "foopy", std::nullopt, "", "foopy", 80},
138*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_HTTPS, "foopy", std::nullopt, "", "foopy", 443},
139*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_SOCKS4, "foopy", std::nullopt, "", "foopy", 1080},
140*6777b538SAndroid Build Coastguard Worker       {ProxyServer::SCHEME_SOCKS5, "foopy", std::nullopt, "", "foopy", 1080},
141*6777b538SAndroid Build Coastguard Worker   };
142*6777b538SAndroid Build Coastguard Worker 
143*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(tests); ++i) {
144*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE(base::NumberToString(i) + ": " + tests[i].input_host + ":" +
145*6777b538SAndroid Build Coastguard Worker                  base::NumberToString(tests[i].input_port.value_or(-1)));
146*6777b538SAndroid Build Coastguard Worker     auto chain = ProxyChain::FromSchemeHostAndPort(
147*6777b538SAndroid Build Coastguard Worker         tests[i].input_scheme, tests[i].input_host, tests[i].input_port);
148*6777b538SAndroid Build Coastguard Worker     auto proxy = chain.First();
149*6777b538SAndroid Build Coastguard Worker 
150*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(proxy.is_valid());
151*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(proxy.scheme(), tests[i].input_scheme);
152*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(proxy.GetHost(), tests[i].expected_host);
153*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(proxy.GetPort(), tests[i].expected_port);
154*6777b538SAndroid Build Coastguard Worker 
155*6777b538SAndroid Build Coastguard Worker     auto chain_from_string_port = ProxyChain::FromSchemeHostAndPort(
156*6777b538SAndroid Build Coastguard Worker         tests[i].input_scheme, tests[i].input_host, tests[i].input_port_str);
157*6777b538SAndroid Build Coastguard Worker     auto proxy_from_string_port = chain_from_string_port.First();
158*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(proxy_from_string_port.is_valid());
159*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(proxy, proxy_from_string_port);
160*6777b538SAndroid Build Coastguard Worker   }
161*6777b538SAndroid Build Coastguard Worker }
162*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,InvalidHostname)163*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, InvalidHostname) {
164*6777b538SAndroid Build Coastguard Worker   const char* const tests[]{
165*6777b538SAndroid Build Coastguard Worker       "",
166*6777b538SAndroid Build Coastguard Worker       "[]",
167*6777b538SAndroid Build Coastguard Worker       "[foo]",
168*6777b538SAndroid Build Coastguard Worker       "foo:",
169*6777b538SAndroid Build Coastguard Worker       "foo:80",
170*6777b538SAndroid Build Coastguard Worker       ":",
171*6777b538SAndroid Build Coastguard Worker       "http://foo",
172*6777b538SAndroid Build Coastguard Worker       "3ffe:2a00:100:7031::1]",
173*6777b538SAndroid Build Coastguard Worker       "[3ffe:2a00:100:7031::1",
174*6777b538SAndroid Build Coastguard Worker       "foo.80",
175*6777b538SAndroid Build Coastguard Worker   };
176*6777b538SAndroid Build Coastguard Worker 
177*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(tests); ++i) {
178*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE(base::NumberToString(i) + ": " + tests[i]);
179*6777b538SAndroid Build Coastguard Worker     auto proxy = ProxyChain::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTP,
180*6777b538SAndroid Build Coastguard Worker                                                    tests[i], 80);
181*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(proxy.IsValid());
182*6777b538SAndroid Build Coastguard Worker   }
183*6777b538SAndroid Build Coastguard Worker }
184*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,InvalidPort)185*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, InvalidPort) {
186*6777b538SAndroid Build Coastguard Worker   const char* const tests[]{
187*6777b538SAndroid Build Coastguard Worker       "-1",
188*6777b538SAndroid Build Coastguard Worker       "65536",
189*6777b538SAndroid Build Coastguard Worker       "foo",
190*6777b538SAndroid Build Coastguard Worker       "0x35",
191*6777b538SAndroid Build Coastguard Worker   };
192*6777b538SAndroid Build Coastguard Worker 
193*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(tests); ++i) {
194*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE(base::NumberToString(i) + ": " + tests[i]);
195*6777b538SAndroid Build Coastguard Worker     auto proxy = ProxyChain::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTP,
196*6777b538SAndroid Build Coastguard Worker                                                    "foopy", tests[i]);
197*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(proxy.IsValid());
198*6777b538SAndroid Build Coastguard Worker   }
199*6777b538SAndroid Build Coastguard Worker }
200*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,SingleProxyChain)201*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, SingleProxyChain) {
202*6777b538SAndroid Build Coastguard Worker   auto proxy_server =
203*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:333", ProxyServer::SCHEME_HTTPS);
204*6777b538SAndroid Build Coastguard Worker 
205*6777b538SAndroid Build Coastguard Worker   std::vector<ProxyServer> proxy_servers = {proxy_server};
206*6777b538SAndroid Build Coastguard Worker   auto proxy = ProxyChain(proxy_servers);
207*6777b538SAndroid Build Coastguard Worker 
208*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(proxy.is_direct());
209*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(proxy.is_single_proxy());
210*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(proxy.is_multi_proxy());
211*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(proxy.proxy_servers(), proxy_servers);
212*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(proxy.length(), 1u);
213*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(proxy.GetProxyServer(0), proxy_server);
214*6777b538SAndroid Build Coastguard Worker }
215*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,MultiProxyChain)216*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, MultiProxyChain) {
217*6777b538SAndroid Build Coastguard Worker   auto proxy_server1 =
218*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:333", ProxyServer::SCHEME_HTTPS);
219*6777b538SAndroid Build Coastguard Worker   auto proxy_server2 =
220*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:444", ProxyServer::SCHEME_HTTPS);
221*6777b538SAndroid Build Coastguard Worker   auto proxy_server3 =
222*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:555", ProxyServer::SCHEME_HTTPS);
223*6777b538SAndroid Build Coastguard Worker 
224*6777b538SAndroid Build Coastguard Worker   std::vector<ProxyServer> proxy_servers = {proxy_server1, proxy_server2,
225*6777b538SAndroid Build Coastguard Worker                                             proxy_server3};
226*6777b538SAndroid Build Coastguard Worker   auto proxy = ProxyChain(proxy_servers);
227*6777b538SAndroid Build Coastguard Worker 
228*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(proxy.is_direct());
229*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(proxy.is_single_proxy());
230*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(proxy.is_multi_proxy());
231*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(proxy.proxy_servers(), proxy_servers);
232*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(proxy.length(), 3u);
233*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(proxy.GetProxyServer(0), proxy_server1);
234*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(proxy.GetProxyServer(1), proxy_server2);
235*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(proxy.GetProxyServer(2), proxy_server3);
236*6777b538SAndroid Build Coastguard Worker }
237*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,SplitLast)238*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, SplitLast) {
239*6777b538SAndroid Build Coastguard Worker   auto proxy_server1 =
240*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:333", ProxyServer::SCHEME_HTTPS);
241*6777b538SAndroid Build Coastguard Worker   auto proxy_server2 =
242*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:444", ProxyServer::SCHEME_HTTPS);
243*6777b538SAndroid Build Coastguard Worker   auto proxy_server3 =
244*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:555", ProxyServer::SCHEME_HTTPS);
245*6777b538SAndroid Build Coastguard Worker 
246*6777b538SAndroid Build Coastguard Worker   auto chain3 = ProxyChain::ForIpProtection(
247*6777b538SAndroid Build Coastguard Worker       {proxy_server1, proxy_server2, proxy_server3});
248*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(chain3.SplitLast(),
249*6777b538SAndroid Build Coastguard Worker             std::make_pair(
250*6777b538SAndroid Build Coastguard Worker                 ProxyChain::ForIpProtection({proxy_server1, proxy_server2}),
251*6777b538SAndroid Build Coastguard Worker                 proxy_server3));
252*6777b538SAndroid Build Coastguard Worker 
253*6777b538SAndroid Build Coastguard Worker   auto chain2 = ProxyChain({proxy_server1, proxy_server2});
254*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(chain2.SplitLast(),
255*6777b538SAndroid Build Coastguard Worker             std::make_pair(ProxyChain({proxy_server1}), proxy_server2));
256*6777b538SAndroid Build Coastguard Worker 
257*6777b538SAndroid Build Coastguard Worker   auto chain1 = ProxyChain({proxy_server1});
258*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(chain1.SplitLast(),
259*6777b538SAndroid Build Coastguard Worker             std::make_pair(ProxyChain::Direct(), proxy_server1));
260*6777b538SAndroid Build Coastguard Worker }
261*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,Prefix)262*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, Prefix) {
263*6777b538SAndroid Build Coastguard Worker   auto proxy_server1 =
264*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:333", ProxyServer::SCHEME_HTTPS);
265*6777b538SAndroid Build Coastguard Worker   auto proxy_server2 =
266*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:444", ProxyServer::SCHEME_HTTPS);
267*6777b538SAndroid Build Coastguard Worker   auto proxy_server3 =
268*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:555", ProxyServer::SCHEME_HTTPS);
269*6777b538SAndroid Build Coastguard Worker   auto chain = ProxyChain::ForIpProtection(
270*6777b538SAndroid Build Coastguard Worker       {proxy_server1, proxy_server2, proxy_server3}, /*chain_id=*/2);
271*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(chain.Prefix(0), ProxyChain::ForIpProtection({}, /*chain_id=*/2));
272*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(chain.Prefix(1),
273*6777b538SAndroid Build Coastguard Worker             ProxyChain::ForIpProtection({proxy_server1}, /*chain_id=*/2));
274*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(chain.Prefix(2),
275*6777b538SAndroid Build Coastguard Worker             ProxyChain::ForIpProtection({proxy_server1, proxy_server2},
276*6777b538SAndroid Build Coastguard Worker                                         /*chain_id=*/2));
277*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(chain.Prefix(3),
278*6777b538SAndroid Build Coastguard Worker             ProxyChain::ForIpProtection(
279*6777b538SAndroid Build Coastguard Worker                 {proxy_server1, proxy_server2, proxy_server3}, /*chain_id=*/2));
280*6777b538SAndroid Build Coastguard Worker }
281*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,First)282*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, First) {
283*6777b538SAndroid Build Coastguard Worker   auto proxy_server1 =
284*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:333", ProxyServer::SCHEME_HTTPS);
285*6777b538SAndroid Build Coastguard Worker   auto proxy_server2 =
286*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:444", ProxyServer::SCHEME_HTTPS);
287*6777b538SAndroid Build Coastguard Worker 
288*6777b538SAndroid Build Coastguard Worker   auto chain = ProxyChain({proxy_server1, proxy_server2});
289*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(chain.First(), proxy_server1);
290*6777b538SAndroid Build Coastguard Worker 
291*6777b538SAndroid Build Coastguard Worker   chain = ProxyChain({proxy_server1});
292*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(chain.First(), proxy_server1);
293*6777b538SAndroid Build Coastguard Worker }
294*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,Last)295*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, Last) {
296*6777b538SAndroid Build Coastguard Worker   auto proxy_server1 =
297*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:333", ProxyServer::SCHEME_HTTPS);
298*6777b538SAndroid Build Coastguard Worker   auto proxy_server2 =
299*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:444", ProxyServer::SCHEME_HTTPS);
300*6777b538SAndroid Build Coastguard Worker 
301*6777b538SAndroid Build Coastguard Worker   auto chain = ProxyChain({proxy_server1, proxy_server2});
302*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(chain.Last(), proxy_server2);
303*6777b538SAndroid Build Coastguard Worker 
304*6777b538SAndroid Build Coastguard Worker   chain = ProxyChain({proxy_server1});
305*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(chain.Last(), proxy_server1);
306*6777b538SAndroid Build Coastguard Worker }
307*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,IsForIpProtection)308*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, IsForIpProtection) {
309*6777b538SAndroid Build Coastguard Worker   auto regular_proxy_chain1 = ProxyChain::Direct();
310*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(regular_proxy_chain1.is_for_ip_protection());
311*6777b538SAndroid Build Coastguard Worker 
312*6777b538SAndroid Build Coastguard Worker   auto ip_protection_proxy_chain1 =
313*6777b538SAndroid Build Coastguard Worker       ProxyChain::ForIpProtection(std::vector<ProxyServer>());
314*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ip_protection_proxy_chain1.is_for_ip_protection());
315*6777b538SAndroid Build Coastguard Worker 
316*6777b538SAndroid Build Coastguard Worker   auto regular_proxy_chain2 =
317*6777b538SAndroid Build Coastguard Worker       ProxyChain({ProxyUriToProxyServer("foo:555", ProxyServer::SCHEME_HTTPS),
318*6777b538SAndroid Build Coastguard Worker                   ProxyUriToProxyServer("foo:666", ProxyServer::SCHEME_HTTPS)});
319*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(regular_proxy_chain2.is_for_ip_protection());
320*6777b538SAndroid Build Coastguard Worker 
321*6777b538SAndroid Build Coastguard Worker   auto ip_protection_proxy_chain2 = ProxyChain::ForIpProtection(
322*6777b538SAndroid Build Coastguard Worker       {ProxyUriToProxyServer("foo:555", ProxyServer::SCHEME_HTTPS),
323*6777b538SAndroid Build Coastguard Worker        ProxyUriToProxyServer("foo:666", ProxyServer::SCHEME_HTTPS)});
324*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ip_protection_proxy_chain2.is_for_ip_protection());
325*6777b538SAndroid Build Coastguard Worker }
326*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,ForIpProtection)327*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, ForIpProtection) {
328*6777b538SAndroid Build Coastguard Worker   auto ip_protection_proxy_chain1 =
329*6777b538SAndroid Build Coastguard Worker       ProxyChain::ForIpProtection(std::vector<ProxyServer>());
330*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ip_protection_proxy_chain1.is_direct());
331*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ip_protection_proxy_chain1.is_for_ip_protection());
332*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ip_protection_proxy_chain1.ip_protection_chain_id(),
333*6777b538SAndroid Build Coastguard Worker             ProxyChain::kDefaultIpProtectionChainId);
334*6777b538SAndroid Build Coastguard Worker 
335*6777b538SAndroid Build Coastguard Worker   auto regular_proxy_chain2 =
336*6777b538SAndroid Build Coastguard Worker       ProxyChain({ProxyUriToProxyServer("foo:555", ProxyServer::SCHEME_HTTPS),
337*6777b538SAndroid Build Coastguard Worker                   ProxyUriToProxyServer("foo:666", ProxyServer::SCHEME_HTTPS)});
338*6777b538SAndroid Build Coastguard Worker   auto ip_protection_proxy_chain2 = ProxyChain::ForIpProtection(
339*6777b538SAndroid Build Coastguard Worker       {ProxyUriToProxyServer("foo:555", ProxyServer::SCHEME_HTTPS),
340*6777b538SAndroid Build Coastguard Worker        ProxyUriToProxyServer("foo:666", ProxyServer::SCHEME_HTTPS)});
341*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ip_protection_proxy_chain2.is_for_ip_protection());
342*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ip_protection_proxy_chain2.ip_protection_chain_id(),
343*6777b538SAndroid Build Coastguard Worker             ProxyChain::kDefaultIpProtectionChainId);
344*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(regular_proxy_chain2.proxy_servers(),
345*6777b538SAndroid Build Coastguard Worker             ip_protection_proxy_chain2.proxy_servers());
346*6777b538SAndroid Build Coastguard Worker 
347*6777b538SAndroid Build Coastguard Worker   auto self_assignable_proxy_chain =
348*6777b538SAndroid Build Coastguard Worker       ProxyChain({ProxyUriToProxyServer("foo:555", ProxyServer::SCHEME_HTTPS),
349*6777b538SAndroid Build Coastguard Worker                   ProxyUriToProxyServer("foo:666", ProxyServer::SCHEME_HTTPS)});
350*6777b538SAndroid Build Coastguard Worker   auto copied_proxy_chain = self_assignable_proxy_chain;
351*6777b538SAndroid Build Coastguard Worker 
352*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(self_assignable_proxy_chain.is_for_ip_protection());
353*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(self_assignable_proxy_chain.ip_protection_chain_id(),
354*6777b538SAndroid Build Coastguard Worker             ProxyChain::kNotIpProtectionChainId);
355*6777b538SAndroid Build Coastguard Worker 
356*6777b538SAndroid Build Coastguard Worker   self_assignable_proxy_chain = ProxyChain::ForIpProtection(
357*6777b538SAndroid Build Coastguard Worker       std::move(self_assignable_proxy_chain.proxy_servers()));
358*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(self_assignable_proxy_chain.is_for_ip_protection());
359*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(self_assignable_proxy_chain.proxy_servers(),
360*6777b538SAndroid Build Coastguard Worker             copied_proxy_chain.proxy_servers());
361*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(self_assignable_proxy_chain.ip_protection_chain_id(),
362*6777b538SAndroid Build Coastguard Worker             ProxyChain::kDefaultIpProtectionChainId);
363*6777b538SAndroid Build Coastguard Worker 
364*6777b538SAndroid Build Coastguard Worker   auto chain_with_id = ProxyChain::ForIpProtection(
365*6777b538SAndroid Build Coastguard Worker       {ProxyUriToProxyServer("foo:555", ProxyServer::SCHEME_HTTPS),
366*6777b538SAndroid Build Coastguard Worker        ProxyUriToProxyServer("foo:666", ProxyServer::SCHEME_HTTPS)},
367*6777b538SAndroid Build Coastguard Worker       /*chain_id=*/3);
368*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(chain_with_id.is_direct());
369*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(chain_with_id.is_for_ip_protection());
370*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(chain_with_id.ip_protection_chain_id(), 3);
371*6777b538SAndroid Build Coastguard Worker }
372*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,IsGetToProxyAllowed)373*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, IsGetToProxyAllowed) {
374*6777b538SAndroid Build Coastguard Worker   auto https_server1 =
375*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:333", ProxyServer::SCHEME_HTTPS);
376*6777b538SAndroid Build Coastguard Worker   auto https_server2 =
377*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:444", ProxyServer::SCHEME_HTTPS);
378*6777b538SAndroid Build Coastguard Worker   auto http_server = ProxyUriToProxyServer("foo:555", ProxyServer::SCHEME_HTTP);
379*6777b538SAndroid Build Coastguard Worker   auto socks_server =
380*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:666", ProxyServer::SCHEME_SOCKS4);
381*6777b538SAndroid Build Coastguard Worker 
382*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ProxyChain::Direct().is_get_to_proxy_allowed());
383*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ProxyChain({https_server1}).is_get_to_proxy_allowed());
384*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ProxyChain({http_server}).is_get_to_proxy_allowed());
385*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ProxyChain({socks_server}).is_get_to_proxy_allowed());
386*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
387*6777b538SAndroid Build Coastguard Worker       ProxyChain({https_server1, https_server2}).is_get_to_proxy_allowed());
388*6777b538SAndroid Build Coastguard Worker }
389*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,IsValid)390*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, IsValid) {
391*6777b538SAndroid Build Coastguard Worker   // Single hop proxy of type Direct is valid.
392*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ProxyChain::Direct().IsValid());
393*6777b538SAndroid Build Coastguard Worker 
394*6777b538SAndroid Build Coastguard Worker   auto https1 = ProxyUriToProxyServer("foo:444", ProxyServer::SCHEME_HTTPS);
395*6777b538SAndroid Build Coastguard Worker   auto https2 = ProxyUriToProxyServer("foo:555", ProxyServer::SCHEME_HTTPS);
396*6777b538SAndroid Build Coastguard Worker   auto quic1 = ProxyUriToProxyServer("foo:666", ProxyServer::SCHEME_QUIC);
397*6777b538SAndroid Build Coastguard Worker   auto quic2 = ProxyUriToProxyServer("foo:777", ProxyServer::SCHEME_QUIC);
398*6777b538SAndroid Build Coastguard Worker   auto socks = ProxyUriToProxyServer("foo:777", ProxyServer::SCHEME_SOCKS5);
399*6777b538SAndroid Build Coastguard Worker 
400*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ProxyChain({https1}).IsValid());
401*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ProxyChain({quic1}).IsValid());
402*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(ProxyChain({https1, https2}).IsValid());
403*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ProxyChain({quic1, https1}).IsValid());
404*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ProxyChain({quic1, quic2, https1, https2}).IsValid());
405*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ProxyChain({https1, quic2}).IsValid());
406*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ProxyChain({https1, https2, quic1, quic2}).IsValid());
407*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ProxyChain({socks, https1}).IsValid());
408*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ProxyChain({socks, https1, https2}).IsValid());
409*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ProxyChain({https1, socks}).IsValid());
410*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(ProxyChain({https1, https2, socks}).IsValid());
411*6777b538SAndroid Build Coastguard Worker 
412*6777b538SAndroid Build Coastguard Worker   // IP protection accepts chains with SCHEME_QUIC, but CHECKs on failure
413*6777b538SAndroid Build Coastguard Worker   // instead of just creating an invalid chain.
414*6777b538SAndroid Build Coastguard Worker   auto IppChain = [](std::vector<ProxyServer> proxy_servers) {
415*6777b538SAndroid Build Coastguard Worker     return ProxyChain::ForIpProtection(std::move(proxy_servers));
416*6777b538SAndroid Build Coastguard Worker   };
417*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IppChain({https1}).IsValid());
418*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IppChain({quic1}).IsValid());
419*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IppChain({https1, https2}).IsValid());
420*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IppChain({quic1, https1}).IsValid());
421*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(IppChain({quic1, quic2, https1, https2}).IsValid());
422*6777b538SAndroid Build Coastguard Worker   EXPECT_CHECK_DEATH(IppChain({https1, quic2}).IsValid());
423*6777b538SAndroid Build Coastguard Worker   EXPECT_CHECK_DEATH(IppChain({https1, https2, quic1, quic2}).IsValid());
424*6777b538SAndroid Build Coastguard Worker   EXPECT_CHECK_DEATH(IppChain({socks, https1}).IsValid());
425*6777b538SAndroid Build Coastguard Worker   EXPECT_CHECK_DEATH(IppChain({socks, https1, https2}).IsValid());
426*6777b538SAndroid Build Coastguard Worker   EXPECT_CHECK_DEATH(IppChain({https1, socks}).IsValid());
427*6777b538SAndroid Build Coastguard Worker   EXPECT_CHECK_DEATH(IppChain({https1, https2, socks}).IsValid());
428*6777b538SAndroid Build Coastguard Worker }
429*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,Unequal)430*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, Unequal) {
431*6777b538SAndroid Build Coastguard Worker   // Ordered proxy chains.
432*6777b538SAndroid Build Coastguard Worker   std::vector<ProxyChain> proxy_chain_list = {
433*6777b538SAndroid Build Coastguard Worker       ProxyChain::Direct(),
434*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyChain("foo:333", ProxyServer::SCHEME_HTTP),
435*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyChain("foo:444", ProxyServer::SCHEME_HTTP),
436*6777b538SAndroid Build Coastguard Worker       ProxyChain({ProxyUriToProxyServer("foo:555", ProxyServer::SCHEME_HTTPS),
437*6777b538SAndroid Build Coastguard Worker                   ProxyUriToProxyServer("foo:666", ProxyServer::SCHEME_HTTPS)}),
438*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyChain("socks4://foo:33", ProxyServer::SCHEME_SOCKS4),
439*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyChain("http://foo:33", ProxyServer::SCHEME_HTTP),
440*6777b538SAndroid Build Coastguard Worker       ProxyChain({ProxyUriToProxyChain("bar:33", ProxyServer::SCHEME_HTTP)}),
441*6777b538SAndroid Build Coastguard Worker       ProxyChain::ForIpProtection(
442*6777b538SAndroid Build Coastguard Worker           {ProxyUriToProxyServer("foo:555", ProxyServer::SCHEME_HTTPS),
443*6777b538SAndroid Build Coastguard Worker            ProxyUriToProxyServer("foo:666", ProxyServer::SCHEME_HTTPS)})};
444*6777b538SAndroid Build Coastguard Worker 
445*6777b538SAndroid Build Coastguard Worker   // Unordered proxy chains.
446*6777b538SAndroid Build Coastguard Worker   std::set<ProxyChain> proxy_chain_set(proxy_chain_list.begin(),
447*6777b538SAndroid Build Coastguard Worker                                        proxy_chain_list.end());
448*6777b538SAndroid Build Coastguard Worker 
449*6777b538SAndroid Build Coastguard Worker   // Initial proxy chain list and set are equal.
450*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(proxy_chain_list.size(), proxy_chain_set.size());
451*6777b538SAndroid Build Coastguard Worker 
452*6777b538SAndroid Build Coastguard Worker   for (const ProxyChain& proxy_chain1 : proxy_chain_list) {
453*6777b538SAndroid Build Coastguard Worker     auto proxy_chain2 = proxy_chain_set.begin();
454*6777b538SAndroid Build Coastguard Worker     // Chain set entries less than `proxy_chain1`.
455*6777b538SAndroid Build Coastguard Worker     while (*proxy_chain2 < proxy_chain1) {
456*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(*proxy_chain2 < proxy_chain1);
457*6777b538SAndroid Build Coastguard Worker       EXPECT_FALSE(proxy_chain1 < *proxy_chain2);
458*6777b538SAndroid Build Coastguard Worker       EXPECT_FALSE(*proxy_chain2 == proxy_chain1);
459*6777b538SAndroid Build Coastguard Worker       EXPECT_FALSE(proxy_chain1 == *proxy_chain2);
460*6777b538SAndroid Build Coastguard Worker       ++proxy_chain2;
461*6777b538SAndroid Build Coastguard Worker     }
462*6777b538SAndroid Build Coastguard Worker 
463*6777b538SAndroid Build Coastguard Worker     // Chain set entry for `proxy_chain1`.
464*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(*proxy_chain2 < proxy_chain1);
465*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(proxy_chain1 < *proxy_chain2);
466*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(*proxy_chain2 == proxy_chain1);
467*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(proxy_chain1 == *proxy_chain2);
468*6777b538SAndroid Build Coastguard Worker     ++proxy_chain2;
469*6777b538SAndroid Build Coastguard Worker 
470*6777b538SAndroid Build Coastguard Worker     // Chain set entries greater than `proxy_chain1`.
471*6777b538SAndroid Build Coastguard Worker     while (proxy_chain2 != proxy_chain_set.end() &&
472*6777b538SAndroid Build Coastguard Worker            proxy_chain1 < *proxy_chain2) {
473*6777b538SAndroid Build Coastguard Worker       EXPECT_FALSE(*proxy_chain2 < proxy_chain1);
474*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(proxy_chain1 < *proxy_chain2);
475*6777b538SAndroid Build Coastguard Worker       EXPECT_FALSE(*proxy_chain2 == proxy_chain1);
476*6777b538SAndroid Build Coastguard Worker       EXPECT_FALSE(proxy_chain1 == *proxy_chain2);
477*6777b538SAndroid Build Coastguard Worker       ++proxy_chain2;
478*6777b538SAndroid Build Coastguard Worker     }
479*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(proxy_chain2, proxy_chain_set.end());
480*6777b538SAndroid Build Coastguard Worker   }
481*6777b538SAndroid Build Coastguard Worker }
482*6777b538SAndroid Build Coastguard Worker 
TEST(ProxyChainTest,Equal)483*6777b538SAndroid Build Coastguard Worker TEST(ProxyChainTest, Equal) {
484*6777b538SAndroid Build Coastguard Worker   ProxyServer proxy_server =
485*6777b538SAndroid Build Coastguard Worker       ProxyUriToProxyServer("foo:11", ProxyServer::SCHEME_HTTP);
486*6777b538SAndroid Build Coastguard Worker 
487*6777b538SAndroid Build Coastguard Worker   ProxyChain proxy_chain1 = ProxyChain(proxy_server);
488*6777b538SAndroid Build Coastguard Worker   ProxyChain proxy_chain2 = ProxyChain(std::vector<ProxyServer>{proxy_server});
489*6777b538SAndroid Build Coastguard Worker   ProxyChain proxy_chain3 =
490*6777b538SAndroid Build Coastguard Worker       ProxyChain(ProxyServer::SCHEME_HTTP, HostPortPair("foo", 11));
491*6777b538SAndroid Build Coastguard Worker 
492*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(proxy_chain1 < proxy_chain2);
493*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(proxy_chain2 < proxy_chain1);
494*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(proxy_chain2 == proxy_chain1);
495*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(proxy_chain2 == proxy_chain1);
496*6777b538SAndroid Build Coastguard Worker 
497*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(proxy_chain2 < proxy_chain3);
498*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(proxy_chain3 < proxy_chain2);
499*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(proxy_chain3 == proxy_chain2);
500*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(proxy_chain3 == proxy_chain2);
501*6777b538SAndroid Build Coastguard Worker }
502*6777b538SAndroid Build Coastguard Worker 
503*6777b538SAndroid Build Coastguard Worker }  // namespace
504*6777b538SAndroid Build Coastguard Worker 
505*6777b538SAndroid Build Coastguard Worker }  // namespace net
506