test_tcp_server_socket_private.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  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. #include "ppapi/tests/test_tcp_server_socket_private.h"
  5. #include <cstdio>
  6. #include <vector>
  7. #include "ppapi/cpp/pass_ref.h"
  8. #include "ppapi/cpp/private/net_address_private.h"
  9. #include "ppapi/cpp/private/tcp_server_socket_private.h"
  10. #include "ppapi/cpp/private/tcp_socket_private.h"
  11. #include "ppapi/tests/test_utils.h"
  12. #include "ppapi/tests/testing_instance.h"
  13. using pp::NetAddressPrivate;
  14. using pp::TCPServerSocketPrivate;
  15. using pp::TCPSocketPrivate;
  16. namespace {
  17. // Used by pp::CompletionCallbacks that want to delete a PP_Resource, passed as
  18. // |user_data|, on completion.
  19. void DeleteResource(void* user_data, int32_t flags) {
  20. delete reinterpret_cast<PP_Resource*>(user_data);
  21. }
  22. } // namespace
  23. REGISTER_TEST_CASE(TCPServerSocketPrivate);
  24. TestTCPServerSocketPrivate::TestTCPServerSocketPrivate(
  25. TestingInstance* instance) : TestCase(instance) {
  26. }
  27. bool TestTCPServerSocketPrivate::Init() {
  28. bool tcp_server_socket_private_is_available =
  29. TCPServerSocketPrivate::IsAvailable();
  30. if (!tcp_server_socket_private_is_available) {
  31. instance_->AppendError(
  32. "PPB_TCPServerSocket_Private interface not available");
  33. }
  34. bool tcp_socket_private_is_available = TCPSocketPrivate::IsAvailable();
  35. if (!tcp_socket_private_is_available)
  36. instance_->AppendError("PPB_TCPSocket_Private interface not available");
  37. bool net_address_private_is_available = NetAddressPrivate::IsAvailable();
  38. if (!net_address_private_is_available)
  39. instance_->AppendError("PPB_NetAddress_Private interface not available");
  40. bool init_host_port = GetLocalHostPort(instance_->pp_instance(),
  41. &host_, &port_);
  42. if (!init_host_port)
  43. instance_->AppendError("Can't init host and port");
  44. return tcp_server_socket_private_is_available &&
  45. tcp_socket_private_is_available &&
  46. net_address_private_is_available &&
  47. init_host_port &&
  48. CheckTestingInterface() &&
  49. EnsureRunningOverHTTP();
  50. }
  51. void TestTCPServerSocketPrivate::RunTests(const std::string& filter) {
  52. RUN_CALLBACK_TEST(TestTCPServerSocketPrivate, Listen, filter);
  53. RUN_CALLBACK_TEST(TestTCPServerSocketPrivate, Backlog, filter);
  54. RUN_CALLBACK_TEST(TestTCPServerSocketPrivate, ListenFails, filter);
  55. RUN_CALLBACK_TEST(TestTCPServerSocketPrivate, ListenHangs, filter);
  56. RUN_CALLBACK_TEST(TestTCPServerSocketPrivate, AcceptFails, filter);
  57. RUN_CALLBACK_TEST(TestTCPServerSocketPrivate, AcceptHangs, filter);
  58. }
  59. std::string TestTCPServerSocketPrivate::GetLocalAddress(
  60. PP_NetAddress_Private* address) {
  61. TCPSocketPrivate socket(instance_);
  62. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  63. callback.WaitForResult(
  64. socket.Connect(host_.c_str(), port_, callback.GetCallback()));
  65. CHECK_CALLBACK_BEHAVIOR(callback);
  66. ASSERT_EQ(PP_OK, callback.result());
  67. ASSERT_TRUE(socket.GetLocalAddress(address));
  68. socket.Disconnect();
  69. PASS();
  70. }
  71. std::string TestTCPServerSocketPrivate::SyncRead(TCPSocketPrivate* socket,
  72. char* buffer,
  73. size_t num_bytes) {
  74. while (num_bytes > 0) {
  75. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  76. callback.WaitForResult(
  77. socket->Read(buffer, static_cast<int32_t>(num_bytes),
  78. callback.GetCallback()));
  79. CHECK_CALLBACK_BEHAVIOR(callback);
  80. ASSERT_TRUE(callback.result() >= 0);
  81. buffer += callback.result();
  82. num_bytes -= callback.result();
  83. }
  84. PASS();
  85. }
  86. std::string TestTCPServerSocketPrivate::SyncWrite(TCPSocketPrivate* socket,
  87. const char* buffer,
  88. size_t num_bytes) {
  89. while (num_bytes > 0) {
  90. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  91. callback.WaitForResult(
  92. socket->Write(buffer, static_cast<int32_t>(num_bytes),
  93. callback.GetCallback()));
  94. CHECK_CALLBACK_BEHAVIOR(callback);
  95. ASSERT_TRUE(callback.result() >= 0);
  96. buffer += callback.result();
  97. num_bytes -= callback.result();
  98. }
  99. PASS();
  100. }
  101. std::string TestTCPServerSocketPrivate::SyncConnect(
  102. TCPSocketPrivate* socket,
  103. PP_NetAddress_Private* address) {
  104. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  105. callback.WaitForResult(
  106. socket->ConnectWithNetAddress(address, callback.GetCallback()));
  107. CHECK_CALLBACK_BEHAVIOR(callback);
  108. ASSERT_EQ(PP_OK, callback.result());
  109. PASS();
  110. }
  111. void TestTCPServerSocketPrivate::ForceConnect(TCPSocketPrivate* socket,
  112. PP_NetAddress_Private* address) {
  113. std::string error_message;
  114. do {
  115. error_message = SyncConnect(socket, address);
  116. } while (!error_message.empty());
  117. }
  118. std::string TestTCPServerSocketPrivate::SyncListenFails(
  119. pp::TCPServerSocketPrivate* socket) {
  120. uint8_t localhost_ip[4] = {127, 0, 0, 1};
  121. PP_NetAddress_Private ipv4;
  122. ASSERT_TRUE(
  123. NetAddressPrivate::CreateFromIPv4Address(localhost_ip, 80, &ipv4));
  124. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  125. callback.WaitForResult(
  126. socket->Listen(&ipv4, 2 /* backlog */, callback.GetCallback()));
  127. CHECK_CALLBACK_BEHAVIOR(callback);
  128. ASSERT_EQ(PP_ERROR_FAILED, callback.result());
  129. PASS();
  130. }
  131. std::string TestTCPServerSocketPrivate::SyncAcceptFails(
  132. pp::TCPServerSocketPrivate* socket) {
  133. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  134. PP_Resource resource;
  135. callback.WaitForResult(socket->Accept(&resource, callback.GetCallback()));
  136. CHECK_CALLBACK_BEHAVIOR(callback);
  137. ASSERT_EQ(PP_ERROR_FAILED, callback.result());
  138. PASS();
  139. }
  140. std::string TestTCPServerSocketPrivate::SyncListen(
  141. TCPServerSocketPrivate* socket,
  142. PP_NetAddress_Private* address,
  143. int32_t backlog) {
  144. PP_NetAddress_Private base_address;
  145. ASSERT_SUBTEST_SUCCESS(GetLocalAddress(&base_address));
  146. if (!NetAddressPrivate::ReplacePort(base_address, 0, address))
  147. return ReportError("PPB_NetAddress_Private::ReplacePort", 0);
  148. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  149. callback.WaitForResult(
  150. socket->Listen(address, backlog, callback.GetCallback()));
  151. CHECK_CALLBACK_BEHAVIOR(callback);
  152. ASSERT_EQ(PP_OK, callback.result());
  153. int32_t rv = socket->GetLocalAddress(address);
  154. ASSERT_EQ(PP_OK, rv);
  155. ASSERT_TRUE(NetAddressPrivate::GetPort(*address) != 0);
  156. PASS();
  157. }
  158. std::string TestTCPServerSocketPrivate::TestListen() {
  159. static const int kBacklog = 2;
  160. TCPServerSocketPrivate server_socket(instance_);
  161. PP_NetAddress_Private address;
  162. ASSERT_SUBTEST_SUCCESS(SyncListen(&server_socket, &address, kBacklog));
  163. // We can't use a blocking callback for Accept, because it will wait forever
  164. // for the client to connect, since the client connects after.
  165. TestCompletionCallback accept_callback(instance_->pp_instance(), PP_REQUIRED);
  166. // We need to make sure there's a message loop to run accept_callback on.
  167. pp::MessageLoop current_thread_loop(pp::MessageLoop::GetCurrent());
  168. if (current_thread_loop.is_null() && testing_interface_->IsOutOfProcess()) {
  169. current_thread_loop = pp::MessageLoop(instance_);
  170. current_thread_loop.AttachToCurrentThread();
  171. }
  172. PP_Resource resource;
  173. int32_t accept_rv = server_socket.Accept(&resource,
  174. accept_callback.GetCallback());
  175. TCPSocketPrivate client_socket(instance_);
  176. ForceConnect(&client_socket, &address);
  177. PP_NetAddress_Private client_local_addr, client_remote_addr;
  178. ASSERT_TRUE(client_socket.GetLocalAddress(&client_local_addr));
  179. ASSERT_TRUE(client_socket.GetRemoteAddress(&client_remote_addr));
  180. accept_callback.WaitForResult(accept_rv);
  181. CHECK_CALLBACK_BEHAVIOR(accept_callback);
  182. ASSERT_EQ(PP_OK, accept_callback.result());
  183. ASSERT_TRUE(resource != 0);
  184. TCPSocketPrivate accepted_socket(pp::PassRef(), resource);
  185. PP_NetAddress_Private accepted_local_addr, accepted_remote_addr;
  186. ASSERT_TRUE(accepted_socket.GetLocalAddress(&accepted_local_addr));
  187. ASSERT_TRUE(accepted_socket.GetRemoteAddress(&accepted_remote_addr));
  188. ASSERT_TRUE(NetAddressPrivate::AreEqual(client_local_addr,
  189. accepted_remote_addr));
  190. const char kSentByte = 'a';
  191. ASSERT_SUBTEST_SUCCESS(SyncWrite(&client_socket,
  192. &kSentByte,
  193. sizeof(kSentByte)));
  194. char received_byte;
  195. ASSERT_SUBTEST_SUCCESS(SyncRead(&accepted_socket,
  196. &received_byte,
  197. sizeof(received_byte)));
  198. ASSERT_EQ(kSentByte, received_byte);
  199. accepted_socket.Disconnect();
  200. client_socket.Disconnect();
  201. server_socket.StopListening();
  202. PASS();
  203. }
  204. std::string TestTCPServerSocketPrivate::TestBacklog() {
  205. static const size_t kBacklog = 5;
  206. TCPServerSocketPrivate server_socket(instance_);
  207. PP_NetAddress_Private address;
  208. ASSERT_SUBTEST_SUCCESS(SyncListen(&server_socket, &address, 2 * kBacklog));
  209. std::vector<TCPSocketPrivate*> client_sockets(kBacklog);
  210. std::vector<TestCompletionCallback*> connect_callbacks(kBacklog);
  211. std::vector<int32_t> connect_rv(kBacklog);
  212. for (size_t i = 0; i < kBacklog; ++i) {
  213. client_sockets[i] = new TCPSocketPrivate(instance_);
  214. connect_callbacks[i] = new TestCompletionCallback(instance_->pp_instance(),
  215. callback_type());
  216. connect_rv[i] = client_sockets[i]->ConnectWithNetAddress(
  217. &address,
  218. connect_callbacks[i]->GetCallback());
  219. }
  220. std::vector<PP_Resource> resources(kBacklog);
  221. std::vector<TCPSocketPrivate*> accepted_sockets(kBacklog);
  222. for (size_t i = 0; i < kBacklog; ++i) {
  223. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  224. callback.WaitForResult(
  225. server_socket.Accept(&resources[i], callback.GetCallback()));
  226. CHECK_CALLBACK_BEHAVIOR(callback);
  227. ASSERT_EQ(PP_OK, callback.result());
  228. ASSERT_TRUE(resources[i] != 0);
  229. accepted_sockets[i] = new TCPSocketPrivate(pp::PassRef(), resources[i]);
  230. }
  231. for (size_t i = 0; i < kBacklog; ++i) {
  232. connect_callbacks[i]->WaitForResult(connect_rv[i]);
  233. CHECK_CALLBACK_BEHAVIOR(*connect_callbacks[i]);
  234. ASSERT_EQ(PP_OK, connect_callbacks[i]->result());
  235. }
  236. for (size_t i = 0; i < kBacklog; ++i) {
  237. const char byte = static_cast<char>('a' + i);
  238. ASSERT_SUBTEST_SUCCESS(SyncWrite(client_sockets[i], &byte, sizeof(byte)));
  239. }
  240. bool byte_received[kBacklog] = {};
  241. for (size_t i = 0; i < kBacklog; ++i) {
  242. char byte;
  243. ASSERT_SUBTEST_SUCCESS(SyncRead(accepted_sockets[i], &byte, sizeof(byte)));
  244. const size_t index = byte - 'a';
  245. ASSERT_FALSE(byte_received[index]);
  246. byte_received[index] = true;
  247. }
  248. for (size_t i = 0; i < kBacklog; ++i) {
  249. client_sockets[i]->Disconnect();
  250. delete client_sockets[i];
  251. delete connect_callbacks[i];
  252. accepted_sockets[i]->Disconnect();
  253. delete accepted_sockets[i];
  254. }
  255. server_socket.StopListening();
  256. PASS();
  257. }
  258. std::string TestTCPServerSocketPrivate::TestListenFails() {
  259. TCPServerSocketPrivate socket(instance_);
  260. ASSERT_SUBTEST_SUCCESS(SyncListenFails(&socket));
  261. // After a listen failure, accept should fail, too.
  262. ASSERT_SUBTEST_SUCCESS(SyncAcceptFails(&socket));
  263. // Listening again fails, just because of the test fixture simulating another
  264. // failure.
  265. ASSERT_SUBTEST_SUCCESS(SyncListenFails(&socket));
  266. PASS();
  267. }
  268. std::string TestTCPServerSocketPrivate::TestListenHangs() {
  269. TCPServerSocketPrivate socket(instance_);
  270. uint8_t localhost_ip[4] = {127, 0, 0, 1};
  271. PP_NetAddress_Private ipv4;
  272. ASSERT_TRUE(
  273. NetAddressPrivate::CreateFromIPv4Address(localhost_ip, 80, &ipv4));
  274. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  275. socket.Listen(&ipv4, 2 /* backlog */, DoNothingCallback());
  276. PASS();
  277. }
  278. std::string TestTCPServerSocketPrivate::TestAcceptFails() {
  279. TCPServerSocketPrivate socket(instance_);
  280. uint8_t localhost_ip[4] = {127, 0, 0, 1};
  281. PP_NetAddress_Private ipv4;
  282. ASSERT_TRUE(
  283. NetAddressPrivate::CreateFromIPv4Address(localhost_ip, 80, &ipv4));
  284. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  285. callback.WaitForResult(
  286. socket.Listen(&ipv4, 2 /* backlog */, callback.GetCallback()));
  287. CHECK_CALLBACK_BEHAVIOR(callback);
  288. ASSERT_EQ(PP_OK, callback.result());
  289. // Accept calls should fail.
  290. ASSERT_SUBTEST_SUCCESS(SyncAcceptFails(&socket));
  291. ASSERT_SUBTEST_SUCCESS(SyncAcceptFails(&socket));
  292. // Listening again fails, since the socket is already listening.
  293. ASSERT_SUBTEST_SUCCESS(SyncListenFails(&socket));
  294. PASS();
  295. }
  296. std::string TestTCPServerSocketPrivate::TestAcceptHangs() {
  297. TCPServerSocketPrivate socket(instance_);
  298. uint8_t localhost_ip[4] = {127, 0, 0, 1};
  299. PP_NetAddress_Private ipv4;
  300. ASSERT_TRUE(
  301. NetAddressPrivate::CreateFromIPv4Address(localhost_ip, 80, &ipv4));
  302. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  303. callback.WaitForResult(
  304. socket.Listen(&ipv4, 2 /* backlog */, callback.GetCallback()));
  305. CHECK_CALLBACK_BEHAVIOR(callback);
  306. ASSERT_EQ(PP_OK, callback.result());
  307. PP_Resource* resource = new PP_Resource();
  308. socket.Accept(resource,
  309. pp::CompletionCallback(&DeleteResource, resource,
  310. PP_COMPLETIONCALLBACK_FLAG_OPTIONAL));
  311. PASS();
  312. }