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

Side by Side Diff: components/grpc_support/bidirectional_stream_unittest.cc

Issue 2487863003: Revert of Revert "Revert of Moving gRPC support interfaces out of cronet and into a new component. (patchset … (Closed)
Patch Set: Created 4 years, 1 month 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 | « components/grpc_support/bidirectional_stream_c.cc ('k') | components/grpc_support/include/DEPS » ('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 2016 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 <stdint.h>
6 #include <list>
7 #include <map>
8 #include <string>
9
10 #include "base/logging.h"
11 #include "base/macros.h"
12 #include "base/memory/ptr_util.h"
13 #include "base/strings/string_util.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "components/grpc_support/include/bidirectional_stream_c.h"
16 #include "components/grpc_support/test/get_stream_engine.h"
17 #include "components/grpc_support/test/quic_test_server.h"
18 #include "net/base/net_errors.h"
19 #include "net/test/test_data_directory.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "url/gurl.h"
22
23 namespace {
24
25 bidirectional_stream_header kTestHeaders[] = {
26 {"header1", "foo"},
27 {"header2", "bar"},
28 };
29 const bidirectional_stream_header_array kTestHeadersArray = {2, 2,
30 kTestHeaders};
31 } // namespace
32
33 namespace grpc_support {
34
35 class BidirectionalStreamTest : public ::testing::TestWithParam<bool> {
36 protected:
37 void SetUp() override {
38 StartQuicTestServer();
39 }
40
41 void TearDown() override {
42 ShutdownQuicTestServer();
43 }
44
45 BidirectionalStreamTest() {}
46 ~BidirectionalStreamTest() override {}
47
48 stream_engine* engine() {
49 return GetTestStreamEngine(GetQuicTestServerPort());
50 }
51
52 private:
53 DISALLOW_COPY_AND_ASSIGN(BidirectionalStreamTest);
54 };
55
56 class TestBidirectionalStreamCallback {
57 public:
58 enum ResponseStep {
59 NOTHING,
60 ON_STREAM_READY,
61 ON_RESPONSE_STARTED,
62 ON_READ_COMPLETED,
63 ON_WRITE_COMPLETED,
64 ON_TRAILERS,
65 ON_CANCELED,
66 ON_FAILED,
67 ON_SUCCEEDED
68 };
69
70 struct WriteData {
71 std::string buffer;
72 // If |flush| is true, then bidirectional_stream_flush() will be
73 // called after writing of the |buffer|.
74 bool flush;
75
76 WriteData(const std::string& buffer, bool flush);
77 ~WriteData();
78
79 DISALLOW_COPY_AND_ASSIGN(WriteData);
80 };
81
82 bidirectional_stream* stream;
83 base::WaitableEvent stream_done_event;
84
85 // Test parameters.
86 std::map<std::string, std::string> request_headers;
87 std::list<std::unique_ptr<WriteData>> write_data;
88 std::string expected_negotiated_protocol;
89 ResponseStep cancel_from_step;
90 size_t read_buffer_size;
91
92 // Test results.
93 ResponseStep response_step;
94 char* read_buffer;
95 std::map<std::string, std::string> response_headers;
96 std::map<std::string, std::string> response_trailers;
97 std::vector<std::string> read_data;
98 int net_error;
99
100 TestBidirectionalStreamCallback()
101 : stream(nullptr),
102 stream_done_event(base::WaitableEvent::ResetPolicy::MANUAL,
103 base::WaitableEvent::InitialState::NOT_SIGNALED),
104 expected_negotiated_protocol("quic/1+spdy/3"),
105 cancel_from_step(NOTHING),
106 read_buffer_size(32768),
107 response_step(NOTHING),
108 read_buffer(nullptr),
109 net_error(0) {}
110
111 ~TestBidirectionalStreamCallback() {
112 if (read_buffer)
113 delete[] read_buffer;
114 }
115
116 static TestBidirectionalStreamCallback* FromStream(
117 bidirectional_stream* stream) {
118 DCHECK(stream);
119 return (TestBidirectionalStreamCallback*)stream->annotation;
120 }
121
122 virtual bool MaybeCancel(bidirectional_stream* stream, ResponseStep step) {
123 DCHECK_EQ(stream, this->stream);
124 response_step = step;
125 DLOG(WARNING) << "Step: " << step;
126
127 if (step != cancel_from_step)
128 return false;
129
130 bidirectional_stream_cancel(stream);
131 bidirectional_stream_write(stream, "abc", 3, false);
132
133 return true;
134 }
135
136 void SignalDone() { stream_done_event.Signal(); }
137
138 void BlockForDone() { stream_done_event.Wait(); }
139
140 void AddWriteData(const std::string& data) { AddWriteData(data, true); }
141 void AddWriteData(const std::string& data, bool flush) {
142 write_data.push_back(base::MakeUnique<WriteData>(data, flush));
143 }
144
145 virtual void MaybeWriteNextData(bidirectional_stream* stream) {
146 DCHECK_EQ(stream, this->stream);
147 if (write_data.empty())
148 return;
149 for (const auto& data : write_data) {
150 bidirectional_stream_write(stream, data->buffer.c_str(),
151 data->buffer.size(),
152 data == write_data.back());
153 if (data->flush) {
154 bidirectional_stream_flush(stream);
155 break;
156 }
157 }
158 }
159
160 bidirectional_stream_callback* callback() const { return &s_callback; }
161
162 private:
163 // C callbacks.
164 static void on_stream_ready_callback(bidirectional_stream* stream) {
165 TestBidirectionalStreamCallback* test = FromStream(stream);
166 if (test->MaybeCancel(stream, ON_STREAM_READY))
167 return;
168 test->MaybeWriteNextData(stream);
169 }
170
171 static void on_response_headers_received_callback(
172 bidirectional_stream* stream,
173 const bidirectional_stream_header_array* headers,
174 const char* negotiated_protocol) {
175 TestBidirectionalStreamCallback* test = FromStream(stream);
176 ASSERT_EQ(test->expected_negotiated_protocol,
177 std::string(negotiated_protocol));
178 for (size_t i = 0; i < headers->count; ++i) {
179 test->response_headers[headers->headers[i].key] =
180 headers->headers[i].value;
181 }
182 if (test->MaybeCancel(stream, ON_RESPONSE_STARTED))
183 return;
184 test->read_buffer = new char[test->read_buffer_size];
185 bidirectional_stream_read(stream, test->read_buffer,
186 test->read_buffer_size);
187 }
188
189 static void on_read_completed_callback(bidirectional_stream* stream,
190 char* data,
191 int count) {
192 TestBidirectionalStreamCallback* test = FromStream(stream);
193 test->read_data.push_back(std::string(data, count));
194 if (test->MaybeCancel(stream, ON_READ_COMPLETED))
195 return;
196 if (count == 0)
197 return;
198 bidirectional_stream_read(stream, test->read_buffer,
199 test->read_buffer_size);
200 }
201
202 static void on_write_completed_callback(bidirectional_stream* stream,
203 const char* data) {
204 TestBidirectionalStreamCallback* test = FromStream(stream);
205 ASSERT_EQ(test->write_data.front()->buffer.c_str(), data);
206 if (test->MaybeCancel(stream, ON_WRITE_COMPLETED))
207 return;
208 bool continue_writing = test->write_data.front()->flush;
209 test->write_data.pop_front();
210 if (continue_writing)
211 test->MaybeWriteNextData(stream);
212 }
213
214 static void on_response_trailers_received_callback(
215 bidirectional_stream* stream,
216 const bidirectional_stream_header_array* trailers) {
217 TestBidirectionalStreamCallback* test = FromStream(stream);
218 for (size_t i = 0; i < trailers->count; ++i) {
219 test->response_trailers[trailers->headers[i].key] =
220 trailers->headers[i].value;
221 }
222
223 if (test->MaybeCancel(stream, ON_TRAILERS))
224 return;
225 }
226
227 static void on_succeded_callback(bidirectional_stream* stream) {
228 TestBidirectionalStreamCallback* test = FromStream(stream);
229 ASSERT_TRUE(test->write_data.empty());
230 test->MaybeCancel(stream, ON_SUCCEEDED);
231 test->SignalDone();
232 }
233
234 static void on_failed_callback(bidirectional_stream* stream, int net_error) {
235 TestBidirectionalStreamCallback* test = FromStream(stream);
236 test->net_error = net_error;
237 test->MaybeCancel(stream, ON_FAILED);
238 test->SignalDone();
239 }
240
241 static void on_canceled_callback(bidirectional_stream* stream) {
242 TestBidirectionalStreamCallback* test = FromStream(stream);
243 test->MaybeCancel(stream, ON_CANCELED);
244 test->SignalDone();
245 }
246
247 static bidirectional_stream_callback s_callback;
248 };
249
250 bidirectional_stream_callback TestBidirectionalStreamCallback::s_callback = {
251 on_stream_ready_callback,
252 on_response_headers_received_callback,
253 on_read_completed_callback,
254 on_write_completed_callback,
255 on_response_trailers_received_callback,
256 on_succeded_callback,
257 on_failed_callback,
258 on_canceled_callback};
259
260 TestBidirectionalStreamCallback::WriteData::WriteData(const std::string& data,
261 bool flush_after)
262 : buffer(data), flush(flush_after) {}
263
264 TestBidirectionalStreamCallback::WriteData::~WriteData() {}
265
266 TEST_P(BidirectionalStreamTest, StartExampleBidiStream) {
267 TestBidirectionalStreamCallback test;
268 test.AddWriteData("Hello, ");
269 test.AddWriteData("world!");
270 // Use small read buffer size to test that response is split properly.
271 test.read_buffer_size = 2;
272 test.stream = bidirectional_stream_create(engine(), &test, test.callback());
273 DCHECK(test.stream);
274 bidirectional_stream_delay_request_headers_until_flush(test.stream,
275 GetParam());
276 bidirectional_stream_start(test.stream, kTestServerUrl, 0,
277 "POST", &kTestHeadersArray, false);
278 test.BlockForDone();
279 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
280 ASSERT_EQ(std::string(kHelloHeaderValue),
281 test.response_headers[kHelloHeaderName]);
282 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
283 ASSERT_EQ(std::string(kHelloBodyValue, 2), test.read_data.front());
284 // Verify that individual read data joined using empty separator match
285 // expected body.
286 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, ""));
287 ASSERT_EQ(std::string(kHelloTrailerValue),
288 test.response_trailers[kHelloTrailerName]);
289 bidirectional_stream_destroy(test.stream);
290 }
291
292 TEST_P(BidirectionalStreamTest, SimplePutWithEmptyWriteDataAtTheEnd) {
293 TestBidirectionalStreamCallback test;
294 test.AddWriteData("Hello, ");
295 test.AddWriteData("world!");
296 test.AddWriteData("");
297 test.stream = bidirectional_stream_create(engine(), &test, test.callback());
298 DCHECK(test.stream);
299 bidirectional_stream_delay_request_headers_until_flush(test.stream,
300 GetParam());
301 bidirectional_stream_start(test.stream, kTestServerUrl, 0,
302 "PUT", &kTestHeadersArray, false);
303 test.BlockForDone();
304 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
305 ASSERT_EQ(std::string(kHelloHeaderValue),
306 test.response_headers[kHelloHeaderName]);
307 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
308 ASSERT_EQ(std::string(kHelloBodyValue), test.read_data.front());
309 ASSERT_EQ(std::string(kHelloTrailerValue),
310 test.response_trailers[kHelloTrailerName]);
311 bidirectional_stream_destroy(test.stream);
312 }
313
314 TEST_P(BidirectionalStreamTest, SimpleGetWithFlush) {
315 TestBidirectionalStreamCallback test;
316 test.stream = bidirectional_stream_create(engine(), &test, test.callback());
317 DCHECK(test.stream);
318 bidirectional_stream_disable_auto_flush(test.stream, true);
319 bidirectional_stream_delay_request_headers_until_flush(test.stream,
320 GetParam());
321 // Flush before start is ignored.
322 bidirectional_stream_flush(test.stream);
323 bidirectional_stream_start(test.stream, kTestServerUrl, 0,
324 "GET", &kTestHeadersArray, true);
325 test.BlockForDone();
326 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
327 ASSERT_EQ(std::string(kHelloHeaderValue),
328 test.response_headers[kHelloHeaderName]);
329 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
330 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, ""));
331 ASSERT_EQ(std::string(kHelloTrailerValue),
332 test.response_trailers[kHelloTrailerName]);
333 // Flush after done is ignored.
334 bidirectional_stream_flush(test.stream);
335 bidirectional_stream_destroy(test.stream);
336 }
337
338 TEST_P(BidirectionalStreamTest, SimplePostWithFlush) {
339 TestBidirectionalStreamCallback test;
340 test.AddWriteData("Test String", false);
341 test.AddWriteData("1234567890", false);
342 test.AddWriteData("woot!", true);
343 test.stream = bidirectional_stream_create(engine(), &test, test.callback());
344 DCHECK(test.stream);
345 bidirectional_stream_disable_auto_flush(test.stream, true);
346 bidirectional_stream_delay_request_headers_until_flush(test.stream,
347 GetParam());
348 // Flush before start is ignored.
349 bidirectional_stream_flush(test.stream);
350 bidirectional_stream_start(test.stream, kTestServerUrl, 0,
351 "POST", &kTestHeadersArray, false);
352 test.BlockForDone();
353 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
354 ASSERT_EQ(std::string(kHelloHeaderValue),
355 test.response_headers[kHelloHeaderName]);
356 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
357 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, ""));
358 ASSERT_EQ(std::string(kHelloTrailerValue),
359 test.response_trailers[kHelloTrailerName]);
360 // Flush after done is ignored.
361 bidirectional_stream_flush(test.stream);
362 bidirectional_stream_destroy(test.stream);
363 }
364
365 TEST_P(BidirectionalStreamTest, SimplePostWithFlushTwice) {
366 TestBidirectionalStreamCallback test;
367 test.AddWriteData("Test String", false);
368 test.AddWriteData("1234567890", false);
369 test.AddWriteData("woot!", true);
370 test.AddWriteData("Test String", false);
371 test.AddWriteData("1234567890", false);
372 test.AddWriteData("woot!", true);
373 test.stream = bidirectional_stream_create(engine(), &test, test.callback());
374 DCHECK(test.stream);
375 bidirectional_stream_disable_auto_flush(test.stream, true);
376 bidirectional_stream_delay_request_headers_until_flush(test.stream,
377 GetParam());
378 // Flush before start is ignored.
379 bidirectional_stream_flush(test.stream);
380 bidirectional_stream_start(test.stream, kTestServerUrl, 0,
381 "POST", &kTestHeadersArray, false);
382 test.BlockForDone();
383 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
384 ASSERT_EQ(std::string(kHelloHeaderValue),
385 test.response_headers[kHelloHeaderName]);
386 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
387 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, ""));
388 ASSERT_EQ(std::string(kHelloTrailerValue),
389 test.response_trailers[kHelloTrailerName]);
390 // Flush after done is ignored.
391 bidirectional_stream_flush(test.stream);
392 bidirectional_stream_destroy(test.stream);
393 }
394
395 TEST_P(BidirectionalStreamTest, SimplePostWithFlushAfterOneWrite) {
396 TestBidirectionalStreamCallback test;
397 test.AddWriteData("Test String", false);
398 test.AddWriteData("1234567890", false);
399 test.AddWriteData("woot!", true);
400 test.stream = bidirectional_stream_create(engine(), &test, test.callback());
401 DCHECK(test.stream);
402 bidirectional_stream_disable_auto_flush(test.stream, true);
403 bidirectional_stream_delay_request_headers_until_flush(test.stream,
404 GetParam());
405 // Flush before start is ignored.
406 bidirectional_stream_flush(test.stream);
407 bidirectional_stream_start(test.stream, kTestServerUrl, 0,
408 "POST", &kTestHeadersArray, false);
409 test.BlockForDone();
410 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
411 ASSERT_EQ(std::string(kHelloHeaderValue),
412 test.response_headers[kHelloHeaderName]);
413 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
414 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, ""));
415 ASSERT_EQ(std::string(kHelloTrailerValue),
416 test.response_trailers[kHelloTrailerName]);
417 // Flush after done is ignored.
418 bidirectional_stream_flush(test.stream);
419 bidirectional_stream_destroy(test.stream);
420 }
421
422 TEST_P(BidirectionalStreamTest, TestDelayedFlush) {
423 class CustomTestBidirectionalStreamCallback
424 : public TestBidirectionalStreamCallback {
425 void MaybeWriteNextData(bidirectional_stream* stream) override {
426 DCHECK_EQ(stream, this->stream);
427 if (write_data.empty())
428 return;
429 // Write all buffers when stream is ready.
430 // Flush after "3" and "5".
431 // EndOfStream is set with "6" but not flushed, so it is not sent.
432 if (write_data.front()->buffer == "1") {
433 for (const auto& data : write_data) {
434 bidirectional_stream_write(stream, data->buffer.c_str(),
435 data->buffer.size(),
436 data == write_data.back());
437 if (data->flush) {
438 bidirectional_stream_flush(stream);
439 }
440 }
441 }
442 // Flush the final buffer with endOfStream flag.
443 if (write_data.front()->buffer == "6")
444 bidirectional_stream_flush(stream);
445 }
446 };
447
448 CustomTestBidirectionalStreamCallback test;
449 test.AddWriteData("1", false);
450 test.AddWriteData("2", false);
451 test.AddWriteData("3", true);
452 test.AddWriteData("4", false);
453 test.AddWriteData("5", true);
454 test.AddWriteData("6", false);
455 test.stream = bidirectional_stream_create(engine(), &test, test.callback());
456 DCHECK(test.stream);
457 bidirectional_stream_disable_auto_flush(test.stream, true);
458 bidirectional_stream_delay_request_headers_until_flush(test.stream,
459 GetParam());
460 // Flush before start is ignored.
461 bidirectional_stream_flush(test.stream);
462 bidirectional_stream_start(test.stream, kTestServerUrl, 0,
463 "POST", &kTestHeadersArray, false);
464 test.BlockForDone();
465 // Flush after done is ignored.
466 bidirectional_stream_flush(test.stream);
467 bidirectional_stream_destroy(test.stream);
468 }
469
470 TEST_P(BidirectionalStreamTest, CancelOnRead) {
471 TestBidirectionalStreamCallback test;
472 test.stream = bidirectional_stream_create(engine(), &test, test.callback());
473 DCHECK(test.stream);
474 bidirectional_stream_delay_request_headers_until_flush(test.stream,
475 GetParam());
476 test.cancel_from_step = TestBidirectionalStreamCallback::ON_READ_COMPLETED;
477 bidirectional_stream_start(test.stream, kTestServerUrl, 0,
478 "POST", &kTestHeadersArray, true);
479 test.BlockForDone();
480 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
481 ASSERT_EQ(std::string(kHelloBodyValue), test.read_data.front());
482 ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step);
483 bidirectional_stream_destroy(test.stream);
484 }
485
486 TEST_P(BidirectionalStreamTest, CancelOnResponse) {
487 TestBidirectionalStreamCallback test;
488 test.stream = bidirectional_stream_create(engine(), &test, test.callback());
489 DCHECK(test.stream);
490 bidirectional_stream_delay_request_headers_until_flush(test.stream,
491 GetParam());
492 test.cancel_from_step = TestBidirectionalStreamCallback::ON_RESPONSE_STARTED;
493 bidirectional_stream_start(test.stream, kTestServerUrl, 0,
494 "POST", &kTestHeadersArray, true);
495 test.BlockForDone();
496 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
497 ASSERT_TRUE(test.read_data.empty());
498 ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step);
499 bidirectional_stream_destroy(test.stream);
500 }
501
502 TEST_P(BidirectionalStreamTest, CancelOnSucceeded) {
503 TestBidirectionalStreamCallback test;
504 test.stream = bidirectional_stream_create(engine(), &test, test.callback());
505 DCHECK(test.stream);
506 bidirectional_stream_delay_request_headers_until_flush(test.stream,
507 GetParam());
508 test.cancel_from_step = TestBidirectionalStreamCallback::ON_SUCCEEDED;
509 bidirectional_stream_start(test.stream, kTestServerUrl, 0,
510 "POST", &kTestHeadersArray, true);
511 test.BlockForDone();
512 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
513 ASSERT_EQ(std::string(kHelloBodyValue), test.read_data.front());
514 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
515 bidirectional_stream_destroy(test.stream);
516 }
517
518 TEST_P(BidirectionalStreamTest, ReadFailsBeforeRequestStarted) {
519 TestBidirectionalStreamCallback test;
520 test.stream = bidirectional_stream_create(engine(), &test, test.callback());
521 DCHECK(test.stream);
522 bidirectional_stream_delay_request_headers_until_flush(test.stream,
523 GetParam());
524 char read_buffer[1];
525 bidirectional_stream_read(test.stream, read_buffer, sizeof(read_buffer));
526 test.BlockForDone();
527 ASSERT_TRUE(test.read_data.empty());
528 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
529 ASSERT_EQ(net::ERR_UNEXPECTED, test.net_error);
530 bidirectional_stream_destroy(test.stream);
531 }
532
533 TEST_P(BidirectionalStreamTest, StreamFailBeforeReadIsExecutedOnNetworkThread) {
534 class CustomTestBidirectionalStreamCallback
535 : public TestBidirectionalStreamCallback {
536 bool MaybeCancel(bidirectional_stream* stream, ResponseStep step) override {
537 if (step == ResponseStep::ON_READ_COMPLETED) {
538 // Shut down the server, and the stream should error out.
539 // The second call to ShutdownQuicTestServer is no-op.
540 ShutdownQuicTestServer();
541 }
542 return TestBidirectionalStreamCallback::MaybeCancel(stream, step);
543 }
544 };
545
546 CustomTestBidirectionalStreamCallback test;
547 test.AddWriteData("Hello, ");
548 test.AddWriteData("world!");
549 test.read_buffer_size = 2;
550 test.stream = bidirectional_stream_create(engine(), &test, test.callback());
551 DCHECK(test.stream);
552 bidirectional_stream_delay_request_headers_until_flush(test.stream,
553 GetParam());
554 bidirectional_stream_start(test.stream, kTestServerUrl, 0,
555 "POST", &kTestHeadersArray, false);
556 test.BlockForDone();
557 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
558 ASSERT_EQ(net::ERR_QUIC_PROTOCOL_ERROR, test.net_error);
559 bidirectional_stream_destroy(test.stream);
560 }
561
562 TEST_P(BidirectionalStreamTest, WriteFailsBeforeRequestStarted) {
563 TestBidirectionalStreamCallback test;
564 test.stream = bidirectional_stream_create(engine(), &test, test.callback());
565 DCHECK(test.stream);
566 bidirectional_stream_delay_request_headers_until_flush(test.stream,
567 GetParam());
568 bidirectional_stream_write(test.stream, "1", 1, false);
569 test.BlockForDone();
570 ASSERT_TRUE(test.read_data.empty());
571 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
572 ASSERT_EQ(net::ERR_UNEXPECTED, test.net_error);
573 bidirectional_stream_destroy(test.stream);
574 }
575
576 TEST_P(BidirectionalStreamTest, StreamFailAfterStreamReadyCallback) {
577 class CustomTestBidirectionalStreamCallback
578 : public TestBidirectionalStreamCallback {
579 bool MaybeCancel(bidirectional_stream* stream, ResponseStep step) override {
580 if (step == ResponseStep::ON_STREAM_READY) {
581 // Shut down the server, and the stream should error out.
582 // The second call to ShutdownQuicTestServer is no-op.
583 ShutdownQuicTestServer();
584 }
585 return TestBidirectionalStreamCallback::MaybeCancel(stream, step);
586 }
587 };
588
589 CustomTestBidirectionalStreamCallback test;
590 test.AddWriteData("Test String");
591 test.stream = bidirectional_stream_create(engine(), &test, test.callback());
592 DCHECK(test.stream);
593 bidirectional_stream_delay_request_headers_until_flush(test.stream,
594 GetParam());
595 bidirectional_stream_start(test.stream, kTestServerUrl, 0,
596 "POST", &kTestHeadersArray, false);
597 test.BlockForDone();
598 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
599 ASSERT_TRUE(test.net_error == net::ERR_QUIC_PROTOCOL_ERROR ||
600 test.net_error == net::ERR_QUIC_HANDSHAKE_FAILED ||
601 test.net_error == net::ERR_CONNECTION_REFUSED);
602 bidirectional_stream_destroy(test.stream);
603 }
604
605 TEST_P(BidirectionalStreamTest,
606 StreamFailBeforeWriteIsExecutedOnNetworkThread) {
607 class CustomTestBidirectionalStreamCallback
608 : public TestBidirectionalStreamCallback {
609 bool MaybeCancel(bidirectional_stream* stream, ResponseStep step) override {
610 if (step == ResponseStep::ON_WRITE_COMPLETED) {
611 // Shut down the server, and the stream should error out.
612 // The second call to ShutdownQuicTestServer is no-op.
613 ShutdownQuicTestServer();
614 }
615 return TestBidirectionalStreamCallback::MaybeCancel(stream, step);
616 }
617 };
618
619 CustomTestBidirectionalStreamCallback test;
620 test.AddWriteData("Test String");
621 test.AddWriteData("1234567890");
622 test.AddWriteData("woot!");
623 test.stream = bidirectional_stream_create(engine(), &test, test.callback());
624 DCHECK(test.stream);
625 bidirectional_stream_delay_request_headers_until_flush(test.stream,
626 GetParam());
627 bidirectional_stream_start(test.stream, kTestServerUrl, 0,
628 "POST", &kTestHeadersArray, false);
629 test.BlockForDone();
630 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
631 ASSERT_TRUE(test.net_error == net::ERR_QUIC_PROTOCOL_ERROR ||
632 test.net_error == net::ERR_QUIC_HANDSHAKE_FAILED);
633 bidirectional_stream_destroy(test.stream);
634 }
635
636 TEST_P(BidirectionalStreamTest, FailedResolution) {
637 TestBidirectionalStreamCallback test;
638 test.stream = bidirectional_stream_create(engine(), &test, test.callback());
639 DCHECK(test.stream);
640 bidirectional_stream_delay_request_headers_until_flush(test.stream,
641 GetParam());
642 test.cancel_from_step = TestBidirectionalStreamCallback::ON_FAILED;
643 bidirectional_stream_start(test.stream, "https://notfound.example.com", 0,
644 "GET", &kTestHeadersArray, true);
645 test.BlockForDone();
646 ASSERT_TRUE(test.read_data.empty());
647 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
648 ASSERT_EQ(net::ERR_NAME_NOT_RESOLVED, test.net_error);
649 bidirectional_stream_destroy(test.stream);
650 }
651
652 INSTANTIATE_TEST_CASE_P(BidirectionalStreamDelayRequestHeadersUntilFlush,
653 BidirectionalStreamTest,
654 ::testing::Values(true, false));
655
656 } // namespace grpc_support
OLDNEW
« no previous file with comments | « components/grpc_support/bidirectional_stream_c.cc ('k') | components/grpc_support/include/DEPS » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698