This source file includes following definitions.
- saved_cmdline_
- WaitOnThread
- CheckReadData
- CheckReadFilteredData
- CheckStringTableSizes
- CheckQueueSize
- CheckWrapper
- TimeoutCallback
- RetrieveActions_FetchFilteredActions0
- RetrieveActions_FetchFilteredActions1
- RetrieveActions_FetchFilteredActions2
- RetrieveActions_FetchFilteredActions300
- Arguments_Stripped
- Arguments_GetSinglesAction
- Arguments_GetTodaysActions
- Arguments_GetOlderActions
- Arguments_CheckMergeCount
- Arguments_CheckMergeCountAndTime
- AllURLsRemoved
- SomeURLsRemoved
- CheckDuplicates
- CheckAction
- CheckRemoveActions
- AllActionsDeleted
- NoActionsDeleted
- Action1Deleted
- Action2Deleted
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "base/cancelable_callback.h"
#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/simple_test_clock.h"
#include "base/test/test_timeouts.h"
#include "chrome/browser/extensions/activity_log/activity_log.h"
#include "chrome/browser/extensions/activity_log/counting_policy.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "extensions/common/extension_builder.h"
#include "sql/statement.h"
#include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/device_settings_service.h"
#endif
using content::BrowserThread;
namespace extensions {
class CountingPolicyTest : public testing::Test {
 public:
  CountingPolicyTest()
      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
        saved_cmdline_(CommandLine::NO_PROGRAM) {
#if defined OS_CHROMEOS
    test_user_manager_.reset(new chromeos::ScopedTestUserManager());
#endif
    CommandLine command_line(CommandLine::NO_PROGRAM);
    saved_cmdline_ = *CommandLine::ForCurrentProcess();
    profile_.reset(new TestingProfile());
    CommandLine::ForCurrentProcess()->AppendSwitch(
        switches::kEnableExtensionActivityLogging);
    extension_service_ = static_cast<TestExtensionSystem*>(
        ExtensionSystem::Get(profile_.get()))->CreateExtensionService
            (&command_line, base::FilePath(), false);
  }
  virtual ~CountingPolicyTest() {
#if defined OS_CHROMEOS
    test_user_manager_.reset();
#endif
    base::RunLoop().RunUntilIdle();
    profile_.reset(NULL);
    base::RunLoop().RunUntilIdle();
    
    *CommandLine::ForCurrentProcess() = saved_cmdline_;
  }
  
  void WaitOnThread(const BrowserThread::ID& thread) {
    BrowserThread::PostTaskAndReply(
        thread,
        FROM_HERE,
        base::Bind(&base::DoNothing),
        base::MessageLoop::current()->QuitClosure());
    base::MessageLoop::current()->Run();
  }
  
  
  void CheckReadData(
      ActivityLogDatabasePolicy* policy,
      const std::string& extension_id,
      int day,
      const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker) {
    CheckReadFilteredData(
        policy, extension_id, Action::ACTION_ANY, "", "", "", day, checker);
  }
  
  
  void CheckReadFilteredData(
      ActivityLogDatabasePolicy* policy,
      const std::string& extension_id,
      const Action::ActionType type,
      const std::string& api_name,
      const std::string& page_url,
      const std::string& arg_url,
      int day,
      const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker) {
    
    
    
    policy->ReadFilteredData(
        extension_id,
        type,
        api_name,
        page_url,
        arg_url,
        day,
        base::Bind(&CountingPolicyTest::CheckWrapper,
                   checker,
                   base::MessageLoop::current()->QuitClosure()));
    
    
    base::CancelableClosure timeout(
        base::Bind(&CountingPolicyTest::TimeoutCallback));
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE, timeout.callback(), TestTimeouts::action_timeout());
    
    
    base::MessageLoop::current()->Run();
    timeout.Cancel();
  }
  
  
  static void CheckStringTableSizes(CountingPolicy* policy,
                                    int string_size,
                                    int url_size) {
    sql::Connection* db = policy->GetDatabaseConnection();
    sql::Statement statement1(db->GetCachedStatement(
        sql::StatementID(SQL_FROM_HERE), "SELECT COUNT(*) FROM string_ids"));
    ASSERT_TRUE(statement1.Step());
    ASSERT_EQ(string_size, statement1.ColumnInt(0));
    sql::Statement statement2(db->GetCachedStatement(
        sql::StatementID(SQL_FROM_HERE), "SELECT COUNT(*) FROM url_ids"));
    ASSERT_TRUE(statement2.Step());
    ASSERT_EQ(url_size, statement2.ColumnInt(0));
  }
  
  
  static void CheckQueueSize(CountingPolicy* policy) {
    
    
    ASSERT_LE(policy->queued_actions_.size(), 200U);
  }
  static void CheckWrapper(
      const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker,
      const base::Closure& done,
      scoped_ptr<Action::ActionVector> results) {
    checker.Run(results.Pass());
    done.Run();
  }
  static void TimeoutCallback() {
    base::MessageLoop::current()->QuitWhenIdle();
    FAIL() << "Policy test timed out waiting for results";
  }
  static void RetrieveActions_FetchFilteredActions0(
      scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
    ASSERT_EQ(0, static_cast<int>(i->size()));
  }
  static void RetrieveActions_FetchFilteredActions1(
      scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
    ASSERT_EQ(1, static_cast<int>(i->size()));
  }
  static void RetrieveActions_FetchFilteredActions2(
      scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
    ASSERT_EQ(2, static_cast<int>(i->size()));
  }
  static void RetrieveActions_FetchFilteredActions300(
      scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
    ASSERT_EQ(300, static_cast<int>(i->size()));
  }
  static void Arguments_Stripped(scoped_ptr<Action::ActionVector> i) {
    scoped_refptr<Action> last = i->front();
    CheckAction(*last, "odlameecjipmbmbejkplpemijjgpljce",
                Action::ACTION_API_CALL, "extension.connect",
                "[\"hello\",\"world\"]", "", "", "", 1);
  }
  static void Arguments_GetSinglesAction(
      scoped_ptr<Action::ActionVector> actions) {
    ASSERT_EQ(1, static_cast<int>(actions->size()));
    CheckAction(*actions->at(0), "punky", Action::ACTION_DOM_ACCESS, "lets",
                "", "http://www.google.com/", "", "", 1);
  }
  static void Arguments_GetTodaysActions(
      scoped_ptr<Action::ActionVector> actions) {
    ASSERT_EQ(3, static_cast<int>(actions->size()));
    CheckAction(*actions->at(0), "punky", Action::ACTION_API_CALL, "brewster",
                "", "", "", "", 2);
    CheckAction(*actions->at(1), "punky", Action::ACTION_DOM_ACCESS, "lets",
                "", "http://www.google.com/", "", "", 1);
    CheckAction(*actions->at(2), "punky", Action::ACTION_API_CALL,
                "extension.sendMessage", "[\"not\",\"stripped\"]", "", "", "",
                1);
  }
  static void Arguments_GetOlderActions(
      scoped_ptr<Action::ActionVector> actions) {
    ASSERT_EQ(2, static_cast<int>(actions->size()));
    CheckAction(*actions->at(0), "punky", Action::ACTION_DOM_ACCESS, "lets",
                "", "http://www.google.com/", "", "", 1);
    CheckAction(*actions->at(1), "punky", Action::ACTION_API_CALL, "brewster",
                "", "", "", "", 1);
  }
  static void Arguments_CheckMergeCount(
      int count,
      scoped_ptr<Action::ActionVector> actions) {
    if (count > 0) {
      ASSERT_EQ(1u, actions->size());
      CheckAction(*actions->at(0), "punky", Action::ACTION_API_CALL, "brewster",
                  "", "", "", "", count);
    } else {
      ASSERT_EQ(0u, actions->size());
    }
  }
  static void Arguments_CheckMergeCountAndTime(
      int count,
      const base::Time& time,
      scoped_ptr<Action::ActionVector> actions) {
    if (count > 0) {
      ASSERT_EQ(1u, actions->size());
      CheckAction(*actions->at(0), "punky", Action::ACTION_API_CALL, "brewster",
                  "", "", "", "", count);
      ASSERT_EQ(time, actions->at(0)->time());
    } else {
      ASSERT_EQ(0u, actions->size());
    }
  }
  static void AllURLsRemoved(scoped_ptr<Action::ActionVector> actions) {
    ASSERT_EQ(2, static_cast<int>(actions->size()));
    CheckAction(*actions->at(0), "punky", Action::ACTION_DOM_ACCESS, "lets",
                "", "", "", "", 1);
    CheckAction(*actions->at(1), "punky", Action::ACTION_DOM_ACCESS, "lets",
                "", "", "", "", 1);
  }
  static void SomeURLsRemoved(scoped_ptr<Action::ActionVector> actions) {
    
    ASSERT_EQ(5, static_cast<int>(actions->size()));
    CheckAction(*actions->at(0), "punky", Action::ACTION_DOM_ACCESS, "lets",
                "", "http://www.google.com/", "Google",
                "http://www.args-url.com/", 1);
    CheckAction(*actions->at(1), "punky", Action::ACTION_DOM_ACCESS, "lets",
                "", "http://www.google.com/", "Google", "", 1);
    CheckAction(*actions->at(2), "punky", Action::ACTION_DOM_ACCESS, "lets",
                "", "", "", "", 1);
    CheckAction(*actions->at(3), "punky", Action::ACTION_DOM_ACCESS, "lets",
                "", "", "", "http://www.google.com/", 1);
    CheckAction(*actions->at(4), "punky", Action::ACTION_DOM_ACCESS, "lets",
                "", "", "", "", 1);
  }
  static void CheckDuplicates(scoped_ptr<Action::ActionVector> actions) {
    ASSERT_EQ(2u, actions->size());
    int total_count = 0;
    for (size_t i = 0; i < actions->size(); i++) {
      total_count += actions->at(i)->count();
    }
    ASSERT_EQ(3, total_count);
  }
  static void CheckAction(const Action& action,
                          const std::string& expected_id,
                          const Action::ActionType& expected_type,
                          const std::string& expected_api_name,
                          const std::string& expected_args_str,
                          const std::string& expected_page_url,
                          const std::string& expected_page_title,
                          const std::string& expected_arg_url,
                          int expected_count) {
    ASSERT_EQ(expected_id, action.extension_id());
    ASSERT_EQ(expected_type, action.action_type());
    ASSERT_EQ(expected_api_name, action.api_name());
    ASSERT_EQ(expected_args_str,
              ActivityLogPolicy::Util::Serialize(action.args()));
    ASSERT_EQ(expected_page_url, action.SerializePageUrl());
    ASSERT_EQ(expected_page_title, action.page_title());
    ASSERT_EQ(expected_arg_url, action.SerializeArgUrl());
    ASSERT_EQ(expected_count, action.count());
    ASSERT_NE(-1, action.action_id());
  }
  
  
  
  void CheckRemoveActions(
      ActivityLogDatabasePolicy* policy,
      const std::vector<int64>& action_ids,
      const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker) {
    
    
    base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
    mock_clock->SetNow(base::Time::Now().LocalMidnight() +
                       base::TimeDelta::FromHours(12));
    policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
    
    scoped_refptr<Action> action =
        new Action("punky1",
                   mock_clock->Now() - base::TimeDelta::FromMinutes(40),
                   Action::ACTION_DOM_ACCESS,
                   "lets1");
    action->mutable_args()->AppendString("vamoose1");
    action->set_page_url(GURL("http://www.google1.com"));
    action->set_page_title("Google1");
    action->set_arg_url(GURL("http://www.args-url1.com"));
    policy->ProcessAction(action);
    
    
    policy->ProcessAction(action);
    action = new Action("punky2",
                        mock_clock->Now() - base::TimeDelta::FromMinutes(30),
                        Action::ACTION_API_CALL,
                        "lets2");
    action->mutable_args()->AppendString("vamoose2");
    action->set_page_url(GURL("http://www.google2.com"));
    action->set_page_title("Google2");
    action->set_arg_url(GURL("http://www.args-url2.com"));
    policy->ProcessAction(action);
    
    
    policy->ProcessAction(action);
    
    policy->RemoveActions(action_ids);
    
    
    CheckReadData(policy, "", -1, checker);
    
    policy->DeleteDatabase();
  }
  static void AllActionsDeleted(scoped_ptr<Action::ActionVector> actions) {
    ASSERT_EQ(0, static_cast<int>(actions->size()));
  }
  static void NoActionsDeleted(scoped_ptr<Action::ActionVector> actions) {
    
    ASSERT_EQ(2, static_cast<int>(actions->size()));
    CheckAction(*actions->at(0),
                "punky2",
                Action::ACTION_API_CALL,
                "lets2",
                "",
                "http://www.google2.com/",
                "Google2",
                "http://www.args-url2.com/",
                2);
    ASSERT_EQ(2, actions->at(0)->action_id());
    CheckAction(*actions->at(1),
                "punky1",
                Action::ACTION_DOM_ACCESS,
                "lets1",
                "",
                "http://www.google1.com/",
                "Google1",
                "http://www.args-url1.com/",
                2);
    ASSERT_EQ(1, actions->at(1)->action_id());
  }
  static void Action1Deleted(scoped_ptr<Action::ActionVector> actions) {
    
    ASSERT_EQ(1, static_cast<int>(actions->size()));
    CheckAction(*actions->at(0),
                "punky2",
                Action::ACTION_API_CALL,
                "lets2",
                "",
                "http://www.google2.com/",
                "Google2",
                "http://www.args-url2.com/",
                2);
    ASSERT_EQ(2, actions->at(0)->action_id());
  }
  static void Action2Deleted(scoped_ptr<Action::ActionVector> actions) {
    
    ASSERT_EQ(1, static_cast<int>(actions->size()));
    CheckAction(*actions->at(0),
                "punky1",
                Action::ACTION_DOM_ACCESS,
                "lets1",
                "",
                "http://www.google1.com/",
                "Google1",
                "http://www.args-url1.com/",
                2);
    ASSERT_EQ(1, actions->at(0)->action_id());
  }
 protected:
  ExtensionService* extension_service_;
  scoped_ptr<TestingProfile> profile_;
  content::TestBrowserThreadBundle thread_bundle_;
  
  
  
  
  CommandLine saved_cmdline_;
#if defined OS_CHROMEOS
  chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
  chromeos::ScopedTestCrosSettings test_cros_settings_;
  scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_;
#endif
};
TEST_F(CountingPolicyTest, Construct) {
  ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
  policy->Init();
  scoped_refptr<const Extension> extension =
      ExtensionBuilder()
          .SetManifest(DictionaryBuilder()
                       .Set("name", "Test extension")
                       .Set("version", "1.0.0")
                       .Set("manifest_version", 2))
          .Build();
  extension_service_->AddExtension(extension.get());
  scoped_ptr<base::ListValue> args(new base::ListValue());
  scoped_refptr<Action> action = new Action(extension->id(),
                                            base::Time::Now(),
                                            Action::ACTION_API_CALL,
                                            "tabs.testMethod");
  action->set_args(args.Pass());
  policy->ProcessAction(action);
  policy->Close();
}
TEST_F(CountingPolicyTest, LogWithStrippedArguments) {
  ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
  policy->Init();
  scoped_refptr<const Extension> extension =
      ExtensionBuilder()
          .SetManifest(DictionaryBuilder()
                       .Set("name", "Test extension")
                       .Set("version", "1.0.0")
                       .Set("manifest_version", 2))
          .Build();
  extension_service_->AddExtension(extension.get());
  scoped_ptr<base::ListValue> args(new base::ListValue());
  args->Set(0, new base::StringValue("hello"));
  args->Set(1, new base::StringValue("world"));
  scoped_refptr<Action> action = new Action(extension->id(),
                                            base::Time::Now(),
                                            Action::ACTION_API_CALL,
                                            "extension.connect");
  action->set_args(args.Pass());
  policy->ProcessAction(action);
  CheckReadData(policy,
                extension->id(),
                0,
                base::Bind(&CountingPolicyTest::Arguments_Stripped));
  policy->Close();
}
TEST_F(CountingPolicyTest, GetTodaysActions) {
  CountingPolicy* policy = new CountingPolicy(profile_.get());
  policy->Init();
  
  
  policy->set_retention_time(base::TimeDelta::FromDays(14));
  
  
  
  
  
  base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
  mock_clock->SetNow(base::Time::Now().LocalMidnight() +
                     base::TimeDelta::FromHours(12));
  policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
  
  scoped_refptr<Action> action =
      new Action("punky",
                 mock_clock->Now() - base::TimeDelta::FromMinutes(40),
                 Action::ACTION_API_CALL,
                 "brewster");
  action->mutable_args()->AppendString("woof");
  policy->ProcessAction(action);
  action = new Action("punky",
                      mock_clock->Now() - base::TimeDelta::FromMinutes(30),
                      Action::ACTION_API_CALL,
                      "brewster");
  action->mutable_args()->AppendString("meow");
  policy->ProcessAction(action);
  action = new Action("punky",
                      mock_clock->Now() - base::TimeDelta::FromMinutes(20),
                      Action::ACTION_API_CALL,
                      "extension.sendMessage");
  action->mutable_args()->AppendString("not");
  action->mutable_args()->AppendString("stripped");
  policy->ProcessAction(action);
  action =
      new Action("punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
  action->mutable_args()->AppendString("vamoose");
  action->set_page_url(GURL("http://www.google.com"));
  policy->ProcessAction(action);
  action = new Action(
      "scoobydoo", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
  action->mutable_args()->AppendString("vamoose");
  action->set_page_url(GURL("http://www.google.com"));
  policy->ProcessAction(action);
  CheckReadData(
      policy,
      "punky",
      0,
      base::Bind(&CountingPolicyTest::Arguments_GetTodaysActions));
  policy->Close();
}
TEST_F(CountingPolicyTest, GetOlderActions) {
  CountingPolicy* policy = new CountingPolicy(profile_.get());
  policy->Init();
  policy->set_retention_time(base::TimeDelta::FromDays(14));
  
  
  base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
  mock_clock->SetNow(base::Time::Now().LocalMidnight() +
                     base::TimeDelta::FromHours(12));
  policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
  
  scoped_refptr<Action> action =
      new Action("punky",
                 mock_clock->Now() - base::TimeDelta::FromDays(3) -
                     base::TimeDelta::FromMinutes(40),
                 Action::ACTION_API_CALL,
                 "brewster");
  action->mutable_args()->AppendString("woof");
  policy->ProcessAction(action);
  action = new Action("punky",
                      mock_clock->Now() - base::TimeDelta::FromDays(3),
                      Action::ACTION_DOM_ACCESS,
                      "lets");
  action->mutable_args()->AppendString("vamoose");
  action->set_page_url(GURL("http://www.google.com"));
  policy->ProcessAction(action);
  action = new Action("punky",
                      mock_clock->Now(),
                      Action::ACTION_DOM_ACCESS,
                      "lets");
  action->mutable_args()->AppendString("too new");
  action->set_page_url(GURL("http://www.google.com"));
  policy->ProcessAction(action);
  action = new Action("punky",
                      mock_clock->Now() - base::TimeDelta::FromDays(7),
                      Action::ACTION_DOM_ACCESS,
                      "lets");
  action->mutable_args()->AppendString("too old");
  action->set_page_url(GURL("http://www.google.com"));
  policy->ProcessAction(action);
  CheckReadData(
      policy,
      "punky",
      3,
      base::Bind(&CountingPolicyTest::Arguments_GetOlderActions));
  policy->Close();
}
TEST_F(CountingPolicyTest, LogAndFetchFilteredActions) {
  ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
  policy->Init();
  scoped_refptr<const Extension> extension =
      ExtensionBuilder()
          .SetManifest(DictionaryBuilder()
                       .Set("name", "Test extension")
                       .Set("version", "1.0.0")
                       .Set("manifest_version", 2))
          .Build();
  extension_service_->AddExtension(extension.get());
  GURL gurl("http://www.google.com");
  
  scoped_refptr<Action> action_api = new Action(extension->id(),
                                                base::Time::Now(),
                                                Action::ACTION_API_CALL,
                                                "tabs.testMethod");
  action_api->set_args(make_scoped_ptr(new base::ListValue()));
  policy->ProcessAction(action_api);
  scoped_refptr<Action> action_dom = new Action(extension->id(),
                                                base::Time::Now(),
                                                Action::ACTION_DOM_ACCESS,
                                                "document.write");
  action_dom->set_args(make_scoped_ptr(new base::ListValue()));
  action_dom->set_page_url(gurl);
  policy->ProcessAction(action_dom);
  CheckReadFilteredData(
      policy,
      extension->id(),
      Action::ACTION_API_CALL,
      "tabs.testMethod",
      "",
      "",
      -1,
      base::Bind(
          &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
  CheckReadFilteredData(
      policy,
      "",
      Action::ACTION_DOM_ACCESS,
      "",
      "",
      "",
      -1,
      base::Bind(
          &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
  CheckReadFilteredData(
      policy,
      "",
      Action::ACTION_DOM_ACCESS,
      "",
      "http://www.google.com/",
      "",
      -1,
      base::Bind(
          &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
  CheckReadFilteredData(
      policy,
      "",
      Action::ACTION_DOM_ACCESS,
      "",
      "http://www.google.com",
      "",
      -1,
      base::Bind(
          &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
  CheckReadFilteredData(
      policy,
      "",
      Action::ACTION_DOM_ACCESS,
      "",
      "http://www.goo",
      "",
      -1,
      base::Bind(
          &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
  CheckReadFilteredData(
      policy,
      extension->id(),
      Action::ACTION_ANY,
      "",
      "",
      "",
      -1,
      base::Bind(
          &CountingPolicyTest::RetrieveActions_FetchFilteredActions2));
  policy->Close();
}
TEST_F(CountingPolicyTest, MergingAndExpiring) {
  CountingPolicy* policy = new CountingPolicy(profile_.get());
  policy->Init();
  
  
  policy->set_retention_time(base::TimeDelta::FromDays(14));
  
  
  base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
  mock_clock->SetNow(base::Time::Now().LocalMidnight() +
                    base::TimeDelta::FromHours(12));
  policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
  
  
  scoped_refptr<Action> action =
      new Action("punky",
                 mock_clock->Now() - base::TimeDelta::FromDays(3) -
                     base::TimeDelta::FromMinutes(40),
                 Action::ACTION_API_CALL,
                 "brewster");
  policy->ProcessAction(action);
  action = new Action("punky",
                      mock_clock->Now() - base::TimeDelta::FromDays(3) -
                          base::TimeDelta::FromMinutes(20),
                      Action::ACTION_API_CALL,
                      "brewster");
  policy->ProcessAction(action);
  action = new Action("punky",
                      mock_clock->Now() - base::TimeDelta::FromDays(2) -
                          base::TimeDelta::FromMinutes(20),
                      Action::ACTION_API_CALL,
                      "brewster");
  policy->ProcessAction(action);
  CheckReadData(policy,
                "punky",
                3,
                base::Bind(&CountingPolicyTest::Arguments_CheckMergeCount, 2));
  CheckReadData(policy,
                "punky",
                2,
                base::Bind(&CountingPolicyTest::Arguments_CheckMergeCount, 1));
  
  
  policy->set_retention_time(base::TimeDelta::FromDays(2));
  policy->last_database_cleaning_time_ = base::Time();
  action = new Action("punky",
                      mock_clock->Now(),
                      Action::ACTION_API_CALL,
                      "brewster");
  policy->ProcessAction(action);
  CheckReadData(policy,
                "punky",
                3,
                base::Bind(&CountingPolicyTest::Arguments_CheckMergeCount, 0));
  CheckReadData(policy,
                "punky",
                2,
                base::Bind(&CountingPolicyTest::Arguments_CheckMergeCount, 1));
  policy->Close();
}
TEST_F(CountingPolicyTest, StringTableCleaning) {
  CountingPolicy* policy = new CountingPolicy(profile_.get());
  policy->Init();
  
  
  policy->set_retention_time(base::TimeDelta::FromDays(14));
  base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
  mock_clock->SetNow(base::Time::Now());
  policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
  
  
  scoped_refptr<Action> action =
      new Action("punky",
                 mock_clock->Now() - base::TimeDelta::FromDays(7),
                 Action::ACTION_API_CALL,
                 "brewster");
  action->set_page_url(GURL("http://www.google.com/"));
  policy->ProcessAction(action);
  
  
  action = new Action(
      "punky", mock_clock->Now(), Action::ACTION_API_CALL, "tabs.create");
  policy->ProcessAction(action);
  
  
  policy->Flush();
  policy->ScheduleAndForget(policy,
                            &CountingPolicyTest::CheckStringTableSizes,
                            3,
                            1);
  WaitOnThread(BrowserThread::DB);
  
  
  
  policy->set_retention_time(base::TimeDelta::FromDays(2));
  policy->last_database_cleaning_time_ = base::Time();
  policy->ProcessAction(action);
  policy->Flush();
  policy->ScheduleAndForget(policy,
                            &CountingPolicyTest::CheckStringTableSizes,
                            2,
                            0);
  WaitOnThread(BrowserThread::DB);
  policy->Close();
}
TEST_F(CountingPolicyTest, MoreMerging) {
  CountingPolicy* policy = new CountingPolicy(profile_.get());
  policy->Init();
  policy->set_retention_time(base::TimeDelta::FromDays(14));
  
  
  base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
  mock_clock->SetNow(base::Time::Now().LocalMidnight() +
                    base::TimeDelta::FromHours(12));
  policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
  
  
  
  
  base::Time time1 =
      mock_clock->Now() - base::TimeDelta::FromDays(2) -
      base::TimeDelta::FromMinutes(40);
  base::Time time2 =
      mock_clock->Now() - base::TimeDelta::FromDays(1) -
      base::TimeDelta::FromMinutes(40);
  base::Time time3 =
      mock_clock->Now() - base::TimeDelta::FromDays(2) -
      base::TimeDelta::FromMinutes(20);
  scoped_refptr<Action> action =
      new Action("punky", time1, Action::ACTION_API_CALL, "brewster");
  policy->ProcessAction(action);
  action = new Action("punky", time2, Action::ACTION_API_CALL, "brewster");
  policy->ProcessAction(action);
  action = new Action("punky", time3, Action::ACTION_API_CALL, "brewster");
  policy->ProcessAction(action);
  CheckReadData(
      policy,
      "punky",
      2,
      base::Bind(
          &CountingPolicyTest::Arguments_CheckMergeCountAndTime, 2, time3));
  CheckReadData(
      policy,
      "punky",
      1,
      base::Bind(
          &CountingPolicyTest::Arguments_CheckMergeCountAndTime, 1, time2));
  
  
  
  base::Time time4 = mock_clock->Now() - base::TimeDelta::FromMinutes(60);
  base::Time time5 = mock_clock->Now() - base::TimeDelta::FromMinutes(20);
  base::Time time6 = mock_clock->Now() - base::TimeDelta::FromMinutes(40);
  action = new Action("punky", time4, Action::ACTION_API_CALL, "brewster");
  policy->ProcessAction(action);
  action = new Action("punky", time5, Action::ACTION_API_CALL, "brewster");
  policy->ProcessAction(action);
  action = new Action("punky", time6, Action::ACTION_API_CALL, "brewster");
  policy->ProcessAction(action);
  CheckReadData(
      policy,
      "punky",
      0,
      base::Bind(
          &CountingPolicyTest::Arguments_CheckMergeCountAndTime, 3, time5));
  policy->Close();
}
TEST_F(CountingPolicyTest, EarlyFlush) {
  CountingPolicy* policy = new CountingPolicy(profile_.get());
  policy->Init();
  for (int i = 0; i < 500; i++) {
    scoped_refptr<Action> action =
        new Action("punky",
                   base::Time::Now(),
                   Action::ACTION_API_CALL,
                   base::StringPrintf("apicall_%d", i));
    policy->ProcessAction(action);
  }
  policy->ScheduleAndForget(policy, &CountingPolicyTest::CheckQueueSize);
  WaitOnThread(BrowserThread::DB);
  policy->Close();
}
TEST_F(CountingPolicyTest, CapReturns) {
  CountingPolicy* policy = new CountingPolicy(profile_.get());
  policy->Init();
  for (int i = 0; i < 305; i++) {
    scoped_refptr<Action> action =
        new Action("punky",
                   base::Time::Now(),
                   Action::ACTION_API_CALL,
                   base::StringPrintf("apicall_%d", i));
    policy->ProcessAction(action);
  }
  policy->Flush();
  WaitOnThread(BrowserThread::DB);
  CheckReadFilteredData(
      policy,
      "punky",
      Action::ACTION_ANY,
      "",
      "",
      "",
      -1,
      base::Bind(
          &CountingPolicyTest::RetrieveActions_FetchFilteredActions300));
  policy->Close();
}
TEST_F(CountingPolicyTest, RemoveAllURLs) {
  ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
  policy->Init();
  
  
  base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
  mock_clock->SetNow(base::Time::Now().LocalMidnight() +
                     base::TimeDelta::FromHours(12));
  policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
  
  scoped_refptr<Action> action =
      new Action("punky", mock_clock->Now(),
                 Action::ACTION_DOM_ACCESS, "lets");
  action->mutable_args()->AppendString("vamoose");
  action->set_page_url(GURL("http://www.google.com"));
  action->set_page_title("Google");
  action->set_arg_url(GURL("http://www.args-url.com"));
  policy->ProcessAction(action);
  mock_clock->Advance(base::TimeDelta::FromSeconds(1));
  action = new Action(
      "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
  action->mutable_args()->AppendString("vamoose");
  action->set_page_url(GURL("http://www.google2.com"));
  action->set_page_title("Google");
  
  
  policy->ProcessAction(action);
  
  std::vector<GURL> no_url_restrictions;
  policy->RemoveURLs(no_url_restrictions);
  CheckReadData(
      policy,
      "punky",
      0,
      base::Bind(&CountingPolicyTest::AllURLsRemoved));
  policy->Close();
}
TEST_F(CountingPolicyTest, RemoveSpecificURLs) {
  ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
  policy->Init();
  
  
  base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
  mock_clock->SetNow(base::Time::Now().LocalMidnight() +
                     base::TimeDelta::FromHours(12));
  policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
  
  
  scoped_refptr<Action> action = new Action("punky", mock_clock->Now(),
                                            Action::ACTION_DOM_ACCESS, "lets");
  action->mutable_args()->AppendString("vamoose");
  action->set_page_url(GURL("http://www.google1.com"));
  action->set_page_title("Google");
  action->set_arg_url(GURL("http://www.google1.com"));
  policy->ProcessAction(action);
  
  mock_clock->Advance(base::TimeDelta::FromSeconds(1));
  action = new Action(
      "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
  action->mutable_args()->AppendString("vamoose");
  action->set_page_url(GURL("http://www.google1.com"));
  action->set_page_title("Google");
  action->set_arg_url(GURL("http://www.google.com"));
  policy->ProcessAction(action);
  
  
  mock_clock->Advance(base::TimeDelta::FromSeconds(1));
  action = new Action(
      "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
  action->mutable_args()->AppendString("vamoose");
  action->set_page_url(GURL("http://www.google2.com"));
  action->set_page_title("Google");
  policy->ProcessAction(action);
  
  mock_clock->Advance(base::TimeDelta::FromSeconds(1));
  action = new Action(
      "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
  action->mutable_args()->AppendString("vamoose");
  action->set_page_url(GURL("http://www.google.com"));
  action->set_page_title("Google");
  action->set_arg_url(GURL("http://www.google1.com"));
  policy->ProcessAction(action);
  
  mock_clock->Advance(base::TimeDelta::FromSeconds(1));
  action = new Action(
      "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
  action->mutable_args()->AppendString("vamoose");
  action->set_page_url(GURL("http://www.google.com"));
  action->set_page_title("Google");
  action->set_arg_url(GURL("http://www.args-url.com"));
  action->set_count(5);
  policy->ProcessAction(action);
    
  std::vector<GURL> urls;
  urls.push_back(GURL("http://www.google1.com"));
  urls.push_back(GURL("http://www.google2.com"));
  urls.push_back(GURL("http://www.url_not_in_db.com"));
  policy->RemoveURLs(urls);
  CheckReadData(
      policy,
      "punky",
      0,
      base::Bind(&CountingPolicyTest::SomeURLsRemoved));
  policy->Close();
}
TEST_F(CountingPolicyTest, RemoveExtensionData) {
  CountingPolicy* policy = new CountingPolicy(profile_.get());
  policy->Init();
  
  
  base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
  mock_clock->SetNow(base::Time::Now().LocalMidnight() +
                     base::TimeDelta::FromHours(12));
  policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
  
  scoped_refptr<Action> action = new Action("deleteextensiondata",
                                            mock_clock->Now(),
                                            Action::ACTION_DOM_ACCESS,
                                            "lets");
  action->mutable_args()->AppendString("vamoose");
  action->set_page_title("Google");
  action->set_arg_url(GURL("http://www.google.com"));
  policy->ProcessAction(action);
  policy->ProcessAction(action);
  policy->ProcessAction(action);
  scoped_refptr<Action> action2 = new Action("dontdelete",
                                             mock_clock->Now(),
                                             Action::ACTION_DOM_ACCESS,
                                             "lets");
  action->mutable_args()->AppendString("vamoose");
  action->set_page_title("Google");
  action->set_arg_url(GURL("http://www.google.com"));
  policy->ProcessAction(action2);
  policy->Flush();
  policy->RemoveExtensionData("deleteextensiondata");
  CheckReadFilteredData(
      policy,
      "deleteextensiondata",
      Action::ACTION_ANY,
      "",
      "",
      "",
      -1,
      base::Bind(
          &CountingPolicyTest::RetrieveActions_FetchFilteredActions0));
  CheckReadFilteredData(
      policy,
      "dontdelete",
      Action::ACTION_ANY,
      "",
      "",
      "",
      -1,
      base::Bind(
          &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
  policy->Close();
}
TEST_F(CountingPolicyTest, DeleteDatabase) {
  CountingPolicy* policy = new CountingPolicy(profile_.get());
  policy->Init();
  
  
  policy->set_retention_time(base::TimeDelta::FromDays(14));
  
  
  
  
  
  base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
  mock_clock->SetNow(base::Time::Now().LocalMidnight() +
                     base::TimeDelta::FromHours(12));
  policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
  
  scoped_refptr<Action> action =
      new Action("punky",
                 mock_clock->Now() - base::TimeDelta::FromMinutes(40),
                 Action::ACTION_API_CALL,
                 "brewster");
  action->mutable_args()->AppendString("woof");
  policy->ProcessAction(action);
  action = new Action("punky",
                      mock_clock->Now() - base::TimeDelta::FromMinutes(30),
                      Action::ACTION_API_CALL,
                      "brewster");
  action->mutable_args()->AppendString("meow");
  policy->ProcessAction(action);
  action = new Action("punky",
                      mock_clock->Now() - base::TimeDelta::FromMinutes(20),
                      Action::ACTION_API_CALL,
                      "extension.sendMessage");
  action->mutable_args()->AppendString("not");
  action->mutable_args()->AppendString("stripped");
  policy->ProcessAction(action);
  action =
      new Action("punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
  action->mutable_args()->AppendString("vamoose");
  action->set_page_url(GURL("http://www.google.com"));
  policy->ProcessAction(action);
  action = new Action(
      "scoobydoo", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
  action->mutable_args()->AppendString("vamoose");
  action->set_page_url(GURL("http://www.google.com"));
  policy->ProcessAction(action);
  CheckReadData(
      policy,
      "punky",
      0,
      base::Bind(&CountingPolicyTest::Arguments_GetTodaysActions));
  policy->DeleteDatabase();
  CheckReadFilteredData(
      policy,
      "",
      Action::ACTION_ANY,
      "",
      "",
      "",
      -1,
      base::Bind(
          &CountingPolicyTest::RetrieveActions_FetchFilteredActions0));
  
  
  
  action =
    new Action("punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
  action->mutable_args()->AppendString("vamoose");
  action->set_page_url(GURL("http://www.google.com"));
  policy->ProcessAction(action);
  CheckReadData(
      policy,
      "",
      -1,
      base::Bind(&CountingPolicyTest::Arguments_GetSinglesAction));
  policy->DeleteDatabase();
  CheckReadFilteredData(
      policy,
      "",
      Action::ACTION_ANY,
      "",
      "",
      "",
      -1,
      base::Bind(
          &CountingPolicyTest::RetrieveActions_FetchFilteredActions0));
  policy->Close();
}
TEST_F(CountingPolicyTest, DuplicateRows) {
  CountingPolicy* policy = new CountingPolicy(profile_.get());
  policy->Init();
  base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
  mock_clock->SetNow(base::Time::Now().LocalMidnight() +
                     base::TimeDelta::FromHours(12));
  policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
  
  scoped_refptr<Action> action;
  action = new Action(
      "punky", mock_clock->Now(), Action::ACTION_API_CALL, "brewster");
  action->set_page_url(GURL("http://www.google.com"));
  policy->ProcessAction(action);
  action = new Action(
      "punky", mock_clock->Now(), Action::ACTION_API_CALL, "brewster");
  action->set_page_url(GURL("http://www.google.co.uk"));
  policy->ProcessAction(action);
  
  
  std::vector<GURL> no_url_restrictions;
  policy->RemoveURLs(no_url_restrictions);
  
  
  action = new Action(
      "punky", mock_clock->Now(), Action::ACTION_API_CALL, "brewster");
  policy->ProcessAction(action);
  CheckReadData(
      policy,
      "punky",
      0,
      base::Bind(&CountingPolicyTest::CheckDuplicates));
  policy->Close();
}
TEST_F(CountingPolicyTest, RemoveActions) {
  ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
  policy->Init();
  std::vector<int64> action_ids;
  CheckRemoveActions(
      policy, action_ids, base::Bind(&CountingPolicyTest::NoActionsDeleted));
  action_ids.push_back(-1);
  action_ids.push_back(-10);
  action_ids.push_back(0);
  action_ids.push_back(5);
  action_ids.push_back(10);
  CheckRemoveActions(
      policy, action_ids, base::Bind(&CountingPolicyTest::NoActionsDeleted));
  action_ids.clear();
  for (int i = 0; i < 50; i++) {
    action_ids.push_back(i + 3);
  }
  CheckRemoveActions(
      policy, action_ids, base::Bind(&CountingPolicyTest::NoActionsDeleted));
  action_ids.clear();
  
  
  action_ids.push_back(1);
  action_ids.push_back(2);
  CheckRemoveActions(
      policy, action_ids, base::Bind(&CountingPolicyTest::AllActionsDeleted));
  action_ids.clear();
  action_ids.push_back(1);
  CheckRemoveActions(
      policy, action_ids, base::Bind(&CountingPolicyTest::Action1Deleted));
  action_ids.clear();
  action_ids.push_back(2);
  CheckRemoveActions(
      policy, action_ids, base::Bind(&CountingPolicyTest::Action2Deleted));
  action_ids.clear();
  policy->Close();
}
}