sockettransportservice_unittest.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  4. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. // Original author: ekr@rtfm.com
  6. #include <iostream>
  7. #include "prio.h"
  8. #include "nsCOMPtr.h"
  9. #include "nsNetCID.h"
  10. #include "nsXPCOM.h"
  11. #include "nsXPCOMGlue.h"
  12. #include "nsIComponentManager.h"
  13. #include "nsIComponentRegistrar.h"
  14. #include "nsIIOService.h"
  15. #include "nsIServiceManager.h"
  16. #include "nsISocketTransportService.h"
  17. #include "nsASocketHandler.h"
  18. #include "nsServiceManagerUtils.h"
  19. #include "nsThreadUtils.h"
  20. #define GTEST_HAS_RTTI 0
  21. #include "gtest/gtest.h"
  22. #include "gtest_utils.h"
  23. using namespace mozilla;
  24. namespace {
  25. class SocketTransportServiceTest : public MtransportTest {
  26. public:
  27. SocketTransportServiceTest() : MtransportTest(),
  28. received_(0),
  29. readpipe_(nullptr),
  30. writepipe_(nullptr),
  31. registered_(false) {
  32. }
  33. ~SocketTransportServiceTest() {
  34. if (readpipe_)
  35. PR_Close(readpipe_);
  36. if (writepipe_)
  37. PR_Close(writepipe_);
  38. }
  39. void SetUp();
  40. void RegisterHandler();
  41. void SendEvent();
  42. void SendPacket();
  43. void ReceivePacket() {
  44. ++received_;
  45. }
  46. void ReceiveEvent() {
  47. ++received_;
  48. }
  49. size_t Received() {
  50. return received_;
  51. }
  52. private:
  53. nsCOMPtr<nsISocketTransportService> stservice_;
  54. nsCOMPtr<nsIEventTarget> target_;
  55. size_t received_;
  56. PRFileDesc *readpipe_;
  57. PRFileDesc *writepipe_;
  58. bool registered_;
  59. };
  60. // Received an event.
  61. class EventReceived : public Runnable {
  62. public:
  63. explicit EventReceived(SocketTransportServiceTest *test) :
  64. test_(test) {}
  65. NS_IMETHOD Run() override {
  66. test_->ReceiveEvent();
  67. return NS_OK;
  68. }
  69. SocketTransportServiceTest *test_;
  70. };
  71. // Register our listener on the socket
  72. class RegisterEvent : public Runnable {
  73. public:
  74. explicit RegisterEvent(SocketTransportServiceTest *test) :
  75. test_(test) {}
  76. NS_IMETHOD Run() override {
  77. test_->RegisterHandler();
  78. return NS_OK;
  79. }
  80. SocketTransportServiceTest *test_;
  81. };
  82. class SocketHandler : public nsASocketHandler {
  83. public:
  84. explicit SocketHandler(SocketTransportServiceTest *test) : test_(test) {
  85. }
  86. void OnSocketReady(PRFileDesc *fd, int16_t outflags) override {
  87. unsigned char buf[1600];
  88. int32_t rv;
  89. rv = PR_Recv(fd, buf, sizeof(buf), 0, PR_INTERVAL_NO_WAIT);
  90. if (rv > 0) {
  91. std::cerr << "Read " << rv << " bytes" << std::endl;
  92. test_->ReceivePacket();
  93. }
  94. }
  95. void OnSocketDetached(PRFileDesc *fd) override {}
  96. void IsLocal(bool *aIsLocal) override {
  97. // TODO(jesup): better check? Does it matter? (likely no)
  98. *aIsLocal = false;
  99. }
  100. virtual uint64_t ByteCountSent() override { return 0; }
  101. virtual uint64_t ByteCountReceived() override { return 0; }
  102. NS_DECL_ISUPPORTS
  103. protected:
  104. virtual ~SocketHandler() {}
  105. private:
  106. SocketTransportServiceTest *test_;
  107. };
  108. NS_IMPL_ISUPPORTS0(SocketHandler)
  109. void SocketTransportServiceTest::SetUp() {
  110. MtransportTest::SetUp();
  111. // Get the transport service as a dispatch target
  112. nsresult rv;
  113. target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
  114. ASSERT_TRUE(NS_SUCCEEDED(rv));
  115. // Get the transport service as a transport service
  116. stservice_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
  117. ASSERT_TRUE(NS_SUCCEEDED(rv));
  118. // Create a loopback pipe
  119. PRStatus status = PR_CreatePipe(&readpipe_, &writepipe_);
  120. ASSERT_EQ(status, PR_SUCCESS);
  121. // Register ourselves as a listener for the read side of the
  122. // socket. The registration has to happen on the STS thread,
  123. // hence this event stuff.
  124. rv = target_->Dispatch(new RegisterEvent(this), 0);
  125. ASSERT_TRUE(NS_SUCCEEDED(rv));
  126. ASSERT_TRUE_WAIT(registered_, 10000);
  127. }
  128. void SocketTransportServiceTest::RegisterHandler() {
  129. nsresult rv;
  130. rv = stservice_->AttachSocket(readpipe_, new SocketHandler(this));
  131. ASSERT_TRUE(NS_SUCCEEDED(rv));
  132. registered_ = true;
  133. }
  134. void SocketTransportServiceTest::SendEvent() {
  135. nsresult rv;
  136. rv = target_->Dispatch(new EventReceived(this), 0);
  137. ASSERT_TRUE(NS_SUCCEEDED(rv));
  138. ASSERT_TRUE_WAIT(Received() == 1, 10000);
  139. }
  140. void SocketTransportServiceTest::SendPacket() {
  141. unsigned char buffer[1024];
  142. memset(buffer, 0, sizeof(buffer));
  143. int32_t status = PR_Write(writepipe_, buffer, sizeof(buffer));
  144. uint32_t size = status & 0xffff;
  145. ASSERT_EQ(sizeof(buffer), size);
  146. }
  147. // The unit tests themselves
  148. TEST_F(SocketTransportServiceTest, SendEvent) {
  149. SendEvent();
  150. }
  151. TEST_F(SocketTransportServiceTest, SendPacket) {
  152. SendPacket();
  153. }
  154. } // end namespace