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

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

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