browser_close_browsertest.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 2012 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/command_line.h" 6#include "base/logging.h" 7#include "base/path_service.h" 8#include "base/stringprintf.h" 9#include "chrome/browser/browser_process.h" 10#include "chrome/browser/download/download_service.h" 11#include "chrome/browser/download/download_service_factory.h" 12#include "chrome/browser/download/download_test_file_chooser_observer.h" 13#include "chrome/browser/net/url_request_mock_util.h" 14#include "chrome/browser/prefs/pref_service.h" 15#include "chrome/browser/profiles/profile.h" 16#include "chrome/browser/profiles/profile_manager.h" 17#include "chrome/browser/ui/browser.h" 18#include "chrome/browser/ui/browser_list.h" 19#include "chrome/browser/ui/browser_tabstrip.h" 20#include "chrome/browser/ui/browser_window.h" 21#include "chrome/common/chrome_paths.h" 22#include "chrome/common/pref_names.h" 23#include "chrome/common/url_constants.h" 24#include "chrome/test/base/in_process_browser_test.h" 25#include "chrome/test/base/ui_test_utils.h" 26#include "content/public/browser/download_item.h" 27#include "content/public/common/page_transition_types.h" 28#include "content/public/test/browser_test_utils.h" 29#include "content/public/test/download_test_observer.h" 30#include "content/test/net/url_request_slow_download_job.h" 31 32using content::BrowserContext; 33using content::BrowserThread; 34using content::DownloadItem; 35using content::DownloadManager; 36using content::URLRequestSlowDownloadJob; 37 38class BrowserCloseTest : public InProcessBrowserTest { 39 public: 40 // Structure defining test cases for DownloadsCloseCheck. 41 struct DownloadsCloseCheckCase { 42 std::string DebugString() const; 43 44 // Input 45 struct { 46 struct { 47 int windows; 48 int downloads; 49 } regular; 50 struct { 51 int windows; 52 int downloads; 53 } incognito; 54 } profile_a; 55 56 struct { 57 struct { 58 int windows; 59 int downloads; 60 } regular; 61 struct { 62 int windows; 63 int downloads; 64 } incognito; 65 } profile_b; 66 67 // We always probe a window in profile A. 68 enum { REGULAR = 0, INCOGNITO = 1 } window_to_probe; 69 70 // Output 71 Browser::DownloadClosePreventionType type; 72 73 // Unchecked if type == DOWNLOAD_CLOSE_OK. 74 int num_blocking; 75 }; 76 77 protected: 78 virtual void SetUpOnMainThread() OVERRIDE { 79 BrowserThread::PostTask( 80 BrowserThread::IO, FROM_HERE, 81 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true)); 82 } 83 84 // Create a second profile to work within multi-profile. 85 Profile* CreateSecondProfile() { 86 FilePath user_data_dir; 87 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); 88 89 if (!second_profile_data_dir_.CreateUniqueTempDirUnderPath(user_data_dir)) 90 return NULL; 91 92 Profile* second_profile = 93 g_browser_process->profile_manager()->GetProfile( 94 second_profile_data_dir_.path()); 95 if (!second_profile) 96 return NULL; 97 98 bool result = second_profile_downloads_dir_.CreateUniqueTempDir(); 99 if (!result) 100 return NULL; 101 second_profile->GetPrefs()->SetFilePath( 102 prefs::kDownloadDefaultDirectory, 103 second_profile_downloads_dir_.path()); 104 105 return second_profile; 106 } 107 108 // Create |num_downloads| number of downloads that are stalled 109 // (will quickly get to a place where the server won't 110 // provide any more data) so that we can test closing the 111 // browser with active downloads. 112 void CreateStalledDownloads(Browser* browser, int num_downloads) { 113 GURL url(URLRequestSlowDownloadJob::kKnownSizeUrl); 114 115 if (num_downloads == 0) 116 return; 117 118 // Setup an observer waiting for the given number of downloads 119 // to get to IN_PROGRESS. 120 DownloadManager* download_manager = 121 BrowserContext::GetDownloadManager(browser->profile()); 122 scoped_ptr<content::DownloadTestObserver> observer( 123 new content::DownloadTestObserverInProgress(download_manager, 124 num_downloads)); 125 126 // Set of that number of downloads. 127 size_t count_downloads = num_downloads; 128 while (num_downloads--) 129 ui_test_utils::NavigateToURLWithDisposition( 130 browser, url, NEW_BACKGROUND_TAB, 131 ui_test_utils::BROWSER_TEST_NONE); 132 133 // Wait for them. 134 observer->WaitForFinished(); 135 EXPECT_EQ(count_downloads, 136 observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS)); 137 } 138 139 // All all downloads created in CreateStalledDownloads() to 140 // complete, and block in this routine until they do complete. 141 void CompleteAllDownloads(Browser* browser) { 142 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl); 143 ui_test_utils::NavigateToURL(browser, finish_url); 144 145 // Go through and, for every single profile, wait until there are 146 // no active downloads on that download manager. 147 std::vector<Profile*> profiles( 148 g_browser_process->profile_manager()->GetLoadedProfiles()); 149 for (std::vector<Profile*>::const_iterator pit = profiles.begin(); 150 pit != profiles.end(); ++pit) { 151 DownloadService* download_service = 152 DownloadServiceFactory::GetForProfile(*pit); 153 if (download_service->HasCreatedDownloadManager()) { 154 DownloadManager *mgr = BrowserContext::GetDownloadManager(*pit); 155 scoped_refptr<content::DownloadTestFlushObserver> observer( 156 new content::DownloadTestFlushObserver(mgr)); 157 observer->WaitForFlush(); 158 } 159 if ((*pit)->HasOffTheRecordProfile()) { 160 DownloadService* incognito_download_service = 161 DownloadServiceFactory::GetForProfile( 162 (*pit)->GetOffTheRecordProfile()); 163 if (incognito_download_service->HasCreatedDownloadManager()) { 164 DownloadManager *mgr = BrowserContext::GetDownloadManager( 165 (*pit)->GetOffTheRecordProfile()); 166 scoped_refptr<content::DownloadTestFlushObserver> observer( 167 new content::DownloadTestFlushObserver(mgr)); 168 observer->WaitForFlush(); 169 } 170 } 171 } 172 } 173 174 // Create a Browser (with associated window) on the specified profile. 175 Browser* CreateBrowserOnProfile(Profile* profile) { 176 Browser* new_browser = new Browser(Browser::CreateParams(profile)); 177 chrome::AddSelectedTabWithURL(new_browser, GURL(chrome::kAboutBlankURL), 178 content::PAGE_TRANSITION_AUTO_TOPLEVEL); 179 content::WaitForLoadStop(chrome::GetActiveWebContents(new_browser)); 180 new_browser->window()->Show(); 181 return new_browser; 182 } 183 184 // Adjust the number of browsers and associated windows up or down 185 // to |num_windows|. This routine assumes that there is only a single 186 // browser associated with the profile on entry. |*base_browser| contains 187 // this browser, and the profile is derived from that browser. On output, 188 // if |*base_browser| was destroyed (because |num_windows == 0|), NULL 189 // is assigned to that memory location. 190 bool AdjustBrowsersOnProfile(Browser** base_browser, int num_windows) { 191 int num_downloads_blocking; 192 if (num_windows == 0) { 193 if (Browser::DOWNLOAD_CLOSE_OK != 194 (*base_browser)->OkToCloseWithInProgressDownloads( 195 &num_downloads_blocking)) 196 return false; 197 (*base_browser)->window()->Close(); 198 *base_browser = 0; 199 return true; 200 } 201 202 // num_windows > 0 203 Profile* profile((*base_browser)->profile()); 204 for (int w = 1; w < num_windows; ++w) { 205 CreateBrowserOnProfile(profile); 206 } 207 return true; 208 } 209 210 int TotalUnclosedBrowsers() { 211 int count = 0; 212 for (BrowserList::const_iterator iter = BrowserList::begin(); 213 iter != BrowserList::end(); ++iter) 214 if (!(*iter)->IsAttemptingToCloseBrowser()) { 215 count++; 216 } 217 return count; 218 } 219 220 // Note that this is invalid to call if TotalUnclosedBrowsers() == 0. 221 Browser* FirstUnclosedBrowser() { 222 for (BrowserList::const_iterator iter = BrowserList::begin(); 223 iter != BrowserList::end(); ++iter) 224 if (!(*iter)->IsAttemptingToCloseBrowser()) 225 return (*iter); 226 return NULL; 227 } 228 229 bool SetupForDownloadCloseCheck() { 230 first_profile_ = browser()->profile(); 231 232 bool result = first_profile_downloads_dir_.CreateUniqueTempDir(); 233 EXPECT_TRUE(result); 234 if (!result) return false; 235 first_profile_->GetPrefs()->SetFilePath( 236 prefs::kDownloadDefaultDirectory, 237 first_profile_downloads_dir_.path()); 238 239 second_profile_ = CreateSecondProfile(); 240 EXPECT_TRUE(second_profile_); 241 if (!second_profile_) return false; 242 243 DownloadTestFileChooserObserver(first_profile_) .EnableFileChooser(false); 244 DownloadTestFileChooserObserver(second_profile_).EnableFileChooser(false); 245 return true; 246 } 247 248 // Test a specific DownloadsCloseCheckCase. Returns false if 249 // an assertion has failed and the test should be aborted. 250 bool ExecuteDownloadCloseCheckCase(size_t i) { 251 const DownloadsCloseCheckCase& check_case(download_close_check_cases[i]); 252 253 // Test invariant: so that we don't actually try and close the browser, 254 // we always enter the function with a single browser window open on the 255 // main profile. That means we need to exit the function the same way. 256 // So we setup everything except for the |first_profile_| regular, and then 257 // flip the bit on the main window. 258 // Note that this means that browser() is unreliable in the context 259 // of this function or its callers; we'll be killing that main window 260 // and recreating it fairly frequently. 261 int unclosed_browsers = TotalUnclosedBrowsers(); 262 EXPECT_EQ(1, unclosed_browsers); 263 if (1 != unclosed_browsers) 264 return false; 265 266 Browser* entry_browser = FirstUnclosedBrowser(); 267 EXPECT_EQ(first_profile_, entry_browser->profile()) 268 << "Case" << i 269 << ": " << check_case.DebugString(); 270 if (first_profile_ != entry_browser->profile()) 271 return false; 272 int total_download_count = DownloadService::DownloadCountAllProfiles(); 273 EXPECT_EQ(0, total_download_count) 274 << "Case " << i 275 << ": " << check_case.DebugString(); 276 if (0 != total_download_count) 277 return false; 278 279 Profile* first_profile_incognito = first_profile_->GetOffTheRecordProfile(); 280 Profile* second_profile_incognito = 281 second_profile_->GetOffTheRecordProfile(); 282 DownloadTestFileChooserObserver(first_profile_incognito) 283 .EnableFileChooser(false); 284 DownloadTestFileChooserObserver(second_profile_incognito) 285 .EnableFileChooser(false); 286 287 // For simplicty of coding, we create a window on each profile so that 288 // we can easily create downloads, then we destroy or create windows 289 // as necessary. 290 Browser* browser_a_regular(CreateBrowserOnProfile(first_profile_)); 291 Browser* browser_a_incognito( 292 CreateBrowserOnProfile(first_profile_incognito)); 293 Browser* browser_b_regular(CreateBrowserOnProfile(second_profile_)); 294 Browser* browser_b_incognito( 295 CreateBrowserOnProfile(second_profile_incognito)); 296 297 // Kill our entry browser. 298 entry_browser->window()->Close(); 299 entry_browser = NULL; 300 301 // Create all downloads needed. 302 CreateStalledDownloads( 303 browser_a_regular, check_case.profile_a.regular.downloads); 304 CreateStalledDownloads( 305 browser_a_incognito, check_case.profile_a.incognito.downloads); 306 CreateStalledDownloads( 307 browser_b_regular, check_case.profile_b.regular.downloads); 308 CreateStalledDownloads( 309 browser_b_incognito, check_case.profile_b.incognito.downloads); 310 311 // Adjust the windows 312 Browser** browsers[] = { 313 &browser_a_regular, &browser_a_incognito, 314 &browser_b_regular, &browser_b_incognito 315 }; 316 int window_counts[] = { 317 check_case.profile_a.regular.windows, 318 check_case.profile_a.incognito.windows, 319 check_case.profile_b.regular.windows, 320 check_case.profile_b.incognito.windows, 321 }; 322 for (size_t j = 0; j < arraysize(browsers); ++j) { 323 bool result = AdjustBrowsersOnProfile(browsers[j], window_counts[j]); 324 EXPECT_TRUE(result); 325 if (!result) 326 return false; 327 } 328 content::RunAllPendingInMessageLoop(); 329 330 // All that work, for this one little test. 331 EXPECT_TRUE((check_case.window_to_probe == 332 DownloadsCloseCheckCase::REGULAR) || 333 (check_case.window_to_probe == 334 DownloadsCloseCheckCase::INCOGNITO)); 335 if (!((check_case.window_to_probe == 336 DownloadsCloseCheckCase::REGULAR) || 337 (check_case.window_to_probe == 338 DownloadsCloseCheckCase::INCOGNITO))) 339 return false; 340 341 int num_downloads_blocking; 342 Browser* browser_to_probe = 343 (check_case.window_to_probe == DownloadsCloseCheckCase::REGULAR ? 344 browser_a_regular : 345 browser_a_incognito); 346 Browser::DownloadClosePreventionType type = 347 browser_to_probe->OkToCloseWithInProgressDownloads( 348 &num_downloads_blocking); 349 EXPECT_EQ(check_case.type, type) << "Case " << i 350 << ": " << check_case.DebugString(); 351 if (type != Browser::DOWNLOAD_CLOSE_OK) 352 EXPECT_EQ(check_case.num_blocking, num_downloads_blocking) 353 << "Case " << i 354 << ": " << check_case.DebugString(); 355 356 // Release all the downloads. 357 CompleteAllDownloads(browser_to_probe); 358 359 // Create a new main window and kill everything else. 360 entry_browser = CreateBrowserOnProfile(first_profile_); 361 for (BrowserList::const_iterator bit = BrowserList::begin(); 362 bit != BrowserList::end(); ++bit) { 363 if ((*bit) != entry_browser) { 364 EXPECT_TRUE((*bit)->window()); 365 if (!(*bit)->window()) 366 return false; 367 (*bit)->window()->Close(); 368 } 369 } 370 content::RunAllPendingInMessageLoop(); 371 372 return true; 373 } 374 375 static const DownloadsCloseCheckCase download_close_check_cases[]; 376 377 // DownloadCloseCheck variables. 378 Profile* first_profile_; 379 Profile* second_profile_; 380 381 ScopedTempDir first_profile_downloads_dir_; 382 ScopedTempDir second_profile_data_dir_; 383 ScopedTempDir second_profile_downloads_dir_; 384}; 385 386const BrowserCloseTest::DownloadsCloseCheckCase 387BrowserCloseTest::download_close_check_cases[] = { 388 // Top level nesting is {profile_a, profile_b} 389 // Second level nesting is {regular, incognito 390 // Third level (inner) nesting is {windows, downloads} 391 392 // Last window (incognito) triggers browser close warning. 393 {{{0, 0}, {1, 1}}, {{0, 0}, {0, 0}}, 394 BrowserCloseTest::DownloadsCloseCheckCase::INCOGNITO, 395 Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN, 1}, 396 397 // Last incognito window triggers incognito close warning. 398 {{{1, 0}, {1, 1}}, {{0, 0}, {0, 0}}, 399 BrowserCloseTest::DownloadsCloseCheckCase::INCOGNITO, 400 Browser::DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE, 1}, 401 402 // Last incognito window with no downloads triggers no warning. 403 {{{0, 0}, {1, 0}}, {{0, 0}, {0, 0}}, 404 BrowserCloseTest::DownloadsCloseCheckCase::INCOGNITO, 405 Browser::DOWNLOAD_CLOSE_OK}, 406 407 // Last incognito window with window+download on another incognito profile 408 // triggers no warning. 409 {{{0, 0}, {1, 0}}, {{0, 0}, {1, 1}}, 410 BrowserCloseTest::DownloadsCloseCheckCase::INCOGNITO, 411 Browser::DOWNLOAD_CLOSE_OK}, 412 413 // Non-last incognito window triggers no warning. 414 {{{0, 0}, {2, 1}}, {{0, 0}, {0, 0}}, 415 BrowserCloseTest::DownloadsCloseCheckCase::INCOGNITO, 416 Browser::DOWNLOAD_CLOSE_OK}, 417 418 // Non-last regular window triggers no warning. 419 {{{2, 1}, {0, 0}}, {{0, 0}, {0, 0}}, 420 BrowserCloseTest::DownloadsCloseCheckCase::REGULAR, 421 Browser::DOWNLOAD_CLOSE_OK}, 422 423 // Last regular window triggers browser close. 424 {{{1, 1}, {0, 0}}, {{0, 0}, {0, 0}}, 425 BrowserCloseTest::DownloadsCloseCheckCase::REGULAR, 426 Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN, 1}, 427 428 // Last regular window triggers browser close for download on different 429 // profile. 430 {{{1, 0}, {0, 0}}, {{0, 1}, {0, 0}}, 431 BrowserCloseTest::DownloadsCloseCheckCase::REGULAR, 432 Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN, 1}, 433 434 // Last regular window triggers no warning if incognito 435 // active (http://crbug.com/61257). 436 {{{1, 0}, {1, 1}}, {{0, 0}, {0, 0}}, 437 BrowserCloseTest::DownloadsCloseCheckCase::REGULAR, 438 Browser::DOWNLOAD_CLOSE_OK}, 439 440 // Last regular window triggers no warning if other profile window active. 441 {{{1, 1}, {0, 0}}, {{1, 0}, {0, 0}}, 442 BrowserCloseTest::DownloadsCloseCheckCase::REGULAR, 443 Browser::DOWNLOAD_CLOSE_OK}, 444 445 // Last regular window triggers no warning if other incognito window 446 // active. 447 {{{1, 0}, {0, 0}}, {{0, 0}, {1, 1}}, 448 BrowserCloseTest::DownloadsCloseCheckCase::REGULAR, 449 Browser::DOWNLOAD_CLOSE_OK}, 450 451 // Last regular window triggers no warning if incognito active. 452 {{{1, 1}, {1, 0}}, {{0, 0}, {0, 0}}, 453 BrowserCloseTest::DownloadsCloseCheckCase::REGULAR, 454 Browser::DOWNLOAD_CLOSE_OK}, 455 456 // Test plural for regular. 457 {{{1, 2}, {0, 0}}, {{0, 0}, {0, 0}}, 458 BrowserCloseTest::DownloadsCloseCheckCase::REGULAR, 459 Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN, 2}, 460 461 // Test plural for incognito. 462 {{{1, 0}, {1, 2}}, {{0, 0}, {0, 0}}, 463 BrowserCloseTest::DownloadsCloseCheckCase::INCOGNITO, 464 Browser::DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE, 2}, 465}; 466 467std::string BrowserCloseTest::DownloadsCloseCheckCase::DebugString() const { 468 std::string result; 469 result += "{"; 470 if (profile_a.regular.windows || profile_a.regular.downloads) 471 result += base::StringPrintf("Regular profile A: (%d w, %d d), ", 472 profile_a.regular.windows, 473 profile_a.regular.downloads); 474 if (profile_a.incognito.windows || profile_a.incognito.downloads) 475 result += base::StringPrintf("Incognito profile A: (%d w, %d d), ", 476 profile_a.incognito.windows, 477 profile_a.incognito.downloads); 478 if (profile_b.regular.windows || profile_b.regular.downloads) 479 result += base::StringPrintf("Regular profile B: (%d w, %d d), ", 480 profile_b.regular.windows, 481 profile_b.regular.downloads); 482 if (profile_b.incognito.windows || profile_b.incognito.downloads) 483 result += base::StringPrintf("Incognito profile B: (%d w, %d d), ", 484 profile_b.incognito.windows, 485 profile_b.incognito.downloads); 486 result += (window_to_probe == REGULAR ? "Probe regular" : 487 window_to_probe == INCOGNITO ? "Probe incognito" : 488 "Probe unknown"); 489 result += "} -> "; 490 if (type == Browser::DOWNLOAD_CLOSE_OK) { 491 result += "No warning"; 492 } else { 493 result += base::StringPrintf( 494 "%s (%d downloads) warning", 495 (type == Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN ? "Browser shutdown" : 496 type == Browser::DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE ? 497 "Incognito close" : "Unknown"), 498 num_blocking); 499 } 500 return result; 501} 502 503// The following test is split into six chunks to reduce the chance 504// of hitting the 25s timeout. 505 506// This test is timing out very often under AddressSanitizer. 507// http://crbug.com/111914 and http://crbug.com/103371. 508// Crashing on Linux. http://crbug.com/100566 509// Timing out on XP debug. http://crbug.com/111914 510// Timing out, http://crbug.com/159449 . 511 512#define MAYBE_DownloadsCloseCheck_0 DISABLED_DownloadsCloseCheck_0 513#define MAYBE_DownloadsCloseCheck_1 DISABLED_DownloadsCloseCheck_1 514#define MAYBE_DownloadsCloseCheck_2 DISABLED_DownloadsCloseCheck_2 515#define MAYBE_DownloadsCloseCheck_3 DISABLED_DownloadsCloseCheck_3 516#define MAYBE_DownloadsCloseCheck_4 DISABLED_DownloadsCloseCheck_4 517#define MAYBE_DownloadsCloseCheck_5 DISABLED_DownloadsCloseCheck_5 518 519IN_PROC_BROWSER_TEST_F(BrowserCloseTest, MAYBE_DownloadsCloseCheck_0) { 520 ASSERT_TRUE(SetupForDownloadCloseCheck()); 521 for (size_t i = 0; i < arraysize(download_close_check_cases) / 6; ++i) { 522 ExecuteDownloadCloseCheckCase(i); 523 } 524} 525 526IN_PROC_BROWSER_TEST_F(BrowserCloseTest, MAYBE_DownloadsCloseCheck_1) { 527 ASSERT_TRUE(SetupForDownloadCloseCheck()); 528 for (size_t i = arraysize(download_close_check_cases) / 6; 529 i < 2 * arraysize(download_close_check_cases) / 6; ++i) { 530 ExecuteDownloadCloseCheckCase(i); 531 } 532} 533 534IN_PROC_BROWSER_TEST_F(BrowserCloseTest, MAYBE_DownloadsCloseCheck_2) { 535 ASSERT_TRUE(SetupForDownloadCloseCheck()); 536 for (size_t i = 2 * arraysize(download_close_check_cases) / 6; 537 i < 3 * arraysize(download_close_check_cases) / 6; ++i) { 538 ExecuteDownloadCloseCheckCase(i); 539 } 540} 541 542IN_PROC_BROWSER_TEST_F(BrowserCloseTest, MAYBE_DownloadsCloseCheck_3) { 543 ASSERT_TRUE(SetupForDownloadCloseCheck()); 544 for (size_t i = 3 * arraysize(download_close_check_cases) / 6; 545 i < 4 * arraysize(download_close_check_cases) / 6; ++i) { 546 ExecuteDownloadCloseCheckCase(i); 547 } 548} 549 550IN_PROC_BROWSER_TEST_F(BrowserCloseTest, MAYBE_DownloadsCloseCheck_4) { 551 ASSERT_TRUE(SetupForDownloadCloseCheck()); 552 for (size_t i = 4 * arraysize(download_close_check_cases) / 6; 553 i < 5 * arraysize(download_close_check_cases) / 6; ++i) { 554 ExecuteDownloadCloseCheckCase(i); 555 } 556} 557 558IN_PROC_BROWSER_TEST_F(BrowserCloseTest, MAYBE_DownloadsCloseCheck_5) { 559 ASSERT_TRUE(SetupForDownloadCloseCheck()); 560 for (size_t i = 5 * arraysize(download_close_check_cases) / 6; 561 i < 6 * arraysize(download_close_check_cases) / 6; ++i) { 562 ExecuteDownloadCloseCheckCase(i); 563 } 564} 565