Home | History | Annotate | Download | only in tests
      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 <cstring>
      6 #include <vector>
      7 
      8 #include "ppapi/cpp/module.h"
      9 #include "ppapi/cpp/private/net_address_private.h"
     10 #include "ppapi/cpp/private/tcp_socket_private.h"
     11 #include "ppapi/cpp/var.h"
     12 #include "ppapi/tests/test_udp_socket_private.h"
     13 #include "ppapi/tests/test_utils.h"
     14 #include "ppapi/tests/testing_instance.h"
     15 
     16 REGISTER_TEST_CASE(UDPSocketPrivate);
     17 
     18 namespace {
     19 
     20 const uint16_t kPortScanFrom = 1024;
     21 const uint16_t kPortScanTo = 4096;
     22 
     23 }  // namespace
     24 
     25 TestUDPSocketPrivate::TestUDPSocketPrivate(
     26     TestingInstance* instance)
     27     : TestCase(instance) {
     28 }
     29 
     30 bool TestUDPSocketPrivate::Init() {
     31   bool tcp_socket_private_is_available = pp::TCPSocketPrivate::IsAvailable();
     32   if (!tcp_socket_private_is_available)
     33     instance_->AppendError("PPB_TCPSocket_Private interface not available");
     34 
     35   bool udp_socket_private_is_available = pp::UDPSocketPrivate::IsAvailable();
     36   if (!udp_socket_private_is_available)
     37     instance_->AppendError("PPB_UDPSocket_Private interface not available");
     38 
     39   bool net_address_private_is_available = pp::NetAddressPrivate::IsAvailable();
     40   if (!net_address_private_is_available)
     41     instance_->AppendError("PPB_NetAddress_Private interface not available");
     42 
     43   bool init_host_port = GetLocalHostPort(instance_->pp_instance(),
     44                                          &host_, &port_);
     45   if (!init_host_port)
     46     instance_->AppendError("Can't init host and port");
     47 
     48   return tcp_socket_private_is_available &&
     49       udp_socket_private_is_available &&
     50       net_address_private_is_available &&
     51       init_host_port &&
     52       CheckTestingInterface() &&
     53       EnsureRunningOverHTTP();
     54 }
     55 
     56 void TestUDPSocketPrivate::RunTests(const std::string& filter) {
     57   RUN_CALLBACK_TEST(TestUDPSocketPrivate, Connect, filter);
     58   RUN_CALLBACK_TEST(TestUDPSocketPrivate, ConnectFailure, filter);
     59   RUN_CALLBACK_TEST(TestUDPSocketPrivate, Broadcast, filter);
     60   RUN_CALLBACK_TEST(TestUDPSocketPrivate, SetSocketFeatureErrors, filter);
     61 }
     62 
     63 std::string TestUDPSocketPrivate::GetLocalAddress(
     64     PP_NetAddress_Private* address) {
     65   pp::TCPSocketPrivate socket(instance_);
     66   TestCompletionCallback callback(instance_->pp_instance(), callback_type());
     67   callback.WaitForResult(
     68       socket.Connect(host_.c_str(), port_, callback.GetCallback()));
     69   CHECK_CALLBACK_BEHAVIOR(callback);
     70   ASSERT_EQ(PP_OK, callback.result());
     71   ASSERT_TRUE(socket.GetLocalAddress(address));
     72   socket.Disconnect();
     73   PASS();
     74 }
     75 
     76 std::string TestUDPSocketPrivate::SetBroadcastOptions(
     77     pp::UDPSocketPrivate* socket) {
     78   int32_t rv = socket->SetSocketFeature(
     79       PP_UDPSOCKETFEATURE_PRIVATE_ADDRESS_REUSE, pp::Var(true));
     80   if (rv != PP_OK)
     81     return ReportError("PPB_UDPSocket_Private::SetSocketFeature", rv);
     82 
     83   rv = socket->SetSocketFeature(PP_UDPSOCKETFEATURE_PRIVATE_BROADCAST,
     84                                 pp::Var(true));
     85   if (rv != PP_OK)
     86     return ReportError("PPB_UDPSocket_Private::SetSocketFeature", rv);
     87 
     88   PASS();
     89 }
     90 
     91 std::string TestUDPSocketPrivate::BindUDPSocket(
     92     pp::UDPSocketPrivate* socket,
     93     PP_NetAddress_Private* address) {
     94   TestCompletionCallback callback(instance_->pp_instance(), callback_type());
     95   callback.WaitForResult(socket->Bind(address, callback.GetCallback()));
     96   CHECK_CALLBACK_BEHAVIOR(callback);
     97   ASSERT_EQ(PP_OK, callback.result());
     98   PASS();
     99 }
    100 
    101 std::string TestUDPSocketPrivate::LookupPortAndBindUDPSocket(
    102     pp::UDPSocketPrivate* socket,
    103     PP_NetAddress_Private *address) {
    104   PP_NetAddress_Private base_address;
    105   ASSERT_SUBTEST_SUCCESS(GetLocalAddress(&base_address));
    106 
    107   bool is_free_port_found = false;
    108   for (uint16_t port = kPortScanFrom; port < kPortScanTo; ++port) {
    109     if (!pp::NetAddressPrivate::ReplacePort(base_address, port, address))
    110       return "PPB_NetAddress_Private::ReplacePort: Failed";
    111     if (BindUDPSocket(socket, address).empty()) {
    112       is_free_port_found = true;
    113       break;
    114     }
    115   }
    116   if (!is_free_port_found)
    117     return "Can't find available port";
    118   if (!socket->GetBoundAddress(address))
    119     return "PPB_UDPSocket_Private::GetBoundAddress: Failed";
    120   PASS();
    121 }
    122 
    123 std::string TestUDPSocketPrivate::BindUDPSocketFailure(
    124     pp::UDPSocketPrivate* socket,
    125     PP_NetAddress_Private *address) {
    126   TestCompletionCallback callback(instance_->pp_instance(), callback_type());
    127   callback.WaitForResult(socket->Bind(address, callback.GetCallback()));
    128   CHECK_CALLBACK_BEHAVIOR(callback);
    129   ASSERT_NE(PP_OK, callback.result());
    130   ASSERT_FALSE(socket->GetBoundAddress(address));
    131   PASS();
    132 }
    133 
    134 std::string TestUDPSocketPrivate::ReadSocket(pp::UDPSocketPrivate* socket,
    135                                              PP_NetAddress_Private* address,
    136                                              size_t size,
    137                                              std::string* message) {
    138   std::vector<char> buffer(size);
    139   TestCompletionCallback callback(instance_->pp_instance(), callback_type());
    140   callback.WaitForResult(
    141       socket->RecvFrom(&buffer[0], size, callback.GetCallback()));
    142   CHECK_CALLBACK_BEHAVIOR(callback);
    143   ASSERT_FALSE(callback.result() < 0);
    144   ASSERT_EQ(size, static_cast<size_t>(callback.result()));
    145   message->assign(buffer.begin(), buffer.end());
    146   PASS();
    147 }
    148 
    149 std::string TestUDPSocketPrivate::PassMessage(pp::UDPSocketPrivate* target,
    150                                               pp::UDPSocketPrivate* source,
    151                                               PP_NetAddress_Private* address,
    152                                               const std::string& message) {
    153   TestCompletionCallback callback(instance_->pp_instance(), callback_type());
    154   int32_t rv = source->SendTo(message.c_str(), message.size(), address,
    155                               callback.GetCallback());
    156   std::string str;
    157   ASSERT_SUBTEST_SUCCESS(ReadSocket(target, address, message.size(), &str));
    158 
    159   callback.WaitForResult(rv);
    160   CHECK_CALLBACK_BEHAVIOR(callback);
    161   ASSERT_FALSE(callback.result() < 0);
    162   ASSERT_EQ(message.size(), static_cast<size_t>(callback.result()));
    163   ASSERT_EQ(message, str);
    164   PASS();
    165 }
    166 
    167 std::string TestUDPSocketPrivate::TestConnect() {
    168   pp::UDPSocketPrivate server_socket(instance_), client_socket(instance_);
    169   PP_NetAddress_Private server_address, client_address;
    170 
    171   ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&server_socket,
    172                                                     &server_address));
    173   ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&client_socket,
    174                                                     &client_address));
    175   const std::string message = "Simple message that will be sent via UDP";
    176   ASSERT_SUBTEST_SUCCESS(PassMessage(&server_socket, &client_socket,
    177                                      &server_address,
    178                                      message));
    179   PP_NetAddress_Private recv_from_address;
    180   ASSERT_TRUE(server_socket.GetRecvFromAddress(&recv_from_address));
    181   ASSERT_TRUE(pp::NetAddressPrivate::AreEqual(recv_from_address,
    182                                               client_address));
    183 
    184   server_socket.Close();
    185   client_socket.Close();
    186 
    187   if (server_socket.GetBoundAddress(&server_address))
    188     return "PPB_UDPSocket_Private::GetBoundAddress: expected Failure";
    189   PASS();
    190 }
    191 
    192 std::string TestUDPSocketPrivate::TestConnectFailure() {
    193   pp::UDPSocketPrivate socket(instance_);
    194   PP_NetAddress_Private invalid_address = {};
    195 
    196   std::string error_message = BindUDPSocketFailure(&socket, &invalid_address);
    197   if (!error_message.empty())
    198     return error_message;
    199 
    200   PASS();
    201 }
    202 
    203 std::string TestUDPSocketPrivate::TestBroadcast() {
    204   const uint8_t broadcast_ip[4] = { 0xff, 0xff, 0xff, 0xff };
    205 
    206   pp::UDPSocketPrivate server1(instance_), server2(instance_);
    207 
    208   ASSERT_SUBTEST_SUCCESS(SetBroadcastOptions(&server1));
    209   ASSERT_SUBTEST_SUCCESS(SetBroadcastOptions(&server2));
    210   PP_NetAddress_Private server_address;
    211   ASSERT_TRUE(pp::NetAddressPrivate::GetAnyAddress(false, &server_address));
    212   ASSERT_SUBTEST_SUCCESS(BindUDPSocket(&server1, &server_address));
    213   // Fill port field of |server_address|.
    214   ASSERT_TRUE(server1.GetBoundAddress(&server_address));
    215   ASSERT_SUBTEST_SUCCESS(BindUDPSocket(&server2, &server_address));
    216 
    217   const uint16_t port = pp::NetAddressPrivate::GetPort(server_address);
    218   PP_NetAddress_Private broadcast_address;
    219   ASSERT_TRUE(pp::NetAddressPrivate::CreateFromIPv4Address(
    220       broadcast_ip, port, &broadcast_address));
    221 
    222   std::string message;
    223   const std::string first_message = "first message";
    224   const std::string second_message = "second_message";
    225 
    226   ASSERT_SUBTEST_SUCCESS(PassMessage(&server1, &server2,
    227                                      &broadcast_address,
    228                                      first_message));
    229   // |first_message| also arrived to |server2|.
    230   ASSERT_SUBTEST_SUCCESS(ReadSocket(&server2, &broadcast_address,
    231                                     first_message.size(), &message));
    232   ASSERT_EQ(first_message, message);
    233 
    234   ASSERT_SUBTEST_SUCCESS(PassMessage(&server2, &server1,
    235                                      &broadcast_address,
    236                                      second_message));
    237   // |second_message| also arrived to |server1|.
    238   ASSERT_SUBTEST_SUCCESS(ReadSocket(&server1, &broadcast_address,
    239                                     second_message.size(), &message));
    240   ASSERT_EQ(second_message, message);
    241 
    242   server1.Close();
    243   server2.Close();
    244   PASS();
    245 }
    246 
    247 std::string TestUDPSocketPrivate::TestSetSocketFeatureErrors() {
    248   pp::UDPSocketPrivate socket(instance_);
    249   // Try to pass incorrect feature name.
    250   int32_t rv = socket.SetSocketFeature(PP_UDPSOCKETFEATURE_PRIVATE_COUNT,
    251                                        pp::Var(true));
    252   ASSERT_EQ(PP_ERROR_BADARGUMENT, rv);
    253 
    254   // Try to pass incorrect feature value's type.
    255   rv = socket.SetSocketFeature(PP_UDPSOCKETFEATURE_PRIVATE_ADDRESS_REUSE,
    256                                pp::Var(1));
    257   ASSERT_EQ(PP_ERROR_BADARGUMENT, rv);
    258   PASS();
    259 }
    260