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