Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / update_client / crx_downloader_unittest.cc
blobb7551ed5cfc2569f0ad5bde24d76186d1304581f
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
3 // found in the LICENSE file.
5 #include "base/bind.h"
6 #include "base/bind_helpers.h"
7 #include "base/files/file_path.h"
8 #include "base/files/file_util.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/path_service.h"
12 #include "base/run_loop.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "components/update_client/crx_downloader.h"
15 #include "net/base/net_errors.h"
16 #include "net/url_request/test_url_request_interceptor.h"
17 #include "net/url_request/url_request_test_util.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 using base::ContentsEqual;
22 namespace update_client {
24 namespace {
26 // Intercepts HTTP GET requests sent to "localhost".
27 typedef net::LocalHostTestURLRequestInterceptor GetInterceptor;
29 const char kTestFileName[] = "jebgalgnebhfojomionfpkfelancnnkf.crx";
31 base::FilePath MakeTestFilePath(const char* file) {
32 base::FilePath path;
33 PathService::Get(base::DIR_SOURCE_ROOT, &path);
34 return path.AppendASCII("components")
35 .AppendASCII("test")
36 .AppendASCII("data")
37 .AppendASCII("update_client")
38 .AppendASCII(file);
41 } // namespace
43 class CrxDownloaderTest : public testing::Test {
44 public:
45 CrxDownloaderTest();
46 ~CrxDownloaderTest() override;
48 // Overrides from testing::Test.
49 void SetUp() override;
50 void TearDown() override;
52 void Quit();
53 void RunThreads();
54 void RunThreadsUntilIdle();
56 void DownloadComplete(int crx_context, const CrxDownloader::Result& result);
58 void DownloadProgress(int crx_context, const CrxDownloader::Result& result);
60 protected:
61 scoped_ptr<CrxDownloader> crx_downloader_;
63 scoped_ptr<GetInterceptor> get_interceptor_;
65 CrxDownloader::DownloadCallback callback_;
66 CrxDownloader::ProgressCallback progress_callback_;
68 int crx_context_;
70 int num_download_complete_calls_;
71 CrxDownloader::Result download_complete_result_;
73 // These members are updated by DownloadProgress.
74 int num_progress_calls_;
75 CrxDownloader::Result download_progress_result_;
77 // A magic value for the context to be used in the tests.
78 static const int kExpectedContext = 0xaabb;
80 private:
81 base::MessageLoopForIO loop_;
82 scoped_refptr<net::TestURLRequestContextGetter> context_;
83 base::Closure quit_closure_;
86 const int CrxDownloaderTest::kExpectedContext;
88 CrxDownloaderTest::CrxDownloaderTest()
89 : callback_(base::Bind(&CrxDownloaderTest::DownloadComplete,
90 base::Unretained(this),
91 kExpectedContext)),
92 progress_callback_(base::Bind(&CrxDownloaderTest::DownloadProgress,
93 base::Unretained(this),
94 kExpectedContext)),
95 crx_context_(0),
96 num_download_complete_calls_(0),
97 num_progress_calls_(0),
98 context_(new net::TestURLRequestContextGetter(
99 base::ThreadTaskRunnerHandle::Get())) {
102 CrxDownloaderTest::~CrxDownloaderTest() {
103 context_ = NULL;
105 // The GetInterceptor requires the message loop to run to destruct correctly.
106 get_interceptor_.reset();
107 RunThreadsUntilIdle();
110 void CrxDownloaderTest::SetUp() {
111 num_download_complete_calls_ = 0;
112 download_complete_result_ = CrxDownloader::Result();
113 num_progress_calls_ = 0;
114 download_progress_result_ = CrxDownloader::Result();
116 // Do not use the background downloader in these tests.
117 crx_downloader_.reset(
118 CrxDownloader::Create(false, context_.get(),
119 base::ThreadTaskRunnerHandle::Get(),
120 NULL).release());
121 crx_downloader_->set_progress_callback(progress_callback_);
123 get_interceptor_.reset(
124 new GetInterceptor(base::ThreadTaskRunnerHandle::Get(),
125 base::ThreadTaskRunnerHandle::Get()));
128 void CrxDownloaderTest::TearDown() {
129 crx_downloader_.reset();
132 void CrxDownloaderTest::Quit() {
133 if (!quit_closure_.is_null())
134 quit_closure_.Run();
137 void CrxDownloaderTest::DownloadComplete(int crx_context,
138 const CrxDownloader::Result& result) {
139 ++num_download_complete_calls_;
140 crx_context_ = crx_context;
141 download_complete_result_ = result;
142 Quit();
145 void CrxDownloaderTest::DownloadProgress(int crx_context,
146 const CrxDownloader::Result& result) {
147 ++num_progress_calls_;
148 download_progress_result_ = result;
151 void CrxDownloaderTest::RunThreads() {
152 base::RunLoop runloop;
153 quit_closure_ = runloop.QuitClosure();
154 runloop.Run();
156 // Since some tests need to drain currently enqueued tasks such as network
157 // intercepts on the IO thread, run the threads until they are
158 // idle. The component updater service won't loop again until the loop count
159 // is set and the service is started.
160 RunThreadsUntilIdle();
163 void CrxDownloaderTest::RunThreadsUntilIdle() {
164 base::RunLoop().RunUntilIdle();
167 // Tests that starting a download without a url results in an error.
168 TEST_F(CrxDownloaderTest, NoUrl) {
169 std::vector<GURL> urls;
170 crx_downloader_->StartDownload(urls, callback_);
171 RunThreadsUntilIdle();
173 EXPECT_EQ(1, num_download_complete_calls_);
174 EXPECT_EQ(kExpectedContext, crx_context_);
175 EXPECT_EQ(-1, download_complete_result_.error);
176 EXPECT_TRUE(download_complete_result_.response.empty());
177 EXPECT_EQ(-1, download_complete_result_.downloaded_bytes);
178 EXPECT_EQ(-1, download_complete_result_.total_bytes);
179 EXPECT_EQ(0, num_progress_calls_);
182 // Tests that downloading from one url is successful.
183 TEST_F(CrxDownloaderTest, OneUrl) {
184 const GURL expected_crx_url =
185 GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
187 const base::FilePath test_file(MakeTestFilePath(kTestFileName));
188 get_interceptor_->SetResponse(expected_crx_url, test_file);
190 crx_downloader_->StartDownloadFromUrl(expected_crx_url, callback_);
191 RunThreads();
193 EXPECT_EQ(1, get_interceptor_->GetHitCount());
195 EXPECT_EQ(1, num_download_complete_calls_);
196 EXPECT_EQ(kExpectedContext, crx_context_);
197 EXPECT_EQ(0, download_complete_result_.error);
198 EXPECT_EQ(1843, download_complete_result_.downloaded_bytes);
199 EXPECT_EQ(1843, download_complete_result_.total_bytes);
200 EXPECT_TRUE(ContentsEqual(download_complete_result_.response, test_file));
202 EXPECT_TRUE(base::DeleteFile(download_complete_result_.response, false));
204 EXPECT_LE(1, num_progress_calls_);
205 EXPECT_EQ(1843, download_progress_result_.downloaded_bytes);
206 EXPECT_EQ(1843, download_progress_result_.total_bytes);
209 // Tests that specifying from two urls has no side effects. Expect a successful
210 // download, and only one download request be made.
211 // This test is flaky on Android. crbug.com/329883
212 #if defined(OS_ANDROID)
213 #define MAYBE_TwoUrls DISABLED_TwoUrls
214 #else
215 #define MAYBE_TwoUrls TwoUrls
216 #endif
217 TEST_F(CrxDownloaderTest, MAYBE_TwoUrls) {
218 const GURL expected_crx_url =
219 GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
221 const base::FilePath test_file(MakeTestFilePath(kTestFileName));
222 get_interceptor_->SetResponse(expected_crx_url, test_file);
224 std::vector<GURL> urls;
225 urls.push_back(expected_crx_url);
226 urls.push_back(expected_crx_url);
228 crx_downloader_->StartDownload(urls, callback_);
229 RunThreads();
231 EXPECT_EQ(1, get_interceptor_->GetHitCount());
233 EXPECT_EQ(1, num_download_complete_calls_);
234 EXPECT_EQ(kExpectedContext, crx_context_);
235 EXPECT_EQ(0, download_complete_result_.error);
236 EXPECT_EQ(1843, download_complete_result_.downloaded_bytes);
237 EXPECT_EQ(1843, download_complete_result_.total_bytes);
238 EXPECT_TRUE(ContentsEqual(download_complete_result_.response, test_file));
240 EXPECT_TRUE(base::DeleteFile(download_complete_result_.response, false));
242 EXPECT_LE(1, num_progress_calls_);
243 EXPECT_EQ(1843, download_progress_result_.downloaded_bytes);
244 EXPECT_EQ(1843, download_progress_result_.total_bytes);
247 // Tests that an invalid host results in a download error.
248 TEST_F(CrxDownloaderTest, OneUrl_InvalidHost) {
249 const GURL expected_crx_url =
250 GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
252 const base::FilePath test_file(MakeTestFilePath(kTestFileName));
253 get_interceptor_->SetResponse(expected_crx_url, test_file);
255 crx_downloader_->StartDownloadFromUrl(
256 GURL(
257 "http://no.such.host"
258 "/download/jebgalgnebhfojomionfpkfelancnnkf.crx"),
259 callback_);
260 RunThreads();
262 EXPECT_EQ(0, get_interceptor_->GetHitCount());
264 EXPECT_EQ(1, num_download_complete_calls_);
265 EXPECT_EQ(kExpectedContext, crx_context_);
266 EXPECT_NE(0, download_complete_result_.error);
267 EXPECT_TRUE(download_complete_result_.response.empty());
270 // Tests that an invalid path results in a download error.
271 TEST_F(CrxDownloaderTest, OneUrl_InvalidPath) {
272 const GURL expected_crx_url =
273 GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
275 const base::FilePath test_file(MakeTestFilePath(kTestFileName));
276 get_interceptor_->SetResponse(expected_crx_url, test_file);
278 crx_downloader_->StartDownloadFromUrl(GURL("http://localhost/no/such/file"),
279 callback_);
280 RunThreads();
282 EXPECT_EQ(0, get_interceptor_->GetHitCount());
284 EXPECT_EQ(1, num_download_complete_calls_);
285 EXPECT_EQ(kExpectedContext, crx_context_);
286 EXPECT_NE(0, download_complete_result_.error);
287 EXPECT_TRUE(download_complete_result_.response.empty());
290 // Tests that the fallback to a valid url is successful.
291 // This test is flaky on Android. crbug.com/329883
292 #if defined(OS_ANDROID)
293 #define MAYBE_TwoUrls_FirstInvalid DISABLED_TwoUrls_FirstInvalid
294 #else
295 #define MAYBE_TwoUrls_FirstInvalid TwoUrls_FirstInvalid
296 #endif
297 TEST_F(CrxDownloaderTest, MAYBE_TwoUrls_FirstInvalid) {
298 const GURL expected_crx_url =
299 GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
301 const base::FilePath test_file(MakeTestFilePath(kTestFileName));
302 get_interceptor_->SetResponse(expected_crx_url, test_file);
304 std::vector<GURL> urls;
305 urls.push_back(GURL("http://localhost/no/such/file"));
306 urls.push_back(expected_crx_url);
308 crx_downloader_->StartDownload(urls, callback_);
309 RunThreads();
311 EXPECT_EQ(1, get_interceptor_->GetHitCount());
313 EXPECT_EQ(1, num_download_complete_calls_);
314 EXPECT_EQ(kExpectedContext, crx_context_);
315 EXPECT_EQ(0, download_complete_result_.error);
316 EXPECT_EQ(1843, download_complete_result_.downloaded_bytes);
317 EXPECT_EQ(1843, download_complete_result_.total_bytes);
318 EXPECT_TRUE(ContentsEqual(download_complete_result_.response, test_file));
320 EXPECT_TRUE(base::DeleteFile(download_complete_result_.response, false));
322 EXPECT_LE(1, num_progress_calls_);
323 EXPECT_EQ(1843, download_progress_result_.downloaded_bytes);
324 EXPECT_EQ(1843, download_progress_result_.total_bytes);
327 // Tests that the download succeeds if the first url is correct and the
328 // second bad url does not have a side-effect.
329 TEST_F(CrxDownloaderTest, TwoUrls_SecondInvalid) {
330 const GURL expected_crx_url =
331 GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
333 const base::FilePath test_file(MakeTestFilePath(kTestFileName));
334 get_interceptor_->SetResponse(expected_crx_url, test_file);
336 std::vector<GURL> urls;
337 urls.push_back(expected_crx_url);
338 urls.push_back(GURL("http://localhost/no/such/file"));
340 crx_downloader_->StartDownload(urls, callback_);
341 RunThreads();
343 EXPECT_EQ(1, get_interceptor_->GetHitCount());
345 EXPECT_EQ(1, num_download_complete_calls_);
346 EXPECT_EQ(kExpectedContext, crx_context_);
347 EXPECT_EQ(0, download_complete_result_.error);
348 EXPECT_EQ(1843, download_complete_result_.downloaded_bytes);
349 EXPECT_EQ(1843, download_complete_result_.total_bytes);
350 EXPECT_TRUE(ContentsEqual(download_complete_result_.response, test_file));
352 EXPECT_TRUE(base::DeleteFile(download_complete_result_.response, false));
354 EXPECT_LE(1, num_progress_calls_);
355 EXPECT_EQ(1843, download_progress_result_.downloaded_bytes);
356 EXPECT_EQ(1843, download_progress_result_.total_bytes);
359 // Tests that the download fails if both urls are bad.
360 TEST_F(CrxDownloaderTest, TwoUrls_BothInvalid) {
361 const GURL expected_crx_url =
362 GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
364 const base::FilePath test_file(MakeTestFilePath(kTestFileName));
365 get_interceptor_->SetResponse(expected_crx_url, test_file);
367 std::vector<GURL> urls;
368 urls.push_back(GURL("http://localhost/no/such/file"));
369 urls.push_back(GURL(
370 "http://no.such.host/"
371 "/download/jebgalgnebhfojomionfpkfelancnnkf.crx"));
373 crx_downloader_->StartDownload(urls, callback_);
374 RunThreads();
376 EXPECT_EQ(0, get_interceptor_->GetHitCount());
378 EXPECT_EQ(1, num_download_complete_calls_);
379 EXPECT_EQ(kExpectedContext, crx_context_);
380 EXPECT_NE(0, download_complete_result_.error);
381 EXPECT_TRUE(download_complete_result_.response.empty());
384 } // namespace update_client