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

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

Issue 1892423002: [Cronet] Add Hello World response to QuicTestServer and use it in bidirectional stream test. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cronet7
Patch Set: Make tests with ShutdownQuicTestServer work. Created 4 years, 7 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/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "base/strings/sys_string_conversions.h" 14 #include "base/strings/sys_string_conversions.h"
15 #include "base/synchronization/waitable_event.h" 15 #include "base/synchronization/waitable_event.h"
16 #include "components/cronet/ios/cronet_c_for_grpc.h" 16 #include "components/cronet/ios/cronet_c_for_grpc.h"
17 #include "components/cronet/ios/cronet_environment.h" 17 #include "components/cronet/ios/cronet_environment.h"
18 #include "components/cronet/ios/test/quic_test_server.h" 18 #include "components/cronet/ios/test/quic_test_server.h"
19 #include "net/base/mac/url_conversions.h" 19 #include "net/base/mac/url_conversions.h"
20 #include "net/base/net_errors.h" 20 #include "net/base/net_errors.h"
21 #include "net/base/test_data_directory.h" 21 #include "net/base/test_data_directory.h"
22 #include "net/cert/mock_cert_verifier.h" 22 #include "net/cert/mock_cert_verifier.h"
23 #include "testing/gtest/include/gtest/gtest.h" 23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "testing/gtest_mac.h" 24 #include "testing/gtest_mac.h"
25 #include "url/gurl.h" 25 #include "url/gurl.h"
26 26
27 namespace { 27 namespace {
28 const char kTestServerHost[] = "test.example.com";
29 const int kTestServerPort = 6121;
30 const char kTestServerUrl[] = "https://test.example.com:6121";
31 28
32 cronet_bidirectional_stream_header kTestHeaders[] = { 29 cronet_bidirectional_stream_header kTestHeaders[] = {
33 {"header1", "foo"}, 30 {"header1", "foo"},
34 {"header2", "bar"}, 31 {"header2", "bar"},
35 }; 32 };
36 const cronet_bidirectional_stream_header_array kTestHeadersArray = { 33 const cronet_bidirectional_stream_header_array kTestHeadersArray = {
37 2, 2, kTestHeaders}; 34 2, 2, kTestHeaders};
38 } // namespace 35 } // namespace
39 36
37 namespace cronet {
38
40 class CronetBidirectionalStreamTest : public ::testing::Test { 39 class CronetBidirectionalStreamTest : public ::testing::Test {
41 protected: 40 protected:
42 CronetBidirectionalStreamTest() {} 41 CronetBidirectionalStreamTest() {}
43 ~CronetBidirectionalStreamTest() override {} 42 ~CronetBidirectionalStreamTest() override {}
44 43
45 void SetUp() override { 44 void SetUp() override {
46 static bool initialized = false; 45 static bool initialized = false;
47 if (!initialized) { 46 if (!initialized) {
48 initialized = true; 47 initialized = true;
49 // Hack to work around issues with SetUp being called multiple times 48 // Hack to work around issues with SetUp being called multiple times
50 // during the test, and QuicTestServer not shutting down / restarting 49 // during the test, and QuicTestServer not shutting down / restarting
51 // gracefully. 50 // gracefully.
52 cronet::CronetEnvironment::Initialize(); 51 CronetEnvironment::Initialize();
53 cronet::StartQuicTestServer();
54 } 52 }
55 53
56 cronet_environment_ = new cronet::CronetEnvironment("CronetTest/1.0.0.0"); 54 StartQuicTestServer();
55
56 cronet_environment_ = new CronetEnvironment("CronetTest/1.0.0.0");
57 cronet_environment_->set_http2_enabled(true); 57 cronet_environment_->set_http2_enabled(true);
58 cronet_environment_->set_quic_enabled(true); 58 cronet_environment_->set_quic_enabled(true);
59 cronet_environment_->set_ssl_key_log_file_name("SSLKEYLOGFILE"); 59 cronet_environment_->set_ssl_key_log_file_name("SSLKEYLOGFILE");
60 60
61 std::unique_ptr<net::MockCertVerifier> mock_cert_verifier( 61 std::unique_ptr<net::MockCertVerifier> mock_cert_verifier(
62 new net::MockCertVerifier()); 62 new net::MockCertVerifier());
63 mock_cert_verifier->set_default_result(net::OK); 63 mock_cert_verifier->set_default_result(net::OK);
64 64
65 cronet_environment_->set_cert_verifier(std::move(mock_cert_verifier)); 65 cronet_environment_->set_cert_verifier(std::move(mock_cert_verifier));
66 cronet_environment_->set_host_resolver_rules( 66 cronet_environment_->set_host_resolver_rules(
67 "MAP test.example.com 127.0.0.1," 67 "MAP test.example.com 127.0.0.1,"
68 "MAP notfound.example.com ~NOTFOUND"); 68 "MAP notfound.example.com ~NOTFOUND");
69 cronet_environment_->AddQuicHint(kTestServerHost, kTestServerPort, 69 cronet_environment_->AddQuicHint(kTestServerDomain, kTestServerPort,
70 kTestServerPort); 70 kTestServerPort);
71 71
72 cronet_environment_->Start(); 72 cronet_environment_->Start();
73 73
74 cronet_engine_.obj = cronet_environment_; 74 cronet_engine_.obj = cronet_environment_;
75 75
76 cronet_environment_->StartNetLog("cronet_netlog.json", true); 76 cronet_environment_->StartNetLog("cronet_netlog.json", true);
77 } 77 }
78 78
79 void TearDown() override { 79 void TearDown() override {
80 // cronet::ShutdownQuicTestServer(); 80 ShutdownQuicTestServer();
81 cronet_environment_->StopNetLog(); 81 cronet_environment_->StopNetLog();
82 //[CronetEngine stopNetLog]; 82 //[CronetEngine stopNetLog];
83 //[CronetEngine uninstall]; 83 //[CronetEngine uninstall];
84 } 84 }
85 85
86 cronet_engine* engine() { return &cronet_engine_; } 86 cronet_engine* engine() { return &cronet_engine_; }
87 87
88 private: 88 private:
89 static cronet::CronetEnvironment* cronet_environment_; 89 static CronetEnvironment* cronet_environment_;
90 static cronet_engine cronet_engine_; 90 static cronet_engine cronet_engine_;
91 }; 91 };
92 92
93 cronet::CronetEnvironment* CronetBidirectionalStreamTest::cronet_environment_; 93 CronetEnvironment* CronetBidirectionalStreamTest::cronet_environment_;
94 cronet_engine CronetBidirectionalStreamTest::cronet_engine_; 94 cronet_engine CronetBidirectionalStreamTest::cronet_engine_;
95 95
96 class TestBidirectionalStreamCallback { 96 class TestBidirectionalStreamCallback {
97 public: 97 public:
98 enum ResponseStep { 98 enum ResponseStep {
99 NOTHING, 99 NOTHING,
100 ON_REQUEST_HEADERS_SENT, 100 ON_REQUEST_HEADERS_SENT,
101 ON_RESPONSE_STARTED, 101 ON_RESPONSE_STARTED,
102 ON_READ_COMPLETED, 102 ON_READ_COMPLETED,
103 ON_WRITE_COMPLETED, 103 ON_WRITE_COMPLETED,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 if (read_buffer) 139 if (read_buffer)
140 delete read_buffer; 140 delete read_buffer;
141 } 141 }
142 142
143 static TestBidirectionalStreamCallback* FromStream( 143 static TestBidirectionalStreamCallback* FromStream(
144 cronet_bidirectional_stream* stream) { 144 cronet_bidirectional_stream* stream) {
145 DCHECK(stream); 145 DCHECK(stream);
146 return (TestBidirectionalStreamCallback*)stream->annotation; 146 return (TestBidirectionalStreamCallback*)stream->annotation;
147 } 147 }
148 148
149 bool MaybeCancel(cronet_bidirectional_stream* stream, ResponseStep step) { 149 virtual bool MaybeCancel(cronet_bidirectional_stream* stream,
150 ResponseStep step) {
150 DCHECK_EQ(stream, this->stream); 151 DCHECK_EQ(stream, this->stream);
151 response_step = step; 152 response_step = step;
152 DLOG(WARNING) << "Step: " << step; 153 DLOG(WARNING) << "Step: " << step;
153 154
154 if (step != cancel_from_step) 155 if (step != cancel_from_step)
155 return false; 156 return false;
156 157
157 cronet_bidirectional_stream_cancel(stream); 158 cronet_bidirectional_stream_cancel(stream);
158 return true; 159 return true;
159 } 160 }
160 161
161 void SignalDone() { stream_done_event.Signal(); } 162 void SignalDone() { stream_done_event.Signal(); }
162 163
163 void BlockForDone() { stream_done_event.Wait(); } 164 void BlockForDone() { stream_done_event.Wait(); }
164 165
165 void AddWriteData(const std::string& data) { write_data.push_back(data); } 166 void AddWriteData(const std::string& data) { write_data.push_back(data); }
166 167
167 void MaybeWriteNextData(cronet_bidirectional_stream* stream) { 168 virtual void MaybeWriteNextData(cronet_bidirectional_stream* stream) {
168 DCHECK_EQ(stream, this->stream); 169 DCHECK_EQ(stream, this->stream);
169 if (write_data.empty()) 170 if (write_data.empty())
170 return; 171 return;
171 cronet_bidirectional_stream_write(stream, write_data.front().c_str(), 172 cronet_bidirectional_stream_write(stream, write_data.front().c_str(),
172 write_data.front().size(), 173 write_data.front().size(),
173 write_data.size() == 1); 174 write_data.size() == 1);
174 } 175 }
175 176
176 cronet_bidirectional_stream_callback* callback() const { return &s_callback; } 177 cronet_bidirectional_stream_callback* callback() const { return &s_callback; }
177 178
178 private: 179 private:
179 // C callbacks. 180 // C callbacks.
180 static void on_request_headers_sent_callback( 181 static void on_request_headers_sent_callback(
xunjieli 2016/04/28 15:23:33 nit: This callback is changed to on_stream_ready()
mef 2016/04/28 17:11:26 Done.
181 cronet_bidirectional_stream* stream) { 182 cronet_bidirectional_stream* stream) {
182 TestBidirectionalStreamCallback* test = FromStream(stream); 183 TestBidirectionalStreamCallback* test = FromStream(stream);
183 if (test->MaybeCancel(stream, ON_REQUEST_HEADERS_SENT)) 184 if (test->MaybeCancel(stream, ON_REQUEST_HEADERS_SENT))
xunjieli 2016/04/28 15:23:33 nit: s/ON_REQUEST_HEADERS_SENT/ON_STREAM_READY
mef 2016/04/28 17:11:26 Done.
184 return; 185 return;
185 test->MaybeWriteNextData(stream); 186 test->MaybeWriteNextData(stream);
186 } 187 }
187 188
188 static void on_response_headers_received_callback( 189 static void on_response_headers_received_callback(
189 cronet_bidirectional_stream* stream, 190 cronet_bidirectional_stream* stream,
190 const cronet_bidirectional_stream_header_array* headers, 191 const cronet_bidirectional_stream_header_array* headers,
191 const char* negotiated_protocol) { 192 const char* negotiated_protocol) {
192 TestBidirectionalStreamCallback* test = FromStream(stream); 193 TestBidirectionalStreamCallback* test = FromStream(stream);
193 ASSERT_EQ(test->expected_negotiated_protocol, 194 ASSERT_EQ(test->expected_negotiated_protocol,
(...skipping 29 matching lines...) Expand all
223 if (test->MaybeCancel(stream, ON_WRITE_COMPLETED)) 224 if (test->MaybeCancel(stream, ON_WRITE_COMPLETED))
224 return; 225 return;
225 test->write_data.pop_front(); 226 test->write_data.pop_front();
226 test->MaybeWriteNextData(stream); 227 test->MaybeWriteNextData(stream);
227 } 228 }
228 229
229 static void on_response_trailers_received_callback( 230 static void on_response_trailers_received_callback(
230 cronet_bidirectional_stream* stream, 231 cronet_bidirectional_stream* stream,
231 const cronet_bidirectional_stream_header_array* trailers) { 232 const cronet_bidirectional_stream_header_array* trailers) {
232 TestBidirectionalStreamCallback* test = FromStream(stream); 233 TestBidirectionalStreamCallback* test = FromStream(stream);
234 for (size_t i = 0; i < trailers->count; ++i) {
235 test->response_trailers[trailers->headers[i].key] =
236 trailers->headers[i].value;
237 }
238
233 if (test->MaybeCancel(stream, ON_TRAILERS)) 239 if (test->MaybeCancel(stream, ON_TRAILERS))
234 return; 240 return;
235 } 241 }
236 242
237 static void on_succeded_callback(cronet_bidirectional_stream* stream) { 243 static void on_succeded_callback(cronet_bidirectional_stream* stream) {
238 TestBidirectionalStreamCallback* test = FromStream(stream); 244 TestBidirectionalStreamCallback* test = FromStream(stream);
239 test->MaybeCancel(stream, ON_SUCCEEDED); 245 test->MaybeCancel(stream, ON_SUCCEEDED);
240 test->SignalDone(); 246 test->SignalDone();
241 } 247 }
242 248
(...skipping 29 matching lines...) Expand all
272 TestBidirectionalStreamCallback test; 278 TestBidirectionalStreamCallback test;
273 test.AddWriteData("Hello, "); 279 test.AddWriteData("Hello, ");
274 test.AddWriteData("world!"); 280 test.AddWriteData("world!");
275 test.read_buffer_size = 2; 281 test.read_buffer_size = 2;
276 test.stream = 282 test.stream =
277 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 283 cronet_bidirectional_stream_create(engine(), &test, test.callback());
278 DCHECK(test.stream); 284 DCHECK(test.stream);
279 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST", 285 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
280 &kTestHeadersArray, false); 286 &kTestHeadersArray, false);
281 test.BlockForDone(); 287 test.BlockForDone();
282 ASSERT_EQ(std::string("404"), test.response_headers[":status"]); 288 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
289 ASSERT_EQ(std::string(kHelloHeaderValue),
290 test.response_headers[kHelloHeaderName]);
283 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step); 291 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
284 ASSERT_EQ(std::string("fi"), test.read_data.front()); 292 ASSERT_EQ(std::string(kHelloBodyValue, 2), test.read_data.front());
285 ASSERT_EQ(std::string("file not found"), 293 ASSERT_EQ(std::string(kHelloBodyValue), base::JoinString(test.read_data, ""));
286 base::JoinString(test.read_data, "")); 294 ASSERT_EQ(std::string(kHelloTrailerValue),
295 test.response_trailers[kHelloTrailerName]);
287 cronet_bidirectional_stream_destroy(test.stream); 296 cronet_bidirectional_stream_destroy(test.stream);
288 } 297 }
289 298
290 TEST_F(CronetBidirectionalStreamTest, CancelOnRead) { 299 TEST_F(CronetBidirectionalStreamTest, CancelOnRead) {
291 TestBidirectionalStreamCallback test; 300 TestBidirectionalStreamCallback test;
292 test.stream = 301 test.stream =
293 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 302 cronet_bidirectional_stream_create(engine(), &test, test.callback());
294 DCHECK(test.stream); 303 DCHECK(test.stream);
295 test.cancel_from_step = TestBidirectionalStreamCallback::ON_READ_COMPLETED; 304 test.cancel_from_step = TestBidirectionalStreamCallback::ON_READ_COMPLETED;
296 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST", 305 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
297 &kTestHeadersArray, true); 306 &kTestHeadersArray, true);
298 test.BlockForDone(); 307 test.BlockForDone();
299 ASSERT_EQ(std::string("404"), test.response_headers[":status"]); 308 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
300 ASSERT_EQ(std::string("file not found"), test.read_data.front()); 309 ASSERT_EQ(std::string(kHelloBodyValue), test.read_data.front());
301 ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step); 310 ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step);
302 cronet_bidirectional_stream_destroy(test.stream); 311 cronet_bidirectional_stream_destroy(test.stream);
303 } 312 }
304 313
305 TEST_F(CronetBidirectionalStreamTest, CancelOnResponse) { 314 TEST_F(CronetBidirectionalStreamTest, CancelOnResponse) {
306 TestBidirectionalStreamCallback test; 315 TestBidirectionalStreamCallback test;
307 test.stream = 316 test.stream =
308 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 317 cronet_bidirectional_stream_create(engine(), &test, test.callback());
309 DCHECK(test.stream); 318 DCHECK(test.stream);
310 test.cancel_from_step = TestBidirectionalStreamCallback::ON_RESPONSE_STARTED; 319 test.cancel_from_step = TestBidirectionalStreamCallback::ON_RESPONSE_STARTED;
311 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST", 320 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
312 &kTestHeadersArray, true); 321 &kTestHeadersArray, true);
313 test.BlockForDone(); 322 test.BlockForDone();
314 ASSERT_EQ(std::string("404"), test.response_headers[":status"]); 323 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
315 ASSERT_TRUE(test.read_data.empty()); 324 ASSERT_TRUE(test.read_data.empty());
316 ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step); 325 ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step);
317 cronet_bidirectional_stream_destroy(test.stream); 326 cronet_bidirectional_stream_destroy(test.stream);
318 } 327 }
319 328
320 TEST_F(CronetBidirectionalStreamTest, CancelOnSucceeded) { 329 TEST_F(CronetBidirectionalStreamTest, CancelOnSucceeded) {
321 TestBidirectionalStreamCallback test; 330 TestBidirectionalStreamCallback test;
322 test.stream = 331 test.stream =
323 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 332 cronet_bidirectional_stream_create(engine(), &test, test.callback());
324 DCHECK(test.stream); 333 DCHECK(test.stream);
325 test.cancel_from_step = TestBidirectionalStreamCallback::ON_SUCCEEDED; 334 test.cancel_from_step = TestBidirectionalStreamCallback::ON_SUCCEEDED;
326 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST", 335 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
327 &kTestHeadersArray, true); 336 &kTestHeadersArray, true);
328 test.BlockForDone(); 337 test.BlockForDone();
329 ASSERT_EQ(std::string("404"), test.response_headers[":status"]); 338 ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]);
330 ASSERT_EQ(std::string("file not found"), test.read_data.front()); 339 ASSERT_EQ(std::string(kHelloBodyValue), test.read_data.front());
331 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step); 340 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
332 cronet_bidirectional_stream_destroy(test.stream); 341 cronet_bidirectional_stream_destroy(test.stream);
333 } 342 }
334 343
335 TEST_F(CronetBidirectionalStreamTest, ReadFailsBeforeRequestStarted) { 344 TEST_F(CronetBidirectionalStreamTest, ReadFailsBeforeRequestStarted) {
336 TestBidirectionalStreamCallback test; 345 TestBidirectionalStreamCallback test;
337 test.stream = 346 test.stream =
338 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 347 cronet_bidirectional_stream_create(engine(), &test, test.callback());
339 DCHECK(test.stream); 348 DCHECK(test.stream);
340 char read_buffer[1]; 349 char read_buffer[1];
341 cronet_bidirectional_stream_read(test.stream, read_buffer, 350 cronet_bidirectional_stream_read(test.stream, read_buffer,
342 sizeof(read_buffer)); 351 sizeof(read_buffer));
343 test.BlockForDone(); 352 test.BlockForDone();
344 ASSERT_TRUE(test.read_data.empty()); 353 ASSERT_TRUE(test.read_data.empty());
345 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step); 354 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
346 ASSERT_EQ(net::ERR_UNEXPECTED, test.net_error); 355 ASSERT_EQ(net::ERR_UNEXPECTED, test.net_error);
347 cronet_bidirectional_stream_destroy(test.stream); 356 cronet_bidirectional_stream_destroy(test.stream);
348 } 357 }
349 358
359 TEST_F(CronetBidirectionalStreamTest,
360 StreamFailBeforeReadIsExecutedOnNetworkThread) {
361 class CustomTestBidirectionalStreamCallback
362 : public TestBidirectionalStreamCallback {
363 bool MaybeCancel(cronet_bidirectional_stream* stream,
364 ResponseStep step) override {
365 if (step == ResponseStep::ON_READ_COMPLETED) {
366 // Shut down the server, and the stream should error out.
367 // The second call to ShutdownQuicTestServer is no-op.
368 ShutdownQuicTestServer();
369 }
370 return TestBidirectionalStreamCallback::MaybeCancel(stream, step);
371 }
372 };
373
374 CustomTestBidirectionalStreamCallback test;
375 test.AddWriteData("Hello, ");
376 test.AddWriteData("world!");
377 test.read_buffer_size = 2;
378 test.stream =
379 cronet_bidirectional_stream_create(engine(), &test, test.callback());
380 DCHECK(test.stream);
381 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
382 &kTestHeadersArray, false);
383 test.BlockForDone();
384 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
385 ASSERT_EQ(net::ERR_QUIC_PROTOCOL_ERROR, test.net_error);
386 cronet_bidirectional_stream_destroy(test.stream);
387 }
388
350 TEST_F(CronetBidirectionalStreamTest, WriteFailsBeforeRequestStarted) { 389 TEST_F(CronetBidirectionalStreamTest, WriteFailsBeforeRequestStarted) {
351 TestBidirectionalStreamCallback test; 390 TestBidirectionalStreamCallback test;
352 test.stream = 391 test.stream =
353 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 392 cronet_bidirectional_stream_create(engine(), &test, test.callback());
354 DCHECK(test.stream); 393 DCHECK(test.stream);
355 cronet_bidirectional_stream_write(test.stream, "1", 1, false); 394 cronet_bidirectional_stream_write(test.stream, "1", 1, false);
356 test.BlockForDone(); 395 test.BlockForDone();
357 ASSERT_TRUE(test.read_data.empty()); 396 ASSERT_TRUE(test.read_data.empty());
358 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step); 397 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
359 ASSERT_EQ(net::ERR_UNEXPECTED, test.net_error); 398 ASSERT_EQ(net::ERR_UNEXPECTED, test.net_error);
360 cronet_bidirectional_stream_destroy(test.stream); 399 cronet_bidirectional_stream_destroy(test.stream);
361 } 400 }
362 401
402 TEST_F(CronetBidirectionalStreamTest,
403 StreamFailBeforeWriteIsExecutedOnNetworkThread) {
404 class CustomTestBidirectionalStreamCallback
405 : public TestBidirectionalStreamCallback {
406 bool MaybeCancel(cronet_bidirectional_stream* stream,
407 ResponseStep step) override {
408 if (step == ResponseStep::ON_WRITE_COMPLETED) {
409 // Shut down the server, and the stream should error out.
410 // The second call to ShutdownQuicTestServer is no-op.
411 ShutdownQuicTestServer();
412 }
413 return TestBidirectionalStreamCallback::MaybeCancel(stream, step);
414 }
415 };
416
417 CustomTestBidirectionalStreamCallback test;
418 test.AddWriteData("Test String");
419 test.AddWriteData("1234567890");
420 test.AddWriteData("woot!");
421 test.stream =
422 cronet_bidirectional_stream_create(engine(), &test, test.callback());
423 DCHECK(test.stream);
424 cronet_bidirectional_stream_start(test.stream, kTestServerUrl, 0, "POST",
425 &kTestHeadersArray, false);
426 test.BlockForDone();
427 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
428 ASSERT_EQ(net::ERR_QUIC_PROTOCOL_ERROR, test.net_error);
429 cronet_bidirectional_stream_destroy(test.stream);
430 }
431
363 TEST_F(CronetBidirectionalStreamTest, FailedResolution) { 432 TEST_F(CronetBidirectionalStreamTest, FailedResolution) {
364 TestBidirectionalStreamCallback test; 433 TestBidirectionalStreamCallback test;
365 test.stream = 434 test.stream =
366 cronet_bidirectional_stream_create(engine(), &test, test.callback()); 435 cronet_bidirectional_stream_create(engine(), &test, test.callback());
367 DCHECK(test.stream); 436 DCHECK(test.stream);
368 test.cancel_from_step = TestBidirectionalStreamCallback::ON_FAILED; 437 test.cancel_from_step = TestBidirectionalStreamCallback::ON_FAILED;
369 cronet_bidirectional_stream_start(test.stream, "https://notfound.example.com", 438 cronet_bidirectional_stream_start(test.stream, "https://notfound.example.com",
370 0, "GET", &kTestHeadersArray, true); 439 0, "GET", &kTestHeadersArray, true);
371 test.BlockForDone(); 440 test.BlockForDone();
372 ASSERT_TRUE(test.read_data.empty()); 441 ASSERT_TRUE(test.read_data.empty());
373 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step); 442 ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step);
374 ASSERT_EQ(net::ERR_NAME_NOT_RESOLVED, test.net_error); 443 ASSERT_EQ(net::ERR_NAME_NOT_RESOLVED, test.net_error);
375 cronet_bidirectional_stream_destroy(test.stream); 444 cronet_bidirectional_stream_destroy(test.stream);
376 } 445 }
446
447 } // namespace cronet
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698