Chromium Code Reviews| 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 | |
| 38 bool LinesAreEqual(std::vector<std::string>& file_a, | |
| 39 std::vector<std::string>& file_b) { | |
| 40 if (file_a.size() != file_b.size()) | |
|
Aaron Boodman
2012/05/29 21:39:08
I believe that you can just use std::equal?
Aaron Boodman
2012/05/30 01:08:42
In case this wasn't clear, I meant you can just us
Devlin
2012/05/30 01:45:15
Done.
| |
| 41 return false; | |
| 42 | |
| 43 for (std::vector<std::string>::const_iterator it_a = file_a.begin(), | |
| 44 it_b = file_b.begin(); it_a != file_a.end() && it_b != file_b.end(); | |
| 45 ++it_a, ++it_b) { | |
| 46 if (*it_a != *it_b) | |
| 47 return false; | |
| 48 } | |
| 49 return true; | |
| 50 } | |
| 51 | |
| 52 // Read the file, and generate a vector of strings. | |
| 53 std::vector<std::string> GetLinesFromFile(FilePath file) { | |
| 54 std::string file_contents; | |
| 55 CHECK(file_util::ReadFileToString(file, &file_contents)); | |
| 56 if (file_contents[file_contents.size() - 1] == '\n') { | |
|
Aaron Boodman
2012/05/29 21:39:08
No curly brace is required here.
Devlin
2012/05/30 01:45:15
Done.
| |
| 57 file_contents = file_contents.substr(0, file_contents.size() - 1); | |
|
Aaron Boodman
2012/05/29 21:39:08
file_contents.resize()
Devlin
2012/05/30 01:45:15
Done.
| |
| 58 } | |
| 59 | |
| 60 std::vector<std::string> lines; | |
| 61 base::SplitString(file_contents, '\n', &lines); | |
| 62 | |
| 63 return lines; | |
| 64 } | |
| 65 | |
| 66 } // namespace | |
| 67 | |
| 68 class MockPageCycler : public PageCycler { | |
| 69 public: | |
| 70 MockPageCycler(Browser* browser, FilePath urls_file, FilePath errors_file) | |
| 71 : PageCycler(browser, urls_file) { | |
| 72 set_errors_file(errors_file); | |
| 73 } | |
| 74 | |
| 75 MockPageCycler(Browser* browser, | |
| 76 FilePath urls_file, | |
| 77 FilePath errors_file, | |
| 78 FilePath stats_file) | |
| 79 : PageCycler(browser, urls_file) { | |
| 80 set_stats_file(stats_file); | |
| 81 set_errors_file(errors_file); | |
| 82 } | |
| 83 | |
| 84 MOCK_METHOD3(DidFinishLoad, void(int64 frame_id, | |
| 85 const GURL& validated_url, | |
| 86 bool is_main_frame)); | |
| 87 MOCK_METHOD6(DidFailProvisionalLoad, void(int64 frame_id, | |
| 88 bool is_main_frame, | |
| 89 const GURL& validated_url, | |
| 90 int error_code, | |
| 91 const string16& error_description, | |
| 92 RenderViewHost* render_view_host)); | |
| 93 MOCK_METHOD1(RenderViewGone, void(base::TerminationStatus status)); | |
| 94 | |
| 95 void PageCyclerDidFailProvisionalLoad( | |
| 96 int64 frame_id, | |
| 97 bool is_main_frame, | |
| 98 const GURL& validated_url, | |
| 99 int error_code, | |
| 100 const string16& error_description, | |
| 101 RenderViewHost* render_view_host) { | |
| 102 PageCycler::DidFailProvisionalLoad(frame_id, is_main_frame, | |
| 103 validated_url, | |
| 104 error_code, error_description, | |
| 105 render_view_host); | |
| 106 } | |
| 107 | |
| 108 void PageCyclerDidFinishLoad(int64 frame_id, | |
| 109 const GURL& validated_url, | |
| 110 bool is_main_frame) { | |
| 111 PageCycler::DidFinishLoad(frame_id, validated_url, is_main_frame); | |
| 112 } | |
| 113 | |
| 114 private: | |
| 115 virtual ~MockPageCycler() {} | |
| 116 DISALLOW_COPY_AND_ASSIGN(MockPageCycler); | |
| 117 }; | |
| 118 | |
| 119 class PageCyclerTest : public BrowserWithTestWindowTest { | |
| 120 public: | |
| 121 PageCyclerTest() {} | |
| 122 ~PageCyclerTest() {} | |
| 123 | |
| 124 virtual void SetUp() OVERRIDE; | |
| 125 void FailProvisionalLoad(int error_code, string16& error_description); | |
| 126 void FinishLoad(); | |
| 127 void RunPageCycler(int total_iterations); | |
| 128 void PumpLoop(); | |
| 129 void CloseBrowser(); | |
| 130 | |
| 131 MockPageCycler* page_cycler() { | |
| 132 return page_cycler_.get(); | |
| 133 } | |
| 134 | |
| 135 void set_page_cycler(MockPageCycler* page_cycler) { | |
| 136 page_cycler_ = page_cycler; | |
| 137 observers_.AddObserver(page_cycler); | |
| 138 } | |
| 139 | |
| 140 const std::vector<GURL>* urls_for_test() { | |
| 141 return page_cycler_->urls_for_test(); | |
| 142 } | |
| 143 | |
| 144 FilePath stats_output_file_path() { | |
| 145 return test_data_dir_.AppendASCII("stats_output"); | |
| 146 } | |
| 147 | |
| 148 FilePath abort_expected_file_path() { | |
| 149 return test_data_dir_.AppendASCII("abort_expected"); | |
| 150 } | |
| 151 | |
| 152 FilePath errors_output_file_path() { | |
| 153 return test_data_dir_.AppendASCII("errors_output"); | |
| 154 } | |
| 155 | |
| 156 FilePath errors_expected_file_path() { | |
| 157 return test_data_dir_.AppendASCII("errors_expected"); | |
| 158 } | |
| 159 | |
| 160 FilePath about_url_file_path() { | |
| 161 return test_data_dir_.AppendASCII("about_url"); | |
| 162 } | |
| 163 | |
| 164 private: | |
| 165 ObserverList<WebContentsObserver> observers_; | |
| 166 scoped_refptr<MockPageCycler> page_cycler_; | |
| 167 FilePath test_data_dir_; | |
| 168 }; | |
| 169 | |
| 170 void PageCyclerTest::SetUp() { | |
| 171 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_); | |
| 172 test_data_dir_ = test_data_dir_.AppendASCII("page_cycler"); | |
| 173 | |
| 174 BrowserWithTestWindowTest::SetUp(); | |
| 175 AddTab(browser(), kAboutURL); | |
| 176 ASSERT_FALSE(browser()->GetSelectedWebContents() == NULL); | |
| 177 } | |
| 178 | |
| 179 void PageCyclerTest::FailProvisionalLoad(int error_code, | |
| 180 string16& error_description) { | |
| 181 FOR_EACH_OBSERVER(WebContentsObserver, | |
| 182 observers_, | |
| 183 DidFailProvisionalLoad(kFrameID, kIsMainFrame, kAboutURL, error_code, | |
| 184 error_description, NULL)); | |
| 185 PumpLoop(); | |
| 186 } | |
| 187 | |
| 188 void PageCyclerTest::FinishLoad() { | |
| 189 FOR_EACH_OBSERVER(WebContentsObserver, | |
| 190 observers_, | |
| 191 DidFinishLoad(kFrameID, kAboutURL, kIsMainFrame)); | |
| 192 PumpLoop(); | |
| 193 } | |
| 194 | |
| 195 void PageCyclerTest::RunPageCycler(int total_iterations) { | |
| 196 page_cycler_->Run(total_iterations); | |
| 197 PumpLoop(); | |
| 198 } | |
| 199 | |
| 200 void PageCyclerTest::PumpLoop() { | |
| 201 content::BrowserThread::GetBlockingPool()->FlushForTesting(); | |
| 202 message_loop()->RunAllPending(); | |
| 203 } | |
| 204 | |
| 205 void PageCyclerTest::CloseBrowser() { | |
| 206 browser()->OnWindowClosing(); | |
| 207 DestroyBrowser(); | |
| 208 PumpLoop(); | |
| 209 } | |
| 210 | |
| 211 TEST_F(PageCyclerTest, FailProvisionalLoads) { | |
| 212 ASSERT_TRUE(PathExists(errors_expected_file_path())); | |
| 213 ASSERT_TRUE(PathExists(about_url_file_path())); | |
| 214 | |
| 215 set_page_cycler(new MockPageCycler(browser(), | |
| 216 about_url_file_path(), | |
| 217 errors_output_file_path())); | |
| 218 RunPageCycler(kSingleIteration); | |
| 219 | |
| 220 // Page cycler expects browser to automatically start loading the first page. | |
| 221 EXPECT_CALL(*page_cycler(), DidFinishLoad(kFrameID, kAboutURL, kIsMainFrame)) | |
| 222 .WillOnce(Invoke(page_cycler(), | |
| 223 &MockPageCycler::PageCyclerDidFinishLoad)); | |
| 224 FinishLoad(); | |
| 225 | |
| 226 // DNS server fail error message. | |
| 227 string16 error_string = | |
| 228 string16(ASCIIToUTF16(net::ErrorToString(net::ERR_DNS_SERVER_FAILED))); | |
| 229 EXPECT_CALL(*page_cycler(), | |
| 230 DidFailProvisionalLoad(kFrameID, kIsMainFrame, _, | |
| 231 net::ERR_DNS_SERVER_FAILED, error_string, | |
| 232 _)) | |
| 233 .WillOnce(Invoke(page_cycler(), | |
| 234 &MockPageCycler::PageCyclerDidFailProvisionalLoad)); | |
| 235 FailProvisionalLoad(net::ERR_DNS_SERVER_FAILED, error_string); | |
| 236 | |
| 237 // DNS time-out error message. | |
| 238 error_string = string16( | |
| 239 ASCIIToUTF16(net::ErrorToString(net::ERR_DNS_TIMED_OUT))); | |
| 240 EXPECT_CALL(*page_cycler(), | |
| 241 DidFailProvisionalLoad(kFrameID, | |
| 242 kIsMainFrame, _, net::ERR_DNS_TIMED_OUT, | |
| 243 error_string, _)) | |
| 244 .WillOnce(Invoke(page_cycler(), | |
| 245 &MockPageCycler::PageCyclerDidFailProvisionalLoad)); | |
| 246 | |
| 247 FailProvisionalLoad(net::ERR_DNS_TIMED_OUT, error_string); | |
| 248 | |
| 249 // DNS time-out error message. | |
| 250 error_string = string16( | |
| 251 ASCIIToUTF16(net::ErrorToString(net::ERR_INVALID_URL))); | |
| 252 EXPECT_CALL(*page_cycler(), | |
| 253 DidFailProvisionalLoad(kFrameID, kIsMainFrame, _, | |
| 254 net::ERR_INVALID_URL, error_string, _)) | |
| 255 .WillOnce(Invoke(page_cycler(), | |
| 256 &MockPageCycler::PageCyclerDidFailProvisionalLoad)); | |
| 257 FailProvisionalLoad(net::ERR_INVALID_URL, error_string); | |
| 258 | |
| 259 PumpLoop(); | |
| 260 | |
| 261 std::vector<std::string> errors_output = | |
| 262 GetLinesFromFile(errors_output_file_path()); | |
| 263 std::vector<std::string> errors_expected = | |
| 264 GetLinesFromFile(errors_expected_file_path()); | |
| 265 ASSERT_TRUE(LinesAreEqual(errors_output, errors_expected)); | |
|
Aaron Boodman
2012/05/29 21:39:08
Why not just compare the file contents as strings?
Devlin
2012/05/30 01:45:15
Done.
| |
| 266 file_util::Delete(errors_output_file_path(), false); | |
|
Aaron Boodman
2012/05/29 21:39:08
Did you consider using ScopedTempDir here too?
Devlin
2012/05/30 01:45:15
Done.
| |
| 267 } | |
| 268 | |
| 269 TEST_F(PageCyclerTest, StatsFile) { | |
| 270 const int kNumLoads = 4; | |
| 271 | |
| 272 ASSERT_TRUE(PathExists(errors_expected_file_path())); | |
| 273 ASSERT_TRUE(PathExists(about_url_file_path())); | |
| 274 | |
| 275 if (PathExists(stats_output_file_path())) | |
| 276 file_util::Delete(stats_output_file_path(), false); | |
| 277 ASSERT_FALSE(PathExists(stats_output_file_path())); | |
| 278 | |
| 279 set_page_cycler(new MockPageCycler(browser(), about_url_file_path(), | |
| 280 errors_output_file_path())); | |
| 281 page_cycler()->set_stats_file(stats_output_file_path()); | |
| 282 RunPageCycler(kSingleIteration); | |
| 283 | |
| 284 for (int i = 0; i < kNumLoads; ++i) { | |
| 285 EXPECT_CALL(*page_cycler(), DidFinishLoad( | |
| 286 kFrameID, kAboutURL, kIsMainFrame)) | |
| 287 .WillOnce(Invoke(page_cycler(), | |
| 288 &MockPageCycler::PageCyclerDidFinishLoad)); | |
| 289 FinishLoad(); | |
| 290 } | |
| 291 | |
| 292 PumpLoop(); | |
| 293 EXPECT_FALSE(PathExists(errors_output_file_path())); | |
| 294 ASSERT_TRUE(PathExists(stats_output_file_path())); | |
| 295 file_util::Delete(stats_output_file_path(), false); | |
| 296 } | |
| 297 | |
| 298 TEST_F(PageCyclerTest, KillBrowserAndAbort) { | |
| 299 ASSERT_TRUE(PathExists(abort_expected_file_path())); | |
| 300 ASSERT_TRUE(PathExists(errors_expected_file_path())); | |
| 301 ASSERT_TRUE(PathExists(about_url_file_path())); | |
| 302 | |
| 303 set_page_cycler(new MockPageCycler(browser(), | |
| 304 about_url_file_path(), | |
| 305 errors_output_file_path())); | |
| 306 RunPageCycler(kSingleIteration); | |
| 307 | |
| 308 EXPECT_CALL(*page_cycler(), DidFinishLoad(kFrameID, kAboutURL, kIsMainFrame)) | |
| 309 .WillOnce(Invoke(page_cycler(), | |
| 310 &MockPageCycler::PageCyclerDidFinishLoad)); | |
| 311 message_loop()->RunAllPending(); | |
| 312 | |
| 313 FinishLoad(); | |
| 314 | |
| 315 CloseBrowser(); | |
| 316 PumpLoop(); | |
| 317 std::vector<std::string> errors_output = | |
| 318 GetLinesFromFile(errors_output_file_path()); | |
| 319 std::vector<std::string> abort_expected = | |
| 320 GetLinesFromFile(abort_expected_file_path()); | |
| 321 ASSERT_TRUE(LinesAreEqual(errors_output, abort_expected)); | |
| 322 file_util::Delete(errors_output_file_path(), false); | |
| 323 } | |
| 324 | |
| 325 TEST_F(PageCyclerTest, MultipleIterations) { | |
| 326 const int kMultipleIterations = 3; | |
| 327 const int kNumLoads = 10; | |
| 328 | |
| 329 ASSERT_TRUE(PathExists(about_url_file_path())); | |
| 330 | |
| 331 set_page_cycler(new MockPageCycler(browser(), | |
| 332 about_url_file_path(), | |
| 333 errors_output_file_path())); | |
| 334 page_cycler()->set_stats_file(stats_output_file_path()); | |
| 335 RunPageCycler(kMultipleIterations); | |
| 336 | |
| 337 EXPECT_CALL(*page_cycler(), DidFinishLoad(kFrameID, kAboutURL, kIsMainFrame)) | |
| 338 .WillRepeatedly(Invoke(page_cycler(), | |
| 339 &MockPageCycler::PageCyclerDidFinishLoad)); | |
| 340 | |
| 341 for (int i = 0; i < kNumLoads; ++i) | |
| 342 FinishLoad(); | |
| 343 | |
| 344 PumpLoop(); | |
| 345 EXPECT_FALSE(PathExists(errors_output_file_path())); | |
| 346 ASSERT_TRUE(PathExists(stats_output_file_path())); | |
| 347 file_util::Delete(stats_output_file_path(), false); | |
| 348 } | |
| OLD | NEW |