1// Copyright (c) 2012 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 "base/memory/ref_counted.h" 6#include "base/strings/stringprintf.h" 7#include "chrome/browser/extensions/extension_apitest.h" 8#include "chrome/browser/extensions/extension_service.h" 9#include "chrome/browser/ui/browser.h" 10#include "chrome/common/chrome_paths.h" 11#include "chrome/test/base/in_process_browser_test.h" 12#include "chrome/test/base/ui_test_utils.h" 13#include "extensions/browser/api/dns/host_resolver_wrapper.h" 14#include "extensions/browser/api/dns/mock_host_resolver_creator.h" 15#include "extensions/browser/api/socket/socket_api.h" 16#include "extensions/test/extension_test_message_listener.h" 17#include "extensions/test/result_catcher.h" 18#include "net/dns/mock_host_resolver.h" 19#include "net/test/spawned_test_server/spawned_test_server.h" 20 21using extensions::Extension; 22using extensions::ResultCatcher; 23 24namespace { 25 26const std::string kHostname = "127.0.0.1"; 27const int kPort = 8888; 28 29class SocketApiTest : public ExtensionApiTest { 30 public: 31 SocketApiTest() : resolver_event_(true, false), 32 resolver_creator_( 33 new extensions::MockHostResolverCreator()) { 34 } 35 36 virtual void SetUpOnMainThread() OVERRIDE { 37 extensions::HostResolverWrapper::GetInstance()->SetHostResolverForTesting( 38 resolver_creator_->CreateMockHostResolver()); 39 } 40 41 virtual void TearDownOnMainThread() OVERRIDE { 42 extensions::HostResolverWrapper::GetInstance()-> 43 SetHostResolverForTesting(NULL); 44 resolver_creator_->DeleteMockHostResolver(); 45 } 46 47 private: 48 base::WaitableEvent resolver_event_; 49 50 // The MockHostResolver asserts that it's used on the same thread on which 51 // it's created, which is actually a stronger rule than its real counterpart. 52 // But that's fine; it's good practice. 53 scoped_refptr<extensions::MockHostResolverCreator> resolver_creator_; 54}; 55 56} // namespace 57 58IN_PROC_BROWSER_TEST_F(SocketApiTest, SocketUDPExtension) { 59 scoped_ptr<net::SpawnedTestServer> test_server( 60 new net::SpawnedTestServer( 61 net::SpawnedTestServer::TYPE_UDP_ECHO, 62 net::SpawnedTestServer::kLocalhost, 63 base::FilePath(FILE_PATH_LITERAL("net/data")))); 64 EXPECT_TRUE(test_server->Start()); 65 66 net::HostPortPair host_port_pair = test_server->host_port_pair(); 67 int port = host_port_pair.port(); 68 ASSERT_GT(port, 0); 69 70 // Test that sendTo() is properly resolving hostnames. 71 host_port_pair.set_host("LOCALhost"); 72 73 ResultCatcher catcher; 74 catcher.RestrictToBrowserContext(browser()->profile()); 75 76 ExtensionTestMessageListener listener("info_please", true); 77 78 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("socket/api"))); 79 EXPECT_TRUE(listener.WaitUntilSatisfied()); 80 listener.Reply( 81 base::StringPrintf("udp:%s:%d", host_port_pair.host().c_str(), port)); 82 83 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 84} 85 86IN_PROC_BROWSER_TEST_F(SocketApiTest, SocketTCPExtension) { 87 scoped_ptr<net::SpawnedTestServer> test_server( 88 new net::SpawnedTestServer( 89 net::SpawnedTestServer::TYPE_TCP_ECHO, 90 net::SpawnedTestServer::kLocalhost, 91 base::FilePath(FILE_PATH_LITERAL("net/data")))); 92 EXPECT_TRUE(test_server->Start()); 93 94 net::HostPortPair host_port_pair = test_server->host_port_pair(); 95 int port = host_port_pair.port(); 96 ASSERT_GT(port, 0); 97 98 // Test that connect() is properly resolving hostnames. 99 host_port_pair.set_host("lOcAlHoSt"); 100 101 ResultCatcher catcher; 102 catcher.RestrictToBrowserContext(browser()->profile()); 103 104 ExtensionTestMessageListener listener("info_please", true); 105 106 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("socket/api"))); 107 EXPECT_TRUE(listener.WaitUntilSatisfied()); 108 listener.Reply( 109 base::StringPrintf("tcp:%s:%d", host_port_pair.host().c_str(), port)); 110 111 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 112} 113 114IN_PROC_BROWSER_TEST_F(SocketApiTest, SocketTCPServerExtension) { 115 ResultCatcher catcher; 116 catcher.RestrictToBrowserContext(browser()->profile()); 117 ExtensionTestMessageListener listener("info_please", true); 118 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("socket/api"))); 119 EXPECT_TRUE(listener.WaitUntilSatisfied()); 120 listener.Reply( 121 base::StringPrintf("tcp_server:%s:%d", kHostname.c_str(), kPort)); 122 123 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 124} 125 126IN_PROC_BROWSER_TEST_F(SocketApiTest, SocketTCPServerUnbindOnUnload) { 127 ResultCatcher catcher; 128 const Extension* extension = 129 LoadExtension(test_data_dir_.AppendASCII("socket/unload")); 130 ASSERT_TRUE(extension); 131 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 132 133 UnloadExtension(extension->id()); 134 135 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("socket/unload"))) 136 << message_; 137 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 138} 139 140IN_PROC_BROWSER_TEST_F(SocketApiTest, SocketMulticast) { 141 ResultCatcher catcher; 142 catcher.RestrictToBrowserContext(browser()->profile()); 143 ExtensionTestMessageListener listener("info_please", true); 144 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("socket/api"))); 145 EXPECT_TRUE(listener.WaitUntilSatisfied()); 146 listener.Reply( 147 base::StringPrintf("multicast:%s:%d", kHostname.c_str(), kPort)); 148 149 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); 150} 151