Chromium Code Reviews| 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, request.Pass()) {} | |
| 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 | |
|
falken
2015/12/18 01:28:48
apologetic nit: add period to sentence
jkarlin
2015/12/18 12:28:30
Done.
| |
| 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(service_request.Pass()); | |
| 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 |