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

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: Remove flushing_write_data_. 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;
xunjieli 2016/06/14 14:29:35 Maybe add a brief comment on what |flush| is.
mef 2016/06/14 19:54:31 Done.
110
111 WriteData(const std::string& buffer, bool flush);
112 ~WriteData();
113
114 DISALLOW_COPY_AND_ASSIGN(WriteData);
xunjieli 2016/06/14 14:29:35 include macros.h?
mef 2016/06/14 19:54:30 Done.
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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 return false; 164 return false;
158 165
159 cronet_bidirectional_stream_cancel(stream); 166 cronet_bidirectional_stream_cancel(stream);
160 return true; 167 return true;
161 } 168 }
162 169
163 void SignalDone() { stream_done_event.Signal(); } 170 void SignalDone() { stream_done_event.Signal(); }
164 171
165 void BlockForDone() { stream_done_event.Wait(); } 172 void BlockForDone() { stream_done_event.Wait(); }
166 173
167 void AddWriteData(const std::string& data) { write_data.push_back(data); } 174 void AddWriteData(const std::string& data) { AddWriteData(data, true); }
175 void AddWriteData(const std::string& data, bool flush) {
176 write_data.push_back(base::WrapUnique(new WriteData(data, flush)));
177 }
168 178
169 virtual void MaybeWriteNextData(cronet_bidirectional_stream* stream) { 179 virtual void MaybeWriteNextData(cronet_bidirectional_stream* stream) {
170 DCHECK_EQ(stream, this->stream); 180 DCHECK_EQ(stream, this->stream);
171 if (write_data.empty()) 181 if (write_data.empty())
172 return; 182 return;
173 cronet_bidirectional_stream_write(stream, write_data.front().c_str(), 183 for (const auto& data : write_data) {
174 write_data.front().size(), 184 cronet_bidirectional_stream_write(stream, data->buffer.c_str(),
175 write_data.size() == 1); 185 data->buffer.size(),
186 data == write_data.back());
187 if (data->flush) {
188 cronet_bidirectional_stream_flush(stream);
189 break;
190 }
191 }
176 } 192 }
177 193
178 cronet_bidirectional_stream_callback* callback() const { return &s_callback; } 194 cronet_bidirectional_stream_callback* callback() const { return &s_callback; }
179 195
180 private: 196 private:
181 // C callbacks. 197 // C callbacks.
182 static void on_stream_ready_callback(cronet_bidirectional_stream* stream) { 198 static void on_stream_ready_callback(cronet_bidirectional_stream* stream) {
183 TestBidirectionalStreamCallback* test = FromStream(stream); 199 TestBidirectionalStreamCallback* test = FromStream(stream);
184 if (test->MaybeCancel(stream, ON_STREAM_READY)) 200 if (test->MaybeCancel(stream, ON_STREAM_READY))
185 return; 201 return;
(...skipping 27 matching lines...) Expand all
213 return; 229 return;
214 if (count == 0) 230 if (count == 0)
215 return; 231 return;
216 cronet_bidirectional_stream_read(stream, test->read_buffer, 232 cronet_bidirectional_stream_read(stream, test->read_buffer,
217 test->read_buffer_size); 233 test->read_buffer_size);
218 } 234 }
219 235
220 static void on_write_completed_callback(cronet_bidirectional_stream* stream, 236 static void on_write_completed_callback(cronet_bidirectional_stream* stream,
221 const char* data) { 237 const char* data) {
222 TestBidirectionalStreamCallback* test = FromStream(stream); 238 TestBidirectionalStreamCallback* test = FromStream(stream);
223 ASSERT_EQ(test->write_data.front().c_str(), data); 239 ASSERT_EQ(test->write_data.front()->buffer.c_str(), data);
224 if (test->MaybeCancel(stream, ON_WRITE_COMPLETED)) 240 if (test->MaybeCancel(stream, ON_WRITE_COMPLETED))
225 return; 241 return;
242 bool continue_writing = test->write_data.front()->flush;
226 test->write_data.pop_front(); 243 test->write_data.pop_front();
xunjieli 2016/06/14 14:29:35 Suggest that we also check |data| is the same as t
mef 2016/06/14 19:54:31 Hrm, is it different than ASSERT_EQ(test->write_da
xunjieli 2016/06/14 19:56:12 Acknowledged. Sorry, I missed that part.
227 test->MaybeWriteNextData(stream); 244 if (continue_writing)
245 test->MaybeWriteNextData(stream);
228 } 246 }
229 247
230 static void on_response_trailers_received_callback( 248 static void on_response_trailers_received_callback(
231 cronet_bidirectional_stream* stream, 249 cronet_bidirectional_stream* stream,
232 const cronet_bidirectional_stream_header_array* trailers) { 250 const cronet_bidirectional_stream_header_array* trailers) {
233 TestBidirectionalStreamCallback* test = FromStream(stream); 251 TestBidirectionalStreamCallback* test = FromStream(stream);
234 for (size_t i = 0; i < trailers->count; ++i) { 252 for (size_t i = 0; i < trailers->count; ++i) {
235 test->response_trailers[trailers->headers[i].key] = 253 test->response_trailers[trailers->headers[i].key] =
236 trailers->headers[i].value; 254 trailers->headers[i].value;
237 } 255 }
238 256
239 if (test->MaybeCancel(stream, ON_TRAILERS)) 257 if (test->MaybeCancel(stream, ON_TRAILERS))
240 return; 258 return;
241 } 259 }
242 260
243 static void on_succeded_callback(cronet_bidirectional_stream* stream) { 261 static void on_succeded_callback(cronet_bidirectional_stream* stream) {
xunjieli 2016/06/14 14:29:35 maybe check test->write_data is now empty (we have
mef 2016/06/14 19:54:31 Done.
244 TestBidirectionalStreamCallback* test = FromStream(stream); 262 TestBidirectionalStreamCallback* test = FromStream(stream);
245 test->MaybeCancel(stream, ON_SUCCEEDED); 263 test->MaybeCancel(stream, ON_SUCCEEDED);
246 test->SignalDone(); 264 test->SignalDone();
247 } 265 }
248 266
249 static void on_failed_callback(cronet_bidirectional_stream* stream, 267 static void on_failed_callback(cronet_bidirectional_stream* stream,
250 int net_error) { 268 int net_error) {
251 TestBidirectionalStreamCallback* test = FromStream(stream); 269 TestBidirectionalStreamCallback* test = FromStream(stream);
252 test->net_error = net_error; 270 test->net_error = net_error;
253 test->MaybeCancel(stream, ON_FAILED); 271 test->MaybeCancel(stream, ON_FAILED);
(...skipping 13 matching lines...) Expand all
267 TestBidirectionalStreamCallback::s_callback = { 285 TestBidirectionalStreamCallback::s_callback = {
268 on_stream_ready_callback, 286 on_stream_ready_callback,
269 on_response_headers_received_callback, 287 on_response_headers_received_callback,
270 on_read_completed_callback, 288 on_read_completed_callback,
271 on_write_completed_callback, 289 on_write_completed_callback,
272 on_response_trailers_received_callback, 290 on_response_trailers_received_callback,
273 on_succeded_callback, 291 on_succeded_callback,
274 on_failed_callback, 292 on_failed_callback,
275 on_canceled_callback}; 293 on_canceled_callback};
276 294
277 TEST_F(CronetBidirectionalStreamTest, StartExampleBidiStream) { 295 TestBidirectionalStreamCallback::WriteData::WriteData(const std::string& data,
296 bool flush_after)
297 : buffer(data), flush(flush_after) {}
298
299 TestBidirectionalStreamCallback::WriteData::~WriteData() {}
300
301 TEST_P(CronetBidirectionalStreamTest, StartExampleBidiStream) {
278 TestBidirectionalStreamCallback test; 302 TestBidirectionalStreamCallback test;
279 test.AddWriteData("Hello, "); 303 test.AddWriteData("Hello, ");
280 test.AddWriteData("world!"); 304 test.AddWriteData("world!");
281 test.read_buffer_size = 2; 305 test.read_buffer_size = 2;
282 test.stream = 306 test.stream =
283 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 307 cronet_bidirectional_stream_create(engine(), &test, test.callback());
284 DCHECK(test.stream); 308 DCHECK(test.stream);
309 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
310 GetParam());
285 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST", 311 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
286 &kTestHeadersArray, false); 312 &kTestHeadersArray, false);
287 test.BlockForDone(); 313 test.BlockForDone();
288 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]); 314 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
289 ASSERT_EQ(std::string(kHelloHeaderValue), 315 ASSERT_EQ(std::string(kHelloHeaderValue),
290 test.response_headers[kHelloHeaderName]); 316 test.response_headers[kHelloHeaderName]);
291 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step); 317 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
292 ASSERT_EQ(std::string(kHelloBodyValue, 2), test.read_data.front()); 318 ASSERT_EQ(std::string(kHelloBodyValue, 2), test.read_data.front());
293 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, "")); 319 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, ""));
294 ASSERT_EQ(std::string(kHelloTrailerValue), 320 ASSERT_EQ(std::string(kHelloTrailerValue),
295 test.response_trailers[kHelloTrailerName]); 321 test.response_trailers[kHelloTrailerName]);
296 cronet_bidirectional_stream_destroy(test.stream); 322 cronet_bidirectional_stream_destroy(test.stream);
297 } 323 }
298 324
299 TEST_F(CronetBidirectionalStreamTest, CancelOnRead) { 325 TEST_P(CronetBidirectionalStreamTest, SimpleGetWithFlush) {
300 TestBidirectionalStreamCallback test; 326 TestBidirectionalStreamCallback test;
301 test.stream = 327 test.stream =
302 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 328 cronet_bidirectional_stream_create(engine(), &test, test.callback());
303 DCHECK(test.stream); 329 DCHECK(test.stream);
330 cronet_bidirectional_stream_disable_auto_flush(test.stream, true);
331 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
332 GetParam());
333 // Flush before start is ignored.
334 cronet_bidirectional_stream_flush(test.stream);
335 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "GET",
336 &kTestHeadersArray, true);
337 test.BlockForDone();
338 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
339 ASSERT_EQ(std::string(kHelloHeaderValue),
340 test.response_headers[kHelloHeaderName]);
341 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
342 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, ""));
343 ASSERT_EQ(std::string(kHelloTrailerValue),
344 test.response_trailers[kHelloTrailerName]);
345 // Flush after done is ignored.
346 cronet_bidirectional_stream_flush(test.stream);
347 cronet_bidirectional_stream_destroy(test.stream);
348 }
349
350 TEST_P(CronetBidirectionalStreamTest, SimplePostWithFlush) {
351 TestBidirectionalStreamCallback test;
352 test.AddWriteData("Test String", false);
353 test.AddWriteData("1234567890", false);
354 test.AddWriteData("woot!", true);
355 test.stream =
356 cronet_bidirectional_stream_create(engine(), &test, test.callback());
357 DCHECK(test.stream);
358 cronet_bidirectional_stream_disable_auto_flush(test.stream, true);
359 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
360 GetParam());
361 // Flush before start is ignored.
362 cronet_bidirectional_stream_flush(test.stream);
363 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
364 &kTestHeadersArray, false);
365 test.BlockForDone();
366 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
367 ASSERT_EQ(std::string(kHelloHeaderValue),
368 test.response_headers[kHelloHeaderName]);
369 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
370 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, ""));
371 ASSERT_EQ(std::string(kHelloTrailerValue),
372 test.response_trailers[kHelloTrailerName]);
373 // Flush after done is ignored.
374 cronet_bidirectional_stream_flush(test.stream);
375 cronet_bidirectional_stream_destroy(test.stream);
376 }
377
378 TEST_P(CronetBidirectionalStreamTest, SimplePostWithFlushTwice) {
379 TestBidirectionalStreamCallback test;
380 test.AddWriteData("Test String", false);
381 test.AddWriteData("1234567890", false);
382 test.AddWriteData("woot!", true);
383 test.AddWriteData("Test String", false);
384 test.AddWriteData("1234567890", false);
385 test.AddWriteData("woot!", true);
386 test.stream =
387 cronet_bidirectional_stream_create(engine(), &test, test.callback());
388 DCHECK(test.stream);
389 cronet_bidirectional_stream_disable_auto_flush(test.stream, true);
390 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
391 GetParam());
392 // Flush before start is ignored.
393 cronet_bidirectional_stream_flush(test.stream);
394 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
395 &kTestHeadersArray, false);
396 test.BlockForDone();
397 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
398 ASSERT_EQ(std::string(kHelloHeaderValue),
399 test.response_headers[kHelloHeaderName]);
400 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
401 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, ""));
402 ASSERT_EQ(std::string(kHelloTrailerValue),
403 test.response_trailers[kHelloTrailerName]);
404 // Flush after done is ignored.
405 cronet_bidirectional_stream_flush(test.stream);
406 cronet_bidirectional_stream_destroy(test.stream);
407 }
408
409 TEST_P(CronetBidirectionalStreamTest, SimplePostWithFlushAfterOneWrite) {
410 TestBidirectionalStreamCallback test;
411 test.AddWriteData("Test String", false);
412 test.AddWriteData("1234567890", false);
413 test.AddWriteData("woot!", true);
414 test.stream =
415 cronet_bidirectional_stream_create(engine(), &test, test.callback());
416 DCHECK(test.stream);
417 cronet_bidirectional_stream_disable_auto_flush(test.stream, true);
418 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
419 GetParam());
420 // Flush before start is ignored.
421 cronet_bidirectional_stream_flush(test.stream);
422 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
423 &kTestHeadersArray, false);
424 test.BlockForDone();
425 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
426 ASSERT_EQ(std::string(kHelloHeaderValue),
427 test.response_headers[kHelloHeaderName]);
428 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
429 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, ""));
430 ASSERT_EQ(std::string(kHelloTrailerValue),
431 test.response_trailers[kHelloTrailerName]);
432 // Flush after done is ignored.
433 cronet_bidirectional_stream_flush(test.stream);
434 cronet_bidirectional_stream_destroy(test.stream);
435 }
436
437 TEST_P(CronetBidirectionalStreamTest, CancelOnRead) {
438 TestBidirectionalStreamCallback test;
439 test.stream =
440 cronet_bidirectional_stream_create(engine(), &test, test.callback());
441 DCHECK(test.stream);
442 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
443 GetParam());
304 test.cancel_from_step = TestBidirectionalStreamCallback::ON_READ_COMPLETED; 444 test.cancel_from_step = TestBidirectionalStreamCallback::ON_READ_COMPLETED;
305 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST", 445 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
306 &kTestHeadersArray, true); 446 &kTestHeadersArray, true);
307 test.BlockForDone(); 447 test.BlockForDone();
308 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]); 448 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
309 ASSERT_EQ(std::string(kHelloBodyValue), test.read_data.front()); 449 ASSERT_EQ(std::string(kHelloBodyValue), test.read_data.front());
310 ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step); 450 ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step);
311 cronet_bidirectional_stream_destroy(test.stream); 451 cronet_bidirectional_stream_destroy(test.stream);
312 } 452 }
313 453
314 TEST_F(CronetBidirectionalStreamTest, CancelOnResponse) { 454 TEST_P(CronetBidirectionalStreamTest, CancelOnResponse) {
315 TestBidirectionalStreamCallback test; 455 TestBidirectionalStreamCallback test;
316 test.stream = 456 test.stream =
317 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 457 cronet_bidirectional_stream_create(engine(), &test, test.callback());
318 DCHECK(test.stream); 458 DCHECK(test.stream);
459 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
460 GetParam());
319 test.cancel_from_step = TestBidirectionalStreamCallback::ON_RESPONSE_STARTED; 461 test.cancel_from_step = TestBidirectionalStreamCallback::ON_RESPONSE_STARTED;
320 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST", 462 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
321 &kTestHeadersArray, true); 463 &kTestHeadersArray, true);
322 test.BlockForDone(); 464 test.BlockForDone();
323 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]); 465 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
324 ASSERT_TRUE(test.read_data.empty()); 466 ASSERT_TRUE(test.read_data.empty());
325 ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step); 467 ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step);
326 cronet_bidirectional_stream_destroy(test.stream); 468 cronet_bidirectional_stream_destroy(test.stream);
327 } 469 }
328 470
329 TEST_F(CronetBidirectionalStreamTest, CancelOnSucceeded) { 471 TEST_P(CronetBidirectionalStreamTest, CancelOnSucceeded) {
330 TestBidirectionalStreamCallback test; 472 TestBidirectionalStreamCallback test;
331 test.stream = 473 test.stream =
332 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 474 cronet_bidirectional_stream_create(engine(), &test, test.callback());
333 DCHECK(test.stream); 475 DCHECK(test.stream);
476 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
477 GetParam());
334 test.cancel_from_step = TestBidirectionalStreamCallback::ON_SUCCEEDED; 478 test.cancel_from_step = TestBidirectionalStreamCallback::ON_SUCCEEDED;
335 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST", 479 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
336 &kTestHeadersArray, true); 480 &kTestHeadersArray, true);
337 test.BlockForDone(); 481 test.BlockForDone();
338 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]); 482 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
339 ASSERT_EQ(std::string(kHelloBodyValue), test.read_data.front()); 483 ASSERT_EQ(std::string(kHelloBodyValue), test.read_data.front());
340 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step); 484 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
341 cronet_bidirectional_stream_destroy(test.stream); 485 cronet_bidirectional_stream_destroy(test.stream);
342 } 486 }
343 487
344 TEST_F(CronetBidirectionalStreamTest, ReadFailsBeforeRequestStarted) { 488 TEST_P(CronetBidirectionalStreamTest, ReadFailsBeforeRequestStarted) {
345 TestBidirectionalStreamCallback test; 489 TestBidirectionalStreamCallback test;
346 test.stream = 490 test.stream =
347 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 491 cronet_bidirectional_stream_create(engine(), &test, test.callback());
348 DCHECK(test.stream); 492 DCHECK(test.stream);
493 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
494 GetParam());
349 char read_buffer[1]; 495 char read_buffer[1];
350 cronet_bidirectional_stream_read(test.stream, read_buffer, 496 cronet_bidirectional_stream_read(test.stream, read_buffer,
351 sizeof(read_buffer)); 497 sizeof(read_buffer));
352 test.BlockForDone(); 498 test.BlockForDone();
353 ASSERT_TRUE(test.read_data.empty()); 499 ASSERT_TRUE(test.read_data.empty());
354 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step); 500 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
355 ASSERT_EQ(net::ERR_UNEXPECTED, test.net_error); 501 ASSERT_EQ(net::ERR_UNEXPECTED, test.net_error);
356 cronet_bidirectional_stream_destroy(test.stream); 502 cronet_bidirectional_stream_destroy(test.stream);
357 } 503 }
358 504
359 TEST_F(CronetBidirectionalStreamTest, 505 TEST_P(CronetBidirectionalStreamTest,
360 StreamFailBeforeReadIsExecutedOnNetworkThread) { 506 StreamFailBeforeReadIsExecutedOnNetworkThread) {
361 class CustomTestBidirectionalStreamCallback 507 class CustomTestBidirectionalStreamCallback
362 : public TestBidirectionalStreamCallback { 508 : public TestBidirectionalStreamCallback {
363 bool MaybeCancel(cronet_bidirectional_stream* stream, 509 bool MaybeCancel(cronet_bidirectional_stream* stream,
364 ResponseStep step) override { 510 ResponseStep step) override {
365 if (step == ResponseStep::ON_READ_COMPLETED) { 511 if (step == ResponseStep::ON_READ_COMPLETED) {
366 // Shut down the server, and the stream should error out. 512 // Shut down the server, and the stream should error out.
367 // The second call to ShutdownQuicTestServer is no-op. 513 // The second call to ShutdownQuicTestServer is no-op.
368 ShutdownQuicTestServer(); 514 ShutdownQuicTestServer();
369 } 515 }
370 return TestBidirectionalStreamCallback::MaybeCancel(stream, step); 516 return TestBidirectionalStreamCallback::MaybeCancel(stream, step);
371 } 517 }
372 }; 518 };
373 519
374 CustomTestBidirectionalStreamCallback test; 520 CustomTestBidirectionalStreamCallback test;
375 test.AddWriteData("Hello, "); 521 test.AddWriteData("Hello, ");
376 test.AddWriteData("world!"); 522 test.AddWriteData("world!");
377 test.read_buffer_size = 2; 523 test.read_buffer_size = 2;
378 test.stream = 524 test.stream =
379 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 525 cronet_bidirectional_stream_create(engine(), &test, test.callback());
380 DCHECK(test.stream); 526 DCHECK(test.stream);
527 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
528 GetParam());
381 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST", 529 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
382 &kTestHeadersArray, false); 530 &kTestHeadersArray, false);
383 test.BlockForDone(); 531 test.BlockForDone();
384 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step); 532 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
385 ASSERT_EQ(net::ERR_QUIC_PROTOCOL_ERROR, test.net_error); 533 ASSERT_EQ(net::ERR_QUIC_PROTOCOL_ERROR, test.net_error);
386 cronet_bidirectional_stream_destroy(test.stream); 534 cronet_bidirectional_stream_destroy(test.stream);
387 } 535 }
388 536
389 TEST_F(CronetBidirectionalStreamTest, WriteFailsBeforeRequestStarted) { 537 TEST_P(CronetBidirectionalStreamTest, WriteFailsBeforeRequestStarted) {
390 TestBidirectionalStreamCallback test; 538 TestBidirectionalStreamCallback test;
391 test.stream = 539 test.stream =
392 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 540 cronet_bidirectional_stream_create(engine(), &test, test.callback());
393 DCHECK(test.stream); 541 DCHECK(test.stream);
542 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
543 GetParam());
394 cronet_bidirectional_stream_write(test.stream, "1", 1, false); 544 cronet_bidirectional_stream_write(test.stream, "1", 1, false);
395 test.BlockForDone(); 545 test.BlockForDone();
396 ASSERT_TRUE(test.read_data.empty()); 546 ASSERT_TRUE(test.read_data.empty());
397 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step); 547 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
398 ASSERT_EQ(net::ERR_UNEXPECTED, test.net_error); 548 ASSERT_EQ(net::ERR_UNEXPECTED, test.net_error);
399 cronet_bidirectional_stream_destroy(test.stream); 549 cronet_bidirectional_stream_destroy(test.stream);
400 } 550 }
401 551
402 TEST_F(CronetBidirectionalStreamTest, 552 TEST_P(CronetBidirectionalStreamTest,
403 StreamFailBeforeWriteIsExecutedOnNetworkThread) { 553 StreamFailBeforeWriteIsExecutedOnNetworkThread) {
404 class CustomTestBidirectionalStreamCallback 554 class CustomTestBidirectionalStreamCallback
405 : public TestBidirectionalStreamCallback { 555 : public TestBidirectionalStreamCallback {
406 bool MaybeCancel(cronet_bidirectional_stream* stream, 556 bool MaybeCancel(cronet_bidirectional_stream* stream,
407 ResponseStep step) override { 557 ResponseStep step) override {
408 if (step == ResponseStep::ON_WRITE_COMPLETED) { 558 if (step == ResponseStep::ON_WRITE_COMPLETED) {
409 // Shut down the server, and the stream should error out. 559 // Shut down the server, and the stream should error out.
410 // The second call to ShutdownQuicTestServer is no-op. 560 // The second call to ShutdownQuicTestServer is no-op.
411 ShutdownQuicTestServer(); 561 ShutdownQuicTestServer();
412 } 562 }
413 return TestBidirectionalStreamCallback::MaybeCancel(stream, step); 563 return TestBidirectionalStreamCallback::MaybeCancel(stream, step);
414 } 564 }
415 }; 565 };
416 566
417 CustomTestBidirectionalStreamCallback test; 567 CustomTestBidirectionalStreamCallback test;
418 test.AddWriteData("Test String"); 568 test.AddWriteData("Test String");
419 test.AddWriteData("1234567890"); 569 test.AddWriteData("1234567890");
420 test.AddWriteData("woot!"); 570 test.AddWriteData("woot!");
421 test.stream = 571 test.stream =
422 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 572 cronet_bidirectional_stream_create(engine(), &test, test.callback());
423 DCHECK(test.stream); 573 DCHECK(test.stream);
574 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
575 GetParam());
424 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST", 576 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
425 &kTestHeadersArray, false); 577 &kTestHeadersArray, false);
426 test.BlockForDone(); 578 test.BlockForDone();
427 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step); 579 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
428 ASSERT_EQ(net::ERR_QUIC_PROTOCOL_ERROR, test.net_error); 580 ASSERT_TRUE(test.net_error == net::ERR_QUIC_PROTOCOL_ERROR ||
581 test.net_error == net::ERR_QUIC_HANDSHAKE_FAILED);
429 cronet_bidirectional_stream_destroy(test.stream); 582 cronet_bidirectional_stream_destroy(test.stream);
430 } 583 }
431 584
432 TEST_F(CronetBidirectionalStreamTest, FailedResolution) { 585 TEST_P(CronetBidirectionalStreamTest, FailedResolution) {
433 TestBidirectionalStreamCallback test; 586 TestBidirectionalStreamCallback test;
434 test.stream = 587 test.stream =
435 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 588 cronet_bidirectional_stream_create(engine(), &test, test.callback());
436 DCHECK(test.stream); 589 DCHECK(test.stream);
590 cronet_bidirectional_stream_delay_request_headers_until_flush(test.stream,
591 GetParam());
437 test.cancel_from_step = TestBidirectionalStreamCallback::ON_FAILED; 592 test.cancel_from_step = TestBidirectionalStreamCallback::ON_FAILED;
438 cronet_bidirectional_stream_start(test.stream, "https://notfound.example.com", 593 cronet_bidirectional_stream_start(test.stream, "https://notfound.example.com",
439 0, "GET", &kTestHeadersArray, true); 594 0, "GET", &kTestHeadersArray, true);
440 test.BlockForDone(); 595 test.BlockForDone();
441 ASSERT_TRUE(test.read_data.empty()); 596 ASSERT_TRUE(test.read_data.empty());
442 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step); 597 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
443 ASSERT_EQ(net::ERR_NAME_NOT_RESOLVED, test.net_error); 598 ASSERT_EQ(net::ERR_NAME_NOT_RESOLVED, test.net_error);
444 cronet_bidirectional_stream_destroy(test.stream); 599 cronet_bidirectional_stream_destroy(test.stream);
445 } 600 }
446 601
602 INSTANTIATE_TEST_CASE_P(CronetBidirectionalStreamDelayRequestHeadersUntilFlush,
603 CronetBidirectionalStreamTest,
604 ::testing::Values(true, false));
605
447 } // namespace cronet 606 } // 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