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.
6 #include "base/file_util.h"
7 #include "base/files/file_path.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/path_service.h"
11 #include "base/run_loop.h"
12 #include "base/threading/sequenced_worker_pool.h"
13 #include "chrome/browser/component_updater/crx_downloader.h"
14 #include "chrome/common/chrome_paths.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/test/test_browser_thread_bundle.h"
17 #include "content/test/net/url_request_prepackaged_interceptor.h"
18 #include "net/base/net_errors.h"
19 #include "net/url_request/url_request_test_util.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 using content::BrowserThread
;
24 namespace component_updater
{
28 // Intercepts HTTP GET requests sent to "localhost".
29 typedef content::URLLocalHostRequestPrepackagedInterceptor GetInterceptor
;
31 base::FilePath
test_file(const char* file
) {
33 PathService::Get(chrome::DIR_TEST_DATA
, &path
);
34 return path
.AppendASCII("components").AppendASCII(file
);
39 class CrxDownloaderTest
: public testing::Test
{
42 virtual ~CrxDownloaderTest();
44 // Overrides from testing::Test.
45 virtual void SetUp() OVERRIDE
;
46 virtual void TearDown() OVERRIDE
;
50 void RunThreadsUntilIdle();
52 void DownloadComplete(int crx_context
, const CrxDownloader::Result
& result
);
55 scoped_ptr
<CrxDownloader
> crx_downloader_
;
59 base::FilePath response_
;
63 // A magic value for the context to be used in the tests.
64 static const int kExpectedContext
= 0xaabb;
67 scoped_refptr
<base::SequencedTaskRunner
> blocking_task_runner_
;
68 scoped_refptr
<net::TestURLRequestContextGetter
> context_
;
69 content::TestBrowserThreadBundle thread_bundle_
;
70 base::Closure quit_closure_
;
73 const int CrxDownloaderTest::kExpectedContext
;
75 CrxDownloaderTest::CrxDownloaderTest()
79 blocking_task_runner_(BrowserThread::GetBlockingPool()->
80 GetSequencedTaskRunnerWithShutdownBehavior(
81 BrowserThread::GetBlockingPool()->GetSequenceToken(),
82 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN
)),
83 context_(new net::TestURLRequestContextGetter(
84 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
))),
85 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP
) {
88 CrxDownloaderTest::~CrxDownloaderTest() {
92 void CrxDownloaderTest::SetUp() {
94 crx_downloader_
.reset(CrxDownloader::Create(
95 false, // Do not use the background downloader in these tests.
97 blocking_task_runner_
,
98 base::Bind(&CrxDownloaderTest::DownloadComplete
,
99 base::Unretained(this),
103 void CrxDownloaderTest::TearDown() {
106 void CrxDownloaderTest::Quit() {
107 if (!quit_closure_
.is_null())
111 void CrxDownloaderTest::DownloadComplete(
113 const CrxDownloader::Result
& result
) {
115 crx_context_
= crx_context
;
116 error_
= result
.error
;
117 response_
= result
.response
;
121 void CrxDownloaderTest::RunThreads() {
122 base::RunLoop runloop
;
123 quit_closure_
= runloop
.QuitClosure();
126 // Since some tests need to drain currently enqueued tasks such as network
127 // intercepts on the IO thread, run the threads until they are
128 // idle. The component updater service won't loop again until the loop count
129 // is set and the service is started.
130 RunThreadsUntilIdle();
133 void CrxDownloaderTest::RunThreadsUntilIdle() {
134 base::RunLoop().RunUntilIdle();
137 // Tests that starting a download without a url results in an error.
138 TEST_F(CrxDownloaderTest
, NoUrl
) {
139 std::vector
<GURL
> urls
;
140 crx_downloader_
->StartDownload(urls
);
142 RunThreadsUntilIdle();
143 EXPECT_EQ(-1, error_
);
144 EXPECT_EQ(kExpectedContext
, crx_context_
);
146 EXPECT_EQ(1, num_calls_
);
149 // Tests that downloading from one url is successful.
150 TEST_F(CrxDownloaderTest
, OneUrl
) {
151 const GURL expected_crx_url
=
152 GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
154 GetInterceptor interceptor
;
155 interceptor
.SetResponse(
157 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
159 crx_downloader_
->StartDownloadFromUrl(expected_crx_url
);
162 EXPECT_EQ(1, interceptor
.GetHitCount());
163 EXPECT_EQ(0, error_
);
164 EXPECT_EQ(kExpectedContext
, crx_context_
);
166 EXPECT_EQ(1, num_calls_
);
169 // Tests that specifying from two urls has no side effects. Expect a successful
170 // download, and only one download request be made.
171 TEST_F(CrxDownloaderTest
, TwoUrls
) {
172 const GURL expected_crx_url
=
173 GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
175 GetInterceptor interceptor
;
176 interceptor
.SetResponse(
178 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
180 std::vector
<GURL
> urls
;
181 urls
.push_back(expected_crx_url
);
182 urls
.push_back(expected_crx_url
);
184 crx_downloader_
->StartDownload(urls
);
187 EXPECT_EQ(1, interceptor
.GetHitCount());
188 EXPECT_EQ(0, error_
);
189 EXPECT_EQ(kExpectedContext
, crx_context_
);
191 EXPECT_EQ(1, num_calls_
);
194 // Tests that an invalid host results in a download error.
195 TEST_F(CrxDownloaderTest
, OneUrl_InvalidHost
) {
196 const GURL expected_crx_url
=
197 GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
199 GetInterceptor interceptor
;
200 interceptor
.SetResponse(
202 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
204 crx_downloader_
->StartDownloadFromUrl(
205 GURL("http://no.such.host"
206 "/download/jebgalgnebhfojomionfpkfelancnnkf.crx"));
209 EXPECT_EQ(0, interceptor
.GetHitCount());
210 EXPECT_NE(0, error_
);
211 EXPECT_EQ(kExpectedContext
, crx_context_
);
213 EXPECT_EQ(1, num_calls_
);
216 // Tests that an invalid path results in a download error.
217 TEST_F(CrxDownloaderTest
, OneUrl_InvalidPath
) {
218 const GURL expected_crx_url
=
219 GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
221 GetInterceptor interceptor
;
222 interceptor
.SetResponse(
224 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
226 crx_downloader_
->StartDownloadFromUrl(GURL("http://localhost/no/such/file"));
229 EXPECT_EQ(0, interceptor
.GetHitCount());
230 EXPECT_NE(0, error_
);
231 EXPECT_EQ(kExpectedContext
, crx_context_
);
233 EXPECT_EQ(1, num_calls_
);
236 // Tests that the fallback to a valid url is successful.
237 TEST_F(CrxDownloaderTest
, TwoUrls_FirstInvalid
) {
238 const GURL expected_crx_url
=
239 GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
241 GetInterceptor interceptor
;
242 interceptor
.SetResponse(
244 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
246 std::vector
<GURL
> urls
;
247 urls
.push_back(GURL("http://localhost/no/such/file"));
248 urls
.push_back(expected_crx_url
);
250 crx_downloader_
->StartDownload(urls
);
253 EXPECT_EQ(1, interceptor
.GetHitCount());
254 EXPECT_EQ(0, error_
);
255 EXPECT_EQ(kExpectedContext
, crx_context_
);
257 EXPECT_EQ(1, num_calls_
);
260 // Tests that the download succeeds if the first url is correct and the
261 // second bad url does not have a side-effect.
262 TEST_F(CrxDownloaderTest
, TwoUrls_SecondInvalid
) {
263 const GURL expected_crx_url
=
264 GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
266 GetInterceptor interceptor
;
267 interceptor
.SetResponse(
269 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
271 std::vector
<GURL
> urls
;
272 urls
.push_back(expected_crx_url
);
273 urls
.push_back(GURL("http://localhost/no/such/file"));
275 crx_downloader_
->StartDownload(urls
);
278 EXPECT_EQ(1, interceptor
.GetHitCount());
279 EXPECT_EQ(0, error_
);
280 EXPECT_EQ(kExpectedContext
, crx_context_
);
282 EXPECT_EQ(1, num_calls_
);
285 // Tests that the download fails if both urls are bad.
286 TEST_F(CrxDownloaderTest
, TwoUrls_BothInvalid
) {
287 const GURL expected_crx_url
=
288 GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
290 GetInterceptor interceptor
;
291 interceptor
.SetResponse(
293 test_file("jebgalgnebhfojomionfpkfelancnnkf.crx"));
295 std::vector
<GURL
> urls
;
296 urls
.push_back(GURL("http://localhost/no/such/file"));
297 urls
.push_back(GURL("http://no.such.host/"
298 "/download/jebgalgnebhfojomionfpkfelancnnkf.crx"));
300 crx_downloader_
->StartDownload(urls
);
303 EXPECT_EQ(0, interceptor
.GetHitCount());
304 EXPECT_NE(0, error_
);
305 EXPECT_EQ(kExpectedContext
, crx_context_
);
307 EXPECT_EQ(1, num_calls_
);
310 } // namespace component_updater