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

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
« no previous file with comments | « remoting/protocol/quic_channel_factory.cc ('k') | remoting/remoting_srcs.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 TearDown() override {
82 DeleteAll();
83 // QuicChannelFactory destroys the internals asynchronously. Run all pending
84 // tasks to avoid leaking memory.
85 base::RunLoop().RunUntilIdle();
86 }
87
88 void Initialize() {
89 host_base_channel_factory_.PairWith(&client_base_channel_factory_);
90 host_base_channel_factory_.set_asynchronous_create(GetParam());
91 client_base_channel_factory_.set_asynchronous_create(GetParam());
92
93 const char kTestSessionId[] = "123123";
94 host_quic_.reset(new QuicChannelFactory(kTestSessionId, true));
95 client_quic_.reset(new QuicChannelFactory(kTestSessionId, false));
96
97 std::string message = client_quic_->CreateSessionInitiateConfigMessage();
98 EXPECT_TRUE(host_quic_->ProcessSessionInitiateConfigMessage(message));
99 message = host_quic_->CreateSessionAcceptConfigMessage();
100 EXPECT_TRUE(client_quic_->ProcessSessionAcceptConfigMessage(message));
101
102 const char kTestSharedSecret[] = "Shared Secret";
103 host_quic_->Start(&host_base_channel_factory_, kTestSharedSecret);
104 client_quic_->Start(&client_base_channel_factory_, kTestSharedSecret);
105
106 FakeDatagramSocket* host_base_channel =
107 host_base_channel_factory_.GetFakeChannel(kQuicChannelName);
108 if (host_base_channel)
109 host_base_channel->set_async_send(GetParam());
110
111 FakeDatagramSocket* client_base_channel =
112 client_base_channel_factory_.GetFakeChannel(kQuicChannelName);
113 if (client_base_channel)
114 client_base_channel->set_async_send(GetParam());
115 }
116
117 void CreateChannel(const std::string& name,
118 scoped_ptr<P2PStreamSocket>* host_channel,
119 scoped_ptr<P2PStreamSocket>* client_channel) {
120 int counter = 2;
121 base::RunLoop run_loop;
122 host_quic_->CreateChannel(
123 name,
124 base::Bind(&QuicChannelFactoryTest::OnChannelConnected,
125 base::Unretained(this), host_channel, &counter, &run_loop));
126 client_quic_->CreateChannel(
127 name, base::Bind(&QuicChannelFactoryTest::OnChannelConnected,
128 base::Unretained(this), client_channel, &counter,
129 &run_loop));
130
131 run_loop.Run();
132
133 EXPECT_TRUE(host_channel->get());
134 EXPECT_TRUE(client_channel->get());
135 }
136
137 scoped_refptr<net::IOBufferWithSize> CreateTestBuffer(int size) {
138 scoped_refptr<net::IOBufferWithSize> result =
139 new net::IOBufferWithSize(size);
140 for (int i = 0; i < size; ++i) {
141 result->data()[i] = rand() % 256;
142 }
143 return result;
144 }
145
146 base::MessageLoop message_loop_;
147
148 FakeDatagramChannelFactory host_base_channel_factory_;
149 FakeDatagramChannelFactory client_base_channel_factory_;
150
151 scoped_ptr<QuicChannelFactory> host_quic_;
152 scoped_ptr<QuicChannelFactory> client_quic_;
153
154 scoped_ptr<P2PStreamSocket> host_channel1_;
155 scoped_ptr<P2PStreamSocket> client_channel1_;
156 scoped_ptr<P2PStreamSocket> host_channel2_;
157 scoped_ptr<P2PStreamSocket> client_channel2_;
158 };
159
160 INSTANTIATE_TEST_CASE_P(SyncWrite,
161 QuicChannelFactoryTest,
162 ::testing::Values(false));
163 INSTANTIATE_TEST_CASE_P(AsyncWrite,
164 QuicChannelFactoryTest,
165 ::testing::Values(true));
166
167 TEST_P(QuicChannelFactoryTest, OneChannel) {
168 Initialize();
169
170 scoped_ptr<P2PStreamSocket> host_channel;
171 scoped_ptr<P2PStreamSocket> client_channel;
172 ASSERT_NO_FATAL_FAILURE(
173 CreateChannel(kTestChannelName, &host_channel, &client_channel));
174
175 StreamConnectionTester tester(host_channel.get(), client_channel.get(),
176 kMessageSize, kMessages);
177 tester.Start();
178 message_loop_.Run();
179 tester.CheckResults();
180 }
181
182 TEST_P(QuicChannelFactoryTest, TwoChannels) {
183 Initialize();
184
185 scoped_ptr<P2PStreamSocket> host_channel1_;
186 scoped_ptr<P2PStreamSocket> client_channel1_;
187 ASSERT_NO_FATAL_FAILURE(
188 CreateChannel(kTestChannelName, &host_channel1_, &client_channel1_));
189
190 scoped_ptr<P2PStreamSocket> host_channel2_;
191 scoped_ptr<P2PStreamSocket> client_channel2_;
192 ASSERT_NO_FATAL_FAILURE(
193 CreateChannel(kTestChannelName2, &host_channel2_, &client_channel2_));
194
195 StreamConnectionTester tester1(host_channel1_.get(), client_channel1_.get(),
196 kMessageSize, kMessages);
197 StreamConnectionTester tester2(host_channel2_.get(), client_channel2_.get(),
198 kMessageSize, kMessages);
199 tester1.Start();
200 tester2.Start();
201 while (!tester1.done() || !tester2.done()) {
202 message_loop_.Run();
203 }
204 tester1.CheckResults();
205 tester2.CheckResults();
206 }
207
208 TEST_P(QuicChannelFactoryTest, SendFail) {
209 Initialize();
210
211 scoped_ptr<P2PStreamSocket> host_channel1_;
212 scoped_ptr<P2PStreamSocket> client_channel1_;
213 ASSERT_NO_FATAL_FAILURE(
214 CreateChannel(kTestChannelName, &host_channel1_, &client_channel1_));
215
216 scoped_ptr<P2PStreamSocket> host_channel2_;
217 scoped_ptr<P2PStreamSocket> client_channel2_;
218 ASSERT_NO_FATAL_FAILURE(
219 CreateChannel(kTestChannelName2, &host_channel2_, &client_channel2_));
220
221 host_base_channel_factory_.GetFakeChannel(kQuicChannelName)
222 ->set_next_send_error(net::ERR_FAILED);
223
224 scoped_refptr<net::IOBufferWithSize> buf = CreateTestBuffer(100);
225
226
227 // Try writing to a channel. This should result in all stream being closed due
228 // to an error.
229 {
230 net::TestCompletionCallback write_cb_1;
231 host_channel1_->Write(buf.get(), buf->size(), write_cb_1.callback());
232 base::RunLoop().RunUntilIdle();
233 }
234
235 // Repeated attempt to write should result in an error.
236 {
237 net::TestCompletionCallback write_cb_1;
238 net::TestCompletionCallback write_cb_2;
239 EXPECT_NE(net::OK, host_channel1_->Write(buf.get(), buf->size(),
240 write_cb_1.callback()));
241 EXPECT_FALSE(write_cb_1.have_result());
242 EXPECT_NE(net::OK, host_channel1_->Write(buf.get(), buf->size(),
243 write_cb_2.callback()));
244 EXPECT_FALSE(write_cb_2.have_result());
245 }
246 }
247
248 TEST_P(QuicChannelFactoryTest, DeleteWhenFailed) {
249 Initialize();
250
251 ASSERT_NO_FATAL_FAILURE(
252 CreateChannel(kTestChannelName, &host_channel1_, &client_channel1_));
253 ASSERT_NO_FATAL_FAILURE(
254 CreateChannel(kTestChannelName2, &host_channel2_, &client_channel2_));
255
256 host_base_channel_factory_.GetFakeChannel(kQuicChannelName)
257 ->set_next_send_error(net::ERR_FAILED);
258
259 scoped_refptr<net::IOBufferWithSize> read_buf =
260 new net::IOBufferWithSize(100);
261
262 EXPECT_EQ(net::ERR_IO_PENDING,
263 host_channel1_->Read(
264 read_buf.get(), read_buf->size(),
265 base::Bind(&QuicChannelFactoryTest::FailedReadDeleteAll,
266 base::Unretained(this))));
267
268 // Try writing to a channel. This should result it DeleteAll() called and the
269 // connection torn down.
270 scoped_refptr<net::IOBufferWithSize> buf = CreateTestBuffer(100);
271 net::TestCompletionCallback write_cb_1;
272 host_channel1_->Write(buf.get(), buf->size(), write_cb_1.callback());
273
274 base::RunLoop().RunUntilIdle();
275
276 // Check that the connection was torn down.
277 EXPECT_FALSE(host_quic_);
278 }
279
280 TEST_P(QuicChannelFactoryTest, SessionFail) {
281 host_base_channel_factory_.set_fail_create(true);
282 Initialize();
283
284 host_quic_->CreateChannel(
285 kTestChannelName,
286 base::Bind(&QuicChannelFactoryTest::OnChannelConnectedExpectFail,
287 base::Unretained(this)));
288
289 // host_quic_ may be destroyed at this point in sync mode.
290 if (host_quic_) {
291 host_quic_->CreateChannel(
292 kTestChannelName2,
293 base::Bind(&QuicChannelFactoryTest::OnChannelConnectedNotReached,
294 base::Unretained(this)));
295 }
296
297 base::RunLoop().RunUntilIdle();
298
299 // Check that DeleteAll() was called and the connection was torn down.
300 EXPECT_FALSE(host_quic_);
301 }
302
303 // Verify that the host just ignores incoming stream with unexpected name.
304 TEST_P(QuicChannelFactoryTest, UnknownName) {
305 Initialize();
306
307 // Create a new channel from the client side.
308 client_quic_->CreateChannel(
309 kTestChannelName, base::Bind(&QuicChannelFactoryTest::OnChannelConnected,
310 base::Unretained(this), &client_channel1_,
311 nullptr, nullptr));
312 base::RunLoop().RunUntilIdle();
313
314 EXPECT_EQ(0U, host_quic_->GetP2PSessionForTests()->GetNumOpenStreams());
315 }
316
317 // Verify that incoming streams that have received only partial name are
318 // destroyed correctly.
319 TEST_P(QuicChannelFactoryTest, SendPartialName) {
320 Initialize();
321
322 base::RunLoop().RunUntilIdle();
323
324 net::QuicP2PSession* session = client_quic_->GetP2PSessionForTests();
325 net::QuicP2PStream* stream = session->CreateOutgoingDynamicStream();
326
327 std::string name = kTestChannelName;
328 // Send only half of the name to the host.
329 stream->WriteHeader(std::string(1, static_cast<char>(name.size())) +
330 name.substr(0, name.size() / 2));
331
332 base::RunLoop().RunUntilIdle();
333
334 // Host should have received the new stream and is still waiting for the name.
335 EXPECT_EQ(1U, host_quic_->GetP2PSessionForTests()->GetNumOpenStreams());
336
337 session->CloseStream(stream->id());
338 base::RunLoop().RunUntilIdle();
339
340 // Verify that the stream was closed on the host side.
341 EXPECT_EQ(0U, host_quic_->GetP2PSessionForTests()->GetNumOpenStreams());
342
343 // Create another stream with only partial name and tear down connection while
344 // it's still pending.
345 stream = session->CreateOutgoingDynamicStream();
346 stream->WriteHeader(std::string(1, static_cast<char>(name.size())) +
347 name.substr(0, name.size() / 2));
348 base::RunLoop().RunUntilIdle();
349 EXPECT_EQ(1U, host_quic_->GetP2PSessionForTests()->GetNumOpenStreams());
350 }
351
352 } // namespace protocol
353 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/protocol/quic_channel_factory.cc ('k') | remoting/remoting_srcs.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698