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

Side by Side Diff: net/quic/quartc/quartc_session_test.cc

Issue 2916033003: Landing Recent QUIC changes until 03:18 AM, May 28, UTC (Closed)
Patch Set: A few more EXPORTs. Created 3 years, 6 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 | « net/quic/quartc/quartc_session_interface.h ('k') | net/quic/quartc/quartc_stream.h » ('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 (c) 2017 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 "net/quic/quartc/quartc_session.h"
6
7 #include "net/quic/core/crypto/crypto_server_config_protobuf.h"
8 #include "net/quic/core/quic_simple_buffer_allocator.h"
9 #include "net/quic/core/quic_types.h"
10 #include "net/quic/quartc/quartc_factory.h"
11 #include "net/quic/quartc/quartc_factory_interface.h"
12 #include "net/quic/quartc/quartc_packet_writer.h"
13 #include "net/quic/quartc/quartc_stream_interface.h"
14 #include "net/quic/test_tools/mock_clock.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 using std::string;
19
20 namespace net {
21
22 namespace {
23
24 static const char kExporterLabel[] = "label";
25 static const uint8_t kExporterContext[] = "context";
26 static const size_t kExporterContextLen = sizeof(kExporterContext);
27 static const size_t kOutputKeyLength = 20;
28 static QuartcStreamInterface::WriteParameters kDefaultWriteParam;
29 static QuartcSessionInterface::OutgoingStreamParameters kDefaultStreamParam;
30 static QuicByteCount kDefaultMaxPacketSize = 1200;
31
32 // Single-threaded scheduled task runner based on a MockClock.
33 //
34 // Simulates asynchronous execution on a single thread by holding scheduled
35 // tasks until Run() is called. Performs no synchronization, assumes that
36 // Schedule() and Run() are called on the same thread.
37 class FakeTaskRunner : public QuartcTaskRunnerInterface {
38 public:
39 explicit FakeTaskRunner(MockClock* clock)
40 : tasks_([this](const TaskType& l, const TaskType& r) {
41 // Items at a later time should run after items at an earlier time.
42 // Priority queue comparisons should return true if l appears after r.
43 return l->time() > r->time();
44 }),
45 clock_(clock) {}
46
47 ~FakeTaskRunner() override {}
48
49 // Runs all tasks scheduled in the next total_ms milliseconds. Advances the
50 // clock by total_ms. Runs tasks in time order. Executes tasks scheduled at
51 // the same in an arbitrary order.
52 void Run(uint32_t total_ms) {
53 for (uint32_t i = 0; i < total_ms; ++i) {
54 while (!tasks_.empty() && tasks_.top()->time() <= clock_->Now()) {
55 tasks_.top()->Run();
56 tasks_.pop();
57 }
58 clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
59 }
60 }
61
62 private:
63 class InnerTask {
64 public:
65 InnerTask(std::function<void()> task, QuicTime time)
66 : task_(std::move(task)), time_(time) {}
67
68 void Cancel() { cancelled_ = true; }
69
70 void Run() {
71 if (!cancelled_) {
72 task_();
73 }
74 }
75
76 QuicTime time() const { return time_; }
77
78 private:
79 bool cancelled_ = false;
80 std::function<void()> task_;
81 QuicTime time_;
82 };
83
84 public:
85 // Hook for cancelling a scheduled task.
86 class ScheduledTask : public QuartcTaskRunnerInterface::ScheduledTask {
87 public:
88 explicit ScheduledTask(std::shared_ptr<InnerTask> inner)
89 : inner_(std::move(inner)) {}
90
91 // Cancel if the caller deletes the ScheduledTask. This behavior is
92 // consistent with the actual task runner Quartc uses.
93 ~ScheduledTask() override { Cancel(); }
94
95 // ScheduledTask implementation.
96 void Cancel() override { inner_->Cancel(); }
97
98 private:
99 std::shared_ptr<InnerTask> inner_;
100 };
101
102 // See QuartcTaskRunnerInterface.
103 std::unique_ptr<QuartcTaskRunnerInterface::ScheduledTask> Schedule(
104 Task* task,
105 uint64_t delay_ms) override {
106 auto inner = std::shared_ptr<InnerTask>(new InnerTask(
107 [task] { task->Run(); },
108 clock_->Now() + QuicTime::Delta::FromMilliseconds(delay_ms)));
109 tasks_.push(inner);
110 return std::unique_ptr<QuartcTaskRunnerInterface::ScheduledTask>(
111 new ScheduledTask(inner));
112 }
113
114 // Schedules a function to run immediately.
115 void Schedule(std::function<void()> task) {
116 tasks_.push(std::shared_ptr<InnerTask>(
117 new InnerTask(std::move(task), clock_->Now())));
118 }
119
120 private:
121 // InnerTasks are shared by the queue and ScheduledTask (which hooks into it
122 // to implement Cancel()).
123 using TaskType = std::shared_ptr<InnerTask>;
124 std::priority_queue<TaskType,
125 std::vector<TaskType>,
126 std::function<bool(const TaskType&, const TaskType&)>>
127 tasks_;
128 MockClock* clock_;
129 };
130
131 // QuartcClock that wraps a MockClock.
132 //
133 // This is silly because Quartc wraps it as a QuicClock, and MockClock is
134 // already a QuicClock. But we don't have much choice. We need to pass a
135 // QuartcClockInterface into the Quartc wrappers.
136 class MockQuartcClock : public QuartcClockInterface {
137 public:
138 explicit MockQuartcClock(MockClock* clock) : clock_(clock) {}
139
140 int64_t NowMicroseconds() override {
141 return clock_->WallNow().ToUNIXMicroseconds();
142 }
143
144 private:
145 MockClock* clock_;
146 };
147
148 // Used by QuicCryptoServerConfig to provide server credentials, returning a
149 // canned response equal to |success|.
150 class FakeProofSource : public ProofSource {
151 public:
152 explicit FakeProofSource(bool success) : success_(success) {}
153
154 // ProofSource override.
155 void GetProof(const QuicSocketAddress& server_ip,
156 const string& hostname,
157 const string& server_config,
158 QuicVersion quic_version,
159 QuicStringPiece chlo_hash,
160 const QuicTagVector& connection_options,
161 std::unique_ptr<Callback> callback) override {
162 QuicReferenceCountedPointer<ProofSource::Chain> chain;
163 QuicCryptoProof proof;
164 if (success_) {
165 std::vector<string> certs;
166 certs.push_back("Required to establish handshake");
167 chain = new ProofSource::Chain(certs);
168 proof.signature = "Signature";
169 proof.leaf_cert_scts = "Time";
170 }
171 callback->Run(success_, chain, proof, nullptr /* details */);
172 }
173
174 private:
175 // Whether or not obtaining proof source succeeds.
176 bool success_;
177 };
178
179 // Used by QuicCryptoClientConfig to verify server credentials, returning a
180 // canned response of QUIC_SUCCESS if |success| is true.
181 class FakeProofVerifier : public ProofVerifier {
182 public:
183 explicit FakeProofVerifier(bool success) : success_(success) {}
184
185 // ProofVerifier override
186 QuicAsyncStatus VerifyProof(
187 const string& hostname,
188 const uint16_t port,
189 const string& server_config,
190 QuicVersion quic_version,
191 QuicStringPiece chlo_hash,
192 const std::vector<string>& certs,
193 const string& cert_sct,
194 const string& signature,
195 const ProofVerifyContext* context,
196 string* error_details,
197 std::unique_ptr<ProofVerifyDetails>* verify_details,
198 std::unique_ptr<ProofVerifierCallback> callback) override {
199 return success_ ? QUIC_SUCCESS : QUIC_FAILURE;
200 }
201
202 QuicAsyncStatus VerifyCertChain(
203 const string& hostname,
204 const std::vector<string>& certs,
205 const ProofVerifyContext* context,
206 string* error_details,
207 std::unique_ptr<ProofVerifyDetails>* details,
208 std::unique_ptr<ProofVerifierCallback> callback) override {
209 LOG(INFO) << "VerifyProof() ignoring credentials and returning success";
210 return success_ ? QUIC_SUCCESS : QUIC_FAILURE;
211 }
212
213 private:
214 // Whether or not proof verification succeeds.
215 bool success_;
216 };
217
218 // Used by the FakeTransportChannel.
219 class FakeTransportChannelObserver {
220 public:
221 virtual ~FakeTransportChannelObserver() {}
222
223 // Called when the other peer is trying to send message.
224 virtual void OnTransportChannelReadPacket(const string& data) = 0;
225 };
226
227 // Simulate the P2P communication transport. Used by the
228 // QuartcSessionInterface::Transport.
229 class FakeTransportChannel {
230 public:
231 explicit FakeTransportChannel(FakeTaskRunner* task_runner, MockClock* clock)
232 : task_runner_(task_runner), clock_(clock) {}
233
234 void SetDestination(FakeTransportChannel* dest) {
235 if (!dest_) {
236 dest_ = dest;
237 dest_->SetDestination(this);
238 }
239 }
240
241 int SendPacket(const char* data, size_t len) {
242 // If the destination is not set.
243 if (!dest_) {
244 return -1;
245 }
246 // Advance the time 10us to ensure the RTT is never 0ms.
247 clock_->AdvanceTime(QuicTime::Delta::FromMicroseconds(10));
248 if (async_ && task_runner_) {
249 string packet(data, len);
250 task_runner_->Schedule([this, packet] { send(packet); });
251 } else {
252 send(string(data, len));
253 }
254 return static_cast<int>(len);
255 }
256
257 void send(const string& data) {
258 DCHECK(dest_);
259 DCHECK(dest_->observer());
260 dest_->observer()->OnTransportChannelReadPacket(data);
261 }
262
263 FakeTransportChannelObserver* observer() { return observer_; }
264
265 void SetObserver(FakeTransportChannelObserver* observer) {
266 observer_ = observer;
267 }
268
269 void SetAsync(bool async) { async_ = async; }
270
271 private:
272 // The writing destination of this channel.
273 FakeTransportChannel* dest_ = nullptr;
274 // The observer of this channel. Called when the received the data.
275 FakeTransportChannelObserver* observer_ = nullptr;
276 // If async, will send packets by running asynchronous tasks.
277 bool async_ = false;
278 // Used to send data asynchronously.
279 FakeTaskRunner* task_runner_;
280 // The test clock. Used to ensure the RTT is not 0.
281 MockClock* clock_;
282 };
283
284 // Used by the QuartcPacketWriter.
285 class FakeTransport : public QuartcSessionInterface::PacketTransport {
286 public:
287 explicit FakeTransport(FakeTransportChannel* channel) : channel_(channel) {}
288
289 bool CanWrite() override { return true; }
290
291 int Write(const char* buffer, size_t buf_len) override {
292 DCHECK(channel_);
293 return channel_->SendPacket(buffer, buf_len);
294 }
295
296 private:
297 FakeTransportChannel* channel_;
298 };
299
300 class FakeQuartcSessionDelegate : public QuartcSessionInterface::Delegate {
301 public:
302 explicit FakeQuartcSessionDelegate(
303 QuartcStreamInterface::Delegate* stream_delegate)
304 : stream_delegate_(stream_delegate) {}
305 // Called when peers have established forward-secure encryption
306 void OnCryptoHandshakeComplete() override {
307 LOG(INFO) << "Crypto handshake complete!";
308 }
309 // Called when connection closes locally, or remotely by peer.
310 void OnConnectionClosed(int error_code, bool from_remote) override {
311 connected_ = false;
312 }
313 // Called when an incoming QUIC stream is created.
314 void OnIncomingStream(QuartcStreamInterface* quartc_stream) override {
315 last_incoming_stream_ = quartc_stream;
316 last_incoming_stream_->SetDelegate(stream_delegate_);
317 }
318
319 QuartcStreamInterface* incoming_stream() { return last_incoming_stream_; }
320
321 bool connected() { return connected_; }
322
323 private:
324 QuartcStreamInterface* last_incoming_stream_;
325 bool connected_ = true;
326 QuartcStream::Delegate* stream_delegate_;
327 };
328
329 class FakeQuartcStreamDelegate : public QuartcStreamInterface::Delegate {
330 public:
331 void OnReceived(QuartcStreamInterface* stream,
332 const char* data,
333 size_t size) override {
334 last_received_data_ = string(data, size);
335 }
336
337 void OnClose(QuartcStreamInterface* stream) override {}
338
339 void OnBufferedAmountDecrease(QuartcStreamInterface* stream) override {}
340
341 string data() { return last_received_data_; }
342
343 private:
344 string last_received_data_;
345 };
346
347 class QuartcSessionForTest : public QuartcSession,
348 public FakeTransportChannelObserver {
349 public:
350 QuartcSessionForTest(std::unique_ptr<QuicConnection> connection,
351 const QuicConfig& config,
352 const string& remote_fingerprint_value,
353 Perspective perspective,
354 QuicConnectionHelperInterface* helper,
355 QuicClock* clock)
356 : QuartcSession(std::move(connection),
357 config,
358 remote_fingerprint_value,
359 perspective,
360 helper,
361 clock) {
362 stream_delegate_.reset(new FakeQuartcStreamDelegate);
363 session_delegate_.reset(
364 new FakeQuartcSessionDelegate(stream_delegate_.get()));
365
366 SetDelegate(session_delegate_.get());
367 }
368
369 // QuartcPacketWriter override.
370 void OnTransportChannelReadPacket(const string& data) override {
371 OnTransportReceived(data.c_str(), data.length());
372 }
373
374 string data() { return stream_delegate_->data(); }
375
376 bool has_data() { return !data().empty(); }
377
378 FakeQuartcSessionDelegate* session_delegate() {
379 return session_delegate_.get();
380 }
381
382 FakeQuartcStreamDelegate* stream_delegate() { return stream_delegate_.get(); }
383
384 private:
385 std::unique_ptr<FakeQuartcStreamDelegate> stream_delegate_;
386 std::unique_ptr<FakeQuartcSessionDelegate> session_delegate_;
387 };
388
389 class QuartcSessionTest : public ::testing::Test,
390 public QuicConnectionHelperInterface {
391 public:
392 ~QuartcSessionTest() override {}
393
394 void Init() {
395 // Quic crashes if packets are sent at time 0, and the clock defaults to 0.
396 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
397 client_channel_.reset(new FakeTransportChannel(&task_runner_, &clock_));
398 server_channel_.reset(new FakeTransportChannel(&task_runner_, &clock_));
399 // Make the channel asynchronous so that two peer will not keep calling each
400 // other when they exchange information.
401 client_channel_->SetAsync(true);
402 client_channel_->SetDestination(server_channel_.get());
403
404 client_transport_.reset(new FakeTransport(client_channel_.get()));
405 server_transport_.reset(new FakeTransport(server_channel_.get()));
406
407 client_writer_.reset(
408 new QuartcPacketWriter(client_transport_.get(), kDefaultMaxPacketSize));
409 server_writer_.reset(
410 new QuartcPacketWriter(server_transport_.get(), kDefaultMaxPacketSize));
411 }
412
413 // The parameters are used to control whether the handshake will success or
414 // not.
415 void CreateClientAndServerSessions(bool client_handshake_success = true,
416 bool server_handshake_success = true) {
417 Init();
418 client_peer_ = CreateSession(Perspective::IS_CLIENT);
419 server_peer_ = CreateSession(Perspective::IS_SERVER);
420
421 client_channel_->SetObserver(client_peer_.get());
422 server_channel_->SetObserver(server_peer_.get());
423
424 client_peer_->SetClientCryptoConfig(
425 new QuicCryptoClientConfig(std::unique_ptr<ProofVerifier>(
426 new FakeProofVerifier(client_handshake_success))));
427
428 QuicCryptoServerConfig* server_config = new QuicCryptoServerConfig(
429 "TESTING", QuicRandom::GetInstance(),
430 std::unique_ptr<FakeProofSource>(
431 new FakeProofSource(server_handshake_success)));
432 // Provide server with serialized config string to prove ownership.
433 QuicCryptoServerConfig::ConfigOptions options;
434 std::unique_ptr<QuicServerConfigProtobuf> primary_config(
435 server_config->GenerateConfig(QuicRandom::GetInstance(), &clock_,
436 options));
437 std::unique_ptr<CryptoHandshakeMessage> message(
438 server_config->AddConfig(std::move(primary_config), clock_.WallNow()));
439
440 server_peer_->SetServerCryptoConfig(server_config);
441 }
442
443 std::unique_ptr<QuartcSessionForTest> CreateSession(Perspective perspective) {
444 std::unique_ptr<QuicConnection> quic_connection =
445 CreateConnection(perspective);
446 string remote_fingerprint_value = "value";
447 QuicConfig config;
448 return std::unique_ptr<QuartcSessionForTest>(new QuartcSessionForTest(
449 std::move(quic_connection), config, remote_fingerprint_value,
450 perspective, this, &clock_));
451 }
452
453 std::unique_ptr<QuicConnection> CreateConnection(Perspective perspective) {
454 QuartcPacketWriter* writer = perspective == Perspective::IS_CLIENT
455 ? client_writer_.get()
456 : server_writer_.get();
457 QuicIpAddress ip;
458 ip.FromString("0.0.0.0");
459 bool owns_writer = false;
460 if (!alarm_factory_) {
461 // QuartcFactory is only used as an alarm factory.
462 QuartcFactoryConfig config;
463 config.clock = &quartc_clock_;
464 config.task_runner = &task_runner_;
465 alarm_factory_.reset(new QuartcFactory(config));
466 }
467 return std::unique_ptr<QuicConnection>(new QuicConnection(
468 0, QuicSocketAddress(ip, 0), this /*QuicConnectionHelperInterface*/,
469 alarm_factory_.get(), writer, owns_writer, perspective,
470 AllSupportedVersions()));
471 }
472
473 // Runs all tasks scheduled in the next 200 ms.
474 void RunTasks() { task_runner_.Run(200); }
475
476 void StartHandshake() {
477 server_peer_->StartCryptoHandshake();
478 client_peer_->StartCryptoHandshake();
479 RunTasks();
480 }
481
482 // Test handshake establishment and sending/receiving of data for two
483 // directions.
484 void TestStreamConnection() {
485 ASSERT_TRUE(server_peer_->IsCryptoHandshakeConfirmed());
486 ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed());
487 ASSERT_TRUE(server_peer_->IsEncryptionEstablished());
488 ASSERT_TRUE(client_peer_->IsEncryptionEstablished());
489
490 uint8_t server_key[kOutputKeyLength];
491 uint8_t client_key[kOutputKeyLength];
492 bool use_context = true;
493 bool server_success = server_peer_->ExportKeyingMaterial(
494 kExporterLabel, kExporterContext, kExporterContextLen, use_context,
495 server_key, kOutputKeyLength);
496 ASSERT_TRUE(server_success);
497 bool client_success = client_peer_->ExportKeyingMaterial(
498 kExporterLabel, kExporterContext, kExporterContextLen, use_context,
499 client_key, kOutputKeyLength);
500 ASSERT_TRUE(client_success);
501 EXPECT_EQ(0, memcmp(server_key, client_key, sizeof(server_key)));
502
503 // Now we can establish encrypted outgoing stream.
504 QuartcStreamInterface* outgoing_stream =
505 server_peer_->CreateOutgoingStream(kDefaultStreamParam);
506 ASSERT_NE(nullptr, outgoing_stream);
507 EXPECT_TRUE(server_peer_->HasOpenDynamicStreams());
508
509 outgoing_stream->SetDelegate(server_peer_->stream_delegate());
510
511 // Send a test message from peer 1 to peer 2.
512 const char kTestMessage[] = "Hello";
513 outgoing_stream->Write(kTestMessage, strlen(kTestMessage),
514 kDefaultWriteParam);
515 RunTasks();
516
517 // Wait for peer 2 to receive messages.
518 ASSERT_TRUE(client_peer_->has_data());
519
520 QuartcStreamInterface* incoming =
521 client_peer_->session_delegate()->incoming_stream();
522 ASSERT_TRUE(incoming);
523 EXPECT_TRUE(client_peer_->HasOpenDynamicStreams());
524
525 EXPECT_EQ(client_peer_->data(), kTestMessage);
526 // Send a test message from peer 2 to peer 1.
527 const char kTestResponse[] = "Response";
528 incoming->Write(kTestResponse, strlen(kTestResponse), kDefaultWriteParam);
529 RunTasks();
530 // Wait for peer 1 to receive messages.
531 ASSERT_TRUE(server_peer_->has_data());
532
533 EXPECT_EQ(server_peer_->data(), kTestResponse);
534 }
535
536 // Test that client and server are not connected after handshake failure.
537 void TestDisconnectAfterFailedHandshake() {
538 EXPECT_TRUE(!client_peer_->session_delegate()->connected());
539 EXPECT_TRUE(!server_peer_->session_delegate()->connected());
540
541 EXPECT_FALSE(client_peer_->IsEncryptionEstablished());
542 EXPECT_FALSE(client_peer_->IsCryptoHandshakeConfirmed());
543
544 EXPECT_FALSE(server_peer_->IsEncryptionEstablished());
545 EXPECT_FALSE(server_peer_->IsCryptoHandshakeConfirmed());
546 }
547
548 const QuicClock* GetClock() const override { return &clock_; }
549
550 QuicRandom* GetRandomGenerator() override {
551 return QuicRandom::GetInstance();
552 }
553
554 QuicBufferAllocator* GetBufferAllocator() override {
555 return &buffer_allocator_;
556 }
557
558 protected:
559 std::unique_ptr<QuicAlarmFactory> alarm_factory_;
560 SimpleBufferAllocator buffer_allocator_;
561 MockClock clock_;
562 MockQuartcClock quartc_clock_{&clock_};
563
564 std::unique_ptr<FakeTransportChannel> client_channel_;
565 std::unique_ptr<FakeTransportChannel> server_channel_;
566 std::unique_ptr<FakeTransport> client_transport_;
567 std::unique_ptr<FakeTransport> server_transport_;
568 std::unique_ptr<QuartcPacketWriter> client_writer_;
569 std::unique_ptr<QuartcPacketWriter> server_writer_;
570 std::unique_ptr<QuartcSessionForTest> client_peer_;
571 std::unique_ptr<QuartcSessionForTest> server_peer_;
572
573 FakeTaskRunner task_runner_{&clock_};
574 };
575
576 TEST_F(QuartcSessionTest, StreamConnection) {
577 CreateClientAndServerSessions();
578 StartHandshake();
579 TestStreamConnection();
580 }
581
582 TEST_F(QuartcSessionTest, ClientRejection) {
583 CreateClientAndServerSessions(false /*client_handshake_success*/,
584 true /*server_handshake_success*/);
585 StartHandshake();
586 TestDisconnectAfterFailedHandshake();
587 }
588
589 TEST_F(QuartcSessionTest, ServerRejection) {
590 CreateClientAndServerSessions(true /*client_handshake_success*/,
591 false /*server_handshake_success*/);
592 StartHandshake();
593 TestDisconnectAfterFailedHandshake();
594 }
595
596 // Test that data streams are not created before handshake.
597 TEST_F(QuartcSessionTest, CannotCreateDataStreamBeforeHandshake) {
598 CreateClientAndServerSessions();
599 EXPECT_EQ(nullptr, server_peer_->CreateOutgoingStream(kDefaultStreamParam));
600 EXPECT_EQ(nullptr, client_peer_->CreateOutgoingStream(kDefaultStreamParam));
601 }
602
603 TEST_F(QuartcSessionTest, CloseQuartcStream) {
604 CreateClientAndServerSessions();
605 StartHandshake();
606 ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed());
607 ASSERT_TRUE(server_peer_->IsCryptoHandshakeConfirmed());
608 QuartcStreamInterface* stream =
609 client_peer_->CreateOutgoingStream(kDefaultStreamParam);
610 ASSERT_NE(nullptr, stream);
611
612 uint32_t id = stream->stream_id();
613 EXPECT_FALSE(client_peer_->IsClosedStream(id));
614 stream->SetDelegate(client_peer_->stream_delegate());
615 stream->Close();
616 RunTasks();
617 EXPECT_TRUE(client_peer_->IsClosedStream(id));
618 }
619
620 TEST_F(QuartcSessionTest, CancelQuartcStream) {
621 CreateClientAndServerSessions();
622 StartHandshake();
623 ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed());
624 ASSERT_TRUE(server_peer_->IsCryptoHandshakeConfirmed());
625
626 QuartcStreamInterface* stream =
627 client_peer_->CreateOutgoingStream(kDefaultStreamParam);
628 ASSERT_NE(nullptr, stream);
629
630 uint32_t id = stream->stream_id();
631 EXPECT_FALSE(client_peer_->IsClosedStream(id));
632 stream->SetDelegate(client_peer_->stream_delegate());
633 client_peer_->CancelStream(id);
634 EXPECT_EQ(stream->stream_error(),
635 QuicRstStreamErrorCode::QUIC_STREAM_CANCELLED);
636 EXPECT_TRUE(client_peer_->IsClosedStream(id));
637 }
638
639 } // namespace
640
641 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quartc/quartc_session_interface.h ('k') | net/quic/quartc/quartc_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698