diff options
Diffstat (limited to 'media/mtransport/test/sockettransportservice_unittest.cpp')
-rw-r--r-- | media/mtransport/test/sockettransportservice_unittest.cpp | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/media/mtransport/test/sockettransportservice_unittest.cpp b/media/mtransport/test/sockettransportservice_unittest.cpp new file mode 100644 index 000000000..43746c908 --- /dev/null +++ b/media/mtransport/test/sockettransportservice_unittest.cpp @@ -0,0 +1,208 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Original author: ekr@rtfm.com +#include <iostream> + +#include "prio.h" + +#include "nsCOMPtr.h" +#include "nsNetCID.h" +#include "nsXPCOM.h" +#include "nsXPCOMGlue.h" + +#include "nsIComponentManager.h" +#include "nsIComponentRegistrar.h" +#include "nsIIOService.h" +#include "nsIServiceManager.h" +#include "nsISocketTransportService.h" + +#include "nsASocketHandler.h" +#include "nsServiceManagerUtils.h" +#include "nsThreadUtils.h" + + +#define GTEST_HAS_RTTI 0 +#include "gtest/gtest.h" +#include "gtest_utils.h" + +using namespace mozilla; + +namespace { +class SocketTransportServiceTest : public MtransportTest { + public: + SocketTransportServiceTest() : MtransportTest(), + received_(0), + readpipe_(nullptr), + writepipe_(nullptr), + registered_(false) { + } + + ~SocketTransportServiceTest() { + if (readpipe_) + PR_Close(readpipe_); + if (writepipe_) + PR_Close(writepipe_); + } + + void SetUp(); + void RegisterHandler(); + void SendEvent(); + void SendPacket(); + + void ReceivePacket() { + ++received_; + } + + void ReceiveEvent() { + ++received_; + } + + size_t Received() { + return received_; + } + + private: + nsCOMPtr<nsISocketTransportService> stservice_; + nsCOMPtr<nsIEventTarget> target_; + size_t received_; + PRFileDesc *readpipe_; + PRFileDesc *writepipe_; + bool registered_; +}; + + +// Received an event. +class EventReceived : public Runnable { +public: + explicit EventReceived(SocketTransportServiceTest *test) : + test_(test) {} + + NS_IMETHOD Run() override { + test_->ReceiveEvent(); + return NS_OK; + } + + SocketTransportServiceTest *test_; +}; + + +// Register our listener on the socket +class RegisterEvent : public Runnable { +public: + explicit RegisterEvent(SocketTransportServiceTest *test) : + test_(test) {} + + NS_IMETHOD Run() override { + test_->RegisterHandler(); + return NS_OK; + } + + SocketTransportServiceTest *test_; +}; + + +class SocketHandler : public nsASocketHandler { + public: + explicit SocketHandler(SocketTransportServiceTest *test) : test_(test) { + } + + void OnSocketReady(PRFileDesc *fd, int16_t outflags) override { + unsigned char buf[1600]; + + int32_t rv; + rv = PR_Recv(fd, buf, sizeof(buf), 0, PR_INTERVAL_NO_WAIT); + if (rv > 0) { + std::cerr << "Read " << rv << " bytes" << std::endl; + test_->ReceivePacket(); + } + } + + void OnSocketDetached(PRFileDesc *fd) override {} + + void IsLocal(bool *aIsLocal) override { + // TODO(jesup): better check? Does it matter? (likely no) + *aIsLocal = false; + } + + virtual uint64_t ByteCountSent() override { return 0; } + virtual uint64_t ByteCountReceived() override { return 0; } + + NS_DECL_ISUPPORTS + + protected: + virtual ~SocketHandler() {} + + private: + SocketTransportServiceTest *test_; +}; + +NS_IMPL_ISUPPORTS0(SocketHandler) + +void SocketTransportServiceTest::SetUp() { + MtransportTest::SetUp(); + + // Get the transport service as a dispatch target + nsresult rv; + target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); + ASSERT_TRUE(NS_SUCCEEDED(rv)); + + // Get the transport service as a transport service + stservice_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); + ASSERT_TRUE(NS_SUCCEEDED(rv)); + + // Create a loopback pipe + PRStatus status = PR_CreatePipe(&readpipe_, &writepipe_); + ASSERT_EQ(status, PR_SUCCESS); + + // Register ourselves as a listener for the read side of the + // socket. The registration has to happen on the STS thread, + // hence this event stuff. + rv = target_->Dispatch(new RegisterEvent(this), 0); + ASSERT_TRUE(NS_SUCCEEDED(rv)); + ASSERT_TRUE_WAIT(registered_, 10000); + +} + +void SocketTransportServiceTest::RegisterHandler() { + nsresult rv; + + rv = stservice_->AttachSocket(readpipe_, new SocketHandler(this)); + ASSERT_TRUE(NS_SUCCEEDED(rv)); + + registered_ = true; +} + +void SocketTransportServiceTest::SendEvent() { + nsresult rv; + + rv = target_->Dispatch(new EventReceived(this), 0); + ASSERT_TRUE(NS_SUCCEEDED(rv)); + ASSERT_TRUE_WAIT(Received() == 1, 10000); +} + +void SocketTransportServiceTest::SendPacket() { + unsigned char buffer[1024]; + memset(buffer, 0, sizeof(buffer)); + + int32_t status = PR_Write(writepipe_, buffer, sizeof(buffer)); + uint32_t size = status & 0xffff; + ASSERT_EQ(sizeof(buffer), size); +} + + + +// The unit tests themselves +TEST_F(SocketTransportServiceTest, SendEvent) { + SendEvent(); +} + +TEST_F(SocketTransportServiceTest, SendPacket) { + SendPacket(); +} + + +} // end namespace |