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 "content/browser/background_fetch/background_fetch_job_controller.h" | 5 #include "content/browser/background_fetch/background_fetch_job_controller.h" |
6 | 6 |
7 #include <string> | |
8 #include <vector> | |
9 | |
7 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
8 #include "base/callback_helpers.h" | 11 #include "base/callback_helpers.h" |
12 #include "base/guid.h" | |
9 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
10 #include "base/run_loop.h" | 14 #include "base/run_loop.h" |
15 #include "base/strings/string_number_conversions.h" | |
11 #include "content/browser/background_fetch/background_fetch_data_manager.h" | 16 #include "content/browser/background_fetch/background_fetch_data_manager.h" |
12 #include "content/browser/background_fetch/background_fetch_job_info.h" | 17 #include "content/browser/background_fetch/background_fetch_job_info.h" |
13 #include "content/browser/background_fetch/background_fetch_request_info.h" | 18 #include "content/browser/background_fetch/background_fetch_request_info.h" |
14 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
15 #include "content/public/test/mock_download_item.h" | 20 #include "content/public/test/mock_download_item.h" |
16 #include "content/public/test/mock_download_manager.h" | 21 #include "content/public/test/mock_download_manager.h" |
17 #include "content/public/test/test_browser_context.h" | 22 #include "content/public/test/test_browser_context.h" |
18 #include "content/public/test/test_browser_thread_bundle.h" | 23 #include "content/public/test/test_browser_thread_bundle.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
20 | 25 |
21 namespace { | 26 namespace { |
22 | 27 |
23 const char kOrigin[] = "https://example.com/"; | 28 const char kOrigin[] = "https://example.com/"; |
24 const char kJobGuid[] = "TestRequestGuid"; | 29 const char kJobGuid[] = "TestRequestGuid"; |
25 constexpr int64_t kServiceWorkerRegistrationId = 9001; | 30 constexpr int64_t kServiceWorkerRegistrationId = 9001; |
26 const char kTestUrl[] = "http://www.example.com/example.html"; | 31 const char kTestUrl[] = "http://www.example.com/example.html"; |
27 const char kTag[] = "testTag"; | 32 const char kTag[] = "testTag"; |
28 | 33 |
29 } // namespace | 34 } // namespace |
30 | 35 |
31 namespace content { | 36 namespace content { |
32 | 37 |
33 // Use the basic MockDownloadItem, but override it to provide a valid GUID. | 38 // Use the basic MockDownloadItem, but override it to provide a valid GUID. |
34 class MockDownloadItemWithValues : public MockDownloadItem { | 39 class MockDownloadItemWithValues : public MockDownloadItem { |
35 public: | 40 public: |
41 MockDownloadItemWithValues(const std::string& guid) : guid_(guid) {} | |
42 | |
36 const std::string& GetGuid() const override { return guid_; } | 43 const std::string& GetGuid() const override { return guid_; } |
37 void SetGuid(const std::string& guid) { guid_ = guid; } | 44 void SetGuid(const std::string& guid) { guid_ = guid; } |
38 | 45 |
46 DownloadState GetState() const override { return state_; } | |
47 void SetState(DownloadState state) { state_ = state; } | |
48 | |
39 private: | 49 private: |
40 std::string guid_; | 50 std::string guid_; |
51 DownloadState state_ = DownloadItem::DownloadState::IN_PROGRESS; | |
41 }; | 52 }; |
42 | 53 |
43 // Use the basic MockDownloadManager, but override it so that it implements the | 54 // Use the basic MockDownloadManager, but override it so that it implements the |
44 // functionality that the JobController requires. | 55 // functionality that the JobController requires. |
45 class MockDownloadManagerWithCallback : public MockDownloadManager { | 56 class MockDownloadManagerWithCallback : public MockDownloadManager { |
46 public: | 57 public: |
47 void DownloadUrl(std::unique_ptr<DownloadUrlParameters> params) override { | 58 void DownloadUrl(std::unique_ptr<DownloadUrlParameters> params) override { |
48 DownloadUrlMock(params.get()); | 59 DownloadUrlMock(params.get()); |
49 params->callback().Run(&download_item_, DOWNLOAD_INTERRUPT_REASON_NONE); | 60 std::string guid = base::GenerateGUID(); |
61 std::unique_ptr<MockDownloadItemWithValues> item = | |
62 base::MakeUnique<MockDownloadItemWithValues>(guid); | |
63 params->callback().Run(item.get(), DOWNLOAD_INTERRUPT_REASON_NONE); | |
64 download_items_.push_back(std::move(item)); | |
50 } | 65 } |
51 | 66 |
67 // This is very inefficient, but is only called during shutdown. | |
Peter Beverloo
2017/03/13 14:05:27
nit: it would be good to clarify why. O(n) is not
harkness
2017/03/13 15:53:13
Updated. Based on our discussion last week, if we'
| |
52 DownloadItem* GetDownloadByGuid(const std::string& guid) override { | 68 DownloadItem* GetDownloadByGuid(const std::string& guid) override { |
53 return &download_item_; | 69 for (const auto& item : download_items_) { |
70 if (item->GetGuid() == guid) | |
71 return item.get(); | |
72 } | |
73 return nullptr; | |
54 } | 74 } |
55 | 75 |
56 MockDownloadItemWithValues* download_item() { return &download_item_; } | 76 const std::vector<std::unique_ptr<MockDownloadItemWithValues>>& |
77 download_items() const { | |
78 return download_items_; | |
79 } | |
57 | 80 |
58 private: | 81 private: |
59 MockDownloadItemWithValues download_item_; | 82 std::vector<std::unique_ptr<MockDownloadItemWithValues>> download_items_; |
60 }; | 83 }; |
61 | 84 |
62 class BackgroundFetchJobControllerTest : public ::testing::Test { | 85 class BackgroundFetchJobControllerTest : public ::testing::Test { |
63 public: | 86 public: |
64 BackgroundFetchJobControllerTest() | 87 BackgroundFetchJobControllerTest() |
65 : download_manager_(new MockDownloadManagerWithCallback()) {} | 88 : download_manager_(new MockDownloadManagerWithCallback()) {} |
66 ~BackgroundFetchJobControllerTest() override = default; | 89 ~BackgroundFetchJobControllerTest() override = default; |
67 | 90 |
68 void SetUp() override { | 91 void SetUp() override { |
69 // The download_manager_ ownership is given to the BrowserContext, and the | 92 // The download_manager_ ownership is given to the BrowserContext, and the |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
104 | 127 |
105 DownloadItem::Observer* ItemObserver() const { return job_controller_.get(); } | 128 DownloadItem::Observer* ItemObserver() const { return job_controller_.get(); } |
106 | 129 |
107 private: | 130 private: |
108 TestBrowserThreadBundle thread_bundle_; | 131 TestBrowserThreadBundle thread_bundle_; |
109 TestBrowserContext browser_context_; | 132 TestBrowserContext browser_context_; |
110 std::unique_ptr<BackgroundFetchJobController> job_controller_; | 133 std::unique_ptr<BackgroundFetchJobController> job_controller_; |
111 MockDownloadManagerWithCallback* download_manager_; | 134 MockDownloadManagerWithCallback* download_manager_; |
112 }; | 135 }; |
113 | 136 |
114 TEST_F(BackgroundFetchJobControllerTest, StartDownload) { | 137 TEST_F(BackgroundFetchJobControllerTest, SingleRequestJob) { |
115 BackgroundFetchJobInfo job_info(kTag, url::Origin(GURL(kOrigin)), | 138 BackgroundFetchJobInfo job_info(kTag, url::Origin(GURL(kOrigin)), |
116 kServiceWorkerRegistrationId); | 139 kServiceWorkerRegistrationId); |
117 BackgroundFetchRequestInfo request_info(GURL(kTestUrl), kJobGuid); | 140 BackgroundFetchRequestInfo request_info(GURL(kTestUrl), kJobGuid); |
118 std::vector<BackgroundFetchRequestInfo> request_infos{request_info}; | 141 std::vector<BackgroundFetchRequestInfo> request_infos{request_info}; |
119 | 142 |
120 // Create a MockDownloadItem that the test can manipulate. | |
121 MockDownloadItemWithValues* item = download_manager()->download_item(); | |
122 item->SetGuid("foo"); | |
123 | |
124 // Get a JobData to give to the JobController. The JobController then gets | 143 // Get a JobData to give to the JobController. The JobController then gets |
125 // the BackgroundFetchRequestInfos from the JobData. The JobController will | 144 // the BackgroundFetchRequestInfos from the JobData. The JobController will |
126 // take ownership of the JobData. | 145 // take ownership of the JobData. |
127 BackgroundFetchJobData* job_data = new BackgroundFetchJobData(request_infos); | 146 BackgroundFetchJobData* job_data = new BackgroundFetchJobData(request_infos); |
128 InitializeJobController(job_data); | 147 InitializeJobController(job_data); |
129 | 148 |
130 EXPECT_CALL(*(download_manager()), | 149 EXPECT_CALL(*(download_manager()), |
131 DownloadUrlMock(::testing::Pointee(::testing::Property( | 150 DownloadUrlMock(::testing::Pointee(::testing::Property( |
132 &DownloadUrlParameters::url, GURL(kTestUrl))))) | 151 &DownloadUrlParameters::url, GURL(kTestUrl))))) |
133 .Times(1); | 152 .Times(1); |
134 | 153 |
135 StartProcessing(); | 154 StartProcessing(); |
155 | |
156 // Get one of the pending downloads from the download manager. | |
157 auto& download_items = download_manager()->download_items(); | |
158 ASSERT_EQ(1U, download_items.size()); | |
159 MockDownloadItemWithValues* item = download_items[0].get(); | |
160 | |
161 // Update the observer with no actual change. | |
162 ItemObserver()->OnDownloadUpdated(item); | |
163 EXPECT_FALSE(job_data->IsComplete()); | |
164 | |
165 // Update the item to be completed then update the observer. The JobController | |
166 // should update the JobData that the request is complete. | |
167 item->SetState(DownloadItem::DownloadState::COMPLETE); | |
168 ItemObserver()->OnDownloadUpdated(item); | |
169 EXPECT_TRUE(job_data->IsComplete()); | |
170 } | |
171 | |
172 TEST_F(BackgroundFetchJobControllerTest, MultipleRequestJob) { | |
173 BackgroundFetchJobInfo job_info(kTag, url::Origin(GURL(kOrigin)), | |
174 kServiceWorkerRegistrationId); | |
175 std::vector<BackgroundFetchRequestInfo> request_infos; | |
176 for (int i = 0; i < 10; i++) { | |
177 request_infos.emplace_back( | |
178 BackgroundFetchRequestInfo(GURL(kTestUrl), base::IntToString(i))); | |
Peter Beverloo
2017/03/13 14:05:27
This is not how you'd use emplace_back, right? Sho
harkness
2017/03/13 15:53:13
Ack, of course you're right. Updated.
| |
179 } | |
180 | |
181 // Get a JobData to give to the JobController. The JobController then gets | |
182 // the BackgroundFetchRequestInfos from the JobData. The JobController will | |
183 // take ownership of the JobData. | |
184 BackgroundFetchJobData* job_data = new BackgroundFetchJobData(request_infos); | |
185 InitializeJobController(job_data); | |
186 | |
187 EXPECT_CALL(*(download_manager()), | |
188 DownloadUrlMock(::testing::Pointee(::testing::Property( | |
189 &DownloadUrlParameters::url, GURL(kTestUrl))))) | |
190 .Times(10); | |
191 | |
192 StartProcessing(); | |
193 | |
194 // Get one of the pending downloads from the download manager. | |
195 auto& download_items = download_manager()->download_items(); | |
196 ASSERT_EQ(1U, download_items.size()); | |
197 MockDownloadItemWithValues* item = download_items[0].get(); | |
198 | |
199 // Update the observer with no actual change. | |
200 ItemObserver()->OnDownloadUpdated(item); | |
201 EXPECT_FALSE(job_data->IsComplete()); | |
202 ASSERT_EQ(1U, download_items.size()); | |
203 | |
204 for (size_t i = 0; i < 9; i++) { | |
205 // Update the next item to be completed then update the observer. | |
206 ASSERT_EQ(i + 1, download_items.size()); | |
207 item = download_items[i].get(); | |
208 item->SetState(DownloadItem::DownloadState::COMPLETE); | |
209 ItemObserver()->OnDownloadUpdated(item); | |
210 EXPECT_FALSE(job_data->IsComplete()); | |
211 } | |
212 EXPECT_FALSE(job_data->HasRequestsRemaining()); | |
213 | |
214 // Finally, update the last request to be complete. The JobController should | |
215 // see that there are no more requests and mark the job as done. | |
216 ASSERT_EQ(10U, download_items.size()); | |
217 item = download_items[9].get(); | |
218 item->SetState(DownloadItem::DownloadState::COMPLETE); | |
219 ItemObserver()->OnDownloadUpdated(item); | |
220 EXPECT_TRUE(job_data->IsComplete()); | |
136 } | 221 } |
137 | 222 |
138 } // namespace content | 223 } // namespace content |
OLD | NEW |