OLD | NEW |
(Empty) | |
| 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/file_util.h" |
| 6 #include "base/path_service.h" |
| 7 #include "base/string_split.h" |
| 8 #include "base/string_util.h" |
| 9 #include "base/threading/sequenced_worker_pool.h" |
| 10 #include "base/utf_string_conversions.h" |
| 11 #include "chrome/app/chrome_command_ids.h" |
| 12 #include "chrome/browser/browser_process.h" |
| 13 #include "chrome/browser/page_cycler/page_cycler.h" |
| 14 #include "chrome/common/chrome_paths.h" |
| 15 #include "chrome/common/url_constants.h" |
| 16 #include "chrome/test/base/browser_with_test_window_test.h" |
| 17 #include "chrome/test/base/testing_pref_service.h" |
| 18 #include "content/public/browser/render_view_host.h" |
| 19 #include "content/test/test_browser_thread.h" |
| 20 #include "net/base/net_errors.h" |
| 21 #include "testing/gmock/include/gmock/gmock.h" |
| 22 #include "testing/gtest/include/gtest/gtest.h" |
| 23 |
| 24 using ::testing::_; |
| 25 using ::testing::Invoke; |
| 26 using content::RenderViewHost; |
| 27 using content::TestBrowserThread; |
| 28 using content::WebContentsObserver; |
| 29 using file_util::ContentsEqual; |
| 30 using file_util::PathExists; |
| 31 |
| 32 namespace { |
| 33 const int kFrameID = 1; |
| 34 const bool kIsMainFrame = true; |
| 35 const GURL kAboutURL = GURL(chrome::kAboutBlankURL); |
| 36 const int kSingleIteration = 1; |
| 37 } // namespace |
| 38 |
| 39 class MockPageCycler : public PageCycler { |
| 40 public: |
| 41 MockPageCycler(Browser* browser, FilePath urls_file, FilePath errors_file) |
| 42 : PageCycler(browser, urls_file) { |
| 43 set_errors_file(errors_file); |
| 44 } |
| 45 |
| 46 MockPageCycler(Browser* browser, |
| 47 FilePath urls_file, |
| 48 FilePath errors_file, |
| 49 FilePath stats_file) |
| 50 : PageCycler(browser, urls_file) { |
| 51 set_stats_file(stats_file); |
| 52 set_errors_file(errors_file); |
| 53 } |
| 54 |
| 55 MOCK_METHOD3(DidFinishLoad, void(int64 frame_id, |
| 56 const GURL& validated_url, |
| 57 bool is_main_frame)); |
| 58 MOCK_METHOD6(DidFailProvisionalLoad, void(int64 frame_id, |
| 59 bool is_main_frame, |
| 60 const GURL& validated_url, |
| 61 int error_code, |
| 62 const string16& error_description, |
| 63 RenderViewHost* render_view_host)); |
| 64 MOCK_METHOD1(RenderViewGone, void(base::TerminationStatus status)); |
| 65 |
| 66 void PageCyclerDidFailProvisionalLoad( |
| 67 int64 frame_id, |
| 68 bool is_main_frame, |
| 69 const GURL& validated_url, |
| 70 int error_code, |
| 71 const string16& error_description, |
| 72 RenderViewHost* render_view_host) { |
| 73 PageCycler::DidFailProvisionalLoad(frame_id, is_main_frame, |
| 74 validated_url, |
| 75 error_code, error_description, |
| 76 render_view_host); |
| 77 } |
| 78 |
| 79 void PageCyclerDidFinishLoad(int64 frame_id, |
| 80 const GURL& validated_url, |
| 81 bool is_main_frame) { |
| 82 PageCycler::DidFinishLoad(frame_id, validated_url, is_main_frame); |
| 83 } |
| 84 |
| 85 private: |
| 86 |
| 87 // We need to override Finish() because the calls to exit the browser in a |
| 88 // real PageCycler do not work in unittests (they interfere with later tests). |
| 89 virtual void Finish() OVERRIDE { |
| 90 BrowserList::RemoveObserver(this); |
| 91 Release(); |
| 92 } |
| 93 |
| 94 virtual ~MockPageCycler() {}\ |
| 95 |
| 96 DISALLOW_COPY_AND_ASSIGN(MockPageCycler); |
| 97 }; |
| 98 |
| 99 class PageCyclerTest : public BrowserWithTestWindowTest { |
| 100 public: |
| 101 PageCyclerTest() { |
| 102 } |
| 103 |
| 104 virtual ~PageCyclerTest() { |
| 105 } |
| 106 |
| 107 virtual void SetUp() OVERRIDE { |
| 108 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_); |
| 109 test_data_dir_ = test_data_dir_.AppendASCII("page_cycler"); |
| 110 |
| 111 BrowserWithTestWindowTest::SetUp(); |
| 112 AddTab(browser(), kAboutURL); |
| 113 ASSERT_FALSE(browser()->GetSelectedWebContents() == NULL); |
| 114 } |
| 115 |
| 116 void InitFilePaths(const FilePath& temp_path) { |
| 117 errors_file_ = temp_path.AppendASCII("errors_file"); |
| 118 stats_file_ = temp_path.AppendASCII("stats_file"); |
| 119 |
| 120 CHECK(!file_util::PathExists(errors_file_)); |
| 121 CHECK(!file_util::PathExists(stats_file_)); |
| 122 } |
| 123 |
| 124 void FailProvisionalLoad(int error_code, string16& error_description) { |
| 125 FOR_EACH_OBSERVER( |
| 126 WebContentsObserver, |
| 127 observers_, |
| 128 DidFailProvisionalLoad(kFrameID, kIsMainFrame, kAboutURL, error_code, |
| 129 error_description, NULL)); |
| 130 PumpLoop(); |
| 131 } |
| 132 |
| 133 void FinishLoad() { |
| 134 FOR_EACH_OBSERVER( |
| 135 WebContentsObserver, |
| 136 observers_, |
| 137 DidFinishLoad(kFrameID, kAboutURL, kIsMainFrame)); |
| 138 PumpLoop(); |
| 139 } |
| 140 |
| 141 void RunPageCycler(int total_iterations) { |
| 142 page_cycler_->Run(total_iterations); |
| 143 PumpLoop(); |
| 144 } |
| 145 |
| 146 void PumpLoop() { |
| 147 content::BrowserThread::GetBlockingPool()->FlushForTesting(); |
| 148 message_loop()->RunAllPending(); |
| 149 } |
| 150 |
| 151 void CloseBrowser() { |
| 152 DestroyBrowser(); |
| 153 PumpLoop(); |
| 154 } |
| 155 |
| 156 MockPageCycler* page_cycler() { |
| 157 return page_cycler_.get(); |
| 158 } |
| 159 |
| 160 void set_page_cycler(MockPageCycler* page_cycler) { |
| 161 page_cycler_ = page_cycler; |
| 162 observers_.AddObserver(page_cycler); |
| 163 } |
| 164 |
| 165 const std::vector<GURL>* urls_for_test() { |
| 166 return page_cycler_->urls_for_test(); |
| 167 } |
| 168 |
| 169 FilePath stats_file() { |
| 170 return stats_file_; |
| 171 } |
| 172 |
| 173 FilePath errors_file() { |
| 174 return errors_file_; |
| 175 } |
| 176 |
| 177 FilePath urls_file() { |
| 178 return test_data_dir_.AppendASCII("about_url"); |
| 179 } |
| 180 |
| 181 FilePath test_data_dir() { |
| 182 return test_data_dir_; |
| 183 } |
| 184 |
| 185 private: |
| 186 ObserverList<WebContentsObserver> observers_; |
| 187 scoped_refptr<MockPageCycler> page_cycler_; |
| 188 FilePath test_data_dir_; |
| 189 FilePath stats_file_; |
| 190 FilePath errors_file_; |
| 191 FilePath urls_file_; |
| 192 }; |
| 193 |
| 194 TEST_F(PageCyclerTest, FailProvisionalLoads) { |
| 195 const FilePath errors_expected_file = |
| 196 test_data_dir().AppendASCII("errors_expected"); |
| 197 |
| 198 ScopedTempDir temp; |
| 199 ASSERT_TRUE(temp.CreateUniqueTempDir()); |
| 200 InitFilePaths(temp.path()); |
| 201 |
| 202 ASSERT_TRUE(PathExists(errors_expected_file)); |
| 203 ASSERT_TRUE(PathExists(urls_file())); |
| 204 |
| 205 set_page_cycler(new MockPageCycler(browser(), |
| 206 urls_file(), |
| 207 errors_file())); |
| 208 RunPageCycler(kSingleIteration); |
| 209 |
| 210 // Page cycler expects browser to automatically start loading the first page. |
| 211 EXPECT_CALL(*page_cycler(), DidFinishLoad(kFrameID, kAboutURL, kIsMainFrame)) |
| 212 .WillOnce(Invoke(page_cycler(), |
| 213 &MockPageCycler::PageCyclerDidFinishLoad)); |
| 214 FinishLoad(); |
| 215 |
| 216 // DNS server fail error message. |
| 217 string16 error_string = |
| 218 string16(ASCIIToUTF16(net::ErrorToString(net::ERR_DNS_SERVER_FAILED))); |
| 219 EXPECT_CALL(*page_cycler(), |
| 220 DidFailProvisionalLoad(kFrameID, kIsMainFrame, _, |
| 221 net::ERR_DNS_SERVER_FAILED, error_string, |
| 222 _)) |
| 223 .WillOnce(Invoke(page_cycler(), |
| 224 &MockPageCycler::PageCyclerDidFailProvisionalLoad)); |
| 225 FailProvisionalLoad(net::ERR_DNS_SERVER_FAILED, error_string); |
| 226 |
| 227 // DNS time-out error message. |
| 228 error_string = string16( |
| 229 ASCIIToUTF16(net::ErrorToString(net::ERR_DNS_TIMED_OUT))); |
| 230 EXPECT_CALL(*page_cycler(), |
| 231 DidFailProvisionalLoad(kFrameID, |
| 232 kIsMainFrame, _, net::ERR_DNS_TIMED_OUT, |
| 233 error_string, _)) |
| 234 .WillOnce(Invoke(page_cycler(), |
| 235 &MockPageCycler::PageCyclerDidFailProvisionalLoad)); |
| 236 |
| 237 FailProvisionalLoad(net::ERR_DNS_TIMED_OUT, error_string); |
| 238 |
| 239 // DNS time-out error message. |
| 240 error_string = string16( |
| 241 ASCIIToUTF16(net::ErrorToString(net::ERR_INVALID_URL))); |
| 242 EXPECT_CALL(*page_cycler(), |
| 243 DidFailProvisionalLoad(kFrameID, kIsMainFrame, _, |
| 244 net::ERR_INVALID_URL, error_string, _)) |
| 245 .WillOnce(Invoke(page_cycler(), |
| 246 &MockPageCycler::PageCyclerDidFailProvisionalLoad)); |
| 247 FailProvisionalLoad(net::ERR_INVALID_URL, error_string); |
| 248 |
| 249 PumpLoop(); |
| 250 |
| 251 std::string errors_output; |
| 252 std::string errors_expected; |
| 253 ASSERT_TRUE(file_util::ReadFileToString(errors_file(), |
| 254 &errors_output)); |
| 255 ASSERT_TRUE(file_util::ReadFileToString(errors_expected_file, |
| 256 &errors_expected)); |
| 257 ASSERT_EQ(errors_output, errors_expected); |
| 258 } |
| 259 |
| 260 TEST_F(PageCyclerTest, StatsFile) { |
| 261 const int kNumLoads = 4; |
| 262 |
| 263 ScopedTempDir temp; |
| 264 ASSERT_TRUE(temp.CreateUniqueTempDir()); |
| 265 InitFilePaths(temp.path()); |
| 266 |
| 267 ASSERT_TRUE(PathExists(urls_file())); |
| 268 |
| 269 set_page_cycler(new MockPageCycler(browser(), urls_file(), |
| 270 errors_file())); |
| 271 page_cycler()->set_stats_file(stats_file()); |
| 272 RunPageCycler(kSingleIteration); |
| 273 |
| 274 for (int i = 0; i < kNumLoads; ++i) { |
| 275 EXPECT_CALL(*page_cycler(), DidFinishLoad( |
| 276 kFrameID, kAboutURL, kIsMainFrame)) |
| 277 .WillOnce(Invoke(page_cycler(), |
| 278 &MockPageCycler::PageCyclerDidFinishLoad)); |
| 279 FinishLoad(); |
| 280 } |
| 281 |
| 282 PumpLoop(); |
| 283 EXPECT_FALSE(PathExists(errors_file())); |
| 284 ASSERT_TRUE(PathExists(stats_file())); |
| 285 } |
| 286 |
| 287 TEST_F(PageCyclerTest, KillBrowserAndAbort) { |
| 288 const FilePath errors_expected_file = |
| 289 test_data_dir().AppendASCII("abort_expected"); |
| 290 |
| 291 ScopedTempDir temp; |
| 292 ASSERT_TRUE(temp.CreateUniqueTempDir()); |
| 293 InitFilePaths(temp.path()); |
| 294 |
| 295 ASSERT_TRUE(PathExists(errors_expected_file)); |
| 296 ASSERT_TRUE(PathExists(urls_file())); |
| 297 |
| 298 set_page_cycler(new MockPageCycler(browser(), |
| 299 urls_file(), |
| 300 errors_file())); |
| 301 RunPageCycler(kSingleIteration); |
| 302 |
| 303 EXPECT_CALL(*page_cycler(), DidFinishLoad(kFrameID, kAboutURL, kIsMainFrame)) |
| 304 .WillOnce(Invoke(page_cycler(), |
| 305 &MockPageCycler::PageCyclerDidFinishLoad)); |
| 306 message_loop()->RunAllPending(); |
| 307 |
| 308 FinishLoad(); |
| 309 |
| 310 CloseBrowser(); |
| 311 PumpLoop(); |
| 312 |
| 313 std::string errors_output; |
| 314 std::string errors_expected; |
| 315 ASSERT_TRUE(file_util::ReadFileToString(errors_file(), |
| 316 &errors_output)); |
| 317 ASSERT_TRUE(file_util::ReadFileToString(errors_expected_file, |
| 318 &errors_expected)); |
| 319 ASSERT_EQ(errors_output, errors_expected); |
| 320 } |
| 321 |
| 322 TEST_F(PageCyclerTest, MultipleIterations) { |
| 323 const int kMultipleIterations = 3; |
| 324 const int kNumLoads = 10; |
| 325 |
| 326 ScopedTempDir temp; |
| 327 ASSERT_TRUE(temp.CreateUniqueTempDir()); |
| 328 InitFilePaths(temp.path()); |
| 329 |
| 330 ASSERT_TRUE(PathExists(urls_file())); |
| 331 |
| 332 set_page_cycler(new MockPageCycler(browser(), |
| 333 urls_file(), |
| 334 errors_file())); |
| 335 page_cycler()->set_stats_file(stats_file()); |
| 336 RunPageCycler(kMultipleIterations); |
| 337 |
| 338 EXPECT_CALL(*page_cycler(), DidFinishLoad(kFrameID, kAboutURL, kIsMainFrame)) |
| 339 .WillRepeatedly(Invoke(page_cycler(), |
| 340 &MockPageCycler::PageCyclerDidFinishLoad)); |
| 341 |
| 342 for (int i = 0; i < kNumLoads; ++i) |
| 343 FinishLoad(); |
| 344 |
| 345 PumpLoop(); |
| 346 EXPECT_FALSE(PathExists(errors_file())); |
| 347 ASSERT_TRUE(PathExists(stats_file())); |
| 348 } |
OLD | NEW |