OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 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 "content/browser/service_worker/service_worker_cache_writer.h" | |
6 | |
7 #include <list> | |
8 #include <queue> | |
9 #include <string> | |
10 | |
11 #include "base/stl_util.h" | |
12 #include "content/browser/service_worker/service_worker_disk_cache.h" | |
13 #include "testing/gtest/include/gtest/gtest.h" | |
14 | |
15 namespace content { | |
16 namespace { | |
17 | |
18 // A test implementation of ServiceWorkerResponseReader. | |
19 // | |
20 // This class exposes the ability to expect reads (see ExpectRead*() below). | |
21 // Each call to ReadInfo() or ReadData() consumes another expected read, in the | |
22 // order those reads were expected, so: | |
23 // reader->ExpectReadInfoOk(5, false); | |
24 // reader->ExpectReadDataOk("abcdef", false); | |
25 // reader->ExpectReadDataOk("ghijkl", false); | |
26 // Expects these calls, in this order: | |
27 // reader->ReadInfo(...); // reader writes 5 into | |
28 // // |info_buf->response_data_size| | |
29 // reader->ReadData(...); // reader writes "abcdef" into |buf| | |
30 // reader->ReadData(...); // reader writes "ghijkl" into |buf| | |
31 // If an unexpected call happens, this class DCHECKs. | |
32 // If an expected read is marked "async", it will not complete immediately, but | |
33 // must be completed by the test using CompletePendingRead(). | |
34 // These is a convenience method AllExpectedReadsDone() which returns whether | |
35 // there are any expected reads that have not yet happened. | |
falken
2015/09/01 08:06:37
Thanks for these explanatory comments!
Elly Fong-Jones
2015/09/01 13:17:48
No problem.
| |
36 class MockServiceWorkerResponseReader : public ServiceWorkerResponseReader { | |
37 public: | |
38 MockServiceWorkerResponseReader() : ServiceWorkerResponseReader(0, nullptr) {} | |
39 ~MockServiceWorkerResponseReader() override {} | |
40 | |
41 // ServiceWorkerResponseReader overrides | |
42 void ReadInfo(HttpResponseInfoIOBuffer* info_buf, | |
43 const net::CompletionCallback& callback) override; | |
44 void ReadData(net::IOBuffer* buf, | |
45 int buf_len, | |
46 const net::CompletionCallback& callback) override; | |
47 | |
48 // Test helpers. ExpectReadInfo() and ExpectReadData() give precise control | |
49 // over both the data to be written and the result to return. | |
50 // ExpectReadInfoOk() and ExpectReadDataOk() are convenience functions for | |
51 // expecting successful reads, which always have their length as their result. | |
52 | |
53 // Expect a call to ReadInfo() on this reader. For these functions, |len| will | |
54 // be used as |response_data_size|, not as the length of this particular read. | |
55 void ExpectReadInfo(size_t len, bool async, int result); | |
56 void ExpectReadInfoOk(size_t len, bool async); | |
57 | |
58 // Expect a call to ReadData() on this reader. For these functions, |len| is | |
59 // the length of the data to be written back; in ExpectReadDataOk(), |len| is | |
60 // implicitly the length of |data|. | |
61 void ExpectReadData(const char* data, size_t len, bool async, int result); | |
62 void ExpectReadDataOk(const std::string& data, bool async); | |
63 | |
64 // Complete a pending async read. It is an error to call this function without | |
65 // a pending async read (ie, a previous call to ReadInfo() or ReadData() | |
66 // having not run its callback yet). | |
67 void CompletePendingRead(); | |
68 | |
69 // Returns whether all expected reads have occurred. | |
70 bool AllExpectedReadsDone() { return expected_reads_.size() == 0; } | |
71 | |
72 private: | |
73 struct ExpectedRead { | |
74 ExpectedRead(size_t len, bool async, int result) | |
75 : data(nullptr), len(len), info(true), async(async), result(result) {} | |
76 ExpectedRead(const char* data, size_t len, bool async, int result) | |
77 : data(data), len(len), info(false), async(async), result(result) {} | |
78 const char* data; | |
79 size_t len; | |
80 bool info; | |
81 bool async; | |
82 int result; | |
83 }; | |
84 | |
85 std::queue<ExpectedRead> expected_reads_; | |
86 scoped_refptr<net::IOBuffer> pending_buffer_; | |
87 size_t pending_buffer_len_; | |
88 scoped_refptr<HttpResponseInfoIOBuffer> pending_info_; | |
89 net::CompletionCallback pending_callback_; | |
90 }; | |
91 | |
92 void MockServiceWorkerResponseReader::ReadInfo( | |
93 HttpResponseInfoIOBuffer* info_buf, | |
94 const net::CompletionCallback& callback) { | |
95 DCHECK(!expected_reads_.empty()); | |
96 ExpectedRead expected = expected_reads_.front(); | |
97 EXPECT_TRUE(expected.info); | |
98 if (expected.async) { | |
99 pending_info_ = info_buf; | |
100 pending_callback_ = callback; | |
101 } else { | |
102 expected_reads_.pop(); | |
103 info_buf->response_data_size = expected.len; | |
104 callback.Run(expected.result); | |
105 } | |
106 } | |
107 | |
108 void MockServiceWorkerResponseReader::ReadData( | |
109 net::IOBuffer* buf, | |
110 int buf_len, | |
111 const net::CompletionCallback& callback) { | |
112 DCHECK(!expected_reads_.empty()); | |
113 ExpectedRead expected = expected_reads_.front(); | |
114 EXPECT_FALSE(expected.info); | |
115 if (expected.async) { | |
116 pending_callback_ = callback; | |
117 pending_buffer_ = buf; | |
118 pending_buffer_len_ = static_cast<size_t>(buf_len); | |
119 } else { | |
120 expected_reads_.pop(); | |
121 if (expected.len > 0) { | |
122 size_t to_read = std::min(static_cast<size_t>(buf_len), expected.len); | |
123 memcpy(buf->data(), expected.data, to_read); | |
124 } | |
125 callback.Run(expected.result); | |
126 } | |
127 } | |
128 | |
129 void MockServiceWorkerResponseReader::ExpectReadInfo(size_t len, | |
130 bool async, | |
131 int result) { | |
132 expected_reads_.push(ExpectedRead(len, async, result)); | |
133 } | |
134 | |
135 void MockServiceWorkerResponseReader::ExpectReadInfoOk(size_t len, bool async) { | |
136 expected_reads_.push(ExpectedRead(len, async, len)); | |
137 } | |
138 | |
139 void MockServiceWorkerResponseReader::ExpectReadData(const char* data, | |
140 size_t len, | |
141 bool async, | |
142 int result) { | |
143 expected_reads_.push(ExpectedRead(data, len, async, result)); | |
144 } | |
145 | |
146 void MockServiceWorkerResponseReader::ExpectReadDataOk(const std::string& data, | |
147 bool async) { | |
148 expected_reads_.push( | |
149 ExpectedRead(data.data(), data.size(), async, data.size())); | |
150 } | |
151 | |
152 void MockServiceWorkerResponseReader::CompletePendingRead() { | |
153 DCHECK(!expected_reads_.empty()); | |
154 ExpectedRead expected = expected_reads_.front(); | |
155 expected_reads_.pop(); | |
156 EXPECT_TRUE(expected.async); | |
157 if (expected.info) { | |
158 pending_info_->response_data_size = expected.len; | |
159 } else { | |
160 size_t to_read = std::min(pending_buffer_len_, expected.len); | |
161 if (to_read > 0) | |
162 memcpy(pending_buffer_->data(), expected.data, to_read); | |
163 } | |
164 pending_info_ = nullptr; | |
165 pending_buffer_ = nullptr; | |
166 net::CompletionCallback callback = pending_callback_; | |
167 pending_callback_.Reset(); | |
168 callback.Run(expected.result); | |
169 } | |
170 | |
171 // A test implementation of ServiceWorkerResponseWriter. | |
172 // | |
173 // This class exposes the ability to expect writes (see ExpectWrite*Ok() below). | |
174 // Each write to this class via WriteInfo() or WriteData() consumes another | |
175 // expected write, in the order they were added, so: | |
176 // writer->ExpectWriteInfoOk(5, false); | |
177 // writer->ExpectWriteDataOk(6, false); | |
178 // writer->ExpectWriteDataOk(6, false); | |
179 // Expects these calls, in this order: | |
180 // writer->WriteInfo(...); // checks that |buf->response_data_size| == 5 | |
181 // writer->WriteData(...); // checks that 6 bytes are being written | |
182 // writer->WriteData(...); // checks that another 6 bytes are being written | |
183 // If this class receives an unexpected call to WriteInfo() or WriteData(), it | |
184 // DCHECKs. | |
185 // Expected writes marked async do not complete synchronously, but rather return | |
186 // without running their callback and need to be completed with | |
187 // CompletePendingWrite(). | |
188 // A convenience method AllExpectedWritesDone() is exposed so tests can ensure | |
189 // that all expected writes have been consumed by matching calls to WriteInfo() | |
190 // or WriteData(). | |
191 class MockServiceWorkerResponseWriter : public ServiceWorkerResponseWriter { | |
192 public: | |
193 MockServiceWorkerResponseWriter() | |
194 : ServiceWorkerResponseWriter(0, nullptr), | |
195 info_written_(0), | |
196 data_written_(0) {} | |
197 ~MockServiceWorkerResponseWriter() override {} | |
198 | |
199 // ServiceWorkerResponseWriter overrides | |
200 void WriteInfo(HttpResponseInfoIOBuffer* info_buf, | |
201 const net::CompletionCallback& callback) override; | |
202 void WriteData(net::IOBuffer* buf, | |
203 int buf_len, | |
204 const net::CompletionCallback& callback) override; | |
205 | |
206 // Enqueue expected writes. | |
207 void ExpectWriteInfoOk(size_t len, bool async); | |
208 void ExpectWriteDataOk(size_t len, bool async); | |
209 | |
210 // Complete a pending asynchronous write. This method DCHECKs unless there is | |
211 // a pending write (a write for which WriteInfo() or WriteData() has been | |
212 // called but the callback has not yet been run). | |
213 void CompletePendingWrite(); | |
214 | |
215 // Returns whether all expected reads have been consumed. | |
216 bool AllExpectedWritesDone() { return expected_writes_.size() == 0; } | |
217 | |
218 private: | |
219 struct ExpectedWrite { | |
220 ExpectedWrite(bool is_info, size_t length, bool async, int result) | |
221 : is_info(is_info), length(length), async(async), result(result) {} | |
222 bool is_info; | |
223 size_t length; | |
224 bool async; | |
225 int result; | |
226 }; | |
227 | |
228 std::queue<ExpectedWrite> expected_writes_; | |
229 | |
230 size_t info_written_; | |
231 size_t data_written_; | |
232 | |
233 net::CompletionCallback pending_callback_; | |
234 }; | |
235 | |
236 void MockServiceWorkerResponseWriter::WriteInfo( | |
237 HttpResponseInfoIOBuffer* info_buf, | |
238 const net::CompletionCallback& callback) { | |
239 DCHECK(!expected_writes_.empty()); | |
240 ExpectedWrite write = expected_writes_.front(); | |
241 EXPECT_TRUE(write.is_info); | |
242 EXPECT_EQ(write.length, static_cast<size_t>(info_buf->response_data_size)); | |
243 info_written_ += info_buf->response_data_size; | |
244 if (!write.async) { | |
245 expected_writes_.pop(); | |
246 callback.Run(write.result); | |
247 } else { | |
248 pending_callback_ = callback; | |
249 } | |
250 } | |
251 | |
252 void MockServiceWorkerResponseWriter::WriteData( | |
253 net::IOBuffer* buf, | |
254 int buf_len, | |
255 const net::CompletionCallback& callback) { | |
256 DCHECK(!expected_writes_.empty()); | |
257 ExpectedWrite write = expected_writes_.front(); | |
258 EXPECT_FALSE(write.is_info); | |
259 EXPECT_EQ(write.length, static_cast<size_t>(buf_len)); | |
260 data_written_ += buf_len; | |
261 if (!write.async) { | |
262 expected_writes_.pop(); | |
263 callback.Run(write.result); | |
264 } else { | |
265 pending_callback_ = callback; | |
266 } | |
267 } | |
268 | |
269 void MockServiceWorkerResponseWriter::ExpectWriteInfoOk(size_t length, | |
270 bool async) { | |
271 ExpectedWrite expected(true, length, async, length); | |
272 expected_writes_.push(expected); | |
273 } | |
274 | |
275 void MockServiceWorkerResponseWriter::ExpectWriteDataOk(size_t length, | |
276 bool async) { | |
277 ExpectedWrite expected(false, length, async, length); | |
278 expected_writes_.push(expected); | |
279 } | |
280 | |
281 void MockServiceWorkerResponseWriter::CompletePendingWrite() { | |
282 DCHECK(!expected_writes_.empty()); | |
283 ExpectedWrite write = expected_writes_.front(); | |
284 DCHECK(write.async); | |
285 expected_writes_.pop(); | |
286 pending_callback_.Run(write.result); | |
287 } | |
288 | |
289 class ServiceWorkerCacheWriterTest : public ::testing::Test { | |
290 public: | |
291 ServiceWorkerCacheWriterTest() | |
292 : readers_deleter_(&readers_), writers_deleter_(&writers_) {} | |
293 | |
294 void SetUp() override { | |
295 ::testing::Test::SetUp(); | |
296 cache_writer_.reset(new ServiceWorkerCacheWriter( | |
297 base::Bind(&ServiceWorkerCacheWriterTest::CreateReader, | |
298 base::Unretained(this)), | |
299 base::Bind(&ServiceWorkerCacheWriterTest::CreateWriter, | |
300 base::Unretained(this)))); | |
301 write_complete_ = false; | |
302 } | |
303 | |
304 MockServiceWorkerResponseReader* ExpectReader() { | |
305 scoped_ptr<MockServiceWorkerResponseReader> reader( | |
306 new MockServiceWorkerResponseReader); | |
307 MockServiceWorkerResponseReader* borrowed_reader = reader.get(); | |
308 readers_.push_back(reader.release()); // give ownership to |readers_| | |
309 return borrowed_reader; | |
310 } | |
311 | |
312 MockServiceWorkerResponseWriter* ExpectWriter() { | |
313 scoped_ptr<MockServiceWorkerResponseWriter> writer( | |
314 new MockServiceWorkerResponseWriter); | |
315 MockServiceWorkerResponseWriter* borrowed_writer = writer.get(); | |
316 writers_.push_back(writer.release()); // give ownership to |writers_| | |
317 return borrowed_writer; | |
318 } | |
319 | |
320 protected: | |
321 // TODO(ellyjones): when unique_ptr<> is allowed, make these instead: | |
322 // std::list<unique_ptr<...>> | |
323 // Right now, these cannot use scoped_ptr. | |
324 // Their elements are deleted by the STLElementDeleters below when this object | |
325 // goes out of scope. | |
326 std::list<MockServiceWorkerResponseReader*> readers_; | |
327 std::list<MockServiceWorkerResponseWriter*> writers_; | |
328 STLElementDeleter<std::list<MockServiceWorkerResponseReader*>> | |
329 readers_deleter_; | |
330 STLElementDeleter<std::list<MockServiceWorkerResponseWriter*>> | |
331 writers_deleter_; | |
332 scoped_ptr<ServiceWorkerCacheWriter> cache_writer_; | |
333 bool write_complete_; | |
334 net::Error last_error_; | |
335 | |
336 scoped_ptr<ServiceWorkerResponseReader> CreateReader() { | |
337 if (readers_.empty()) | |
338 return make_scoped_ptr<ServiceWorkerResponseReader>(nullptr); | |
339 scoped_ptr<ServiceWorkerResponseReader> reader(readers_.front()); | |
340 readers_.pop_front(); | |
341 return reader.Pass(); | |
342 } | |
343 scoped_ptr<ServiceWorkerResponseWriter> CreateWriter() { | |
344 if (writers_.empty()) | |
345 return make_scoped_ptr<ServiceWorkerResponseWriter>(nullptr); | |
346 scoped_ptr<ServiceWorkerResponseWriter> writer(writers_.front()); | |
347 writers_.pop_front(); | |
348 return writer.Pass(); | |
349 } | |
350 | |
351 ServiceWorkerCacheWriter::OnWriteCompleteCallback CreateWriteCallback() { | |
352 return base::Bind(&ServiceWorkerCacheWriterTest::OnWriteComplete, | |
353 base::Unretained(this)); | |
354 } | |
355 | |
356 void OnWriteComplete(net::Error error) { | |
357 write_complete_ = true; | |
358 last_error_ = error; | |
359 } | |
360 | |
361 net::Error WriteHeaders(size_t len) { | |
362 scoped_refptr<HttpResponseInfoIOBuffer> buf(new HttpResponseInfoIOBuffer); | |
363 buf->response_data_size = len; | |
364 return cache_writer_->MaybeWriteHeaders(buf.get(), CreateWriteCallback()); | |
365 } | |
366 | |
367 net::Error WriteData(const std::string& data) { | |
368 scoped_refptr<net::IOBuffer> buf = new net::StringIOBuffer(data); | |
369 return cache_writer_->MaybeWriteData(buf.get(), data.size(), | |
370 CreateWriteCallback()); | |
371 } | |
372 }; | |
373 | |
374 // Passthrough tests: | |
375 // In these tests, the ServiceWorkerCacheWriter under test has no existing | |
376 // reader, since no calls to ExpectReader() have been made; this means that | |
377 // there is no existing cached response and the incoming data is written back to | |
378 // the cache directly. | |
379 | |
380 TEST_F(ServiceWorkerCacheWriterTest, PassthroughHeadersSync) { | |
381 const size_t kHeaderSize = 16; | |
382 MockServiceWorkerResponseWriter* writer = ExpectWriter(); | |
383 writer->ExpectWriteInfoOk(kHeaderSize, false); | |
384 | |
385 net::Error error = WriteHeaders(kHeaderSize); | |
386 EXPECT_EQ(net::OK, error); | |
387 EXPECT_FALSE(write_complete_); | |
388 EXPECT_TRUE(writer->AllExpectedWritesDone()); | |
389 EXPECT_EQ(0U, cache_writer_->BytesWritten()); | |
390 } | |
391 | |
392 TEST_F(ServiceWorkerCacheWriterTest, PassthroughHeadersAsync) { | |
393 size_t kHeaderSize = 16; | |
394 MockServiceWorkerResponseWriter* writer = ExpectWriter(); | |
395 writer->ExpectWriteInfoOk(kHeaderSize, true); | |
396 | |
397 net::Error error = WriteHeaders(kHeaderSize); | |
398 EXPECT_EQ(net::ERR_IO_PENDING, error); | |
399 EXPECT_FALSE(write_complete_); | |
400 writer->CompletePendingWrite(); | |
401 EXPECT_TRUE(write_complete_); | |
402 EXPECT_TRUE(writer->AllExpectedWritesDone()); | |
403 EXPECT_EQ(0U, cache_writer_->BytesWritten()); | |
404 } | |
405 | |
406 TEST_F(ServiceWorkerCacheWriterTest, PassthroughDataSync) { | |
407 const std::string data1 = "abcdef"; | |
408 const std::string data2 = "ghijklmno"; | |
409 size_t response_size = data1.size() + data2.size(); | |
410 | |
411 MockServiceWorkerResponseWriter* writer = ExpectWriter(); | |
412 writer->ExpectWriteInfoOk(response_size, false); | |
413 writer->ExpectWriteDataOk(data1.size(), false); | |
414 writer->ExpectWriteDataOk(data2.size(), false); | |
415 | |
416 net::Error error = WriteHeaders(response_size); | |
417 EXPECT_EQ(net::OK, error); | |
418 | |
419 error = WriteData(data1); | |
420 EXPECT_EQ(net::OK, error); | |
421 | |
422 error = WriteData(data2); | |
423 EXPECT_EQ(net::OK, error); | |
424 EXPECT_TRUE(writer->AllExpectedWritesDone()); | |
425 } | |
426 | |
427 TEST_F(ServiceWorkerCacheWriterTest, PassthroughDataAsync) { | |
428 const std::string data1 = "abcdef"; | |
429 const std::string data2 = "ghijklmno"; | |
430 size_t response_size = data1.size() + data2.size(); | |
431 | |
432 MockServiceWorkerResponseWriter* writer = ExpectWriter(); | |
433 writer->ExpectWriteInfoOk(response_size, false); | |
434 writer->ExpectWriteDataOk(data1.size(), true); | |
435 writer->ExpectWriteDataOk(data2.size(), true); | |
436 | |
437 net::Error error = WriteHeaders(response_size); | |
438 EXPECT_EQ(net::OK, error); | |
439 | |
440 error = WriteData(data1); | |
441 EXPECT_EQ(net::ERR_IO_PENDING, error); | |
442 writer->CompletePendingWrite(); | |
443 EXPECT_TRUE(write_complete_); | |
444 | |
445 write_complete_ = false; | |
446 error = WriteData(data2); | |
447 EXPECT_EQ(net::ERR_IO_PENDING, error); | |
448 writer->CompletePendingWrite(); | |
449 EXPECT_TRUE(write_complete_); | |
450 EXPECT_TRUE(writer->AllExpectedWritesDone()); | |
451 } | |
452 | |
453 // Comparison tests: | |
454 // For the Compare* tests below, the ServiceWorkerCacheWriter under test has a | |
455 // reader for an existing cached response, so it will compare the response being | |
456 // written to it against the existing cached response. | |
457 | |
458 TEST_F(ServiceWorkerCacheWriterTest, CompareHeadersSync) { | |
459 size_t response_size = 3; | |
460 MockServiceWorkerResponseWriter* writer = ExpectWriter(); | |
461 MockServiceWorkerResponseReader* reader = ExpectReader(); | |
462 | |
463 reader->ExpectReadInfoOk(response_size, false); | |
464 | |
465 net::Error error = WriteHeaders(response_size); | |
466 EXPECT_EQ(net::OK, error); | |
467 EXPECT_TRUE(writer->AllExpectedWritesDone()); | |
468 EXPECT_TRUE(reader->AllExpectedReadsDone()); | |
469 } | |
470 | |
471 TEST_F(ServiceWorkerCacheWriterTest, CompareDataOkSync) { | |
472 const std::string data1 = "abcdef"; | |
473 size_t response_size = data1.size(); | |
474 | |
475 MockServiceWorkerResponseWriter* writer = ExpectWriter(); | |
476 MockServiceWorkerResponseReader* reader = ExpectReader(); | |
477 | |
478 reader->ExpectReadInfoOk(response_size, false); | |
479 reader->ExpectReadDataOk(data1, false); | |
480 | |
481 net::Error error = WriteHeaders(response_size); | |
482 EXPECT_EQ(net::OK, error); | |
483 | |
484 error = WriteData(data1); | |
485 EXPECT_EQ(net::OK, error); | |
486 | |
487 EXPECT_TRUE(writer->AllExpectedWritesDone()); | |
488 EXPECT_TRUE(reader->AllExpectedReadsDone()); | |
489 EXPECT_EQ(0U, cache_writer_->BytesWritten()); | |
490 } | |
491 | |
492 TEST_F(ServiceWorkerCacheWriterTest, CompareShortCacheReads) { | |
493 const size_t kHeaderSize = 16; | |
494 const std::string& data1 = "abcdef"; | |
495 const std::string& cache_data2 = "ghi"; | |
496 const std::string& cache_data3 = "j"; | |
497 const std::string& cache_data4 = "kl"; | |
498 const std::string& net_data2 = "ghijkl"; | |
499 const std::string& data5 = "mnopqrst"; | |
500 | |
501 MockServiceWorkerResponseReader* reader = ExpectReader(); | |
502 reader->ExpectReadInfo(kHeaderSize, false, kHeaderSize); | |
503 reader->ExpectReadDataOk(data1, false); | |
504 reader->ExpectReadDataOk(cache_data2, false); | |
505 reader->ExpectReadDataOk(cache_data3, false); | |
506 reader->ExpectReadDataOk(cache_data4, false); | |
507 reader->ExpectReadDataOk(data5, false); | |
508 | |
509 net::Error error = WriteHeaders(kHeaderSize); | |
510 EXPECT_EQ(net::OK, error); | |
511 error = WriteData(data1); | |
512 EXPECT_EQ(net::OK, error); | |
513 error = WriteData(net_data2); | |
514 EXPECT_EQ(net::OK, error); | |
515 error = WriteData(data5); | |
516 EXPECT_EQ(net::OK, error); | |
falken
2015/09/01 08:06:37
should this also test AllExpectedDone() and BytesW
Elly Fong-Jones
2015/09/01 13:17:48
Done.
| |
517 } | |
518 | |
519 TEST_F(ServiceWorkerCacheWriterTest, CompareDataOkAsync) { | |
520 const std::string data1 = "abcdef"; | |
521 size_t response_size = data1.size(); | |
522 | |
523 MockServiceWorkerResponseWriter* writer = ExpectWriter(); | |
524 MockServiceWorkerResponseReader* reader = ExpectReader(); | |
525 | |
526 reader->ExpectReadInfoOk(response_size, true); | |
527 reader->ExpectReadDataOk(data1, true); | |
528 | |
529 net::Error error = WriteHeaders(response_size); | |
530 EXPECT_EQ(net::ERR_IO_PENDING, error); | |
531 reader->CompletePendingRead(); | |
532 | |
533 error = WriteData(data1); | |
534 EXPECT_EQ(net::ERR_IO_PENDING, error); | |
535 reader->CompletePendingRead(); | |
536 | |
537 EXPECT_TRUE(writer->AllExpectedWritesDone()); | |
538 EXPECT_TRUE(reader->AllExpectedReadsDone()); | |
539 } | |
540 | |
541 TEST_F(ServiceWorkerCacheWriterTest, CompareDataManyOkAsync) { | |
542 const std::string expected_data[] = { | |
543 "abcdef", "ghijkl", "mnopqr", "stuvwxyz", | |
544 }; | |
545 size_t response_size = 0; | |
546 for (size_t i = 0; i < arraysize(expected_data); ++i) | |
547 response_size += expected_data[i].size(); | |
548 | |
549 MockServiceWorkerResponseWriter* writer = ExpectWriter(); | |
550 MockServiceWorkerResponseReader* reader = ExpectReader(); | |
551 | |
552 reader->ExpectReadInfoOk(response_size, true); | |
553 for (size_t i = 0; i < arraysize(expected_data); ++i) { | |
554 reader->ExpectReadDataOk(expected_data[i], true); | |
555 } | |
556 | |
557 net::Error error = WriteHeaders(response_size); | |
558 EXPECT_EQ(net::ERR_IO_PENDING, error); | |
559 reader->CompletePendingRead(); | |
560 | |
561 for (size_t i = 0; i < arraysize(expected_data); ++i) { | |
562 error = WriteData(expected_data[i]); | |
563 EXPECT_EQ(net::ERR_IO_PENDING, error); | |
564 reader->CompletePendingRead(); | |
565 EXPECT_EQ(net::OK, last_error_); | |
566 } | |
567 | |
568 EXPECT_TRUE(writer->AllExpectedWritesDone()); | |
569 EXPECT_TRUE(reader->AllExpectedReadsDone()); | |
570 } | |
571 | |
572 // This test writes headers and three data blocks data1, data2, data3; data2 | |
573 // differs in the cached version. The writer should be asked to rewrite the | |
574 // headers and body with the new value, and the copy reader should be asked to | |
575 // read the header and data1. | |
576 TEST_F(ServiceWorkerCacheWriterTest, CompareFailedCopySync) { | |
577 std::string data1 = "abcdef"; | |
578 std::string cache_data2 = "ghijkl"; | |
579 std::string net_data2 = "mnopqr"; | |
580 std::string data3 = "stuvwxyz"; | |
581 size_t cache_response_size = data1.size() + cache_data2.size() + data3.size(); | |
582 size_t net_response_size = data1.size() + net_data2.size() + data3.size(); | |
583 | |
584 MockServiceWorkerResponseWriter* writer = ExpectWriter(); | |
585 MockServiceWorkerResponseReader* compare_reader = ExpectReader(); | |
586 MockServiceWorkerResponseReader* copy_reader = ExpectReader(); | |
587 | |
588 compare_reader->ExpectReadInfoOk(cache_response_size, false); | |
589 compare_reader->ExpectReadDataOk(data1, false); | |
590 compare_reader->ExpectReadDataOk(cache_data2, false); | |
591 | |
592 copy_reader->ExpectReadInfoOk(cache_response_size, false); | |
593 copy_reader->ExpectReadDataOk(data1, false); | |
594 | |
595 writer->ExpectWriteInfoOk(net_response_size, false); | |
596 writer->ExpectWriteDataOk(data1.size(), false); | |
597 writer->ExpectWriteDataOk(net_data2.size(), false); | |
598 writer->ExpectWriteDataOk(data3.size(), false); | |
599 | |
600 net::Error error = WriteHeaders(net_response_size); | |
601 EXPECT_EQ(net::OK, error); | |
602 error = WriteData(data1); | |
603 EXPECT_EQ(net::OK, error); | |
604 error = WriteData(net_data2); | |
605 EXPECT_EQ(net::OK, error); | |
606 error = WriteData(data3); | |
607 EXPECT_EQ(net::OK, error); | |
608 } | |
609 | |
610 // Tests behavior when the cached data is shorter than the network data. | |
611 TEST_F(ServiceWorkerCacheWriterTest, CompareFailedCopyShort) { | |
612 std::string data1 = "abcdef"; | |
613 std::string cache_data2 = "mnop"; | |
614 std::string net_data2 = "mnopqr"; | |
615 std::string data3 = "stuvwxyz"; | |
616 size_t cache_response_size = data1.size() + cache_data2.size() + data3.size(); | |
617 size_t net_response_size = data1.size() + net_data2.size() + data3.size(); | |
618 | |
619 MockServiceWorkerResponseWriter* writer = ExpectWriter(); | |
620 MockServiceWorkerResponseReader* compare_reader = ExpectReader(); | |
621 MockServiceWorkerResponseReader* copy_reader = ExpectReader(); | |
622 | |
623 compare_reader->ExpectReadInfoOk(cache_response_size, false); | |
624 compare_reader->ExpectReadDataOk(data1, false); | |
625 compare_reader->ExpectReadDataOk(cache_data2, false); | |
626 compare_reader->ExpectReadDataOk("", false); // EOF read | |
627 | |
628 copy_reader->ExpectReadInfoOk(cache_response_size, false); | |
629 copy_reader->ExpectReadDataOk(data1, false); | |
630 | |
631 writer->ExpectWriteInfoOk(net_response_size, false); | |
632 writer->ExpectWriteDataOk(data1.size(), false); | |
633 writer->ExpectWriteDataOk(net_data2.size(), false); | |
634 writer->ExpectWriteDataOk(data3.size(), false); | |
635 | |
636 net::Error error = WriteHeaders(net_response_size); | |
637 EXPECT_EQ(net::OK, error); | |
638 error = WriteData(data1); | |
639 EXPECT_EQ(net::OK, error); | |
640 error = WriteData(net_data2); | |
641 EXPECT_EQ(net::OK, error); | |
642 error = WriteData(data3); | |
643 EXPECT_EQ(net::OK, error); | |
644 } | |
645 | |
646 // Tests behavior when the cached data is longer than the network data. | |
647 TEST_F(ServiceWorkerCacheWriterTest, CompareFailedCopyLong) { | |
648 std::string data1 = "abcdef"; | |
649 std::string cache_data2 = "mnop"; | |
650 std::string net_data2 = "mnop"; | |
651 std::string cache_data3 = "qr"; | |
652 size_t cached_size = data1.size() + cache_data2.size() + cache_data3.size(); | |
653 size_t net_size = data1.size() + net_data2.size(); | |
654 | |
655 MockServiceWorkerResponseWriter* writer = ExpectWriter(); | |
656 MockServiceWorkerResponseReader* compare_reader = ExpectReader(); | |
657 MockServiceWorkerResponseReader* copy_reader = ExpectReader(); | |
658 | |
659 compare_reader->ExpectReadInfoOk(cached_size, false); | |
660 compare_reader->ExpectReadDataOk(data1, false); | |
661 compare_reader->ExpectReadDataOk(cache_data2, false); | |
662 | |
663 copy_reader->ExpectReadInfoOk(cached_size, false); | |
664 copy_reader->ExpectReadDataOk(data1, false); | |
665 copy_reader->ExpectReadDataOk(cache_data2, false); | |
666 | |
667 writer->ExpectWriteInfoOk(net_size, false); | |
668 writer->ExpectWriteDataOk(data1.size(), false); | |
669 writer->ExpectWriteDataOk(net_data2.size(), false); | |
670 | |
671 net::Error error = WriteHeaders(net_size); | |
672 EXPECT_EQ(net::OK, error); | |
673 error = WriteData(data1); | |
674 EXPECT_EQ(net::OK, error); | |
675 error = WriteData(net_data2); | |
676 EXPECT_EQ(net::OK, error); | |
677 } | |
678 | |
679 } // namespace | |
680 } // namespace content | |
OLD | NEW |