OLD | NEW |
---|---|
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_registration.h" | 5 #include "content/browser/service_worker/service_worker_registration.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/files/scoped_temp_dir.h" | 10 #include "base/files/scoped_temp_dir.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
13 #include "base/threading/thread_task_runner_handle.h" | 13 #include "base/threading/thread_task_runner_handle.h" |
14 #include "content/browser/service_worker/embedded_worker_status.h" | |
14 #include "content/browser/service_worker/embedded_worker_test_helper.h" | 15 #include "content/browser/service_worker/embedded_worker_test_helper.h" |
15 #include "content/browser/service_worker/service_worker_context_core.h" | 16 #include "content/browser/service_worker/service_worker_context_core.h" |
16 #include "content/browser/service_worker/service_worker_registration_handle.h" | 17 #include "content/browser/service_worker/service_worker_registration_handle.h" |
18 #include "content/browser/service_worker/service_worker_test_utils.h" | |
19 #include "content/common/service_worker/service_worker_utils.h" | |
17 #include "content/public/test/test_browser_thread_bundle.h" | 20 #include "content/public/test/test_browser_thread_bundle.h" |
18 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
19 #include "url/gurl.h" | 22 #include "url/gurl.h" |
20 | 23 |
21 namespace content { | 24 namespace content { |
22 | 25 |
26 namespace { | |
27 | |
28 int CreateInflightRequest(ServiceWorkerVersion* version) { | |
29 version->StartWorker(ServiceWorkerMetrics::EventType::PUSH, | |
30 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | |
31 base::RunLoop().RunUntilIdle(); | |
32 return version->StartRequest( | |
33 ServiceWorkerMetrics::EventType::PUSH, | |
34 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | |
35 } | |
36 | |
37 } // namespace | |
38 | |
23 class ServiceWorkerRegistrationTest : public testing::Test { | 39 class ServiceWorkerRegistrationTest : public testing::Test { |
24 public: | 40 public: |
25 ServiceWorkerRegistrationTest() | 41 ServiceWorkerRegistrationTest() |
26 : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} | 42 : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} |
27 | 43 |
28 void SetUp() override { | 44 void SetUp() override { |
29 helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath())); | 45 helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath())); |
46 | |
47 helper_->context()->storage()->LazyInitialize(base::Bind(&base::DoNothing)); | |
48 base::RunLoop().RunUntilIdle(); | |
30 } | 49 } |
31 | 50 |
32 void TearDown() override { | 51 void TearDown() override { |
33 helper_.reset(); | 52 helper_.reset(); |
34 base::RunLoop().RunUntilIdle(); | 53 base::RunLoop().RunUntilIdle(); |
35 } | 54 } |
36 | 55 |
37 ServiceWorkerContextCore* context() { return helper_->context(); } | 56 ServiceWorkerContextCore* context() { return helper_->context(); } |
57 ServiceWorkerStorage* storage() { return helper_->context()->storage(); } | |
38 | 58 |
39 class RegistrationListener : public ServiceWorkerRegistration::Listener { | 59 class RegistrationListener : public ServiceWorkerRegistration::Listener { |
40 public: | 60 public: |
41 RegistrationListener() {} | 61 RegistrationListener() {} |
42 ~RegistrationListener() { | 62 ~RegistrationListener() { |
43 if (observed_registration_.get()) | 63 if (observed_registration_.get()) |
44 observed_registration_->RemoveListener(this); | 64 observed_registration_->RemoveListener(this); |
45 } | 65 } |
46 | 66 |
47 void OnVersionAttributesChanged( | 67 void OnVersionAttributesChanged( |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
153 new ServiceWorkerRegistration(kScope, kRegistrationId, | 173 new ServiceWorkerRegistration(kScope, kRegistrationId, |
154 context()->AsWeakPtr()); | 174 context()->AsWeakPtr()); |
155 std::unique_ptr<ServiceWorkerRegistrationHandle> handle( | 175 std::unique_ptr<ServiceWorkerRegistrationHandle> handle( |
156 new ServiceWorkerRegistrationHandle( | 176 new ServiceWorkerRegistrationHandle( |
157 context()->AsWeakPtr(), base::WeakPtr<ServiceWorkerProviderHost>(), | 177 context()->AsWeakPtr(), base::WeakPtr<ServiceWorkerProviderHost>(), |
158 registration.get())); | 178 registration.get())); |
159 registration->NotifyRegistrationFailed(); | 179 registration->NotifyRegistrationFailed(); |
160 // Don't crash when handle gets destructed. | 180 // Don't crash when handle gets destructed. |
161 } | 181 } |
162 | 182 |
183 // Sets up a registration with a waiting worker, and an active worker | |
184 // with a controllee and an inflight request. | |
185 class ServiceWorkerActivationTest : public ServiceWorkerRegistrationTest { | |
186 public: | |
187 ServiceWorkerActivationTest() : ServiceWorkerRegistrationTest() {} | |
188 | |
189 void SetUp() override { | |
190 ServiceWorkerRegistrationTest::SetUp(); | |
191 | |
192 const GURL kScope("https://www.example.not/"); | |
193 const GURL kScript("https://www.example.not/service_worker.js"); | |
194 | |
195 registration_ = new ServiceWorkerRegistration( | |
196 kScope, storage()->NewRegistrationId(), context()->AsWeakPtr()); | |
197 | |
198 // Create an active version. | |
199 scoped_refptr<ServiceWorkerVersion> version_1 = new ServiceWorkerVersion( | |
200 registration_.get(), kScript, storage()->NewVersionId(), | |
201 context()->AsWeakPtr()); | |
202 registration_->SetActiveVersion(version_1); | |
203 version_1->SetStatus(ServiceWorkerVersion::ACTIVATED); | |
204 | |
205 // Store the registration. | |
206 std::vector<ServiceWorkerDatabase::ResourceRecord> records; | |
207 records.push_back(ServiceWorkerDatabase::ResourceRecord( | |
208 10, version_1->script_url(), 100)); | |
209 version_1->script_cache_map()->SetResources(records); | |
210 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; | |
211 context()->storage()->StoreRegistration( | |
212 registration_.get(), version_1.get(), | |
213 CreateReceiverOnCurrentThread(&status)); | |
214 base::RunLoop().RunUntilIdle(); | |
215 ASSERT_EQ(SERVICE_WORKER_OK, status); | |
216 | |
217 // Give the active version a controllee. | |
218 host_.reset(new ServiceWorkerProviderHost( | |
219 33 /* dummy render process id */, | |
220 MSG_ROUTING_NONE /* render_frame_id */, 1 /* dummy provider_id */, | |
221 SERVICE_WORKER_PROVIDER_FOR_WINDOW, | |
222 ServiceWorkerProviderHost::FrameSecurityLevel::SECURE, | |
223 context()->AsWeakPtr(), nullptr)); | |
224 version_1->AddControllee(host_.get()); | |
225 | |
226 // Give the active version an in-flight request. | |
227 request_id_ = CreateInflightRequest(version_1.get()); | |
228 | |
229 // Create a waiting version. | |
230 scoped_refptr<ServiceWorkerVersion> version_2 = new ServiceWorkerVersion( | |
231 registration_.get(), kScript, storage()->NewVersionId(), | |
232 context()->AsWeakPtr()); | |
233 registration_->SetWaitingVersion(version_2); | |
234 version_2->SetStatus(ServiceWorkerVersion::INSTALLED); | |
235 | |
236 // Set it to activate when ready. The original version should still be | |
237 // active. | |
238 registration_->ActivateWaitingVersionWhenReady(); | |
239 base::RunLoop().RunUntilIdle(); | |
240 EXPECT_EQ(version_1.get(), registration_->active_version()); | |
241 } | |
242 | |
243 void TearDown() override { | |
244 registration_->active_version()->RemoveListener(registration_.get()); | |
245 ServiceWorkerRegistrationTest::TearDown(); | |
246 } | |
247 | |
248 ServiceWorkerRegistration* registration() { return registration_.get(); } | |
249 ServiceWorkerProviderHost* controllee() { return host_.get(); } | |
250 int inflight_request_id() { return request_id_; } | |
251 | |
252 private: | |
253 scoped_refptr<ServiceWorkerRegistration> registration_; | |
254 std::unique_ptr<ServiceWorkerProviderHost> host_; | |
255 int request_id_; | |
256 }; | |
257 | |
258 // Test activation triggered by loss of controllee. | |
259 TEST_F(ServiceWorkerActivationTest, NoControllee) { | |
nhiroki
2016/07/08 05:04:42
It would be better to swap line 258-259 with line
falken
2016/07/08 07:06:45
Good eye, done.
| |
260 scoped_refptr<ServiceWorkerRegistration> reg = registration(); | |
261 scoped_refptr<ServiceWorkerVersion> version_1 = reg->active_version(); | |
262 scoped_refptr<ServiceWorkerVersion> version_2 = reg->waiting_version(); | |
263 | |
264 // Remove the controllee. Since there is an in-flight request, | |
265 // activation should not yet happen. | |
266 version_1->RemoveControllee(controllee()); | |
267 base::RunLoop().RunUntilIdle(); | |
268 EXPECT_EQ(version_1.get(), reg->active_version()); | |
269 | |
270 // Finish the request. Activation should happen. | |
271 version_1->FinishRequest(inflight_request_id(), true /* was_handled */); | |
272 base::RunLoop().RunUntilIdle(); | |
273 EXPECT_EQ(version_2.get(), reg->active_version()); | |
274 } | |
275 | |
276 // Test activation triggered by finishing all requests. | |
277 TEST_F(ServiceWorkerActivationTest, NoInflightRequest) { | |
nhiroki
2016/07/08 05:04:42
ditto.
| |
278 scoped_refptr<ServiceWorkerRegistration> reg = registration(); | |
279 scoped_refptr<ServiceWorkerVersion> version_1 = reg->active_version(); | |
280 scoped_refptr<ServiceWorkerVersion> version_2 = reg->waiting_version(); | |
281 | |
282 // Finish the request. Since there is a controllee, activation should not yet | |
283 // happen. | |
284 version_1->FinishRequest(inflight_request_id(), true /* was_handled */); | |
285 base::RunLoop().RunUntilIdle(); | |
286 EXPECT_EQ(version_1.get(), reg->active_version()); | |
287 | |
288 // Remove the controllee. Activation should happen. | |
289 version_1->RemoveControllee(controllee()); | |
290 base::RunLoop().RunUntilIdle(); | |
291 EXPECT_EQ(version_2.get(), reg->active_version()); | |
292 } | |
293 | |
294 // Test activation triggered by skipWaiting. | |
295 TEST_F(ServiceWorkerActivationTest, SkipWaiting) { | |
296 scoped_refptr<ServiceWorkerRegistration> reg = registration(); | |
297 scoped_refptr<ServiceWorkerVersion> version_1 = reg->active_version(); | |
298 scoped_refptr<ServiceWorkerVersion> version_2 = reg->waiting_version(); | |
299 | |
300 // Finish the in-flight request. Since there is a controllee, | |
301 // activation should not happen. | |
302 version_1->FinishRequest(inflight_request_id(), true /* was_handled */); | |
303 base::RunLoop().RunUntilIdle(); | |
304 EXPECT_EQ(version_1.get(), reg->active_version()); | |
305 | |
306 // Call skipWaiting. Activation should happen. | |
307 version_2->OnSkipWaiting(77 /* dummy request_id */); | |
308 base::RunLoop().RunUntilIdle(); | |
309 EXPECT_EQ(version_2.get(), reg->active_version()); | |
310 } | |
311 | |
312 // Test activation triggered by skipWaiting and finishing requests. | |
313 TEST_F(ServiceWorkerActivationTest, SkipWaitingWithInflightRequest) { | |
314 scoped_refptr<ServiceWorkerRegistration> reg = registration(); | |
315 scoped_refptr<ServiceWorkerVersion> version_1 = reg->active_version(); | |
316 scoped_refptr<ServiceWorkerVersion> version_2 = reg->waiting_version(); | |
317 | |
318 // Set skip waiting flag. Since there is still an in-flight request, | |
319 // activation should not happen. | |
320 version_2->OnSkipWaiting(77 /* dummy request_id */); | |
321 base::RunLoop().RunUntilIdle(); | |
322 EXPECT_EQ(version_1.get(), reg->active_version()); | |
323 | |
324 // Finish the request. Activation should happen. | |
325 version_1->FinishRequest(inflight_request_id(), true /* was_handled */); | |
326 base::RunLoop().RunUntilIdle(); | |
327 EXPECT_EQ(version_2.get(), reg->active_version()); | |
328 } | |
329 | |
163 } // namespace content | 330 } // namespace content |
OLD | NEW |