Home | History | Annotate | Download | only in socket
      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/path_service.h"
      7 #include "base/strings/stringprintf.h"
      8 #include "chrome/browser/extensions/api/dns/host_resolver_wrapper.h"
      9 #include "chrome/browser/extensions/api/dns/mock_host_resolver_creator.h"
     10 #include "chrome/browser/extensions/api/socket/socket_api.h"
     11 #include "chrome/browser/extensions/extension_apitest.h"
     12 #include "chrome/browser/extensions/extension_function_test_utils.h"
     13 #include "chrome/browser/extensions/extension_service.h"
     14 #include "chrome/browser/extensions/extension_test_message_listener.h"
     15 #include "chrome/browser/ui/browser.h"
     16 #include "chrome/browser/ui/extensions/application_launch.h"
     17 #include "chrome/common/chrome_paths.h"
     18 #include "chrome/test/base/in_process_browser_test.h"
     19 #include "chrome/test/base/ui_test_utils.h"
     20 #include "net/dns/mock_host_resolver.h"
     21 #include "net/test/spawned_test_server/spawned_test_server.h"
     22 
     23 using extensions::Extension;
     24 
     25 namespace utils = extension_function_test_utils;
     26 
     27 namespace {
     28 
     29 // TODO(jschuh): Hanging plugin tests. crbug.com/244653
     30 #if defined(OS_WIN) && defined(ARCH_CPU_X86_64)
     31 #define MAYBE(x) DISABLED_##x
     32 #else
     33 #define MAYBE(x) x
     34 #endif
     35 
     36 const std::string kHostname = "127.0.0.1";
     37 const int kPort = 8888;
     38 
     39 class SocketApiTest : public ExtensionApiTest {
     40  public:
     41   SocketApiTest() : resolver_event_(true, false),
     42                     resolver_creator_(
     43                         new extensions::MockHostResolverCreator()) {
     44   }
     45 
     46   virtual void SetUpOnMainThread() OVERRIDE {
     47     extensions::HostResolverWrapper::GetInstance()->SetHostResolverForTesting(
     48         resolver_creator_->CreateMockHostResolver());
     49   }
     50 
     51   virtual void CleanUpOnMainThread() OVERRIDE {
     52     extensions::HostResolverWrapper::GetInstance()->
     53         SetHostResolverForTesting(NULL);
     54     resolver_creator_->DeleteMockHostResolver();
     55   }
     56 
     57  private:
     58   base::WaitableEvent resolver_event_;
     59 
     60   // The MockHostResolver asserts that it's used on the same thread on which
     61   // it's created, which is actually a stronger rule than its real counterpart.
     62   // But that's fine; it's good practice.
     63   scoped_refptr<extensions::MockHostResolverCreator> resolver_creator_;
     64 };
     65 
     66 #if !defined(DISABLE_NACL)
     67 // TODO(yzshen): Build testing framework for all extensions APIs in Pepper. And
     68 // move these Pepper API tests there.
     69 class SocketPpapiTest : public SocketApiTest {
     70  public:
     71   SocketPpapiTest() {
     72   }
     73   virtual ~SocketPpapiTest() {
     74   }
     75 
     76   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
     77     SocketApiTest::SetUpCommandLine(command_line);
     78     // TODO(yzshen): It is better to use switches::kEnablePepperTesting.
     79     // However, that requires adding a new DEPS entry. Considering that we are
     80     // going to move the Pepper API tests to a new place, use a string literal
     81     // for now.
     82     command_line->AppendSwitch("enable-pepper-testing");
     83 
     84     PathService::Get(chrome::DIR_GEN_TEST_DATA, &app_dir_);
     85     app_dir_ = app_dir_.AppendASCII(
     86         "chrome/test/data/extensions/api_test/socket/ppapi/newlib");
     87   }
     88 
     89  protected:
     90   void LaunchTestingApp() {
     91     const Extension* extension = LoadExtension(app_dir_);
     92     ASSERT_TRUE(extension);
     93 
     94     chrome::AppLaunchParams params(browser()->profile(), extension,
     95                                    extension_misc::LAUNCH_NONE,
     96                                    NEW_WINDOW);
     97     params.command_line = CommandLine::ForCurrentProcess();
     98     chrome::OpenApplication(params);
     99   }
    100 
    101  private:
    102   base::FilePath app_dir_;
    103 };
    104 #endif
    105 
    106 }  // namespace
    107 
    108 IN_PROC_BROWSER_TEST_F(SocketApiTest, SocketUDPCreateGood) {
    109   scoped_refptr<extensions::SocketCreateFunction> socket_create_function(
    110       new extensions::SocketCreateFunction());
    111   scoped_refptr<Extension> empty_extension(utils::CreateEmptyExtension());
    112 
    113   socket_create_function->set_extension(empty_extension.get());
    114   socket_create_function->set_has_callback(true);
    115 
    116   scoped_ptr<base::Value> result(utils::RunFunctionAndReturnSingleResult(
    117       socket_create_function.get(), "[\"udp\"]", browser(), utils::NONE));
    118   ASSERT_EQ(base::Value::TYPE_DICTIONARY, result->GetType());
    119   base::DictionaryValue *value =
    120       static_cast<base::DictionaryValue*>(result.get());
    121   int socketId = -1;
    122   EXPECT_TRUE(value->GetInteger("socketId", &socketId));
    123   EXPECT_TRUE(socketId > 0);
    124 }
    125 
    126 IN_PROC_BROWSER_TEST_F(SocketApiTest, SocketTCPCreateGood) {
    127   scoped_refptr<extensions::SocketCreateFunction> socket_create_function(
    128       new extensions::SocketCreateFunction());
    129   scoped_refptr<Extension> empty_extension(utils::CreateEmptyExtension());
    130 
    131   socket_create_function->set_extension(empty_extension.get());
    132   socket_create_function->set_has_callback(true);
    133 
    134   scoped_ptr<base::Value> result(utils::RunFunctionAndReturnSingleResult(
    135       socket_create_function.get(), "[\"tcp\"]", browser(), utils::NONE));
    136   ASSERT_EQ(base::Value::TYPE_DICTIONARY, result->GetType());
    137   base::DictionaryValue *value =
    138       static_cast<base::DictionaryValue*>(result.get());
    139   int socketId = -1;
    140   EXPECT_TRUE(value->GetInteger("socketId", &socketId));
    141   ASSERT_TRUE(socketId > 0);
    142 }
    143 
    144 IN_PROC_BROWSER_TEST_F(SocketApiTest, GetNetworkList) {
    145   scoped_refptr<extensions::SocketGetNetworkListFunction> socket_function(
    146       new extensions::SocketGetNetworkListFunction());
    147   scoped_refptr<Extension> empty_extension(utils::CreateEmptyExtension());
    148 
    149   socket_function->set_extension(empty_extension.get());
    150   socket_function->set_has_callback(true);
    151 
    152   scoped_ptr<base::Value> result(utils::RunFunctionAndReturnSingleResult(
    153       socket_function.get(), "[]", browser(), utils::NONE));
    154   ASSERT_EQ(base::Value::TYPE_LIST, result->GetType());
    155 
    156   // If we're invoking socket tests, all we can confirm is that we have at
    157   // least one address, but not what it is.
    158   base::ListValue *value = static_cast<base::ListValue*>(result.get());
    159   ASSERT_TRUE(value->GetSize() > 0);
    160 }
    161 
    162 IN_PROC_BROWSER_TEST_F(SocketApiTest, SocketUDPExtension) {
    163   scoped_ptr<net::SpawnedTestServer> test_server(
    164       new net::SpawnedTestServer(
    165           net::SpawnedTestServer::TYPE_UDP_ECHO,
    166           net::SpawnedTestServer::kLocalhost,
    167           base::FilePath(FILE_PATH_LITERAL("net/data"))));
    168   EXPECT_TRUE(test_server->Start());
    169 
    170   net::HostPortPair host_port_pair = test_server->host_port_pair();
    171   int port = host_port_pair.port();
    172   ASSERT_TRUE(port > 0);
    173 
    174   // Test that sendTo() is properly resolving hostnames.
    175   host_port_pair.set_host("LOCALhost");
    176 
    177   ResultCatcher catcher;
    178   catcher.RestrictToProfile(browser()->profile());
    179 
    180   ExtensionTestMessageListener listener("info_please", true);
    181 
    182   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("socket/api")));
    183   EXPECT_TRUE(listener.WaitUntilSatisfied());
    184   listener.Reply(
    185       base::StringPrintf("udp:%s:%d", host_port_pair.host().c_str(), port));
    186 
    187   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    188 }
    189 
    190 IN_PROC_BROWSER_TEST_F(SocketApiTest, SocketTCPExtension) {
    191   scoped_ptr<net::SpawnedTestServer> test_server(
    192       new net::SpawnedTestServer(
    193           net::SpawnedTestServer::TYPE_TCP_ECHO,
    194           net::SpawnedTestServer::kLocalhost,
    195           base::FilePath(FILE_PATH_LITERAL("net/data"))));
    196   EXPECT_TRUE(test_server->Start());
    197 
    198   net::HostPortPair host_port_pair = test_server->host_port_pair();
    199   int port = host_port_pair.port();
    200   ASSERT_TRUE(port > 0);
    201 
    202   // Test that connect() is properly resolving hostnames.
    203   host_port_pair.set_host("lOcAlHoSt");
    204 
    205   ResultCatcher catcher;
    206   catcher.RestrictToProfile(browser()->profile());
    207 
    208   ExtensionTestMessageListener listener("info_please", true);
    209 
    210   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("socket/api")));
    211   EXPECT_TRUE(listener.WaitUntilSatisfied());
    212   listener.Reply(
    213       base::StringPrintf("tcp:%s:%d", host_port_pair.host().c_str(), port));
    214 
    215   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    216 }
    217 
    218 IN_PROC_BROWSER_TEST_F(SocketApiTest, SocketTCPServerExtension) {
    219   ResultCatcher catcher;
    220   catcher.RestrictToProfile(browser()->profile());
    221   ExtensionTestMessageListener listener("info_please", true);
    222   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("socket/api")));
    223   EXPECT_TRUE(listener.WaitUntilSatisfied());
    224   listener.Reply(
    225       base::StringPrintf("tcp_server:%s:%d", kHostname.c_str(), kPort));
    226 
    227   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    228 }
    229 
    230 IN_PROC_BROWSER_TEST_F(SocketApiTest, SocketTCPServerUnbindOnUnload) {
    231   ResultCatcher catcher;
    232   const Extension* extension =
    233       LoadExtension(test_data_dir_.AppendASCII("socket/unload"));
    234   ASSERT_TRUE(extension);
    235   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    236 
    237   UnloadExtension(extension->id());
    238 
    239   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("socket/unload")))
    240       << message_;
    241   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    242 }
    243 
    244 IN_PROC_BROWSER_TEST_F(SocketApiTest, SocketMulticast) {
    245   ResultCatcher catcher;
    246   catcher.RestrictToProfile(browser()->profile());
    247   ExtensionTestMessageListener listener("info_please", true);
    248   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("socket/api")));
    249   EXPECT_TRUE(listener.WaitUntilSatisfied());
    250   listener.Reply(
    251       base::StringPrintf("multicast:%s:%d", kHostname.c_str(), kPort));
    252 
    253   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    254 }
    255 
    256 #if !defined(DISABLE_NACL)
    257 IN_PROC_BROWSER_TEST_F(SocketPpapiTest, MAYBE(UDP)) {
    258   scoped_ptr<net::SpawnedTestServer> test_server(
    259       new net::SpawnedTestServer(
    260           net::SpawnedTestServer::TYPE_UDP_ECHO,
    261           net::SpawnedTestServer::kLocalhost,
    262           base::FilePath(FILE_PATH_LITERAL("net/data"))));
    263   EXPECT_TRUE(test_server->Start());
    264 
    265   net::HostPortPair host_port_pair = test_server->host_port_pair();
    266   int port = host_port_pair.port();
    267   ASSERT_TRUE(port > 0);
    268 
    269   // Test that sendTo() is properly resolving hostnames.
    270   host_port_pair.set_host("LOCALhost");
    271 
    272   ResultCatcher catcher;
    273   catcher.RestrictToProfile(browser()->profile());
    274 
    275   ExtensionTestMessageListener listener("info_please", true);
    276 
    277   LaunchTestingApp();
    278 
    279   EXPECT_TRUE(listener.WaitUntilSatisfied());
    280   listener.Reply(
    281       base::StringPrintf("udp:%s:%d", host_port_pair.host().c_str(), port));
    282 
    283   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    284 }
    285 
    286 IN_PROC_BROWSER_TEST_F(SocketPpapiTest, MAYBE(TCP)) {
    287   scoped_ptr<net::SpawnedTestServer> test_server(
    288       new net::SpawnedTestServer(
    289           net::SpawnedTestServer::TYPE_TCP_ECHO,
    290           net::SpawnedTestServer::kLocalhost,
    291           base::FilePath(FILE_PATH_LITERAL("net/data"))));
    292   EXPECT_TRUE(test_server->Start());
    293 
    294   net::HostPortPair host_port_pair = test_server->host_port_pair();
    295   int port = host_port_pair.port();
    296   ASSERT_TRUE(port > 0);
    297 
    298   // Test that connect() is properly resolving hostnames.
    299   host_port_pair.set_host("lOcAlHoSt");
    300 
    301   ResultCatcher catcher;
    302   catcher.RestrictToProfile(browser()->profile());
    303 
    304   ExtensionTestMessageListener listener("info_please", true);
    305 
    306   LaunchTestingApp();
    307 
    308   EXPECT_TRUE(listener.WaitUntilSatisfied());
    309   listener.Reply(
    310       base::StringPrintf("tcp:%s:%d", host_port_pair.host().c_str(), port));
    311 
    312   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    313 }
    314 
    315 IN_PROC_BROWSER_TEST_F(SocketPpapiTest, MAYBE(TCPServer)) {
    316   ResultCatcher catcher;
    317   catcher.RestrictToProfile(browser()->profile());
    318   ExtensionTestMessageListener listener("info_please", true);
    319 
    320   LaunchTestingApp();
    321 
    322   EXPECT_TRUE(listener.WaitUntilSatisfied());
    323   listener.Reply(
    324       base::StringPrintf("tcp_server:%s:%d", kHostname.c_str(), kPort));
    325 
    326   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    327 }
    328 
    329 IN_PROC_BROWSER_TEST_F(SocketPpapiTest, MAYBE(Multicast)) {
    330   ResultCatcher catcher;
    331   catcher.RestrictToProfile(browser()->profile());
    332   ExtensionTestMessageListener listener("info_please", true);
    333 
    334   LaunchTestingApp();
    335 
    336   EXPECT_TRUE(listener.WaitUntilSatisfied());
    337   listener.Reply(
    338       base::StringPrintf("multicast:%s:%d", kHostname.c_str(), kPort));
    339 
    340   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    341 }
    342 #endif
    343