1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/mtransport/test/sockettransportservice_unittest.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,216 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +// Original author: ekr@rtfm.com 1.11 +#include <iostream> 1.12 + 1.13 +#include "prio.h" 1.14 + 1.15 +#include "nsCOMPtr.h" 1.16 +#include "nsNetCID.h" 1.17 +#include "nsXPCOM.h" 1.18 +#include "nsXPCOMGlue.h" 1.19 + 1.20 +#include "nsIComponentManager.h" 1.21 +#include "nsIComponentRegistrar.h" 1.22 +#include "nsIIOService.h" 1.23 +#include "nsIServiceManager.h" 1.24 +#include "nsISocketTransportService.h" 1.25 + 1.26 +#include "nsASocketHandler.h" 1.27 +#include "nsServiceManagerUtils.h" 1.28 +#include "nsThreadUtils.h" 1.29 + 1.30 +#include "mtransport_test_utils.h" 1.31 + 1.32 +#define GTEST_HAS_RTTI 0 1.33 +#include "gtest/gtest.h" 1.34 +#include "gtest_utils.h" 1.35 + 1.36 +MtransportTestUtils *test_utils; 1.37 + 1.38 +namespace { 1.39 +class SocketTransportServiceTest : public ::testing::Test { 1.40 + public: 1.41 + SocketTransportServiceTest() : received_(0), 1.42 + readpipe_(nullptr), 1.43 + writepipe_(nullptr), 1.44 + registered_(false) { 1.45 + } 1.46 + 1.47 + ~SocketTransportServiceTest() { 1.48 + if (readpipe_) 1.49 + PR_Close(readpipe_); 1.50 + if (writepipe_) 1.51 + PR_Close(writepipe_); 1.52 + } 1.53 + 1.54 + void SetUp(); 1.55 + void RegisterHandler(); 1.56 + void SendEvent(); 1.57 + void SendPacket(); 1.58 + 1.59 + void ReceivePacket() { 1.60 + ++received_; 1.61 + } 1.62 + 1.63 + void ReceiveEvent() { 1.64 + ++received_; 1.65 + } 1.66 + 1.67 + size_t Received() { 1.68 + return received_; 1.69 + } 1.70 + 1.71 + private: 1.72 + nsCOMPtr<nsISocketTransportService> stservice_; 1.73 + nsCOMPtr<nsIEventTarget> target_; 1.74 + size_t received_; 1.75 + PRFileDesc *readpipe_; 1.76 + PRFileDesc *writepipe_; 1.77 + bool registered_; 1.78 +}; 1.79 + 1.80 + 1.81 +// Received an event. 1.82 +class EventReceived : public nsRunnable { 1.83 +public: 1.84 + EventReceived(SocketTransportServiceTest *test) : 1.85 + test_(test) {} 1.86 + 1.87 + NS_IMETHOD Run() { 1.88 + test_->ReceiveEvent(); 1.89 + return NS_OK; 1.90 + } 1.91 + 1.92 + SocketTransportServiceTest *test_; 1.93 +}; 1.94 + 1.95 + 1.96 +// Register our listener on the socket 1.97 +class RegisterEvent : public nsRunnable { 1.98 +public: 1.99 + RegisterEvent(SocketTransportServiceTest *test) : 1.100 + test_(test) {} 1.101 + 1.102 + NS_IMETHOD Run() { 1.103 + test_->RegisterHandler(); 1.104 + return NS_OK; 1.105 + } 1.106 + 1.107 + SocketTransportServiceTest *test_; 1.108 +}; 1.109 + 1.110 + 1.111 +class SocketHandler : public nsASocketHandler { 1.112 + public: 1.113 + SocketHandler(SocketTransportServiceTest *test) : test_(test) { 1.114 + } 1.115 + virtual ~SocketHandler() {} 1.116 + 1.117 + void OnSocketReady(PRFileDesc *fd, int16_t outflags) { 1.118 + unsigned char buf[1600]; 1.119 + 1.120 + int32_t rv; 1.121 + rv = PR_Recv(fd, buf, sizeof(buf), 0, PR_INTERVAL_NO_WAIT); 1.122 + if (rv > 0) { 1.123 + std::cerr << "Read " << rv << " bytes" << std::endl; 1.124 + test_->ReceivePacket(); 1.125 + } 1.126 + } 1.127 + 1.128 + void OnSocketDetached(PRFileDesc *fd) {} 1.129 + 1.130 + void IsLocal(bool *aIsLocal) { 1.131 + // TODO(jesup): better check? Does it matter? (likely no) 1.132 + *aIsLocal = false; 1.133 + } 1.134 + 1.135 + virtual uint64_t ByteCountSent() { return 0; } 1.136 + virtual uint64_t ByteCountReceived() { return 0; } 1.137 + 1.138 + NS_DECL_ISUPPORTS 1.139 + 1.140 + private: 1.141 + SocketTransportServiceTest *test_; 1.142 +}; 1.143 + 1.144 +NS_IMPL_ISUPPORTS0(SocketHandler) 1.145 + 1.146 +void SocketTransportServiceTest::SetUp() { 1.147 + // Get the transport service as a dispatch target 1.148 + nsresult rv; 1.149 + target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); 1.150 + ASSERT_TRUE(NS_SUCCEEDED(rv)); 1.151 + 1.152 + // Get the transport service as a transport service 1.153 + stservice_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); 1.154 + ASSERT_TRUE(NS_SUCCEEDED(rv)); 1.155 + 1.156 + // Create a loopback pipe 1.157 + PRStatus status = PR_CreatePipe(&readpipe_, &writepipe_); 1.158 + ASSERT_EQ(status, PR_SUCCESS); 1.159 + 1.160 + // Register ourselves as a listener for the read side of the 1.161 + // socket. The registration has to happen on the STS thread, 1.162 + // hence this event stuff. 1.163 + rv = target_->Dispatch(new RegisterEvent(this), 0); 1.164 + ASSERT_TRUE(NS_SUCCEEDED(rv)); 1.165 + ASSERT_TRUE_WAIT(registered_, 10000); 1.166 + 1.167 +} 1.168 + 1.169 +void SocketTransportServiceTest::RegisterHandler() { 1.170 + nsresult rv; 1.171 + 1.172 + rv = stservice_->AttachSocket(readpipe_, new SocketHandler(this)); 1.173 + ASSERT_TRUE(NS_SUCCEEDED(rv)); 1.174 + 1.175 + registered_ = true; 1.176 +} 1.177 + 1.178 +void SocketTransportServiceTest::SendEvent() { 1.179 + nsresult rv; 1.180 + 1.181 + rv = target_->Dispatch(new EventReceived(this), 0); 1.182 + ASSERT_TRUE(NS_SUCCEEDED(rv)); 1.183 + ASSERT_TRUE_WAIT(Received() == 1, 10000); 1.184 +} 1.185 + 1.186 +void SocketTransportServiceTest::SendPacket() { 1.187 + unsigned char buffer[1024]; 1.188 + memset(buffer, 0, sizeof(buffer)); 1.189 + 1.190 + int32_t status = PR_Write(writepipe_, buffer, sizeof(buffer)); 1.191 + uint32_t size = status & 0xffff; 1.192 + ASSERT_EQ(sizeof(buffer), size); 1.193 +} 1.194 + 1.195 + 1.196 + 1.197 +// The unit tests themselves 1.198 +TEST_F(SocketTransportServiceTest, SendEvent) { 1.199 + SendEvent(); 1.200 +} 1.201 + 1.202 +TEST_F(SocketTransportServiceTest, SendPacket) { 1.203 + SendPacket(); 1.204 +} 1.205 + 1.206 + 1.207 +} // end namespace 1.208 + 1.209 + 1.210 +int main(int argc, char **argv) { 1.211 + test_utils = new MtransportTestUtils(); 1.212 + 1.213 + // Start the tests 1.214 + ::testing::InitGoogleTest(&argc, argv); 1.215 + 1.216 + int rv = RUN_ALL_TESTS(); 1.217 + delete test_utils; 1.218 + return rv; 1.219 +}