Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / component_updater / test / crx_downloader_unittest.cc
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.
4
5 #include "base/bind.h"
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"
21
22 using content::BrowserThread;
23 using base::ContentsEqual;
24
25 namespace component_updater {
26
27 namespace {
28
29 // Intercepts HTTP GET requests sent to "localhost".
30 typedef content::URLLocalHostRequestPrepackagedInterceptor GetInterceptor;
31
32 const char kTestFileName[] = "jebgalgnebhfojomionfpkfelancnnkf.crx";
33
34 base::FilePath MakeTestFilePath(const char* file) {
35   base::FilePath path;
36   PathService::Get(chrome::DIR_TEST_DATA, &path);
37   return path.AppendASCII("components").AppendASCII(file);
38 }
39
40 }  // namespace
41
42 class CrxDownloaderTest : public testing::Test {
43  public:
44   CrxDownloaderTest();
45   virtual ~CrxDownloaderTest();
46
47   // Overrides from testing::Test.
48   virtual void SetUp() OVERRIDE;
49   virtual void TearDown() OVERRIDE;
50
51   void Quit();
52   void RunThreads();
53   void RunThreadsUntilIdle();
54
55   void DownloadComplete(int crx_context, const CrxDownloader::Result& result);
56
57   void DownloadProgress(int crx_context, const CrxDownloader::Result& result);
58
59  protected:
60   scoped_ptr<CrxDownloader> crx_downloader_;
61
62   CrxDownloader::DownloadCallback callback_;
63   CrxDownloader::ProgressCallback progress_callback_;
64
65   int crx_context_;
66
67   int num_download_complete_calls_;
68   CrxDownloader::Result download_complete_result_;
69
70   // These members are updated by DownloadProgress.
71   int num_progress_calls_;
72   CrxDownloader::Result download_progress_result_;
73
74   // A magic value for the context to be used in the tests.
75   static const int kExpectedContext = 0xaabb;
76
77  private:
78   scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
79   scoped_refptr<net::TestURLRequestContextGetter> context_;
80   content::TestBrowserThreadBundle thread_bundle_;
81   base::Closure quit_closure_;
82 };
83
84 const int CrxDownloaderTest::kExpectedContext;
85
86 CrxDownloaderTest::CrxDownloaderTest()
87     : callback_(base::Bind(&CrxDownloaderTest::DownloadComplete,
88                            base::Unretained(this),
89                            kExpectedContext)),
90       progress_callback_(base::Bind(&CrxDownloaderTest::DownloadProgress,
91                                     base::Unretained(this),
92                                     kExpectedContext)),
93       crx_context_(0),
94       num_download_complete_calls_(0),
95       num_progress_calls_(0),
96       blocking_task_runner_(BrowserThread::GetBlockingPool()->
97           GetSequencedTaskRunnerWithShutdownBehavior(
98               BrowserThread::GetBlockingPool()->GetSequenceToken(),
99               base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
100       context_(new net::TestURLRequestContextGetter(
101           BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO))),
102       thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {
103 }
104
105 CrxDownloaderTest::~CrxDownloaderTest() {
106   context_ = NULL;
107 }
108
109 void CrxDownloaderTest::SetUp() {
110   num_download_complete_calls_ = 0;
111   download_complete_result_ = CrxDownloader::Result();
112   num_progress_calls_ = 0;
113   download_progress_result_ = CrxDownloader::Result();
114   crx_downloader_.reset(CrxDownloader::Create(
115       false,  // Do not use the background downloader in these tests.
116       context_.get(),
117       blocking_task_runner_));
118   crx_downloader_->set_progress_callback(progress_callback_);
119 }
120
121 void CrxDownloaderTest::TearDown() {
122   crx_downloader_.reset();
123 }
124
125 void CrxDownloaderTest::Quit() {
126   if (!quit_closure_.is_null())
127     quit_closure_.Run();
128 }
129
130 void CrxDownloaderTest::DownloadComplete(int crx_context,
131                                          const CrxDownloader::Result& result) {
132   ++num_download_complete_calls_;
133   crx_context_ = crx_context;
134   download_complete_result_ = result;
135   Quit();
136 }
137
138 void CrxDownloaderTest::DownloadProgress(int crx_context,
139                                          const CrxDownloader::Result& result) {
140   ++num_progress_calls_;
141   download_progress_result_ = result;
142 }
143
144 void CrxDownloaderTest::RunThreads() {
145   base::RunLoop runloop;
146   quit_closure_ = runloop.QuitClosure();
147   runloop.Run();
148
149   // Since some tests need to drain currently enqueued tasks such as network
150   // intercepts on the IO thread, run the threads until they are
151   // idle. The component updater service won't loop again until the loop count
152   // is set and the service is started.
153   RunThreadsUntilIdle();
154 }
155
156 void CrxDownloaderTest::RunThreadsUntilIdle() {
157   base::RunLoop().RunUntilIdle();
158 }
159
160 // Tests that starting a download without a url results in an error.
161 TEST_F(CrxDownloaderTest, NoUrl) {
162   std::vector<GURL> urls;
163   crx_downloader_->StartDownload(urls, callback_);
164   RunThreadsUntilIdle();
165
166   EXPECT_EQ(1, num_download_complete_calls_);
167   EXPECT_EQ(kExpectedContext, crx_context_);
168   EXPECT_EQ(-1, download_complete_result_.error);
169   EXPECT_TRUE(download_complete_result_.response.empty());
170   EXPECT_EQ(-1, download_complete_result_.downloaded_bytes);
171   EXPECT_EQ(-1, download_complete_result_.total_bytes);
172   EXPECT_EQ(0, num_progress_calls_);
173 }
174
175 // Tests that downloading from one url is successful.
176 TEST_F(CrxDownloaderTest, OneUrl) {
177   const GURL expected_crx_url =
178       GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
179
180   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
181   GetInterceptor interceptor;
182   interceptor.SetResponse(expected_crx_url, test_file);
183
184   crx_downloader_->StartDownloadFromUrl(expected_crx_url, callback_);
185   RunThreads();
186
187   EXPECT_EQ(1, interceptor.GetHitCount());
188
189   EXPECT_EQ(1, num_download_complete_calls_);
190   EXPECT_EQ(kExpectedContext, crx_context_);
191   EXPECT_EQ(0, download_complete_result_.error);
192   EXPECT_EQ(1843, download_complete_result_.downloaded_bytes);
193   EXPECT_EQ(1843, download_complete_result_.total_bytes);
194   EXPECT_TRUE(ContentsEqual(download_complete_result_.response, test_file));
195
196   EXPECT_TRUE(base::DeleteFile(download_complete_result_.response, false));
197
198   EXPECT_LE(1, num_progress_calls_);
199   EXPECT_EQ(1843, download_progress_result_.downloaded_bytes);
200   EXPECT_EQ(1843, download_progress_result_.total_bytes);
201 }
202
203 // Tests that specifying from two urls has no side effects. Expect a successful
204 // download, and only one download request be made.
205 // This test is flaky on Android. crbug.com/329883
206 #if defined(OS_ANDROID)
207 #define MAYBE_TwoUrls DISABLED_TwoUrls
208 #else
209 #define MAYBE_TwoUrls TwoUrls
210 #endif
211 TEST_F(CrxDownloaderTest, MAYBE_TwoUrls) {
212   const GURL expected_crx_url =
213       GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
214
215   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
216   GetInterceptor interceptor;
217   interceptor.SetResponse(expected_crx_url, test_file);
218
219   std::vector<GURL> urls;
220   urls.push_back(expected_crx_url);
221   urls.push_back(expected_crx_url);
222
223   crx_downloader_->StartDownload(urls, callback_);
224   RunThreads();
225
226   EXPECT_EQ(1, interceptor.GetHitCount());
227
228   EXPECT_EQ(1, num_download_complete_calls_);
229   EXPECT_EQ(kExpectedContext, crx_context_);
230   EXPECT_EQ(0, download_complete_result_.error);
231   EXPECT_EQ(1843, download_complete_result_.downloaded_bytes);
232   EXPECT_EQ(1843, download_complete_result_.total_bytes);
233   EXPECT_TRUE(ContentsEqual(download_complete_result_.response, test_file));
234
235   EXPECT_TRUE(base::DeleteFile(download_complete_result_.response, false));
236
237   EXPECT_LE(1, num_progress_calls_);
238   EXPECT_EQ(1843, download_progress_result_.downloaded_bytes);
239   EXPECT_EQ(1843, download_progress_result_.total_bytes);
240 }
241
242 // Tests that an invalid host results in a download error.
243 TEST_F(CrxDownloaderTest, OneUrl_InvalidHost) {
244   const GURL expected_crx_url =
245       GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
246
247   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
248   GetInterceptor interceptor;
249   interceptor.SetResponse(expected_crx_url, test_file);
250
251   crx_downloader_->StartDownloadFromUrl(
252       GURL("http://no.such.host"
253            "/download/jebgalgnebhfojomionfpkfelancnnkf.crx"),
254       callback_);
255   RunThreads();
256
257   EXPECT_EQ(0, interceptor.GetHitCount());
258
259   EXPECT_EQ(1, num_download_complete_calls_);
260   EXPECT_EQ(kExpectedContext, crx_context_);
261   EXPECT_NE(0, download_complete_result_.error);
262   EXPECT_TRUE(download_complete_result_.response.empty());
263 }
264
265 // Tests that an invalid path results in a download error.
266 TEST_F(CrxDownloaderTest, OneUrl_InvalidPath) {
267   const GURL expected_crx_url =
268       GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
269
270   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
271   GetInterceptor interceptor;
272   interceptor.SetResponse(expected_crx_url, test_file);
273
274   crx_downloader_->StartDownloadFromUrl(GURL("http://localhost/no/such/file"),
275                                         callback_);
276   RunThreads();
277
278   EXPECT_EQ(0, interceptor.GetHitCount());
279
280   EXPECT_EQ(1, num_download_complete_calls_);
281   EXPECT_EQ(kExpectedContext, crx_context_);
282   EXPECT_NE(0, download_complete_result_.error);
283   EXPECT_TRUE(download_complete_result_.response.empty());
284 }
285
286 // Tests that the fallback to a valid url is successful.
287 // This test is flaky on Android. crbug.com/329883
288 #if defined(OS_ANDROID)
289 #define MAYBE_TwoUrls_FirstInvalid DISABLED_TwoUrls_FirstInvalid
290 #else
291 #define MAYBE_TwoUrls_FirstInvalid TwoUrls_FirstInvalid
292 #endif
293 TEST_F(CrxDownloaderTest, MAYBE_TwoUrls_FirstInvalid) {
294   const GURL expected_crx_url =
295       GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
296
297   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
298   GetInterceptor interceptor;
299   interceptor.SetResponse(expected_crx_url, test_file);
300
301   std::vector<GURL> urls;
302   urls.push_back(GURL("http://localhost/no/such/file"));
303   urls.push_back(expected_crx_url);
304
305   crx_downloader_->StartDownload(urls, callback_);
306   RunThreads();
307
308   EXPECT_EQ(1, interceptor.GetHitCount());
309
310   EXPECT_EQ(1, num_download_complete_calls_);
311   EXPECT_EQ(kExpectedContext, crx_context_);
312   EXPECT_EQ(0, download_complete_result_.error);
313   EXPECT_EQ(1843, download_complete_result_.downloaded_bytes);
314   EXPECT_EQ(1843, download_complete_result_.total_bytes);
315   EXPECT_TRUE(ContentsEqual(download_complete_result_.response, test_file));
316
317   EXPECT_TRUE(base::DeleteFile(download_complete_result_.response, false));
318
319   EXPECT_LE(1, num_progress_calls_);
320   EXPECT_EQ(1843, download_progress_result_.downloaded_bytes);
321   EXPECT_EQ(1843, download_progress_result_.total_bytes);
322 }
323
324 // Tests that the download succeeds if the first url is correct and the
325 // second bad url does not have a side-effect.
326 TEST_F(CrxDownloaderTest, TwoUrls_SecondInvalid) {
327   const GURL expected_crx_url =
328       GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
329
330   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
331   GetInterceptor interceptor;
332   interceptor.SetResponse(expected_crx_url, test_file);
333
334   std::vector<GURL> urls;
335   urls.push_back(expected_crx_url);
336   urls.push_back(GURL("http://localhost/no/such/file"));
337
338   crx_downloader_->StartDownload(urls, callback_);
339   RunThreads();
340
341   EXPECT_EQ(1, interceptor.GetHitCount());
342
343   EXPECT_EQ(1, num_download_complete_calls_);
344   EXPECT_EQ(kExpectedContext, crx_context_);
345   EXPECT_EQ(0, download_complete_result_.error);
346   EXPECT_EQ(1843, download_complete_result_.downloaded_bytes);
347   EXPECT_EQ(1843, download_complete_result_.total_bytes);
348   EXPECT_TRUE(ContentsEqual(download_complete_result_.response, test_file));
349
350   EXPECT_TRUE(base::DeleteFile(download_complete_result_.response, false));
351
352   EXPECT_LE(1, num_progress_calls_);
353   EXPECT_EQ(1843, download_progress_result_.downloaded_bytes);
354   EXPECT_EQ(1843, download_progress_result_.total_bytes);
355 }
356
357 // Tests that the download fails if both urls are bad.
358 TEST_F(CrxDownloaderTest, TwoUrls_BothInvalid) {
359   const GURL expected_crx_url =
360       GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
361
362   const base::FilePath test_file(MakeTestFilePath(kTestFileName));
363   GetInterceptor interceptor;
364   interceptor.SetResponse(expected_crx_url, test_file);
365
366   std::vector<GURL> urls;
367   urls.push_back(GURL("http://localhost/no/such/file"));
368   urls.push_back(GURL("http://no.such.host/"
369                       "/download/jebgalgnebhfojomionfpkfelancnnkf.crx"));
370
371   crx_downloader_->StartDownload(urls, callback_);
372   RunThreads();
373
374   EXPECT_EQ(0, interceptor.GetHitCount());
375
376   EXPECT_EQ(1, num_download_complete_calls_);
377   EXPECT_EQ(kExpectedContext, crx_context_);
378   EXPECT_NE(0, download_complete_result_.error);
379   EXPECT_TRUE(download_complete_result_.response.empty());
380 }
381
382 }  // namespace component_updater