Index: chrome_browser_proxy_resolver_unittest.cc |
diff --git a/chrome_browser_proxy_resolver_unittest.cc b/chrome_browser_proxy_resolver_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..09a8be7857a2d5e09d2581b0e755baaf4dd9c085 |
--- /dev/null |
+++ b/chrome_browser_proxy_resolver_unittest.cc |
@@ -0,0 +1,238 @@ |
+// Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <deque> |
+#include <string> |
+ |
+#include <gtest/gtest.h> |
+ |
+#include "update_engine/chrome_browser_proxy_resolver.h" |
+#include "update_engine/mock_dbus_interface.h" |
+ |
+using std::deque; |
+using std::string; |
+using ::testing::_; |
+using ::testing::Return; |
+using ::testing::SetArgumentPointee; |
+using ::testing::StrEq; |
+ |
+namespace chromeos_update_engine { |
+ |
+class ChromeBrowserProxyResolverTest : public ::testing::Test { }; |
+ |
+TEST(ChromeBrowserProxyResolverTest, ParseTest) { |
+ // Test ideas from |
+ // http://src.chromium.org/svn/trunk/src/net/proxy/proxy_list_unittest.cc |
+ const char* inputs[] = { |
+ "PROXY foopy:10", |
+ " DIRECT", // leading space. |
+ "PROXY foopy1 ; proxy foopy2;\t DIRECT", |
+ "proxy foopy1 ; SOCKS foopy2", |
+ "DIRECT ; proxy foopy1 ; DIRECT ; SOCKS5 foopy2;DIRECT ", |
+ "DIRECT ; proxy foopy1:80; DIRECT ; DIRECT", |
+ "PROXY-foopy:10", |
+ "PROXY", |
+ "PROXY foopy1 ; JUNK ; JUNK ; SOCKS5 foopy2 ; ;", |
+ "HTTP foopy1; SOCKS5 foopy2" |
+ }; |
+ deque<string> outputs[arraysize(inputs)]; |
+ outputs[0].push_back("http://foopy:10"); |
+ outputs[0].push_back(kNoProxy); |
+ outputs[1].push_back(kNoProxy); |
+ outputs[2].push_back("http://foopy1"); |
+ outputs[2].push_back("http://foopy2"); |
+ outputs[2].push_back(kNoProxy); |
+ outputs[3].push_back("http://foopy1"); |
+ outputs[3].push_back("socks4://foopy2"); |
+ outputs[3].push_back(kNoProxy); |
+ outputs[4].push_back(kNoProxy); |
+ outputs[4].push_back("http://foopy1"); |
+ outputs[4].push_back(kNoProxy); |
+ outputs[4].push_back("socks5://foopy2"); |
+ outputs[4].push_back(kNoProxy); |
+ outputs[5].push_back(kNoProxy); |
+ outputs[5].push_back("http://foopy1:80"); |
+ outputs[5].push_back(kNoProxy); |
+ outputs[5].push_back(kNoProxy); |
+ outputs[6].push_back(kNoProxy); |
+ outputs[7].push_back(kNoProxy); |
+ outputs[8].push_back("http://foopy1"); |
+ outputs[8].push_back("socks5://foopy2"); |
+ outputs[8].push_back(kNoProxy); |
+ outputs[9].push_back("socks5://foopy2"); |
+ outputs[9].push_back(kNoProxy); |
+ |
+ for (size_t i = 0; i < arraysize(inputs); i++) { |
+ deque<string> results = |
+ ChromeBrowserProxyResolver::ParseProxyString(inputs[i]); |
+ deque<string>& expected = outputs[i]; |
+ EXPECT_EQ(results.size(), expected.size()) << "i = " << i; |
+ if (expected.size() != results.size()) |
+ continue; |
+ for (size_t j = 0; j < expected.size(); j++) { |
+ EXPECT_EQ(expected[j], results[j]) << "i = " << i; |
+ } |
+ } |
+} |
+ |
+namespace { |
+void DbusInterfaceTestResolved(const std::deque<std::string>& proxies, |
+ void* data) { |
+ EXPECT_EQ(2, proxies.size()); |
+ EXPECT_EQ("socks5://192.168.52.83:5555", proxies[0]); |
+ EXPECT_EQ(kNoProxy, proxies[1]); |
+ g_main_loop_quit(reinterpret_cast<GMainLoop*>(data)); |
+} |
+void DbusInterfaceTestResolvedNoReply(const std::deque<std::string>& proxies, |
+ void* data) { |
+ EXPECT_EQ(1, proxies.size()); |
+ EXPECT_EQ(kNoProxy, proxies[0]); |
+ g_main_loop_quit(reinterpret_cast<GMainLoop*>(data)); |
+} |
+struct SendReplyArgs { |
+ DBusConnection* connection; |
+ DBusMessage* message; |
+ ChromeBrowserProxyResolver* resolver; |
+}; |
+gboolean SendReply(gpointer data) { |
+ LOG(INFO) << "Calling SendReply"; |
+ SendReplyArgs* args = reinterpret_cast<SendReplyArgs*>(data); |
+ ChromeBrowserProxyResolver::StaticFilterMessage( |
+ args->connection, |
+ args->message, |
+ args->resolver); |
+ return FALSE; // Don't keep calling this function |
+} |
+ |
+// chrome_replies should be set to whether or not we fake a reply from |
+// chrome. If there's no reply, the resolver should time out. |
+void RunTest(bool chrome_replies) { |
+ long number = 1; |
+ DBusGConnection* kMockSystemGBus = |
+ reinterpret_cast<DBusGConnection*>(number++); |
+ DBusConnection* kMockSystemBus = |
+ reinterpret_cast<DBusConnection*>(number++); |
+ DBusGProxy* kMockDbusProxy = |
+ reinterpret_cast<DBusGProxy*>(number++); |
+ DBusMessage* kMockDbusMessage = |
+ reinterpret_cast<DBusMessage*>(number++); |
+ |
+ const char kUrl[] = "http://example.com/blah"; |
+ |
+ MockDbusGlib dbus_iface; |
+ |
+ EXPECT_CALL(dbus_iface, BusGet(_, _)) |
+ .Times(3) |
+ .WillRepeatedly(Return(kMockSystemGBus)); |
+ EXPECT_CALL(dbus_iface, |
+ ConnectionGetConnection(kMockSystemGBus)) |
+ .Times(2) |
+ .WillRepeatedly(Return(kMockSystemBus)); |
+ EXPECT_CALL(dbus_iface, DbusBusAddMatch(kMockSystemBus, _, _)); |
+ EXPECT_CALL(dbus_iface, |
+ DbusConnectionAddFilter(kMockSystemBus, _, _, _)) |
+ .WillOnce(Return(1)); |
+ EXPECT_CALL(dbus_iface, |
+ ProxyNewForNameOwner(kMockSystemGBus, |
+ StrEq(kLibCrosServiceName), |
+ StrEq(kLibCrosServicePath), |
+ StrEq(kLibCrosServiceInterface), |
+ _)) |
+ .WillOnce(Return(kMockDbusProxy)); |
+ EXPECT_CALL(dbus_iface, ProxyCall( |
+ kMockDbusProxy, |
+ StrEq(kLibCrosServiceResolveNetworkProxyMethodName), |
+ _, |
+ G_TYPE_STRING, StrEq(kUrl), |
+ G_TYPE_STRING, StrEq(kLibCrosProxyResolveSignalInterface), |
+ G_TYPE_STRING, StrEq(kLibCrosProxyResolveName), |
+ G_TYPE_INVALID)) |
+ .WillOnce(Return(TRUE)); |
+ EXPECT_CALL(dbus_iface, |
+ DbusConnectionRemoveFilter(kMockSystemBus, _, _)); |
+ if (chrome_replies) { |
+ EXPECT_CALL(dbus_iface, |
+ DbusMessageIsSignal(kMockDbusMessage, |
+ kLibCrosProxyResolveSignalInterface, |
+ kLibCrosProxyResolveName)) |
+ .WillOnce(Return(1)); |
+ EXPECT_CALL(dbus_iface, |
+ DbusMessageGetArgs(kMockDbusMessage, _, |
+ DBUS_TYPE_STRING, _, |
+ DBUS_TYPE_STRING, _, |
+ DBUS_TYPE_STRING, _, |
+ DBUS_TYPE_INVALID)) |
+ .WillOnce(DoAll(SetArgumentPointee<3>(strdup(kUrl)), |
+ SetArgumentPointee<5>( |
+ strdup("SOCKS5 192.168.52.83:5555;DIRECT")), |
+ Return(TRUE))); |
+ } |
+ |
+ GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE); |
+ |
+ ChromeBrowserProxyResolver resolver(&dbus_iface); |
+ EXPECT_TRUE(resolver.Init()); |
+ resolver.set_timeout(1); |
+ SendReplyArgs args = { |
+ kMockSystemBus, |
+ kMockDbusMessage, |
+ &resolver |
+ }; |
+ if (chrome_replies) |
+ g_idle_add(SendReply, &args); |
+ EXPECT_TRUE(resolver.GetProxiesForUrl(kUrl, |
+ chrome_replies ? |
+ &DbusInterfaceTestResolved : |
+ &DbusInterfaceTestResolvedNoReply, |
+ loop)); |
+ g_main_loop_run(loop); |
+ g_main_loop_unref(loop); |
+} |
+} // namespace {} |
+ |
+TEST(ChromeBrowserProxyResolverTest, SuccessTest) { |
+ RunTest(true); |
+} |
+ |
+TEST(ChromeBrowserProxyResolverTest, NoReplyTest) { |
+ RunTest(false); |
+} |
+ |
+TEST(ChromeBrowserProxyResolverTest, NoChromeTest) { |
+ long number = 1; |
+ DBusGConnection* kMockSystemGBus = |
+ reinterpret_cast<DBusGConnection*>(number++); |
+ DBusConnection* kMockSystemBus = |
+ reinterpret_cast<DBusConnection*>(number++); |
+ |
+ const char kUrl[] = "http://example.com/blah"; |
+ |
+ MockDbusGlib dbus_iface; |
+ |
+ EXPECT_CALL(dbus_iface, BusGet(_, _)) |
+ .Times(2) |
+ .WillRepeatedly(Return(kMockSystemGBus)); |
+ EXPECT_CALL(dbus_iface, |
+ ConnectionGetConnection(kMockSystemGBus)) |
+ .Times(1) |
+ .WillOnce(Return(kMockSystemBus)); |
+ EXPECT_CALL(dbus_iface, DbusBusAddMatch(kMockSystemBus, _, _)); |
+ EXPECT_CALL(dbus_iface, |
+ DbusConnectionAddFilter(kMockSystemBus, _, _, _)) |
+ .WillOnce(Return(1)); |
+ EXPECT_CALL(dbus_iface, |
+ ProxyNewForNameOwner(kMockSystemGBus, |
+ StrEq(kLibCrosServiceName), |
+ StrEq(kLibCrosServicePath), |
+ StrEq(kLibCrosServiceInterface), |
+ _)) |
+ .WillOnce(Return(static_cast<DBusGProxy*>(NULL))); |
+ EXPECT_CALL(dbus_iface, |
+ DbusConnectionRemoveFilter(kMockSystemBus, _, _)); |
+ ChromeBrowserProxyResolver resolver(&dbus_iface); |
+ EXPECT_FALSE(resolver.Init()); |
+ EXPECT_FALSE(resolver.GetProxiesForUrl(kUrl, NULL, NULL)); |
+} |
+ |
+} // namespace chromeos_update_engine |