| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "components/offline_pages/core/prefetch/prefetch_dispatcher_impl.h" | 5 #include "components/offline_pages/core/prefetch/prefetch_dispatcher_impl.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/test/scoped_feature_list.h" | 9 #include "base/test/scoped_feature_list.h" |
| 10 #include "base/test/test_simple_task_runner.h" | 10 #include "base/test/test_simple_task_runner.h" |
| 11 #include "base/threading/thread_task_runner_handle.h" | 11 #include "base/threading/thread_task_runner_handle.h" |
| 12 #include "components/offline_pages/core/client_namespace_constants.h" | 12 #include "components/offline_pages/core/client_namespace_constants.h" |
| 13 #include "components/offline_pages/core/offline_event_logger.h" | 13 #include "components/offline_pages/core/offline_event_logger.h" |
| 14 #include "components/offline_pages/core/offline_page_feature.h" | 14 #include "components/offline_pages/core/offline_page_feature.h" |
| 15 #include "components/offline_pages/core/prefetch/prefetch_in_memory_store.h" | |
| 16 #include "components/offline_pages/core/prefetch/prefetch_service.h" | 15 #include "components/offline_pages/core/prefetch/prefetch_service.h" |
| 16 #include "components/offline_pages/core/prefetch/store/prefetch_store_command_fa
ctory.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 #include "url/gurl.h" |
| 18 | 19 |
| 19 namespace offline_pages { | 20 namespace offline_pages { |
| 20 | 21 |
| 21 class TestScopedBackgroundTask | 22 class TestScopedBackgroundTask |
| 22 : public PrefetchDispatcher::ScopedBackgroundTask { | 23 : public PrefetchDispatcher::ScopedBackgroundTask { |
| 23 public: | 24 public: |
| 24 TestScopedBackgroundTask() = default; | 25 TestScopedBackgroundTask() = default; |
| 25 ~TestScopedBackgroundTask() override = default; | 26 ~TestScopedBackgroundTask() override = default; |
| 26 | 27 |
| 27 void SetNeedsReschedule(bool reschedule, bool backoff) override { | 28 void SetNeedsReschedule(bool reschedule, bool backoff) override { |
| 28 needs_reschedule_called = true; | 29 needs_reschedule_called = true; |
| 29 } | 30 } |
| 30 | 31 |
| 31 bool needs_reschedule_called = false; | 32 bool needs_reschedule_called = false; |
| 32 }; | 33 }; |
| 33 | 34 |
| 35 namespace { |
| 36 class TestPrefetchStoreCommandFactory; |
| 37 |
| 38 class TestAddUrlsStoreCommand : public AddUrlsStoreCommand { |
| 39 public: |
| 40 TestAddUrlsStoreCommand(TestPrefetchStoreCommandFactory* factory) |
| 41 : factory_(factory){}; |
| 42 ~TestAddUrlsStoreCommand() override{}; |
| 43 void Execute(const std::string& name_space, |
| 44 const std::vector<PrefetchURL>& prefetch_urls, |
| 45 UrlsAddedCallback callback) override; |
| 46 |
| 47 private: |
| 48 TestPrefetchStoreCommandFactory* factory_; |
| 49 }; |
| 50 |
| 51 class TestCleanupZombiesStoreCommand : public CleanupZombiesStoreCommand { |
| 52 public: |
| 53 TestCleanupZombiesStoreCommand(TestPrefetchStoreCommandFactory* factory) |
| 54 : factory_(factory){}; |
| 55 ~TestCleanupZombiesStoreCommand() override{}; |
| 56 void Execute(const std::string& name_space, |
| 57 const std::vector<GURL>& urls_to_keep, |
| 58 base::OnceCallback<void()> callback) override; |
| 59 |
| 60 private: |
| 61 TestPrefetchStoreCommandFactory* factory_; |
| 62 }; |
| 63 |
| 64 class TestPrefetchStoreCommandFactory : public PrefetchStoreCommandFactory { |
| 65 public: |
| 66 std::unique_ptr<AddUrlsStoreCommand> createAddUrls() override { |
| 67 return base::MakeUnique<TestAddUrlsStoreCommand>(this); |
| 68 } |
| 69 |
| 70 std::unique_ptr<CleanupZombiesStoreCommand> createCleanupZombies() override { |
| 71 return base::MakeUnique<TestCleanupZombiesStoreCommand>(this); |
| 72 } |
| 73 |
| 74 int add_url_execute_calls_ = 0; |
| 75 bool add_url_succeeds = true; |
| 76 int zombies_execute_calls_ = 0; |
| 77 }; |
| 78 |
| 79 void TestAddUrlsStoreCommand::Execute( |
| 80 const std::string& name_space, |
| 81 const std::vector<PrefetchURL>& prefetch_urls, |
| 82 UrlsAddedCallback callback) { |
| 83 ++factory_->add_url_execute_calls_; |
| 84 std::move(callback).Run(factory_->add_url_succeeds); |
| 85 } |
| 86 |
| 87 void TestCleanupZombiesStoreCommand::Execute( |
| 88 const std::string& name_space, |
| 89 const std::vector<GURL>& urls_to_keep, |
| 90 base::OnceCallback<void()> callback) { |
| 91 ++factory_->zombies_execute_calls_; |
| 92 std::move(callback).Run(); |
| 93 } |
| 94 |
| 95 } // namespace |
| 96 |
| 34 class PrefetchDispatcherTest : public testing::Test, public PrefetchService { | 97 class PrefetchDispatcherTest : public testing::Test, public PrefetchService { |
| 35 public: | 98 public: |
| 99 const std::string TEST_NAMESPACE = "TestPrefetchClientNamespace"; |
| 100 |
| 36 PrefetchDispatcherTest(); | 101 PrefetchDispatcherTest(); |
| 37 | 102 |
| 38 // Test implementation. | 103 // Test implementation. |
| 39 void SetUp() override; | 104 void SetUp() override; |
| 40 void TearDown() override; | 105 void TearDown() override; |
| 41 | 106 |
| 42 // PrefetchService implementation: | 107 // PrefetchService implementation: |
| 43 OfflineEventLogger* GetLogger() override; | 108 OfflineEventLogger* GetLogger() override; |
| 44 OfflineMetricsCollector* GetOfflineMetricsCollector() override; | 109 OfflineMetricsCollector* GetOfflineMetricsCollector() override; |
| 45 PrefetchDispatcher* GetPrefetchDispatcher() override; | 110 PrefetchDispatcher* GetPrefetchDispatcher() override; |
| 46 PrefetchGCMHandler* GetPrefetchGCMHandler() override; | 111 PrefetchGCMHandler* GetPrefetchGCMHandler() override; |
| 47 PrefetchStore* GetPrefetchStore() override; | 112 PrefetchStoreCommandFactory* GetPrefetchStoreCommandFactory() override; |
| 48 SuggestedArticlesObserver* GetSuggestedArticlesObserver() override; | 113 SuggestedArticlesObserver* GetSuggestedArticlesObserver() override; |
| 49 | 114 |
| 50 // KeyedService implementation. | 115 // KeyedService implementation. |
| 51 void Shutdown() override {} | 116 void Shutdown() override {} |
| 52 | 117 |
| 53 void PumpLoop(); | 118 void PumpLoop(); |
| 54 PrefetchDispatcher::ScopedBackgroundTask* GetBackgroundTask() { | 119 PrefetchDispatcher::ScopedBackgroundTask* GetBackgroundTask() { |
| 55 return dispatcher_impl_->task_.get(); | 120 return dispatcher_impl_->task_.get(); |
| 56 } | 121 } |
| 57 | 122 |
| 58 TaskQueue* dispatcher_task_queue() { return &dispatcher_impl_->task_queue_; } | 123 TaskQueue* dispatcher_task_queue() { return &dispatcher_impl_->task_queue_; } |
| 59 | 124 |
| 125 protected: |
| 126 std::unique_ptr<TestPrefetchStoreCommandFactory> test_command_factory_; |
| 127 std::vector<PrefetchURL> test_urls_; |
| 128 |
| 60 private: | 129 private: |
| 130 std::unique_ptr<PrefetchDispatcherImpl> dispatcher_impl_; |
| 61 OfflineEventLogger logger_; | 131 OfflineEventLogger logger_; |
| 62 base::test::ScopedFeatureList feature_list_; | 132 base::test::ScopedFeatureList feature_list_; |
| 63 | |
| 64 std::unique_ptr<PrefetchInMemoryStore> in_memory_store_; | |
| 65 std::unique_ptr<PrefetchDispatcherImpl> dispatcher_impl_; | |
| 66 | |
| 67 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; | 133 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
| 68 base::ThreadTaskRunnerHandle task_runner_handle_; | 134 base::ThreadTaskRunnerHandle task_runner_handle_; |
| 69 }; | 135 }; |
| 70 | 136 |
| 71 PrefetchDispatcherTest::PrefetchDispatcherTest() | 137 PrefetchDispatcherTest::PrefetchDispatcherTest() |
| 72 : task_runner_(new base::TestSimpleTaskRunner), | 138 : task_runner_(new base::TestSimpleTaskRunner), |
| 73 task_runner_handle_(task_runner_) { | 139 task_runner_handle_(task_runner_) { |
| 74 feature_list_.InitAndEnableFeature(kPrefetchingOfflinePagesFeature); | 140 feature_list_.InitAndEnableFeature(kPrefetchingOfflinePagesFeature); |
| 75 } | 141 } |
| 76 | 142 |
| 77 void PrefetchDispatcherTest::SetUp() { | 143 void PrefetchDispatcherTest::SetUp() { |
| 78 ASSERT_EQ(base::ThreadTaskRunnerHandle::Get(), task_runner_); | 144 ASSERT_EQ(base::ThreadTaskRunnerHandle::Get(), task_runner_); |
| 79 ASSERT_FALSE(task_runner_->HasPendingTask()); | 145 ASSERT_FALSE(task_runner_->HasPendingTask()); |
| 80 in_memory_store_ = base::MakeUnique<PrefetchInMemoryStore>(); | 146 test_command_factory_ = base::MakeUnique<TestPrefetchStoreCommandFactory>(); |
| 81 dispatcher_impl_ = base::MakeUnique<PrefetchDispatcherImpl>(); | 147 dispatcher_impl_ = base::MakeUnique<PrefetchDispatcherImpl>(); |
| 82 dispatcher_impl_->SetService(this); | 148 dispatcher_impl_->SetService(this); |
| 149 |
| 150 ASSERT_TRUE(test_urls_.empty()); |
| 151 test_urls_.push_back({"1", GURL("http://testurl.com/foo")}); |
| 152 test_urls_.push_back({"2", GURL("https://testurl.com/bar")}); |
| 83 } | 153 } |
| 84 | 154 |
| 85 void PrefetchDispatcherTest::TearDown() { | 155 void PrefetchDispatcherTest::TearDown() { |
| 86 task_runner_->ClearPendingTasks(); | 156 task_runner_->ClearPendingTasks(); |
| 87 } | 157 } |
| 88 | 158 |
| 89 OfflineEventLogger* PrefetchDispatcherTest::GetLogger() { | 159 OfflineEventLogger* PrefetchDispatcherTest::GetLogger() { |
| 90 return &logger_; | 160 return &logger_; |
| 91 } | 161 } |
| 92 | 162 |
| 93 OfflineMetricsCollector* PrefetchDispatcherTest::GetOfflineMetricsCollector() { | 163 OfflineMetricsCollector* PrefetchDispatcherTest::GetOfflineMetricsCollector() { |
| 94 NOTREACHED(); | 164 NOTREACHED(); |
| 95 return nullptr; | 165 return nullptr; |
| 96 } | 166 } |
| 97 | 167 |
| 98 PrefetchDispatcher* PrefetchDispatcherTest::GetPrefetchDispatcher() { | 168 PrefetchDispatcher* PrefetchDispatcherTest::GetPrefetchDispatcher() { |
| 99 return dispatcher_impl_.get(); | 169 return dispatcher_impl_.get(); |
| 100 } | 170 } |
| 101 | 171 |
| 102 PrefetchGCMHandler* PrefetchDispatcherTest::GetPrefetchGCMHandler() { | 172 PrefetchGCMHandler* PrefetchDispatcherTest::GetPrefetchGCMHandler() { |
| 103 NOTREACHED(); | 173 NOTREACHED(); |
| 104 return nullptr; | 174 return nullptr; |
| 105 } | 175 } |
| 106 | 176 |
| 107 PrefetchStore* PrefetchDispatcherTest::GetPrefetchStore() { | 177 PrefetchStoreCommandFactory* |
| 108 return in_memory_store_.get(); | 178 PrefetchDispatcherTest::GetPrefetchStoreCommandFactory() { |
| 179 return test_command_factory_.get(); |
| 109 } | 180 } |
| 110 | 181 |
| 111 SuggestedArticlesObserver* | 182 SuggestedArticlesObserver* |
| 112 PrefetchDispatcherTest::GetSuggestedArticlesObserver() { | 183 PrefetchDispatcherTest::GetSuggestedArticlesObserver() { |
| 113 NOTREACHED(); | 184 NOTREACHED(); |
| 114 return nullptr; | 185 return nullptr; |
| 115 } | 186 } |
| 116 | 187 |
| 117 void PrefetchDispatcherTest::PumpLoop() { | 188 void PrefetchDispatcherTest::PumpLoop() { |
| 118 task_runner_->RunUntilIdle(); | 189 task_runner_->RunUntilIdle(); |
| 119 } | 190 } |
| 120 | 191 |
| 121 TEST_F(PrefetchDispatcherTest, DispatcherDoesNotCrash) { | 192 TEST_F(PrefetchDispatcherTest, DispatcherDoesNotCrash) { |
| 122 GetPrefetchDispatcher()->AddCandidatePrefetchURLs(std::vector<PrefetchURL>()); | 193 GetPrefetchDispatcher()->AddCandidatePrefetchURLs(TEST_NAMESPACE, test_urls_); |
| 123 GetPrefetchDispatcher()->RemoveAllUnprocessedPrefetchURLs( | 194 GetPrefetchDispatcher()->RemoveAllUnprocessedPrefetchURLs( |
| 124 kSuggestedArticlesNamespace); | 195 kSuggestedArticlesNamespace); |
| 125 GetPrefetchDispatcher()->RemovePrefetchURLsByClientId( | 196 GetPrefetchDispatcher()->RemovePrefetchURLsByClientId( |
| 126 {kSuggestedArticlesNamespace, "123"}); | 197 {kSuggestedArticlesNamespace, "123"}); |
| 127 } | 198 } |
| 128 | 199 |
| 129 TEST_F(PrefetchDispatcherTest, AddCandidatePrefetchURLsTask) { | 200 TEST_F(PrefetchDispatcherTest, AddCandidatePrefetchURLsTask) { |
| 130 GetPrefetchDispatcher()->AddCandidatePrefetchURLs(std::vector<PrefetchURL>()); | 201 GetPrefetchDispatcher()->AddCandidatePrefetchURLs(TEST_NAMESPACE, test_urls_); |
| 131 EXPECT_TRUE(dispatcher_task_queue()->HasPendingTasks()); | 202 EXPECT_TRUE(dispatcher_task_queue()->HasPendingTasks()); |
| 132 EXPECT_TRUE(dispatcher_task_queue()->HasRunningTask()); | 203 EXPECT_TRUE(dispatcher_task_queue()->HasRunningTask()); |
| 133 PumpLoop(); | 204 PumpLoop(); |
| 134 EXPECT_FALSE(dispatcher_task_queue()->HasPendingTasks()); | 205 EXPECT_FALSE(dispatcher_task_queue()->HasPendingTasks()); |
| 135 EXPECT_FALSE(dispatcher_task_queue()->HasRunningTask()); | 206 EXPECT_FALSE(dispatcher_task_queue()->HasRunningTask()); |
| 207 EXPECT_EQ(1, test_command_factory_->add_url_execute_calls_); |
| 208 EXPECT_EQ(1, test_command_factory_->zombies_execute_calls_); |
| 209 } |
| 210 |
| 211 TEST_F(PrefetchDispatcherTest, AddCandidatePrefetchURLsTaskFailsAdding) { |
| 212 test_command_factory_->add_url_succeeds = false; |
| 213 GetPrefetchDispatcher()->AddCandidatePrefetchURLs(TEST_NAMESPACE, test_urls_); |
| 214 EXPECT_TRUE(dispatcher_task_queue()->HasPendingTasks()); |
| 215 EXPECT_TRUE(dispatcher_task_queue()->HasRunningTask()); |
| 216 PumpLoop(); |
| 217 EXPECT_FALSE(dispatcher_task_queue()->HasPendingTasks()); |
| 218 EXPECT_FALSE(dispatcher_task_queue()->HasRunningTask()); |
| 219 EXPECT_EQ(1, test_command_factory_->add_url_execute_calls_); |
| 220 EXPECT_EQ(0, test_command_factory_->zombies_execute_calls_); |
| 136 } | 221 } |
| 137 | 222 |
| 138 TEST_F(PrefetchDispatcherTest, DispatcherDoesNothingIfFeatureNotEnabled) { | 223 TEST_F(PrefetchDispatcherTest, DispatcherDoesNothingIfFeatureNotEnabled) { |
| 139 base::test::ScopedFeatureList disabled_feature_list; | 224 base::test::ScopedFeatureList disabled_feature_list; |
| 140 disabled_feature_list.InitAndDisableFeature(kPrefetchingOfflinePagesFeature); | 225 disabled_feature_list.InitAndDisableFeature(kPrefetchingOfflinePagesFeature); |
| 141 | 226 |
| 142 // Don't add a task for new prefetch URLs. | 227 // Don't add a task for new prefetch URLs. |
| 143 ClientId client_id("namespace", "id"); | 228 PrefetchURL prefetch_url("id", GURL("https://www.chromium.org")); |
| 144 PrefetchURL prefetch_url(client_id, GURL("https://www.chromium.org")); | |
| 145 GetPrefetchDispatcher()->AddCandidatePrefetchURLs( | 229 GetPrefetchDispatcher()->AddCandidatePrefetchURLs( |
| 146 std::vector<PrefetchURL>(1, prefetch_url)); | 230 TEST_NAMESPACE, std::vector<PrefetchURL>(1, prefetch_url)); |
| 147 EXPECT_FALSE(dispatcher_task_queue()->HasRunningTask()); | 231 EXPECT_FALSE(dispatcher_task_queue()->HasRunningTask()); |
| 148 | 232 |
| 149 // Do nothing with a new background task. | 233 // Do nothing with a new background task. |
| 150 GetPrefetchDispatcher()->BeginBackgroundTask( | 234 GetPrefetchDispatcher()->BeginBackgroundTask( |
| 151 base::MakeUnique<TestScopedBackgroundTask>()); | 235 base::MakeUnique<TestScopedBackgroundTask>()); |
| 152 EXPECT_EQ(nullptr, GetBackgroundTask()); | 236 EXPECT_EQ(nullptr, GetBackgroundTask()); |
| 153 | 237 |
| 154 // Everything else is unimplemented. | 238 // Everything else is unimplemented. |
| 155 } | 239 } |
| 156 | 240 |
| 157 } // namespace offline_pages | 241 } // namespace offline_pages |
| OLD | NEW |