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

Side by Side Diff: components/cronet/ios/test/cronet_bidirectional_stream_test.mm

Issue 2050483002: [Cronet] Coalesce small buffers into single QUIC packet in GRPC on iOS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: A little test cleanup. Created 4 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import <Foundation/Foundation.h> 5 #import <Foundation/Foundation.h>
6 #include <stdint.h> 6 #include <stdint.h>
7 #include <list> 7 #include <list>
8 #include <map> 8 #include <map>
9 #include <string> 9 #include <string>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/mac/scoped_nsobject.h" 12 #include "base/mac/scoped_nsobject.h"
13 #include "base/memory/ptr_util.h"
13 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
14 #include "base/strings/sys_string_conversions.h" 15 #include "base/strings/sys_string_conversions.h"
15 #include "base/synchronization/waitable_event.h" 16 #include "base/synchronization/waitable_event.h"
16 #include "components/cronet/ios/cronet_c_for_grpc.h" 17 #include "components/cronet/ios/cronet_c_for_grpc.h"
17 #include "components/cronet/ios/cronet_environment.h" 18 #include "components/cronet/ios/cronet_environment.h"
18 #include "components/cronet/ios/test/quic_test_server.h" 19 #include "components/cronet/ios/test/quic_test_server.h"
19 #include "net/base/mac/url_conversions.h" 20 #include "net/base/mac/url_conversions.h"
20 #include "net/base/net_errors.h" 21 #include "net/base/net_errors.h"
21 #include "net/base/test_data_directory.h" 22 #include "net/base/test_data_directory.h"
22 #include "net/cert/mock_cert_verifier.h" 23 #include "net/cert/mock_cert_verifier.h"
23 #include "testing/gtest/include/gtest/gtest.h" 24 #include "testing/gtest/include/gtest/gtest.h"
24 #include "testing/gtest_mac.h" 25 #include "testing/gtest_mac.h"
25 #include "url/gurl.h" 26 #include "url/gurl.h"
26 27
27 namespace { 28 namespace {
28 29
29 cronet_bidirectional_stream_header kTestHeaders[] = { 30 cronet_bidirectional_stream_header kTestHeaders[] = {
30 {"header1", "foo"}, 31 {"header1", "foo"},
31 {"header2", "bar"}, 32 {"header2", "bar"},
32 }; 33 };
33 const cronet_bidirectional_stream_header_array kTestHeadersArray = { 34 const cronet_bidirectional_stream_header_array kTestHeadersArray = {
34 2, 2, kTestHeaders}; 35 2, 2, kTestHeaders};
35 } // namespace 36 } // namespace
36 37
37 namespace cronet { 38 namespace cronet {
38 39
39 class CronetBidirectionalStreamTest : public ::testing::Test { 40 class CronetBidirectionalStreamTest : public ::testing::TestWithParam<bool> {
40 protected: 41 protected:
41 CronetBidirectionalStreamTest() {} 42 CronetBidirectionalStreamTest() {}
42 ~CronetBidirectionalStreamTest() override {} 43 ~CronetBidirectionalStreamTest() override {}
43 44
44 void SetUp() override { 45 void SetUp() override {
45 static bool initialized = false; 46 static bool initialized = false;
46 if (!initialized) { 47 if (!initialized) {
47 initialized = true; 48 initialized = true;
48 // Hack to work around issues with SetUp being called multiple times 49 // Hack to work around issues with SetUp being called multiple times
49 // during the test, and QuicTestServer not shutting down / restarting 50 // during the test, and QuicTestServer not shutting down / restarting
50 // gracefully. 51 // gracefully.
51 CronetEnvironment::Initialize(); 52 CronetEnvironment::Initialize();
53 cronet_environment_ = new CronetEnvironment("CronetTest/1.0.0.0");
54 cronet_environment_->set_http2_enabled(true);
55 cronet_environment_->set_quic_enabled(true);
56 cronet_environment_->set_ssl_key_log_file_name("SSLKEYLOGFILE");
57
58 std::unique_ptr<net::MockCertVerifier> mock_cert_verifier(
59 new net::MockCertVerifier());
60 mock_cert_verifier->set_default_result(net::OK);
61
62 cronet_environment_->set_cert_verifier(std::move(mock_cert_verifier));
63 cronet_environment_->set_host_resolver_rules(
64 "MAP test.example.com 127.0.0.1,"
65 "MAP notfound.example.com ~NOTFOUND");
66 cronet_environment_->AddQuicHint(kTestServerDomain, kTestServerPort,
67 kTestServerPort);
68
69 cronet_environment_->Start();
70
71 cronet_engine_.obj = cronet_environment_;
52 } 72 }
53 73
54 StartQuicTestServer(); 74 StartQuicTestServer();
55
56 cronet_environment_ = new CronetEnvironment("CronetTest/1.0.0.0");
57 cronet_environment_->set_http2_enabled(true);
58 cronet_environment_->set_quic_enabled(true);
59 cronet_environment_->set_ssl_key_log_file_name("SSLKEYLOGFILE");
60
61 std::unique_ptr<net::MockCertVerifier> mock_cert_verifier(
62 new net::MockCertVerifier());
63 mock_cert_verifier->set_default_result(net::OK);
64
65 cronet_environment_->set_cert_verifier(std::move(mock_cert_verifier));
66 cronet_environment_->set_host_resolver_rules(
67 "MAP test.example.com 127.0.0.1,"
68 "MAP notfound.example.com ~NOTFOUND");
69 cronet_environment_->AddQuicHint(kTestServerDomain, kTestServerPort,
70 kTestServerPort);
71
72 cronet_environment_->Start();
73
74 cronet_engine_.obj = cronet_environment_;
75
76 cronet_environment_->StartNetLog("cronet_netlog.json", true); 75 cronet_environment_->StartNetLog("cronet_netlog.json", true);
77 } 76 }
78 77
79 void TearDown() override { 78 void TearDown() override {
80 ShutdownQuicTestServer(); 79 ShutdownQuicTestServer();
81 cronet_environment_->StopNetLog(); 80 cronet_environment_->StopNetLog();
82 //[CronetEngine stopNetLog];
83 //[CronetEngine uninstall];
84 } 81 }
85 82
86 cronet_engine* engine() { return &cronet_engine_; } 83 cronet_engine* engine() { return &cronet_engine_; }
87 84
88 private: 85 private:
89 static CronetEnvironment* cronet_environment_; 86 static CronetEnvironment* cronet_environment_;
90 static cronet_engine cronet_engine_; 87 static cronet_engine cronet_engine_;
91 }; 88 };
92 89
93 CronetEnvironment* CronetBidirectionalStreamTest::cronet_environment_; 90 CronetEnvironment* CronetBidirectionalStreamTest::cronet_environment_ = nullptr;
94 cronet_engine CronetBidirectionalStreamTest::cronet_engine_; 91 cronet_engine CronetBidirectionalStreamTest::cronet_engine_ = {0};
95 92
96 class TestBidirectionalStreamCallback { 93 class TestBidirectionalStreamCallback {
97 public: 94 public:
98 enum ResponseStep { 95 enum ResponseStep {
99 NOTHING, 96 NOTHING,
100 ON_STREAM_READY, 97 ON_STREAM_READY,
101 ON_RESPONSE_STARTED, 98 ON_RESPONSE_STARTED,
102 ON_READ_COMPLETED, 99 ON_READ_COMPLETED,
103 ON_WRITE_COMPLETED, 100 ON_WRITE_COMPLETED,
104 ON_TRAILERS, 101 ON_TRAILERS,
105 ON_CANCELED, 102 ON_CANCELED,
106 ON_FAILED, 103 ON_FAILED,
107 ON_SUCCEEDED 104 ON_SUCCEEDED
108 }; 105 };
109 106
107 struct WriteData {
108 std::string buffer;
109 bool flush;
110
111 WriteData(const std::string& buffer, bool flush);
112 ~WriteData();
113
114 DISALLOW_COPY_AND_ASSIGN(WriteData);
115 };
116
110 cronet_bidirectional_stream* stream; 117 cronet_bidirectional_stream* stream;
111 base::WaitableEvent stream_done_event; 118 base::WaitableEvent stream_done_event;
112 119
113 // Test parameters. 120 // Test parameters.
114 std::map<std::string, std::string> request_headers; 121 std::map<std::string, std::string> request_headers;
115 std::list<std::string> write_data; 122 std::list<std::unique_ptr<WriteData>> write_data;
116 std::string expected_negotiated_protocol; 123 std::string expected_negotiated_protocol;
117 ResponseStep cancel_from_step; 124 ResponseStep cancel_from_step;
118 size_t read_buffer_size; 125 size_t read_buffer_size;
119 126
120 // Test results. 127 // Test results.
121 ResponseStep response_step; 128 ResponseStep response_step;
122 char* read_buffer; 129 char* read_buffer;
123 std::map<std::string, std::string> response_headers; 130 std::map<std::string, std::string> response_headers;
124 std::map<std::string, std::string> response_trailers; 131 std::map<std::string, std::string> response_trailers;
125 std::vector<std::string> read_data; 132 std::vector<std::string> read_data;
(...skipping 30 matching lines...) Expand all
156 return false; 163 return false;
157 164
158 cronet_bidirectional_stream_cancel(stream); 165 cronet_bidirectional_stream_cancel(stream);
159 return true; 166 return true;
160 } 167 }
161 168
162 void SignalDone() { stream_done_event.Signal(); } 169 void SignalDone() { stream_done_event.Signal(); }
163 170
164 void BlockForDone() { stream_done_event.Wait(); } 171 void BlockForDone() { stream_done_event.Wait(); }
165 172
166 void AddWriteData(const std::string& data) { write_data.push_back(data); } 173 void AddWriteData(const std::string& data) { AddWriteData(data, true); }
174 void AddWriteData(const std::string& data, bool flush) {
175 write_data.push_back(base::WrapUnique(new WriteData(data, flush)));
176 }
167 177
168 virtual void MaybeWriteNextData(cronet_bidirectional_stream* stream) { 178 virtual void MaybeWriteNextData(cronet_bidirectional_stream* stream) {
169 DCHECK_EQ(stream, this->stream); 179 DCHECK_EQ(stream, this->stream);
170 if (write_data.empty()) 180 if (write_data.empty())
171 return; 181 return;
172 cronet_bidirectional_stream_write(stream, write_data.front().c_str(), 182 for (const auto& data : write_data) {
173 write_data.front().size(), 183 cronet_bidirectional_stream_write(stream, data->buffer.c_str(),
174 write_data.size() == 1); 184 data->buffer.size(),
185 data == write_data.back());
186 if (data->flush) {
187 cronet_bidirectional_stream_flush(stream);
188 break;
189 }
190 }
175 } 191 }
176 192
177 cronet_bidirectional_stream_callback* callback() const { return &s_callback; } 193 cronet_bidirectional_stream_callback* callback() const { return &s_callback; }
178 194
179 private: 195 private:
180 // C callbacks. 196 // C callbacks.
181 static void on_stream_ready_callback(cronet_bidirectional_stream* stream) { 197 static void on_stream_ready_callback(cronet_bidirectional_stream* stream) {
182 TestBidirectionalStreamCallback* test = FromStream(stream); 198 TestBidirectionalStreamCallback* test = FromStream(stream);
183 if (test->MaybeCancel(stream, ON_STREAM_READY)) 199 if (test->MaybeCancel(stream, ON_STREAM_READY))
184 return; 200 return;
(...skipping 27 matching lines...) Expand all
212 return; 228 return;
213 if (count == 0) 229 if (count == 0)
214 return; 230 return;
215 cronet_bidirectional_stream_read(stream, test->read_buffer, 231 cronet_bidirectional_stream_read(stream, test->read_buffer,
216 test->read_buffer_size); 232 test->read_buffer_size);
217 } 233 }
218 234
219 static void on_write_completed_callback(cronet_bidirectional_stream* stream, 235 static void on_write_completed_callback(cronet_bidirectional_stream* stream,
220 const char* data) { 236 const char* data) {
221 TestBidirectionalStreamCallback* test = FromStream(stream); 237 TestBidirectionalStreamCallback* test = FromStream(stream);
222 ASSERT_EQ(test->write_data.front().c_str(), data); 238 ASSERT_EQ(test->write_data.front()->buffer.c_str(), data);
223 if (test->MaybeCancel(stream, ON_WRITE_COMPLETED)) 239 if (test->MaybeCancel(stream, ON_WRITE_COMPLETED))
224 return; 240 return;
241 bool continue_writing = test->write_data.front()->flush;
225 test->write_data.pop_front(); 242 test->write_data.pop_front();
226 test->MaybeWriteNextData(stream); 243 if (continue_writing)
244 test->MaybeWriteNextData(stream);
227 } 245 }
228 246
229 static void on_response_trailers_received_callback( 247 static void on_response_trailers_received_callback(
230 cronet_bidirectional_stream* stream, 248 cronet_bidirectional_stream* stream,
231 const cronet_bidirectional_stream_header_array* trailers) { 249 const cronet_bidirectional_stream_header_array* trailers) {
232 TestBidirectionalStreamCallback* test = FromStream(stream); 250 TestBidirectionalStreamCallback* test = FromStream(stream);
233 for (size_t i = 0; i < trailers->count; ++i) { 251 for (size_t i = 0; i < trailers->count; ++i) {
234 test->response_trailers[trailers->headers[i].key] = 252 test->response_trailers[trailers->headers[i].key] =
235 trailers->headers[i].value; 253 trailers->headers[i].value;
236 } 254 }
(...skipping 29 matching lines...) Expand all
266 TestBidirectionalStreamCallback::s_callback = { 284 TestBidirectionalStreamCallback::s_callback = {
267 on_stream_ready_callback, 285 on_stream_ready_callback,
268 on_response_headers_received_callback, 286 on_response_headers_received_callback,
269 on_read_completed_callback, 287 on_read_completed_callback,
270 on_write_completed_callback, 288 on_write_completed_callback,
271 on_response_trailers_received_callback, 289 on_response_trailers_received_callback,
272 on_succeded_callback, 290 on_succeded_callback,
273 on_failed_callback, 291 on_failed_callback,
274 on_canceled_callback}; 292 on_canceled_callback};
275 293
276 TEST_F(CronetBidirectionalStreamTest, StartExampleBidiStream) { 294 TestBidirectionalStreamCallback::WriteData::WriteData(const std::string& data,
295 bool flush_after)
296 : buffer(data), flush(flush_after) {}
297
298 TestBidirectionalStreamCallback::WriteData::~WriteData() {}
299
300 TEST_P(CronetBidirectionalStreamTest, StartExampleBidiStream) {
277 TestBidirectionalStreamCallback test; 301 TestBidirectionalStreamCallback test;
278 test.AddWriteData("Hello, "); 302 test.AddWriteData("Hello, ");
279 test.AddWriteData("world!"); 303 test.AddWriteData("world!");
280 test.read_buffer_size = 2; 304 test.read_buffer_size = 2;
281 test.stream = 305 test.stream =
282 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 306 cronet_bidirectional_stream_create(engine(), &test, test.callback());
283 DCHECK(test.stream); 307 DCHECK(test.stream);
308 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
309 GetParam());
284 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST", 310 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
285 &kTestHeadersArray, false); 311 &kTestHeadersArray, false);
286 test.BlockForDone(); 312 test.BlockForDone();
287 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]); 313 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
288 ASSERT_EQ(std::string(kHelloHeaderValue), 314 ASSERT_EQ(std::string(kHelloHeaderValue),
289 test.response_headers[kHelloHeaderName]); 315 test.response_headers[kHelloHeaderName]);
290 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step); 316 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
291 ASSERT_EQ(std::string(kHelloBodyValue, 2), test.read_data.front()); 317 ASSERT_EQ(std::string(kHelloBodyValue, 2), test.read_data.front());
292 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, "")); 318 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, ""));
293 ASSERT_EQ(std::string(kHelloTrailerValue), 319 ASSERT_EQ(std::string(kHelloTrailerValue),
294 test.response_trailers[kHelloTrailerName]); 320 test.response_trailers[kHelloTrailerName]);
295 cronet_bidirectional_stream_destroy(test.stream); 321 cronet_bidirectional_stream_destroy(test.stream);
296 } 322 }
297 323
298 TEST_F(CronetBidirectionalStreamTest, CancelOnRead) { 324 TEST_P(CronetBidirectionalStreamTest, SimpleGetWithFlush) {
299 TestBidirectionalStreamCallback test; 325 TestBidirectionalStreamCallback test;
300 test.stream = 326 test.stream =
301 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 327 cronet_bidirectional_stream_create(engine(), &test, test.callback());
302 DCHECK(test.stream); 328 DCHECK(test.stream);
329 cronet_bidirectional_stream_disable_auto_flush(test.stream, true);
330 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
331 GetParam());
332 // Flush before start is ignored.
333 cronet_bidirectional_stream_flush(test.stream);
334 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "GET",
335 &kTestHeadersArray, true);
336 test.BlockForDone();
337 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
338 ASSERT_EQ(std::string(kHelloHeaderValue),
339 test.response_headers[kHelloHeaderName]);
340 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
341 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, ""));
342 ASSERT_EQ(std::string(kHelloTrailerValue),
343 test.response_trailers[kHelloTrailerName]);
344 // Flush after done is ignored.
345 cronet_bidirectional_stream_flush(test.stream);
346 cronet_bidirectional_stream_destroy(test.stream);
347 }
348
349 TEST_P(CronetBidirectionalStreamTest, SimplePostWithFlush) {
350 TestBidirectionalStreamCallback test;
351 test.AddWriteData("Test String", false);
352 test.AddWriteData("1234567890", false);
353 test.AddWriteData("woot!", true);
354 test.stream =
355 cronet_bidirectional_stream_create(engine(), &test, test.callback());
356 DCHECK(test.stream);
357 cronet_bidirectional_stream_disable_auto_flush(test.stream, true);
358 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
359 GetParam());
360 // Flush before start is ignored.
361 cronet_bidirectional_stream_flush(test.stream);
362 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
363 &kTestHeadersArray, false);
364 test.BlockForDone();
365 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
366 ASSERT_EQ(std::string(kHelloHeaderValue),
367 test.response_headers[kHelloHeaderName]);
368 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
369 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, ""));
370 ASSERT_EQ(std::string(kHelloTrailerValue),
371 test.response_trailers[kHelloTrailerName]);
372 // Flush after done is ignored.
373 cronet_bidirectional_stream_flush(test.stream);
374 cronet_bidirectional_stream_destroy(test.stream);
375 }
376
377 TEST_P(CronetBidirectionalStreamTest, SimplePostWithFlushTwice) {
378 TestBidirectionalStreamCallback test;
379 test.AddWriteData("Test String", false);
380 test.AddWriteData("1234567890", false);
381 test.AddWriteData("woot!", true);
382 test.AddWriteData("Test String", false);
383 test.AddWriteData("1234567890", false);
384 test.AddWriteData("woot!", true);
385 test.stream =
386 cronet_bidirectional_stream_create(engine(), &test, test.callback());
387 DCHECK(test.stream);
388 cronet_bidirectional_stream_disable_auto_flush(test.stream, true);
389 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
390 GetParam());
391 // Flush before start is ignored.
392 cronet_bidirectional_stream_flush(test.stream);
393 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
394 &kTestHeadersArray, false);
395 test.BlockForDone();
396 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
397 ASSERT_EQ(std::string(kHelloHeaderValue),
398 test.response_headers[kHelloHeaderName]);
399 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
400 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, ""));
401 ASSERT_EQ(std::string(kHelloTrailerValue),
402 test.response_trailers[kHelloTrailerName]);
403 // Flush after done is ignored.
404 cronet_bidirectional_stream_flush(test.stream);
405 cronet_bidirectional_stream_destroy(test.stream);
406 }
407
408 TEST_P(CronetBidirectionalStreamTest, SimplePostWithFlushAfterOneWrite) {
409 TestBidirectionalStreamCallback test;
410 test.AddWriteData("Test String", false);
411 test.AddWriteData("1234567890", false);
412 test.AddWriteData("woot!", true);
413 test.stream =
414 cronet_bidirectional_stream_create(engine(), &test, test.callback());
415 DCHECK(test.stream);
416 cronet_bidirectional_stream_disable_auto_flush(test.stream, true);
417 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
418 GetParam());
419 // Flush before start is ignored.
420 cronet_bidirectional_stream_flush(test.stream);
421 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
422 &kTestHeadersArray, false);
423 test.BlockForDone();
424 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
425 ASSERT_EQ(std::string(kHelloHeaderValue),
426 test.response_headers[kHelloHeaderName]);
427 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
428 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, ""));
429 ASSERT_EQ(std::string(kHelloTrailerValue),
430 test.response_trailers[kHelloTrailerName]);
431 // Flush after done is ignored.
432 cronet_bidirectional_stream_flush(test.stream);
433 cronet_bidirectional_stream_destroy(test.stream);
434 }
435
436 TEST_P(CronetBidirectionalStreamTest, CancelOnRead) {
437 TestBidirectionalStreamCallback test;
438 test.stream =
439 cronet_bidirectional_stream_create(engine(), &test, test.callback());
440 DCHECK(test.stream);
441 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
442 GetParam());
303 test.cancel_from_step = TestBidirectionalStreamCallback::ON_READ_COMPLETED; 443 test.cancel_from_step = TestBidirectionalStreamCallback::ON_READ_COMPLETED;
304 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST", 444 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
305 &kTestHeadersArray, true); 445 &kTestHeadersArray, true);
306 test.BlockForDone(); 446 test.BlockForDone();
307 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]); 447 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
308 ASSERT_EQ(std::string(kHelloBodyValue), test.read_data.front()); 448 ASSERT_EQ(std::string(kHelloBodyValue), test.read_data.front());
309 ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step); 449 ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step);
310 cronet_bidirectional_stream_destroy(test.stream); 450 cronet_bidirectional_stream_destroy(test.stream);
311 } 451 }
312 452
313 TEST_F(CronetBidirectionalStreamTest, CancelOnResponse) { 453 TEST_P(CronetBidirectionalStreamTest, CancelOnResponse) {
314 TestBidirectionalStreamCallback test; 454 TestBidirectionalStreamCallback test;
315 test.stream = 455 test.stream =
316 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 456 cronet_bidirectional_stream_create(engine(), &test, test.callback());
317 DCHECK(test.stream); 457 DCHECK(test.stream);
458 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
459 GetParam());
318 test.cancel_from_step = TestBidirectionalStreamCallback::ON_RESPONSE_STARTED; 460 test.cancel_from_step = TestBidirectionalStreamCallback::ON_RESPONSE_STARTED;
319 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST", 461 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
320 &kTestHeadersArray, true); 462 &kTestHeadersArray, true);
321 test.BlockForDone(); 463 test.BlockForDone();
322 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]); 464 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
323 ASSERT_TRUE(test.read_data.empty()); 465 ASSERT_TRUE(test.read_data.empty());
324 ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step); 466 ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step);
325 cronet_bidirectional_stream_destroy(test.stream); 467 cronet_bidirectional_stream_destroy(test.stream);
326 } 468 }
327 469
328 TEST_F(CronetBidirectionalStreamTest, CancelOnSucceeded) { 470 TEST_P(CronetBidirectionalStreamTest, CancelOnSucceeded) {
329 TestBidirectionalStreamCallback test; 471 TestBidirectionalStreamCallback test;
330 test.stream = 472 test.stream =
331 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 473 cronet_bidirectional_stream_create(engine(), &test, test.callback());
332 DCHECK(test.stream); 474 DCHECK(test.stream);
475 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
476 GetParam());
333 test.cancel_from_step = TestBidirectionalStreamCallback::ON_SUCCEEDED; 477 test.cancel_from_step = TestBidirectionalStreamCallback::ON_SUCCEEDED;
334 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST", 478 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
335 &kTestHeadersArray, true); 479 &kTestHeadersArray, true);
336 test.BlockForDone(); 480 test.BlockForDone();
337 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]); 481 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
338 ASSERT_EQ(std::string(kHelloBodyValue), test.read_data.front()); 482 ASSERT_EQ(std::string(kHelloBodyValue), test.read_data.front());
339 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step); 483 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
340 cronet_bidirectional_stream_destroy(test.stream); 484 cronet_bidirectional_stream_destroy(test.stream);
341 } 485 }
342 486
343 TEST_F(CronetBidirectionalStreamTest, ReadFailsBeforeRequestStarted) { 487 TEST_P(CronetBidirectionalStreamTest, ReadFailsBeforeRequestStarted) {
344 TestBidirectionalStreamCallback test; 488 TestBidirectionalStreamCallback test;
345 test.stream = 489 test.stream =
346 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 490 cronet_bidirectional_stream_create(engine(), &test, test.callback());
347 DCHECK(test.stream); 491 DCHECK(test.stream);
492 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
493 GetParam());
348 char read_buffer[1]; 494 char read_buffer[1];
349 cronet_bidirectional_stream_read(test.stream, read_buffer, 495 cronet_bidirectional_stream_read(test.stream, read_buffer,
350 sizeof(read_buffer)); 496 sizeof(read_buffer));
351 test.BlockForDone(); 497 test.BlockForDone();
352 ASSERT_TRUE(test.read_data.empty()); 498 ASSERT_TRUE(test.read_data.empty());
353 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step); 499 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
354 ASSERT_EQ(net::ERR_UNEXPECTED, test.net_error); 500 ASSERT_EQ(net::ERR_UNEXPECTED, test.net_error);
355 cronet_bidirectional_stream_destroy(test.stream); 501 cronet_bidirectional_stream_destroy(test.stream);
356 } 502 }
357 503
358 TEST_F(CronetBidirectionalStreamTest, 504 TEST_P(CronetBidirectionalStreamTest,
359 StreamFailBeforeReadIsExecutedOnNetworkThread) { 505 StreamFailBeforeReadIsExecutedOnNetworkThread) {
360 class CustomTestBidirectionalStreamCallback 506 class CustomTestBidirectionalStreamCallback
361 : public TestBidirectionalStreamCallback { 507 : public TestBidirectionalStreamCallback {
362 bool MaybeCancel(cronet_bidirectional_stream* stream, 508 bool MaybeCancel(cronet_bidirectional_stream* stream,
363 ResponseStep step) override { 509 ResponseStep step) override {
364 if (step == ResponseStep::ON_READ_COMPLETED) { 510 if (step == ResponseStep::ON_READ_COMPLETED) {
365 // Shut down the server, and the stream should error out. 511 // Shut down the server, and the stream should error out.
366 // The second call to ShutdownQuicTestServer is no-op. 512 // The second call to ShutdownQuicTestServer is no-op.
367 ShutdownQuicTestServer(); 513 ShutdownQuicTestServer();
368 } 514 }
369 return TestBidirectionalStreamCallback::MaybeCancel(stream, step); 515 return TestBidirectionalStreamCallback::MaybeCancel(stream, step);
370 } 516 }
371 }; 517 };
372 518
373 CustomTestBidirectionalStreamCallback test; 519 CustomTestBidirectionalStreamCallback test;
374 test.AddWriteData("Hello, "); 520 test.AddWriteData("Hello, ");
375 test.AddWriteData("world!"); 521 test.AddWriteData("world!");
376 test.read_buffer_size = 2; 522 test.read_buffer_size = 2;
377 test.stream = 523 test.stream =
378 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 524 cronet_bidirectional_stream_create(engine(), &test, test.callback());
379 DCHECK(test.stream); 525 DCHECK(test.stream);
526 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
527 GetParam());
380 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST", 528 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
381 &kTestHeadersArray, false); 529 &kTestHeadersArray, false);
382 test.BlockForDone(); 530 test.BlockForDone();
383 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step); 531 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
384 ASSERT_EQ(net::ERR_QUIC_PROTOCOL_ERROR, test.net_error); 532 ASSERT_EQ(net::ERR_QUIC_PROTOCOL_ERROR, test.net_error);
385 cronet_bidirectional_stream_destroy(test.stream); 533 cronet_bidirectional_stream_destroy(test.stream);
386 } 534 }
387 535
388 TEST_F(CronetBidirectionalStreamTest, WriteFailsBeforeRequestStarted) { 536 TEST_P(CronetBidirectionalStreamTest, WriteFailsBeforeRequestStarted) {
389 TestBidirectionalStreamCallback test; 537 TestBidirectionalStreamCallback test;
390 test.stream = 538 test.stream =
391 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 539 cronet_bidirectional_stream_create(engine(), &test, test.callback());
392 DCHECK(test.stream); 540 DCHECK(test.stream);
541 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
542 GetParam());
393 cronet_bidirectional_stream_write(test.stream, "1", 1, false); 543 cronet_bidirectional_stream_write(test.stream, "1", 1, false);
394 test.BlockForDone(); 544 test.BlockForDone();
395 ASSERT_TRUE(test.read_data.empty()); 545 ASSERT_TRUE(test.read_data.empty());
396 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step); 546 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
397 ASSERT_EQ(net::ERR_UNEXPECTED, test.net_error); 547 ASSERT_EQ(net::ERR_UNEXPECTED, test.net_error);
398 cronet_bidirectional_stream_destroy(test.stream); 548 cronet_bidirectional_stream_destroy(test.stream);
399 } 549 }
400 550
401 TEST_F(CronetBidirectionalStreamTest, 551 TEST_P(CronetBidirectionalStreamTest,
402 StreamFailBeforeWriteIsExecutedOnNetworkThread) { 552 StreamFailBeforeWriteIsExecutedOnNetworkThread) {
403 class CustomTestBidirectionalStreamCallback 553 class CustomTestBidirectionalStreamCallback
404 : public TestBidirectionalStreamCallback { 554 : public TestBidirectionalStreamCallback {
405 bool MaybeCancel(cronet_bidirectional_stream* stream, 555 bool MaybeCancel(cronet_bidirectional_stream* stream,
406 ResponseStep step) override { 556 ResponseStep step) override {
407 if (step == ResponseStep::ON_WRITE_COMPLETED) { 557 if (step == ResponseStep::ON_WRITE_COMPLETED) {
408 // Shut down the server, and the stream should error out. 558 // Shut down the server, and the stream should error out.
409 // The second call to ShutdownQuicTestServer is no-op. 559 // The second call to ShutdownQuicTestServer is no-op.
410 ShutdownQuicTestServer(); 560 ShutdownQuicTestServer();
411 } 561 }
412 return TestBidirectionalStreamCallback::MaybeCancel(stream, step); 562 return TestBidirectionalStreamCallback::MaybeCancel(stream, step);
413 } 563 }
414 }; 564 };
415 565
416 CustomTestBidirectionalStreamCallback test; 566 CustomTestBidirectionalStreamCallback test;
417 test.AddWriteData("Test String"); 567 test.AddWriteData("Test String");
418 test.AddWriteData("1234567890"); 568 test.AddWriteData("1234567890");
419 test.AddWriteData("woot!"); 569 test.AddWriteData("woot!");
420 test.stream = 570 test.stream =
421 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 571 cronet_bidirectional_stream_create(engine(), &test, test.callback());
422 DCHECK(test.stream); 572 DCHECK(test.stream);
573 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
574 GetParam());
423 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST", 575 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
424 &kTestHeadersArray, false); 576 &kTestHeadersArray, false);
425 test.BlockForDone(); 577 test.BlockForDone();
426 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step); 578 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
427 ASSERT_EQ(net::ERR_QUIC_PROTOCOL_ERROR, test.net_error); 579 ASSERT_EQ(net::ERR_QUIC_PROTOCOL_ERROR, test.net_error);
428 cronet_bidirectional_stream_destroy(test.stream); 580 cronet_bidirectional_stream_destroy(test.stream);
429 } 581 }
430 582
431 TEST_F(CronetBidirectionalStreamTest, FailedResolution) { 583 TEST_P(CronetBidirectionalStreamTest, FailedResolution) {
432 TestBidirectionalStreamCallback test; 584 TestBidirectionalStreamCallback test;
433 test.stream = 585 test.stream =
434 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 586 cronet_bidirectional_stream_create(engine(), &test, test.callback());
435 DCHECK(test.stream); 587 DCHECK(test.stream);
588 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
589 GetParam());
436 test.cancel_from_step = TestBidirectionalStreamCallback::ON_FAILED; 590 test.cancel_from_step = TestBidirectionalStreamCallback::ON_FAILED;
437 cronet_bidirectional_stream_start(test.stream, "https://notfound.example.com", 591 cronet_bidirectional_stream_start(test.stream, "https://notfound.example.com",
438 0, "GET", &kTestHeadersArray, true); 592 0, "GET", &kTestHeadersArray, true);
439 test.BlockForDone(); 593 test.BlockForDone();
440 ASSERT_TRUE(test.read_data.empty()); 594 ASSERT_TRUE(test.read_data.empty());
441 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step); 595 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
442 ASSERT_EQ(net::ERR_NAME_NOT_RESOLVED, test.net_error); 596 ASSERT_EQ(net::ERR_NAME_NOT_RESOLVED, test.net_error);
443 cronet_bidirectional_stream_destroy(test.stream); 597 cronet_bidirectional_stream_destroy(test.stream);
444 } 598 }
445 599
600 INSTANTIATE_TEST_CASE_P(CronetBidirectionalStreamDelayRequestHeadersUntilFlush,
601 CronetBidirectionalStreamTest,
602 ::testing::Values(true, false));
603
446 } // namespace cronet 604 } // namespace cronet
OLDNEW
« components/cronet/ios/cronet_c_for_grpc.h ('K') | « components/cronet/ios/cronet_c_for_grpc.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698