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

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

Issue 293483002: Store the service worker script and its imports on first load... really (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: tests Created 6 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/service_worker/service_worker_storage.h"
6
7 #include "base/logging.h" 5 #include "base/logging.h"
8 #include "base/message_loop/message_loop.h" 6 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h" 7 #include "base/run_loop.h"
10 #include "content/browser/browser_thread_impl.h" 8 #include "content/browser/browser_thread_impl.h"
11 #include "content/browser/service_worker/service_worker_context_core.h" 9 #include "content/browser/service_worker/service_worker_context_core.h"
10 #include "content/browser/service_worker/service_worker_disk_cache.h"
12 #include "content/browser/service_worker/service_worker_registration.h" 11 #include "content/browser/service_worker/service_worker_registration.h"
12 #include "content/browser/service_worker/service_worker_storage.h"
13 #include "content/browser/service_worker/service_worker_version.h" 13 #include "content/browser/service_worker/service_worker_version.h"
14 #include "content/public/test/test_browser_thread_bundle.h" 14 #include "content/public/test/test_browser_thread_bundle.h"
15 #include "net/base/io_buffer.h"
16 #include "net/base/net_errors.h"
17 #include "net/http/http_response_headers.h"
15 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
16 19
20 using net::IOBuffer;
21 using net::WrappedIOBuffer;
22
17 namespace content { 23 namespace content {
18 24
19 namespace { 25 namespace {
20 26
27 typedef ServiceWorkerDatabase::RegistrationData RegistrationData;
28 typedef ServiceWorkerDatabase::ResourceRecord ResourceRecord;
29
21 void StatusCallback(bool* was_called, 30 void StatusCallback(bool* was_called,
22 ServiceWorkerStatusCode* result, 31 ServiceWorkerStatusCode* result,
23 ServiceWorkerStatusCode status) { 32 ServiceWorkerStatusCode status) {
24 *was_called = true; 33 *was_called = true;
25 *result = status; 34 *result = status;
26 } 35 }
27 36
28 ServiceWorkerStorage::StatusCallback MakeStatusCallback( 37 ServiceWorkerStorage::StatusCallback MakeStatusCallback(
29 bool* was_called, 38 bool* was_called,
30 ServiceWorkerStatusCode* result) { 39 ServiceWorkerStatusCode* result) {
(...skipping 25 matching lines...) Expand all
56 *was_called = true; 65 *was_called = true;
57 *all_out = all; 66 *all_out = all;
58 } 67 }
59 68
60 ServiceWorkerStorage::GetAllRegistrationInfosCallback MakeGetAllCallback( 69 ServiceWorkerStorage::GetAllRegistrationInfosCallback MakeGetAllCallback(
61 bool* was_called, 70 bool* was_called,
62 std::vector<ServiceWorkerRegistrationInfo>* all) { 71 std::vector<ServiceWorkerRegistrationInfo>* all) {
63 return base::Bind(&GetAllCallback, was_called, all); 72 return base::Bind(&GetAllCallback, was_called, all);
64 } 73 }
65 74
75 void NoopCallback() {
nhiroki 2014/05/22 01:20:13 You may want to use DoNothing() in bind_helpers.h.
michaeln 2014/05/22 02:02:37 Done, ty!
76 }
77
78 void OnIOComplete(int* rv_out, int rv) {
79 *rv_out = rv;
80 }
81
82 void WriteBasicResponse(ServiceWorkerStorage* storage, int64 id) {
83 scoped_ptr<ServiceWorkerResponseWriter> writer =
84 storage->CreateResponseWriter(id);
85
86 const char kHttpHeaders[] =
87 "HTTP/1.0 200 HONKYDORY\0Content-Length: 6\0\0";
88 const char kHttpBody[] = "Hello\0";
89 scoped_refptr<IOBuffer> body(new WrappedIOBuffer(kHttpBody));
90 std::string raw_headers(kHttpHeaders, arraysize(kHttpHeaders));
91 scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo);
92 info->request_time = base::Time::Now();
93 info->response_time = base::Time::Now();
94 info->was_cached = false;
95 info->headers = new net::HttpResponseHeaders(raw_headers);
96 scoped_refptr<HttpResponseInfoIOBuffer> info_buffer =
97 new HttpResponseInfoIOBuffer(info.release());
98
99 int rv = -1234;
100 writer->WriteInfo(info_buffer, base::Bind(&OnIOComplete, &rv));
101 base::RunLoop().RunUntilIdle();
102 EXPECT_LT(0, rv);
103
104 rv = -1234;
105 writer->WriteData(body, arraysize(kHttpBody),
106 base::Bind(&OnIOComplete, &rv));
nhiroki 2014/05/22 01:20:13 indent-nit.
michaeln 2014/05/22 02:02:37 Done.
107 base::RunLoop().RunUntilIdle();
108 EXPECT_EQ(arraysize(kHttpBody), rv);
109 }
110
111 bool VerifyBasicResponse(ServiceWorkerStorage* storage, int64 id,
112 bool expected_positive_result) {
113 const char kExpectedHttpBody[] = "Hello\0";
114 scoped_ptr<ServiceWorkerResponseReader> reader =
115 storage->CreateResponseReader(id);
116 scoped_refptr<HttpResponseInfoIOBuffer> info_buffer =
117 new HttpResponseInfoIOBuffer();
118 int rv = -1234;
119 reader->ReadInfo(info_buffer, base::Bind(&OnIOComplete, &rv));
120 base::RunLoop().RunUntilIdle();
121 if (expected_positive_result) {
122 EXPECT_LT(0, rv);
123 }
nhiroki 2014/05/22 01:20:13 nit: you can remove "{}"
michaeln 2014/05/22 02:02:37 Done. (mysterious macro w/o brackets spooks me tho
nhiroki 2014/05/22 03:15:34 Ah... sorry, I unthoughtfully commented this after
124 if (rv <= 0)
125 return false;
126
127 const int kBigEnough = 512;
128 scoped_refptr<net::IOBuffer> buffer = new IOBuffer(kBigEnough);
129 rv = -1234;
130 reader->ReadData(buffer, kBigEnough, base::Bind(&OnIOComplete, &rv));
131 base::RunLoop().RunUntilIdle();
132 EXPECT_EQ(arraysize(kExpectedHttpBody), rv);
133 if (rv <= 0)
134 return false;
135
136 bool status_match =
137 std::string("HONKYDORY") ==
138 info_buffer->http_info->headers->GetStatusText();
139 bool data_match =
140 std::string(kExpectedHttpBody) == std::string(buffer->data());
141
142 EXPECT_TRUE(status_match);
143 EXPECT_TRUE(data_match);
144 return status_match && data_match;
145 }
146
66 } // namespace 147 } // namespace
67 148
68 class ServiceWorkerStorageTest : public testing::Test { 149 class ServiceWorkerStorageTest : public testing::Test {
69 public: 150 public:
70 ServiceWorkerStorageTest() 151 ServiceWorkerStorageTest()
71 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) { 152 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {
72 } 153 }
73 154
74 virtual void SetUp() OVERRIDE { 155 virtual void SetUp() OVERRIDE {
75 context_.reset(new ServiceWorkerContextCore( 156 context_.reset(new ServiceWorkerContextCore(
76 base::FilePath(), 157 base::FilePath(),
77 base::MessageLoopProxy::current(), 158 base::MessageLoopProxy::current(),
78 base::MessageLoopProxy::current(), 159 base::MessageLoopProxy::current(),
79 NULL, 160 NULL,
80 NULL, 161 NULL,
81 scoped_ptr<ServiceWorkerProcessManager>())); 162 scoped_ptr<ServiceWorkerProcessManager>()));
82 context_ptr_ = context_->AsWeakPtr(); 163 context_ptr_ = context_->AsWeakPtr();
83 } 164 }
84 165
85 virtual void TearDown() OVERRIDE { 166 virtual void TearDown() OVERRIDE {
86 context_.reset(); 167 context_.reset();
87 } 168 }
88 169
89 ServiceWorkerStorage* storage() { return context_->storage(); } 170 ServiceWorkerStorage* storage() { return context_->storage(); }
90 171
172 // A static class method for friendliness.
173 static void VerifyPurgeableListStatusCallback(
174 ServiceWorkerDatabase* database,
175 std::set<int64> *purgeable_ids,
176 bool* was_called,
177 ServiceWorkerStatusCode* result,
178 ServiceWorkerStatusCode status) {
179 *was_called = true;
180 *result = status;
181 database->GetPurgeableResourceIds(purgeable_ids);
nhiroki 2014/05/22 01:20:13 Can you check a status code of GetPurgeableResourc
michaeln 2014/05/22 02:02:37 Done.
182 }
183
91 protected: 184 protected:
92 scoped_ptr<ServiceWorkerContextCore> context_; 185 scoped_ptr<ServiceWorkerContextCore> context_;
93 base::WeakPtr<ServiceWorkerContextCore> context_ptr_; 186 base::WeakPtr<ServiceWorkerContextCore> context_ptr_;
94 TestBrowserThreadBundle browser_thread_bundle_; 187 TestBrowserThreadBundle browser_thread_bundle_;
95 }; 188 };
96 189
97 TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) { 190 TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
98 const GURL kScope("http://www.test.com/scope/*"); 191 const GURL kScope("http://www.test.com/scope/*");
99 const GURL kScript("http://www.test.com/script.js"); 192 const GURL kScript("http://www.test.com/script.js");
100 const GURL kDocumentUrl("http://www.test.com/scope/document.html"); 193 const GURL kDocumentUrl("http://www.test.com/scope/document.html");
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 was_called = false; 528 was_called = false;
436 529
437 storage()->GetAllRegistrations( 530 storage()->GetAllRegistrations(
438 MakeGetAllCallback(&was_called, &all_registrations)); 531 MakeGetAllCallback(&was_called, &all_registrations));
439 base::RunLoop().RunUntilIdle(); 532 base::RunLoop().RunUntilIdle();
440 ASSERT_TRUE(was_called); 533 ASSERT_TRUE(was_called);
441 EXPECT_TRUE(all_registrations.empty()); 534 EXPECT_TRUE(all_registrations.empty());
442 was_called = false; 535 was_called = false;
443 } 536 }
444 537
538 TEST_F(ServiceWorkerStorageTest, ResourceIdsAreStoredAndPurged) {
539 storage()->LazyInitialize(base::Bind(&NoopCallback));
540 base::RunLoop().RunUntilIdle();
541 const GURL kScope("http://www.test.com/scope/*");
nhiroki 2014/05/22 01:20:13 "www.test.com" seems to be a domain for an actual
michaeln 2014/05/22 02:02:37 does it matter? no network traffic is generated by
nhiroki 2014/05/22 03:15:34 Yes, this doesn't generate any traffic. Probably
542 const GURL kScript("http://www.test.com/script.js");
543 const GURL kImport("http://www.test.com/import.js");
544 const GURL kDocumentUrl("http://www.test.com/scope/document.html");
545 const int64 kRegistrationId = storage()->NewRegistrationId();
546 const int64 kVersionId = storage()->NewVersionId();
547 const int64 kResourceId1 = storage()->NewResourceId();
548 const int64 kResourceId2 = storage()->NewResourceId();
549
550 // Cons up a new registration+version with two script resources.
551 RegistrationData data;
552 data.registration_id = kRegistrationId;
553 data.scope = kScope;
554 data.script = kScript;
555 data.version_id = kVersionId;
556 data.is_active = false;
557 std::vector<ResourceRecord> resources;
558 resources.push_back(ResourceRecord(kResourceId1, kScript));
559 resources.push_back(ResourceRecord(kResourceId2, kImport));
560 scoped_refptr<ServiceWorkerRegistration> registration =
561 storage()->GetOrCreateRegistration(data, resources);
562 registration->pending_version()->SetStatus(ServiceWorkerVersion::NEW);
563
564 // Add the resources ids to the uncommitted list.
565 std::set<int64> resource_ids;
566 resource_ids.insert(kResourceId1);
567 resource_ids.insert(kResourceId2);
568 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
569 storage()->database_->WriteUncommittedResourceIds(resource_ids));
570
571 // And dump something in the disk cache for them.
572 WriteBasicResponse(storage(), kResourceId1);
573 WriteBasicResponse(storage(), kResourceId2);
574 EXPECT_TRUE(VerifyBasicResponse(storage(), kResourceId1, true));
575 EXPECT_TRUE(VerifyBasicResponse(storage(), kResourceId2, true));
576
577 // Storing the registration/version should take the resources ids out
578 // of the uncommitted list.
579 bool was_called = false;
580 ServiceWorkerStatusCode result =
581 ServiceWorkerStatusCode::SERVICE_WORKER_ERROR_FAILED;
582 storage()->StoreRegistration(registration, registration->pending_version(),
583 MakeStatusCallback(&was_called, &result));
584 base::RunLoop().RunUntilIdle();
585 ASSERT_TRUE(was_called);
586 EXPECT_EQ(ServiceWorkerStatusCode::SERVICE_WORKER_OK, result);
587 std::set<int64> verify_ids;
588 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
589 storage()->database_->GetUncommittedResourceIds(&verify_ids));
590 EXPECT_TRUE(verify_ids.empty());
591
592 // Deleting it should result in the resources being added to the
593 // purgable list and then doomed in the disk cache and removed from
nhiroki 2014/05/22 01:20:13 nit: s/purgable/purgeable/
michaeln 2014/05/22 02:02:37 Done.
594 // that list.
595 was_called = false;
596 verify_ids.clear();
597 storage()->DeleteRegistration(
598 registration->id(), kScope.GetOrigin(),
599 base::Bind(&VerifyPurgeableListStatusCallback,
600 base::Unretained(storage()->database_.get()),
601 &verify_ids,
602 &was_called, &result));
nhiroki 2014/05/22 01:20:13 indent-nit.
michaeln 2014/05/22 02:02:37 Done.
603 base::RunLoop().RunUntilIdle();
604 ASSERT_TRUE(was_called);
605 EXPECT_EQ(ServiceWorkerStatusCode::SERVICE_WORKER_OK, result);
606 EXPECT_EQ(2u, verify_ids.size());
607 verify_ids.clear();
608 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
609 storage()->database_->GetPurgeableResourceIds(&verify_ids));
610 EXPECT_TRUE(verify_ids.empty());
611
612 EXPECT_FALSE(VerifyBasicResponse(storage(), kResourceId1, false));
613 EXPECT_FALSE(VerifyBasicResponse(storage(), kResourceId2, false));
614 }
615
445 } // namespace content 616 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698