OLD | NEW |
| (Empty) |
1 // Copyright 2008-2010 Google Inc. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 // ======================================================================== | |
15 | |
16 // TODO(omaha): why so many dependencies for this unit test? | |
17 | |
18 #include <windows.h> | |
19 #include <atlstr.h> | |
20 #include "omaha/base/app_util.h" | |
21 #include "omaha/base/error.h" | |
22 #include "omaha/base/file.h" | |
23 #include "omaha/base/path.h" | |
24 #include "omaha/base/scoped_any.h" | |
25 #include "omaha/base/scoped_ptr_address.h" | |
26 #include "omaha/base/signatures.h" | |
27 #include "omaha/base/thread_pool.h" | |
28 #include "omaha/base/timer.h" | |
29 #include "omaha/base/utils.h" | |
30 #include "omaha/base/vistautil.h" | |
31 #include "omaha/base/vista_utils.h" | |
32 #include "omaha/common/config_manager.h" | |
33 #include "omaha/goopdate/app_state_checking_for_update.h" | |
34 #include "omaha/goopdate/app_state_waiting_to_download.h" | |
35 #include "omaha/goopdate/app_unittest_base.h" | |
36 #include "omaha/goopdate/download_manager.h" | |
37 #include "omaha/goopdate/update_response_utils.h" | |
38 #include "omaha/testing/unit_test.h" | |
39 | |
40 using ::testing::_; | |
41 using ::testing::Return; | |
42 | |
43 namespace omaha { | |
44 | |
45 namespace { | |
46 | |
47 const TCHAR kUpdateBinHash[] = _T("YF2z/br/S6E3KTca0MT7qziJN44="); | |
48 const TCHAR kUpdateBin1Hash[] = _T("tbYInfmArVRUD62Ex292vN4LtGQ="); | |
49 | |
50 const TCHAR kAppGuid1[] = _T("{0B35E146-D9CB-4145-8A91-43FDCAEBCD1E}"); | |
51 const TCHAR kAppGuid2[] = _T("{C7F2B395-A01C-4806-AA07-9163F66AFC48}"); | |
52 | |
53 | |
54 class DownloadAppWorkItem : public UserWorkItem { | |
55 public: | |
56 DownloadAppWorkItem(DownloadManager* download_manager, App* app) | |
57 : download_manager_(download_manager), app_(app) {} | |
58 | |
59 private: | |
60 virtual void DoProcess() { | |
61 download_manager_->DownloadApp(app_); | |
62 } | |
63 | |
64 DownloadManager* download_manager_; | |
65 App* app_; | |
66 | |
67 DISALLOW_EVIL_CONSTRUCTORS(DownloadAppWorkItem); | |
68 }; | |
69 | |
70 } // namespace | |
71 | |
72 class DownloadManagerTest : public AppTestBase { | |
73 public: | |
74 static HRESULT BuildUniqueFileName(const CString& filename, | |
75 CString* unique_filename) { | |
76 return DownloadManager::BuildUniqueFileName(filename, | |
77 unique_filename); | |
78 } | |
79 | |
80 protected: | |
81 explicit DownloadManagerTest(bool is_machine) | |
82 : AppTestBase(is_machine, true) {} | |
83 | |
84 virtual void SetUp() { | |
85 AppTestBase::SetUp(); | |
86 | |
87 CleanupFiles(); | |
88 | |
89 download_manager_.reset(new DownloadManager(is_machine_)); | |
90 EXPECT_SUCCEEDED(download_manager_->Initialize()); | |
91 } | |
92 | |
93 virtual void TearDown() { | |
94 download_manager_.reset(); | |
95 CleanupFiles(); | |
96 | |
97 AppTestBase::TearDown(); | |
98 } | |
99 | |
100 virtual void CleanupFiles() = 0; | |
101 | |
102 static HRESULT LoadBundleFromXml(AppBundle* app_bundle, | |
103 const CStringA& buffer_string) { | |
104 __mutexScope(app_bundle->model()->lock()); | |
105 | |
106 std::vector<uint8> buffer(buffer_string.GetLength()); | |
107 memcpy(&buffer.front(), buffer_string, buffer.size()); | |
108 | |
109 scoped_ptr<xml::UpdateResponse> update_response( | |
110 xml::UpdateResponse::Create()); | |
111 HRESULT hr = update_response->Deserialize(buffer); | |
112 if (FAILED(hr)) { | |
113 return hr; | |
114 } | |
115 | |
116 for (size_t i = 0; i != app_bundle->GetNumberOfApps(); ++i) { | |
117 hr = update_response_utils::BuildApp(update_response.get(), | |
118 S_OK, | |
119 app_bundle->GetApp(i)); | |
120 if (FAILED(hr)) { | |
121 return hr; | |
122 } | |
123 } | |
124 | |
125 return S_OK; | |
126 } | |
127 | |
128 static void SetAppStateCheckingForUpdate(App* app) { | |
129 SetAppStateForUnitTest(app, new fsm::AppStateCheckingForUpdate); | |
130 } | |
131 | |
132 static void SetAppStateWaitingToDownload(App* app) { | |
133 SetAppStateForUnitTest(app, new fsm::AppStateWaitingToDownload); | |
134 } | |
135 | |
136 const CString cache_path_; | |
137 scoped_ptr<DownloadManager> download_manager_; | |
138 }; | |
139 | |
140 | |
141 class DownloadManagerMachineTest : public DownloadManagerTest { | |
142 protected: | |
143 DownloadManagerMachineTest() : DownloadManagerTest(true) {} | |
144 | |
145 virtual void CleanupFiles() { | |
146 ConfigManager* cm(ConfigManager::Instance()); | |
147 DeleteDirectory(cm->GetMachineInstallWorkingDir()); | |
148 DeleteDirectory(cm->GetMachineSecureDownloadStorageDir()); | |
149 } | |
150 }; | |
151 | |
152 class DownloadManagerUserTest : public DownloadManagerTest { | |
153 protected: | |
154 DownloadManagerUserTest() : DownloadManagerTest(false) {} | |
155 | |
156 virtual void CleanupFiles() { | |
157 ConfigManager* cm(ConfigManager::Instance()); | |
158 DeleteDirectory(cm->GetUserInstallWorkingDir()); | |
159 DeleteDirectory(cm->GetUserDownloadStorageDir()); | |
160 } | |
161 }; | |
162 | |
163 TEST_F(DownloadManagerUserTest, DownloadApp_MultiplePackagesInOneApp) { | |
164 App* app = NULL; | |
165 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid1), &app)); | |
166 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("App1")))); | |
167 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_TRUE)); // Allow download. | |
168 | |
169 // One app, two packages. | |
170 CStringA buffer_string = | |
171 | |
172 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
173 "<response protocol=\"3.0\">" | |
174 "<app appid=\"{0B35E146-D9CB-4145-8A91-43FDCAEBCD1E}\" status=\"ok\">" | |
175 "<updatecheck status=\"ok\">" | |
176 "<urls>" | |
177 "<url codebase=\"http://dl.google.com/update2/\"/>" | |
178 "</urls>" | |
179 "<manifest version=\"1.0\">" | |
180 "<packages>" | |
181 "<package " | |
182 "hash=\"YF2z/br/S6E3KTca0MT7qziJN44=\" " | |
183 "name=\"UpdateData.bin\" " | |
184 "required=\"true\" " | |
185 "size=\"2048\"/>" | |
186 "<package " | |
187 "hash=\"tbYInfmArVRUD62Ex292vN4LtGQ=\" " | |
188 "name=\"UpdateData1.bin\" " | |
189 "required=\"true\" " | |
190 "size=\"2048\"/>" | |
191 "</packages>" | |
192 "</manifest>" | |
193 "</updatecheck>" | |
194 "</app>" | |
195 "</response>"; | |
196 | |
197 EXPECT_HRESULT_SUCCEEDED(LoadBundleFromXml(app_bundle_.get(), buffer_string)); | |
198 SetAppStateWaitingToDownload(app); | |
199 | |
200 EXPECT_SUCCEEDED(download_manager_->DownloadApp(app)); | |
201 | |
202 // Tests the first package. | |
203 const Package* package = app->next_version()->GetPackage(0); | |
204 ASSERT_TRUE(package); | |
205 EXPECT_STREQ(_T("UpdateData.bin"), package->filename()); | |
206 EXPECT_EQ(2048, package->expected_size()); | |
207 EXPECT_STREQ(kUpdateBinHash, package->expected_hash()); | |
208 EXPECT_EQ(2048, package->bytes_downloaded()); | |
209 EXPECT_TRUE(download_manager_->IsPackageAvailable(package)); | |
210 | |
211 // Tests the second package. | |
212 package = app->next_version()->GetPackage(1); | |
213 ASSERT_TRUE(package); | |
214 EXPECT_STREQ(_T("UpdateData1.bin"), package->filename()); | |
215 EXPECT_EQ(2048, package->expected_size()); | |
216 EXPECT_STREQ(kUpdateBin1Hash, package->expected_hash()); | |
217 EXPECT_EQ(2048, package->bytes_downloaded()); | |
218 EXPECT_TRUE(download_manager_->IsPackageAvailable(package)); | |
219 } | |
220 | |
221 // Downloads multiple apps serially. | |
222 TEST_F(DownloadManagerUserTest, DownloadApp_MultipleApps) { | |
223 App* app = NULL; | |
224 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid1), &app)); | |
225 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("App1")))); | |
226 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_TRUE)); // Allow download. | |
227 | |
228 app = NULL; | |
229 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid2), &app)); | |
230 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("App2")))); | |
231 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_TRUE)); // Allow download. | |
232 | |
233 // Two apps, one package each. | |
234 CStringA buffer_string = | |
235 | |
236 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
237 "<response protocol=\"3.0\">" | |
238 "<app appid=\"{0B35E146-D9CB-4145-8A91-43FDCAEBCD1E}\" status=\"ok\">" | |
239 "<updatecheck status=\"ok\">" | |
240 "<urls>" | |
241 "<url codebase=\"http://dl.google.com/update2/\"/>" | |
242 "</urls>" | |
243 "<manifest version=\"1.0\">" | |
244 "<packages>" | |
245 "<package " | |
246 "hash=\"YF2z/br/S6E3KTca0MT7qziJN44=\" " | |
247 "name=\"UpdateData.bin\" " | |
248 "required=\"true\" " | |
249 "size=\"2048\"/>" | |
250 "</packages>" | |
251 "</manifest>" | |
252 "</updatecheck>" | |
253 "</app>" | |
254 "<app appid=\"{C7F2B395-A01C-4806-AA07-9163F66AFC48}\" status=\"ok\">" | |
255 "<updatecheck status=\"ok\">" | |
256 "<urls>" | |
257 "<url codebase=\"http://dl.google.com/update2/\"/>" | |
258 "</urls>" | |
259 "<manifest version=\"2.0\">" | |
260 "<packages>" | |
261 "<package " | |
262 "hash=\"tbYInfmArVRUD62Ex292vN4LtGQ=\" " | |
263 "name=\"UpdateData1.bin\" " | |
264 "required=\"true\" " | |
265 "size=\"2048\"/>" | |
266 "</packages>" | |
267 "</manifest>" | |
268 "</updatecheck>" | |
269 "</app>" | |
270 "</response>"; | |
271 | |
272 EXPECT_HRESULT_SUCCEEDED(LoadBundleFromXml(app_bundle_.get(), buffer_string)); | |
273 | |
274 // Tests the first app. | |
275 app = app_bundle_->GetApp(0); | |
276 ASSERT_TRUE(app); | |
277 SetAppStateWaitingToDownload(app); | |
278 EXPECT_SUCCEEDED(download_manager_->DownloadApp(app)); | |
279 | |
280 const Package* package = app->next_version()->GetPackage(0); | |
281 ASSERT_TRUE(package); | |
282 EXPECT_STREQ(_T("UpdateData.bin"), package->filename()); | |
283 EXPECT_EQ(2048, package->expected_size()); | |
284 EXPECT_STREQ(kUpdateBinHash, package->expected_hash()); | |
285 EXPECT_EQ(2048, package->bytes_downloaded()); | |
286 EXPECT_TRUE(download_manager_->IsPackageAvailable(package)); | |
287 | |
288 // Tests the second app. | |
289 app = app_bundle_->GetApp(1); | |
290 ASSERT_TRUE(app); | |
291 SetAppStateWaitingToDownload(app); | |
292 EXPECT_SUCCEEDED(download_manager_->DownloadApp(app)); | |
293 | |
294 package = app->next_version()->GetPackage(0); | |
295 ASSERT_TRUE(package); | |
296 EXPECT_STREQ(_T("UpdateData1.bin"), package->filename()); | |
297 EXPECT_EQ(2048, package->expected_size()); | |
298 EXPECT_STREQ(kUpdateBin1Hash, package->expected_hash()); | |
299 EXPECT_EQ(2048, package->bytes_downloaded()); | |
300 EXPECT_TRUE(download_manager_->IsPackageAvailable(package)); | |
301 } | |
302 | |
303 // Downloads multiple apps concurrently. The test builds a bundle of two | |
304 // apps, creates two thread pool work items to download the apps, waits | |
305 // for the downloads to complete, and then checks the results of each download. | |
306 // This is essentialy the same unit test as DownloadApp_MultipleApps done | |
307 // concurrently instead of serially. | |
308 TEST_F(DownloadManagerUserTest, DownloadApp_Concurrent) { | |
309 App* app = NULL; | |
310 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid1), &app)); | |
311 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("App1")))); | |
312 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_TRUE)); // Allow download. | |
313 | |
314 app = NULL; | |
315 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid2), &app)); | |
316 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("App2")))); | |
317 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_TRUE)); // Allow download. | |
318 | |
319 // Two apps, one package each. | |
320 CStringA buffer_string = | |
321 | |
322 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
323 "<response protocol=\"3.0\">" | |
324 "<app appid=\"{0B35E146-D9CB-4145-8A91-43FDCAEBCD1E}\" status=\"ok\">" | |
325 "<updatecheck status=\"ok\">" | |
326 "<urls>" | |
327 "<url codebase=\"http://dl.google.com/update2/\"/>" | |
328 "</urls>" | |
329 "<manifest version=\"1.0\">" | |
330 "<packages>" | |
331 "<package " | |
332 "hash=\"YF2z/br/S6E3KTca0MT7qziJN44=\" " | |
333 "name=\"UpdateData.bin\" " | |
334 "required=\"true\" " | |
335 "size=\"2048\"/>" | |
336 "</packages>" | |
337 "</manifest>" | |
338 "</updatecheck>" | |
339 "</app>" | |
340 "<app appid=\"{C7F2B395-A01C-4806-AA07-9163F66AFC48}\" status=\"ok\">" | |
341 "<updatecheck status=\"ok\">" | |
342 "<urls>" | |
343 "<url codebase=\"http://dl.google.com/update2/\"/>" | |
344 "</urls>" | |
345 "<manifest version=\"2.0\">" | |
346 "<packages>" | |
347 "<package " | |
348 "hash=\"tbYInfmArVRUD62Ex292vN4LtGQ=\" " | |
349 "name=\"UpdateData1.bin\" " | |
350 "required=\"true\" " | |
351 "size=\"2048\"/>" | |
352 "</packages>" | |
353 "</manifest>" | |
354 "</updatecheck>" | |
355 "</app>" | |
356 "</response>"; | |
357 | |
358 EXPECT_HRESULT_SUCCEEDED(LoadBundleFromXml(app_bundle_.get(), buffer_string)); | |
359 | |
360 // The thread pool waits up to 1 minute for the work items to complete when | |
361 // the thread pool object is destroyed. | |
362 const int kShutdownDelayMs = 60000; | |
363 | |
364 ThreadPool thread_pool; | |
365 ASSERT_HRESULT_SUCCEEDED(thread_pool.Initialize(kShutdownDelayMs)); | |
366 | |
367 const int kNumApps = 2; | |
368 | |
369 for (int i = 0; i != kNumApps; ++i) { | |
370 app = app_bundle_->GetApp(i); | |
371 SetAppStateWaitingToDownload(app); | |
372 | |
373 scoped_ptr<DownloadAppWorkItem> work_item( | |
374 new DownloadAppWorkItem(download_manager_.get(), app)); | |
375 | |
376 // WT_EXECUTELONGFUNCTION causes the thread pool to use multiple threads. | |
377 ASSERT_HRESULT_SUCCEEDED(thread_pool.QueueUserWorkItem( | |
378 work_item.release(), | |
379 WT_EXECUTELONGFUNCTION)); | |
380 } | |
381 | |
382 // Poll the state of the download manager and wait up to 1 minute for the | |
383 // downloads to complete. | |
384 const int kTimeToWaitForDownloadsMs = 60000; | |
385 const int kTimeToSleepWhenPollingMs = 10; | |
386 | |
387 // Wait some time for the download manager to pick up the work items and | |
388 // become busy. | |
389 Timer timer(true); | |
390 while (timer.GetMilliseconds() < kTimeToWaitForDownloadsMs) { | |
391 if (download_manager_->IsBusy()) { | |
392 break; | |
393 } | |
394 } | |
395 timer.Reset(); | |
396 | |
397 // Wait for the download manager to exit its busy state. | |
398 timer.Start(); | |
399 while (download_manager_->IsBusy() && | |
400 timer.GetMilliseconds() < kTimeToWaitForDownloadsMs) { | |
401 ::Sleep(kTimeToSleepWhenPollingMs); | |
402 } | |
403 | |
404 // Expect that downloads have completed in a reasonable time. | |
405 EXPECT_FALSE(download_manager_->IsBusy()); | |
406 | |
407 // Test the outcome of the two downloads. | |
408 app = app_bundle_->GetApp(0); | |
409 const Package* package = app->next_version()->GetPackage(0); | |
410 ASSERT_TRUE(package); | |
411 EXPECT_STREQ(_T("UpdateData.bin"), package->filename()); | |
412 EXPECT_EQ(2048, package->expected_size()); | |
413 EXPECT_STREQ(kUpdateBinHash, package->expected_hash()); | |
414 EXPECT_EQ(2048, package->bytes_downloaded()); | |
415 EXPECT_TRUE(download_manager_->IsPackageAvailable(package)); | |
416 | |
417 app = app_bundle_->GetApp(1); | |
418 package = app->next_version()->GetPackage(0); | |
419 ASSERT_TRUE(package); | |
420 EXPECT_STREQ(_T("UpdateData1.bin"), package->filename()); | |
421 EXPECT_EQ(2048, package->expected_size()); | |
422 EXPECT_STREQ(kUpdateBin1Hash, package->expected_hash()); | |
423 EXPECT_EQ(2048, package->bytes_downloaded()); | |
424 EXPECT_TRUE(download_manager_->IsPackageAvailable(package)); | |
425 | |
426 // Try to cancel the downloads if they could not complete in time and the | |
427 // download manager is still busy. The thread pool waits a while for the work | |
428 // items to complete after they have been canceled. | |
429 if (download_manager_->IsBusy()) { | |
430 for (int i = 0; i != kNumApps; ++i) { | |
431 download_manager_->Cancel(app_bundle_->GetApp(i)); | |
432 } | |
433 return; | |
434 } | |
435 } | |
436 | |
437 // Downloads multiple apps concurrently and cancels the downloads while they | |
438 // are in progress. The test builds a bundle of two apps with one file each, | |
439 // creates two thread pool work items to download the apps, waits for the | |
440 // downloads to begin, and then cancels them. | |
441 // TODO(omaha): Fix the intermittent failures. | |
442 TEST_F(DownloadManagerUserTest, DISABLED_DownloadApp_Cancel) { | |
443 App* app = NULL; | |
444 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid1), &app)); | |
445 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("App1")))); | |
446 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_TRUE)); // Allow download. | |
447 | |
448 app = NULL; | |
449 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid2), &app)); | |
450 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("App2")))); | |
451 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_TRUE)); // Allow download. | |
452 | |
453 // Two apps, one package each. | |
454 CStringA buffer_string = | |
455 | |
456 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
457 "<response protocol=\"3.0\">" | |
458 "<app appid=\"{0B35E146-D9CB-4145-8A91-43FDCAEBCD1E}\" status=\"ok\">" | |
459 "<updatecheck status=\"ok\">" | |
460 "<urls>" | |
461 "<url codebase=\"http://dl.google.com/dl/edgedl/update2/\"/>" | |
462 "</urls>" | |
463 "<manifest version=\"1.0\">" | |
464 "<packages>" | |
465 "<package " | |
466 "hash=\"jCBqGodZn1Ms5oZ1U28LFUaQDXo=\" " | |
467 "name=\"UpdateData_10M.bin\" " | |
468 "required=\"true\" " | |
469 "size=\"10485760\"/>" | |
470 "</packages>" | |
471 "</manifest>" | |
472 "</updatecheck>" | |
473 "</app>" | |
474 "<app appid=\"{C7F2B395-A01C-4806-AA07-9163F66AFC48}\" status=\"ok\">" | |
475 "<updatecheck status=\"ok\">" | |
476 "<urls>" | |
477 "<url codebase=\"http://dl.google.com/dl/edgedl/update2/\"/>" | |
478 "</urls>" | |
479 "<manifest version=\"2.0\">" | |
480 "<packages>" | |
481 "<package " | |
482 "hash=\"jCBqGodZn1Ms5oZ1U28LFUaQDXo=\" " | |
483 "name=\"UpdateData_10M.bin\" " | |
484 "required=\"true\" " | |
485 "size=\"10485760\"/>" | |
486 "</packages>" | |
487 "</manifest>" | |
488 "</updatecheck>" | |
489 "</app>" | |
490 "</response>"; | |
491 | |
492 EXPECT_HRESULT_SUCCEEDED(LoadBundleFromXml(app_bundle_.get(), buffer_string)); | |
493 | |
494 // The thread pool waits up to 1 minute for the work items to complete when | |
495 // the thread pool object is destroyed. | |
496 const int kShutdownDelayMs = 60000; | |
497 | |
498 ThreadPool thread_pool; | |
499 ASSERT_HRESULT_SUCCEEDED(thread_pool.Initialize(kShutdownDelayMs)); | |
500 | |
501 const int kNumApps = 2; | |
502 | |
503 for (int i = 0; i != kNumApps; ++i) { | |
504 app = app_bundle_->GetApp(i); | |
505 SetAppStateWaitingToDownload(app); | |
506 | |
507 scoped_ptr<DownloadAppWorkItem> work_item( | |
508 new DownloadAppWorkItem(download_manager_.get(), app)); | |
509 | |
510 ASSERT_HRESULT_SUCCEEDED(thread_pool.QueueUserWorkItem( | |
511 work_item.release(), | |
512 WT_EXECUTELONGFUNCTION)); | |
513 } | |
514 | |
515 for (int i = 0; i != kNumApps; ++i) { | |
516 app = app_bundle_->GetApp(i); | |
517 EXPECT_NE(STATE_ERROR, app->state()); | |
518 } | |
519 | |
520 // Poll the state of the download manager and wait up to 1 minute for the | |
521 // downloads to complete. | |
522 const int kTimeToWaitForDownloadsMs = 60000; | |
523 const int kTimeToSleepWhenPollingMs = 10; | |
524 | |
525 // Cancel the downloads as soon as all apps are downloading and | |
526 // wait until all apps have transitioned in the error state. | |
527 Timer timer(true); | |
528 bool is_done = false; | |
529 while (!is_done && timer.GetMilliseconds() < kTimeToWaitForDownloadsMs) { | |
530 int num_apps_downloading = 0; | |
531 | |
532 for (int i = 0; i != kNumApps; ++i) { | |
533 app = app_bundle_->GetApp(i); | |
534 if (app->state() == STATE_DOWNLOADING) { | |
535 const Package* package = app->next_version()->GetPackage(0); | |
536 if (package->bytes_downloaded()) { | |
537 ++num_apps_downloading; | |
538 } | |
539 } | |
540 } | |
541 | |
542 is_done = (num_apps_downloading == kNumApps); | |
543 | |
544 ::Sleep(kTimeToSleepWhenPollingMs); | |
545 } | |
546 | |
547 for (int i = 0; i != kNumApps; ++i) { | |
548 download_manager_->Cancel(app_bundle_->GetApp(i)); | |
549 } | |
550 | |
551 is_done = false; | |
552 while (!is_done && timer.GetMilliseconds() < kTimeToWaitForDownloadsMs) { | |
553 int num_apps_cancelled = 0; | |
554 for (int i = 0; i != kNumApps; ++i) { | |
555 app = app_bundle_->GetApp(i); | |
556 if (app->state() == STATE_ERROR) { | |
557 ++num_apps_cancelled; | |
558 } | |
559 } | |
560 | |
561 is_done = (num_apps_cancelled == kNumApps); | |
562 | |
563 ::Sleep(kTimeToSleepWhenPollingMs); | |
564 } | |
565 | |
566 for (int i = 0; i != kNumApps; ++i) { | |
567 // Check the state of the app and the package after the cancel call. | |
568 app = app_bundle_->GetApp(i); | |
569 EXPECT_EQ(STATE_ERROR, app->state()); | |
570 | |
571 const Package* package = app->next_version()->GetPackage(0); | |
572 ASSERT_TRUE(package); | |
573 EXPECT_LT(0, package->bytes_downloaded()); | |
574 VARIANT_BOOL is_available(false); | |
575 EXPECT_HRESULT_SUCCEEDED(package->get_isAvailable(&is_available)); | |
576 EXPECT_FALSE(is_available); | |
577 | |
578 // Check CurrentAppState members. | |
579 CComPtr<IDispatch> current_state_disp; | |
580 EXPECT_HRESULT_SUCCEEDED(app->get_currentState(¤t_state_disp)); | |
581 CComPtr<ICurrentState> current_state; | |
582 EXPECT_HRESULT_SUCCEEDED( | |
583 current_state_disp->QueryInterface(¤t_state)); | |
584 | |
585 LONG state_value = 0; | |
586 EXPECT_HRESULT_SUCCEEDED(current_state->get_stateValue(&state_value)); | |
587 EXPECT_EQ(STATE_ERROR, static_cast<CurrentState>(state_value)); | |
588 | |
589 LONG error_code = 0; | |
590 EXPECT_HRESULT_SUCCEEDED(current_state->get_errorCode(&error_code)); | |
591 EXPECT_EQ(GOOPDATE_E_CANCELLED, error_code); | |
592 | |
593 LONG extra_code1 = 0; | |
594 EXPECT_HRESULT_SUCCEEDED(current_state->get_errorCode(&extra_code1)); | |
595 EXPECT_EQ(0, extra_code1); | |
596 } | |
597 } | |
598 | |
599 // Common packages of different apps are not cached by the package cache and | |
600 // will be redownloaded until the network cache is implemented. | |
601 // TODO(omaha): fix unit test as soon as the network cache is implemented. | |
602 TEST_F(DownloadManagerUserTest, DownloadApp_MultipleAppsCommonPackage) { | |
603 App* app = NULL; | |
604 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid1), &app)); | |
605 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("App1")))); | |
606 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_TRUE)); // Allow download. | |
607 | |
608 app = NULL; | |
609 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid2), &app)); | |
610 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("App2")))); | |
611 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_TRUE)); // Allow download. | |
612 | |
613 // Two apps, same package each. | |
614 CStringA buffer_string = | |
615 | |
616 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
617 "<response protocol=\"3.0\">" | |
618 "<app appid=\"{0B35E146-D9CB-4145-8A91-43FDCAEBCD1E}\" status=\"ok\">" | |
619 "<updatecheck status=\"ok\">" | |
620 "<urls>" | |
621 "<url codebase=\"http://dl.google.com/update2/\"/>" | |
622 "</urls>" | |
623 "<manifest version=\"1.0\">" | |
624 "<packages>" | |
625 "<package " | |
626 "hash=\"YF2z/br/S6E3KTca0MT7qziJN44=\" " | |
627 "name=\"UpdateData.bin\" " | |
628 "required=\"true\" " | |
629 "size=\"2048\"/>" | |
630 "</packages>" | |
631 "</manifest>" | |
632 "</updatecheck>" | |
633 "</app>" | |
634 "<app appid=\"{C7F2B395-A01C-4806-AA07-9163F66AFC48}\" status=\"ok\">" | |
635 "<updatecheck status=\"ok\">" | |
636 "<urls>" | |
637 "<url codebase=\"http://dl.google.com/update2/\"/>" | |
638 "</urls>" | |
639 "<manifest version=\"2.0\">" | |
640 "<packages>" | |
641 "<package " | |
642 "hash=\"YF2z/br/S6E3KTca0MT7qziJN44=\" " | |
643 "name=\"UpdateData.bin\" " | |
644 "required=\"true\" " | |
645 "size=\"2048\"/>" | |
646 "</packages>" | |
647 "</manifest>" | |
648 "</updatecheck>" | |
649 "</app>" | |
650 "</response>"; | |
651 | |
652 EXPECT_HRESULT_SUCCEEDED(LoadBundleFromXml(app_bundle_.get(), buffer_string)); | |
653 | |
654 // Tests the first app. | |
655 app = app_bundle_->GetApp(0); | |
656 ASSERT_TRUE(app); | |
657 SetAppStateWaitingToDownload(app); | |
658 EXPECT_SUCCEEDED(download_manager_->DownloadApp(app)); | |
659 | |
660 const Package* package = app->next_version()->GetPackage(0); | |
661 ASSERT_TRUE(package); | |
662 EXPECT_STREQ(_T("UpdateData.bin"), package->filename()); | |
663 EXPECT_EQ(2048, package->expected_size()); | |
664 EXPECT_STREQ(kUpdateBinHash, package->expected_hash()); | |
665 EXPECT_EQ(2048, package->bytes_downloaded()); | |
666 EXPECT_TRUE(download_manager_->IsPackageAvailable(package)); | |
667 | |
668 // Tests the second app. The package is redownloaded. | |
669 app = app_bundle_->GetApp(1); | |
670 ASSERT_TRUE(app); | |
671 SetAppStateWaitingToDownload(app); | |
672 EXPECT_SUCCEEDED(download_manager_->DownloadApp(app)); | |
673 | |
674 package = app->next_version()->GetPackage(0); | |
675 ASSERT_TRUE(package); | |
676 EXPECT_STREQ(_T("UpdateData.bin"), package->filename()); | |
677 EXPECT_EQ(2048, package->expected_size()); | |
678 EXPECT_STREQ(kUpdateBinHash, package->expected_hash()); | |
679 EXPECT_EQ(2048, package->bytes_downloaded()); | |
680 EXPECT_TRUE(download_manager_->IsPackageAvailable(package)); | |
681 } | |
682 | |
683 // Creates two bundles with the same app. The package corresponding to the | |
684 // app in the second bundle must come from the cache. | |
685 TEST_F(DownloadManagerUserTest, DownloadApp_FileAlreadyInCache) { | |
686 App* app = NULL; | |
687 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid1), &app)); | |
688 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("App1")))); | |
689 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_TRUE)); // Allow download. | |
690 | |
691 CStringA buffer_string = | |
692 | |
693 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
694 "<response protocol=\"3.0\">" | |
695 "<app appid=\"{0B35E146-D9CB-4145-8A91-43FDCAEBCD1E}\" status=\"ok\">" | |
696 "<updatecheck status=\"ok\">" | |
697 "<urls>" | |
698 "<url codebase=\"http://dl.google.com/update2/\"/>" | |
699 "</urls>" | |
700 "<manifest version=\"1.0\">" | |
701 "<packages>" | |
702 "<package " | |
703 "hash=\"YF2z/br/S6E3KTca0MT7qziJN44=\" " | |
704 "name=\"UpdateData.bin\" " | |
705 "required=\"true\" " | |
706 "size=\"2048\"/>" | |
707 "</packages>" | |
708 "</manifest>" | |
709 "</updatecheck>" | |
710 "</app>" | |
711 "</response>"; | |
712 | |
713 EXPECT_HRESULT_SUCCEEDED(LoadBundleFromXml(app_bundle_.get(), buffer_string)); | |
714 SetAppStateWaitingToDownload(app); | |
715 | |
716 EXPECT_SUCCEEDED(download_manager_->DownloadApp(app)); | |
717 | |
718 // Tests the package and the bytes downloaded. | |
719 const Package* package = app->next_version()->GetPackage(0); | |
720 ASSERT_TRUE(package); | |
721 EXPECT_STREQ(_T("UpdateData.bin"), package->filename()); | |
722 EXPECT_EQ(2048, package->expected_size()); | |
723 EXPECT_STREQ(kUpdateBinHash, package->expected_hash()); | |
724 EXPECT_EQ(2048, package->bytes_downloaded()); | |
725 EXPECT_TRUE(download_manager_->IsPackageAvailable(package)); | |
726 | |
727 // Create the second app bundle. | |
728 shared_ptr<AppBundle> app_bundle2(model_->CreateAppBundle(false)); | |
729 EXPECT_SUCCEEDED(app_bundle2->put_displayName(CComBSTR(_T("My Bundle")))); | |
730 EXPECT_SUCCEEDED(app_bundle2->put_displayLanguage(CComBSTR(_T("en")))); | |
731 EXPECT_SUCCEEDED(app_bundle2->initialize()); | |
732 | |
733 app = NULL; | |
734 ASSERT_SUCCEEDED(app_bundle2->createApp(CComBSTR(kAppGuid1), &app)); | |
735 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("App1")))); | |
736 // Since the package is cached, it does not matter if the EULA is accepted. | |
737 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_FALSE)); | |
738 | |
739 EXPECT_HRESULT_SUCCEEDED(LoadBundleFromXml(app_bundle2.get(), buffer_string)); | |
740 SetAppStateWaitingToDownload(app); | |
741 | |
742 EXPECT_SUCCEEDED(download_manager_->DownloadApp(app)); | |
743 | |
744 // Tests the package and the bytes downloaded. | |
745 package = app->next_version()->GetPackage(0); | |
746 ASSERT_TRUE(package); | |
747 EXPECT_STREQ(_T("UpdateData.bin"), package->filename()); | |
748 EXPECT_EQ(2048, package->expected_size()); | |
749 EXPECT_STREQ(kUpdateBinHash, package->expected_hash()); | |
750 | |
751 // No bytes are downloaded if the package has been cached already. | |
752 EXPECT_EQ(0, package->bytes_downloaded()); | |
753 EXPECT_TRUE(download_manager_->IsPackageAvailable(package)); | |
754 } | |
755 | |
756 TEST_F(DownloadManagerUserTest, DownloadApp_404) { | |
757 App* app = NULL; | |
758 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid1), &app)); | |
759 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("404 Test")))); | |
760 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_TRUE)); // Allow download. | |
761 | |
762 CStringA buffer_string = | |
763 | |
764 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
765 "<response protocol=\"3.0\">" | |
766 "<app appid=\"{0B35E146-D9CB-4145-8A91-43FDCAEBCD1E}\" status=\"ok\">" | |
767 "<updatecheck status=\"ok\">" | |
768 "<urls>" | |
769 "<url codebase=\"http://dl.google.com/update2/\"/>" | |
770 "</urls>" | |
771 "<manifest version=\"1.0\">" | |
772 "<packages>" | |
773 "<package " | |
774 "hash=\"YF2z/br/S6E3KTca0MT7qziJN44=\" " | |
775 "name=\"NoSuchFile-OmahaTest.exe\" " | |
776 "required=\"true\" " | |
777 "size=\"2048\"/>" | |
778 "</packages>" | |
779 "</manifest>" | |
780 "</updatecheck>" | |
781 "</app>" | |
782 "</response>"; | |
783 | |
784 EXPECT_HRESULT_SUCCEEDED(LoadBundleFromXml(app_bundle_.get(), buffer_string)); | |
785 SetAppStateWaitingToDownload(app); | |
786 | |
787 EXPECT_EQ(GOOPDATE_E_NETWORK_FIRST + 404, | |
788 download_manager_->DownloadApp(app)); | |
789 | |
790 const Package* package = app->next_version()->GetPackage(0); | |
791 ASSERT_TRUE(package); | |
792 EXPECT_STREQ(_T("NoSuchFile-OmahaTest.exe"), package->filename()); | |
793 EXPECT_EQ(2048, package->expected_size()); | |
794 EXPECT_STREQ(kUpdateBinHash, package->expected_hash()); | |
795 EXPECT_EQ(0, package->bytes_downloaded()); | |
796 EXPECT_FALSE(download_manager_->IsPackageAvailable(package)); | |
797 } | |
798 | |
799 TEST_F(DownloadManagerUserTest, DownloadApp_HashFailure) { | |
800 App* app = NULL; | |
801 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid1), &app)); | |
802 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("Hash Fail")))); | |
803 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_TRUE)); // Allow download. | |
804 | |
805 // Provides the wrong hash for the package. | |
806 CStringA buffer_string = | |
807 | |
808 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
809 "<response protocol=\"3.0\">" | |
810 "<app appid=\"{0B35E146-D9CB-4145-8A91-43FDCAEBCD1E}\" status=\"ok\">" | |
811 "<updatecheck status=\"ok\">" | |
812 "<urls>" | |
813 "<url codebase=\"http://dl.google.com/update2/\"/>" | |
814 "</urls>" | |
815 "<manifest version=\"1.0\">" | |
816 "<packages>" | |
817 "<package " | |
818 "hash=\"tbYInfmArVRUD62Ex292vN4LtGQ=\" " | |
819 "name=\"UpdateData.bin\" " | |
820 "required=\"true\" " | |
821 "size=\"2048\"/>" | |
822 "</packages>" | |
823 "</manifest>" | |
824 "</updatecheck>" | |
825 "</app>" | |
826 "</response>"; | |
827 | |
828 EXPECT_HRESULT_SUCCEEDED(LoadBundleFromXml(app_bundle_.get(), buffer_string)); | |
829 SetAppStateWaitingToDownload(app); | |
830 | |
831 EXPECT_EQ(SIGS_E_INVALID_SIGNATURE, | |
832 download_manager_->DownloadApp(app)); | |
833 | |
834 const Package* package = app->next_version()->GetPackage(0); | |
835 ASSERT_TRUE(package); | |
836 EXPECT_STREQ(_T("UpdateData.bin"), package->filename()); | |
837 EXPECT_EQ(2048, package->expected_size()); | |
838 EXPECT_STREQ(kUpdateBin1Hash, package->expected_hash()); | |
839 EXPECT_EQ(2048, package->bytes_downloaded()); | |
840 EXPECT_FALSE(download_manager_->IsPackageAvailable(package)); | |
841 | |
842 // All bytes were downloaded even if the validation of the file has failed. | |
843 EXPECT_EQ(2048, package->bytes_downloaded()); | |
844 } | |
845 | |
846 TEST_F(DownloadManagerUserTest, DownloadApp_HashFailure_ActualSmaller) { | |
847 App* app = NULL; | |
848 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid1), &app)); | |
849 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("Hash Fail")))); | |
850 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_TRUE)); // Allow download. | |
851 | |
852 // Provides the wrong hash for the package. | |
853 CStringA buffer_string = | |
854 | |
855 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
856 "<response protocol=\"3.0\">" | |
857 "<app appid=\"{0B35E146-D9CB-4145-8A91-43FDCAEBCD1E}\" status=\"ok\">" | |
858 "<updatecheck status=\"ok\">" | |
859 "<urls>" | |
860 "<url codebase=\"http://dl.google.com/update2/\"/>" | |
861 "</urls>" | |
862 "<manifest version=\"1.0\">" | |
863 "<packages>" | |
864 "<package " | |
865 "hash=\"tbYInfmArVRUD62Ex292vN4LtGQ=\" " | |
866 "name=\"UpdateData.bin\" " | |
867 "required=\"true\" " | |
868 "size=\"2048000\"/>" | |
869 "</packages>" | |
870 "</manifest>" | |
871 "</updatecheck>" | |
872 "</app>" | |
873 "</response>"; | |
874 | |
875 EXPECT_HRESULT_SUCCEEDED(LoadBundleFromXml(app_bundle_.get(), buffer_string)); | |
876 SetAppStateWaitingToDownload(app); | |
877 | |
878 EXPECT_EQ(GOOPDATEDOWNLOAD_E_FILE_SIZE_SMALLER, | |
879 download_manager_->DownloadApp(app)); | |
880 | |
881 const Package* package = app->next_version()->GetPackage(0); | |
882 ASSERT_TRUE(package); | |
883 EXPECT_STREQ(_T("UpdateData.bin"), package->filename()); | |
884 EXPECT_EQ(2048000, package->expected_size()); | |
885 EXPECT_STREQ(kUpdateBin1Hash, package->expected_hash()); | |
886 EXPECT_EQ(2048, package->bytes_downloaded()); | |
887 EXPECT_FALSE(download_manager_->IsPackageAvailable(package)); | |
888 | |
889 // Actual bytes were downloaded even if the validation of the file has failed. | |
890 EXPECT_EQ(2048, package->bytes_downloaded()); | |
891 } | |
892 | |
893 TEST_F(DownloadManagerUserTest, DownloadApp_HashFailure_ActualLarger) { | |
894 App* app = NULL; | |
895 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid1), &app)); | |
896 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("Hash Fail")))); | |
897 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_TRUE)); // Allow download. | |
898 | |
899 // Provides the wrong hash for the package. | |
900 CStringA buffer_string = | |
901 | |
902 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
903 "<response protocol=\"3.0\">" | |
904 "<app appid=\"{0B35E146-D9CB-4145-8A91-43FDCAEBCD1E}\" status=\"ok\">" | |
905 "<updatecheck status=\"ok\">" | |
906 "<urls>" | |
907 "<url codebase=\"http://dl.google.com/update2/\"/>" | |
908 "</urls>" | |
909 "<manifest version=\"1.0\">" | |
910 "<packages>" | |
911 "<package " | |
912 "hash=\"tbYInfmArVRUD62Ex292vN4LtGQ=\" " | |
913 "name=\"UpdateData.bin\" " | |
914 "required=\"true\" " | |
915 "size=\"20\"/>" | |
916 "</packages>" | |
917 "</manifest>" | |
918 "</updatecheck>" | |
919 "</app>" | |
920 "</response>"; | |
921 | |
922 EXPECT_HRESULT_SUCCEEDED(LoadBundleFromXml(app_bundle_.get(), buffer_string)); | |
923 SetAppStateWaitingToDownload(app); | |
924 | |
925 EXPECT_EQ(GOOPDATEDOWNLOAD_E_FILE_SIZE_LARGER, | |
926 download_manager_->DownloadApp(app)); | |
927 | |
928 const Package* package = app->next_version()->GetPackage(0); | |
929 ASSERT_TRUE(package); | |
930 EXPECT_STREQ(_T("UpdateData.bin"), package->filename()); | |
931 EXPECT_EQ(20, package->expected_size()); | |
932 EXPECT_STREQ(kUpdateBin1Hash, package->expected_hash()); | |
933 EXPECT_EQ(2048, package->bytes_downloaded()); | |
934 EXPECT_FALSE(download_manager_->IsPackageAvailable(package)); | |
935 | |
936 // Actual bytes were downloaded even if the validation of the file has failed | |
937 // or expected a smaller file. | |
938 EXPECT_EQ(2048, package->bytes_downloaded()); | |
939 } | |
940 | |
941 TEST_F(DownloadManagerUserTest, DownloadApp_BaseUrlFallback) { | |
942 App* app = NULL; | |
943 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid1), &app)); | |
944 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("Hash Fail")))); | |
945 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_TRUE)); // Allow download. | |
946 | |
947 // Provides the wrong hash for the package. | |
948 CStringA buffer_string = | |
949 | |
950 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
951 "<response protocol=\"3.0\">" | |
952 "<app appid=\"{0B35E146-D9CB-4145-8A91-43FDCAEBCD1E}\" status=\"ok\">" | |
953 "<updatecheck status=\"ok\">" | |
954 "<urls>" | |
955 "<url codebase=\"http://dl.google.com/update2/TEST_NOT_EXIST/\"/>" | |
956 "<url codebase=\"http://dl.google.com/update2/\"/>" | |
957 "</urls>" | |
958 "<manifest version=\"1.0\">" | |
959 "<packages>" | |
960 "<package " | |
961 "hash=\"YF2z/br/S6E3KTca0MT7qziJN44=\" " | |
962 "name=\"UpdateData.bin\" " | |
963 "required=\"true\" " | |
964 "size=\"2048\"/>" | |
965 "</packages>" | |
966 "</manifest>" | |
967 "</updatecheck>" | |
968 "</app>" | |
969 "</response>"; | |
970 | |
971 EXPECT_HRESULT_SUCCEEDED(LoadBundleFromXml(app_bundle_.get(), buffer_string)); | |
972 SetAppStateWaitingToDownload(app); | |
973 | |
974 EXPECT_SUCCEEDED(download_manager_->DownloadApp(app)); | |
975 const Package* package = app->next_version()->GetPackage(0); | |
976 ASSERT_TRUE(package); | |
977 EXPECT_STREQ(_T("UpdateData.bin"), package->filename()); | |
978 EXPECT_EQ(2048, package->expected_size()); | |
979 EXPECT_STREQ(kUpdateBinHash, package->expected_hash()); | |
980 EXPECT_EQ(2048, package->bytes_downloaded()); | |
981 EXPECT_TRUE(download_manager_->IsPackageAvailable(package)); | |
982 } | |
983 | |
984 TEST_F(DownloadManagerUserTest, DownloadApp_FallbackToNextUrlIfCachingFails) { | |
985 App* app = NULL; | |
986 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid1), &app)); | |
987 EXPECT_SUCCEEDED( | |
988 app->put_displayName(CComBSTR(_T("Hash Fails For First Url")))); | |
989 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_TRUE)); // Allow download. | |
990 | |
991 // First URL points to a corrupted file. | |
992 CStringA buffer_string = | |
993 | |
994 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
995 "<response protocol=\"3.0\">" | |
996 "<app appid=\"{0B35E146-D9CB-4145-8A91-43FDCAEBCD1E}\" status=\"ok\">" | |
997 "<updatecheck status=\"ok\">" | |
998 "<urls>" | |
999 "<url codebase=\"http://dl.google.com/update2/test/fakedata/\"/>" | |
1000 "<url codebase=\"http://dl.google.com/update2/\"/>" | |
1001 "</urls>" | |
1002 "<manifest version=\"1.0\">" | |
1003 "<packages>" | |
1004 "<package " | |
1005 "hash=\"YF2z/br/S6E3KTca0MT7qziJN44=\" " | |
1006 "name=\"UpdateData.bin\" " | |
1007 "required=\"true\" " | |
1008 "size=\"2048\"/>" | |
1009 "</packages>" | |
1010 "</manifest>" | |
1011 "</updatecheck>" | |
1012 "</app>" | |
1013 "</response>"; | |
1014 | |
1015 EXPECT_HRESULT_SUCCEEDED(LoadBundleFromXml(app_bundle_.get(), buffer_string)); | |
1016 SetAppStateWaitingToDownload(app); | |
1017 | |
1018 EXPECT_SUCCEEDED(download_manager_->DownloadApp(app)); | |
1019 const Package* package = app->next_version()->GetPackage(0); | |
1020 ASSERT_TRUE(package); | |
1021 EXPECT_STREQ(_T("UpdateData.bin"), package->filename()); | |
1022 EXPECT_EQ(2048, package->expected_size()); | |
1023 EXPECT_STREQ(kUpdateBinHash, package->expected_hash()); | |
1024 EXPECT_EQ(2048, package->bytes_downloaded()); | |
1025 EXPECT_TRUE(download_manager_->IsPackageAvailable(package)); | |
1026 } | |
1027 | |
1028 TEST_F(DownloadManagerUserTest, DownloadApp_EulaNotAccepted) { | |
1029 App* app = NULL; | |
1030 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid1), &app)); | |
1031 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("App1")))); | |
1032 | |
1033 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_FALSE)); | |
1034 | |
1035 CStringA buffer_string = | |
1036 | |
1037 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
1038 "<response protocol=\"3.0\">" | |
1039 "<app appid=\"{0B35E146-D9CB-4145-8A91-43FDCAEBCD1E}\" status=\"ok\">" | |
1040 "<updatecheck status=\"ok\">" | |
1041 "<urls>" | |
1042 "<url codebase=\"http://dl.google.com/update2/\"/>" | |
1043 "</urls>" | |
1044 "<manifest version=\"1.0\">" | |
1045 "<packages>" | |
1046 "<package " | |
1047 "hash=\"YF2z/br/S6E3KTca0MT7qziJN44=\" " | |
1048 "name=\"UpdateData.bin\" " | |
1049 "required=\"true\" " | |
1050 "size=\"2048\"/>" | |
1051 "</packages>" | |
1052 "</manifest>" | |
1053 "</updatecheck>" | |
1054 "</app>" | |
1055 "</response>"; | |
1056 | |
1057 EXPECT_HRESULT_SUCCEEDED(LoadBundleFromXml(app_bundle_.get(), buffer_string)); | |
1058 SetAppStateWaitingToDownload(app); | |
1059 | |
1060 ExpectAsserts expect_asserts; // Eula not accepted causes asserts. | |
1061 | |
1062 EXPECT_EQ(GOOPDATE_E_APP_UPDATE_DISABLED_EULA_NOT_ACCEPTED, | |
1063 download_manager_->DownloadApp(app)); | |
1064 | |
1065 const Package* package = app->next_version()->GetPackage(0); | |
1066 ASSERT_TRUE(package); | |
1067 EXPECT_STREQ(_T("UpdateData.bin"), package->filename()); | |
1068 EXPECT_EQ(2048, package->expected_size()); | |
1069 EXPECT_STREQ(kUpdateBinHash, package->expected_hash()); | |
1070 EXPECT_EQ(0, package->bytes_downloaded()); | |
1071 EXPECT_FALSE(download_manager_->IsPackageAvailable(package)); | |
1072 } | |
1073 | |
1074 TEST_F(DownloadManagerUserTest, GetPackage) { | |
1075 App* app = NULL; | |
1076 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid1), &app)); | |
1077 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("App1")))); | |
1078 EXPECT_SUCCEEDED(app->put_isEulaAccepted(VARIANT_TRUE)); // Allow download. | |
1079 | |
1080 // One app, one package. | |
1081 CStringA buffer_string = | |
1082 | |
1083 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
1084 "<response protocol=\"3.0\">" | |
1085 "<app appid=\"{0B35E146-D9CB-4145-8A91-43FDCAEBCD1E}\" status=\"ok\">" | |
1086 "<updatecheck status=\"ok\">" | |
1087 "<urls>" | |
1088 "<url codebase=\"http://dl.google.com/update2/\"/>" | |
1089 "</urls>" | |
1090 "<manifest version=\"1.0\">" | |
1091 "<packages>" | |
1092 "<package " | |
1093 "hash=\"YF2z/br/S6E3KTca0MT7qziJN44=\" " | |
1094 "name=\"UpdateData.bin\" " | |
1095 "required=\"true\" " | |
1096 "size=\"2048\"/>" | |
1097 "</packages>" | |
1098 "</manifest>" | |
1099 "</updatecheck>" | |
1100 "</app>" | |
1101 "</response>"; | |
1102 | |
1103 EXPECT_HRESULT_SUCCEEDED(LoadBundleFromXml(app_bundle_.get(), buffer_string)); | |
1104 SetAppStateWaitingToDownload(app); | |
1105 | |
1106 const Package* package = app->next_version()->GetPackage(0); | |
1107 ASSERT_TRUE(package); | |
1108 | |
1109 EXPECT_FALSE(download_manager_->IsPackageAvailable(package)); | |
1110 EXPECT_SUCCEEDED(download_manager_->DownloadApp(app)); | |
1111 EXPECT_TRUE(download_manager_->IsPackageAvailable(package)); | |
1112 | |
1113 // Get a unique temp dir name. The directory is not created. | |
1114 CString dir(GetUniqueTempDirectoryName()); | |
1115 | |
1116 // The call fails if the package destination directory does not exist. | |
1117 EXPECT_FAILED(download_manager_->GetPackage(package, dir)); | |
1118 | |
1119 EXPECT_SUCCEEDED(CreateDir(dir, NULL)); | |
1120 EXPECT_SUCCEEDED(download_manager_->GetPackage(package, dir)); | |
1121 | |
1122 CString filename(ConcatenatePath(dir, package->filename())); | |
1123 std::vector<CString> files; | |
1124 files.push_back(filename); | |
1125 EXPECT_SUCCEEDED(AuthenticateFiles(files, kUpdateBinHash)); | |
1126 | |
1127 // Getting the package the second time overwrites the destination file | |
1128 // and succeeds. | |
1129 EXPECT_SUCCEEDED(download_manager_->GetPackage(package, dir)); | |
1130 | |
1131 EXPECT_SUCCEEDED(DeleteDirectory(dir)); | |
1132 } | |
1133 | |
1134 TEST_F(DownloadManagerUserTest, GetPackage_NotPresent) { | |
1135 App* app = NULL; | |
1136 ASSERT_SUCCEEDED(app_bundle_->createApp(CComBSTR(kAppGuid1), &app)); | |
1137 EXPECT_SUCCEEDED(app->put_displayName(CComBSTR(_T("App1")))); | |
1138 | |
1139 // One app, one package. | |
1140 CStringA buffer_string = | |
1141 | |
1142 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
1143 "<response protocol=\"3.0\">" | |
1144 "<app appid=\"{0B35E146-D9CB-4145-8A91-43FDCAEBCD1E}\" status=\"ok\">" | |
1145 "<updatecheck status=\"ok\">" | |
1146 "<urls>" | |
1147 "<url codebase=\"http://dl.google.com/update2/\"/>" | |
1148 "</urls>" | |
1149 "<manifest version=\"1.0\">" | |
1150 "<packages>" | |
1151 "<package " | |
1152 "hash=\"YF2z/br/S6E3KTca0MT7qziJN44=\" " | |
1153 "name=\"UpdateData.bin\" " | |
1154 "required=\"true\" " | |
1155 "size=\"2048\"/>" | |
1156 "</packages>" | |
1157 "</manifest>" | |
1158 "</updatecheck>" | |
1159 "</app>" | |
1160 "</response>"; | |
1161 | |
1162 EXPECT_HRESULT_SUCCEEDED(LoadBundleFromXml(app_bundle_.get(), buffer_string)); | |
1163 SetAppStateWaitingToDownload(app); | |
1164 | |
1165 const Package* package = app->next_version()->GetPackage(0); | |
1166 ASSERT_TRUE(package); | |
1167 | |
1168 EXPECT_FALSE(download_manager_->IsPackageAvailable(package)); | |
1169 | |
1170 // Get a unique temp dir name. The directory is not created. | |
1171 CString dir(GetUniqueTempDirectoryName()); | |
1172 | |
1173 EXPECT_SUCCEEDED(CreateDir(dir, NULL)); | |
1174 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), | |
1175 download_manager_->GetPackage(package, dir)); | |
1176 | |
1177 EXPECT_SUCCEEDED(DeleteDirectory(dir)); | |
1178 } | |
1179 | |
1180 TEST(DownloadManagerTest, BuildUniqueFileName) { | |
1181 CString file1, file2; | |
1182 EXPECT_SUCCEEDED(DownloadManagerTest::BuildUniqueFileName(_T("a"), &file1)); | |
1183 EXPECT_SUCCEEDED(DownloadManagerTest::BuildUniqueFileName(_T("a"), &file2)); | |
1184 EXPECT_STRNE(file1, file2); | |
1185 } | |
1186 | |
1187 TEST(DownloadManagerTest, GetMessageForError) { | |
1188 const TCHAR* kEnglish = _T("en"); | |
1189 EXPECT_SUCCEEDED(ResourceManager::Create( | |
1190 true, app_util::GetCurrentModuleDirectory(), kEnglish)); | |
1191 | |
1192 EXPECT_STREQ( | |
1193 _T("The installer could not connect to the Internet. Ensure that your ") | |
1194 _T("computer is connected to the Internet and your firewall allows ") | |
1195 _T("GoogleUpdate.exe to connect then try again."), | |
1196 DownloadManager::GetMessageForError( | |
1197 ErrorContext(GOOPDATE_E_NO_NETWORK), kEnglish)); | |
1198 | |
1199 EXPECT_STREQ( | |
1200 _T("The installer could not connect to the Internet because of ") | |
1201 _T("an HTTP 401 Unauthorized response. This is likely a proxy ") | |
1202 _T("configuration issue. Please configure the proxy server to allow ") | |
1203 _T("network access and try again or contact your network administrator."), | |
1204 DownloadManager::GetMessageForError( | |
1205 ErrorContext(GOOPDATE_E_NETWORK_UNAUTHORIZED), kEnglish)); | |
1206 | |
1207 EXPECT_STREQ( | |
1208 _T("The installer could not connect to the Internet because of ") | |
1209 _T("an HTTP 403 Forbidden response. This is likely a proxy ") | |
1210 _T("configuration issue. Please configure the proxy server to allow ") | |
1211 _T("network access and try again or contact your network administrator."), | |
1212 DownloadManager::GetMessageForError( | |
1213 ErrorContext(GOOPDATE_E_NETWORK_FORBIDDEN), kEnglish)); | |
1214 | |
1215 EXPECT_STREQ( | |
1216 _T("The installer could not connect to the Internet because a ") | |
1217 _T("proxy server required user authentication. Please configure the ") | |
1218 _T("proxy server to allow network access and try again or contact your ") | |
1219 _T("network administrator."), | |
1220 DownloadManager::GetMessageForError( | |
1221 ErrorContext(GOOPDATE_E_NETWORK_PROXYAUTHREQUIRED), | |
1222 kEnglish)); | |
1223 | |
1224 EXPECT_STREQ( | |
1225 _T("The download failed."), | |
1226 DownloadManager::GetMessageForError(ErrorContext(E_FAIL), kEnglish)); | |
1227 | |
1228 EXPECT_STREQ( | |
1229 _T("Failed to cache the downloaded installer. Error: 0x80070005."), | |
1230 DownloadManager::GetMessageForError( | |
1231 ErrorContext(GOOPDATEDOWNLOAD_E_CACHING_FAILED, 0x80070005), | |
1232 kEnglish)); | |
1233 | |
1234 ResourceManager::Delete(); | |
1235 } | |
1236 | |
1237 } // namespace omaha | |
OLD | NEW |