| OLD | NEW |
| 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/browsing_data/history_counter.h" | 5 #include "chrome/browser/browsing_data/history_counter.h" |
| 6 | 6 |
| 7 #include "base/prefs/pref_service.h" | 7 #include "base/prefs/pref_service.h" |
| 8 #include "base/run_loop.h" | 8 #include "base/run_loop.h" |
| 9 #include "base/strings/string_number_conversions.h" | |
| 10 #include "chrome/browser/history/history_service_factory.h" | 9 #include "chrome/browser/history/history_service_factory.h" |
| 11 #include "chrome/browser/history/web_history_service_factory.h" | 10 #include "chrome/browser/history/web_history_service_factory.h" |
| 12 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" | 11 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" |
| 13 #include "chrome/browser/signin/signin_manager_factory.h" | 12 #include "chrome/browser/signin/signin_manager_factory.h" |
| 14 #include "chrome/browser/sync/test/integration/sync_test.h" | 13 #include "chrome/browser/sync/test/integration/sync_test.h" |
| 15 #include "chrome/browser/ui/browser.h" | 14 #include "chrome/browser/ui/browser.h" |
| 16 #include "chrome/common/pref_names.h" | 15 #include "chrome/common/pref_names.h" |
| 17 #include "components/browser_sync/browser/profile_sync_service.h" | 16 #include "components/browser_sync/browser/profile_sync_service.h" |
| 17 #include "components/history/core/browser/fake_web_history_service.h" |
| 18 #include "components/history/core/browser/history_service.h" | 18 #include "components/history/core/browser/history_service.h" |
| 19 #include "components/history/core/browser/web_history_service.h" | 19 #include "components/history/core/browser/web_history_service.h" |
| 20 #include "components/signin/core/browser/profile_oauth2_token_service.h" | 20 #include "components/signin/core/browser/profile_oauth2_token_service.h" |
| 21 #include "components/signin/core/browser/signin_manager.h" | 21 #include "components/signin/core/browser/signin_manager.h" |
| 22 #include "net/base/url_util.h" | |
| 23 #include "net/http/http_status_code.h" | 22 #include "net/http/http_status_code.h" |
| 24 #include "url/gurl.h" | 23 #include "url/gurl.h" |
| 25 | 24 |
| 26 namespace { | 25 namespace { |
| 27 | 26 |
| 28 class HistoryCounterTest : public SyncTest { | 27 class HistoryCounterTest : public SyncTest { |
| 29 public: | 28 public: |
| 30 HistoryCounterTest() : SyncTest(SINGLE_CLIENT) { | 29 HistoryCounterTest() : SyncTest(SINGLE_CLIENT) { |
| 31 // TODO(msramek): Only one of the test cases, RestartOnSyncChange, is a Sync | 30 // TODO(msramek): Only one of the test cases, RestartOnSyncChange, is a Sync |
| 32 // integration test. Extract it and move it to the rest of integration tests | 31 // integration test. Extract it and move it to the rest of integration tests |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 | 228 |
| 230 SetDeletionPeriodPref(BrowsingDataRemover::FOUR_WEEKS); | 229 SetDeletionPeriodPref(BrowsingDataRemover::FOUR_WEEKS); |
| 231 WaitForCounting(); | 230 WaitForCounting(); |
| 232 EXPECT_EQ(8u, GetLocalResult()); | 231 EXPECT_EQ(8u, GetLocalResult()); |
| 233 | 232 |
| 234 SetDeletionPeriodPref(BrowsingDataRemover::EVERYTHING); | 233 SetDeletionPeriodPref(BrowsingDataRemover::EVERYTHING); |
| 235 WaitForCounting(); | 234 WaitForCounting(); |
| 236 EXPECT_EQ(9u, GetLocalResult()); | 235 EXPECT_EQ(9u, GetLocalResult()); |
| 237 } | 236 } |
| 238 | 237 |
| 239 class FakeWebHistoryService : public history::WebHistoryService { | |
| 240 public: | |
| 241 | |
| 242 class Request : public history::WebHistoryService::Request { | |
| 243 public: | |
| 244 Request(FakeWebHistoryService* service, | |
| 245 bool emulate_success, | |
| 246 int emulate_response_code, | |
| 247 const CompletionCallback& callback, | |
| 248 base::Time begin, | |
| 249 base::Time end) | |
| 250 : service_(service), | |
| 251 emulate_success_(emulate_success), | |
| 252 emulate_response_code_(emulate_response_code), | |
| 253 callback_(callback), | |
| 254 begin_(begin), | |
| 255 end_(end), | |
| 256 is_pending_(false) { | |
| 257 } | |
| 258 | |
| 259 bool IsPending() override { | |
| 260 return is_pending_; | |
| 261 } | |
| 262 | |
| 263 int GetResponseCode() override { | |
| 264 return emulate_response_code_; | |
| 265 } | |
| 266 | |
| 267 const std::string& GetResponseBody() override { | |
| 268 // It is currently not important to mimic the exact format of visits, | |
| 269 // just to get the correct number. | |
| 270 response_body_ = "{ \"event\": ["; | |
| 271 for (int i = 0; | |
| 272 i < service_->GetNumberOfVisitsBetween(begin_, end_); ++i) { | |
| 273 response_body_ += i ? ", {}" : "{}"; | |
| 274 } | |
| 275 response_body_ += "] }"; | |
| 276 return response_body_; | |
| 277 } | |
| 278 | |
| 279 void SetPostData(const std::string& post_data) override {}; | |
| 280 | |
| 281 void Start() override { | |
| 282 is_pending_ = true; | |
| 283 callback_.Run(this, emulate_success_); | |
| 284 } | |
| 285 | |
| 286 private: | |
| 287 FakeWebHistoryService* service_; | |
| 288 bool emulate_success_; | |
| 289 int emulate_response_code_; | |
| 290 const CompletionCallback& callback_; | |
| 291 base::Time begin_; | |
| 292 base::Time end_; | |
| 293 bool is_pending_; | |
| 294 std::string response_body_; | |
| 295 | |
| 296 DISALLOW_COPY_AND_ASSIGN(Request); | |
| 297 }; | |
| 298 | |
| 299 explicit FakeWebHistoryService(Profile* profile) | |
| 300 : history::WebHistoryService( | |
| 301 ProfileOAuth2TokenServiceFactory::GetForProfile(profile), | |
| 302 SigninManagerFactory::GetForProfile(profile), | |
| 303 profile->GetRequestContext()) { | |
| 304 } | |
| 305 | |
| 306 void SetRequestOptions(bool emulate_success, int emulate_response_code) { | |
| 307 emulate_success_ = emulate_success; | |
| 308 emulate_response_code_ = emulate_response_code; | |
| 309 } | |
| 310 | |
| 311 void AddSyncedVisit(std::string url, base::Time timestamp) { | |
| 312 visits_.push_back(make_pair(url, timestamp)); | |
| 313 } | |
| 314 | |
| 315 void ClearSyncedVisits() { | |
| 316 visits_.clear(); | |
| 317 } | |
| 318 | |
| 319 int GetNumberOfVisitsBetween(const base::Time& begin, const base::Time& end) { | |
| 320 int result = 0; | |
| 321 for (const Visit& visit : visits_) { | |
| 322 if (visit.second >= begin && visit.second < end) | |
| 323 ++result; | |
| 324 } | |
| 325 return result; | |
| 326 } | |
| 327 | |
| 328 private: | |
| 329 base::Time GetTimeForKeyInQuery( | |
| 330 const GURL& url, const std::string& key) { | |
| 331 std::string value; | |
| 332 if (!net::GetValueForKeyInQuery(url, key, &value)) | |
| 333 return base::Time(); | |
| 334 | |
| 335 int64 us; | |
| 336 if (!base::StringToInt64(value, &us)) | |
| 337 return base::Time(); | |
| 338 return base::Time::UnixEpoch() + base::TimeDelta::FromMicroseconds(us); | |
| 339 } | |
| 340 | |
| 341 Request* CreateRequest(const GURL& url, | |
| 342 const CompletionCallback& callback) override { | |
| 343 // Find the time range endpoints in the URL. | |
| 344 base::Time begin = GetTimeForKeyInQuery(url, "min"); | |
| 345 base::Time end = GetTimeForKeyInQuery(url, "max"); | |
| 346 | |
| 347 if (end.is_null()) | |
| 348 end = base::Time::Max(); | |
| 349 | |
| 350 return new Request( | |
| 351 this, emulate_success_, emulate_response_code_, callback, begin, end); | |
| 352 } | |
| 353 | |
| 354 // Parameters for the fake request. | |
| 355 bool emulate_success_; | |
| 356 int emulate_response_code_; | |
| 357 | |
| 358 // Fake visits storage. | |
| 359 typedef std::pair<std::string, base::Time> Visit; | |
| 360 std::vector<Visit> visits_; | |
| 361 | |
| 362 DISALLOW_COPY_AND_ASSIGN(FakeWebHistoryService); | |
| 363 }; | |
| 364 | |
| 365 // Test the behavior for a profile that syncs history. | 238 // Test the behavior for a profile that syncs history. |
| 366 IN_PROC_BROWSER_TEST_F(HistoryCounterTest, Synced) { | 239 IN_PROC_BROWSER_TEST_F(HistoryCounterTest, Synced) { |
| 367 // WebHistoryService makes network requests, so we need to use a fake one | 240 // WebHistoryService makes network requests, so we need to use a fake one |
| 368 // for testing. | 241 // for testing. |
| 369 // TODO(msramek): Move this to a separate file, next to WebHistoryService. | 242 scoped_ptr<history::FakeWebHistoryService> service( |
| 370 scoped_ptr<FakeWebHistoryService> service( | 243 new history::FakeWebHistoryService( |
| 371 new FakeWebHistoryService(browser()->profile())); | 244 ProfileOAuth2TokenServiceFactory::GetForProfile(browser()->profile()), |
| 245 SigninManagerFactory::GetForProfile(browser()->profile()), |
| 246 browser()->profile()->GetRequestContext())); |
| 372 | 247 |
| 373 HistoryCounter counter; | 248 HistoryCounter counter; |
| 374 counter.SetWebHistoryServiceForTesting(service.get()); | 249 counter.SetWebHistoryServiceForTesting(service.get()); |
| 375 counter.Init(browser()->profile(), | 250 counter.Init(browser()->profile(), |
| 376 base::Bind(&HistoryCounterTest::Callback, | 251 base::Bind(&HistoryCounterTest::Callback, |
| 377 base::Unretained(this))); | 252 base::Unretained(this))); |
| 378 | 253 |
| 379 // No entries locally and no entries in Sync. | 254 // No entries locally and no entries in Sync. |
| 380 service->SetRequestOptions(true /* success */, net::HTTP_OK); | 255 service->SetupFakeResponse(true /* success */, net::HTTP_OK); |
| 381 counter.Restart(); | 256 counter.Restart(); |
| 382 WaitForCounting(); | 257 WaitForCounting(); |
| 383 EXPECT_EQ(0u, GetLocalResult()); | 258 EXPECT_EQ(0u, GetLocalResult()); |
| 384 EXPECT_FALSE(HasSyncedVisits()); | 259 EXPECT_FALSE(HasSyncedVisits()); |
| 385 | 260 |
| 386 // No entries locally. There are some entries in Sync, but they are out of the | 261 // No entries locally. There are some entries in Sync, but they are out of the |
| 387 // time range. | 262 // time range. |
| 388 SetDeletionPeriodPref(BrowsingDataRemover::LAST_HOUR); | 263 SetDeletionPeriodPref(BrowsingDataRemover::LAST_HOUR); |
| 389 service->AddSyncedVisit( | 264 service->AddSyncedVisit( |
| 390 "www.google.com", GetCurrentTime() - base::TimeDelta::FromHours(2)); | 265 "www.google.com", GetCurrentTime() - base::TimeDelta::FromHours(2)); |
| 391 service->AddSyncedVisit( | 266 service->AddSyncedVisit( |
| 392 "www.chrome.com", GetCurrentTime() - base::TimeDelta::FromHours(2)); | 267 "www.chrome.com", GetCurrentTime() - base::TimeDelta::FromHours(2)); |
| 393 service->SetRequestOptions(true /* success */, net::HTTP_OK); | 268 service->SetupFakeResponse(true /* success */, net::HTTP_OK); |
| 394 counter.Restart(); | 269 counter.Restart(); |
| 395 WaitForCounting(); | 270 WaitForCounting(); |
| 396 EXPECT_EQ(0u, GetLocalResult()); | 271 EXPECT_EQ(0u, GetLocalResult()); |
| 397 EXPECT_FALSE(HasSyncedVisits()); | 272 EXPECT_FALSE(HasSyncedVisits()); |
| 398 | 273 |
| 399 // No entries locally, but some entries in Sync. | 274 // No entries locally, but some entries in Sync. |
| 400 service->AddSyncedVisit("www.google.com", GetCurrentTime()); | 275 service->AddSyncedVisit("www.google.com", GetCurrentTime()); |
| 401 service->SetRequestOptions(true /* success */, net::HTTP_OK); | 276 service->SetupFakeResponse(true /* success */, net::HTTP_OK); |
| 402 counter.Restart(); | 277 counter.Restart(); |
| 403 WaitForCounting(); | 278 WaitForCounting(); |
| 404 EXPECT_EQ(0u, GetLocalResult()); | 279 EXPECT_EQ(0u, GetLocalResult()); |
| 405 EXPECT_TRUE(HasSyncedVisits()); | 280 EXPECT_TRUE(HasSyncedVisits()); |
| 406 | 281 |
| 407 // To err on the safe side, if the server request fails, we assume that there | 282 // To err on the safe side, if the server request fails, we assume that there |
| 408 // might be some items on the server. | 283 // might be some items on the server. |
| 409 service->SetRequestOptions(true /* success */, | 284 service->SetupFakeResponse(true /* success */, |
| 410 net::HTTP_INTERNAL_SERVER_ERROR); | 285 net::HTTP_INTERNAL_SERVER_ERROR); |
| 411 counter.Restart(); | 286 counter.Restart(); |
| 412 WaitForCounting(); | 287 WaitForCounting(); |
| 413 EXPECT_EQ(0u, GetLocalResult()); | 288 EXPECT_EQ(0u, GetLocalResult()); |
| 414 EXPECT_TRUE(HasSyncedVisits()); | 289 EXPECT_TRUE(HasSyncedVisits()); |
| 415 | 290 |
| 416 // Same when the entire query fails. | 291 // Same when the entire query fails. |
| 417 service->SetRequestOptions(false /* success */, | 292 service->SetupFakeResponse(false /* success */, |
| 418 net::HTTP_INTERNAL_SERVER_ERROR); | 293 net::HTTP_INTERNAL_SERVER_ERROR); |
| 419 counter.Restart(); | 294 counter.Restart(); |
| 420 WaitForCounting(); | 295 WaitForCounting(); |
| 421 EXPECT_EQ(0u, GetLocalResult()); | 296 EXPECT_EQ(0u, GetLocalResult()); |
| 422 EXPECT_TRUE(HasSyncedVisits()); | 297 EXPECT_TRUE(HasSyncedVisits()); |
| 423 | 298 |
| 424 // Nonzero local count, nonempty sync. | 299 // Nonzero local count, nonempty sync. |
| 425 AddVisit("https://www.google.com"); | 300 AddVisit("https://www.google.com"); |
| 426 AddVisit("https://www.chrome.com"); | 301 AddVisit("https://www.chrome.com"); |
| 427 service->SetRequestOptions(true /* success */, net::HTTP_OK); | 302 service->SetupFakeResponse(true /* success */, net::HTTP_OK); |
| 428 counter.Restart(); | 303 counter.Restart(); |
| 429 WaitForCounting(); | 304 WaitForCounting(); |
| 430 EXPECT_EQ(2u, GetLocalResult()); | 305 EXPECT_EQ(2u, GetLocalResult()); |
| 431 EXPECT_TRUE(HasSyncedVisits()); | 306 EXPECT_TRUE(HasSyncedVisits()); |
| 432 | 307 |
| 433 // Nonzero local count, empty sync. | 308 // Nonzero local count, empty sync. |
| 434 service->ClearSyncedVisits(); | 309 service->ClearSyncedVisits(); |
| 435 service->SetRequestOptions(true /* success */, net::HTTP_OK); | 310 service->SetupFakeResponse(true /* success */, net::HTTP_OK); |
| 436 counter.Restart(); | 311 counter.Restart(); |
| 437 WaitForCounting(); | 312 WaitForCounting(); |
| 438 EXPECT_EQ(2u, GetLocalResult()); | 313 EXPECT_EQ(2u, GetLocalResult()); |
| 439 EXPECT_FALSE(HasSyncedVisits()); | 314 EXPECT_FALSE(HasSyncedVisits()); |
| 440 } | 315 } |
| 441 | 316 |
| 442 // Test that the counting restarts when history sync state changes. | 317 // Test that the counting restarts when history sync state changes. |
| 443 // TODO(crbug.com/553421): Enable this test and move it to the | 318 // TODO(crbug.com/553421): Enable this test and move it to the |
| 444 // sync/test/integration directory. | 319 // sync/test/integration directory. |
| 445 IN_PROC_BROWSER_TEST_F(HistoryCounterTest, DISABLED_RestartOnSyncChange) { | 320 IN_PROC_BROWSER_TEST_F(HistoryCounterTest, DISABLED_RestartOnSyncChange) { |
| 446 // Set up the Sync client. | 321 // Set up the Sync client. |
| 447 ASSERT_TRUE(SetupClients()); | 322 ASSERT_TRUE(SetupClients()); |
| 448 static const int kFirstProfileIndex = 0; | 323 static const int kFirstProfileIndex = 0; |
| 449 ProfileSyncService* sync_service = GetSyncService(kFirstProfileIndex); | 324 ProfileSyncService* sync_service = GetSyncService(kFirstProfileIndex); |
| 450 Profile* profile = GetProfile(kFirstProfileIndex); | 325 Profile* profile = GetProfile(kFirstProfileIndex); |
| 451 | 326 |
| 452 // Set up the fake web history service and the counter. | 327 // Set up the fake web history service and the counter. |
| 453 scoped_ptr<FakeWebHistoryService> web_history_service( | 328 scoped_ptr<history::FakeWebHistoryService> web_history_service( |
| 454 new FakeWebHistoryService(profile)); | 329 new history::FakeWebHistoryService( |
| 330 ProfileOAuth2TokenServiceFactory::GetForProfile(browser()->profile()), |
| 331 SigninManagerFactory::GetForProfile(browser()->profile()), |
| 332 browser()->profile()->GetRequestContext())); |
| 455 HistoryCounter counter; | 333 HistoryCounter counter; |
| 456 counter.SetWebHistoryServiceForTesting(web_history_service.get()); | 334 counter.SetWebHistoryServiceForTesting(web_history_service.get()); |
| 457 counter.Init(profile, | 335 counter.Init(profile, |
| 458 base::Bind(&HistoryCounterTest::Callback, | 336 base::Bind(&HistoryCounterTest::Callback, |
| 459 base::Unretained(this))); | 337 base::Unretained(this))); |
| 460 | 338 |
| 461 // Note that some Sync operations notify observers immediately (and thus there | 339 // Note that some Sync operations notify observers immediately (and thus there |
| 462 // is no need to call |WaitForCounting()|; in fact, it would block the test), | 340 // is no need to call |WaitForCounting()|; in fact, it would block the test), |
| 463 // while other operations only post the task on UI thread's message loop | 341 // while other operations only post the task on UI thread's message loop |
| 464 // (which requires calling |WaitForCounting()| for them to run). Therefore, | 342 // (which requires calling |WaitForCounting()| for them to run). Therefore, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 // history deletion did not change. However, in reality we can get two | 388 // history deletion did not change. However, in reality we can get two |
| 511 // notifications, one that history sync has stopped and another that it is | 389 // notifications, one that history sync has stopped and another that it is |
| 512 // active again. | 390 // active again. |
| 513 | 391 |
| 514 // Stopping the Sync service triggers a restart. | 392 // Stopping the Sync service triggers a restart. |
| 515 sync_service->RequestStop(sync_driver::SyncService::CLEAR_DATA); | 393 sync_service->RequestStop(sync_driver::SyncService::CLEAR_DATA); |
| 516 WaitForCountingOrConfirmFinished(); | 394 WaitForCountingOrConfirmFinished(); |
| 517 } | 395 } |
| 518 | 396 |
| 519 } // namespace | 397 } // namespace |
| OLD | NEW |