| OLD | NEW | 
|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "base/cancelable_callback.h" | 5 #include "base/cancelable_callback.h" | 
| 6 #include "base/command_line.h" | 6 #include "base/command_line.h" | 
| 7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" | 
| 8 #include "base/run_loop.h" | 8 #include "base/run_loop.h" | 
|  | 9 #include "base/strings/stringprintf.h" | 
| 9 #include "base/synchronization/waitable_event.h" | 10 #include "base/synchronization/waitable_event.h" | 
| 10 #include "base/test/simple_test_clock.h" | 11 #include "base/test/simple_test_clock.h" | 
| 11 #include "chrome/browser/extensions/activity_log/activity_log.h" | 12 #include "chrome/browser/extensions/activity_log/activity_log.h" | 
| 12 #include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h" | 13 #include "chrome/browser/extensions/activity_log/counting_policy.h" | 
| 13 #include "chrome/browser/extensions/extension_service.h" | 14 #include "chrome/browser/extensions/extension_service.h" | 
| 14 #include "chrome/browser/extensions/test_extension_system.h" | 15 #include "chrome/browser/extensions/test_extension_system.h" | 
| 15 #include "chrome/common/chrome_constants.h" | 16 #include "chrome/common/chrome_constants.h" | 
| 16 #include "chrome/common/chrome_switches.h" | 17 #include "chrome/common/chrome_switches.h" | 
| 17 #include "chrome/common/extensions/extension_builder.h" | 18 #include "chrome/common/extensions/extension_builder.h" | 
| 18 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 19 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 
| 19 #include "chrome/test/base/testing_profile.h" | 20 #include "chrome/test/base/testing_profile.h" | 
| 20 #include "content/public/test/test_browser_thread_bundle.h" | 21 #include "content/public/test/test_browser_thread_bundle.h" | 
| 21 #include "sql/statement.h" | 22 #include "sql/statement.h" | 
| 22 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" | 
| 23 | 24 | 
| 24 #if defined(OS_CHROMEOS) | 25 #if defined(OS_CHROMEOS) | 
| 25 #include "chrome/browser/chromeos/login/user_manager.h" | 26 #include "chrome/browser/chromeos/login/user_manager.h" | 
| 26 #include "chrome/browser/chromeos/settings/cros_settings.h" | 27 #include "chrome/browser/chromeos/settings/cros_settings.h" | 
| 27 #include "chrome/browser/chromeos/settings/device_settings_service.h" | 28 #include "chrome/browser/chromeos/settings/device_settings_service.h" | 
| 28 #endif | 29 #endif | 
| 29 | 30 | 
| 30 namespace extensions { | 31 namespace extensions { | 
| 31 | 32 | 
| 32 class FullStreamUIPolicyTest : public testing::Test { | 33 class CountingPolicyTest : public testing::Test { | 
| 33  public: | 34  public: | 
| 34   FullStreamUIPolicyTest() | 35   CountingPolicyTest() | 
| 35       : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), | 36       : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), | 
| 36         saved_cmdline_(CommandLine::NO_PROGRAM) { | 37         saved_cmdline_(CommandLine::NO_PROGRAM) { | 
| 37 #if defined OS_CHROMEOS | 38 #if defined OS_CHROMEOS | 
| 38     test_user_manager_.reset(new chromeos::ScopedTestUserManager()); | 39     test_user_manager_.reset(new chromeos::ScopedTestUserManager()); | 
| 39 #endif | 40 #endif | 
| 40     CommandLine command_line(CommandLine::NO_PROGRAM); | 41     CommandLine command_line(CommandLine::NO_PROGRAM); | 
| 41     saved_cmdline_ = *CommandLine::ForCurrentProcess(); | 42     saved_cmdline_ = *CommandLine::ForCurrentProcess(); | 
| 42     profile_.reset(new TestingProfile()); | 43     profile_.reset(new TestingProfile()); | 
| 43     CommandLine::ForCurrentProcess()->AppendSwitch( | 44     CommandLine::ForCurrentProcess()->AppendSwitch( | 
| 44         switches::kEnableExtensionActivityLogging); | 45         switches::kEnableExtensionActivityLogging); | 
| 45     CommandLine::ForCurrentProcess()->AppendSwitch( | 46     CommandLine::ForCurrentProcess()->AppendSwitch( | 
| 46         switches::kEnableExtensionActivityLogTesting); | 47         switches::kEnableExtensionActivityLogTesting); | 
| 47     extension_service_ = static_cast<TestExtensionSystem*>( | 48     extension_service_ = static_cast<TestExtensionSystem*>( | 
| 48         ExtensionSystem::Get(profile_.get()))->CreateExtensionService | 49         ExtensionSystem::Get(profile_.get()))->CreateExtensionService | 
| 49             (&command_line, base::FilePath(), false); | 50             (&command_line, base::FilePath(), false); | 
| 50   } | 51   } | 
| 51 | 52 | 
| 52   virtual ~FullStreamUIPolicyTest() { | 53   virtual ~CountingPolicyTest() { | 
| 53 #if defined OS_CHROMEOS | 54 #if defined OS_CHROMEOS | 
| 54     test_user_manager_.reset(); | 55     test_user_manager_.reset(); | 
| 55 #endif | 56 #endif | 
| 56     base::RunLoop().RunUntilIdle(); | 57     base::RunLoop().RunUntilIdle(); | 
| 57     profile_.reset(NULL); | 58     profile_.reset(NULL); | 
| 58     base::RunLoop().RunUntilIdle(); | 59     base::RunLoop().RunUntilIdle(); | 
| 59     // Restore the original command line and undo the affects of SetUp(). | 60     // Restore the original command line and undo the affects of SetUp(). | 
| 60     *CommandLine::ForCurrentProcess() = saved_cmdline_; | 61     *CommandLine::ForCurrentProcess() = saved_cmdline_; | 
| 61   } | 62   } | 
| 62 | 63 | 
| 63   // A helper function to call ReadData on a policy object and wait for the | 64   // A helper function to call ReadData on a policy object and wait for the | 
| 64   // results to be processed. | 65   // results to be processed. | 
| 65   void CheckReadData( | 66   void CheckReadData( | 
| 66       ActivityLogPolicy* policy, | 67       ActivityLogPolicy* policy, | 
| 67       const std::string& extension_id, | 68       const std::string& extension_id, | 
| 68       const int day, | 69       const int day, | 
| 69       const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker) { | 70       const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker) { | 
| 70     // Submit a request to the policy to read back some data, and call the | 71     // Submit a request to the policy to read back some data, and call the | 
| 71     // checker function when results are available.  This will happen on the | 72     // checker function when results are available.  This will happen on the | 
| 72     // database thread. | 73     // database thread. | 
| 73     policy->ReadData( | 74     policy->ReadData( | 
| 74         extension_id, | 75         extension_id, | 
| 75         day, | 76         day, | 
| 76         base::Bind(&FullStreamUIPolicyTest::CheckWrapper, | 77         base::Bind(&CountingPolicyTest::CheckWrapper, | 
| 77                    checker, | 78                    checker, | 
| 78                    base::MessageLoop::current()->QuitClosure())); | 79                    base::MessageLoop::current()->QuitClosure())); | 
| 79 | 80 | 
| 80     // Set up a timeout that will trigger after 5 seconds; if we haven't | 81     // Set up a timeout that will trigger after 5 seconds; if we haven't | 
| 81     // received any results by then assume that the test is broken. | 82     // received any results by then assume that the test is broken. | 
| 82     base::CancelableClosure timeout( | 83     base::CancelableClosure timeout( | 
| 83         base::Bind(&FullStreamUIPolicyTest::TimeoutCallback)); | 84         base::Bind(&CountingPolicyTest::TimeoutCallback)); | 
| 84     base::MessageLoop::current()->PostDelayedTask( | 85     base::MessageLoop::current()->PostDelayedTask( | 
| 85         FROM_HERE, timeout.callback(), base::TimeDelta::FromSeconds(5)); | 86         FROM_HERE, timeout.callback(), base::TimeDelta::FromSeconds(5)); | 
| 86 | 87 | 
| 87     // Wait for results; either the checker or the timeout callbacks should | 88     // Wait for results; either the checker or the timeout callbacks should | 
| 88     // cause the main loop to exit. | 89     // cause the main loop to exit. | 
| 89     base::MessageLoop::current()->Run(); | 90     base::MessageLoop::current()->Run(); | 
| 90 | 91 | 
| 91     timeout.Cancel(); | 92     timeout.Cancel(); | 
| 92   } | 93   } | 
| 93 | 94 | 
| 94   static void CheckWrapper( | 95   static void CheckWrapper( | 
| 95       const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker, | 96       const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker, | 
| 96       const base::Closure& done, | 97       const base::Closure& done, | 
| 97       scoped_ptr<Action::ActionVector> results) { | 98       scoped_ptr<Action::ActionVector> results) { | 
| 98     checker.Run(results.Pass()); | 99     checker.Run(results.Pass()); | 
| 99     done.Run(); | 100     done.Run(); | 
| 100   } | 101   } | 
| 101 | 102 | 
| 102   static void TimeoutCallback() { | 103   static void TimeoutCallback() { | 
| 103     base::MessageLoop::current()->QuitWhenIdle(); | 104     base::MessageLoop::current()->QuitWhenIdle(); | 
| 104     FAIL() << "Policy test timed out waiting for results"; | 105     FAIL() << "Policy test timed out waiting for results"; | 
| 105   } | 106   } | 
| 106 | 107 | 
| 107   static void RetrieveActions_LogAndFetchActions( | 108   static void Arguments_Stripped(scoped_ptr<Action::ActionVector> i) { | 
| 108       scoped_ptr<std::vector<scoped_refptr<Action> > > i) { |  | 
| 109     ASSERT_EQ(2, static_cast<int>(i->size())); |  | 
| 110   } |  | 
| 111 |  | 
| 112   static void Arguments_Present(scoped_ptr<Action::ActionVector> i) { |  | 
| 113     scoped_refptr<Action> last = i->front(); | 109     scoped_refptr<Action> last = i->front(); | 
| 114     std::string args = | 110     std::string args = | 
| 115         "ID=odlameecjipmbmbejkplpemijjgpljce CATEGORY=api_call " | 111         "ID=odlameecjipmbmbejkplpemijjgpljce CATEGORY=api_call " | 
| 116         "API=extension.connect ARGS=[\"hello\",\"world\"]"; | 112         "API=extension.connect ARGS=[\"hello\",\"world\"] COUNT=1"; | 
| 117     ASSERT_EQ(args, last->PrintForDebug()); | 113     ASSERT_EQ(args, last->PrintForDebug()); | 
| 118   } | 114   } | 
| 119 | 115 | 
| 120   static void Arguments_GetTodaysActions( | 116   static void Arguments_GetTodaysActions( | 
| 121       scoped_ptr<Action::ActionVector> actions) { | 117       scoped_ptr<Action::ActionVector> actions) { | 
|  | 118     std::string api_stripped_print = | 
|  | 119         "ID=punky CATEGORY=api_call API=brewster COUNT=2"; | 
| 122     std::string api_print = | 120     std::string api_print = | 
| 123         "ID=punky CATEGORY=api_call API=brewster ARGS=[\"woof\"]"; | 121         "ID=punky CATEGORY=api_call API=extension.sendMessage " | 
|  | 122         "ARGS=[\"not\",\"stripped\"] COUNT=1"; | 
| 124     std::string dom_print = | 123     std::string dom_print = | 
| 125         "ID=punky CATEGORY=dom_access API=lets ARGS=[\"vamoose\"] " | 124         "ID=punky CATEGORY=dom_access API=lets ARGS=[\"vamoose\"] " | 
| 126         "PAGE_URL=http://www.google.com/"; | 125         "PAGE_URL=http://www.google.com/ COUNT=1"; | 
|  | 126     ASSERT_EQ(3, static_cast<int>(actions->size())); | 
|  | 127     ASSERT_EQ(dom_print, actions->at(0)->PrintForDebug()); | 
|  | 128     ASSERT_EQ(api_print, actions->at(1)->PrintForDebug()); | 
|  | 129     ASSERT_EQ(api_stripped_print, actions->at(2)->PrintForDebug()); | 
|  | 130   } | 
|  | 131 | 
|  | 132   static void Arguments_GetOlderActions( | 
|  | 133       scoped_ptr<Action::ActionVector> actions) { | 
|  | 134     std::string api_print = | 
|  | 135         "ID=punky CATEGORY=api_call API=brewster COUNT=1"; | 
|  | 136     std::string dom_print = | 
|  | 137         "ID=punky CATEGORY=dom_access API=lets ARGS=[\"vamoose\"] " | 
|  | 138         "PAGE_URL=http://www.google.com/ COUNT=1"; | 
| 127     ASSERT_EQ(2, static_cast<int>(actions->size())); | 139     ASSERT_EQ(2, static_cast<int>(actions->size())); | 
| 128     ASSERT_EQ(dom_print, actions->at(0)->PrintForDebug()); | 140     ASSERT_EQ(dom_print, actions->at(0)->PrintForDebug()); | 
| 129     ASSERT_EQ(api_print, actions->at(1)->PrintForDebug()); | 141     ASSERT_EQ(api_print, actions->at(1)->PrintForDebug()); | 
| 130   } | 142   } | 
| 131 | 143 | 
| 132   static void Arguments_GetOlderActions( | 144   static void Arguments_CheckMergeCount( | 
|  | 145       int count, | 
| 133       scoped_ptr<Action::ActionVector> actions) { | 146       scoped_ptr<Action::ActionVector> actions) { | 
| 134     std::string api_print = | 147     std::string api_print = base::StringPrintf( | 
| 135         "ID=punky CATEGORY=api_call API=brewster ARGS=[\"woof\"]"; | 148         "ID=punky CATEGORY=api_call API=brewster COUNT=%d", count); | 
| 136     std::string dom_print = | 149     if (count > 0) { | 
| 137         "ID=punky CATEGORY=dom_access API=lets ARGS=[\"vamoose\"] " | 150       ASSERT_EQ(1u, actions->size()); | 
| 138         "PAGE_URL=http://www.google.com/"; | 151       ASSERT_EQ(api_print, actions->at(0)->PrintForDebug()); | 
| 139     ASSERT_EQ(2, static_cast<int>(actions->size())); | 152     } else { | 
| 140     ASSERT_EQ(dom_print, actions->at(0)->PrintForDebug()); | 153       ASSERT_EQ(0u, actions->size()); | 
| 141     ASSERT_EQ(api_print, actions->at(1)->PrintForDebug()); | 154     } | 
| 142   } | 155   } | 
| 143 | 156 | 
| 144  protected: | 157  protected: | 
| 145   ExtensionService* extension_service_; | 158   ExtensionService* extension_service_; | 
| 146   scoped_ptr<TestingProfile> profile_; | 159   scoped_ptr<TestingProfile> profile_; | 
| 147   content::TestBrowserThreadBundle thread_bundle_; | 160   content::TestBrowserThreadBundle thread_bundle_; | 
| 148   // Used to preserve a copy of the original command line. | 161   // Used to preserve a copy of the original command line. | 
| 149   // The test framework will do this itself as well. However, by then, | 162   // The test framework will do this itself as well. However, by then, | 
| 150   // it is too late to call ActivityLog::RecomputeLoggingIsEnabled() in | 163   // it is too late to call ActivityLog::RecomputeLoggingIsEnabled() in | 
| 151   // TearDown(). | 164   // TearDown(). | 
| 152   CommandLine saved_cmdline_; | 165   CommandLine saved_cmdline_; | 
| 153 | 166 | 
| 154 #if defined OS_CHROMEOS | 167 #if defined OS_CHROMEOS | 
| 155   chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; | 168   chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; | 
| 156   chromeos::ScopedTestCrosSettings test_cros_settings_; | 169   chromeos::ScopedTestCrosSettings test_cros_settings_; | 
| 157   scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_; | 170   scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_; | 
| 158 #endif | 171 #endif | 
| 159 }; | 172 }; | 
| 160 | 173 | 
| 161 TEST_F(FullStreamUIPolicyTest, Construct) { | 174 TEST_F(CountingPolicyTest, Construct) { | 
| 162   ActivityLogPolicy* policy = new FullStreamUIPolicy(profile_.get()); | 175   ActivityLogPolicy* policy = new CountingPolicy(profile_.get()); | 
| 163   scoped_refptr<const Extension> extension = | 176   scoped_refptr<const Extension> extension = | 
| 164       ExtensionBuilder() | 177       ExtensionBuilder() | 
| 165           .SetManifest(DictionaryBuilder() | 178           .SetManifest(DictionaryBuilder() | 
| 166                        .Set("name", "Test extension") | 179                        .Set("name", "Test extension") | 
| 167                        .Set("version", "1.0.0") | 180                        .Set("version", "1.0.0") | 
| 168                        .Set("manifest_version", 2)) | 181                        .Set("manifest_version", 2)) | 
| 169           .Build(); | 182           .Build(); | 
| 170   extension_service_->AddExtension(extension.get()); | 183   extension_service_->AddExtension(extension.get()); | 
| 171   scoped_ptr<base::ListValue> args(new base::ListValue()); | 184   scoped_ptr<base::ListValue> args(new base::ListValue()); | 
| 172   scoped_refptr<Action> action = new Action(extension->id(), | 185   scoped_refptr<Action> action = new Action(extension->id(), | 
| 173                                             base::Time::Now(), | 186                                             base::Time::Now(), | 
| 174                                             Action::ACTION_API_CALL, | 187                                             Action::ACTION_API_CALL, | 
| 175                                             "tabs.testMethod"); | 188                                             "tabs.testMethod"); | 
| 176   action->set_args(args.Pass()); | 189   action->set_args(args.Pass()); | 
| 177   policy->ProcessAction(action); | 190   policy->ProcessAction(action); | 
| 178   policy->Close(); | 191   policy->Close(); | 
| 179 } | 192 } | 
| 180 | 193 | 
| 181 TEST_F(FullStreamUIPolicyTest, LogAndFetchActions) { | 194 TEST_F(CountingPolicyTest, LogWithStrippedArguments) { | 
| 182   ActivityLogPolicy* policy = new FullStreamUIPolicy(profile_.get()); | 195   ActivityLogPolicy* policy = new CountingPolicy(profile_.get()); | 
| 183   scoped_refptr<const Extension> extension = | 196   scoped_refptr<const Extension> extension = | 
| 184       ExtensionBuilder() | 197       ExtensionBuilder() | 
| 185           .SetManifest(DictionaryBuilder() | 198           .SetManifest(DictionaryBuilder() | 
| 186                        .Set("name", "Test extension") |  | 
| 187                        .Set("version", "1.0.0") |  | 
| 188                        .Set("manifest_version", 2)) |  | 
| 189           .Build(); |  | 
| 190   extension_service_->AddExtension(extension.get()); |  | 
| 191   GURL gurl("http://www.google.com"); |  | 
| 192 |  | 
| 193   // Write some API calls |  | 
| 194   scoped_refptr<Action> action_api = new Action(extension->id(), |  | 
| 195                                                 base::Time::Now(), |  | 
| 196                                                 Action::ACTION_API_CALL, |  | 
| 197                                                 "tabs.testMethod"); |  | 
| 198   action_api->set_args(make_scoped_ptr(new base::ListValue())); |  | 
| 199   policy->ProcessAction(action_api); |  | 
| 200 |  | 
| 201   scoped_refptr<Action> action_dom = new Action(extension->id(), |  | 
| 202                                                 base::Time::Now(), |  | 
| 203                                                 Action::ACTION_DOM_ACCESS, |  | 
| 204                                                 "document.write"); |  | 
| 205   action_dom->set_args(make_scoped_ptr(new base::ListValue())); |  | 
| 206   action_dom->set_page_url(gurl); |  | 
| 207   policy->ProcessAction(action_dom); |  | 
| 208 |  | 
| 209   CheckReadData( |  | 
| 210       policy, |  | 
| 211       extension->id(), |  | 
| 212       0, |  | 
| 213       base::Bind(&FullStreamUIPolicyTest::RetrieveActions_LogAndFetchActions)); |  | 
| 214 |  | 
| 215   policy->Close(); |  | 
| 216 } |  | 
| 217 |  | 
| 218 TEST_F(FullStreamUIPolicyTest, LogWithArguments) { |  | 
| 219   ActivityLogPolicy* policy = new FullStreamUIPolicy(profile_.get()); |  | 
| 220   scoped_refptr<const Extension> extension = |  | 
| 221       ExtensionBuilder() |  | 
| 222           .SetManifest(DictionaryBuilder() |  | 
| 223                        .Set("name", "Test extension") | 199                        .Set("name", "Test extension") | 
| 224                        .Set("version", "1.0.0") | 200                        .Set("version", "1.0.0") | 
| 225                        .Set("manifest_version", 2)) | 201                        .Set("manifest_version", 2)) | 
| 226           .Build(); | 202           .Build(); | 
| 227   extension_service_->AddExtension(extension.get()); | 203   extension_service_->AddExtension(extension.get()); | 
| 228 | 204 | 
| 229   scoped_ptr<base::ListValue> args(new base::ListValue()); | 205   scoped_ptr<base::ListValue> args(new base::ListValue()); | 
| 230   args->Set(0, new base::StringValue("hello")); | 206   args->Set(0, new base::StringValue("hello")); | 
| 231   args->Set(1, new base::StringValue("world")); | 207   args->Set(1, new base::StringValue("world")); | 
| 232   scoped_refptr<Action> action = new Action(extension->id(), | 208   scoped_refptr<Action> action = new Action(extension->id(), | 
| 233                                             base::Time::Now(), | 209                                             base::Time::Now(), | 
| 234                                             Action::ACTION_API_CALL, | 210                                             Action::ACTION_API_CALL, | 
| 235                                             "extension.connect"); | 211                                             "extension.connect"); | 
| 236   action->set_args(args.Pass()); | 212   action->set_args(args.Pass()); | 
| 237 | 213 | 
| 238   policy->ProcessAction(action); | 214   policy->ProcessAction(action); | 
| 239   CheckReadData(policy, | 215   CheckReadData(policy, | 
| 240                 extension->id(), | 216                 extension->id(), | 
| 241                 0, | 217                 0, | 
| 242                 base::Bind(&FullStreamUIPolicyTest::Arguments_Present)); | 218                 base::Bind(&CountingPolicyTest::Arguments_Stripped)); | 
| 243   policy->Close(); | 219   policy->Close(); | 
| 244 } | 220 } | 
| 245 | 221 | 
| 246 TEST_F(FullStreamUIPolicyTest, GetTodaysActions) { | 222 TEST_F(CountingPolicyTest, GetTodaysActions) { | 
| 247   ActivityLogPolicy* policy = new FullStreamUIPolicy(profile_.get()); | 223   CountingPolicy* policy = new CountingPolicy(profile_.get()); | 
|  | 224   // Disable row expiration for this test by setting a time before any actions | 
|  | 225   // we generate. | 
|  | 226   policy->set_retention_time(base::TimeDelta::FromDays(14)); | 
| 248 | 227 | 
| 249   // Use a mock clock to ensure that events are not recorded on the wrong day | 228   // Use a mock clock to ensure that events are not recorded on the wrong day | 
| 250   // when the test is run close to local midnight. | 229   // when the test is run close to local midnight.  Note: Ownership is passed | 
| 251   base::SimpleTestClock mock_clock; | 230   // to the policy, but we still keep a pointer locally.  The policy will take | 
| 252   mock_clock.SetNow(base::Time::Now().LocalMidnight() + | 231   // care of destruction; this is safe since the policy outlives all our | 
| 253                     base::TimeDelta::FromHours(12)); | 232   // accesses to the mock clock. | 
| 254   policy->SetClockForTesting(&mock_clock); | 233   base::SimpleTestClock* mock_clock = new base::SimpleTestClock(); | 
|  | 234   mock_clock->SetNow(base::Time::Now().LocalMidnight() + | 
|  | 235                      base::TimeDelta::FromHours(12)); | 
|  | 236   policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock)); | 
| 255 | 237 | 
| 256   // Record some actions | 238   // Record some actions | 
| 257   scoped_refptr<Action> action = | 239   scoped_refptr<Action> action = | 
| 258       new Action("punky", | 240       new Action("punky", | 
| 259                  mock_clock.Now() - base::TimeDelta::FromMinutes(40), | 241                  mock_clock->Now() - base::TimeDelta::FromMinutes(40), | 
| 260                  Action::ACTION_API_CALL, | 242                  Action::ACTION_API_CALL, | 
| 261                  "brewster"); | 243                  "brewster"); | 
| 262   action->mutable_args()->AppendString("woof"); | 244   action->mutable_args()->AppendString("woof"); | 
| 263   policy->ProcessAction(action); | 245   policy->ProcessAction(action); | 
| 264 | 246 | 
|  | 247   action = new Action("punky", | 
|  | 248                       mock_clock->Now() - base::TimeDelta::FromMinutes(30), | 
|  | 249                       Action::ACTION_API_CALL, | 
|  | 250                       "brewster"); | 
|  | 251   action->mutable_args()->AppendString("meow"); | 
|  | 252   policy->ProcessAction(action); | 
|  | 253 | 
|  | 254   action = new Action("punky", | 
|  | 255                       mock_clock->Now() - base::TimeDelta::FromMinutes(20), | 
|  | 256                       Action::ACTION_API_CALL, | 
|  | 257                       "extension.sendMessage"); | 
|  | 258   action->mutable_args()->AppendString("not"); | 
|  | 259   action->mutable_args()->AppendString("stripped"); | 
|  | 260   policy->ProcessAction(action); | 
|  | 261 | 
| 265   action = | 262   action = | 
| 266       new Action("punky", mock_clock.Now(), Action::ACTION_DOM_ACCESS, "lets"); | 263       new Action("punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets"); | 
| 267   action->mutable_args()->AppendString("vamoose"); | 264   action->mutable_args()->AppendString("vamoose"); | 
| 268   action->set_page_url(GURL("http://www.google.com")); | 265   action->set_page_url(GURL("http://www.google.com")); | 
| 269   policy->ProcessAction(action); | 266   policy->ProcessAction(action); | 
| 270 | 267 | 
| 271   action = new Action( | 268   action = new Action( | 
| 272       "scoobydoo", mock_clock.Now(), Action::ACTION_DOM_ACCESS, "lets"); | 269       "scoobydoo", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets"); | 
| 273   action->mutable_args()->AppendString("vamoose"); | 270   action->mutable_args()->AppendString("vamoose"); | 
| 274   action->set_page_url(GURL("http://www.google.com")); | 271   action->set_page_url(GURL("http://www.google.com")); | 
| 275   policy->ProcessAction(action); | 272   policy->ProcessAction(action); | 
| 276 | 273 | 
| 277   CheckReadData( | 274   CheckReadData( | 
| 278       policy, | 275       policy, | 
| 279       "punky", | 276       "punky", | 
| 280       0, | 277       0, | 
| 281       base::Bind(&FullStreamUIPolicyTest::Arguments_GetTodaysActions)); | 278       base::Bind(&CountingPolicyTest::Arguments_GetTodaysActions)); | 
| 282   policy->Close(); | 279   policy->Close(); | 
| 283 } | 280 } | 
| 284 | 281 | 
| 285 // Check that we can read back less recent actions in the db. | 282 // Check that we can read back less recent actions in the db. | 
| 286 TEST_F(FullStreamUIPolicyTest, GetOlderActions) { | 283 TEST_F(CountingPolicyTest, GetOlderActions) { | 
| 287   ActivityLogPolicy* policy = new FullStreamUIPolicy(profile_.get()); | 284   CountingPolicy* policy = new CountingPolicy(profile_.get()); | 
|  | 285   policy->set_retention_time(base::TimeDelta::FromDays(14)); | 
| 288 | 286 | 
| 289   // Use a mock clock to ensure that events are not recorded on the wrong day | 287   // Use a mock clock to ensure that events are not recorded on the wrong day | 
| 290   // when the test is run close to local midnight. | 288   // when the test is run close to local midnight. | 
| 291   base::SimpleTestClock mock_clock; | 289   base::SimpleTestClock* mock_clock = new base::SimpleTestClock(); | 
| 292   mock_clock.SetNow(base::Time::Now().LocalMidnight() + | 290   mock_clock->SetNow(base::Time::Now().LocalMidnight() + | 
| 293                     base::TimeDelta::FromHours(12)); | 291                      base::TimeDelta::FromHours(12)); | 
| 294   policy->SetClockForTesting(&mock_clock); | 292   policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock)); | 
| 295 | 293 | 
| 296   // Record some actions | 294   // Record some actions | 
| 297   scoped_refptr<Action> action = | 295   scoped_refptr<Action> action = | 
| 298       new Action("punky", | 296       new Action("punky", | 
| 299                  mock_clock.Now() - base::TimeDelta::FromDays(3) - | 297                  mock_clock->Now() - base::TimeDelta::FromDays(3) - | 
| 300                      base::TimeDelta::FromMinutes(40), | 298                      base::TimeDelta::FromMinutes(40), | 
| 301                  Action::ACTION_API_CALL, | 299                  Action::ACTION_API_CALL, | 
| 302                  "brewster"); | 300                  "brewster"); | 
| 303   action->mutable_args()->AppendString("woof"); | 301   action->mutable_args()->AppendString("woof"); | 
| 304   policy->ProcessAction(action); | 302   policy->ProcessAction(action); | 
| 305 | 303 | 
| 306   action = new Action("punky", | 304   action = new Action("punky", | 
| 307                       mock_clock.Now() - base::TimeDelta::FromDays(3), | 305                       mock_clock->Now() - base::TimeDelta::FromDays(3), | 
| 308                       Action::ACTION_DOM_ACCESS, | 306                       Action::ACTION_DOM_ACCESS, | 
| 309                       "lets"); | 307                       "lets"); | 
| 310   action->mutable_args()->AppendString("vamoose"); | 308   action->mutable_args()->AppendString("vamoose"); | 
| 311   action->set_page_url(GURL("http://www.google.com")); | 309   action->set_page_url(GURL("http://www.google.com")); | 
| 312   policy->ProcessAction(action); | 310   policy->ProcessAction(action); | 
| 313 | 311 | 
| 314   action = new Action("punky", | 312   action = new Action("punky", | 
| 315                       mock_clock.Now(), | 313                       mock_clock->Now(), | 
| 316                       Action::ACTION_DOM_ACCESS, | 314                       Action::ACTION_DOM_ACCESS, | 
| 317                       "lets"); | 315                       "lets"); | 
| 318   action->mutable_args()->AppendString("too new"); | 316   action->mutable_args()->AppendString("too new"); | 
| 319   action->set_page_url(GURL("http://www.google.com")); | 317   action->set_page_url(GURL("http://www.google.com")); | 
| 320   policy->ProcessAction(action); | 318   policy->ProcessAction(action); | 
| 321 | 319 | 
| 322   action = new Action("punky", | 320   action = new Action("punky", | 
| 323                       mock_clock.Now() - base::TimeDelta::FromDays(7), | 321                       mock_clock->Now() - base::TimeDelta::FromDays(7), | 
| 324                       Action::ACTION_DOM_ACCESS, | 322                       Action::ACTION_DOM_ACCESS, | 
| 325                       "lets"); | 323                       "lets"); | 
| 326   action->mutable_args()->AppendString("too old"); | 324   action->mutable_args()->AppendString("too old"); | 
| 327   action->set_page_url(GURL("http://www.google.com")); | 325   action->set_page_url(GURL("http://www.google.com")); | 
| 328   policy->ProcessAction(action); | 326   policy->ProcessAction(action); | 
| 329 | 327 | 
| 330   CheckReadData( | 328   CheckReadData( | 
| 331       policy, | 329       policy, | 
| 332       "punky", | 330       "punky", | 
| 333       3, | 331       3, | 
| 334       base::Bind(&FullStreamUIPolicyTest::Arguments_GetOlderActions)); | 332       base::Bind(&CountingPolicyTest::Arguments_GetOlderActions)); | 
|  | 333 | 
| 335   policy->Close(); | 334   policy->Close(); | 
| 336 } | 335 } | 
| 337 | 336 | 
|  | 337 // Check that merging of actions only occurs within the same day, not across | 
|  | 338 // days, and that old data can be expired from the database. | 
|  | 339 TEST_F(CountingPolicyTest, MergingAndExpiring) { | 
|  | 340   CountingPolicy* policy = new CountingPolicy(profile_.get()); | 
|  | 341   // Initially disable expiration by setting a retention time before any | 
|  | 342   // actions we generate. | 
|  | 343   policy->set_retention_time(base::TimeDelta::FromDays(14)); | 
|  | 344 | 
|  | 345   // Use a mock clock to ensure that events are not recorded on the wrong day | 
|  | 346   // when the test is run close to local midnight. | 
|  | 347   base::SimpleTestClock* mock_clock = new base::SimpleTestClock(); | 
|  | 348   mock_clock->SetNow(base::Time::Now().LocalMidnight() + | 
|  | 349                     base::TimeDelta::FromHours(12)); | 
|  | 350   policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock)); | 
|  | 351 | 
|  | 352   // The first two actions should be merged; the last one is on a separate day | 
|  | 353   // and should not be. | 
|  | 354   scoped_refptr<Action> action = | 
|  | 355       new Action("punky", | 
|  | 356                  mock_clock->Now() - base::TimeDelta::FromDays(3) - | 
|  | 357                      base::TimeDelta::FromMinutes(40), | 
|  | 358                  Action::ACTION_API_CALL, | 
|  | 359                  "brewster"); | 
|  | 360   policy->ProcessAction(action); | 
|  | 361 | 
|  | 362   action = new Action("punky", | 
|  | 363                       mock_clock->Now() - base::TimeDelta::FromDays(3) - | 
|  | 364                           base::TimeDelta::FromMinutes(20), | 
|  | 365                       Action::ACTION_API_CALL, | 
|  | 366                       "brewster"); | 
|  | 367   policy->ProcessAction(action); | 
|  | 368 | 
|  | 369   action = new Action("punky", | 
|  | 370                       mock_clock->Now() - base::TimeDelta::FromDays(2) - | 
|  | 371                           base::TimeDelta::FromMinutes(20), | 
|  | 372                       Action::ACTION_API_CALL, | 
|  | 373                       "brewster"); | 
|  | 374   policy->ProcessAction(action); | 
|  | 375 | 
|  | 376   CheckReadData(policy, | 
|  | 377                 "punky", | 
|  | 378                 3, | 
|  | 379                 base::Bind(&CountingPolicyTest::Arguments_CheckMergeCount, 2)); | 
|  | 380   CheckReadData(policy, | 
|  | 381                 "punky", | 
|  | 382                 2, | 
|  | 383                 base::Bind(&CountingPolicyTest::Arguments_CheckMergeCount, 1)); | 
|  | 384 | 
|  | 385   // Clean actions before midnight two days ago.  Force expiration to run by | 
|  | 386   // clearing last_database_cleaning_time_ and submitting a new action. | 
|  | 387   policy->set_retention_time(base::TimeDelta::FromDays(2)); | 
|  | 388   policy->last_database_cleaning_time_ = base::Time(); | 
|  | 389   action = new Action("punky", | 
|  | 390                       mock_clock->Now(), | 
|  | 391                       Action::ACTION_API_CALL, | 
|  | 392                       "brewster"); | 
|  | 393   policy->ProcessAction(action); | 
|  | 394 | 
|  | 395   CheckReadData(policy, | 
|  | 396                 "punky", | 
|  | 397                 3, | 
|  | 398                 base::Bind(&CountingPolicyTest::Arguments_CheckMergeCount, 0)); | 
|  | 399   CheckReadData(policy, | 
|  | 400                 "punky", | 
|  | 401                 2, | 
|  | 402                 base::Bind(&CountingPolicyTest::Arguments_CheckMergeCount, 1)); | 
|  | 403 | 
|  | 404   policy->Close(); | 
|  | 405 } | 
|  | 406 | 
| 338 }  // namespace extensions | 407 }  // namespace extensions | 
| OLD | NEW | 
|---|