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

Side by Side Diff: net/tools/flip_server/spdy_interface_test.cc

Issue 2169503002: Remove flip_server. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 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
« no previous file with comments | « net/tools/flip_server/spdy_interface.cc ('k') | net/tools/flip_server/spdy_ssl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/tools/flip_server/spdy_interface.h"
6
7 #include <list>
8 #include <memory>
9
10 #include "base/strings/string_piece.h"
11 #include "net/spdy/buffered_spdy_framer.h"
12 #include "net/tools/balsa/balsa_enums.h"
13 #include "net/tools/balsa/balsa_headers.h"
14 #include "net/tools/flip_server/flip_config.h"
15 #include "net/tools/flip_server/flip_test_utils.h"
16 #include "net/tools/flip_server/mem_cache.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 namespace net {
21
22 using ::base::StringPiece;
23 using ::testing::_;
24 using ::testing::InSequence;
25 using ::testing::InvokeWithoutArgs;
26 using ::testing::Return;
27 using ::testing::SaveArg;
28 using ::testing::Values;
29
30 inline bool operator==(StringPiece x,
31 const SpdyHeaderBlock::StringPieceProxy& y) {
32 return x == y.operator StringPiece();
33 }
34
35 namespace {
36
37 struct StringSaver {
38 public:
39 StringSaver() : data(NULL), size(0) {}
40 void Save() { string = std::string(data, size); }
41
42 const char* data;
43 size_t size;
44 std::string string;
45 };
46
47 class SpdyFramerVisitor : public BufferedSpdyFramerVisitorInterface {
48 public:
49 virtual ~SpdyFramerVisitor() {}
50 MOCK_METHOD1(OnError, void(SpdyFramer::SpdyError));
51 MOCK_METHOD2(OnStreamError, void(SpdyStreamId, const std::string&));
52 // SaveArg cannot be used on non-copyable types like SpdyHeaderBlock.
53 void OnHeaders(SpdyStreamId stream_id,
54 bool has_priority,
55 int weight,
56 SpdyStreamId parent_stream_id,
57 bool exclusive,
58 bool fin,
59 const SpdyHeaderBlock& headers) override {
60 actual_header_block_ = headers.Clone();
61 OnHeadersMock(stream_id, has_priority, weight, parent_stream_id, exclusive,
62 fin, headers);
63 }
64 MOCK_METHOD7(OnHeadersMock,
65 void(SpdyStreamId stream_id,
66 bool has_priority,
67 int weight,
68 SpdyStreamId parent_stream_id,
69 bool exclusive,
70 bool fin,
71 const SpdyHeaderBlock& headers));
72 MOCK_METHOD3(OnDataFrameHeader, void(SpdyStreamId, size_t, bool));
73 MOCK_METHOD3(OnStreamFrameData, void(SpdyStreamId, const char*, size_t));
74 MOCK_METHOD1(OnStreamEnd, void(SpdyStreamId));
75 MOCK_METHOD2(OnStreamPadding, void(SpdyStreamId, size_t));
76 MOCK_METHOD1(OnHeaderFrameStart,
77 SpdyHeadersHandlerInterface*(SpdyStreamId stream_id));
78 MOCK_METHOD2(OnHeaderFrameEnd,
79 void(SpdyStreamId stream_id, bool end_headers));
80 MOCK_METHOD1(OnSettings, void(bool clear_persisted));
81 MOCK_METHOD3(OnSetting, void(SpdySettingsIds, uint8_t, uint32_t));
82 MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack));
83 MOCK_METHOD2(OnRstStream, void(SpdyStreamId, SpdyRstStreamStatus));
84 MOCK_METHOD3(OnGoAway, void(SpdyStreamId, SpdyGoAwayStatus, StringPiece));
85 MOCK_METHOD2(OnWindowUpdate, void(SpdyStreamId, int));
86 MOCK_METHOD3(OnPushPromise,
87 void(SpdyStreamId, SpdyStreamId, const SpdyHeaderBlock&));
88 MOCK_METHOD3(OnAltSvc,
89 void(SpdyStreamId,
90 base::StringPiece,
91 const SpdyAltSvcWireFormat::AlternativeServiceVector&));
92 MOCK_METHOD2(OnUnknownFrame, bool(SpdyStreamId stream_id, int frame_type));
93
94 SpdyHeaderBlock actual_header_block_;
95 };
96
97 class FakeSMConnection : public SMConnection {
98 public:
99 FakeSMConnection(EpollServer* epoll_server,
100 SSLState* ssl_state,
101 MemoryCache* memory_cache,
102 FlipAcceptor* acceptor,
103 std::string log_prefix)
104 : SMConnection(epoll_server,
105 ssl_state,
106 memory_cache,
107 acceptor,
108 log_prefix) {}
109
110 MOCK_METHOD0(Cleanup, void());
111 MOCK_METHOD8(InitSMConnection,
112 void(SMConnectionPoolInterface*,
113 SMInterface*,
114 EpollServer*,
115 int,
116 std::string,
117 std::string,
118 std::string,
119 bool));
120 };
121
122 // This class is almost SpdySM, except one function.
123 // This class is the test target of tests in this file.
124 class TestSpdySM : public SpdySM {
125 public:
126 virtual ~TestSpdySM() {}
127 TestSpdySM(SMConnection* connection,
128 SMInterface* sm_http_interface,
129 EpollServer* epoll_server,
130 MemoryCache* memory_cache,
131 FlipAcceptor* acceptor)
132 : SpdySM(connection,
133 sm_http_interface,
134 epoll_server,
135 memory_cache,
136 acceptor) {}
137
138 MOCK_METHOD2(FindOrMakeNewSMConnectionInterface,
139 SMInterface*(const std::string&, const std::string&));
140 };
141
142 class SpdySMTestBase : public ::testing::Test {
143 public:
144 explicit SpdySMTestBase(FlipHandlerType type) {
145 SSLState* ssl_state = NULL;
146 mock_another_interface_.reset(new MockSMInterface);
147 memory_cache_.reset(new MemoryCache);
148 acceptor_.reset(new FlipAcceptor(type,
149 "127.0.0.1",
150 "8941",
151 "ssl_cert_filename",
152 "ssl_key_filename",
153 "127.0.0.1",
154 "8942",
155 "127.0.0.1",
156 "8943",
157 1,
158 0,
159 true,
160 1,
161 false,
162 true,
163 NULL));
164 epoll_server_.reset(new EpollServer);
165 connection_.reset(new FakeSMConnection(epoll_server_.get(),
166 ssl_state,
167 memory_cache_.get(),
168 acceptor_.get(),
169 "log_prefix"));
170
171 interface_.reset(new TestSpdySM(
172 connection_.get(), mock_another_interface_.get(), epoll_server_.get(),
173 memory_cache_.get(), acceptor_.get()));
174
175 spdy_framer_.reset(new BufferedSpdyFramer());
176 spdy_framer_visitor_.reset(new SpdyFramerVisitor);
177 spdy_framer_->set_visitor(spdy_framer_visitor_.get());
178 }
179
180 ~SpdySMTestBase() override {
181 if (acceptor_->listen_fd_ >= 0) {
182 epoll_server_->UnregisterFD(acceptor_->listen_fd_);
183 close(acceptor_->listen_fd_);
184 acceptor_->listen_fd_ = -1;
185 }
186 OutputList& output_list = *connection_->output_list();
187 for (OutputList::const_iterator i = output_list.begin();
188 i != output_list.end();
189 ++i) {
190 delete *i;
191 }
192 output_list.clear();
193 }
194
195 bool HasStream(uint32_t stream_id) {
196 return interface_->output_ordering().ExistsInPriorityMaps(stream_id);
197 }
198
199 protected:
200 std::unique_ptr<MockSMInterface> mock_another_interface_;
201 std::unique_ptr<MemoryCache> memory_cache_;
202 std::unique_ptr<FlipAcceptor> acceptor_;
203 std::unique_ptr<EpollServer> epoll_server_;
204 std::unique_ptr<FakeSMConnection> connection_;
205 std::unique_ptr<TestSpdySM> interface_;
206 std::unique_ptr<BufferedSpdyFramer> spdy_framer_;
207 std::unique_ptr<SpdyFramerVisitor> spdy_framer_visitor_;
208 };
209
210 class SpdySMProxyTest : public SpdySMTestBase {
211 public:
212 SpdySMProxyTest() : SpdySMTestBase(FLIP_HANDLER_PROXY) {}
213 ~SpdySMProxyTest() override {}
214 };
215
216 class SpdySMServerTest : public SpdySMTestBase {
217 public:
218 SpdySMServerTest() : SpdySMTestBase(FLIP_HANDLER_SPDY_SERVER) {}
219 ~SpdySMServerTest() override {}
220 };
221
222 TEST_F(SpdySMProxyTest, InitSMConnection) {
223 {
224 InSequence s;
225 EXPECT_CALL(*connection_, InitSMConnection(_, _, _, _, _, _, _, _));
226 }
227 interface_->InitSMConnection(
228 NULL, NULL, epoll_server_.get(), -1, "", "", "", false);
229 }
230
231 TEST_F(SpdySMProxyTest, OnRstStream) {
232 BufferedSpdyFramerVisitorInterface* visitor = interface_.get();
233 uint32_t stream_id = 82;
234 MemCacheIter mci;
235 mci.stream_id = stream_id;
236
237 {
238 BalsaHeaders headers;
239 std::string filename = "foobar";
240 memory_cache_->InsertFile(&headers, filename, "");
241 mci.file_data = memory_cache_->GetFileData(filename);
242 }
243
244 interface_->AddToOutputOrder(mci);
245 ASSERT_TRUE(HasStream(stream_id));
246 visitor->OnRstStream(stream_id, RST_STREAM_INVALID);
247 ASSERT_FALSE(HasStream(stream_id));
248 }
249
250 TEST_F(SpdySMProxyTest, ProcessReadInput) {
251 ASSERT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME,
252 interface_->spdy_framer()->state());
253 interface_->ProcessReadInput("", 1);
254 ASSERT_EQ(SpdyFramer::SPDY_READING_COMMON_HEADER,
255 interface_->spdy_framer()->state());
256 }
257
258 TEST_F(SpdySMProxyTest, ResetForNewConnection) {
259 uint32_t stream_id = 13;
260 MemCacheIter mci;
261 mci.stream_id = stream_id;
262 // incomplete input
263 const char input[] = {'\0', '\0', '\0'};
264
265 {
266 BalsaHeaders headers;
267 std::string filename = "foobar";
268 memory_cache_->InsertFile(&headers, filename, "");
269 mci.file_data = memory_cache_->GetFileData(filename);
270 }
271
272 interface_->AddToOutputOrder(mci);
273 ASSERT_TRUE(HasStream(stream_id));
274 interface_->ProcessReadInput(input, sizeof(input));
275 ASSERT_NE(SpdyFramer::SPDY_READY_FOR_FRAME,
276 interface_->spdy_framer()->state());
277
278 interface_->ResetForNewConnection();
279 ASSERT_FALSE(HasStream(stream_id));
280 ASSERT_TRUE(interface_->spdy_framer() == NULL);
281 }
282
283 TEST_F(SpdySMProxyTest, CreateFramer) {
284 interface_->ResetForNewConnection();
285 interface_->CreateFramer();
286 ASSERT_TRUE(interface_->spdy_framer());
287 }
288
289 TEST_F(SpdySMProxyTest, PostAcceptHook) {
290 interface_->PostAcceptHook();
291
292 ASSERT_EQ(1u, connection_->output_list()->size());
293 std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
294 DataFrame* df = *i++;
295
296 {
297 InSequence s;
298 EXPECT_CALL(*spdy_framer_visitor_, OnSettings(false));
299 EXPECT_CALL(*spdy_framer_visitor_,
300 OnSetting(SETTINGS_MAX_CONCURRENT_STREAMS, 0u, 100u));
301 }
302 spdy_framer_->ProcessInput(df->data, df->size);
303 }
304
305 TEST_F(SpdySMProxyTest, NewStream) {
306 // TODO(yhirano): SpdySM::NewStream leads to crash when
307 // acceptor_->flip_handler_type_ != FLIP_HANDLER_SPDY_SERVER.
308 // It should be fixed though I don't know the solution now.
309 }
310
311 TEST_F(SpdySMProxyTest, AddToOutputOrder) {
312 uint32_t stream_id = 13;
313 MemCacheIter mci;
314 mci.stream_id = stream_id;
315
316 {
317 BalsaHeaders headers;
318 std::string filename = "foobar";
319 memory_cache_->InsertFile(&headers, filename, "");
320 mci.file_data = memory_cache_->GetFileData(filename);
321 }
322
323 interface_->AddToOutputOrder(mci);
324 ASSERT_TRUE(HasStream(stream_id));
325 }
326
327 TEST_F(SpdySMProxyTest, SendErrorNotFound) {
328 uint32_t stream_id = 82;
329 const char* actual_data;
330 size_t actual_size;
331 testing::MockFunction<void(int)> checkpoint; // NOLINT
332
333 interface_->SendErrorNotFound(stream_id);
334
335 ASSERT_EQ(2u, connection_->output_list()->size());
336
337 {
338 InSequence s;
339 EXPECT_CALL(*spdy_framer_visitor_,
340 OnHeadersMock(stream_id, /*has_priority=*/false, _, _, _,
341 /*fin=*/false, _));
342 EXPECT_CALL(checkpoint, Call(0));
343 EXPECT_CALL(*spdy_framer_visitor_,
344 OnDataFrameHeader(stream_id, _, true));
345 EXPECT_CALL(*spdy_framer_visitor_, OnStreamFrameData(stream_id, _, _))
346 .Times(1)
347 .WillOnce(DoAll(SaveArg<1>(&actual_data), SaveArg<2>(&actual_size)));
348 EXPECT_CALL(*spdy_framer_visitor_, OnStreamFrameData(stream_id, NULL, 0))
349 .Times(1);
350 }
351
352 std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
353 DataFrame* df = *i++;
354 spdy_framer_->ProcessInput(df->data, df->size);
355 checkpoint.Call(0);
356 df = *i++;
357 spdy_framer_->ProcessInput(df->data, df->size);
358
359 ASSERT_EQ(2, spdy_framer_->frames_received());
360 ASSERT_EQ(2u, spdy_framer_visitor_->actual_header_block_.size());
361 ASSERT_EQ("404 Not Found",
362 spdy_framer_visitor_->actual_header_block_[":status"]);
363 ASSERT_EQ("HTTP/1.1", spdy_framer_visitor_->actual_header_block_[":version"]);
364 ASSERT_EQ("wtf?", StringPiece(actual_data, actual_size));
365 }
366
367 TEST_F(SpdySMProxyTest, SendSynReply) {
368 uint32_t stream_id = 82;
369 BalsaHeaders headers;
370 headers.AppendHeader("key1", "value1");
371 headers.SetResponseFirstlineFromStringPieces("HTTP/1.1", "200", "OK");
372
373 interface_->SendSynReply(stream_id, headers);
374
375 ASSERT_EQ(1u, connection_->output_list()->size());
376 std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
377 DataFrame* df = *i++;
378
379 {
380 InSequence s;
381 EXPECT_CALL(*spdy_framer_visitor_,
382 OnHeadersMock(stream_id, /*has_priority=*/false, _, _, _,
383 /*fin=*/false, _));
384 }
385
386 spdy_framer_->ProcessInput(df->data, df->size);
387 ASSERT_EQ(1, spdy_framer_->frames_received());
388 ASSERT_EQ(3u, spdy_framer_visitor_->actual_header_block_.size());
389 ASSERT_EQ("200 OK", spdy_framer_visitor_->actual_header_block_[":status"]);
390 ASSERT_EQ("HTTP/1.1", spdy_framer_visitor_->actual_header_block_[":version"]);
391 ASSERT_EQ("value1", spdy_framer_visitor_->actual_header_block_["key1"]);
392 }
393
394 TEST_F(SpdySMProxyTest, SendDataFrame) {
395 uint32_t stream_id = 133;
396 SpdyDataFlags flags = DATA_FLAG_NONE;
397 const char* actual_data;
398 size_t actual_size;
399
400 interface_->SendDataFrame(stream_id, "hello", 5, flags, true);
401
402 ASSERT_EQ(1u, connection_->output_list()->size());
403 std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
404 DataFrame* df = *i++;
405
406 {
407 InSequence s;
408 EXPECT_CALL(*spdy_framer_visitor_,
409 OnDataFrameHeader(stream_id, _, false));
410 EXPECT_CALL(*spdy_framer_visitor_, OnStreamFrameData(stream_id, _, _))
411 .WillOnce(DoAll(SaveArg<1>(&actual_data), SaveArg<2>(&actual_size)));
412 }
413
414 spdy_framer_->ProcessInput(df->data, df->size);
415 ASSERT_EQ(1, spdy_framer_->frames_received());
416 ASSERT_EQ("hello", StringPiece(actual_data, actual_size));
417 }
418
419 TEST_F(SpdySMProxyTest, SendLongDataFrame) {
420 uint32_t stream_id = 133;
421 SpdyDataFlags flags = DATA_FLAG_NONE;
422 const char* actual_data;
423 size_t actual_size;
424
425 std::string data = std::string(kSpdySegmentSize, 'a') +
426 std::string(kSpdySegmentSize, 'b') + "c";
427 interface_->SendDataFrame(stream_id, data.data(), data.size(), flags, true);
428
429 {
430 InSequence s;
431 for (int i = 0; i < 3; ++i) {
432 EXPECT_CALL(*spdy_framer_visitor_,
433 OnDataFrameHeader(stream_id, _, false));
434 EXPECT_CALL(*spdy_framer_visitor_, OnStreamFrameData(stream_id, _, _))
435 .WillOnce(
436 DoAll(SaveArg<1>(&actual_data), SaveArg<2>(&actual_size)));
437 }
438 }
439
440 ASSERT_EQ(3u, connection_->output_list()->size());
441 std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
442 DataFrame* df = *i++;
443 spdy_framer_->ProcessInput(df->data, df->size);
444 ASSERT_EQ(std::string(kSpdySegmentSize, 'a'),
445 StringPiece(actual_data, actual_size));
446
447 df = *i++;
448 spdy_framer_->ProcessInput(df->data, df->size);
449 ASSERT_EQ(std::string(kSpdySegmentSize, 'b'),
450 StringPiece(actual_data, actual_size));
451
452 df = *i++;
453 spdy_framer_->ProcessInput(df->data, df->size);
454 ASSERT_EQ("c", StringPiece(actual_data, actual_size));
455 }
456
457 TEST_F(SpdySMServerTest, NewStream) {
458 uint32_t stream_id = 13;
459 std::string filename = "foobar";
460
461 {
462 BalsaHeaders headers;
463 memory_cache_->InsertFile(&headers, filename, "");
464 }
465
466 interface_->NewStream(stream_id, 0, filename);
467 ASSERT_TRUE(HasStream(stream_id));
468 }
469
470 TEST_F(SpdySMServerTest, NewStreamError) {
471 uint32_t stream_id = 82;
472 const char* actual_data;
473 size_t actual_size;
474 testing::MockFunction<void(int)> checkpoint; // NOLINT
475
476 interface_->NewStream(stream_id, 0, "nonexistingfile");
477
478 ASSERT_EQ(2u, connection_->output_list()->size());
479
480 {
481 InSequence s;
482 EXPECT_CALL(*spdy_framer_visitor_,
483 OnHeadersMock(stream_id, /*has_priority=*/false, _, _, _,
484 /*fin=*/false, _));
485 EXPECT_CALL(checkpoint, Call(0));
486 EXPECT_CALL(*spdy_framer_visitor_,
487 OnDataFrameHeader(stream_id, _, true));
488 EXPECT_CALL(*spdy_framer_visitor_, OnStreamFrameData(stream_id, _, _))
489 .Times(1)
490 .WillOnce(DoAll(SaveArg<1>(&actual_data), SaveArg<2>(&actual_size)));
491 EXPECT_CALL(*spdy_framer_visitor_, OnStreamFrameData(stream_id, NULL, 0))
492 .Times(1);
493 }
494
495 std::list<DataFrame*>::const_iterator i = connection_->output_list()->begin();
496 DataFrame* df = *i++;
497 spdy_framer_->ProcessInput(df->data, df->size);
498 checkpoint.Call(0);
499 df = *i++;
500 spdy_framer_->ProcessInput(df->data, df->size);
501
502 ASSERT_EQ(2, spdy_framer_->frames_received());
503 ASSERT_EQ(2u, spdy_framer_visitor_->actual_header_block_.size());
504 ASSERT_EQ("404 Not Found",
505 spdy_framer_visitor_->actual_header_block_["status"]);
506 ASSERT_EQ("HTTP/1.1", spdy_framer_visitor_->actual_header_block_["version"]);
507 ASSERT_EQ("wtf?", StringPiece(actual_data, actual_size));
508 }
509
510 } // namespace
511
512 } // namespace net
OLDNEW
« no previous file with comments | « net/tools/flip_server/spdy_interface.cc ('k') | net/tools/flip_server/spdy_ssl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698