Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(362)

Side by Side Diff: remoting/protocol/quic_channel_factory_unittest.cc

Issue 1273233002: Implement QuicChannel and QuicChannelFactory (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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/quic_channel_factory.h"
6
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "net/base/io_buffer.h"
11 #include "net/base/net_errors.h"
12 #include "net/base/test_completion_callback.h"
13 #include "net/quic/p2p/quic_p2p_session.h"
14 #include "net/quic/p2p/quic_p2p_stream.h"
15 #include "net/socket/socket.h"
16 #include "remoting/base/constants.h"
17 #include "remoting/protocol/connection_tester.h"
18 #include "remoting/protocol/fake_datagram_socket.h"
19 #include "remoting/protocol/p2p_stream_socket.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 using testing::_;
24 using testing::AtMost;
25 using testing::InvokeWithoutArgs;
26
27 namespace remoting {
28 namespace protocol {
29
30 namespace {
31
32 const int kMessageSize = 1024;
33 const int kMessages = 100;
34
35 const char kTestChannelName[] = "test";
36 const char kTestChannelName2[] = "test2";
37
38 } // namespace
39
40 class QuicChannelFactoryTest : public testing::Test,
41 public testing::WithParamInterface<bool> {
42 public:
43 void DeleteAll() {
44 host_channel1_.reset();
45 host_channel2_.reset();
46 client_channel1_.reset();
47 client_channel2_.reset();
48 host_quic_.reset();
49 client_quic_.reset();
50 }
51
52 void FailedReadDeleteAll(int result) {
53 EXPECT_NE(net::OK, result);
54 DeleteAll();
55 }
56
57 void OnChannelConnected(scoped_ptr<P2PStreamSocket>* storage,
58 int* counter,
59 base::RunLoop* run_loop,
60 scoped_ptr<P2PStreamSocket> socket) {
61 *storage = socket.Pass();
62 if (counter) {
63 --(*counter);
64 EXPECT_GE(*counter, 0);
65 if (*counter == 0)
66 run_loop->Quit();
67 }
68 }
69
70 void OnChannelConnectedExpectFail(scoped_ptr<P2PStreamSocket> socket) {
71 EXPECT_FALSE(socket);
72 host_quic_->CancelChannelCreation(kTestChannelName2);
73 DeleteAll();
74 }
75
76 void OnChannelConnectedNotReached(scoped_ptr<P2PStreamSocket> socket) {
77 NOTREACHED();
78 }
79
80 protected:
81 void Initialize() {
82 host_base_channel_factory_.PairWith(&client_base_channel_factory_);
83 host_base_channel_factory_.set_asynchronous_create(GetParam());
84 client_base_channel_factory_.set_asynchronous_create(GetParam());
85
86 const char kTestSessionId[] = "123123";
87 host_quic_.reset(new QuicChannelFactory(kTestSessionId, true));
88 client_quic_.reset(new QuicChannelFactory(kTestSessionId, false));
89
90 std::string message = client_quic_->CreateSessionInitiateConfigMessage();
91 EXPECT_TRUE(host_quic_->ProcessSessionInitiateConfigMessage(message));
92 message = host_quic_->CreateSessionAcceptConfigMessage();
93 EXPECT_TRUE(client_quic_->ProcessSessionAcceptConfigMessage(message));
94
95 const char kTestSharedSecret[] = "Shared Secret";
96 host_quic_->Start(&host_base_channel_factory_, kTestSharedSecret);
97 client_quic_->Start(&client_base_channel_factory_, kTestSharedSecret);
98
99 FakeDatagramSocket* host_base_channel =
100 host_base_channel_factory_.GetFakeChannel(kQuicChannelName);
101 if (host_base_channel)
102 host_base_channel->set_async_send(GetParam());
103
104 FakeDatagramSocket* client_base_channel =
105 client_base_channel_factory_.GetFakeChannel(kQuicChannelName);
106 if (client_base_channel)
107 client_base_channel->set_async_send(GetParam());
108 }
109
110 void CreateChannel(const std::string& name,
111 scoped_ptr<P2PStreamSocket>* host_channel,
112 scoped_ptr<P2PStreamSocket>* client_channel) {
113 int counter = 2;
114 base::RunLoop run_loop;
115 host_quic_->CreateChannel(
116 name,
117 base::Bind(&QuicChannelFactoryTest::OnChannelConnected,
118 base::Unretained(this), host_channel, &counter, &run_loop));
119 client_quic_->CreateChannel(
120 name, base::Bind(&QuicChannelFactoryTest::OnChannelConnected,
121 base::Unretained(this), client_channel, &counter,
122 &run_loop));
123
124 run_loop.Run();
125
126 EXPECT_TRUE(host_channel->get());
127 EXPECT_TRUE(client_channel->get());
128 }
129
130 scoped_refptr<net::IOBufferWithSize> CreateTestBuffer(int size) {
131 scoped_refptr<net::IOBufferWithSize> result =
132 new net::IOBufferWithSize(size);
133 for (int i = 0; i < size; ++i) {
134 result->data()[i] = rand() % 256;
135 }
136 return result;
137 }
138
139 base::MessageLoop message_loop_;
140
141 FakeDatagramChannelFactory host_base_channel_factory_;
142 FakeDatagramChannelFactory client_base_channel_factory_;
143
144 scoped_ptr<QuicChannelFactory> host_quic_;
145 scoped_ptr<QuicChannelFactory> client_quic_;
146
147 scoped_ptr<P2PStreamSocket> host_channel1_;
148 scoped_ptr<P2PStreamSocket> client_channel1_;
149 scoped_ptr<P2PStreamSocket> host_channel2_;
150 scoped_ptr<P2PStreamSocket> client_channel2_;
151 };
152
153 INSTANTIATE_TEST_CASE_P(SyncWrite,
154 QuicChannelFactoryTest,
155 ::testing::Values(false));
dcaiafa 2015/08/10 23:31:36 That's a neat trick!
156 INSTANTIATE_TEST_CASE_P(AsyncWrite,
157 QuicChannelFactoryTest,
158 ::testing::Values(true));
159
160 TEST_P(QuicChannelFactoryTest, OneChannel) {
161 Initialize();
162
163 scoped_ptr<P2PStreamSocket> host_channel;
164 scoped_ptr<P2PStreamSocket> client_channel;
165 ASSERT_NO_FATAL_FAILURE(
166 CreateChannel(kTestChannelName, &host_channel, &client_channel));
167
168 StreamConnectionTester tester(host_channel.get(), client_channel.get(),
169 kMessageSize, kMessages);
170 tester.Start();
171 message_loop_.Run();
172 tester.CheckResults();
173 }
174
175 TEST_P(QuicChannelFactoryTest, TwoChannels) {
176 Initialize();
177
178 scoped_ptr<P2PStreamSocket> host_channel1_;
179 scoped_ptr<P2PStreamSocket> client_channel1_;
180 ASSERT_NO_FATAL_FAILURE(
181 CreateChannel(kTestChannelName, &host_channel1_, &client_channel1_));
182
183 scoped_ptr<P2PStreamSocket> host_channel2_;
184 scoped_ptr<P2PStreamSocket> client_channel2_;
185 ASSERT_NO_FATAL_FAILURE(
186 CreateChannel(kTestChannelName2, &host_channel2_, &client_channel2_));
187
188 StreamConnectionTester tester1(host_channel1_.get(), client_channel1_.get(),
189 kMessageSize, kMessages);
190 StreamConnectionTester tester2(host_channel2_.get(), client_channel2_.get(),
191 kMessageSize, kMessages);
192 tester1.Start();
193 tester2.Start();
194 while (!tester1.done() || !tester2.done()) {
195 message_loop_.Run();
196 }
197 tester1.CheckResults();
198 tester2.CheckResults();
199 }
200
201 TEST_P(QuicChannelFactoryTest, SendFail) {
202 Initialize();
203
204 scoped_ptr<P2PStreamSocket> host_channel1_;
205 scoped_ptr<P2PStreamSocket> client_channel1_;
206 ASSERT_NO_FATAL_FAILURE(
207 CreateChannel(kTestChannelName, &host_channel1_, &client_channel1_));
208
209 scoped_ptr<P2PStreamSocket> host_channel2_;
210 scoped_ptr<P2PStreamSocket> client_channel2_;
211 ASSERT_NO_FATAL_FAILURE(
212 CreateChannel(kTestChannelName2, &host_channel2_, &client_channel2_));
213
214 host_base_channel_factory_.GetFakeChannel(kQuicChannelName)
215 ->set_next_send_error(net::ERR_FAILED);
216
217 scoped_refptr<net::IOBufferWithSize> buf = CreateTestBuffer(100);
218
219
220 // Try writing to a channel. This should result in all stream being closed due
221 // to an error.
222 {
223 net::TestCompletionCallback write_cb_1;
224 host_channel1_->Write(buf.get(), buf->size(), write_cb_1.callback());
225 base::RunLoop().RunUntilIdle();
226 }
227
228 // Repeated attempt to write should result in an error.
229 {
230 net::TestCompletionCallback write_cb_1;
231 net::TestCompletionCallback write_cb_2;
232 EXPECT_NE(net::OK, host_channel1_->Write(buf.get(), buf->size(),
233 write_cb_1.callback()));
234 EXPECT_FALSE(write_cb_1.have_result());
235 EXPECT_NE(net::OK, host_channel1_->Write(buf.get(), buf->size(),
236 write_cb_2.callback()));
237 EXPECT_FALSE(write_cb_2.have_result());
238 }
239 }
240
241 TEST_P(QuicChannelFactoryTest, DeleteWhenFailed) {
242 Initialize();
243
244 ASSERT_NO_FATAL_FAILURE(
245 CreateChannel(kTestChannelName, &host_channel1_, &client_channel1_));
246 ASSERT_NO_FATAL_FAILURE(
247 CreateChannel(kTestChannelName2, &host_channel2_, &client_channel2_));
248
249 host_base_channel_factory_.GetFakeChannel(kQuicChannelName)
250 ->set_next_send_error(net::ERR_FAILED);
251
252 scoped_refptr<net::IOBufferWithSize> read_buf =
253 new net::IOBufferWithSize(100);
254
255 EXPECT_EQ(net::ERR_IO_PENDING,
256 host_channel1_->Read(
257 read_buf.get(), read_buf->size(),
258 base::Bind(&QuicChannelFactoryTest::FailedReadDeleteAll,
259 base::Unretained(this))));
260
261 // Try writing to a channel. This should result it DeleteAll() called and the
262 // connection torn down.
263 scoped_refptr<net::IOBufferWithSize> buf = CreateTestBuffer(100);
264 net::TestCompletionCallback write_cb_1;
265 host_channel1_->Write(buf.get(), buf->size(), write_cb_1.callback());
266
267 base::RunLoop().RunUntilIdle();
268
269 // Check that the connection was torn down.
270 EXPECT_FALSE(host_quic_);
271 }
272
273 TEST_P(QuicChannelFactoryTest, SessionFail) {
274 host_base_channel_factory_.set_fail_create(true);
275 Initialize();
276
277 host_quic_->CreateChannel(
278 kTestChannelName,
279 base::Bind(&QuicChannelFactoryTest::OnChannelConnectedExpectFail,
280 base::Unretained(this)));
281
282 // host_quic_ may be destroyed at this point in sync mode.
283 if (host_quic_) {
284 host_quic_->CreateChannel(
285 kTestChannelName2,
286 base::Bind(&QuicChannelFactoryTest::OnChannelConnectedNotReached,
287 base::Unretained(this)));
288 }
289
290 base::RunLoop().RunUntilIdle();
291
292 // Check that DeleteAll() was called and the connection was torn down.
293 EXPECT_FALSE(host_quic_);
294 }
295
296 // Verify that the host just ignores incoming stream with unexpected name.
297 TEST_P(QuicChannelFactoryTest, UnknownName) {
298 Initialize();
299
300 // Create a new channel from the client side.
301 client_quic_->CreateChannel(
302 kTestChannelName, base::Bind(&QuicChannelFactoryTest::OnChannelConnected,
303 base::Unretained(this), &client_channel1_,
304 nullptr, nullptr));
305 base::RunLoop().RunUntilIdle();
306
307 EXPECT_EQ(0U, host_quic_->GetP2PSessionForTests()->GetNumOpenStreams());
308 }
309
310 // Verify that incoming streams that have received only partial name are
311 // destroyed correctly.
312 TEST_P(QuicChannelFactoryTest, SendPartialName) {
313 Initialize();
314
315 base::RunLoop().RunUntilIdle();
316
317 net::QuicP2PSession* session = client_quic_->GetP2PSessionForTests();
318 net::QuicP2PStream* stream = session->CreateOutgoingDynamicStream();
319
320 std::string name = kTestChannelName;
321 // Send only half of the name to the host.
322 stream->WriteHeader(std::string(1, static_cast<char>(name.size())) +
323 name.substr(0, name.size() / 2));
324
325 base::RunLoop().RunUntilIdle();
326
327 // Host should have received the new stream and is still waiting for the name.
328 EXPECT_EQ(1U, host_quic_->GetP2PSessionForTests()->GetNumOpenStreams());
329
330 session->CloseStream(stream->id());
331 base::RunLoop().RunUntilIdle();
332
333 // Verify that the stream was closed on the host side.
334 EXPECT_EQ(0U, host_quic_->GetP2PSessionForTests()->GetNumOpenStreams());
335
336 // Create another stream with only partial name and tear down connection while
337 // it's still pending.
338 stream = session->CreateOutgoingDynamicStream();
339 stream->WriteHeader(std::string(1, static_cast<char>(name.size())) +
340 name.substr(0, name.size() / 2));
341 base::RunLoop().RunUntilIdle();
342 EXPECT_EQ(1U, host_quic_->GetP2PSessionForTests()->GetNumOpenStreams());
343 }
344
345 } // namespace protocol
346 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698