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

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

Issue 1858483002: Cronet for iOS with C API for GRPC support. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@small
Patch Set: Address Helen's comments. Created 4 years, 8 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
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import <Foundation/Foundation.h>
6 #include <stdint.h>
7 #include <list>
8 #include <map>
9 #include <string>
10
11 #include "base/logging.h"
12 #include "base/mac/scoped_nsobject.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/sys_string_conversions.h"
15 #include "base/synchronization/waitable_event.h"
16 #include "components/cronet/ios/cronet_c_for_grpc.h"
17 #include "components/cronet/ios/cronet_environment.h"
18 #include "components/cronet/ios/test/quic_test_server.h"
19 #include "net/base/mac/url_conversions.h"
20 #include "net/base/test_data_directory.h"
21 #include "net/cert/mock_cert_verifier.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "testing/gtest_mac.h"
24 #include "url/gurl.h"
25
26 class CronetBidirectionalStreamTest : public ::testing::Test {
27 protected:
28 CronetBidirectionalStreamTest() {}
29 ~CronetBidirectionalStreamTest() override {}
30
31 void SetUp() override {
32 static bool initialized = false;
xunjieli 2016/04/08 17:46:15 Why is this a static bool?
mef 2016/04/08 20:40:43 It's a kludge because I'm having troubles with Set
33 if (!initialized) {
34 initialized = true;
35 cronet::CronetEnvironment::Initialize();
36 cronet::StartQuicTestServer();
37 }
38
39 cronet_environment_ = new cronet::CronetEnvironment("CronetTest/1.0.0.0");
40 cronet_environment_->set_http2_enabled(true);
41 cronet_environment_->set_quic_enabled(true);
42 cronet_environment_->set_ssl_key_log_file_name("SSLKEYLOGFILE");
43
44 scoped_ptr<net::MockCertVerifier> mock_cert_verifier(
45 new net::MockCertVerifier());
46 mock_cert_verifier->set_default_result(net::OK);
47
48 // cronet_environment_->set_cert_verifier(std::move(mock_cert_verifier));
49 cronet_environment_->set_host_resolver_rules(
50 "MAP test.example.com 127.0.0.1");
51 cronet_environment_->AddQuicHint("test.example.com", 6121, 6121);
52
53 cronet_environment_->Install();
54
55 cronet_engine_.obj = cronet_environment_;
56
57 // logging::SetMinLogLevel(-5);
58 cronet_environment_->StartNetLog("cronet_netlog.json", true);
59 //[CronetEngine startNetLogToFile:@"cronet_test_netlog.json" logBytes:YES];
60 }
61
62 void TearDown() override {
63 // cronet::ShutdownQuicTestServer();
64 cronet_environment_->StopNetLog();
65 //[CronetEngine stopNetLog];
66 //[CronetEngine uninstall];
67 }
68
69 cronet_engine* engine() { return &cronet_engine_; }
70
71 private:
72 static cronet::CronetEnvironment* cronet_environment_;
73 static cronet_engine cronet_engine_;
74 };
75
76 cronet::CronetEnvironment* CronetBidirectionalStreamTest::cronet_environment_;
77 cronet_engine CronetBidirectionalStreamTest::cronet_engine_;
78
79 class TestBidirectionalStreamCallback {
80 public:
81 enum ResponseStep {
82 NOTHING,
83 ON_REQUEST_HEADERS_SENT,
84 ON_RESPONSE_STARTED,
85 ON_READ_COMPLETED,
86 ON_WRITE_COMPLETED,
87 ON_TRAILERS,
88 ON_CANCELED,
89 ON_FAILED,
90 ON_SUCCEEDED
91 };
92
93 cronet_bidirectional_stream* stream;
94 base::WaitableEvent stream_done_event;
95
96 // Test parameters.
97 std::map<std::string, std::string> request_headers;
98 std::list<std::string> write_data;
99 std::string expected_negotiated_protocol;
100 ResponseStep cancel_from_step;
101 size_t read_buffer_size;
102
103 // Test results.
104 ResponseStep response_step;
105 char* read_buffer;
106 std::map<std::string, std::string> response_headers;
107 std::map<std::string, std::string> response_trailers;
108 std::vector<std::string> read_data;
109
110 TestBidirectionalStreamCallback()
111 : stream(nullptr),
112 stream_done_event(true, false),
113 expected_negotiated_protocol("quic/1+spdy/3"),
114 cancel_from_step(NOTHING),
115 read_buffer_size(32768),
116 response_step(NOTHING),
117 read_buffer(nullptr) {}
118
119 ~TestBidirectionalStreamCallback() {
120 if (read_buffer)
121 delete read_buffer;
122 }
123
124 static TestBidirectionalStreamCallback* FromStream(
125 cronet_bidirectional_stream* stream) {
126 DCHECK(stream);
127 return (TestBidirectionalStreamCallback*)stream->annotation;
128 }
129
130 bool MaybeCancel(cronet_bidirectional_stream* stream, ResponseStep step) {
131 DCHECK_EQ(stream, this->stream);
132 response_step = step;
133 DLOG(WARNING) << "Step: " << step;
134
135 if (step != cancel_from_step)
136 return false;
137
138 cronet_bidirectional_stream_cancel(stream);
139 return true;
140 }
141
142 void SignalDone() { stream_done_event.Signal(); }
143
144 void BlockForDone() { stream_done_event.Wait(); }
145
146 void AddWriteData(const std::string& data) { write_data.push_back(data); }
147
148 void MaybeWriteNextData(cronet_bidirectional_stream* stream) {
149 DCHECK_EQ(stream, this->stream);
150 if (write_data.empty())
151 return;
152 cronet_bidirectional_stream_write(stream, write_data.front().c_str(),
153 write_data.front().size(),
154 write_data.size() == 1);
155 }
156
157 cronet_bidirectional_stream_callback* callback() const { return &s_callback; }
158
159 private:
160 // C callbacks.
161 static void on_request_headers_sent_callback(
162 cronet_bidirectional_stream* stream) {
163 TestBidirectionalStreamCallback* test = FromStream(stream);
164 if (test->MaybeCancel(stream, ON_REQUEST_HEADERS_SENT))
165 return;
166 test->MaybeWriteNextData(stream);
167 }
168
169 static void on_response_headers_received_callback(
170 cronet_bidirectional_stream* stream,
171 const cronet_bidirectional_stream_header_array* headers,
172 const char* negotiated_protocol) {
173 TestBidirectionalStreamCallback* test = FromStream(stream);
174 ASSERT_EQ(test->expected_negotiated_protocol,
175 std::string(negotiated_protocol));
176 for (size_t i = 0; i < headers->count; ++i) {
177 test->response_headers[headers->headers[i].key] =
178 headers->headers[i].value;
179 }
180 if (test->MaybeCancel(stream, ON_RESPONSE_STARTED))
181 return;
182 test->read_buffer = new char[test->read_buffer_size];
183 cronet_bidirectional_stream_read(stream, test->read_buffer,
184 test->read_buffer_size);
185 }
186
187 static void on_read_completed_callback(cronet_bidirectional_stream* stream,
188 char* data,
189 int count) {
190 TestBidirectionalStreamCallback* test = FromStream(stream);
191 test->read_data.push_back(std::string(data, count));
192 if (test->MaybeCancel(stream, ON_READ_COMPLETED))
193 return;
194 if (count == 0)
195 return;
196 cronet_bidirectional_stream_read(stream, test->read_buffer,
197 test->read_buffer_size);
198 }
199
200 static void on_write_completed_callback(cronet_bidirectional_stream* stream,
201 const char* data) {
202 TestBidirectionalStreamCallback* test = FromStream(stream);
203 ASSERT_EQ(test->write_data.front().c_str(), data);
204 if (test->MaybeCancel(stream, ON_WRITE_COMPLETED))
205 return;
206 test->write_data.pop_front();
207 test->MaybeWriteNextData(stream);
208 }
209
210 static void on_response_trailers_received_callback(
211 cronet_bidirectional_stream* stream,
212 const cronet_bidirectional_stream_header_array* trailers) {
213 TestBidirectionalStreamCallback* test = FromStream(stream);
214 if (test->MaybeCancel(stream, ON_TRAILERS))
215 return;
216 }
217
218 static void on_succeded_callback(cronet_bidirectional_stream* stream) {
219 TestBidirectionalStreamCallback* test = FromStream(stream);
220 test->MaybeCancel(stream, ON_SUCCEEDED);
221 test->SignalDone();
222 }
223
224 static void on_failed_callback(cronet_bidirectional_stream* stream,
225 int net_error) {
226 TestBidirectionalStreamCallback* test = FromStream(stream);
227 test->MaybeCancel(stream, ON_FAILED);
228 test->SignalDone();
229 }
230
231 static void on_canceled_callback(cronet_bidirectional_stream* stream) {
232 TestBidirectionalStreamCallback* test = FromStream(stream);
233 test->MaybeCancel(stream, ON_CANCELED);
234 test->SignalDone();
235 }
236
237 static cronet_bidirectional_stream_callback s_callback;
238 };
239
240 cronet_bidirectional_stream_callback
241 TestBidirectionalStreamCallback::s_callback = {
242 on_request_headers_sent_callback,
243 on_response_headers_received_callback,
244 on_read_completed_callback,
245 on_write_completed_callback,
246 on_response_trailers_received_callback,
247 on_succeded_callback,
248 on_failed_callback,
249 on_canceled_callback};
250
251 TEST_F(CronetBidirectionalStreamTest, StartExampleBidiStream) {
252 TestBidirectionalStreamCallback test;
253 test.AddWriteData("Hello, ");
254 test.AddWriteData("world!");
255 test.read_buffer_size = 2;
256 test.stream =
257 cronet_bidirectional_stream_create(engine(), &test, test.callback());
258 DCHECK(test.stream);
259 cronet_bidirectional_stream_header headers[] = {
260 {"header1", "foo"}, {"header2", "bar"},
261 };
262 cronet_bidirectional_stream_header_array headers_array = {2, 2, headers};
263 cronet_bidirectional_stream_start(test.stream,
264 "https://test.example.com:6121", 0, "POST",
265 &headers_array, false);
266 test.BlockForDone();
267 ASSERT_EQ(std::string("404"), test.response_headers[":status"]);
268 ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step);
269 ASSERT_EQ(std::string("fi"), test.read_data.front());
270 ASSERT_EQ(std::string("file not found"),
271 base::JoinString(test.read_data, ""));
272 cronet_bidirectional_stream_destroy(test.stream);
273 }
274
275 TEST_F(CronetBidirectionalStreamTest, CancelOnRead) {
276 TestBidirectionalStreamCallback test;
277 test.stream =
278 cronet_bidirectional_stream_create(engine(), &test, test.callback());
279 DCHECK(test.stream);
280 test.cancel_from_step = TestBidirectionalStreamCallback::ON_READ_COMPLETED;
281 cronet_bidirectional_stream_header headers[] = {
282 {"header1", "foo"}, {"header2", "bar"},
283 };
284 cronet_bidirectional_stream_header_array headers_array = {2, 2, headers};
285 cronet_bidirectional_stream_start(test.stream,
286 "https://test.example.com:6121", 0, "POST",
287 &headers_array, true);
288 test.BlockForDone();
289 ASSERT_EQ(std::string("404"), test.response_headers[":status"]);
290 ASSERT_EQ(std::string("file not found"), test.read_data.front());
291 ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step);
292 cronet_bidirectional_stream_destroy(test.stream);
293 }
294
295 TEST_F(CronetBidirectionalStreamTest, CancelOnResponse) {
296 TestBidirectionalStreamCallback test;
297 test.stream =
298 cronet_bidirectional_stream_create(engine(), &test, test.callback());
299 DCHECK(test.stream);
300 test.cancel_from_step = TestBidirectionalStreamCallback::ON_RESPONSE_STARTED;
301 cronet_bidirectional_stream_header headers[] = {
302 {"header1", "foo"}, {"header2", "bar"},
303 };
304 cronet_bidirectional_stream_header_array headers_array = {2, 2, headers};
305 cronet_bidirectional_stream_start(test.stream,
306 "https://test.example.com:6121", 0, "POST",
307 &headers_array, true);
308 test.BlockForDone();
309 ASSERT_EQ(std::string("404"), test.response_headers[":status"]);
310 ASSERT_TRUE(test.read_data.empty());
311 ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step);
312 cronet_bidirectional_stream_destroy(test.stream);
313 }
314
315 TEST_F(CronetBidirectionalStreamTest, GoogleIt) {
316 TestBidirectionalStreamCallback test;
317 test.stream =
318 cronet_bidirectional_stream_create(engine(), &test, test.callback());
319 DCHECK(test.stream);
320 test.cancel_from_step = TestBidirectionalStreamCallback::ON_READ_COMPLETED;
321 test.expected_negotiated_protocol = "h2";
322 cronet_bidirectional_stream_header headers[] = {
323 {"header1", "foo"}, {"header2", "bar"},
324 };
325 cronet_bidirectional_stream_header_array headers_array = {2, 2, headers};
326 cronet_bidirectional_stream_start(test.stream, "https://www.google.com", 0,
327 "GET", &headers_array, true);
328 test.BlockForDone();
329 ASSERT_EQ(std::string("200"), test.response_headers[":status"]);
330 ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step);
331 cronet_bidirectional_stream_destroy(test.stream);
332 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698