• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2011 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "update_engine/chrome_browser_proxy_resolver.h"
18 
19 #include <deque>
20 #include <string>
21 #include <vector>
22 
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25 
26 #include <base/macros.h>
27 #include <brillo/errors/error.h>
28 
29 #include "network_proxy/dbus-proxies.h"
30 #include "network_proxy/dbus-proxy-mocks.h"
31 #include "update_engine/dbus_test_utils.h"
32 
33 using ::testing::DoAll;
34 using ::testing::SaveArg;
35 using ::testing::StrEq;
36 using ::testing::_;
37 using org::chromium::NetworkProxyServiceInterfaceProxyMock;
38 using std::deque;
39 using std::string;
40 using std::vector;
41 
42 namespace chromeos_update_engine {
43 
44 namespace {
45 
46 // Callback for ProxyResolver::GetProxiesForUrl() that copies |src| to |dest|.
CopyProxies(deque<string> * dest,const deque<string> & src)47 void CopyProxies(deque<string>* dest, const deque<string>& src) {
48   *dest = src;
49 }
50 
51 }  // namespace
52 
53 class ChromeBrowserProxyResolverTest : public ::testing::Test {
54  public:
55   ChromeBrowserProxyResolverTest() = default;
56   ~ChromeBrowserProxyResolverTest() override = default;
57 
58  protected:
59   // Adds a GoogleMock expectation for a call to |dbus_proxy_|'s
60   // ResolveProxyAsync method to resolve |url|.
AddResolveProxyExpectation(const std::string & url)61   void AddResolveProxyExpectation(const std::string& url) {
62     EXPECT_CALL(dbus_proxy_, ResolveProxyAsync(StrEq(url), _, _, _))
63         .WillOnce(DoAll(SaveArg<1>(&success_callback_),
64                         SaveArg<2>(&error_callback_)));
65   }
66 
67   NetworkProxyServiceInterfaceProxyMock dbus_proxy_;
68   ChromeBrowserProxyResolver resolver_{&dbus_proxy_};
69 
70   // Callbacks that were passed to |dbus_proxy_|'s ResolveProxyAsync method.
71   base::Callback<void(const std::string&, const std::string&)>
72       success_callback_;
73   base::Callback<void(brillo::Error*)> error_callback_;
74 
75  private:
76   DISALLOW_COPY_AND_ASSIGN(ChromeBrowserProxyResolverTest);
77 };
78 
TEST_F(ChromeBrowserProxyResolverTest,Parse)79 TEST_F(ChromeBrowserProxyResolverTest, Parse) {
80   // Test ideas from
81   // http://src.chromium.org/svn/trunk/src/net/proxy/proxy_list_unittest.cc
82   vector<string> inputs = {
83       "PROXY foopy:10",
84       " DIRECT", // leading space.
85       "PROXY foopy1 ; proxy foopy2;\t DIRECT",
86       "proxy foopy1 ; SOCKS foopy2",
87       "DIRECT ; proxy foopy1 ; DIRECT ; SOCKS5 foopy2;DIRECT ",
88       "DIRECT ; proxy foopy1:80; DIRECT ; DIRECT",
89       "PROXY-foopy:10",
90       "PROXY",
91       "PROXY foopy1 ; JUNK ; JUNK ; SOCKS5 foopy2 ; ;",
92       "HTTP foopy1; SOCKS5 foopy2",
93   };
94   vector<deque<string>> outputs = {
95       {"http://foopy:10", kNoProxy},
96       {kNoProxy},
97       {"http://foopy1", "http://foopy2", kNoProxy},
98       {"http://foopy1", "socks4://foopy2", kNoProxy},
99       {kNoProxy, "http://foopy1", kNoProxy, "socks5://foopy2", kNoProxy},
100       {kNoProxy, "http://foopy1:80", kNoProxy, kNoProxy},
101       {kNoProxy},
102       {kNoProxy},
103       {"http://foopy1", "socks5://foopy2", kNoProxy},
104       {"socks5://foopy2", kNoProxy},
105   };
106   ASSERT_EQ(inputs.size(), outputs.size());
107 
108   for (size_t i = 0; i < inputs.size(); i++) {
109     deque<string> results =
110         ChromeBrowserProxyResolver::ParseProxyString(inputs[i]);
111     deque<string>& expected = outputs[i];
112     EXPECT_EQ(results.size(), expected.size()) << "i = " << i;
113     if (expected.size() != results.size())
114       continue;
115     for (size_t j = 0; j < expected.size(); j++) {
116       EXPECT_EQ(expected[j], results[j]) << "i = " << i;
117     }
118   }
119 }
120 
TEST_F(ChromeBrowserProxyResolverTest,Success)121 TEST_F(ChromeBrowserProxyResolverTest, Success) {
122   const char kUrl[] = "http://example.com/blah";
123   const char kProxyConfig[] = "SOCKS5 192.168.52.83:5555;DIRECT";
124   AddResolveProxyExpectation(kUrl);
125   deque<string> proxies;
126   resolver_.GetProxiesForUrl(kUrl, base::Bind(&CopyProxies, &proxies));
127 
128   // Run the D-Bus success callback and verify that the proxies are passed to
129   // the supplied function.
130   ASSERT_FALSE(success_callback_.is_null());
131   success_callback_.Run(kProxyConfig, string());
132   ASSERT_EQ(2u, proxies.size());
133   EXPECT_EQ("socks5://192.168.52.83:5555", proxies[0]);
134   EXPECT_EQ(kNoProxy, proxies[1]);
135 }
136 
TEST_F(ChromeBrowserProxyResolverTest,Failure)137 TEST_F(ChromeBrowserProxyResolverTest, Failure) {
138   const char kUrl[] = "http://example.com/blah";
139   AddResolveProxyExpectation(kUrl);
140   deque<string> proxies;
141   resolver_.GetProxiesForUrl(kUrl, base::Bind(&CopyProxies, &proxies));
142 
143   // Run the D-Bus error callback and verify that the supplied function is
144   // instructed to use a direct connection.
145   ASSERT_FALSE(error_callback_.is_null());
146   brillo::ErrorPtr error = brillo::Error::Create(FROM_HERE, "", "", "");
147   error_callback_.Run(error.get());
148   ASSERT_EQ(1u, proxies.size());
149   EXPECT_EQ(kNoProxy, proxies[0]);
150 }
151 
TEST_F(ChromeBrowserProxyResolverTest,CancelCallback)152 TEST_F(ChromeBrowserProxyResolverTest, CancelCallback) {
153   const char kUrl[] = "http://example.com/blah";
154   AddResolveProxyExpectation(kUrl);
155   int called = 0;
156   auto callback = base::Bind(
157       [](int* called, const deque<string>& proxies) { (*called)++; }, &called);
158   ProxyRequestId request = resolver_.GetProxiesForUrl(kUrl, callback);
159 
160   // Cancel the request and then run the D-Bus success callback. The original
161   // callback shouldn't be run.
162   EXPECT_TRUE(resolver_.CancelProxyRequest(request));
163   ASSERT_FALSE(success_callback_.is_null());
164   success_callback_.Run("DIRECT", string());
165   EXPECT_EQ(0, called);
166 }
167 
TEST_F(ChromeBrowserProxyResolverTest,CancelCallbackTwice)168 TEST_F(ChromeBrowserProxyResolverTest, CancelCallbackTwice) {
169   const char kUrl[] = "http://example.com/blah";
170   AddResolveProxyExpectation(kUrl);
171   deque<string> proxies;
172   ProxyRequestId request =
173       resolver_.GetProxiesForUrl(kUrl, base::Bind(&CopyProxies, &proxies));
174 
175   // Cancel the same request twice. The second call should fail.
176   EXPECT_TRUE(resolver_.CancelProxyRequest(request));
177   EXPECT_FALSE(resolver_.CancelProxyRequest(request));
178 }
179 
180 }  // namespace chromeos_update_engine
181