OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 "base/basictypes.h" | 5 #include "base/basictypes.h" |
6 #include "base/run_loop.h" | 6 #include "base/run_loop.h" |
7 #include "content/browser/message_port_service.h" | 7 #include "content/browser/message_port_service.h" |
8 #include "content/browser/service_worker/embedded_worker_registry.h" | 8 #include "content/browser/service_worker/embedded_worker_registry.h" |
9 #include "content/browser/service_worker/embedded_worker_test_helper.h" | 9 #include "content/browser/service_worker/embedded_worker_test_helper.h" |
10 #include "content/browser/service_worker/service_worker_context_core.h" | 10 #include "content/browser/service_worker/service_worker_context_core.h" |
11 #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_test_utils.h" | 12 #include "content/browser/service_worker/service_worker_test_utils.h" |
13 #include "content/browser/service_worker/service_worker_version.h" | 13 #include "content/browser/service_worker/service_worker_version.h" |
| 14 #include "content/common/background_sync_service.mojom.h" |
14 #include "content/common/service_worker/service_worker_utils.h" | 15 #include "content/common/service_worker/service_worker_utils.h" |
15 #include "content/public/test/mock_render_process_host.h" | 16 #include "content/public/test/mock_render_process_host.h" |
16 #include "content/public/test/test_browser_thread_bundle.h" | 17 #include "content/public/test/test_browser_thread_bundle.h" |
| 18 #include "mojo/public/cpp/bindings/strong_binding.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
18 | 20 |
19 // IPC messages for testing --------------------------------------------------- | 21 // IPC messages for testing --------------------------------------------------- |
20 | 22 |
21 #define IPC_MESSAGE_IMPL | 23 #define IPC_MESSAGE_IMPL |
22 #include "ipc/ipc_message_macros.h" | 24 #include "ipc/ipc_message_macros.h" |
23 | 25 |
24 #define IPC_MESSAGE_START TestMsgStart | 26 #define IPC_MESSAGE_START TestMsgStart |
25 | 27 |
26 IPC_MESSAGE_CONTROL0(TestMsg_Message) | 28 IPC_MESSAGE_CONTROL0(TestMsg_Message) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 | 63 |
62 private: | 64 private: |
63 void OnMessage() { | 65 void OnMessage() { |
64 // Do nothing. | 66 // Do nothing. |
65 } | 67 } |
66 | 68 |
67 int current_embedded_worker_id_; | 69 int current_embedded_worker_id_; |
68 DISALLOW_COPY_AND_ASSIGN(MessageReceiver); | 70 DISALLOW_COPY_AND_ASSIGN(MessageReceiver); |
69 }; | 71 }; |
70 | 72 |
| 73 class MockBackgroundSyncServiceClient : public BackgroundSyncServiceClient { |
| 74 public: |
| 75 MockBackgroundSyncServiceClient( |
| 76 mojo::InterfaceRequest<BackgroundSyncServiceClient> request) |
| 77 : binding_(this, std::move(request)) {} |
| 78 |
| 79 void RunCallback() { |
| 80 EXPECT_FALSE(callback_.is_null()); |
| 81 callback_.Run(SERVICE_WORKER_EVENT_STATUS_ABORTED); |
| 82 } |
| 83 |
| 84 private: |
| 85 // BackgroundSyncServiceClient overrides |
| 86 void Sync(int64_t handle_id, |
| 87 content::BackgroundSyncEventLastChance last_chance, |
| 88 const SyncCallback& callback) override { |
| 89 EXPECT_TRUE(callback_.is_null()); |
| 90 callback_ = callback; |
| 91 } |
| 92 |
| 93 SyncCallback callback_; |
| 94 mojo::StrongBinding<BackgroundSyncServiceClient> binding_; |
| 95 |
| 96 DISALLOW_COPY_AND_ASSIGN(MockBackgroundSyncServiceClient); |
| 97 }; |
| 98 |
71 void VerifyCalled(bool* called) { | 99 void VerifyCalled(bool* called) { |
72 *called = true; | 100 *called = true; |
73 } | 101 } |
74 | 102 |
75 void ObserveStatusChanges(ServiceWorkerVersion* version, | 103 void ObserveStatusChanges(ServiceWorkerVersion* version, |
76 std::vector<ServiceWorkerVersion::Status>* statuses) { | 104 std::vector<ServiceWorkerVersion::Status>* statuses) { |
77 statuses->push_back(version->status()); | 105 statuses->push_back(version->status()); |
78 version->RegisterStatusChangeCallback( | 106 version->RegisterStatusChangeCallback( |
79 base::Bind(&ObserveStatusChanges, base::Unretained(version), statuses)); | 107 base::Bind(&ObserveStatusChanges, base::Unretained(version), statuses)); |
80 } | 108 } |
81 | 109 |
82 void ReceiveFetchResult(ServiceWorkerStatusCode* status, | 110 void ReceiveFetchResult(ServiceWorkerStatusCode* status, |
83 ServiceWorkerStatusCode actual_status, | 111 ServiceWorkerStatusCode actual_status, |
84 ServiceWorkerFetchEventResult actual_result, | 112 ServiceWorkerFetchEventResult actual_result, |
85 const ServiceWorkerResponse& response) { | 113 const ServiceWorkerResponse& response) { |
86 *status = actual_status; | 114 *status = actual_status; |
87 } | 115 } |
88 | 116 |
| 117 void ReceiveSyncStatus(ServiceWorkerStatusCode* status, |
| 118 ServiceWorkerStatusCode actual_status) { |
| 119 *status = actual_status; |
| 120 } |
| 121 |
89 // A specialized listener class to receive test messages from a worker. | 122 // A specialized listener class to receive test messages from a worker. |
90 class MessageReceiverFromWorker : public EmbeddedWorkerInstance::Listener { | 123 class MessageReceiverFromWorker : public EmbeddedWorkerInstance::Listener { |
91 public: | 124 public: |
92 explicit MessageReceiverFromWorker(EmbeddedWorkerInstance* instance) | 125 explicit MessageReceiverFromWorker(EmbeddedWorkerInstance* instance) |
93 : instance_(instance) { | 126 : instance_(instance) { |
94 instance_->AddListener(this); | 127 instance_->AddListener(this); |
95 } | 128 } |
96 ~MessageReceiverFromWorker() override { instance_->RemoveListener(this); } | 129 ~MessageReceiverFromWorker() override { instance_->RemoveListener(this); } |
97 | 130 |
98 void OnStarted() override { NOTREACHED(); } | 131 void OnStarted() override { NOTREACHED(); } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 struct RunningStateListener : public ServiceWorkerVersion::Listener { | 171 struct RunningStateListener : public ServiceWorkerVersion::Listener { |
139 RunningStateListener() : last_status(ServiceWorkerVersion::STOPPED) {} | 172 RunningStateListener() : last_status(ServiceWorkerVersion::STOPPED) {} |
140 ~RunningStateListener() override {} | 173 ~RunningStateListener() override {} |
141 void OnRunningStateChanged(ServiceWorkerVersion* version) override { | 174 void OnRunningStateChanged(ServiceWorkerVersion* version) override { |
142 last_status = version->running_status(); | 175 last_status = version->running_status(); |
143 } | 176 } |
144 ServiceWorkerVersion::RunningStatus last_status; | 177 ServiceWorkerVersion::RunningStatus last_status; |
145 }; | 178 }; |
146 | 179 |
147 ServiceWorkerVersionTest() | 180 ServiceWorkerVersionTest() |
148 : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} | 181 : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), |
| 182 mock_background_sync_dispatcher_(nullptr) {} |
149 | 183 |
150 void SetUp() override { | 184 void SetUp() override { |
151 helper_ = GetMessageReceiver(); | 185 helper_ = GetMessageReceiver(); |
152 | 186 |
153 pattern_ = GURL("http://www.example.com/test/"); | 187 pattern_ = GURL("http://www.example.com/test/"); |
154 registration_ = new ServiceWorkerRegistration( | 188 registration_ = new ServiceWorkerRegistration( |
155 pattern_, | 189 pattern_, |
156 1L, | 190 1L, |
157 helper_->context()->AsWeakPtr()); | 191 helper_->context()->AsWeakPtr()); |
158 version_ = new ServiceWorkerVersion( | 192 version_ = new ServiceWorkerVersion( |
(...skipping 14 matching lines...) Expand all Loading... |
173 version_.get(), | 207 version_.get(), |
174 CreateReceiverOnCurrentThread(&status)); | 208 CreateReceiverOnCurrentThread(&status)); |
175 base::RunLoop().RunUntilIdle(); | 209 base::RunLoop().RunUntilIdle(); |
176 ASSERT_EQ(SERVICE_WORKER_OK, status); | 210 ASSERT_EQ(SERVICE_WORKER_OK, status); |
177 | 211 |
178 // Simulate adding one process to the pattern. | 212 // Simulate adding one process to the pattern. |
179 helper_->SimulateAddProcessToPattern(pattern_, | 213 helper_->SimulateAddProcessToPattern(pattern_, |
180 helper_->mock_render_process_id()); | 214 helper_->mock_render_process_id()); |
181 ASSERT_TRUE(helper_->context()->process_manager() | 215 ASSERT_TRUE(helper_->context()->process_manager() |
182 ->PatternHasProcessToRun(pattern_)); | 216 ->PatternHasProcessToRun(pattern_)); |
| 217 |
| 218 // Create a mock BackgroundSyncServiceClient. |
| 219 mojo::InterfaceRequest<BackgroundSyncServiceClient> service_request = |
| 220 mojo::GetProxy(&version_->background_sync_dispatcher_); |
| 221 // The MockBackgroundSyncServiceClient is bound to the client, and will be |
| 222 // deleted when the client is deleted. |
| 223 mock_background_sync_dispatcher_ = |
| 224 new MockBackgroundSyncServiceClient(std::move(service_request)); |
| 225 base::RunLoop().RunUntilIdle(); |
183 } | 226 } |
184 | 227 |
185 virtual scoped_ptr<MessageReceiver> GetMessageReceiver() { | 228 virtual scoped_ptr<MessageReceiver> GetMessageReceiver() { |
186 return make_scoped_ptr(new MessageReceiver()); | 229 return make_scoped_ptr(new MessageReceiver()); |
187 } | 230 } |
188 | 231 |
189 void TearDown() override { | 232 void TearDown() override { |
190 version_ = 0; | 233 version_ = 0; |
191 registration_ = 0; | 234 registration_ = 0; |
192 helper_.reset(); | 235 helper_.reset(); |
193 } | 236 } |
194 | 237 |
195 TestBrowserThreadBundle thread_bundle_; | 238 TestBrowserThreadBundle thread_bundle_; |
196 scoped_ptr<MessageReceiver> helper_; | 239 scoped_ptr<MessageReceiver> helper_; |
197 scoped_refptr<ServiceWorkerRegistration> registration_; | 240 scoped_refptr<ServiceWorkerRegistration> registration_; |
198 scoped_refptr<ServiceWorkerVersion> version_; | 241 scoped_refptr<ServiceWorkerVersion> version_; |
| 242 MockBackgroundSyncServiceClient* mock_background_sync_dispatcher_; |
199 GURL pattern_; | 243 GURL pattern_; |
200 | 244 |
201 private: | 245 private: |
202 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersionTest); | 246 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersionTest); |
203 }; | 247 }; |
204 | 248 |
205 class MessageReceiverDisallowStart : public MessageReceiver { | 249 class MessageReceiverDisallowStart : public MessageReceiver { |
206 public: | 250 public: |
207 MessageReceiverDisallowStart() | 251 MessageReceiverDisallowStart() |
208 : MessageReceiver() {} | 252 : MessageReceiver() {} |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 base::Bind(&base::DoNothing), | 790 base::Bind(&base::DoNothing), |
747 base::Bind(&ReceiveFetchResult, &status)); | 791 base::Bind(&ReceiveFetchResult, &status)); |
748 base::RunLoop().RunUntilIdle(); | 792 base::RunLoop().RunUntilIdle(); |
749 | 793 |
750 // Callback has not completed yet. | 794 // Callback has not completed yet. |
751 EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, status); | 795 EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, status); |
752 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status()); | 796 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status()); |
753 | 797 |
754 // Simulate timeout. | 798 // Simulate timeout. |
755 EXPECT_TRUE(version_->timeout_timer_.IsRunning()); | 799 EXPECT_TRUE(version_->timeout_timer_.IsRunning()); |
756 version_->SetAllRequestTimes( | 800 version_->SetAllRequestExpirations(base::TimeTicks::Now()); |
757 base::TimeTicks::Now() - | |
758 base::TimeDelta::FromMinutes( | |
759 ServiceWorkerVersion::kRequestTimeoutMinutes + 1)); | |
760 version_->timeout_timer_.user_task().Run(); | 801 version_->timeout_timer_.user_task().Run(); |
761 base::RunLoop().RunUntilIdle(); | 802 base::RunLoop().RunUntilIdle(); |
762 EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, status); | 803 EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, status); |
763 EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status()); | 804 EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status()); |
764 } | 805 } |
765 | 806 |
| 807 TEST_F(ServiceWorkerVersionTest, RequestCustomizedTimeout) { |
| 808 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value |
| 809 version_->SetStatus(ServiceWorkerVersion::ACTIVATED); |
| 810 |
| 811 // Create a sync request that should expire Now(). |
| 812 version_->DispatchSyncEvent(0 /* sync handle id */, |
| 813 BACKGROUND_SYNC_EVENT_LAST_CHANCE_IS_LAST_CHANCE, |
| 814 base::TimeDelta(), /* max duration */ |
| 815 base::Bind(&ReceiveSyncStatus, &status)); |
| 816 base::RunLoop().RunUntilIdle(); |
| 817 EXPECT_TRUE(version_->timeout_timer_.IsRunning()); |
| 818 version_->timeout_timer_.user_task().Run(); |
| 819 base::RunLoop().RunUntilIdle(); |
| 820 EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, status); |
| 821 } |
| 822 |
| 823 TEST_F(ServiceWorkerWaitForeverInFetchTest, MixedRequestTimeouts) { |
| 824 ServiceWorkerStatusCode sync_status = |
| 825 SERVICE_WORKER_ERROR_NETWORK; // dummy value |
| 826 ServiceWorkerStatusCode fetch_status = |
| 827 SERVICE_WORKER_ERROR_NETWORK; // dummy value |
| 828 version_->SetStatus(ServiceWorkerVersion::ACTIVATED); |
| 829 |
| 830 // Create a fetch request that should expire sometime later. |
| 831 version_->DispatchFetchEvent(ServiceWorkerFetchRequest(), |
| 832 base::Bind(&base::DoNothing), |
| 833 base::Bind(&ReceiveFetchResult, &fetch_status)); |
| 834 // Create a sync request that should expire Now(). |
| 835 version_->DispatchSyncEvent(0 /* sync handle id */, |
| 836 BACKGROUND_SYNC_EVENT_LAST_CHANCE_IS_LAST_CHANCE, |
| 837 base::TimeDelta(), /* max duration */ |
| 838 base::Bind(&ReceiveSyncStatus, &sync_status)); |
| 839 base::RunLoop().RunUntilIdle(); |
| 840 EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, sync_status); |
| 841 |
| 842 // Verify the sync has timed out but not the fetch. |
| 843 EXPECT_TRUE(version_->timeout_timer_.IsRunning()); |
| 844 version_->timeout_timer_.user_task().Run(); |
| 845 base::RunLoop().RunUntilIdle(); |
| 846 EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, sync_status); |
| 847 EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, fetch_status); |
| 848 |
| 849 // Background sync timeouts don't stop the service worker. |
| 850 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status()); |
| 851 |
| 852 // Gracefully handle the sync event finishing after the timeout. |
| 853 mock_background_sync_dispatcher_->RunCallback(); |
| 854 base::RunLoop().RunUntilIdle(); |
| 855 |
| 856 // Verify that the fetch times out later. |
| 857 version_->SetAllRequestExpirations(base::TimeTicks::Now()); |
| 858 version_->timeout_timer_.user_task().Run(); |
| 859 base::RunLoop().RunUntilIdle(); |
| 860 EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, fetch_status); |
| 861 |
| 862 // Other timeouts do stop the service worker. |
| 863 EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status()); |
| 864 } |
| 865 |
766 TEST_F(ServiceWorkerFailToStartTest, RendererCrash) { | 866 TEST_F(ServiceWorkerFailToStartTest, RendererCrash) { |
767 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value | 867 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value |
768 version_->StartWorker( | 868 version_->StartWorker( |
769 CreateReceiverOnCurrentThread(&status)); | 869 CreateReceiverOnCurrentThread(&status)); |
770 base::RunLoop().RunUntilIdle(); | 870 base::RunLoop().RunUntilIdle(); |
771 | 871 |
772 // Callback has not completed yet. | 872 // Callback has not completed yet. |
773 EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, status); | 873 EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, status); |
774 EXPECT_EQ(ServiceWorkerVersion::STARTING, version_->running_status()); | 874 EXPECT_EQ(ServiceWorkerVersion::STARTING, version_->running_status()); |
775 | 875 |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
932 GURL valid_scope_2("http://www.example.com/test/subscope"); | 1032 GURL valid_scope_2("http://www.example.com/test/subscope"); |
933 version_->OnRegisterForeignFetchScopes(std::vector<GURL>(1, valid_scope_2)); | 1033 version_->OnRegisterForeignFetchScopes(std::vector<GURL>(1, valid_scope_2)); |
934 base::RunLoop().RunUntilIdle(); | 1034 base::RunLoop().RunUntilIdle(); |
935 EXPECT_EQ(3, helper_->mock_render_process_host()->bad_msg_count()); | 1035 EXPECT_EQ(3, helper_->mock_render_process_host()->bad_msg_count()); |
936 EXPECT_EQ(2u, version_->foreign_fetch_scopes_.size()); | 1036 EXPECT_EQ(2u, version_->foreign_fetch_scopes_.size()); |
937 EXPECT_EQ(valid_scope_1, version_->foreign_fetch_scopes_[0]); | 1037 EXPECT_EQ(valid_scope_1, version_->foreign_fetch_scopes_[0]); |
938 EXPECT_EQ(valid_scope_2, version_->foreign_fetch_scopes_[1]); | 1038 EXPECT_EQ(valid_scope_2, version_->foreign_fetch_scopes_[1]); |
939 } | 1039 } |
940 | 1040 |
941 } // namespace content | 1041 } // namespace content |
OLD | NEW |