15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/test/integration/typed_urls_helper.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h"
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/common/cancelable_request.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_backend.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_db_task.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/history/history_service.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_service_factory.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_types.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/test/integration/sync_test.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sync_datatype_helper::test;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FlushHistoryDBQueueTask : public history::HistoryDBTask {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit FlushHistoryDBQueueTask(base::WaitableEvent* event)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : wait_event_(event) {}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool RunOnDBThread(history::HistoryBackend* backend,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::HistoryDatabase* db) OVERRIDE {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wait_event_->Signal();
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DoneRunOnMainThread() OVERRIDE {}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~FlushHistoryDBQueueTask() {}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent* wait_event_;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GetTypedUrlsTask : public history::HistoryDBTask {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetTypedUrlsTask(history::URLRows* rows, base::WaitableEvent* event)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : rows_(rows), wait_event_(event) {}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool RunOnDBThread(history::HistoryBackend* backend,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::HistoryDatabase* db) OVERRIDE {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fetch the typed URLs.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend->GetAllTypedURLs(rows_);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wait_event_->Signal();
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DoneRunOnMainThread() OVERRIDE {}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~GetTypedUrlsTask() {}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRows* rows_;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent* wait_event_;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GetUrlTask : public history::HistoryDBTask {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetUrlTask(const GURL& url,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             history::URLRow* row,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             bool* found,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             base::WaitableEvent* event)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : url_(url), row_(row), wait_event_(event), found_(found) {}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool RunOnDBThread(history::HistoryBackend* backend,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::HistoryDatabase* db) OVERRIDE {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fetch the typed URLs.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *found_ = backend->GetURL(url_, row_);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wait_event_->Signal();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DoneRunOnMainThread() OVERRIDE {}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~GetUrlTask() {}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url_;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRow* row_;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent* wait_event_;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool* found_;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class GetVisitsTask : public history::HistoryDBTask {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetVisitsTask(history::URLID id,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                history::VisitVector* visits,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                base::WaitableEvent* event)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : id_(id), visits_(visits), wait_event_(event) {}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool RunOnDBThread(history::HistoryBackend* backend,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::HistoryDatabase* db) OVERRIDE {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fetch the visits.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend->GetVisitsForURL(id_, visits_);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wait_event_->Signal();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DoneRunOnMainThread() OVERRIDE {}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~GetVisitsTask() {}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLID id_;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::VisitVector* visits_;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent* wait_event_;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RemoveVisitsTask : public history::HistoryDBTask {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RemoveVisitsTask(const history::VisitVector& visits,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::WaitableEvent* event)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : visits_(visits), wait_event_(event) {}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool RunOnDBThread(history::HistoryBackend* backend,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             history::HistoryDatabase* db) OVERRIDE {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fetch the visits.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend->RemoveVisits(visits_);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wait_event_->Signal();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DoneRunOnMainThread() OVERRIDE {}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~RemoveVisitsTask() {}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const history::VisitVector& visits_;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent* wait_event_;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Waits for the history DB thread to finish executing its current set of
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tasks.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WaitForHistoryDBThread(int index) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelableRequestConsumer cancelable_consumer;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryService* service = HistoryServiceFactory::GetForProfileWithoutCreating(
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test()->GetProfile(index));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent wait_event(true, false);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service->ScheduleDBTask(new FlushHistoryDBQueueTask(&wait_event),
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          &cancelable_consumer);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wait_event.Wait();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a URLRow in the specified HistoryService with the passed transition
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// type.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddToHistory(HistoryService* service,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const GURL& url,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  content::PageTransition transition,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  history::VisitSource source,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const base::Time& timestamp) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service->AddPage(url,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   timestamp,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   NULL, // scope
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   1234, // page_id
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   GURL(),  // referrer
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   history::RedirectList(),
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   transition,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   source,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   false);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service->SetPageTitle(url, ASCIIToUTF16(url.spec() + " - title"));
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)history::URLRows GetTypedUrlsFromHistoryService(HistoryService* service) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelableRequestConsumer cancelable_consumer;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRows rows;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent wait_event(true, false);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service->ScheduleDBTask(new GetTypedUrlsTask(&rows, &wait_event),
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          &cancelable_consumer);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wait_event.Wait();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rows;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetUrlFromHistoryService(HistoryService* service,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const GURL& url, history::URLRow* row) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelableRequestConsumer cancelable_consumer;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent wait_event(true, false);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool found;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service->ScheduleDBTask(new GetUrlTask(url, row, &found, &wait_event),
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          &cancelable_consumer);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wait_event.Wait();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return found;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)history::VisitVector GetVisitsFromHistoryService(HistoryService* service,
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 history::URLID id) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelableRequestConsumer cancelable_consumer;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent wait_event(true, false);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::VisitVector visits;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service->ScheduleDBTask(new GetVisitsTask(id, &visits, &wait_event),
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          &cancelable_consumer);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wait_event.Wait();
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return visits;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RemoveVisitsFromHistoryService(HistoryService* service,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const history::VisitVector& visits) {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelableRequestConsumer cancelable_consumer;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent wait_event(true, false);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service->ScheduleDBTask(new RemoveVisitsTask(visits, &wait_event),
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          &cancelable_consumer);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wait_event.Wait();
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static base::Time* timestamp = NULL;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace typed_urls_helper {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)history::URLRows GetTypedUrlsFromClient(int index) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryService* service = HistoryServiceFactory::GetForProfileWithoutCreating(
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test()->GetProfile(index));
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetTypedUrlsFromHistoryService(service);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetUrlFromClient(int index, const GURL& url, history::URLRow* row) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryService* service = HistoryServiceFactory::GetForProfileWithoutCreating(
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test()->GetProfile(index));
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetUrlFromHistoryService(service, url, row);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)history::VisitVector GetVisitsFromClient(int index, history::URLID id) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryService* service = HistoryServiceFactory::GetForProfileWithoutCreating(
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test()->GetProfile(index));
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetVisitsFromHistoryService(service, id);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RemoveVisitsFromClient(int index, const history::VisitVector& visits) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryService* service = HistoryServiceFactory::GetForProfileWithoutCreating(
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test()->GetProfile(index));
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RemoveVisitsFromHistoryService(service, visits);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Time GetTimestamp() {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The history subsystem doesn't like identical timestamps for page visits,
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and it will massage the visit timestamps if we try to use identical
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // values, which can lead to spurious errors. So make sure all timestamps
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are unique.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!::timestamp)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::timestamp = new base::Time(base::Time::Now());
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time original = *::timestamp;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *::timestamp += base::TimeDelta::FromMilliseconds(1);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return original;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddUrlToHistory(int index, const GURL& url) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddUrlToHistoryWithTransition(index, url, content::PAGE_TRANSITION_TYPED,
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                history::SOURCE_BROWSED);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddUrlToHistoryWithTransition(int index,
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const GURL& url,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   content::PageTransition transition,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   history::VisitSource source) {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time timestamp = GetTimestamp();
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddUrlToHistoryWithTimestamp(index, url, transition, source, timestamp);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddUrlToHistoryWithTimestamp(int index,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const GURL& url,
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  content::PageTransition transition,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  history::VisitSource source,
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const base::Time& timestamp) {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddToHistory(HistoryServiceFactory::GetForProfileWithoutCreating(
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   test()->GetProfile(index)),
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               url,
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               transition,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               source,
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               timestamp);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (test()->use_verifier())
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddToHistory(
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HistoryServiceFactory::GetForProfile(test()->verifier(),
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             Profile::IMPLICIT_ACCESS),
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url,
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        transition,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        source,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        timestamp);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait until the AddPage() request has completed so we know the change has
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // filtered down to the sync observers (don't need to wait for the
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // verifier profile since it doesn't sync).
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WaitForHistoryDBThread(index);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeleteUrlFromHistory(int index, const GURL& url) {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryServiceFactory::GetForProfileWithoutCreating(
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test()->GetProfile(index))->DeleteURL(url);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (test()->use_verifier())
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HistoryServiceFactory::GetForProfile(test()->verifier(),
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         Profile::IMPLICIT_ACCESS)->
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DeleteURL(url);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WaitForHistoryDBThread(index);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeleteUrlsFromHistory(int index, const std::vector<GURL>& urls) {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryServiceFactory::GetForProfileWithoutCreating(
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test()->GetProfile(index))->DeleteURLsForTest(urls);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (test()->use_verifier())
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HistoryServiceFactory::GetForProfile(test()->verifier(),
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         Profile::IMPLICIT_ACCESS)->
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DeleteURLsForTest(urls);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WaitForHistoryDBThread(index);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AssertURLRowVectorsAreEqual(const history::URLRows& left,
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const history::URLRows& right) {
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(left.size(), right.size());
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < left.size(); ++i) {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // URLs could be out-of-order, so look for a matching URL in the second
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // array.
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool found = false;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t j = 0; j < right.size(); ++j) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (left[i].url() == right[j].url()) {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AssertURLRowsAreEqual(left[i], right[j]);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        found = true;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(found);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AreVisitsEqual(const history::VisitVector& visit1,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const history::VisitVector& visit2) {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (visit1.size() != visit2.size())
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < visit1.size(); ++i) {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (visit1[i].transition != visit2[i].transition)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (visit1[i].visit_time != visit2[i].visit_time)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AreVisitsUnique(const history::VisitVector& visits) {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time t = base::Time::FromInternalValue(0);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < visits.size(); ++i) {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (t == visits[i].visit_time)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    t = visits[i].visit_time;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AssertURLRowsAreEqual(
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const history::URLRow& left, const history::URLRow& right) {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(left.url(), right.url());
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(left.title(), right.title());
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(left.visit_count(), right.visit_count());
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(left.typed_count(), right.typed_count());
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(left.last_visit(), right.last_visit());
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(left.hidden(), right.hidden());
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AssertAllProfilesHaveSameURLsAsVerifier() {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryService* verifier_service =
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HistoryServiceFactory::GetForProfile(test()->verifier(),
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           Profile::IMPLICIT_ACCESS);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLRows verifier_urls =
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetTypedUrlsFromHistoryService(verifier_service);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < test()->num_clients(); ++i) {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::URLRows urls = GetTypedUrlsFromClient(i);
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AssertURLRowVectorsAreEqual(verifier_urls, urls);
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace typed_urls_helper
375