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.
5 #include "content/browser/service_worker/service_worker_cache.h"
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/test/test_browser_context.h"
17 #include "content/public/test/test_browser_thread_bundle.h"
18 #include "net/url_request/url_request_context.h"
19 #include "net/url_request/url_request_context_getter.h"
20 #include "net/url_request/url_request_job_factory_impl.h"
21 #include "storage/browser/blob/blob_data_handle.h"
22 #include "storage/browser/blob/blob_storage_context.h"
23 #include "storage/browser/blob/blob_url_request_job_factory.h"
24 #include "storage/browser/quota/quota_manager_proxy.h"
25 #include "storage/common/blob/blob_data.h"
26 #include "testing/gtest/include/gtest/gtest.h"
31 const char kTestData
[] = "Hello World";
33 // Returns a BlobProtocolHandler that uses |blob_storage_context|. Caller owns
35 storage::BlobProtocolHandler
* CreateMockBlobProtocolHandler(
36 storage::BlobStorageContext
* blob_storage_context
) {
37 // The FileSystemContext and MessageLoopProxy are not actually used but a
38 // MessageLoopProxy is needed to avoid a DCHECK in BlobURLRequestJob ctor.
39 return new storage::BlobProtocolHandler(
40 blob_storage_context
, NULL
, base::MessageLoopProxy::current().get());
45 class ServiceWorkerCacheTest
: public testing::Test
{
47 ServiceWorkerCacheTest()
48 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP
),
49 callback_error_(ServiceWorkerCache::ErrorTypeOK
) {}
51 virtual void SetUp() override
{
52 ChromeBlobStorageContext
* blob_storage_context
=
53 ChromeBlobStorageContext::GetFor(&browser_context_
);
54 // Wait for chrome_blob_storage_context to finish initializing.
55 base::RunLoop().RunUntilIdle();
56 blob_storage_context_
= blob_storage_context
->context();
58 quota_manager_proxy_
= new MockQuotaManagerProxy(
59 nullptr, base::MessageLoopProxy::current().get());
61 url_request_job_factory_
.reset(new net::URLRequestJobFactoryImpl
);
62 url_request_job_factory_
->SetProtocolHandler(
63 "blob", CreateMockBlobProtocolHandler(blob_storage_context
->context()));
65 net::URLRequestContext
* url_request_context
=
66 browser_context_
.GetRequestContext()->GetURLRequestContext();
68 url_request_context
->set_job_factory(url_request_job_factory_
.get());
70 CreateRequests(blob_storage_context
);
73 cache_
= ServiceWorkerCache::CreateMemoryCache(
74 GURL("http://example.com"),
77 blob_storage_context
->context()->AsWeakPtr());
79 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
80 cache_
= ServiceWorkerCache::CreatePersistentCache(
81 GURL("http://example.com"),
85 blob_storage_context
->context()->AsWeakPtr());
89 virtual void TearDown() override
{
90 quota_manager_proxy_
->SimulateQuotaManagerDestroyed();
91 base::RunLoop().RunUntilIdle();
94 void CreateRequests(ChromeBlobStorageContext
* blob_storage_context
) {
95 ServiceWorkerHeaderMap headers
;
96 headers
.insert(std::make_pair("a", "a"));
97 headers
.insert(std::make_pair("b", "b"));
98 body_request_
= ServiceWorkerFetchRequest(
99 GURL("http://example.com/body.html"), "GET", headers
, GURL(""), false);
101 ServiceWorkerFetchRequest(GURL("http://example.com/no_body.html"),
107 std::string expected_response
;
108 for (int i
= 0; i
< 100; ++i
)
109 expected_blob_data_
+= kTestData
;
111 scoped_refptr
<storage::BlobData
> blob_data(
112 new storage::BlobData("blob-id:myblob"));
113 blob_data
->AppendData(expected_blob_data_
);
116 blob_storage_context
->context()->AddFinishedBlob(blob_data
.get());
119 ServiceWorkerResponse(GURL("http://example.com/body.html"),
122 blink::WebServiceWorkerResponseTypeDefault
,
124 blob_handle_
->uuid(),
125 expected_blob_data_
.size());
128 ServiceWorkerResponse(GURL("http://example.com/no_body.html"),
131 blink::WebServiceWorkerResponseTypeDefault
,
137 scoped_ptr
<ServiceWorkerFetchRequest
> CopyFetchRequest(
138 const ServiceWorkerFetchRequest
& request
) {
139 return make_scoped_ptr(new ServiceWorkerFetchRequest(request
.url
,
146 scoped_ptr
<ServiceWorkerResponse
> CopyFetchResponse(
147 const ServiceWorkerResponse
& response
) {
148 scoped_ptr
<ServiceWorkerResponse
> sw_response(
149 new ServiceWorkerResponse(response
.url
,
150 response
.status_code
,
151 response
.status_text
,
152 response
.response_type
,
155 response
.blob_size
));
156 return sw_response
.Pass();
159 bool Put(const ServiceWorkerFetchRequest
& request
,
160 const ServiceWorkerResponse
& response
) {
161 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
163 cache_
->Put(CopyFetchRequest(request
),
164 CopyFetchResponse(response
),
165 base::Bind(&ServiceWorkerCacheTest::ResponseAndErrorCallback
,
166 base::Unretained(this),
167 base::Unretained(loop
.get())));
168 // TODO(jkarlin): These functions should use base::RunLoop().RunUntilIdle()
169 // once the cache uses a passed in MessageLoopProxy instead of the CACHE
173 return callback_error_
== ServiceWorkerCache::ErrorTypeOK
;
176 bool Match(const ServiceWorkerFetchRequest
& request
) {
177 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
179 cache_
->Match(CopyFetchRequest(request
),
180 base::Bind(&ServiceWorkerCacheTest::ResponseAndErrorCallback
,
181 base::Unretained(this),
182 base::Unretained(loop
.get())));
185 return callback_error_
== ServiceWorkerCache::ErrorTypeOK
;
188 bool Delete(const ServiceWorkerFetchRequest
& request
) {
189 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
191 cache_
->Delete(CopyFetchRequest(request
),
192 base::Bind(&ServiceWorkerCacheTest::ErrorTypeCallback
,
193 base::Unretained(this),
194 base::Unretained(loop
.get())));
197 return callback_error_
== ServiceWorkerCache::ErrorTypeOK
;
201 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
203 cache_
->Keys(base::Bind(&ServiceWorkerCacheTest::RequestsCallback
,
204 base::Unretained(this),
205 base::Unretained(loop
.get())));
208 return callback_error_
== ServiceWorkerCache::ErrorTypeOK
;
211 void RequestsCallback(base::RunLoop
* run_loop
,
212 ServiceWorkerCache::ErrorType error
,
213 scoped_ptr
<ServiceWorkerCache::Requests
> requests
) {
214 callback_error_
= error
;
215 callback_strings_
.clear();
216 for (size_t i
= 0u; i
< requests
->size(); ++i
)
217 callback_strings_
.push_back(requests
->at(i
).url
.spec());
221 void ErrorTypeCallback(base::RunLoop
* run_loop
,
222 ServiceWorkerCache::ErrorType error
) {
223 callback_error_
= error
;
227 void ResponseAndErrorCallback(
228 base::RunLoop
* run_loop
,
229 ServiceWorkerCache::ErrorType error
,
230 scoped_ptr
<ServiceWorkerResponse
> response
,
231 scoped_ptr
<storage::BlobDataHandle
> body_handle
) {
232 callback_error_
= error
;
233 callback_response_
= response
.Pass();
235 if (error
== ServiceWorkerCache::ErrorTypeOK
&&
236 !callback_response_
->blob_uuid
.empty()) {
237 callback_response_data_
= body_handle
.Pass();
243 void CopyBody(storage::BlobDataHandle
* blob_handle
, std::string
* output
) {
244 storage::BlobData
* data
= blob_handle
->data();
245 std::vector
<storage::BlobData::Item
> items
= data
->items();
246 for (size_t i
= 0, max
= items
.size(); i
< max
; ++i
)
247 output
->append(items
[i
].bytes(), items
[i
].length());
250 bool VerifyKeys(const std::vector
<std::string
>& expected_keys
) {
251 if (expected_keys
.size() != callback_strings_
.size())
254 std::set
<std::string
> found_set
;
255 for (int i
= 0, max
= callback_strings_
.size(); i
< max
; ++i
)
256 found_set
.insert(callback_strings_
[i
]);
258 for (int i
= 0, max
= expected_keys
.size(); i
< max
; ++i
) {
259 if (found_set
.find(expected_keys
[i
]) == found_set
.end())
265 bool TestResponseType(blink::WebServiceWorkerResponseType response_type
) {
266 body_response_
.response_type
= response_type
;
267 EXPECT_TRUE(Put(body_request_
, body_response_
));
268 EXPECT_TRUE(Match(body_request_
));
269 EXPECT_TRUE(Delete(body_request_
));
270 return response_type
== callback_response_
->response_type
;
273 virtual bool MemoryOnly() { return false; }
276 TestBrowserContext browser_context_
;
277 TestBrowserThreadBundle browser_thread_bundle_
;
278 scoped_ptr
<net::URLRequestJobFactoryImpl
> url_request_job_factory_
;
279 scoped_refptr
<MockQuotaManagerProxy
> quota_manager_proxy_
;
280 storage::BlobStorageContext
* blob_storage_context_
;
282 base::ScopedTempDir temp_dir_
;
283 scoped_refptr
<ServiceWorkerCache
> cache_
;
285 ServiceWorkerFetchRequest body_request_
;
286 ServiceWorkerResponse body_response_
;
287 ServiceWorkerFetchRequest no_body_request_
;
288 ServiceWorkerResponse no_body_response_
;
289 scoped_ptr
<storage::BlobDataHandle
> blob_handle_
;
290 std::string expected_blob_data_
;
292 ServiceWorkerCache::ErrorType callback_error_
;
293 scoped_ptr
<ServiceWorkerResponse
> callback_response_
;
294 scoped_ptr
<storage::BlobDataHandle
> callback_response_data_
;
295 std::vector
<std::string
> callback_strings_
;
298 class ServiceWorkerCacheTestP
: public ServiceWorkerCacheTest
,
299 public testing::WithParamInterface
<bool> {
300 bool MemoryOnly() override
{ return !GetParam(); }
303 class ServiceWorkerCacheMemoryOnlyTest
304 : public ServiceWorkerCacheTest
,
305 public testing::WithParamInterface
<bool> {
306 bool MemoryOnly() override
{ return true; }
309 TEST_P(ServiceWorkerCacheTestP
, PutNoBody
) {
310 EXPECT_TRUE(Put(no_body_request_
, no_body_response_
));
311 EXPECT_TRUE(callback_response_
);
312 EXPECT_STREQ(no_body_response_
.url
.spec().c_str(),
313 callback_response_
->url
.spec().c_str());
314 EXPECT_FALSE(callback_response_data_
);
315 EXPECT_STREQ("", callback_response_
->blob_uuid
.c_str());
316 EXPECT_EQ(0u, callback_response_
->blob_size
);
319 TEST_P(ServiceWorkerCacheTestP
, PutBody
) {
320 EXPECT_TRUE(Put(body_request_
, body_response_
));
321 EXPECT_TRUE(callback_response_
);
322 EXPECT_STREQ(body_response_
.url
.spec().c_str(),
323 callback_response_
->url
.spec().c_str());
324 EXPECT_TRUE(callback_response_data_
);
325 EXPECT_STRNE("", callback_response_
->blob_uuid
.c_str());
326 EXPECT_EQ(expected_blob_data_
.size(), callback_response_
->blob_size
);
328 std::string response_body
;
329 CopyBody(callback_response_data_
.get(), &response_body
);
330 EXPECT_STREQ(expected_blob_data_
.c_str(), response_body
.c_str());
333 TEST_F(ServiceWorkerCacheTest
, PutBodyDropBlobRef
) {
334 scoped_ptr
<base::RunLoop
> loop(new base::RunLoop());
335 cache_
->Put(CopyFetchRequest(body_request_
),
336 CopyFetchResponse(body_response_
),
337 base::Bind(&ServiceWorkerCacheTestP::ResponseAndErrorCallback
,
338 base::Unretained(this),
339 base::Unretained(loop
.get())));
340 // The handle should be held by the cache now so the deref here should be
342 blob_handle_
.reset();
345 EXPECT_EQ(ServiceWorkerCache::ErrorTypeOK
, callback_error_
);
348 TEST_P(ServiceWorkerCacheTestP
, MatchNoBody
) {
349 EXPECT_TRUE(Put(no_body_request_
, no_body_response_
));
350 EXPECT_TRUE(Match(no_body_request_
));
351 EXPECT_EQ(200, callback_response_
->status_code
);
352 EXPECT_STREQ("OK", callback_response_
->status_text
.c_str());
353 EXPECT_STREQ("http://example.com/no_body.html",
354 callback_response_
->url
.spec().c_str());
355 EXPECT_STREQ("", callback_response_
->blob_uuid
.c_str());
356 EXPECT_EQ(0u, callback_response_
->blob_size
);
359 TEST_P(ServiceWorkerCacheTestP
, MatchBody
) {
360 EXPECT_TRUE(Put(body_request_
, body_response_
));
361 EXPECT_TRUE(Match(body_request_
));
362 EXPECT_EQ(200, callback_response_
->status_code
);
363 EXPECT_STREQ("OK", callback_response_
->status_text
.c_str());
364 EXPECT_STREQ("http://example.com/body.html",
365 callback_response_
->url
.spec().c_str());
366 EXPECT_STRNE("", callback_response_
->blob_uuid
.c_str());
367 EXPECT_EQ(expected_blob_data_
.size(), callback_response_
->blob_size
);
369 std::string response_body
;
370 CopyBody(callback_response_data_
.get(), &response_body
);
371 EXPECT_STREQ(expected_blob_data_
.c_str(), response_body
.c_str());
374 TEST_P(ServiceWorkerCacheTestP
, Vary
) {
375 body_request_
.headers
["vary_foo"] = "foo";
376 body_response_
.headers
["vary"] = "vary_foo";
377 EXPECT_TRUE(Put(body_request_
, body_response_
));
378 EXPECT_TRUE(Match(body_request_
));
380 body_request_
.headers
["vary_foo"] = "bar";
381 EXPECT_FALSE(Match(body_request_
));
383 body_request_
.headers
.erase("vary_foo");
384 EXPECT_FALSE(Match(body_request_
));
387 TEST_P(ServiceWorkerCacheTestP
, EmptyVary
) {
388 body_response_
.headers
["vary"] = "";
389 EXPECT_TRUE(Put(body_request_
, body_response_
));
390 EXPECT_TRUE(Match(body_request_
));
392 body_request_
.headers
["zoo"] = "zoo";
393 EXPECT_TRUE(Match(body_request_
));
396 TEST_P(ServiceWorkerCacheTestP
, NoVaryButDiffHeaders
) {
397 EXPECT_TRUE(Put(body_request_
, body_response_
));
398 EXPECT_TRUE(Match(body_request_
));
400 body_request_
.headers
["zoo"] = "zoo";
401 EXPECT_TRUE(Match(body_request_
));
404 TEST_P(ServiceWorkerCacheTestP
, VaryMultiple
) {
405 body_request_
.headers
["vary_foo"] = "foo";
406 body_request_
.headers
["vary_bar"] = "bar";
407 body_response_
.headers
["vary"] = " vary_foo , vary_bar";
408 EXPECT_TRUE(Put(body_request_
, body_response_
));
409 EXPECT_TRUE(Match(body_request_
));
411 body_request_
.headers
["vary_bar"] = "foo";
412 EXPECT_FALSE(Match(body_request_
));
414 body_request_
.headers
.erase("vary_bar");
415 EXPECT_FALSE(Match(body_request_
));
418 TEST_P(ServiceWorkerCacheTestP
, VaryNewHeader
) {
419 body_request_
.headers
["vary_foo"] = "foo";
420 body_response_
.headers
["vary"] = " vary_foo, vary_bar";
421 EXPECT_TRUE(Put(body_request_
, body_response_
));
422 EXPECT_TRUE(Match(body_request_
));
424 body_request_
.headers
["vary_bar"] = "bar";
425 EXPECT_FALSE(Match(body_request_
));
428 TEST_P(ServiceWorkerCacheTestP
, VaryStar
) {
429 body_response_
.headers
["vary"] = "*";
430 EXPECT_TRUE(Put(body_request_
, body_response_
));
431 EXPECT_FALSE(Match(body_request_
));
434 TEST_P(ServiceWorkerCacheTestP
, EmptyKeys
) {
436 EXPECT_EQ(0u, callback_strings_
.size());
439 TEST_P(ServiceWorkerCacheTestP
, TwoKeys
) {
440 EXPECT_TRUE(Put(no_body_request_
, no_body_response_
));
441 EXPECT_TRUE(Put(body_request_
, body_response_
));
443 EXPECT_EQ(2u, callback_strings_
.size());
444 std::vector
<std::string
> expected_keys
;
445 expected_keys
.push_back(no_body_request_
.url
.spec());
446 expected_keys
.push_back(body_request_
.url
.spec());
447 EXPECT_TRUE(VerifyKeys(expected_keys
));
450 TEST_P(ServiceWorkerCacheTestP
, TwoKeysThenOne
) {
451 EXPECT_TRUE(Put(no_body_request_
, no_body_response_
));
452 EXPECT_TRUE(Put(body_request_
, body_response_
));
454 EXPECT_EQ(2u, callback_strings_
.size());
455 std::vector
<std::string
> expected_keys
;
456 expected_keys
.push_back(no_body_request_
.url
.spec());
457 expected_keys
.push_back(body_request_
.url
.spec());
458 EXPECT_TRUE(VerifyKeys(expected_keys
));
460 EXPECT_TRUE(Delete(body_request_
));
462 EXPECT_EQ(1u, callback_strings_
.size());
463 std::vector
<std::string
> expected_key
;
464 expected_key
.push_back(no_body_request_
.url
.spec());
465 EXPECT_TRUE(VerifyKeys(expected_key
));
468 // TODO(jkarlin): Once SimpleCache is working bug-free on Windows reenable these
469 // tests. In the meanwhile we know that Windows operations will be a little
470 // flaky (though not crashy). See https://crbug.com/409109 and
471 // https://crbug.com/416940.
473 TEST_P(ServiceWorkerCacheTestP
, DeleteNoBody
) {
474 EXPECT_TRUE(Put(no_body_request_
, no_body_response_
));
475 EXPECT_TRUE(Match(no_body_request_
));
476 EXPECT_TRUE(Delete(no_body_request_
));
477 EXPECT_FALSE(Match(no_body_request_
));
478 EXPECT_FALSE(Delete(no_body_request_
));
479 EXPECT_TRUE(Put(no_body_request_
, no_body_response_
));
480 EXPECT_TRUE(Match(no_body_request_
));
481 EXPECT_TRUE(Delete(no_body_request_
));
484 TEST_P(ServiceWorkerCacheTestP
, DeleteBody
) {
485 EXPECT_TRUE(Put(body_request_
, body_response_
));
486 EXPECT_TRUE(Match(body_request_
));
487 EXPECT_TRUE(Delete(body_request_
));
488 EXPECT_FALSE(Match(body_request_
));
489 EXPECT_FALSE(Delete(body_request_
));
490 EXPECT_TRUE(Put(body_request_
, body_response_
));
491 EXPECT_TRUE(Match(body_request_
));
492 EXPECT_TRUE(Delete(body_request_
));
495 TEST_P(ServiceWorkerCacheTestP
, QuickStressNoBody
) {
496 for (int i
= 0; i
< 100; ++i
) {
497 EXPECT_FALSE(Match(no_body_request_
));
498 EXPECT_TRUE(Put(no_body_request_
, no_body_response_
));
499 EXPECT_TRUE(Match(no_body_request_
));
500 EXPECT_TRUE(Delete(no_body_request_
));
504 TEST_P(ServiceWorkerCacheTestP
, QuickStressBody
) {
505 for (int i
= 0; i
< 100; ++i
) {
506 ASSERT_FALSE(Match(body_request_
));
507 ASSERT_TRUE(Put(body_request_
, body_response_
));
508 ASSERT_TRUE(Match(body_request_
));
509 ASSERT_TRUE(Delete(body_request_
));
513 TEST_P(ServiceWorkerCacheTestP
, PutResponseType
) {
514 EXPECT_TRUE(TestResponseType(blink::WebServiceWorkerResponseTypeBasic
));
515 EXPECT_TRUE(TestResponseType(blink::WebServiceWorkerResponseTypeCORS
));
516 EXPECT_TRUE(TestResponseType(blink::WebServiceWorkerResponseTypeDefault
));
517 EXPECT_TRUE(TestResponseType(blink::WebServiceWorkerResponseTypeError
));
518 EXPECT_TRUE(TestResponseType(blink::WebServiceWorkerResponseTypeOpaque
));
522 TEST_F(ServiceWorkerCacheTest
, CaselessServiceWorkerResponseHeaders
) {
523 // ServiceWorkerCache depends on ServiceWorkerResponse having caseless
524 // headers so that it can quickly lookup vary headers.
525 ServiceWorkerResponse
response(GURL("http://www.example.com"),
528 blink::WebServiceWorkerResponseTypeDefault
,
529 ServiceWorkerHeaderMap(),
532 response
.headers
["content-type"] = "foo";
533 response
.headers
["Content-Type"] = "bar";
534 EXPECT_EQ("bar", response
.headers
["content-type"]);
537 TEST_F(ServiceWorkerCacheTest
, CaselessServiceWorkerFetchRequestHeaders
) {
538 // ServiceWorkerCache depends on ServiceWorkerFetchRequest having caseless
539 // headers so that it can quickly lookup vary headers.
540 ServiceWorkerFetchRequest
request(GURL("http://www.example.com"),
542 ServiceWorkerHeaderMap(),
545 request
.headers
["content-type"] = "foo";
546 request
.headers
["Content-Type"] = "bar";
547 EXPECT_EQ("bar", request
.headers
["content-type"]);
550 TEST_P(ServiceWorkerCacheTestP
, QuotaManagerModified
) {
551 EXPECT_EQ(0, quota_manager_proxy_
->notify_storage_modified_count());
553 EXPECT_TRUE(Put(no_body_request_
, no_body_response_
));
554 EXPECT_EQ(1, quota_manager_proxy_
->notify_storage_modified_count());
555 EXPECT_LT(0, quota_manager_proxy_
->last_notified_delta());
556 int64 sum_delta
= quota_manager_proxy_
->last_notified_delta();
558 EXPECT_TRUE(Put(body_request_
, body_response_
));
559 EXPECT_EQ(2, quota_manager_proxy_
->notify_storage_modified_count());
560 EXPECT_LT(sum_delta
, quota_manager_proxy_
->last_notified_delta());
561 sum_delta
+= quota_manager_proxy_
->last_notified_delta();
563 EXPECT_TRUE(Delete(body_request_
));
564 EXPECT_EQ(3, quota_manager_proxy_
->notify_storage_modified_count());
565 sum_delta
+= quota_manager_proxy_
->last_notified_delta();
567 EXPECT_TRUE(Delete(no_body_request_
));
568 EXPECT_EQ(4, quota_manager_proxy_
->notify_storage_modified_count());
569 sum_delta
+= quota_manager_proxy_
->last_notified_delta();
571 EXPECT_EQ(0, sum_delta
);
574 TEST_F(ServiceWorkerCacheMemoryOnlyTest
, MemoryBackedSize
) {
575 EXPECT_EQ(0, cache_
->MemoryBackedSize());
576 EXPECT_TRUE(Put(no_body_request_
, no_body_response_
));
577 EXPECT_LT(0, cache_
->MemoryBackedSize());
578 int64 no_body_size
= cache_
->MemoryBackedSize();
580 EXPECT_TRUE(Delete(no_body_request_
));
581 EXPECT_EQ(0, cache_
->MemoryBackedSize());
583 EXPECT_TRUE(Put(body_request_
, body_response_
));
584 EXPECT_LT(no_body_size
, cache_
->MemoryBackedSize());
586 EXPECT_TRUE(Delete(body_request_
));
587 EXPECT_EQ(0, cache_
->MemoryBackedSize());
590 TEST_F(ServiceWorkerCacheTest
, MemoryBackedSizePersistent
) {
591 EXPECT_EQ(0, cache_
->MemoryBackedSize());
592 EXPECT_TRUE(Put(no_body_request_
, no_body_response_
));
593 EXPECT_EQ(0, cache_
->MemoryBackedSize());
596 INSTANTIATE_TEST_CASE_P(ServiceWorkerCacheTest
,
597 ServiceWorkerCacheTestP
,
598 ::testing::Values(false, true));
600 } // namespace content