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

Side by Side Diff: content/browser/service_worker/service_worker_cache_unittest.cc

Issue 1039763002: Cache Storage: Move files to content/*/cache_storage, rename classes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: GN fix Created 5 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 2014 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.h"
6
7 #include "base/files/file_path.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/message_loop/message_loop_proxy.h"
10 #include "base/run_loop.h"
11 #include "content/browser/fileapi/chrome_blob_storage_context.h"
12 #include "content/browser/fileapi/mock_url_request_delegate.h"
13 #include "content/browser/quota/mock_quota_manager_proxy.h"
14 #include "content/common/service_worker/service_worker_types.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/common/referrer.h"
17 #include "content/public/test/test_browser_context.h"
18 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "net/url_request/url_request_context.h"
20 #include "net/url_request/url_request_context_getter.h"
21 #include "net/url_request/url_request_job_factory_impl.h"
22 #include "storage/browser/blob/blob_data_builder.h"
23 #include "storage/browser/blob/blob_data_handle.h"
24 #include "storage/browser/blob/blob_data_snapshot.h"
25 #include "storage/browser/blob/blob_storage_context.h"
26 #include "storage/browser/blob/blob_url_request_job_factory.h"
27 #include "storage/browser/quota/quota_manager_proxy.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29
30 namespace content {
31
32 namespace {
33 const char kTestData[] = "Hello World";
34
35 // Returns a BlobProtocolHandler that uses |blob_storage_context|. Caller owns
36 // the memory.
37 storage::BlobProtocolHandler* CreateMockBlobProtocolHandler(
38 storage::BlobStorageContext* blob_storage_context) {
39 // The FileSystemContext and MessageLoopProxy are not actually used but a
40 // MessageLoopProxy is needed to avoid a DCHECK in BlobURLRequestJob ctor.
41 return new storage::BlobProtocolHandler(
42 blob_storage_context, NULL, base::MessageLoopProxy::current().get());
43 }
44
45 // A disk_cache::Backend wrapper that can delay operations.
46 class DelayableBackend : public disk_cache::Backend {
47 public:
48 DelayableBackend(scoped_ptr<disk_cache::Backend> backend)
49 : backend_(backend.Pass()), delay_open_(false) {}
50
51 // disk_cache::Backend overrides
52 net::CacheType GetCacheType() const override {
53 return backend_->GetCacheType();
54 }
55 int32 GetEntryCount() const override { return backend_->GetEntryCount(); }
56 int OpenEntry(const std::string& key,
57 disk_cache::Entry** entry,
58 const CompletionCallback& callback) override {
59 if (delay_open_) {
60 open_entry_callback_ =
61 base::Bind(&DelayableBackend::OpenEntryDelayedImpl,
62 base::Unretained(this), key, entry, callback);
63 return net::ERR_IO_PENDING;
64 }
65
66 return backend_->OpenEntry(key, entry, callback);
67 }
68 int CreateEntry(const std::string& key,
69 disk_cache::Entry** entry,
70 const CompletionCallback& callback) override {
71 return backend_->CreateEntry(key, entry, callback);
72 }
73 int DoomEntry(const std::string& key,
74 const CompletionCallback& callback) override {
75 return backend_->DoomEntry(key, callback);
76 }
77 int DoomAllEntries(const CompletionCallback& callback) override {
78 return backend_->DoomAllEntries(callback);
79 }
80 int DoomEntriesBetween(base::Time initial_time,
81 base::Time end_time,
82 const CompletionCallback& callback) override {
83 return backend_->DoomEntriesBetween(initial_time, end_time, callback);
84 }
85 int DoomEntriesSince(base::Time initial_time,
86 const CompletionCallback& callback) override {
87 return backend_->DoomEntriesSince(initial_time, callback);
88 }
89 scoped_ptr<Iterator> CreateIterator() override {
90 return backend_->CreateIterator();
91 }
92 void GetStats(
93 std::vector<std::pair<std::string, std::string>>* stats) override {
94 return backend_->GetStats(stats);
95 }
96 void OnExternalCacheHit(const std::string& key) override {
97 return backend_->OnExternalCacheHit(key);
98 }
99
100 // Call to continue a delayed open.
101 void OpenEntryContinue() {
102 EXPECT_FALSE(open_entry_callback_.is_null());
103 open_entry_callback_.Run();
104 }
105
106 void set_delay_open(bool value) { delay_open_ = value; }
107
108 private:
109 void OpenEntryDelayedImpl(const std::string& key,
110 disk_cache::Entry** entry,
111 const CompletionCallback& callback) {
112 int rv = backend_->OpenEntry(key, entry, callback);
113 if (rv != net::ERR_IO_PENDING)
114 callback.Run(rv);
115 }
116
117 scoped_ptr<disk_cache::Backend> backend_;
118 bool delay_open_;
119 base::Closure open_entry_callback_;
120 };
121
122 } // namespace
123
124 // A ServiceWorkerCache that can optionally delay during backend creation.
125 class TestServiceWorkerCache : public ServiceWorkerCache {
126 public:
127 TestServiceWorkerCache(
128 const GURL& origin,
129 const base::FilePath& path,
130 net::URLRequestContext* request_context,
131 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy,
132 base::WeakPtr<storage::BlobStorageContext> blob_context)
133 : ServiceWorkerCache(origin,
134 path,
135 request_context,
136 quota_manager_proxy,
137 blob_context),
138 delay_backend_creation_(false) {}
139
140 void CreateBackend(const ErrorCallback& callback) override {
141 backend_creation_callback_ = callback;
142 if (delay_backend_creation_)
143 return;
144 ContinueCreateBackend();
145 }
146
147 void ContinueCreateBackend() {
148 ServiceWorkerCache::CreateBackend(backend_creation_callback_);
149 }
150
151 void set_delay_backend_creation(bool delay) {
152 delay_backend_creation_ = delay;
153 }
154
155 // Swap the existing backend with a delayable one. The backend must have been
156 // created before calling this.
157 DelayableBackend* UseDelayableBackend() {
158 EXPECT_TRUE(backend_);
159 DelayableBackend* delayable_backend = new DelayableBackend(backend_.Pass());
160 backend_.reset(delayable_backend);
161 return delayable_backend;
162 }
163
164 private:
165 ~TestServiceWorkerCache() override {}
166
167 bool delay_backend_creation_;
168 ErrorCallback backend_creation_callback_;
169
170 DISALLOW_COPY_AND_ASSIGN(TestServiceWorkerCache);
171 };
172
173 class ServiceWorkerCacheTest : public testing::Test {
174 public:
175 ServiceWorkerCacheTest()
176 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
177 callback_error_(ServiceWorkerCache::ERROR_TYPE_OK),
178 callback_closed_(false) {}
179
180 void SetUp() override {
181 ChromeBlobStorageContext* blob_storage_context =
182 ChromeBlobStorageContext::GetFor(&browser_context_);
183 // Wait for chrome_blob_storage_context to finish initializing.
184 base::RunLoop().RunUntilIdle();
185 blob_storage_context_ = blob_storage_context->context();
186
187 quota_manager_proxy_ = new MockQuotaManagerProxy(
188 nullptr, base::MessageLoopProxy::current().get());
189
190 url_request_job_factory_.reset(new net::URLRequestJobFactoryImpl);
191 url_request_job_factory_->SetProtocolHandler(
192 "blob", CreateMockBlobProtocolHandler(blob_storage_context->context()));
193
194 net::URLRequestContext* url_request_context =
195 browser_context_.GetRequestContext()->GetURLRequestContext();
196
197 url_request_context->set_job_factory(url_request_job_factory_.get());
198
199 CreateRequests(blob_storage_context);
200
201 if (!MemoryOnly())
202 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
203 base::FilePath path = MemoryOnly() ? base::FilePath() : temp_dir_.path();
204
205 cache_ = make_scoped_refptr(new TestServiceWorkerCache(
206 GURL("http://example.com"), path, url_request_context,
207 quota_manager_proxy_, blob_storage_context->context()->AsWeakPtr()));
208 }
209
210 void TearDown() override {
211 quota_manager_proxy_->SimulateQuotaManagerDestroyed();
212 base::RunLoop().RunUntilIdle();
213 }
214
215 void CreateRequests(ChromeBlobStorageContext* blob_storage_context) {
216 ServiceWorkerHeaderMap headers;
217 headers.insert(std::make_pair("a", "a"));
218 headers.insert(std::make_pair("b", "b"));
219 body_request_ =
220 ServiceWorkerFetchRequest(GURL("http://example.com/body.html"), "GET",
221 headers, Referrer(), false);
222 no_body_request_ =
223 ServiceWorkerFetchRequest(GURL("http://example.com/no_body.html"),
224 "GET",
225 headers,
226 Referrer(),
227 false);
228
229 std::string expected_response;
230 for (int i = 0; i < 100; ++i)
231 expected_blob_data_ += kTestData;
232
233 scoped_ptr<storage::BlobDataBuilder> blob_data(
234 new storage::BlobDataBuilder("blob-id:myblob"));
235 blob_data->AppendData(expected_blob_data_);
236
237 blob_handle_ =
238 blob_storage_context->context()->AddFinishedBlob(blob_data.get());
239
240 body_response_ =
241 ServiceWorkerResponse(GURL("http://example.com/body.html"),
242 200,
243 "OK",
244 blink::WebServiceWorkerResponseTypeDefault,
245 headers,
246 blob_handle_->uuid(),
247 expected_blob_data_.size(),
248 GURL());
249
250 no_body_response_ =
251 ServiceWorkerResponse(GURL("http://example.com/no_body.html"),
252 200,
253 "OK",
254 blink::WebServiceWorkerResponseTypeDefault,
255 headers,
256 "",
257 0,
258 GURL());
259 }
260
261 scoped_ptr<ServiceWorkerFetchRequest> CopyFetchRequest(
262 const ServiceWorkerFetchRequest& request) {
263 return make_scoped_ptr(new ServiceWorkerFetchRequest(request.url,
264 request.method,
265 request.headers,
266 request.referrer,
267 request.is_reload));
268 }
269
270 scoped_ptr<ServiceWorkerResponse> CopyFetchResponse(
271 const ServiceWorkerResponse& response) {
272 scoped_ptr<ServiceWorkerResponse> sw_response(
273 new ServiceWorkerResponse(response.url,
274 response.status_code,
275 response.status_text,
276 response.response_type,
277 response.headers,
278 response.blob_uuid,
279 response.blob_size,
280 response.stream_url));
281 return sw_response.Pass();
282 }
283
284 bool Put(const ServiceWorkerFetchRequest& request,
285 const ServiceWorkerResponse& response) {
286 scoped_ptr<base::RunLoop> loop(new base::RunLoop());
287
288 cache_->Put(CopyFetchRequest(request),
289 CopyFetchResponse(response),
290 base::Bind(&ServiceWorkerCacheTest::ResponseAndErrorCallback,
291 base::Unretained(this),
292 base::Unretained(loop.get())));
293 // TODO(jkarlin): These functions should use base::RunLoop().RunUntilIdle()
294 // once the cache uses a passed in MessageLoopProxy instead of the CACHE
295 // thread.
296 loop->Run();
297
298 return callback_error_ == ServiceWorkerCache::ERROR_TYPE_OK;
299 }
300
301 bool Match(const ServiceWorkerFetchRequest& request) {
302 scoped_ptr<base::RunLoop> loop(new base::RunLoop());
303
304 cache_->Match(CopyFetchRequest(request),
305 base::Bind(&ServiceWorkerCacheTest::ResponseAndErrorCallback,
306 base::Unretained(this),
307 base::Unretained(loop.get())));
308 loop->Run();
309
310 return callback_error_ == ServiceWorkerCache::ERROR_TYPE_OK;
311 }
312
313 bool Delete(const ServiceWorkerFetchRequest& request) {
314 scoped_ptr<base::RunLoop> loop(new base::RunLoop());
315
316 cache_->Delete(CopyFetchRequest(request),
317 base::Bind(&ServiceWorkerCacheTest::ErrorTypeCallback,
318 base::Unretained(this),
319 base::Unretained(loop.get())));
320 loop->Run();
321
322 return callback_error_ == ServiceWorkerCache::ERROR_TYPE_OK;
323 }
324
325 bool Keys() {
326 scoped_ptr<base::RunLoop> loop(new base::RunLoop());
327
328 cache_->Keys(base::Bind(&ServiceWorkerCacheTest::RequestsCallback,
329 base::Unretained(this),
330 base::Unretained(loop.get())));
331 loop->Run();
332
333 return callback_error_ == ServiceWorkerCache::ERROR_TYPE_OK;
334 }
335
336 bool Close() {
337 scoped_ptr<base::RunLoop> loop(new base::RunLoop());
338
339 cache_->Close(base::Bind(&ServiceWorkerCacheTest::CloseCallback,
340 base::Unretained(this),
341 base::Unretained(loop.get())));
342 loop->Run();
343 return callback_closed_;
344 }
345
346 void RequestsCallback(base::RunLoop* run_loop,
347 ServiceWorkerCache::ErrorType error,
348 scoped_ptr<ServiceWorkerCache::Requests> requests) {
349 callback_error_ = error;
350 callback_strings_.clear();
351 if (requests) {
352 for (size_t i = 0u; i < requests->size(); ++i)
353 callback_strings_.push_back(requests->at(i).url.spec());
354 }
355 if (run_loop)
356 run_loop->Quit();
357 }
358
359 void ErrorTypeCallback(base::RunLoop* run_loop,
360 ServiceWorkerCache::ErrorType error) {
361 callback_error_ = error;
362 if (run_loop)
363 run_loop->Quit();
364 }
365
366 void ResponseAndErrorCallback(
367 base::RunLoop* run_loop,
368 ServiceWorkerCache::ErrorType error,
369 scoped_ptr<ServiceWorkerResponse> response,
370 scoped_ptr<storage::BlobDataHandle> body_handle) {
371 callback_error_ = error;
372 callback_response_ = response.Pass();
373 callback_response_data_.reset();
374 if (error == ServiceWorkerCache::ERROR_TYPE_OK &&
375 !callback_response_->blob_uuid.empty()) {
376 callback_response_data_ = body_handle.Pass();
377 }
378
379 if (run_loop)
380 run_loop->Quit();
381 }
382
383 void CloseCallback(base::RunLoop* run_loop) {
384 EXPECT_FALSE(callback_closed_);
385 callback_closed_ = true;
386 if (run_loop)
387 run_loop->Quit();
388 }
389
390 void CopyBody(storage::BlobDataHandle* blob_handle, std::string* output) {
391 scoped_ptr<storage::BlobDataSnapshot> data = blob_handle->CreateSnapshot();
392 const auto& items = data->items();
393 for (const auto& item : items) {
394 output->append(item->bytes(), item->length());
395 }
396 }
397
398 bool VerifyKeys(const std::vector<std::string>& expected_keys) {
399 if (expected_keys.size() != callback_strings_.size())
400 return false;
401
402 std::set<std::string> found_set;
403 for (int i = 0, max = callback_strings_.size(); i < max; ++i)
404 found_set.insert(callback_strings_[i]);
405
406 for (int i = 0, max = expected_keys.size(); i < max; ++i) {
407 if (found_set.find(expected_keys[i]) == found_set.end())
408 return false;
409 }
410 return true;
411 }
412
413 bool TestResponseType(blink::WebServiceWorkerResponseType response_type) {
414 body_response_.response_type = response_type;
415 EXPECT_TRUE(Put(body_request_, body_response_));
416 EXPECT_TRUE(Match(body_request_));
417 EXPECT_TRUE(Delete(body_request_));
418 return response_type == callback_response_->response_type;
419 }
420
421 void VerifyAllOpsFail() {
422 EXPECT_FALSE(Put(no_body_request_, no_body_response_));
423 EXPECT_FALSE(Match(no_body_request_));
424 EXPECT_FALSE(Delete(body_request_));
425 EXPECT_FALSE(Keys());
426 }
427
428 virtual bool MemoryOnly() { return false; }
429
430 protected:
431 TestBrowserContext browser_context_;
432 TestBrowserThreadBundle browser_thread_bundle_;
433 scoped_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_;
434 scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
435 storage::BlobStorageContext* blob_storage_context_;
436
437 base::ScopedTempDir temp_dir_;
438 scoped_refptr<TestServiceWorkerCache> cache_;
439
440 ServiceWorkerFetchRequest body_request_;
441 ServiceWorkerResponse body_response_;
442 ServiceWorkerFetchRequest no_body_request_;
443 ServiceWorkerResponse no_body_response_;
444 scoped_ptr<storage::BlobDataHandle> blob_handle_;
445 std::string expected_blob_data_;
446
447 ServiceWorkerCache::ErrorType callback_error_;
448 scoped_ptr<ServiceWorkerResponse> callback_response_;
449 scoped_ptr<storage::BlobDataHandle> callback_response_data_;
450 std::vector<std::string> callback_strings_;
451 bool callback_closed_;
452 };
453
454 class ServiceWorkerCacheTestP : public ServiceWorkerCacheTest,
455 public testing::WithParamInterface<bool> {
456 bool MemoryOnly() override { return !GetParam(); }
457 };
458
459 class ServiceWorkerCacheMemoryOnlyTest
460 : public ServiceWorkerCacheTest,
461 public testing::WithParamInterface<bool> {
462 bool MemoryOnly() override { return true; }
463 };
464
465 TEST_P(ServiceWorkerCacheTestP, PutNoBody) {
466 EXPECT_TRUE(Put(no_body_request_, no_body_response_));
467 EXPECT_TRUE(callback_response_);
468 EXPECT_STREQ(no_body_response_.url.spec().c_str(),
469 callback_response_->url.spec().c_str());
470 EXPECT_FALSE(callback_response_data_);
471 EXPECT_STREQ("", callback_response_->blob_uuid.c_str());
472 EXPECT_EQ(0u, callback_response_->blob_size);
473 }
474
475 TEST_P(ServiceWorkerCacheTestP, PutBody) {
476 EXPECT_TRUE(Put(body_request_, body_response_));
477 EXPECT_TRUE(callback_response_);
478 EXPECT_STREQ(body_response_.url.spec().c_str(),
479 callback_response_->url.spec().c_str());
480 EXPECT_TRUE(callback_response_data_);
481 EXPECT_STRNE("", callback_response_->blob_uuid.c_str());
482 EXPECT_EQ(expected_blob_data_.size(), callback_response_->blob_size);
483
484 std::string response_body;
485 CopyBody(callback_response_data_.get(), &response_body);
486 EXPECT_STREQ(expected_blob_data_.c_str(), response_body.c_str());
487 }
488
489 TEST_P(ServiceWorkerCacheTestP, ResponseURLDiffersFromRequestURL) {
490 no_body_response_.url = GURL("http://example.com/foobar");
491 EXPECT_STRNE("http://example.com/foobar",
492 no_body_request_.url.spec().c_str());
493 EXPECT_TRUE(Put(no_body_request_, no_body_response_));
494 EXPECT_TRUE(Match(no_body_request_));
495 EXPECT_STREQ("http://example.com/foobar",
496 callback_response_->url.spec().c_str());
497 }
498
499 TEST_P(ServiceWorkerCacheTestP, ResponseURLEmpty) {
500 no_body_response_.url = GURL();
501 EXPECT_STRNE("", no_body_request_.url.spec().c_str());
502 EXPECT_TRUE(Put(no_body_request_, no_body_response_));
503 EXPECT_TRUE(Match(no_body_request_));
504 EXPECT_STREQ("", callback_response_->url.spec().c_str());
505 }
506
507 TEST_F(ServiceWorkerCacheTest, PutBodyDropBlobRef) {
508 scoped_ptr<base::RunLoop> loop(new base::RunLoop());
509 cache_->Put(CopyFetchRequest(body_request_),
510 CopyFetchResponse(body_response_),
511 base::Bind(&ServiceWorkerCacheTestP::ResponseAndErrorCallback,
512 base::Unretained(this),
513 base::Unretained(loop.get())));
514 // The handle should be held by the cache now so the deref here should be
515 // okay.
516 blob_handle_.reset();
517 loop->Run();
518
519 EXPECT_EQ(ServiceWorkerCache::ERROR_TYPE_OK, callback_error_);
520 }
521
522 TEST_P(ServiceWorkerCacheTestP, PutReplace) {
523 EXPECT_TRUE(Put(body_request_, no_body_response_));
524 EXPECT_TRUE(Match(body_request_));
525 EXPECT_FALSE(callback_response_data_);
526
527 EXPECT_TRUE(Put(body_request_, body_response_));
528 EXPECT_TRUE(Match(body_request_));
529 EXPECT_TRUE(callback_response_data_);
530
531 EXPECT_TRUE(Put(body_request_, no_body_response_));
532 EXPECT_TRUE(Match(body_request_));
533 EXPECT_FALSE(callback_response_data_);
534 }
535
536 TEST_P(ServiceWorkerCacheTestP, MatchNoBody) {
537 EXPECT_TRUE(Put(no_body_request_, no_body_response_));
538 EXPECT_TRUE(Match(no_body_request_));
539 EXPECT_EQ(200, callback_response_->status_code);
540 EXPECT_STREQ("OK", callback_response_->status_text.c_str());
541 EXPECT_STREQ("http://example.com/no_body.html",
542 callback_response_->url.spec().c_str());
543 EXPECT_STREQ("", callback_response_->blob_uuid.c_str());
544 EXPECT_EQ(0u, callback_response_->blob_size);
545 }
546
547 TEST_P(ServiceWorkerCacheTestP, MatchBody) {
548 EXPECT_TRUE(Put(body_request_, body_response_));
549 EXPECT_TRUE(Match(body_request_));
550 EXPECT_EQ(200, callback_response_->status_code);
551 EXPECT_STREQ("OK", callback_response_->status_text.c_str());
552 EXPECT_STREQ("http://example.com/body.html",
553 callback_response_->url.spec().c_str());
554 EXPECT_STRNE("", callback_response_->blob_uuid.c_str());
555 EXPECT_EQ(expected_blob_data_.size(), callback_response_->blob_size);
556
557 std::string response_body;
558 CopyBody(callback_response_data_.get(), &response_body);
559 EXPECT_STREQ(expected_blob_data_.c_str(), response_body.c_str());
560 }
561
562 TEST_P(ServiceWorkerCacheTestP, Vary) {
563 body_request_.headers["vary_foo"] = "foo";
564 body_response_.headers["vary"] = "vary_foo";
565 EXPECT_TRUE(Put(body_request_, body_response_));
566 EXPECT_TRUE(Match(body_request_));
567
568 body_request_.headers["vary_foo"] = "bar";
569 EXPECT_FALSE(Match(body_request_));
570
571 body_request_.headers.erase("vary_foo");
572 EXPECT_FALSE(Match(body_request_));
573 }
574
575 TEST_P(ServiceWorkerCacheTestP, EmptyVary) {
576 body_response_.headers["vary"] = "";
577 EXPECT_TRUE(Put(body_request_, body_response_));
578 EXPECT_TRUE(Match(body_request_));
579
580 body_request_.headers["zoo"] = "zoo";
581 EXPECT_TRUE(Match(body_request_));
582 }
583
584 TEST_P(ServiceWorkerCacheTestP, NoVaryButDiffHeaders) {
585 EXPECT_TRUE(Put(body_request_, body_response_));
586 EXPECT_TRUE(Match(body_request_));
587
588 body_request_.headers["zoo"] = "zoo";
589 EXPECT_TRUE(Match(body_request_));
590 }
591
592 TEST_P(ServiceWorkerCacheTestP, VaryMultiple) {
593 body_request_.headers["vary_foo"] = "foo";
594 body_request_.headers["vary_bar"] = "bar";
595 body_response_.headers["vary"] = " vary_foo , vary_bar";
596 EXPECT_TRUE(Put(body_request_, body_response_));
597 EXPECT_TRUE(Match(body_request_));
598
599 body_request_.headers["vary_bar"] = "foo";
600 EXPECT_FALSE(Match(body_request_));
601
602 body_request_.headers.erase("vary_bar");
603 EXPECT_FALSE(Match(body_request_));
604 }
605
606 TEST_P(ServiceWorkerCacheTestP, VaryNewHeader) {
607 body_request_.headers["vary_foo"] = "foo";
608 body_response_.headers["vary"] = " vary_foo, vary_bar";
609 EXPECT_TRUE(Put(body_request_, body_response_));
610 EXPECT_TRUE(Match(body_request_));
611
612 body_request_.headers["vary_bar"] = "bar";
613 EXPECT_FALSE(Match(body_request_));
614 }
615
616 TEST_P(ServiceWorkerCacheTestP, VaryStar) {
617 body_response_.headers["vary"] = "*";
618 EXPECT_TRUE(Put(body_request_, body_response_));
619 EXPECT_FALSE(Match(body_request_));
620 }
621
622 TEST_P(ServiceWorkerCacheTestP, EmptyKeys) {
623 EXPECT_TRUE(Keys());
624 EXPECT_EQ(0u, callback_strings_.size());
625 }
626
627 TEST_P(ServiceWorkerCacheTestP, TwoKeys) {
628 EXPECT_TRUE(Put(no_body_request_, no_body_response_));
629 EXPECT_TRUE(Put(body_request_, body_response_));
630 EXPECT_TRUE(Keys());
631 EXPECT_EQ(2u, callback_strings_.size());
632 std::vector<std::string> expected_keys;
633 expected_keys.push_back(no_body_request_.url.spec());
634 expected_keys.push_back(body_request_.url.spec());
635 EXPECT_TRUE(VerifyKeys(expected_keys));
636 }
637
638 TEST_P(ServiceWorkerCacheTestP, TwoKeysThenOne) {
639 EXPECT_TRUE(Put(no_body_request_, no_body_response_));
640 EXPECT_TRUE(Put(body_request_, body_response_));
641 EXPECT_TRUE(Keys());
642 EXPECT_EQ(2u, callback_strings_.size());
643 std::vector<std::string> expected_keys;
644 expected_keys.push_back(no_body_request_.url.spec());
645 expected_keys.push_back(body_request_.url.spec());
646 EXPECT_TRUE(VerifyKeys(expected_keys));
647
648 EXPECT_TRUE(Delete(body_request_));
649 EXPECT_TRUE(Keys());
650 EXPECT_EQ(1u, callback_strings_.size());
651 std::vector<std::string> expected_key;
652 expected_key.push_back(no_body_request_.url.spec());
653 EXPECT_TRUE(VerifyKeys(expected_key));
654 }
655
656 TEST_P(ServiceWorkerCacheTestP, DeleteNoBody) {
657 EXPECT_TRUE(Put(no_body_request_, no_body_response_));
658 EXPECT_TRUE(Match(no_body_request_));
659 EXPECT_TRUE(Delete(no_body_request_));
660 EXPECT_FALSE(Match(no_body_request_));
661 EXPECT_FALSE(Delete(no_body_request_));
662 EXPECT_TRUE(Put(no_body_request_, no_body_response_));
663 EXPECT_TRUE(Match(no_body_request_));
664 EXPECT_TRUE(Delete(no_body_request_));
665 }
666
667 TEST_P(ServiceWorkerCacheTestP, DeleteBody) {
668 EXPECT_TRUE(Put(body_request_, body_response_));
669 EXPECT_TRUE(Match(body_request_));
670 EXPECT_TRUE(Delete(body_request_));
671 EXPECT_FALSE(Match(body_request_));
672 EXPECT_FALSE(Delete(body_request_));
673 EXPECT_TRUE(Put(body_request_, body_response_));
674 EXPECT_TRUE(Match(body_request_));
675 EXPECT_TRUE(Delete(body_request_));
676 }
677
678 TEST_P(ServiceWorkerCacheTestP, QuickStressNoBody) {
679 for (int i = 0; i < 100; ++i) {
680 EXPECT_FALSE(Match(no_body_request_));
681 EXPECT_TRUE(Put(no_body_request_, no_body_response_));
682 EXPECT_TRUE(Match(no_body_request_));
683 EXPECT_TRUE(Delete(no_body_request_));
684 }
685 }
686
687 TEST_P(ServiceWorkerCacheTestP, QuickStressBody) {
688 for (int i = 0; i < 100; ++i) {
689 ASSERT_FALSE(Match(body_request_));
690 ASSERT_TRUE(Put(body_request_, body_response_));
691 ASSERT_TRUE(Match(body_request_));
692 ASSERT_TRUE(Delete(body_request_));
693 }
694 }
695
696 TEST_P(ServiceWorkerCacheTestP, PutResponseType) {
697 EXPECT_TRUE(TestResponseType(blink::WebServiceWorkerResponseTypeBasic));
698 EXPECT_TRUE(TestResponseType(blink::WebServiceWorkerResponseTypeCORS));
699 EXPECT_TRUE(TestResponseType(blink::WebServiceWorkerResponseTypeDefault));
700 EXPECT_TRUE(TestResponseType(blink::WebServiceWorkerResponseTypeError));
701 EXPECT_TRUE(TestResponseType(blink::WebServiceWorkerResponseTypeOpaque));
702 }
703
704 TEST_F(ServiceWorkerCacheTest, CaselessServiceWorkerResponseHeaders) {
705 // ServiceWorkerCache depends on ServiceWorkerResponse having caseless
706 // headers so that it can quickly lookup vary headers.
707 ServiceWorkerResponse response(GURL("http://www.example.com"),
708 200,
709 "OK",
710 blink::WebServiceWorkerResponseTypeDefault,
711 ServiceWorkerHeaderMap(),
712 "",
713 0,
714 GURL());
715 response.headers["content-type"] = "foo";
716 response.headers["Content-Type"] = "bar";
717 EXPECT_EQ("bar", response.headers["content-type"]);
718 }
719
720 TEST_F(ServiceWorkerCacheTest, CaselessServiceWorkerFetchRequestHeaders) {
721 // ServiceWorkerCache depends on ServiceWorkerFetchRequest having caseless
722 // headers so that it can quickly lookup vary headers.
723 ServiceWorkerFetchRequest request(GURL("http://www.example.com"),
724 "GET",
725 ServiceWorkerHeaderMap(),
726 Referrer(),
727 false);
728 request.headers["content-type"] = "foo";
729 request.headers["Content-Type"] = "bar";
730 EXPECT_EQ("bar", request.headers["content-type"]);
731 }
732
733 TEST_P(ServiceWorkerCacheTestP, QuotaManagerModified) {
734 EXPECT_EQ(0, quota_manager_proxy_->notify_storage_modified_count());
735
736 EXPECT_TRUE(Put(no_body_request_, no_body_response_));
737 EXPECT_EQ(1, quota_manager_proxy_->notify_storage_modified_count());
738 EXPECT_LT(0, quota_manager_proxy_->last_notified_delta());
739 int64 sum_delta = quota_manager_proxy_->last_notified_delta();
740
741 EXPECT_TRUE(Put(body_request_, body_response_));
742 EXPECT_EQ(2, quota_manager_proxy_->notify_storage_modified_count());
743 EXPECT_LT(sum_delta, quota_manager_proxy_->last_notified_delta());
744 sum_delta += quota_manager_proxy_->last_notified_delta();
745
746 EXPECT_TRUE(Delete(body_request_));
747 EXPECT_EQ(3, quota_manager_proxy_->notify_storage_modified_count());
748 sum_delta += quota_manager_proxy_->last_notified_delta();
749
750 EXPECT_TRUE(Delete(no_body_request_));
751 EXPECT_EQ(4, quota_manager_proxy_->notify_storage_modified_count());
752 sum_delta += quota_manager_proxy_->last_notified_delta();
753
754 EXPECT_EQ(0, sum_delta);
755 }
756
757 TEST_F(ServiceWorkerCacheMemoryOnlyTest, MemoryBackedSize) {
758 EXPECT_EQ(0, cache_->MemoryBackedSize());
759 EXPECT_TRUE(Put(no_body_request_, no_body_response_));
760 EXPECT_LT(0, cache_->MemoryBackedSize());
761 int64 no_body_size = cache_->MemoryBackedSize();
762
763 EXPECT_TRUE(Delete(no_body_request_));
764 EXPECT_EQ(0, cache_->MemoryBackedSize());
765
766 EXPECT_TRUE(Put(body_request_, body_response_));
767 EXPECT_LT(no_body_size, cache_->MemoryBackedSize());
768
769 EXPECT_TRUE(Delete(body_request_));
770 EXPECT_EQ(0, cache_->MemoryBackedSize());
771 }
772
773 TEST_F(ServiceWorkerCacheTest, MemoryBackedSizePersistent) {
774 EXPECT_EQ(0, cache_->MemoryBackedSize());
775 EXPECT_TRUE(Put(no_body_request_, no_body_response_));
776 EXPECT_EQ(0, cache_->MemoryBackedSize());
777 }
778
779 TEST_P(ServiceWorkerCacheTestP, OpsFailOnClosedBackendNeverCreated) {
780 cache_->set_delay_backend_creation(
781 true); // Will hang the test if a backend is created.
782 EXPECT_TRUE(Close());
783 VerifyAllOpsFail();
784 }
785
786 TEST_P(ServiceWorkerCacheTestP, OpsFailOnClosedBackend) {
787 // Create the backend and put something in it.
788 EXPECT_TRUE(Put(body_request_, body_response_));
789 EXPECT_TRUE(Close());
790 VerifyAllOpsFail();
791 }
792
793 TEST_P(ServiceWorkerCacheTestP, VerifySerialScheduling) {
794 // Start two operations, the first one is delayed but the second isn't. The
795 // second should wait for the first.
796 EXPECT_TRUE(Keys()); // Opens the backend.
797 DelayableBackend* delayable_backend = cache_->UseDelayableBackend();
798 delayable_backend->set_delay_open(true);
799
800 scoped_ptr<ServiceWorkerResponse> response1 =
801 CopyFetchResponse(body_response_);
802 response1->status_code = 1;
803
804 scoped_ptr<base::RunLoop> close_loop1(new base::RunLoop());
805 cache_->Put(CopyFetchRequest(body_request_), response1.Pass(),
806 base::Bind(&ServiceWorkerCacheTest::ResponseAndErrorCallback,
807 base::Unretained(this), close_loop1.get()));
808
809 // Blocks on opening the cache entry.
810 base::RunLoop().RunUntilIdle();
811
812 delayable_backend->set_delay_open(false);
813 scoped_ptr<ServiceWorkerResponse> response2 =
814 CopyFetchResponse(body_response_);
815 response2->status_code = 2;
816 scoped_ptr<base::RunLoop> close_loop2(new base::RunLoop());
817 cache_->Put(CopyFetchRequest(body_request_), response2.Pass(),
818 base::Bind(&ServiceWorkerCacheTest::ResponseAndErrorCallback,
819 base::Unretained(this), close_loop2.get()));
820
821 // The second put operation should wait for the first to complete.
822 base::RunLoop().RunUntilIdle();
823 EXPECT_FALSE(callback_response_);
824
825 delayable_backend->OpenEntryContinue();
826 close_loop1->Run();
827 EXPECT_EQ(1, callback_response_->status_code);
828 close_loop2->Run();
829 EXPECT_EQ(2, callback_response_->status_code);
830 }
831
832 INSTANTIATE_TEST_CASE_P(ServiceWorkerCacheTest,
833 ServiceWorkerCacheTestP,
834 ::testing::Values(false, true));
835
836 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698