OLD | NEW |
---|---|
(Empty) | |
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 | |
5 #include "remoting/protocol/channel_multiplexer.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/message_loop.h" | |
9 #include "net/base/net_errors.h" | |
10 #include "net/socket/socket.h" | |
11 #include "net/socket/stream_socket.h" | |
12 #include "remoting/base/constants.h" | |
13 #include "remoting/protocol/connection_tester.h" | |
14 #include "remoting/protocol/fake_session.h" | |
15 #include "testing/gmock/include/gmock/gmock.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 | |
18 using testing::_; | |
19 using testing::AtMost; | |
20 using testing::InvokeWithoutArgs; | |
21 | |
22 namespace remoting { | |
23 namespace protocol { | |
24 | |
25 namespace { | |
26 | |
27 const int kMessageSize = 1024; | |
28 const int kMessages = 100; | |
29 const char kMuxChannelName[] = "mux"; | |
30 | |
31 void QuitCurrentThread() { | |
32 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); | |
33 } | |
34 | |
35 class MockSocketCallback { | |
36 public: | |
37 MOCK_METHOD1(OnDone, void(int result)); | |
38 }; | |
39 | |
40 } // namespace | |
41 | |
42 class ChannelMultiplexerTest : public testing::Test { | |
43 public: | |
44 void DeleteAll() { | |
45 host_socket1_.reset(); | |
46 host_socket2_.reset(); | |
47 client_socket1_.reset(); | |
48 client_socket2_.reset(); | |
49 host_mux_.reset(); | |
50 client_mux_.reset(); | |
51 } | |
52 | |
53 protected: | |
54 virtual void SetUp() OVERRIDE { | |
55 // Create pair of multiplexers and connect them to each other. | |
56 host_mux_.reset(new ChannelMultiplexer(&host_session_, kMuxChannelName)); | |
57 client_mux_.reset(new ChannelMultiplexer(&client_session_, | |
58 kMuxChannelName)); | |
59 FakeSocket* host_socket = | |
60 host_session_.GetStreamChannel(ChannelMultiplexer::kMuxChannelName); | |
61 FakeSocket* client_socket = | |
62 client_session_.GetStreamChannel(ChannelMultiplexer::kMuxChannelName); | |
63 host_socket->PairWith(client_socket); | |
64 | |
65 // Make writes asynchronous in one direction. | |
66 host_socket->set_async_write(true); | |
67 } | |
68 | |
69 void CreateChannel(const std::string& name, | |
70 scoped_ptr<net::StreamSocket>* host_socket, | |
71 scoped_ptr<net::StreamSocket>* client_socket) { | |
72 int counter = 2; | |
73 host_mux_->CreateStreamChannel(name, base::Bind( | |
74 &ChannelMultiplexerTest::OnChannelConnected, base::Unretained(this), | |
75 host_socket, &counter)); | |
76 client_mux_->CreateStreamChannel(name, base::Bind( | |
77 &ChannelMultiplexerTest::OnChannelConnected, base::Unretained(this), | |
78 client_socket, &counter)); | |
79 | |
80 message_loop_.Run(); | |
81 | |
82 EXPECT_TRUE(host_socket->get()); | |
83 EXPECT_TRUE(client_socket->get()); | |
84 } | |
85 | |
86 void OnChannelConnected( | |
87 scoped_ptr<net::StreamSocket>* storage, | |
88 int* counter, | |
89 scoped_ptr<net::StreamSocket> socket) { | |
90 *storage = socket.Pass(); | |
91 --(*counter); | |
92 EXPECT_GE(*counter, 0); | |
93 if (*counter == 0) | |
94 QuitCurrentThread(); | |
95 } | |
96 | |
97 scoped_refptr<net::IOBufferWithSize> CreateTestBuffer(int size) { | |
98 scoped_refptr<net::IOBufferWithSize> result = | |
99 new net::IOBufferWithSize(size); | |
100 for (int i = 0; i< size; ++i) { | |
101 result->data()[i] = rand() % 256; | |
102 } | |
103 return result; | |
104 } | |
105 | |
106 MessageLoop message_loop_; | |
107 | |
108 FakeSession host_session_; | |
109 FakeSession client_session_; | |
110 | |
111 scoped_ptr<ChannelMultiplexer> host_mux_; | |
112 scoped_ptr<ChannelMultiplexer> client_mux_; | |
113 | |
114 scoped_ptr<net::StreamSocket> host_socket1_; | |
115 scoped_ptr<net::StreamSocket> client_socket1_; | |
116 scoped_ptr<net::StreamSocket> host_socket2_; | |
117 scoped_ptr<net::StreamSocket> client_socket2_; | |
118 }; | |
119 | |
120 | |
121 TEST_F(ChannelMultiplexerTest, OneChannel) { | |
122 scoped_ptr<net::StreamSocket> host_socket; | |
123 scoped_ptr<net::StreamSocket> client_socket; | |
124 ASSERT_NO_FATAL_FAILURE(CreateChannel("test", &host_socket, &client_socket)); | |
125 | |
126 StreamConnectionTester tester(host_socket.get(), client_socket.get(), | |
127 kMessageSize, kMessages); | |
128 tester.Start(); | |
129 message_loop_.Run(); | |
130 tester.CheckResults(); | |
131 } | |
132 | |
133 TEST_F(ChannelMultiplexerTest, TwoChannels) { | |
134 scoped_ptr<net::StreamSocket> host_socket1_; | |
135 scoped_ptr<net::StreamSocket> client_socket1_; | |
136 ASSERT_NO_FATAL_FAILURE( | |
137 CreateChannel("test", &host_socket1_, &client_socket1_)); | |
138 | |
139 scoped_ptr<net::StreamSocket> host_socket2_; | |
140 scoped_ptr<net::StreamSocket> client_socket2_; | |
141 ASSERT_NO_FATAL_FAILURE( | |
142 CreateChannel("ch2", &host_socket2_, &client_socket2_)); | |
143 | |
144 StreamConnectionTester tester1(host_socket1_.get(), client_socket1_.get(), | |
145 kMessageSize, kMessages); | |
146 StreamConnectionTester tester2(host_socket2_.get(), client_socket2_.get(), | |
147 kMessageSize, kMessages); | |
148 tester1.Start(); | |
149 tester2.Start(); | |
150 while (!tester1.done() || !tester2.done()) { | |
151 message_loop_.Run(); | |
152 } | |
153 tester1.CheckResults(); | |
154 tester2.CheckResults(); | |
155 } | |
156 | |
157 // Four channels, two in each direction | |
158 TEST_F(ChannelMultiplexerTest, FourChannels) { | |
159 scoped_ptr<net::StreamSocket> host_socket1_; | |
160 scoped_ptr<net::StreamSocket> client_socket1_; | |
161 ASSERT_NO_FATAL_FAILURE( | |
162 CreateChannel("test", &host_socket1_, &client_socket1_)); | |
163 | |
164 scoped_ptr<net::StreamSocket> host_socket2_; | |
165 scoped_ptr<net::StreamSocket> client_socket2_; | |
166 ASSERT_NO_FATAL_FAILURE( | |
167 CreateChannel("ch2", &host_socket2_, &client_socket2_)); | |
168 | |
169 scoped_ptr<net::StreamSocket> host_socket3; | |
170 scoped_ptr<net::StreamSocket> client_socket3; | |
171 ASSERT_NO_FATAL_FAILURE( | |
172 CreateChannel("test3", &host_socket3, &client_socket3)); | |
173 | |
174 scoped_ptr<net::StreamSocket> host_socket4; | |
175 scoped_ptr<net::StreamSocket> client_socket4; | |
176 ASSERT_NO_FATAL_FAILURE( | |
177 CreateChannel("ch4", &host_socket4, &client_socket4)); | |
178 | |
179 StreamConnectionTester tester1(host_socket1_.get(), client_socket1_.get(), | |
180 kMessageSize, kMessages); | |
181 StreamConnectionTester tester2(host_socket2_.get(), client_socket2_.get(), | |
182 kMessageSize, kMessages); | |
183 StreamConnectionTester tester3(client_socket3.get(), host_socket3.get(), | |
184 kMessageSize, kMessages); | |
185 StreamConnectionTester tester4(client_socket4.get(), host_socket4.get(), | |
186 kMessageSize, kMessages); | |
187 tester1.Start(); | |
188 tester2.Start(); | |
189 tester3.Start(); | |
190 tester4.Start(); | |
191 while (!tester1.done() || !tester2.done() || | |
192 !tester3.done() || !tester4.done()) { | |
193 message_loop_.Run(); | |
194 } | |
195 tester1.CheckResults(); | |
196 tester2.CheckResults(); | |
197 tester3.CheckResults(); | |
198 tester4.CheckResults(); | |
199 } | |
200 | |
201 TEST_F(ChannelMultiplexerTest, SyncFail) { | |
202 scoped_ptr<net::StreamSocket> host_socket1_; | |
203 scoped_ptr<net::StreamSocket> client_socket1_; | |
204 ASSERT_NO_FATAL_FAILURE( | |
205 CreateChannel("test", &host_socket1_, &client_socket1_)); | |
206 | |
207 scoped_ptr<net::StreamSocket> host_socket2_; | |
208 scoped_ptr<net::StreamSocket> client_socket2_; | |
209 ASSERT_NO_FATAL_FAILURE( | |
210 CreateChannel("ch2", &host_socket2_, &client_socket2_)); | |
211 | |
212 host_session_.GetStreamChannel(kMuxChannelName)-> | |
213 set_next_write_error(net::ERR_FAILED); | |
214 host_session_.GetStreamChannel(kMuxChannelName)-> | |
215 set_async_write(false); | |
216 | |
217 scoped_refptr<net::IOBufferWithSize> buf = CreateTestBuffer(100); | |
218 | |
219 MockSocketCallback cb1; | |
220 EXPECT_CALL(cb1, OnDone(_)) | |
221 .Times(0); | |
222 EXPECT_EQ(net::ERR_FAILED, host_socket1_->Write(buf, buf->size(), base::Bind( | |
223 &MockSocketCallback::OnDone, base::Unretained(&cb1)))); | |
224 MockSocketCallback cb2; | |
225 EXPECT_CALL(cb2, OnDone(_)) | |
Wez
2012/08/07 21:44:45
nit: This expectation should really appear alongsi
Sergey Ulanov
2012/08/07 22:25:14
Done.
| |
226 .Times(0); | |
227 EXPECT_EQ(net::ERR_FAILED, host_socket2_->Write(buf, buf->size(), base::Bind( | |
228 &MockSocketCallback::OnDone, base::Unretained(&cb2)))); | |
229 | |
230 message_loop_.RunAllPending(); | |
231 } | |
232 | |
233 TEST_F(ChannelMultiplexerTest, AsyncFail) { | |
234 ASSERT_NO_FATAL_FAILURE( | |
235 CreateChannel("test", &host_socket1_, &client_socket1_)); | |
236 | |
237 ASSERT_NO_FATAL_FAILURE( | |
238 CreateChannel("ch2", &host_socket2_, &client_socket2_)); | |
239 | |
240 host_session_.GetStreamChannel(kMuxChannelName)-> | |
241 set_next_write_error(net::ERR_FAILED); | |
242 host_session_.GetStreamChannel(kMuxChannelName)-> | |
243 set_async_write(true); | |
244 | |
245 scoped_refptr<net::IOBufferWithSize> buf = CreateTestBuffer(100); | |
246 | |
247 MockSocketCallback cb1; | |
248 EXPECT_CALL(cb1, OnDone(net::ERR_FAILED)); | |
249 EXPECT_EQ(net::ERR_IO_PENDING, | |
250 host_socket1_->Write(buf, buf->size(), base::Bind( | |
251 &MockSocketCallback::OnDone, base::Unretained(&cb1)))); | |
252 MockSocketCallback cb2; | |
253 EXPECT_CALL(cb2, OnDone(net::ERR_FAILED)); | |
Wez
2012/08/07 21:44:45
Same here.
Sergey Ulanov
2012/08/07 22:25:14
Done.
| |
254 EXPECT_EQ(net::ERR_IO_PENDING, | |
255 host_socket2_->Write(buf, buf->size(), base::Bind( | |
256 &MockSocketCallback::OnDone, base::Unretained(&cb2)))); | |
257 | |
258 message_loop_.RunAllPending(); | |
259 } | |
260 | |
261 TEST_F(ChannelMultiplexerTest, DeleteWhenFailed) { | |
262 ASSERT_NO_FATAL_FAILURE( | |
263 CreateChannel("test", &host_socket1_, &client_socket1_)); | |
264 ASSERT_NO_FATAL_FAILURE( | |
265 CreateChannel("ch2", &host_socket2_, &client_socket2_)); | |
266 | |
267 host_session_.GetStreamChannel(kMuxChannelName)-> | |
268 set_next_write_error(net::ERR_FAILED); | |
269 host_session_.GetStreamChannel(kMuxChannelName)-> | |
270 set_async_write(true); | |
271 | |
272 scoped_refptr<net::IOBufferWithSize> buf = CreateTestBuffer(100); | |
273 | |
274 MockSocketCallback cb1; | |
275 EXPECT_CALL(cb1, OnDone(net::ERR_FAILED)) | |
276 .Times(AtMost(1)) | |
277 .WillOnce(InvokeWithoutArgs(this, &ChannelMultiplexerTest::DeleteAll)); | |
278 EXPECT_EQ(net::ERR_IO_PENDING, | |
279 host_socket1_->Write(buf, buf->size(), base::Bind( | |
280 &MockSocketCallback::OnDone, base::Unretained(&cb1)))); | |
281 MockSocketCallback cb2; | |
282 EXPECT_CALL(cb2, OnDone(net::ERR_FAILED)) | |
283 .Times(AtMost(1)) | |
284 .WillOnce(InvokeWithoutArgs(this, &ChannelMultiplexerTest::DeleteAll)); | |
Wez
2012/08/07 21:44:45
And here.
Sergey Ulanov
2012/08/07 22:25:14
Done.
| |
285 EXPECT_EQ(net::ERR_IO_PENDING, | |
286 host_socket2_->Write(buf, buf->size(), base::Bind( | |
287 &MockSocketCallback::OnDone, base::Unretained(&cb2)))); | |
288 | |
289 message_loop_.RunAllPending(); | |
290 | |
291 // Check that the sockets were destroyed. | |
292 EXPECT_FALSE(host_mux_.get()); | |
293 } | |
294 | |
295 } // namespace protocol | |
296 } // namespace remoting | |
OLD | NEW |