123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- // Copyright (c) 2012 The Chromium 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 <cstring>
- #include <vector>
- #include "ppapi/cpp/module.h"
- #include "ppapi/cpp/private/net_address_private.h"
- #include "ppapi/cpp/private/tcp_socket_private.h"
- #include "ppapi/cpp/var.h"
- #include "ppapi/tests/test_udp_socket_private.h"
- #include "ppapi/tests/test_utils.h"
- #include "ppapi/tests/testing_instance.h"
- REGISTER_TEST_CASE(UDPSocketPrivate);
- namespace {
- const uint16_t kPortScanFrom = 1024;
- const uint16_t kPortScanTo = 4096;
- } // namespace
- TestUDPSocketPrivate::TestUDPSocketPrivate(
- TestingInstance* instance)
- : TestCase(instance) {
- }
- bool TestUDPSocketPrivate::Init() {
- bool tcp_socket_private_is_available = pp::TCPSocketPrivate::IsAvailable();
- if (!tcp_socket_private_is_available)
- instance_->AppendError("PPB_TCPSocket_Private interface not available");
- bool udp_socket_private_is_available = pp::UDPSocketPrivate::IsAvailable();
- if (!udp_socket_private_is_available)
- instance_->AppendError("PPB_UDPSocket_Private interface not available");
- bool net_address_private_is_available = pp::NetAddressPrivate::IsAvailable();
- if (!net_address_private_is_available)
- instance_->AppendError("PPB_NetAddress_Private interface not available");
- bool init_host_port = GetLocalHostPort(instance_->pp_instance(),
- &host_, &port_);
- if (!init_host_port)
- instance_->AppendError("Can't init host and port");
- return tcp_socket_private_is_available &&
- udp_socket_private_is_available &&
- net_address_private_is_available &&
- init_host_port &&
- CheckTestingInterface() &&
- EnsureRunningOverHTTP();
- }
- void TestUDPSocketPrivate::RunTests(const std::string& filter) {
- RUN_CALLBACK_TEST(TestUDPSocketPrivate, Connect, filter);
- RUN_CALLBACK_TEST(TestUDPSocketPrivate, ConnectFailure, filter);
- RUN_CALLBACK_TEST(TestUDPSocketPrivate, Broadcast, filter);
- RUN_CALLBACK_TEST(TestUDPSocketPrivate, SetSocketFeatureErrors, filter);
- }
- std::string TestUDPSocketPrivate::GetLocalAddress(
- PP_NetAddress_Private* address) {
- pp::TCPSocketPrivate socket(instance_);
- TestCompletionCallback callback(instance_->pp_instance(), callback_type());
- callback.WaitForResult(
- socket.Connect(host_.c_str(), port_, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- ASSERT_TRUE(socket.GetLocalAddress(address));
- socket.Disconnect();
- PASS();
- }
- std::string TestUDPSocketPrivate::SetBroadcastOptions(
- pp::UDPSocketPrivate* socket) {
- int32_t rv = socket->SetSocketFeature(
- PP_UDPSOCKETFEATURE_PRIVATE_ADDRESS_REUSE, pp::Var(true));
- if (rv != PP_OK)
- return ReportError("PPB_UDPSocket_Private::SetSocketFeature", rv);
- rv = socket->SetSocketFeature(PP_UDPSOCKETFEATURE_PRIVATE_BROADCAST,
- pp::Var(true));
- if (rv != PP_OK)
- return ReportError("PPB_UDPSocket_Private::SetSocketFeature", rv);
- PASS();
- }
- std::string TestUDPSocketPrivate::BindUDPSocket(
- pp::UDPSocketPrivate* socket,
- PP_NetAddress_Private* address) {
- TestCompletionCallback callback(instance_->pp_instance(), callback_type());
- callback.WaitForResult(socket->Bind(address, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_EQ(PP_OK, callback.result());
- PASS();
- }
- std::string TestUDPSocketPrivate::LookupPortAndBindUDPSocket(
- pp::UDPSocketPrivate* socket,
- PP_NetAddress_Private *address) {
- PP_NetAddress_Private base_address;
- ASSERT_SUBTEST_SUCCESS(GetLocalAddress(&base_address));
- bool is_free_port_found = false;
- for (uint16_t port = kPortScanFrom; port < kPortScanTo; ++port) {
- if (!pp::NetAddressPrivate::ReplacePort(base_address, port, address))
- return "PPB_NetAddress_Private::ReplacePort: Failed";
- if (BindUDPSocket(socket, address).empty()) {
- is_free_port_found = true;
- break;
- }
- }
- if (!is_free_port_found)
- return "Can't find available port";
- if (!socket->GetBoundAddress(address))
- return "PPB_UDPSocket_Private::GetBoundAddress: Failed";
- PASS();
- }
- std::string TestUDPSocketPrivate::BindUDPSocketFailure(
- pp::UDPSocketPrivate* socket,
- PP_NetAddress_Private *address) {
- TestCompletionCallback callback(instance_->pp_instance(), callback_type());
- callback.WaitForResult(socket->Bind(address, callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_NE(PP_OK, callback.result());
- ASSERT_FALSE(socket->GetBoundAddress(address));
- PASS();
- }
- std::string TestUDPSocketPrivate::ReadSocket(pp::UDPSocketPrivate* socket,
- PP_NetAddress_Private* address,
- size_t size,
- std::string* message) {
- std::vector<char> buffer(size);
- TestCompletionCallback callback(instance_->pp_instance(), callback_type());
- callback.WaitForResult(
- socket->RecvFrom(&buffer[0], static_cast<int32_t>(size),
- callback.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_FALSE(callback.result() < 0);
- ASSERT_EQ(size, static_cast<size_t>(callback.result()));
- message->assign(buffer.begin(), buffer.end());
- PASS();
- }
- std::string TestUDPSocketPrivate::PassMessage(pp::UDPSocketPrivate* target,
- pp::UDPSocketPrivate* source,
- PP_NetAddress_Private* address,
- const std::string& message) {
- TestCompletionCallback callback(instance_->pp_instance(), callback_type());
- int32_t rv = source->SendTo(message.c_str(),
- static_cast<int32_t>(message.size()), address,
- callback.GetCallback());
- std::string str;
- ASSERT_SUBTEST_SUCCESS(ReadSocket(target, address, message.size(), &str));
- callback.WaitForResult(rv);
- CHECK_CALLBACK_BEHAVIOR(callback);
- ASSERT_FALSE(callback.result() < 0);
- ASSERT_EQ(message.size(), static_cast<size_t>(callback.result()));
- ASSERT_EQ(message, str);
- PASS();
- }
- std::string TestUDPSocketPrivate::TestConnect() {
- pp::UDPSocketPrivate server_socket(instance_), client_socket(instance_);
- PP_NetAddress_Private server_address, client_address;
- ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&server_socket,
- &server_address));
- ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&client_socket,
- &client_address));
- const std::string message = "Simple message that will be sent via UDP";
- ASSERT_SUBTEST_SUCCESS(PassMessage(&server_socket, &client_socket,
- &server_address,
- message));
- PP_NetAddress_Private recv_from_address;
- ASSERT_TRUE(server_socket.GetRecvFromAddress(&recv_from_address));
- ASSERT_TRUE(pp::NetAddressPrivate::AreEqual(recv_from_address,
- client_address));
- server_socket.Close();
- client_socket.Close();
- if (server_socket.GetBoundAddress(&server_address))
- return "PPB_UDPSocket_Private::GetBoundAddress: expected Failure";
- PASS();
- }
- std::string TestUDPSocketPrivate::TestConnectFailure() {
- pp::UDPSocketPrivate socket(instance_);
- PP_NetAddress_Private invalid_address = {};
- std::string error_message = BindUDPSocketFailure(&socket, &invalid_address);
- if (!error_message.empty())
- return error_message;
- PASS();
- }
- std::string TestUDPSocketPrivate::TestBroadcast() {
- const uint8_t broadcast_ip[4] = { 0xff, 0xff, 0xff, 0xff };
- pp::UDPSocketPrivate server1(instance_), server2(instance_);
- ASSERT_SUBTEST_SUCCESS(SetBroadcastOptions(&server1));
- ASSERT_SUBTEST_SUCCESS(SetBroadcastOptions(&server2));
- PP_NetAddress_Private server_address;
- ASSERT_TRUE(pp::NetAddressPrivate::GetAnyAddress(false, &server_address));
- ASSERT_SUBTEST_SUCCESS(BindUDPSocket(&server1, &server_address));
- // Fill port field of |server_address|.
- ASSERT_TRUE(server1.GetBoundAddress(&server_address));
- ASSERT_SUBTEST_SUCCESS(BindUDPSocket(&server2, &server_address));
- const uint16_t port = pp::NetAddressPrivate::GetPort(server_address);
- PP_NetAddress_Private broadcast_address;
- ASSERT_TRUE(pp::NetAddressPrivate::CreateFromIPv4Address(
- broadcast_ip, port, &broadcast_address));
- std::string message;
- const std::string first_message = "first message";
- const std::string second_message = "second_message";
- ASSERT_SUBTEST_SUCCESS(PassMessage(&server1, &server2,
- &broadcast_address,
- first_message));
- // |first_message| also arrived to |server2|.
- ASSERT_SUBTEST_SUCCESS(ReadSocket(&server2, &broadcast_address,
- first_message.size(), &message));
- ASSERT_EQ(first_message, message);
- ASSERT_SUBTEST_SUCCESS(PassMessage(&server2, &server1,
- &broadcast_address,
- second_message));
- // |second_message| also arrived to |server1|.
- ASSERT_SUBTEST_SUCCESS(ReadSocket(&server1, &broadcast_address,
- second_message.size(), &message));
- ASSERT_EQ(second_message, message);
- server1.Close();
- server2.Close();
- PASS();
- }
- std::string TestUDPSocketPrivate::TestSetSocketFeatureErrors() {
- pp::UDPSocketPrivate socket(instance_);
- // Try to pass incorrect feature name.
- int32_t rv = socket.SetSocketFeature(PP_UDPSOCKETFEATURE_PRIVATE_COUNT,
- pp::Var(true));
- ASSERT_EQ(PP_ERROR_BADARGUMENT, rv);
- // Try to pass incorrect feature value's type.
- rv = socket.SetSocketFeature(PP_UDPSOCKETFEATURE_PRIVATE_ADDRESS_REUSE,
- pp::Var(1));
- ASSERT_EQ(PP_ERROR_BADARGUMENT, rv);
- PASS();
- }
|