media/mtransport/test/sockettransportservice_unittest.cpp

branch
TOR_BUG_9701
changeset 8
97036ab72558
equal deleted inserted replaced
-1:000000000000 0:ea6cb32582f6
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 // Original author: ekr@rtfm.com
8 #include <iostream>
9
10 #include "prio.h"
11
12 #include "nsCOMPtr.h"
13 #include "nsNetCID.h"
14 #include "nsXPCOM.h"
15 #include "nsXPCOMGlue.h"
16
17 #include "nsIComponentManager.h"
18 #include "nsIComponentRegistrar.h"
19 #include "nsIIOService.h"
20 #include "nsIServiceManager.h"
21 #include "nsISocketTransportService.h"
22
23 #include "nsASocketHandler.h"
24 #include "nsServiceManagerUtils.h"
25 #include "nsThreadUtils.h"
26
27 #include "mtransport_test_utils.h"
28
29 #define GTEST_HAS_RTTI 0
30 #include "gtest/gtest.h"
31 #include "gtest_utils.h"
32
33 MtransportTestUtils *test_utils;
34
35 namespace {
36 class SocketTransportServiceTest : public ::testing::Test {
37 public:
38 SocketTransportServiceTest() : received_(0),
39 readpipe_(nullptr),
40 writepipe_(nullptr),
41 registered_(false) {
42 }
43
44 ~SocketTransportServiceTest() {
45 if (readpipe_)
46 PR_Close(readpipe_);
47 if (writepipe_)
48 PR_Close(writepipe_);
49 }
50
51 void SetUp();
52 void RegisterHandler();
53 void SendEvent();
54 void SendPacket();
55
56 void ReceivePacket() {
57 ++received_;
58 }
59
60 void ReceiveEvent() {
61 ++received_;
62 }
63
64 size_t Received() {
65 return received_;
66 }
67
68 private:
69 nsCOMPtr<nsISocketTransportService> stservice_;
70 nsCOMPtr<nsIEventTarget> target_;
71 size_t received_;
72 PRFileDesc *readpipe_;
73 PRFileDesc *writepipe_;
74 bool registered_;
75 };
76
77
78 // Received an event.
79 class EventReceived : public nsRunnable {
80 public:
81 EventReceived(SocketTransportServiceTest *test) :
82 test_(test) {}
83
84 NS_IMETHOD Run() {
85 test_->ReceiveEvent();
86 return NS_OK;
87 }
88
89 SocketTransportServiceTest *test_;
90 };
91
92
93 // Register our listener on the socket
94 class RegisterEvent : public nsRunnable {
95 public:
96 RegisterEvent(SocketTransportServiceTest *test) :
97 test_(test) {}
98
99 NS_IMETHOD Run() {
100 test_->RegisterHandler();
101 return NS_OK;
102 }
103
104 SocketTransportServiceTest *test_;
105 };
106
107
108 class SocketHandler : public nsASocketHandler {
109 public:
110 SocketHandler(SocketTransportServiceTest *test) : test_(test) {
111 }
112 virtual ~SocketHandler() {}
113
114 void OnSocketReady(PRFileDesc *fd, int16_t outflags) {
115 unsigned char buf[1600];
116
117 int32_t rv;
118 rv = PR_Recv(fd, buf, sizeof(buf), 0, PR_INTERVAL_NO_WAIT);
119 if (rv > 0) {
120 std::cerr << "Read " << rv << " bytes" << std::endl;
121 test_->ReceivePacket();
122 }
123 }
124
125 void OnSocketDetached(PRFileDesc *fd) {}
126
127 void IsLocal(bool *aIsLocal) {
128 // TODO(jesup): better check? Does it matter? (likely no)
129 *aIsLocal = false;
130 }
131
132 virtual uint64_t ByteCountSent() { return 0; }
133 virtual uint64_t ByteCountReceived() { return 0; }
134
135 NS_DECL_ISUPPORTS
136
137 private:
138 SocketTransportServiceTest *test_;
139 };
140
141 NS_IMPL_ISUPPORTS0(SocketHandler)
142
143 void SocketTransportServiceTest::SetUp() {
144 // Get the transport service as a dispatch target
145 nsresult rv;
146 target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
147 ASSERT_TRUE(NS_SUCCEEDED(rv));
148
149 // Get the transport service as a transport service
150 stservice_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
151 ASSERT_TRUE(NS_SUCCEEDED(rv));
152
153 // Create a loopback pipe
154 PRStatus status = PR_CreatePipe(&readpipe_, &writepipe_);
155 ASSERT_EQ(status, PR_SUCCESS);
156
157 // Register ourselves as a listener for the read side of the
158 // socket. The registration has to happen on the STS thread,
159 // hence this event stuff.
160 rv = target_->Dispatch(new RegisterEvent(this), 0);
161 ASSERT_TRUE(NS_SUCCEEDED(rv));
162 ASSERT_TRUE_WAIT(registered_, 10000);
163
164 }
165
166 void SocketTransportServiceTest::RegisterHandler() {
167 nsresult rv;
168
169 rv = stservice_->AttachSocket(readpipe_, new SocketHandler(this));
170 ASSERT_TRUE(NS_SUCCEEDED(rv));
171
172 registered_ = true;
173 }
174
175 void SocketTransportServiceTest::SendEvent() {
176 nsresult rv;
177
178 rv = target_->Dispatch(new EventReceived(this), 0);
179 ASSERT_TRUE(NS_SUCCEEDED(rv));
180 ASSERT_TRUE_WAIT(Received() == 1, 10000);
181 }
182
183 void SocketTransportServiceTest::SendPacket() {
184 unsigned char buffer[1024];
185 memset(buffer, 0, sizeof(buffer));
186
187 int32_t status = PR_Write(writepipe_, buffer, sizeof(buffer));
188 uint32_t size = status & 0xffff;
189 ASSERT_EQ(sizeof(buffer), size);
190 }
191
192
193
194 // The unit tests themselves
195 TEST_F(SocketTransportServiceTest, SendEvent) {
196 SendEvent();
197 }
198
199 TEST_F(SocketTransportServiceTest, SendPacket) {
200 SendPacket();
201 }
202
203
204 } // end namespace
205
206
207 int main(int argc, char **argv) {
208 test_utils = new MtransportTestUtils();
209
210 // Start the tests
211 ::testing::InitGoogleTest(&argc, argv);
212
213 int rv = RUN_ALL_TESTS();
214 delete test_utils;
215 return rv;
216 }

mercurial