ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / extensions / activity_log / counting_policy_unittest.cc
blobe52a03c3c0e0bacfc0c49f8d1201734c1664031d
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
3 // found in the LICENSE file.
5 #include "base/cancelable_callback.h"
6 #include "base/command_line.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/run_loop.h"
9 #include "base/strings/string_split.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "base/test/simple_test_clock.h"
13 #include "base/test/test_timeouts.h"
14 #include "chrome/browser/extensions/activity_log/activity_log.h"
15 #include "chrome/browser/extensions/activity_log/counting_policy.h"
16 #include "chrome/browser/extensions/extension_service.h"
17 #include "chrome/browser/extensions/test_extension_system.h"
18 #include "chrome/common/chrome_constants.h"
19 #include "chrome/common/chrome_switches.h"
20 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
21 #include "chrome/test/base/testing_profile.h"
22 #include "content/public/test/test_browser_thread_bundle.h"
23 #include "extensions/common/extension_builder.h"
24 #include "sql/statement.h"
25 #include "testing/gtest/include/gtest/gtest.h"
27 #if defined(OS_CHROMEOS)
28 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
29 #include "chrome/browser/chromeos/settings/cros_settings.h"
30 #include "chrome/browser/chromeos/settings/device_settings_service.h"
31 #endif
33 using content::BrowserThread;
35 namespace extensions {
37 class CountingPolicyTest : public testing::Test {
38 public:
39 CountingPolicyTest()
40 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
41 saved_cmdline_(base::CommandLine::NO_PROGRAM) {
42 #if defined OS_CHROMEOS
43 test_user_manager_.reset(new chromeos::ScopedTestUserManager());
44 #endif
45 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
46 saved_cmdline_ = *base::CommandLine::ForCurrentProcess();
47 profile_.reset(new TestingProfile());
48 base::CommandLine::ForCurrentProcess()->AppendSwitch(
49 switches::kEnableExtensionActivityLogging);
50 extension_service_ = static_cast<TestExtensionSystem*>(
51 ExtensionSystem::Get(profile_.get()))->CreateExtensionService
52 (&command_line, base::FilePath(), false);
55 ~CountingPolicyTest() override {
56 #if defined OS_CHROMEOS
57 test_user_manager_.reset();
58 #endif
59 base::RunLoop().RunUntilIdle();
60 profile_.reset(NULL);
61 base::RunLoop().RunUntilIdle();
62 // Restore the original command line and undo the affects of SetUp().
63 *base::CommandLine::ForCurrentProcess() = saved_cmdline_;
66 // Wait for the task queue for the specified thread to empty.
67 void WaitOnThread(const BrowserThread::ID& thread) {
68 BrowserThread::PostTaskAndReply(
69 thread,
70 FROM_HERE,
71 base::Bind(&base::DoNothing),
72 base::MessageLoop::current()->QuitClosure());
73 base::MessageLoop::current()->Run();
76 // A wrapper function for CheckReadFilteredData, so that we don't need to
77 // enter empty string values for parameters we don't care about.
78 void CheckReadData(
79 ActivityLogDatabasePolicy* policy,
80 const std::string& extension_id,
81 int day,
82 const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker) {
83 CheckReadFilteredData(
84 policy, extension_id, Action::ACTION_ANY, "", "", "", day, checker);
87 // A helper function to call ReadFilteredData on a policy object and wait for
88 // the results to be processed.
89 void CheckReadFilteredData(
90 ActivityLogDatabasePolicy* policy,
91 const std::string& extension_id,
92 const Action::ActionType type,
93 const std::string& api_name,
94 const std::string& page_url,
95 const std::string& arg_url,
96 int day,
97 const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker) {
98 // Submit a request to the policy to read back some data, and call the
99 // checker function when results are available. This will happen on the
100 // database thread.
101 policy->ReadFilteredData(
102 extension_id,
103 type,
104 api_name,
105 page_url,
106 arg_url,
107 day,
108 base::Bind(&CountingPolicyTest::CheckWrapper,
109 checker,
110 base::MessageLoop::current()->QuitClosure()));
112 // Set up a timeout for receiving results; if we haven't received anything
113 // when the timeout triggers then assume that the test is broken.
114 base::CancelableClosure timeout(
115 base::Bind(&CountingPolicyTest::TimeoutCallback));
116 base::MessageLoop::current()->PostDelayedTask(
117 FROM_HERE, timeout.callback(), TestTimeouts::action_timeout());
119 // Wait for results; either the checker or the timeout callbacks should
120 // cause the main loop to exit.
121 base::MessageLoop::current()->Run();
123 timeout.Cancel();
126 // A helper function which verifies that the string_ids and url_ids tables in
127 // the database have the specified sizes.
128 static void CheckStringTableSizes(CountingPolicy* policy,
129 int string_size,
130 int url_size) {
131 sql::Connection* db = policy->GetDatabaseConnection();
132 sql::Statement statement1(db->GetCachedStatement(
133 sql::StatementID(SQL_FROM_HERE), "SELECT COUNT(*) FROM string_ids"));
134 ASSERT_TRUE(statement1.Step());
135 ASSERT_EQ(string_size, statement1.ColumnInt(0));
137 sql::Statement statement2(db->GetCachedStatement(
138 sql::StatementID(SQL_FROM_HERE), "SELECT COUNT(*) FROM url_ids"));
139 ASSERT_TRUE(statement2.Step());
140 ASSERT_EQ(url_size, statement2.ColumnInt(0));
143 // Checks that the number of queued actions to be written out does not exceed
144 // kSizeThresholdForFlush. Runs on the database thread.
145 static void CheckQueueSize(CountingPolicy* policy) {
146 // This should be updated if kSizeThresholdForFlush in activity_database.cc
147 // changes.
148 ASSERT_LE(policy->queued_actions_.size(), 200U);
151 static void CheckWrapper(
152 const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker,
153 const base::Closure& done,
154 scoped_ptr<Action::ActionVector> results) {
155 checker.Run(results.Pass());
156 done.Run();
159 static void TimeoutCallback() {
160 base::MessageLoop::current()->QuitWhenIdle();
161 FAIL() << "Policy test timed out waiting for results";
164 static void RetrieveActions_FetchFilteredActions0(
165 scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
166 ASSERT_EQ(0, static_cast<int>(i->size()));
169 static void RetrieveActions_FetchFilteredActions1(
170 scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
171 ASSERT_EQ(1, static_cast<int>(i->size()));
174 static void RetrieveActions_FetchFilteredActions2(
175 scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
176 ASSERT_EQ(2, static_cast<int>(i->size()));
179 static void RetrieveActions_FetchFilteredActions300(
180 scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
181 ASSERT_EQ(300, static_cast<int>(i->size()));
184 static void Arguments_Stripped(scoped_ptr<Action::ActionVector> i) {
185 scoped_refptr<Action> last = i->front();
186 CheckAction(*last.get(),
187 "odlameecjipmbmbejkplpemijjgpljce",
188 Action::ACTION_API_CALL,
189 "extension.connect",
190 "[\"hello\",\"world\"]",
197 static void Arguments_GetSinglesAction(
198 scoped_ptr<Action::ActionVector> actions) {
199 ASSERT_EQ(1, static_cast<int>(actions->size()));
200 CheckAction(*actions->at(0).get(),
201 "punky",
202 Action::ACTION_DOM_ACCESS,
203 "lets",
205 "http://www.google.com/",
211 static void Arguments_GetTodaysActions(
212 scoped_ptr<Action::ActionVector> actions) {
213 ASSERT_EQ(3, static_cast<int>(actions->size()));
214 CheckAction(*actions->at(0).get(),
215 "punky",
216 Action::ACTION_API_CALL,
217 "brewster",
223 CheckAction(*actions->at(1).get(),
224 "punky",
225 Action::ACTION_DOM_ACCESS,
226 "lets",
228 "http://www.google.com/",
232 CheckAction(*actions->at(2).get(),
233 "punky",
234 Action::ACTION_API_CALL,
235 "extension.sendMessage",
236 "[\"not\",\"stripped\"]",
243 static void Arguments_GetOlderActions(
244 scoped_ptr<Action::ActionVector> actions) {
245 ASSERT_EQ(2, static_cast<int>(actions->size()));
246 CheckAction(*actions->at(0).get(),
247 "punky",
248 Action::ACTION_DOM_ACCESS,
249 "lets",
251 "http://www.google.com/",
255 CheckAction(*actions->at(1).get(),
256 "punky",
257 Action::ACTION_API_CALL,
258 "brewster",
266 static void Arguments_CheckMergeCount(
267 int count,
268 scoped_ptr<Action::ActionVector> actions) {
269 if (count > 0) {
270 ASSERT_EQ(1u, actions->size());
271 CheckAction(*actions->at(0).get(),
272 "punky",
273 Action::ACTION_API_CALL,
274 "brewster",
279 count);
280 } else {
281 ASSERT_EQ(0u, actions->size());
285 static void Arguments_CheckMergeCountAndTime(
286 int count,
287 const base::Time& time,
288 scoped_ptr<Action::ActionVector> actions) {
289 if (count > 0) {
290 ASSERT_EQ(1u, actions->size());
291 CheckAction(*actions->at(0).get(),
292 "punky",
293 Action::ACTION_API_CALL,
294 "brewster",
299 count);
300 ASSERT_EQ(time, actions->at(0)->time());
301 } else {
302 ASSERT_EQ(0u, actions->size());
306 static void AllURLsRemoved(scoped_ptr<Action::ActionVector> actions) {
307 ASSERT_EQ(2, static_cast<int>(actions->size()));
308 CheckAction(*actions->at(0).get(),
309 "punky",
310 Action::ACTION_DOM_ACCESS,
311 "lets",
317 CheckAction(*actions->at(1).get(),
318 "punky",
319 Action::ACTION_DOM_ACCESS,
320 "lets",
328 static void SomeURLsRemoved(scoped_ptr<Action::ActionVector> actions) {
329 // These will be in the vector in reverse time order.
330 ASSERT_EQ(5, static_cast<int>(actions->size()));
331 CheckAction(*actions->at(0).get(),
332 "punky",
333 Action::ACTION_DOM_ACCESS,
334 "lets",
336 "http://www.google.com/",
337 "Google",
338 "http://www.args-url.com/",
340 CheckAction(*actions->at(1).get(),
341 "punky",
342 Action::ACTION_DOM_ACCESS,
343 "lets",
345 "http://www.google.com/",
346 "Google",
349 CheckAction(*actions->at(2).get(),
350 "punky",
351 Action::ACTION_DOM_ACCESS,
352 "lets",
358 CheckAction(*actions->at(3).get(),
359 "punky",
360 Action::ACTION_DOM_ACCESS,
361 "lets",
365 "http://www.google.com/",
367 CheckAction(*actions->at(4).get(),
368 "punky",
369 Action::ACTION_DOM_ACCESS,
370 "lets",
378 static void CheckDuplicates(scoped_ptr<Action::ActionVector> actions) {
379 ASSERT_EQ(2u, actions->size());
380 int total_count = 0;
381 for (size_t i = 0; i < actions->size(); i++) {
382 total_count += actions->at(i)->count();
384 ASSERT_EQ(3, total_count);
387 static void CheckAction(const Action& action,
388 const std::string& expected_id,
389 const Action::ActionType& expected_type,
390 const std::string& expected_api_name,
391 const std::string& expected_args_str,
392 const std::string& expected_page_url,
393 const std::string& expected_page_title,
394 const std::string& expected_arg_url,
395 int expected_count) {
396 ASSERT_EQ(expected_id, action.extension_id());
397 ASSERT_EQ(expected_type, action.action_type());
398 ASSERT_EQ(expected_api_name, action.api_name());
399 ASSERT_EQ(expected_args_str,
400 ActivityLogPolicy::Util::Serialize(action.args()));
401 ASSERT_EQ(expected_page_url, action.SerializePageUrl());
402 ASSERT_EQ(expected_page_title, action.page_title());
403 ASSERT_EQ(expected_arg_url, action.SerializeArgUrl());
404 ASSERT_EQ(expected_count, action.count());
405 ASSERT_NE(-1, action.action_id());
408 // A helper function initializes the policy with a number of actions, calls
409 // RemoveActions on a policy object and then checks the result of the
410 // deletion.
411 void CheckRemoveActions(
412 ActivityLogDatabasePolicy* policy,
413 const std::vector<int64>& action_ids,
414 const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker) {
416 // Use a mock clock to ensure that events are not recorded on the wrong day
417 // when the test is run close to local midnight.
418 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
419 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
420 base::TimeDelta::FromHours(12));
421 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
423 // Record some actions
424 scoped_refptr<Action> action =
425 new Action("punky1",
426 mock_clock->Now() - base::TimeDelta::FromMinutes(40),
427 Action::ACTION_DOM_ACCESS,
428 "lets1");
429 action->mutable_args()->AppendString("vamoose1");
430 action->set_page_url(GURL("http://www.google1.com"));
431 action->set_page_title("Google1");
432 action->set_arg_url(GURL("http://www.args-url1.com"));
433 policy->ProcessAction(action);
434 // Record the same action twice, so there are multiple entries in the
435 // database.
436 policy->ProcessAction(action);
438 action = new Action("punky2",
439 mock_clock->Now() - base::TimeDelta::FromMinutes(30),
440 Action::ACTION_API_CALL,
441 "lets2");
442 action->mutable_args()->AppendString("vamoose2");
443 action->set_page_url(GURL("http://www.google2.com"));
444 action->set_page_title("Google2");
445 action->set_arg_url(GURL("http://www.args-url2.com"));
446 policy->ProcessAction(action);
447 // Record the same action twice, so there are multiple entries in the
448 // database.
449 policy->ProcessAction(action);
451 // Submit a request to delete actions.
452 policy->RemoveActions(action_ids);
454 // Check the result of the deletion. The checker function gets all
455 // activities in the database.
456 CheckReadData(policy, "", -1, checker);
458 // Clean database.
459 policy->DeleteDatabase();
462 static void AllActionsDeleted(scoped_ptr<Action::ActionVector> actions) {
463 ASSERT_EQ(0, static_cast<int>(actions->size()));
466 static void NoActionsDeleted(scoped_ptr<Action::ActionVector> actions) {
467 // These will be in the vector in reverse time order.
468 ASSERT_EQ(2, static_cast<int>(actions->size()));
469 CheckAction(*actions->at(0).get(),
470 "punky2",
471 Action::ACTION_API_CALL,
472 "lets2",
474 "http://www.google2.com/",
475 "Google2",
476 "http://www.args-url2.com/",
478 ASSERT_EQ(2, actions->at(0)->action_id());
479 CheckAction(*actions->at(1).get(),
480 "punky1",
481 Action::ACTION_DOM_ACCESS,
482 "lets1",
484 "http://www.google1.com/",
485 "Google1",
486 "http://www.args-url1.com/",
488 ASSERT_EQ(1, actions->at(1)->action_id());
491 static void Action1Deleted(scoped_ptr<Action::ActionVector> actions) {
492 // These will be in the vector in reverse time order.
493 ASSERT_EQ(1, static_cast<int>(actions->size()));
494 CheckAction(*actions->at(0).get(),
495 "punky2",
496 Action::ACTION_API_CALL,
497 "lets2",
499 "http://www.google2.com/",
500 "Google2",
501 "http://www.args-url2.com/",
503 ASSERT_EQ(2, actions->at(0)->action_id());
506 static void Action2Deleted(scoped_ptr<Action::ActionVector> actions) {
507 // These will be in the vector in reverse time order.
508 ASSERT_EQ(1, static_cast<int>(actions->size()));
509 CheckAction(*actions->at(0).get(),
510 "punky1",
511 Action::ACTION_DOM_ACCESS,
512 "lets1",
514 "http://www.google1.com/",
515 "Google1",
516 "http://www.args-url1.com/",
518 ASSERT_EQ(1, actions->at(0)->action_id());
521 protected:
522 ExtensionService* extension_service_;
523 scoped_ptr<TestingProfile> profile_;
524 content::TestBrowserThreadBundle thread_bundle_;
525 // Used to preserve a copy of the original command line.
526 // The test framework will do this itself as well. However, by then,
527 // it is too late to call ActivityLog::RecomputeLoggingIsEnabled() in
528 // TearDown().
529 base::CommandLine saved_cmdline_;
531 #if defined OS_CHROMEOS
532 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
533 chromeos::ScopedTestCrosSettings test_cros_settings_;
534 scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_;
535 #endif
538 TEST_F(CountingPolicyTest, Construct) {
539 ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
540 policy->Init();
541 scoped_refptr<const Extension> extension =
542 ExtensionBuilder()
543 .SetManifest(DictionaryBuilder()
544 .Set("name", "Test extension")
545 .Set("version", "1.0.0")
546 .Set("manifest_version", 2))
547 .Build();
548 extension_service_->AddExtension(extension.get());
549 scoped_ptr<base::ListValue> args(new base::ListValue());
550 scoped_refptr<Action> action = new Action(extension->id(),
551 base::Time::Now(),
552 Action::ACTION_API_CALL,
553 "tabs.testMethod");
554 action->set_args(args.Pass());
555 policy->ProcessAction(action);
556 policy->Close();
559 TEST_F(CountingPolicyTest, LogWithStrippedArguments) {
560 ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
561 policy->Init();
562 scoped_refptr<const Extension> extension =
563 ExtensionBuilder()
564 .SetManifest(DictionaryBuilder()
565 .Set("name", "Test extension")
566 .Set("version", "1.0.0")
567 .Set("manifest_version", 2))
568 .Build();
569 extension_service_->AddExtension(extension.get());
571 scoped_ptr<base::ListValue> args(new base::ListValue());
572 args->Set(0, new base::StringValue("hello"));
573 args->Set(1, new base::StringValue("world"));
574 scoped_refptr<Action> action = new Action(extension->id(),
575 base::Time::Now(),
576 Action::ACTION_API_CALL,
577 "extension.connect");
578 action->set_args(args.Pass());
580 policy->ProcessAction(action);
581 CheckReadData(policy,
582 extension->id(),
584 base::Bind(&CountingPolicyTest::Arguments_Stripped));
585 policy->Close();
588 TEST_F(CountingPolicyTest, GetTodaysActions) {
589 CountingPolicy* policy = new CountingPolicy(profile_.get());
590 policy->Init();
591 // Disable row expiration for this test by setting a time before any actions
592 // we generate.
593 policy->set_retention_time(base::TimeDelta::FromDays(14));
595 // Use a mock clock to ensure that events are not recorded on the wrong day
596 // when the test is run close to local midnight. Note: Ownership is passed
597 // to the policy, but we still keep a pointer locally. The policy will take
598 // care of destruction; this is safe since the policy outlives all our
599 // accesses to the mock clock.
600 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
601 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
602 base::TimeDelta::FromHours(12));
603 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
605 // Record some actions
606 scoped_refptr<Action> action =
607 new Action("punky",
608 mock_clock->Now() - base::TimeDelta::FromMinutes(40),
609 Action::ACTION_API_CALL,
610 "brewster");
611 action->mutable_args()->AppendString("woof");
612 policy->ProcessAction(action);
614 action = new Action("punky",
615 mock_clock->Now() - base::TimeDelta::FromMinutes(30),
616 Action::ACTION_API_CALL,
617 "brewster");
618 action->mutable_args()->AppendString("meow");
619 policy->ProcessAction(action);
621 action = new Action("punky",
622 mock_clock->Now() - base::TimeDelta::FromMinutes(20),
623 Action::ACTION_API_CALL,
624 "extension.sendMessage");
625 action->mutable_args()->AppendString("not");
626 action->mutable_args()->AppendString("stripped");
627 policy->ProcessAction(action);
629 action =
630 new Action("punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
631 action->mutable_args()->AppendString("vamoose");
632 action->set_page_url(GURL("http://www.google.com"));
633 policy->ProcessAction(action);
635 action = new Action(
636 "scoobydoo", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
637 action->mutable_args()->AppendString("vamoose");
638 action->set_page_url(GURL("http://www.google.com"));
639 policy->ProcessAction(action);
641 CheckReadData(
642 policy,
643 "punky",
645 base::Bind(&CountingPolicyTest::Arguments_GetTodaysActions));
646 policy->Close();
649 // Check that we can read back less recent actions in the db.
650 TEST_F(CountingPolicyTest, GetOlderActions) {
651 CountingPolicy* policy = new CountingPolicy(profile_.get());
652 policy->Init();
653 policy->set_retention_time(base::TimeDelta::FromDays(14));
655 // Use a mock clock to ensure that events are not recorded on the wrong day
656 // when the test is run close to local midnight.
657 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
658 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
659 base::TimeDelta::FromHours(12));
660 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
662 // Record some actions
663 scoped_refptr<Action> action =
664 new Action("punky",
665 mock_clock->Now() - base::TimeDelta::FromDays(3) -
666 base::TimeDelta::FromMinutes(40),
667 Action::ACTION_API_CALL,
668 "brewster");
669 action->mutable_args()->AppendString("woof");
670 policy->ProcessAction(action);
672 action = new Action("punky",
673 mock_clock->Now() - base::TimeDelta::FromDays(3),
674 Action::ACTION_DOM_ACCESS,
675 "lets");
676 action->mutable_args()->AppendString("vamoose");
677 action->set_page_url(GURL("http://www.google.com"));
678 policy->ProcessAction(action);
680 action = new Action("punky",
681 mock_clock->Now(),
682 Action::ACTION_DOM_ACCESS,
683 "lets");
684 action->mutable_args()->AppendString("too new");
685 action->set_page_url(GURL("http://www.google.com"));
686 policy->ProcessAction(action);
688 action = new Action("punky",
689 mock_clock->Now() - base::TimeDelta::FromDays(7),
690 Action::ACTION_DOM_ACCESS,
691 "lets");
692 action->mutable_args()->AppendString("too old");
693 action->set_page_url(GURL("http://www.google.com"));
694 policy->ProcessAction(action);
696 CheckReadData(
697 policy,
698 "punky",
700 base::Bind(&CountingPolicyTest::Arguments_GetOlderActions));
702 policy->Close();
705 TEST_F(CountingPolicyTest, LogAndFetchFilteredActions) {
706 ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
707 policy->Init();
708 scoped_refptr<const Extension> extension =
709 ExtensionBuilder()
710 .SetManifest(DictionaryBuilder()
711 .Set("name", "Test extension")
712 .Set("version", "1.0.0")
713 .Set("manifest_version", 2))
714 .Build();
715 extension_service_->AddExtension(extension.get());
716 GURL gurl("http://www.google.com");
718 // Write some API calls
719 scoped_refptr<Action> action_api = new Action(extension->id(),
720 base::Time::Now(),
721 Action::ACTION_API_CALL,
722 "tabs.testMethod");
723 action_api->set_args(make_scoped_ptr(new base::ListValue()));
724 policy->ProcessAction(action_api);
726 scoped_refptr<Action> action_dom = new Action(extension->id(),
727 base::Time::Now(),
728 Action::ACTION_DOM_ACCESS,
729 "document.write");
730 action_dom->set_args(make_scoped_ptr(new base::ListValue()));
731 action_dom->set_page_url(gurl);
732 policy->ProcessAction(action_dom);
734 CheckReadFilteredData(
735 policy,
736 extension->id(),
737 Action::ACTION_API_CALL,
738 "tabs.testMethod",
742 base::Bind(
743 &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
745 CheckReadFilteredData(
746 policy,
748 Action::ACTION_DOM_ACCESS,
753 base::Bind(
754 &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
756 CheckReadFilteredData(
757 policy,
759 Action::ACTION_DOM_ACCESS,
761 "http://www.google.com/",
764 base::Bind(
765 &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
767 CheckReadFilteredData(
768 policy,
770 Action::ACTION_DOM_ACCESS,
772 "http://www.google.com",
775 base::Bind(
776 &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
778 CheckReadFilteredData(
779 policy,
781 Action::ACTION_DOM_ACCESS,
783 "http://www.goo",
786 base::Bind(
787 &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
789 CheckReadFilteredData(
790 policy,
791 extension->id(),
792 Action::ACTION_ANY,
797 base::Bind(
798 &CountingPolicyTest::RetrieveActions_FetchFilteredActions2));
800 policy->Close();
803 // Check that merging of actions only occurs within the same day, not across
804 // days, and that old data can be expired from the database.
805 TEST_F(CountingPolicyTest, MergingAndExpiring) {
806 CountingPolicy* policy = new CountingPolicy(profile_.get());
807 policy->Init();
808 // Initially disable expiration by setting a retention time before any
809 // actions we generate.
810 policy->set_retention_time(base::TimeDelta::FromDays(14));
812 // Use a mock clock to ensure that events are not recorded on the wrong day
813 // when the test is run close to local midnight.
814 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
815 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
816 base::TimeDelta::FromHours(12));
817 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
819 // The first two actions should be merged; the last one is on a separate day
820 // and should not be.
821 scoped_refptr<Action> action =
822 new Action("punky",
823 mock_clock->Now() - base::TimeDelta::FromDays(3) -
824 base::TimeDelta::FromMinutes(40),
825 Action::ACTION_API_CALL,
826 "brewster");
827 policy->ProcessAction(action);
829 action = new Action("punky",
830 mock_clock->Now() - base::TimeDelta::FromDays(3) -
831 base::TimeDelta::FromMinutes(20),
832 Action::ACTION_API_CALL,
833 "brewster");
834 policy->ProcessAction(action);
836 action = new Action("punky",
837 mock_clock->Now() - base::TimeDelta::FromDays(2) -
838 base::TimeDelta::FromMinutes(20),
839 Action::ACTION_API_CALL,
840 "brewster");
841 policy->ProcessAction(action);
843 CheckReadData(policy,
844 "punky",
846 base::Bind(&CountingPolicyTest::Arguments_CheckMergeCount, 2));
847 CheckReadData(policy,
848 "punky",
850 base::Bind(&CountingPolicyTest::Arguments_CheckMergeCount, 1));
852 // Clean actions before midnight two days ago. Force expiration to run by
853 // clearing last_database_cleaning_time_ and submitting a new action.
854 policy->set_retention_time(base::TimeDelta::FromDays(2));
855 policy->last_database_cleaning_time_ = base::Time();
856 action = new Action("punky",
857 mock_clock->Now(),
858 Action::ACTION_API_CALL,
859 "brewster");
860 policy->ProcessAction(action);
862 CheckReadData(policy,
863 "punky",
865 base::Bind(&CountingPolicyTest::Arguments_CheckMergeCount, 0));
866 CheckReadData(policy,
867 "punky",
869 base::Bind(&CountingPolicyTest::Arguments_CheckMergeCount, 1));
871 policy->Close();
874 // Test cleaning of old data in the string and URL tables.
875 TEST_F(CountingPolicyTest, StringTableCleaning) {
876 CountingPolicy* policy = new CountingPolicy(profile_.get());
877 policy->Init();
878 // Initially disable expiration by setting a retention time before any
879 // actions we generate.
880 policy->set_retention_time(base::TimeDelta::FromDays(14));
882 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
883 mock_clock->SetNow(base::Time::Now());
884 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
886 // Insert an action; this should create entries in both the string table (for
887 // the extension and API name) and the URL table (for page_url).
888 scoped_refptr<Action> action =
889 new Action("punky",
890 mock_clock->Now() - base::TimeDelta::FromDays(7),
891 Action::ACTION_API_CALL,
892 "brewster");
893 action->set_page_url(GURL("http://www.google.com/"));
894 policy->ProcessAction(action);
896 // Add an action which will not be expired, so that some strings will remain
897 // in use.
898 action = new Action(
899 "punky", mock_clock->Now(), Action::ACTION_API_CALL, "tabs.create");
900 policy->ProcessAction(action);
902 // There should now be three strings ("punky", "brewster", "tabs.create") and
903 // one URL in the tables.
904 policy->Flush();
905 policy->ScheduleAndForget(policy,
906 &CountingPolicyTest::CheckStringTableSizes,
909 WaitOnThread(BrowserThread::DB);
911 // Trigger a cleaning. The oldest action is expired when we submit a
912 // duplicate of the newer action. After this, there should be two strings
913 // and no URLs.
914 policy->set_retention_time(base::TimeDelta::FromDays(2));
915 policy->last_database_cleaning_time_ = base::Time();
916 policy->ProcessAction(action);
917 policy->Flush();
918 policy->ScheduleAndForget(policy,
919 &CountingPolicyTest::CheckStringTableSizes,
922 WaitOnThread(BrowserThread::DB);
924 policy->Close();
927 // A stress test for memory- and database-based merging of actions. Submit
928 // multiple items, not in chronological order, spanning a few days. Check that
929 // items are merged properly and final timestamps are correct.
930 TEST_F(CountingPolicyTest, MoreMerging) {
931 CountingPolicy* policy = new CountingPolicy(profile_.get());
932 policy->Init();
933 policy->set_retention_time(base::TimeDelta::FromDays(14));
935 // Use a mock clock to ensure that events are not recorded on the wrong day
936 // when the test is run close to local midnight.
937 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
938 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
939 base::TimeDelta::FromHours(12));
940 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
942 // Create an action 2 days ago, then 1 day ago, then 2 days ago. Make sure
943 // that we end up with two merged records (one for each day), and each has
944 // the appropriate timestamp. These merges should happen in the database
945 // since the date keeps changing.
946 base::Time time1 =
947 mock_clock->Now() - base::TimeDelta::FromDays(2) -
948 base::TimeDelta::FromMinutes(40);
949 base::Time time2 =
950 mock_clock->Now() - base::TimeDelta::FromDays(1) -
951 base::TimeDelta::FromMinutes(40);
952 base::Time time3 =
953 mock_clock->Now() - base::TimeDelta::FromDays(2) -
954 base::TimeDelta::FromMinutes(20);
956 scoped_refptr<Action> action =
957 new Action("punky", time1, Action::ACTION_API_CALL, "brewster");
958 policy->ProcessAction(action);
960 action = new Action("punky", time2, Action::ACTION_API_CALL, "brewster");
961 policy->ProcessAction(action);
963 action = new Action("punky", time3, Action::ACTION_API_CALL, "brewster");
964 policy->ProcessAction(action);
966 CheckReadData(
967 policy,
968 "punky",
970 base::Bind(
971 &CountingPolicyTest::Arguments_CheckMergeCountAndTime, 2, time3));
972 CheckReadData(
973 policy,
974 "punky",
976 base::Bind(
977 &CountingPolicyTest::Arguments_CheckMergeCountAndTime, 1, time2));
979 // Create three actions today, where the merges should happen in memory.
980 // Again these are not chronological; timestamp time5 should win out since it
981 // is the latest.
982 base::Time time4 = mock_clock->Now() - base::TimeDelta::FromMinutes(60);
983 base::Time time5 = mock_clock->Now() - base::TimeDelta::FromMinutes(20);
984 base::Time time6 = mock_clock->Now() - base::TimeDelta::FromMinutes(40);
986 action = new Action("punky", time4, Action::ACTION_API_CALL, "brewster");
987 policy->ProcessAction(action);
989 action = new Action("punky", time5, Action::ACTION_API_CALL, "brewster");
990 policy->ProcessAction(action);
992 action = new Action("punky", time6, Action::ACTION_API_CALL, "brewster");
993 policy->ProcessAction(action);
995 CheckReadData(
996 policy,
997 "punky",
999 base::Bind(
1000 &CountingPolicyTest::Arguments_CheckMergeCountAndTime, 3, time5));
1001 policy->Close();
1004 // Check that actions are flushed to disk before letting too many accumulate in
1005 // memory.
1006 TEST_F(CountingPolicyTest, EarlyFlush) {
1007 CountingPolicy* policy = new CountingPolicy(profile_.get());
1008 policy->Init();
1010 for (int i = 0; i < 500; i++) {
1011 scoped_refptr<Action> action =
1012 new Action("punky",
1013 base::Time::Now(),
1014 Action::ACTION_API_CALL,
1015 base::StringPrintf("apicall_%d", i));
1016 policy->ProcessAction(action);
1019 policy->ScheduleAndForget(policy, &CountingPolicyTest::CheckQueueSize);
1020 WaitOnThread(BrowserThread::DB);
1022 policy->Close();
1025 TEST_F(CountingPolicyTest, CapReturns) {
1026 CountingPolicy* policy = new CountingPolicy(profile_.get());
1027 policy->Init();
1029 for (int i = 0; i < 305; i++) {
1030 scoped_refptr<Action> action =
1031 new Action("punky",
1032 base::Time::Now(),
1033 Action::ACTION_API_CALL,
1034 base::StringPrintf("apicall_%d", i));
1035 policy->ProcessAction(action);
1038 policy->Flush();
1039 WaitOnThread(BrowserThread::DB);
1041 CheckReadFilteredData(
1042 policy,
1043 "punky",
1044 Action::ACTION_ANY,
1049 base::Bind(
1050 &CountingPolicyTest::RetrieveActions_FetchFilteredActions300));
1051 policy->Close();
1054 TEST_F(CountingPolicyTest, RemoveAllURLs) {
1055 ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
1056 policy->Init();
1058 // Use a mock clock to ensure that events are not recorded on the wrong day
1059 // when the test is run close to local midnight.
1060 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
1061 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
1062 base::TimeDelta::FromHours(12));
1063 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
1065 // Record some actions
1066 scoped_refptr<Action> action =
1067 new Action("punky", mock_clock->Now(),
1068 Action::ACTION_DOM_ACCESS, "lets");
1069 action->mutable_args()->AppendString("vamoose");
1070 action->set_page_url(GURL("http://www.google.com"));
1071 action->set_page_title("Google");
1072 action->set_arg_url(GURL("http://www.args-url.com"));
1073 policy->ProcessAction(action);
1075 mock_clock->Advance(base::TimeDelta::FromSeconds(1));
1076 action = new Action(
1077 "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
1078 action->mutable_args()->AppendString("vamoose");
1079 action->set_page_url(GURL("http://www.google2.com"));
1080 action->set_page_title("Google");
1081 // Deliberately no arg url set to make sure it stills works if there is no arg
1082 // url.
1083 policy->ProcessAction(action);
1085 // Clean all the URLs.
1086 std::vector<GURL> no_url_restrictions;
1087 policy->RemoveURLs(no_url_restrictions);
1089 CheckReadData(
1090 policy,
1091 "punky",
1093 base::Bind(&CountingPolicyTest::AllURLsRemoved));
1094 policy->Close();
1097 TEST_F(CountingPolicyTest, RemoveSpecificURLs) {
1098 ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
1099 policy->Init();
1101 // Use a mock clock to ensure that events are not recorded on the wrong day
1102 // when the test is run close to local midnight.
1103 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
1104 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
1105 base::TimeDelta::FromHours(12));
1106 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
1108 // Record some actions
1109 // This should have the page url and args url cleared.
1110 scoped_refptr<Action> action = new Action("punky", mock_clock->Now(),
1111 Action::ACTION_DOM_ACCESS, "lets");
1112 action->mutable_args()->AppendString("vamoose");
1113 action->set_page_url(GURL("http://www.google1.com"));
1114 action->set_page_title("Google");
1115 action->set_arg_url(GURL("http://www.google1.com"));
1116 policy->ProcessAction(action);
1118 // This should have the page url cleared but not args url.
1119 mock_clock->Advance(base::TimeDelta::FromSeconds(1));
1120 action = new Action(
1121 "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
1122 action->mutable_args()->AppendString("vamoose");
1123 action->set_page_url(GURL("http://www.google1.com"));
1124 action->set_page_title("Google");
1125 action->set_arg_url(GURL("http://www.google.com"));
1126 policy->ProcessAction(action);
1128 // This should have the page url cleared. The args url is deliberately not
1129 // set to make sure this doesn't cause any issues.
1130 mock_clock->Advance(base::TimeDelta::FromSeconds(1));
1131 action = new Action(
1132 "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
1133 action->mutable_args()->AppendString("vamoose");
1134 action->set_page_url(GURL("http://www.google2.com"));
1135 action->set_page_title("Google");
1136 policy->ProcessAction(action);
1138 // This should have the args url cleared but not the page url or page title.
1139 mock_clock->Advance(base::TimeDelta::FromSeconds(1));
1140 action = new Action(
1141 "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
1142 action->mutable_args()->AppendString("vamoose");
1143 action->set_page_url(GURL("http://www.google.com"));
1144 action->set_page_title("Google");
1145 action->set_arg_url(GURL("http://www.google1.com"));
1146 policy->ProcessAction(action);
1148 // This should have neither cleared.
1149 mock_clock->Advance(base::TimeDelta::FromSeconds(1));
1150 action = new Action(
1151 "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
1152 action->mutable_args()->AppendString("vamoose");
1153 action->set_page_url(GURL("http://www.google.com"));
1154 action->set_page_title("Google");
1155 action->set_arg_url(GURL("http://www.args-url.com"));
1156 action->set_count(5);
1157 policy->ProcessAction(action);
1159 // Clean some URLs.
1160 std::vector<GURL> urls;
1161 urls.push_back(GURL("http://www.google1.com"));
1162 urls.push_back(GURL("http://www.google2.com"));
1163 urls.push_back(GURL("http://www.url_not_in_db.com"));
1164 policy->RemoveURLs(urls);
1166 CheckReadData(
1167 policy,
1168 "punky",
1170 base::Bind(&CountingPolicyTest::SomeURLsRemoved));
1171 policy->Close();
1174 TEST_F(CountingPolicyTest, RemoveExtensionData) {
1175 CountingPolicy* policy = new CountingPolicy(profile_.get());
1176 policy->Init();
1178 // Use a mock clock to ensure that events are not recorded on the wrong day
1179 // when the test is run close to local midnight.
1180 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
1181 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
1182 base::TimeDelta::FromHours(12));
1183 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
1185 // Record some actions
1186 scoped_refptr<Action> action = new Action("deleteextensiondata",
1187 mock_clock->Now(),
1188 Action::ACTION_DOM_ACCESS,
1189 "lets");
1190 action->mutable_args()->AppendString("vamoose");
1191 action->set_page_title("Google");
1192 action->set_arg_url(GURL("http://www.google.com"));
1193 policy->ProcessAction(action);
1194 policy->ProcessAction(action);
1195 policy->ProcessAction(action);
1197 scoped_refptr<Action> action2 = new Action("dontdelete",
1198 mock_clock->Now(),
1199 Action::ACTION_DOM_ACCESS,
1200 "lets");
1201 action->mutable_args()->AppendString("vamoose");
1202 action->set_page_title("Google");
1203 action->set_arg_url(GURL("http://www.google.com"));
1204 policy->ProcessAction(action2);
1206 policy->Flush();
1207 policy->RemoveExtensionData("deleteextensiondata");
1209 CheckReadFilteredData(
1210 policy,
1211 "deleteextensiondata",
1212 Action::ACTION_ANY,
1217 base::Bind(
1218 &CountingPolicyTest::RetrieveActions_FetchFilteredActions0));
1220 CheckReadFilteredData(
1221 policy,
1222 "dontdelete",
1223 Action::ACTION_ANY,
1228 base::Bind(
1229 &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
1230 policy->Close();
1233 TEST_F(CountingPolicyTest, DeleteDatabase) {
1234 CountingPolicy* policy = new CountingPolicy(profile_.get());
1235 policy->Init();
1236 // Disable row expiration for this test by setting a time before any actions
1237 // we generate.
1238 policy->set_retention_time(base::TimeDelta::FromDays(14));
1240 // Use a mock clock to ensure that events are not recorded on the wrong day
1241 // when the test is run close to local midnight. Note: Ownership is passed
1242 // to the policy, but we still keep a pointer locally. The policy will take
1243 // care of destruction; this is safe since the policy outlives all our
1244 // accesses to the mock clock.
1245 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
1246 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
1247 base::TimeDelta::FromHours(12));
1248 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
1250 // Record some actions
1251 scoped_refptr<Action> action =
1252 new Action("punky",
1253 mock_clock->Now() - base::TimeDelta::FromMinutes(40),
1254 Action::ACTION_API_CALL,
1255 "brewster");
1256 action->mutable_args()->AppendString("woof");
1257 policy->ProcessAction(action);
1259 action = new Action("punky",
1260 mock_clock->Now() - base::TimeDelta::FromMinutes(30),
1261 Action::ACTION_API_CALL,
1262 "brewster");
1263 action->mutable_args()->AppendString("meow");
1264 policy->ProcessAction(action);
1266 action = new Action("punky",
1267 mock_clock->Now() - base::TimeDelta::FromMinutes(20),
1268 Action::ACTION_API_CALL,
1269 "extension.sendMessage");
1270 action->mutable_args()->AppendString("not");
1271 action->mutable_args()->AppendString("stripped");
1272 policy->ProcessAction(action);
1274 action =
1275 new Action("punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
1276 action->mutable_args()->AppendString("vamoose");
1277 action->set_page_url(GURL("http://www.google.com"));
1278 policy->ProcessAction(action);
1280 action = new Action(
1281 "scoobydoo", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
1282 action->mutable_args()->AppendString("vamoose");
1283 action->set_page_url(GURL("http://www.google.com"));
1284 policy->ProcessAction(action);
1286 CheckReadData(
1287 policy,
1288 "punky",
1290 base::Bind(&CountingPolicyTest::Arguments_GetTodaysActions));
1292 policy->DeleteDatabase();
1294 CheckReadFilteredData(
1295 policy,
1297 Action::ACTION_ANY,
1302 base::Bind(
1303 &CountingPolicyTest::RetrieveActions_FetchFilteredActions0));
1305 // The following code tests that the caches of url and string tables were
1306 // cleared by the deletion above.
1307 // https://code.google.com/p/chromium/issues/detail?id=341674.
1308 action =
1309 new Action("punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
1310 action->mutable_args()->AppendString("vamoose");
1311 action->set_page_url(GURL("http://www.google.com"));
1312 policy->ProcessAction(action);
1314 CheckReadData(
1315 policy,
1318 base::Bind(&CountingPolicyTest::Arguments_GetSinglesAction));
1320 policy->DeleteDatabase();
1322 CheckReadFilteredData(
1323 policy,
1325 Action::ACTION_ANY,
1330 base::Bind(
1331 &CountingPolicyTest::RetrieveActions_FetchFilteredActions0));
1333 policy->Close();
1336 // Tests that duplicate rows in the activity log database are handled properly
1337 // when updating counts.
1338 TEST_F(CountingPolicyTest, DuplicateRows) {
1339 CountingPolicy* policy = new CountingPolicy(profile_.get());
1340 policy->Init();
1341 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
1342 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
1343 base::TimeDelta::FromHours(12));
1344 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
1346 // Record two actions with distinct URLs.
1347 scoped_refptr<Action> action;
1348 action = new Action(
1349 "punky", mock_clock->Now(), Action::ACTION_API_CALL, "brewster");
1350 action->set_page_url(GURL("http://www.google.com"));
1351 policy->ProcessAction(action);
1353 action = new Action(
1354 "punky", mock_clock->Now(), Action::ACTION_API_CALL, "brewster");
1355 action->set_page_url(GURL("http://www.google.co.uk"));
1356 policy->ProcessAction(action);
1358 // Manipulate the database to clear the URLs, so that we end up with
1359 // duplicate rows.
1360 std::vector<GURL> no_url_restrictions;
1361 policy->RemoveURLs(no_url_restrictions);
1363 // Record one more action, with no URL. This should increment the count on
1364 // one, and exactly one, of the existing rows.
1365 action = new Action(
1366 "punky", mock_clock->Now(), Action::ACTION_API_CALL, "brewster");
1367 policy->ProcessAction(action);
1369 CheckReadData(
1370 policy,
1371 "punky",
1373 base::Bind(&CountingPolicyTest::CheckDuplicates));
1374 policy->Close();
1377 TEST_F(CountingPolicyTest, RemoveActions) {
1378 ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
1379 policy->Init();
1381 std::vector<int64> action_ids;
1383 CheckRemoveActions(
1384 policy, action_ids, base::Bind(&CountingPolicyTest::NoActionsDeleted));
1386 action_ids.push_back(-1);
1387 action_ids.push_back(-10);
1388 action_ids.push_back(0);
1389 action_ids.push_back(5);
1390 action_ids.push_back(10);
1391 CheckRemoveActions(
1392 policy, action_ids, base::Bind(&CountingPolicyTest::NoActionsDeleted));
1393 action_ids.clear();
1395 for (int i = 0; i < 50; i++) {
1396 action_ids.push_back(i + 3);
1398 CheckRemoveActions(
1399 policy, action_ids, base::Bind(&CountingPolicyTest::NoActionsDeleted));
1400 action_ids.clear();
1402 // CheckRemoveActions pushes two actions to the Activity Log database with IDs
1403 // 1 and 2.
1404 action_ids.push_back(1);
1405 action_ids.push_back(2);
1406 CheckRemoveActions(
1407 policy, action_ids, base::Bind(&CountingPolicyTest::AllActionsDeleted));
1408 action_ids.clear();
1410 action_ids.push_back(1);
1411 CheckRemoveActions(
1412 policy, action_ids, base::Bind(&CountingPolicyTest::Action1Deleted));
1413 action_ids.clear();
1415 action_ids.push_back(2);
1416 CheckRemoveActions(
1417 policy, action_ids, base::Bind(&CountingPolicyTest::Action2Deleted));
1418 action_ids.clear();
1420 policy->Close();
1423 } // namespace extensions