Rename GetIconID to GetIconId
[chromium-blink-merge.git] / chrome / browser / extensions / activity_log / counting_policy_unittest.cc
blob45ac54161a363347a602eb59b2cb9b1b7b8e57f1
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/location.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/run_loop.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/strings/string_split.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/synchronization/waitable_event.h"
14 #include "base/test/simple_test_clock.h"
15 #include "base/test/test_timeouts.h"
16 #include "base/thread_task_runner_handle.h"
17 #include "chrome/browser/extensions/activity_log/activity_log.h"
18 #include "chrome/browser/extensions/activity_log/counting_policy.h"
19 #include "chrome/browser/extensions/extension_service.h"
20 #include "chrome/browser/extensions/test_extension_system.h"
21 #include "chrome/common/chrome_constants.h"
22 #include "chrome/common/chrome_switches.h"
23 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
24 #include "chrome/test/base/testing_profile.h"
25 #include "content/public/test/test_browser_thread_bundle.h"
26 #include "extensions/common/extension_builder.h"
27 #include "sql/statement.h"
28 #include "testing/gtest/include/gtest/gtest.h"
30 #if defined(OS_CHROMEOS)
31 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
32 #include "chrome/browser/chromeos/settings/cros_settings.h"
33 #include "chrome/browser/chromeos/settings/device_settings_service.h"
34 #endif
36 using content::BrowserThread;
38 namespace extensions {
40 class CountingPolicyTest : public testing::Test {
41 public:
42 CountingPolicyTest()
43 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
44 saved_cmdline_(base::CommandLine::NO_PROGRAM) {
45 #if defined OS_CHROMEOS
46 test_user_manager_.reset(new chromeos::ScopedTestUserManager());
47 #endif
48 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
49 saved_cmdline_ = *base::CommandLine::ForCurrentProcess();
50 profile_.reset(new TestingProfile());
51 base::CommandLine::ForCurrentProcess()->AppendSwitch(
52 switches::kEnableExtensionActivityLogging);
53 extension_service_ = static_cast<TestExtensionSystem*>(
54 ExtensionSystem::Get(profile_.get()))->CreateExtensionService
55 (&command_line, base::FilePath(), false);
58 ~CountingPolicyTest() override {
59 #if defined OS_CHROMEOS
60 test_user_manager_.reset();
61 #endif
62 base::RunLoop().RunUntilIdle();
63 profile_.reset(NULL);
64 base::RunLoop().RunUntilIdle();
65 // Restore the original command line and undo the affects of SetUp().
66 *base::CommandLine::ForCurrentProcess() = saved_cmdline_;
69 // Wait for the task queue for the specified thread to empty.
70 void WaitOnThread(const BrowserThread::ID& thread) {
71 BrowserThread::PostTaskAndReply(
72 thread,
73 FROM_HERE,
74 base::Bind(&base::DoNothing),
75 base::MessageLoop::current()->QuitClosure());
76 base::MessageLoop::current()->Run();
79 // A wrapper function for CheckReadFilteredData, so that we don't need to
80 // enter empty string values for parameters we don't care about.
81 void CheckReadData(
82 ActivityLogDatabasePolicy* policy,
83 const std::string& extension_id,
84 int day,
85 const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker) {
86 CheckReadFilteredData(
87 policy, extension_id, Action::ACTION_ANY, "", "", "", day, checker);
90 // A helper function to call ReadFilteredData on a policy object and wait for
91 // the results to be processed.
92 void CheckReadFilteredData(
93 ActivityLogDatabasePolicy* policy,
94 const std::string& extension_id,
95 const Action::ActionType type,
96 const std::string& api_name,
97 const std::string& page_url,
98 const std::string& arg_url,
99 int day,
100 const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker) {
101 // Submit a request to the policy to read back some data, and call the
102 // checker function when results are available. This will happen on the
103 // database thread.
104 policy->ReadFilteredData(
105 extension_id,
106 type,
107 api_name,
108 page_url,
109 arg_url,
110 day,
111 base::Bind(&CountingPolicyTest::CheckWrapper,
112 checker,
113 base::MessageLoop::current()->QuitClosure()));
115 // Set up a timeout for receiving results; if we haven't received anything
116 // when the timeout triggers then assume that the test is broken.
117 base::CancelableClosure timeout(
118 base::Bind(&CountingPolicyTest::TimeoutCallback));
119 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
120 FROM_HERE, timeout.callback(), TestTimeouts::action_timeout());
122 // Wait for results; either the checker or the timeout callbacks should
123 // cause the main loop to exit.
124 base::MessageLoop::current()->Run();
126 timeout.Cancel();
129 // A helper function which verifies that the string_ids and url_ids tables in
130 // the database have the specified sizes.
131 static void CheckStringTableSizes(CountingPolicy* policy,
132 int string_size,
133 int url_size) {
134 sql::Connection* db = policy->GetDatabaseConnection();
135 sql::Statement statement1(db->GetCachedStatement(
136 sql::StatementID(SQL_FROM_HERE), "SELECT COUNT(*) FROM string_ids"));
137 ASSERT_TRUE(statement1.Step());
138 ASSERT_EQ(string_size, statement1.ColumnInt(0));
140 sql::Statement statement2(db->GetCachedStatement(
141 sql::StatementID(SQL_FROM_HERE), "SELECT COUNT(*) FROM url_ids"));
142 ASSERT_TRUE(statement2.Step());
143 ASSERT_EQ(url_size, statement2.ColumnInt(0));
146 // Checks that the number of queued actions to be written out does not exceed
147 // kSizeThresholdForFlush. Runs on the database thread.
148 static void CheckQueueSize(CountingPolicy* policy) {
149 // This should be updated if kSizeThresholdForFlush in activity_database.cc
150 // changes.
151 ASSERT_LE(policy->queued_actions_.size(), 200U);
154 static void CheckWrapper(
155 const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker,
156 const base::Closure& done,
157 scoped_ptr<Action::ActionVector> results) {
158 checker.Run(results.Pass());
159 done.Run();
162 static void TimeoutCallback() {
163 base::MessageLoop::current()->QuitWhenIdle();
164 FAIL() << "Policy test timed out waiting for results";
167 static void RetrieveActions_FetchFilteredActions0(
168 scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
169 ASSERT_EQ(0, static_cast<int>(i->size()));
172 static void RetrieveActions_FetchFilteredActions1(
173 scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
174 ASSERT_EQ(1, static_cast<int>(i->size()));
177 static void RetrieveActions_FetchFilteredActions2(
178 scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
179 ASSERT_EQ(2, static_cast<int>(i->size()));
182 static void RetrieveActions_FetchFilteredActions300(
183 scoped_ptr<std::vector<scoped_refptr<Action> > > i) {
184 ASSERT_EQ(300, static_cast<int>(i->size()));
187 static void Arguments_Stripped(scoped_ptr<Action::ActionVector> i) {
188 scoped_refptr<Action> last = i->front();
189 CheckAction(*last.get(),
190 "odlameecjipmbmbejkplpemijjgpljce",
191 Action::ACTION_API_CALL,
192 "extension.connect",
193 "[\"hello\",\"world\"]",
200 static void Arguments_GetSinglesAction(
201 scoped_ptr<Action::ActionVector> actions) {
202 ASSERT_EQ(1, static_cast<int>(actions->size()));
203 CheckAction(*actions->at(0).get(),
204 "punky",
205 Action::ACTION_DOM_ACCESS,
206 "lets",
208 "http://www.google.com/",
214 static void Arguments_GetTodaysActions(
215 scoped_ptr<Action::ActionVector> actions) {
216 ASSERT_EQ(3, static_cast<int>(actions->size()));
217 CheckAction(*actions->at(0).get(),
218 "punky",
219 Action::ACTION_API_CALL,
220 "brewster",
226 CheckAction(*actions->at(1).get(),
227 "punky",
228 Action::ACTION_DOM_ACCESS,
229 "lets",
231 "http://www.google.com/",
235 CheckAction(*actions->at(2).get(),
236 "punky",
237 Action::ACTION_API_CALL,
238 "extension.sendMessage",
239 "[\"not\",\"stripped\"]",
246 static void Arguments_GetOlderActions(
247 scoped_ptr<Action::ActionVector> actions) {
248 ASSERT_EQ(2, static_cast<int>(actions->size()));
249 CheckAction(*actions->at(0).get(),
250 "punky",
251 Action::ACTION_DOM_ACCESS,
252 "lets",
254 "http://www.google.com/",
258 CheckAction(*actions->at(1).get(),
259 "punky",
260 Action::ACTION_API_CALL,
261 "brewster",
269 static void Arguments_CheckMergeCount(
270 int count,
271 scoped_ptr<Action::ActionVector> actions) {
272 if (count > 0) {
273 ASSERT_EQ(1u, actions->size());
274 CheckAction(*actions->at(0).get(),
275 "punky",
276 Action::ACTION_API_CALL,
277 "brewster",
282 count);
283 } else {
284 ASSERT_EQ(0u, actions->size());
288 static void Arguments_CheckMergeCountAndTime(
289 int count,
290 const base::Time& time,
291 scoped_ptr<Action::ActionVector> actions) {
292 if (count > 0) {
293 ASSERT_EQ(1u, actions->size());
294 CheckAction(*actions->at(0).get(),
295 "punky",
296 Action::ACTION_API_CALL,
297 "brewster",
302 count);
303 ASSERT_EQ(time, actions->at(0)->time());
304 } else {
305 ASSERT_EQ(0u, actions->size());
309 static void AllURLsRemoved(scoped_ptr<Action::ActionVector> actions) {
310 ASSERT_EQ(2, static_cast<int>(actions->size()));
311 CheckAction(*actions->at(0).get(),
312 "punky",
313 Action::ACTION_DOM_ACCESS,
314 "lets",
320 CheckAction(*actions->at(1).get(),
321 "punky",
322 Action::ACTION_DOM_ACCESS,
323 "lets",
331 static void SomeURLsRemoved(scoped_ptr<Action::ActionVector> actions) {
332 // These will be in the vector in reverse time order.
333 ASSERT_EQ(5, static_cast<int>(actions->size()));
334 CheckAction(*actions->at(0).get(),
335 "punky",
336 Action::ACTION_DOM_ACCESS,
337 "lets",
339 "http://www.google.com/",
340 "Google",
341 "http://www.args-url.com/",
343 CheckAction(*actions->at(1).get(),
344 "punky",
345 Action::ACTION_DOM_ACCESS,
346 "lets",
348 "http://www.google.com/",
349 "Google",
352 CheckAction(*actions->at(2).get(),
353 "punky",
354 Action::ACTION_DOM_ACCESS,
355 "lets",
361 CheckAction(*actions->at(3).get(),
362 "punky",
363 Action::ACTION_DOM_ACCESS,
364 "lets",
368 "http://www.google.com/",
370 CheckAction(*actions->at(4).get(),
371 "punky",
372 Action::ACTION_DOM_ACCESS,
373 "lets",
381 static void CheckDuplicates(scoped_ptr<Action::ActionVector> actions) {
382 ASSERT_EQ(2u, actions->size());
383 int total_count = 0;
384 for (size_t i = 0; i < actions->size(); i++) {
385 total_count += actions->at(i)->count();
387 ASSERT_EQ(3, total_count);
390 static void CheckAction(const Action& action,
391 const std::string& expected_id,
392 const Action::ActionType& expected_type,
393 const std::string& expected_api_name,
394 const std::string& expected_args_str,
395 const std::string& expected_page_url,
396 const std::string& expected_page_title,
397 const std::string& expected_arg_url,
398 int expected_count) {
399 ASSERT_EQ(expected_id, action.extension_id());
400 ASSERT_EQ(expected_type, action.action_type());
401 ASSERT_EQ(expected_api_name, action.api_name());
402 ASSERT_EQ(expected_args_str,
403 ActivityLogPolicy::Util::Serialize(action.args()));
404 ASSERT_EQ(expected_page_url, action.SerializePageUrl());
405 ASSERT_EQ(expected_page_title, action.page_title());
406 ASSERT_EQ(expected_arg_url, action.SerializeArgUrl());
407 ASSERT_EQ(expected_count, action.count());
408 ASSERT_NE(-1, action.action_id());
411 // A helper function initializes the policy with a number of actions, calls
412 // RemoveActions on a policy object and then checks the result of the
413 // deletion.
414 void CheckRemoveActions(
415 ActivityLogDatabasePolicy* policy,
416 const std::vector<int64>& action_ids,
417 const base::Callback<void(scoped_ptr<Action::ActionVector>)>& checker) {
419 // Use a mock clock to ensure that events are not recorded on the wrong day
420 // when the test is run close to local midnight.
421 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
422 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
423 base::TimeDelta::FromHours(12));
424 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
426 // Record some actions
427 scoped_refptr<Action> action =
428 new Action("punky1",
429 mock_clock->Now() - base::TimeDelta::FromMinutes(40),
430 Action::ACTION_DOM_ACCESS,
431 "lets1");
432 action->mutable_args()->AppendString("vamoose1");
433 action->set_page_url(GURL("http://www.google1.com"));
434 action->set_page_title("Google1");
435 action->set_arg_url(GURL("http://www.args-url1.com"));
436 policy->ProcessAction(action);
437 // Record the same action twice, so there are multiple entries in the
438 // database.
439 policy->ProcessAction(action);
441 action = new Action("punky2",
442 mock_clock->Now() - base::TimeDelta::FromMinutes(30),
443 Action::ACTION_API_CALL,
444 "lets2");
445 action->mutable_args()->AppendString("vamoose2");
446 action->set_page_url(GURL("http://www.google2.com"));
447 action->set_page_title("Google2");
448 action->set_arg_url(GURL("http://www.args-url2.com"));
449 policy->ProcessAction(action);
450 // Record the same action twice, so there are multiple entries in the
451 // database.
452 policy->ProcessAction(action);
454 // Submit a request to delete actions.
455 policy->RemoveActions(action_ids);
457 // Check the result of the deletion. The checker function gets all
458 // activities in the database.
459 CheckReadData(policy, "", -1, checker);
461 // Clean database.
462 policy->DeleteDatabase();
465 static void AllActionsDeleted(scoped_ptr<Action::ActionVector> actions) {
466 ASSERT_EQ(0, static_cast<int>(actions->size()));
469 static void NoActionsDeleted(scoped_ptr<Action::ActionVector> actions) {
470 // These will be in the vector in reverse time order.
471 ASSERT_EQ(2, static_cast<int>(actions->size()));
472 CheckAction(*actions->at(0).get(),
473 "punky2",
474 Action::ACTION_API_CALL,
475 "lets2",
477 "http://www.google2.com/",
478 "Google2",
479 "http://www.args-url2.com/",
481 ASSERT_EQ(2, actions->at(0)->action_id());
482 CheckAction(*actions->at(1).get(),
483 "punky1",
484 Action::ACTION_DOM_ACCESS,
485 "lets1",
487 "http://www.google1.com/",
488 "Google1",
489 "http://www.args-url1.com/",
491 ASSERT_EQ(1, actions->at(1)->action_id());
494 static void Action1Deleted(scoped_ptr<Action::ActionVector> actions) {
495 // These will be in the vector in reverse time order.
496 ASSERT_EQ(1, static_cast<int>(actions->size()));
497 CheckAction(*actions->at(0).get(),
498 "punky2",
499 Action::ACTION_API_CALL,
500 "lets2",
502 "http://www.google2.com/",
503 "Google2",
504 "http://www.args-url2.com/",
506 ASSERT_EQ(2, actions->at(0)->action_id());
509 static void Action2Deleted(scoped_ptr<Action::ActionVector> actions) {
510 // These will be in the vector in reverse time order.
511 ASSERT_EQ(1, static_cast<int>(actions->size()));
512 CheckAction(*actions->at(0).get(),
513 "punky1",
514 Action::ACTION_DOM_ACCESS,
515 "lets1",
517 "http://www.google1.com/",
518 "Google1",
519 "http://www.args-url1.com/",
521 ASSERT_EQ(1, actions->at(0)->action_id());
524 protected:
525 ExtensionService* extension_service_;
526 scoped_ptr<TestingProfile> profile_;
527 content::TestBrowserThreadBundle thread_bundle_;
528 // Used to preserve a copy of the original command line.
529 // The test framework will do this itself as well. However, by then,
530 // it is too late to call ActivityLog::RecomputeLoggingIsEnabled() in
531 // TearDown().
532 base::CommandLine saved_cmdline_;
534 #if defined OS_CHROMEOS
535 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
536 chromeos::ScopedTestCrosSettings test_cros_settings_;
537 scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_;
538 #endif
541 TEST_F(CountingPolicyTest, Construct) {
542 ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
543 policy->Init();
544 scoped_refptr<const Extension> extension =
545 ExtensionBuilder()
546 .SetManifest(DictionaryBuilder()
547 .Set("name", "Test extension")
548 .Set("version", "1.0.0")
549 .Set("manifest_version", 2))
550 .Build();
551 extension_service_->AddExtension(extension.get());
552 scoped_ptr<base::ListValue> args(new base::ListValue());
553 scoped_refptr<Action> action = new Action(extension->id(),
554 base::Time::Now(),
555 Action::ACTION_API_CALL,
556 "tabs.testMethod");
557 action->set_args(args.Pass());
558 policy->ProcessAction(action);
559 policy->Close();
562 TEST_F(CountingPolicyTest, LogWithStrippedArguments) {
563 ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
564 policy->Init();
565 scoped_refptr<const Extension> extension =
566 ExtensionBuilder()
567 .SetManifest(DictionaryBuilder()
568 .Set("name", "Test extension")
569 .Set("version", "1.0.0")
570 .Set("manifest_version", 2))
571 .Build();
572 extension_service_->AddExtension(extension.get());
574 scoped_ptr<base::ListValue> args(new base::ListValue());
575 args->Set(0, new base::StringValue("hello"));
576 args->Set(1, new base::StringValue("world"));
577 scoped_refptr<Action> action = new Action(extension->id(),
578 base::Time::Now(),
579 Action::ACTION_API_CALL,
580 "extension.connect");
581 action->set_args(args.Pass());
583 policy->ProcessAction(action);
584 CheckReadData(policy,
585 extension->id(),
587 base::Bind(&CountingPolicyTest::Arguments_Stripped));
588 policy->Close();
591 TEST_F(CountingPolicyTest, GetTodaysActions) {
592 CountingPolicy* policy = new CountingPolicy(profile_.get());
593 policy->Init();
594 // Disable row expiration for this test by setting a time before any actions
595 // we generate.
596 policy->set_retention_time(base::TimeDelta::FromDays(14));
598 // Use a mock clock to ensure that events are not recorded on the wrong day
599 // when the test is run close to local midnight. Note: Ownership is passed
600 // to the policy, but we still keep a pointer locally. The policy will take
601 // care of destruction; this is safe since the policy outlives all our
602 // accesses to the mock clock.
603 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
604 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
605 base::TimeDelta::FromHours(12));
606 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
608 // Record some actions
609 scoped_refptr<Action> action =
610 new Action("punky",
611 mock_clock->Now() - base::TimeDelta::FromMinutes(40),
612 Action::ACTION_API_CALL,
613 "brewster");
614 action->mutable_args()->AppendString("woof");
615 policy->ProcessAction(action);
617 action = new Action("punky",
618 mock_clock->Now() - base::TimeDelta::FromMinutes(30),
619 Action::ACTION_API_CALL,
620 "brewster");
621 action->mutable_args()->AppendString("meow");
622 policy->ProcessAction(action);
624 action = new Action("punky",
625 mock_clock->Now() - base::TimeDelta::FromMinutes(20),
626 Action::ACTION_API_CALL,
627 "extension.sendMessage");
628 action->mutable_args()->AppendString("not");
629 action->mutable_args()->AppendString("stripped");
630 policy->ProcessAction(action);
632 action =
633 new Action("punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
634 action->mutable_args()->AppendString("vamoose");
635 action->set_page_url(GURL("http://www.google.com"));
636 policy->ProcessAction(action);
638 action = new Action(
639 "scoobydoo", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
640 action->mutable_args()->AppendString("vamoose");
641 action->set_page_url(GURL("http://www.google.com"));
642 policy->ProcessAction(action);
644 CheckReadData(
645 policy,
646 "punky",
648 base::Bind(&CountingPolicyTest::Arguments_GetTodaysActions));
649 policy->Close();
652 // Check that we can read back less recent actions in the db.
653 TEST_F(CountingPolicyTest, GetOlderActions) {
654 CountingPolicy* policy = new CountingPolicy(profile_.get());
655 policy->Init();
656 policy->set_retention_time(base::TimeDelta::FromDays(14));
658 // Use a mock clock to ensure that events are not recorded on the wrong day
659 // when the test is run close to local midnight.
660 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
661 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
662 base::TimeDelta::FromHours(12));
663 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
665 // Record some actions
666 scoped_refptr<Action> action =
667 new Action("punky",
668 mock_clock->Now() - base::TimeDelta::FromDays(3) -
669 base::TimeDelta::FromMinutes(40),
670 Action::ACTION_API_CALL,
671 "brewster");
672 action->mutable_args()->AppendString("woof");
673 policy->ProcessAction(action);
675 action = new Action("punky",
676 mock_clock->Now() - base::TimeDelta::FromDays(3),
677 Action::ACTION_DOM_ACCESS,
678 "lets");
679 action->mutable_args()->AppendString("vamoose");
680 action->set_page_url(GURL("http://www.google.com"));
681 policy->ProcessAction(action);
683 action = new Action("punky",
684 mock_clock->Now(),
685 Action::ACTION_DOM_ACCESS,
686 "lets");
687 action->mutable_args()->AppendString("too new");
688 action->set_page_url(GURL("http://www.google.com"));
689 policy->ProcessAction(action);
691 action = new Action("punky",
692 mock_clock->Now() - base::TimeDelta::FromDays(7),
693 Action::ACTION_DOM_ACCESS,
694 "lets");
695 action->mutable_args()->AppendString("too old");
696 action->set_page_url(GURL("http://www.google.com"));
697 policy->ProcessAction(action);
699 CheckReadData(
700 policy,
701 "punky",
703 base::Bind(&CountingPolicyTest::Arguments_GetOlderActions));
705 policy->Close();
708 TEST_F(CountingPolicyTest, LogAndFetchFilteredActions) {
709 ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
710 policy->Init();
711 scoped_refptr<const Extension> extension =
712 ExtensionBuilder()
713 .SetManifest(DictionaryBuilder()
714 .Set("name", "Test extension")
715 .Set("version", "1.0.0")
716 .Set("manifest_version", 2))
717 .Build();
718 extension_service_->AddExtension(extension.get());
719 GURL gurl("http://www.google.com");
721 // Write some API calls
722 scoped_refptr<Action> action_api = new Action(extension->id(),
723 base::Time::Now(),
724 Action::ACTION_API_CALL,
725 "tabs.testMethod");
726 action_api->set_args(make_scoped_ptr(new base::ListValue()));
727 policy->ProcessAction(action_api);
729 scoped_refptr<Action> action_dom = new Action(extension->id(),
730 base::Time::Now(),
731 Action::ACTION_DOM_ACCESS,
732 "document.write");
733 action_dom->set_args(make_scoped_ptr(new base::ListValue()));
734 action_dom->set_page_url(gurl);
735 policy->ProcessAction(action_dom);
737 CheckReadFilteredData(
738 policy,
739 extension->id(),
740 Action::ACTION_API_CALL,
741 "tabs.testMethod",
745 base::Bind(
746 &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
748 CheckReadFilteredData(
749 policy,
751 Action::ACTION_DOM_ACCESS,
756 base::Bind(
757 &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
759 CheckReadFilteredData(
760 policy,
762 Action::ACTION_DOM_ACCESS,
764 "http://www.google.com/",
767 base::Bind(
768 &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
770 CheckReadFilteredData(
771 policy,
773 Action::ACTION_DOM_ACCESS,
775 "http://www.google.com",
778 base::Bind(
779 &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
781 CheckReadFilteredData(
782 policy,
784 Action::ACTION_DOM_ACCESS,
786 "http://www.goo",
789 base::Bind(
790 &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
792 CheckReadFilteredData(
793 policy,
794 extension->id(),
795 Action::ACTION_ANY,
800 base::Bind(
801 &CountingPolicyTest::RetrieveActions_FetchFilteredActions2));
803 policy->Close();
806 // Check that merging of actions only occurs within the same day, not across
807 // days, and that old data can be expired from the database.
808 TEST_F(CountingPolicyTest, MergingAndExpiring) {
809 CountingPolicy* policy = new CountingPolicy(profile_.get());
810 policy->Init();
811 // Initially disable expiration by setting a retention time before any
812 // actions we generate.
813 policy->set_retention_time(base::TimeDelta::FromDays(14));
815 // Use a mock clock to ensure that events are not recorded on the wrong day
816 // when the test is run close to local midnight.
817 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
818 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
819 base::TimeDelta::FromHours(12));
820 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
822 // The first two actions should be merged; the last one is on a separate day
823 // and should not be.
824 scoped_refptr<Action> action =
825 new Action("punky",
826 mock_clock->Now() - base::TimeDelta::FromDays(3) -
827 base::TimeDelta::FromMinutes(40),
828 Action::ACTION_API_CALL,
829 "brewster");
830 policy->ProcessAction(action);
832 action = new Action("punky",
833 mock_clock->Now() - base::TimeDelta::FromDays(3) -
834 base::TimeDelta::FromMinutes(20),
835 Action::ACTION_API_CALL,
836 "brewster");
837 policy->ProcessAction(action);
839 action = new Action("punky",
840 mock_clock->Now() - base::TimeDelta::FromDays(2) -
841 base::TimeDelta::FromMinutes(20),
842 Action::ACTION_API_CALL,
843 "brewster");
844 policy->ProcessAction(action);
846 CheckReadData(policy,
847 "punky",
849 base::Bind(&CountingPolicyTest::Arguments_CheckMergeCount, 2));
850 CheckReadData(policy,
851 "punky",
853 base::Bind(&CountingPolicyTest::Arguments_CheckMergeCount, 1));
855 // Clean actions before midnight two days ago. Force expiration to run by
856 // clearing last_database_cleaning_time_ and submitting a new action.
857 policy->set_retention_time(base::TimeDelta::FromDays(2));
858 policy->last_database_cleaning_time_ = base::Time();
859 action = new Action("punky",
860 mock_clock->Now(),
861 Action::ACTION_API_CALL,
862 "brewster");
863 policy->ProcessAction(action);
865 CheckReadData(policy,
866 "punky",
868 base::Bind(&CountingPolicyTest::Arguments_CheckMergeCount, 0));
869 CheckReadData(policy,
870 "punky",
872 base::Bind(&CountingPolicyTest::Arguments_CheckMergeCount, 1));
874 policy->Close();
877 // Test cleaning of old data in the string and URL tables.
878 TEST_F(CountingPolicyTest, StringTableCleaning) {
879 CountingPolicy* policy = new CountingPolicy(profile_.get());
880 policy->Init();
881 // Initially disable expiration by setting a retention time before any
882 // actions we generate.
883 policy->set_retention_time(base::TimeDelta::FromDays(14));
885 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
886 mock_clock->SetNow(base::Time::Now());
887 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
889 // Insert an action; this should create entries in both the string table (for
890 // the extension and API name) and the URL table (for page_url).
891 scoped_refptr<Action> action =
892 new Action("punky",
893 mock_clock->Now() - base::TimeDelta::FromDays(7),
894 Action::ACTION_API_CALL,
895 "brewster");
896 action->set_page_url(GURL("http://www.google.com/"));
897 policy->ProcessAction(action);
899 // Add an action which will not be expired, so that some strings will remain
900 // in use.
901 action = new Action(
902 "punky", mock_clock->Now(), Action::ACTION_API_CALL, "tabs.create");
903 policy->ProcessAction(action);
905 // There should now be three strings ("punky", "brewster", "tabs.create") and
906 // one URL in the tables.
907 policy->Flush();
908 policy->ScheduleAndForget(policy,
909 &CountingPolicyTest::CheckStringTableSizes,
912 WaitOnThread(BrowserThread::DB);
914 // Trigger a cleaning. The oldest action is expired when we submit a
915 // duplicate of the newer action. After this, there should be two strings
916 // and no URLs.
917 policy->set_retention_time(base::TimeDelta::FromDays(2));
918 policy->last_database_cleaning_time_ = base::Time();
919 policy->ProcessAction(action);
920 policy->Flush();
921 policy->ScheduleAndForget(policy,
922 &CountingPolicyTest::CheckStringTableSizes,
925 WaitOnThread(BrowserThread::DB);
927 policy->Close();
930 // A stress test for memory- and database-based merging of actions. Submit
931 // multiple items, not in chronological order, spanning a few days. Check that
932 // items are merged properly and final timestamps are correct.
933 TEST_F(CountingPolicyTest, MoreMerging) {
934 CountingPolicy* policy = new CountingPolicy(profile_.get());
935 policy->Init();
936 policy->set_retention_time(base::TimeDelta::FromDays(14));
938 // Use a mock clock to ensure that events are not recorded on the wrong day
939 // when the test is run close to local midnight.
940 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
941 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
942 base::TimeDelta::FromHours(12));
943 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
945 // Create an action 2 days ago, then 1 day ago, then 2 days ago. Make sure
946 // that we end up with two merged records (one for each day), and each has
947 // the appropriate timestamp. These merges should happen in the database
948 // since the date keeps changing.
949 base::Time time1 =
950 mock_clock->Now() - base::TimeDelta::FromDays(2) -
951 base::TimeDelta::FromMinutes(40);
952 base::Time time2 =
953 mock_clock->Now() - base::TimeDelta::FromDays(1) -
954 base::TimeDelta::FromMinutes(40);
955 base::Time time3 =
956 mock_clock->Now() - base::TimeDelta::FromDays(2) -
957 base::TimeDelta::FromMinutes(20);
959 scoped_refptr<Action> action =
960 new Action("punky", time1, Action::ACTION_API_CALL, "brewster");
961 policy->ProcessAction(action);
963 action = new Action("punky", time2, Action::ACTION_API_CALL, "brewster");
964 policy->ProcessAction(action);
966 action = new Action("punky", time3, Action::ACTION_API_CALL, "brewster");
967 policy->ProcessAction(action);
969 CheckReadData(
970 policy,
971 "punky",
973 base::Bind(
974 &CountingPolicyTest::Arguments_CheckMergeCountAndTime, 2, time3));
975 CheckReadData(
976 policy,
977 "punky",
979 base::Bind(
980 &CountingPolicyTest::Arguments_CheckMergeCountAndTime, 1, time2));
982 // Create three actions today, where the merges should happen in memory.
983 // Again these are not chronological; timestamp time5 should win out since it
984 // is the latest.
985 base::Time time4 = mock_clock->Now() - base::TimeDelta::FromMinutes(60);
986 base::Time time5 = mock_clock->Now() - base::TimeDelta::FromMinutes(20);
987 base::Time time6 = mock_clock->Now() - base::TimeDelta::FromMinutes(40);
989 action = new Action("punky", time4, Action::ACTION_API_CALL, "brewster");
990 policy->ProcessAction(action);
992 action = new Action("punky", time5, Action::ACTION_API_CALL, "brewster");
993 policy->ProcessAction(action);
995 action = new Action("punky", time6, Action::ACTION_API_CALL, "brewster");
996 policy->ProcessAction(action);
998 CheckReadData(
999 policy,
1000 "punky",
1002 base::Bind(
1003 &CountingPolicyTest::Arguments_CheckMergeCountAndTime, 3, time5));
1004 policy->Close();
1007 // Check that actions are flushed to disk before letting too many accumulate in
1008 // memory.
1009 TEST_F(CountingPolicyTest, EarlyFlush) {
1010 CountingPolicy* policy = new CountingPolicy(profile_.get());
1011 policy->Init();
1013 for (int i = 0; i < 500; i++) {
1014 scoped_refptr<Action> action =
1015 new Action("punky",
1016 base::Time::Now(),
1017 Action::ACTION_API_CALL,
1018 base::StringPrintf("apicall_%d", i));
1019 policy->ProcessAction(action);
1022 policy->ScheduleAndForget(policy, &CountingPolicyTest::CheckQueueSize);
1023 WaitOnThread(BrowserThread::DB);
1025 policy->Close();
1028 TEST_F(CountingPolicyTest, CapReturns) {
1029 CountingPolicy* policy = new CountingPolicy(profile_.get());
1030 policy->Init();
1032 for (int i = 0; i < 305; i++) {
1033 scoped_refptr<Action> action =
1034 new Action("punky",
1035 base::Time::Now(),
1036 Action::ACTION_API_CALL,
1037 base::StringPrintf("apicall_%d", i));
1038 policy->ProcessAction(action);
1041 policy->Flush();
1042 WaitOnThread(BrowserThread::DB);
1044 CheckReadFilteredData(
1045 policy,
1046 "punky",
1047 Action::ACTION_ANY,
1052 base::Bind(
1053 &CountingPolicyTest::RetrieveActions_FetchFilteredActions300));
1054 policy->Close();
1057 TEST_F(CountingPolicyTest, RemoveAllURLs) {
1058 ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
1059 policy->Init();
1061 // Use a mock clock to ensure that events are not recorded on the wrong day
1062 // when the test is run close to local midnight.
1063 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
1064 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
1065 base::TimeDelta::FromHours(12));
1066 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
1068 // Record some actions
1069 scoped_refptr<Action> action =
1070 new Action("punky", mock_clock->Now(),
1071 Action::ACTION_DOM_ACCESS, "lets");
1072 action->mutable_args()->AppendString("vamoose");
1073 action->set_page_url(GURL("http://www.google.com"));
1074 action->set_page_title("Google");
1075 action->set_arg_url(GURL("http://www.args-url.com"));
1076 policy->ProcessAction(action);
1078 mock_clock->Advance(base::TimeDelta::FromSeconds(1));
1079 action = new Action(
1080 "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
1081 action->mutable_args()->AppendString("vamoose");
1082 action->set_page_url(GURL("http://www.google2.com"));
1083 action->set_page_title("Google");
1084 // Deliberately no arg url set to make sure it stills works if there is no arg
1085 // url.
1086 policy->ProcessAction(action);
1088 // Clean all the URLs.
1089 std::vector<GURL> no_url_restrictions;
1090 policy->RemoveURLs(no_url_restrictions);
1092 CheckReadData(
1093 policy,
1094 "punky",
1096 base::Bind(&CountingPolicyTest::AllURLsRemoved));
1097 policy->Close();
1100 TEST_F(CountingPolicyTest, RemoveSpecificURLs) {
1101 ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
1102 policy->Init();
1104 // Use a mock clock to ensure that events are not recorded on the wrong day
1105 // when the test is run close to local midnight.
1106 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
1107 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
1108 base::TimeDelta::FromHours(12));
1109 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
1111 // Record some actions
1112 // This should have the page url and args url cleared.
1113 scoped_refptr<Action> action = new Action("punky", mock_clock->Now(),
1114 Action::ACTION_DOM_ACCESS, "lets");
1115 action->mutable_args()->AppendString("vamoose");
1116 action->set_page_url(GURL("http://www.google1.com"));
1117 action->set_page_title("Google");
1118 action->set_arg_url(GURL("http://www.google1.com"));
1119 policy->ProcessAction(action);
1121 // This should have the page url cleared but not args url.
1122 mock_clock->Advance(base::TimeDelta::FromSeconds(1));
1123 action = new Action(
1124 "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
1125 action->mutable_args()->AppendString("vamoose");
1126 action->set_page_url(GURL("http://www.google1.com"));
1127 action->set_page_title("Google");
1128 action->set_arg_url(GURL("http://www.google.com"));
1129 policy->ProcessAction(action);
1131 // This should have the page url cleared. The args url is deliberately not
1132 // set to make sure this doesn't cause any issues.
1133 mock_clock->Advance(base::TimeDelta::FromSeconds(1));
1134 action = new Action(
1135 "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
1136 action->mutable_args()->AppendString("vamoose");
1137 action->set_page_url(GURL("http://www.google2.com"));
1138 action->set_page_title("Google");
1139 policy->ProcessAction(action);
1141 // This should have the args url cleared but not the page url or page title.
1142 mock_clock->Advance(base::TimeDelta::FromSeconds(1));
1143 action = new Action(
1144 "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
1145 action->mutable_args()->AppendString("vamoose");
1146 action->set_page_url(GURL("http://www.google.com"));
1147 action->set_page_title("Google");
1148 action->set_arg_url(GURL("http://www.google1.com"));
1149 policy->ProcessAction(action);
1151 // This should have neither cleared.
1152 mock_clock->Advance(base::TimeDelta::FromSeconds(1));
1153 action = new Action(
1154 "punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
1155 action->mutable_args()->AppendString("vamoose");
1156 action->set_page_url(GURL("http://www.google.com"));
1157 action->set_page_title("Google");
1158 action->set_arg_url(GURL("http://www.args-url.com"));
1159 action->set_count(5);
1160 policy->ProcessAction(action);
1162 // Clean some URLs.
1163 std::vector<GURL> urls;
1164 urls.push_back(GURL("http://www.google1.com"));
1165 urls.push_back(GURL("http://www.google2.com"));
1166 urls.push_back(GURL("http://www.url_not_in_db.com"));
1167 policy->RemoveURLs(urls);
1169 CheckReadData(
1170 policy,
1171 "punky",
1173 base::Bind(&CountingPolicyTest::SomeURLsRemoved));
1174 policy->Close();
1177 TEST_F(CountingPolicyTest, RemoveExtensionData) {
1178 CountingPolicy* policy = new CountingPolicy(profile_.get());
1179 policy->Init();
1181 // Use a mock clock to ensure that events are not recorded on the wrong day
1182 // when the test is run close to local midnight.
1183 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
1184 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
1185 base::TimeDelta::FromHours(12));
1186 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
1188 // Record some actions
1189 scoped_refptr<Action> action = new Action("deleteextensiondata",
1190 mock_clock->Now(),
1191 Action::ACTION_DOM_ACCESS,
1192 "lets");
1193 action->mutable_args()->AppendString("vamoose");
1194 action->set_page_title("Google");
1195 action->set_arg_url(GURL("http://www.google.com"));
1196 policy->ProcessAction(action);
1197 policy->ProcessAction(action);
1198 policy->ProcessAction(action);
1200 scoped_refptr<Action> action2 = new Action("dontdelete",
1201 mock_clock->Now(),
1202 Action::ACTION_DOM_ACCESS,
1203 "lets");
1204 action->mutable_args()->AppendString("vamoose");
1205 action->set_page_title("Google");
1206 action->set_arg_url(GURL("http://www.google.com"));
1207 policy->ProcessAction(action2);
1209 policy->Flush();
1210 policy->RemoveExtensionData("deleteextensiondata");
1212 CheckReadFilteredData(
1213 policy,
1214 "deleteextensiondata",
1215 Action::ACTION_ANY,
1220 base::Bind(
1221 &CountingPolicyTest::RetrieveActions_FetchFilteredActions0));
1223 CheckReadFilteredData(
1224 policy,
1225 "dontdelete",
1226 Action::ACTION_ANY,
1231 base::Bind(
1232 &CountingPolicyTest::RetrieveActions_FetchFilteredActions1));
1233 policy->Close();
1236 TEST_F(CountingPolicyTest, DeleteDatabase) {
1237 CountingPolicy* policy = new CountingPolicy(profile_.get());
1238 policy->Init();
1239 // Disable row expiration for this test by setting a time before any actions
1240 // we generate.
1241 policy->set_retention_time(base::TimeDelta::FromDays(14));
1243 // Use a mock clock to ensure that events are not recorded on the wrong day
1244 // when the test is run close to local midnight. Note: Ownership is passed
1245 // to the policy, but we still keep a pointer locally. The policy will take
1246 // care of destruction; this is safe since the policy outlives all our
1247 // accesses to the mock clock.
1248 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
1249 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
1250 base::TimeDelta::FromHours(12));
1251 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
1253 // Record some actions
1254 scoped_refptr<Action> action =
1255 new Action("punky",
1256 mock_clock->Now() - base::TimeDelta::FromMinutes(40),
1257 Action::ACTION_API_CALL,
1258 "brewster");
1259 action->mutable_args()->AppendString("woof");
1260 policy->ProcessAction(action);
1262 action = new Action("punky",
1263 mock_clock->Now() - base::TimeDelta::FromMinutes(30),
1264 Action::ACTION_API_CALL,
1265 "brewster");
1266 action->mutable_args()->AppendString("meow");
1267 policy->ProcessAction(action);
1269 action = new Action("punky",
1270 mock_clock->Now() - base::TimeDelta::FromMinutes(20),
1271 Action::ACTION_API_CALL,
1272 "extension.sendMessage");
1273 action->mutable_args()->AppendString("not");
1274 action->mutable_args()->AppendString("stripped");
1275 policy->ProcessAction(action);
1277 action =
1278 new Action("punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
1279 action->mutable_args()->AppendString("vamoose");
1280 action->set_page_url(GURL("http://www.google.com"));
1281 policy->ProcessAction(action);
1283 action = new Action(
1284 "scoobydoo", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
1285 action->mutable_args()->AppendString("vamoose");
1286 action->set_page_url(GURL("http://www.google.com"));
1287 policy->ProcessAction(action);
1289 CheckReadData(
1290 policy,
1291 "punky",
1293 base::Bind(&CountingPolicyTest::Arguments_GetTodaysActions));
1295 policy->DeleteDatabase();
1297 CheckReadFilteredData(
1298 policy,
1300 Action::ACTION_ANY,
1305 base::Bind(
1306 &CountingPolicyTest::RetrieveActions_FetchFilteredActions0));
1308 // The following code tests that the caches of url and string tables were
1309 // cleared by the deletion above.
1310 // https://code.google.com/p/chromium/issues/detail?id=341674.
1311 action =
1312 new Action("punky", mock_clock->Now(), Action::ACTION_DOM_ACCESS, "lets");
1313 action->mutable_args()->AppendString("vamoose");
1314 action->set_page_url(GURL("http://www.google.com"));
1315 policy->ProcessAction(action);
1317 CheckReadData(
1318 policy,
1321 base::Bind(&CountingPolicyTest::Arguments_GetSinglesAction));
1323 policy->DeleteDatabase();
1325 CheckReadFilteredData(
1326 policy,
1328 Action::ACTION_ANY,
1333 base::Bind(
1334 &CountingPolicyTest::RetrieveActions_FetchFilteredActions0));
1336 policy->Close();
1339 // Tests that duplicate rows in the activity log database are handled properly
1340 // when updating counts.
1341 TEST_F(CountingPolicyTest, DuplicateRows) {
1342 CountingPolicy* policy = new CountingPolicy(profile_.get());
1343 policy->Init();
1344 base::SimpleTestClock* mock_clock = new base::SimpleTestClock();
1345 mock_clock->SetNow(base::Time::Now().LocalMidnight() +
1346 base::TimeDelta::FromHours(12));
1347 policy->SetClockForTesting(scoped_ptr<base::Clock>(mock_clock));
1349 // Record two actions with distinct URLs.
1350 scoped_refptr<Action> action;
1351 action = new Action(
1352 "punky", mock_clock->Now(), Action::ACTION_API_CALL, "brewster");
1353 action->set_page_url(GURL("http://www.google.com"));
1354 policy->ProcessAction(action);
1356 action = new Action(
1357 "punky", mock_clock->Now(), Action::ACTION_API_CALL, "brewster");
1358 action->set_page_url(GURL("http://www.google.co.uk"));
1359 policy->ProcessAction(action);
1361 // Manipulate the database to clear the URLs, so that we end up with
1362 // duplicate rows.
1363 std::vector<GURL> no_url_restrictions;
1364 policy->RemoveURLs(no_url_restrictions);
1366 // Record one more action, with no URL. This should increment the count on
1367 // one, and exactly one, of the existing rows.
1368 action = new Action(
1369 "punky", mock_clock->Now(), Action::ACTION_API_CALL, "brewster");
1370 policy->ProcessAction(action);
1372 CheckReadData(
1373 policy,
1374 "punky",
1376 base::Bind(&CountingPolicyTest::CheckDuplicates));
1377 policy->Close();
1380 TEST_F(CountingPolicyTest, RemoveActions) {
1381 ActivityLogDatabasePolicy* policy = new CountingPolicy(profile_.get());
1382 policy->Init();
1384 std::vector<int64> action_ids;
1386 CheckRemoveActions(
1387 policy, action_ids, base::Bind(&CountingPolicyTest::NoActionsDeleted));
1389 action_ids.push_back(-1);
1390 action_ids.push_back(-10);
1391 action_ids.push_back(0);
1392 action_ids.push_back(5);
1393 action_ids.push_back(10);
1394 CheckRemoveActions(
1395 policy, action_ids, base::Bind(&CountingPolicyTest::NoActionsDeleted));
1396 action_ids.clear();
1398 for (int i = 0; i < 50; i++) {
1399 action_ids.push_back(i + 3);
1401 CheckRemoveActions(
1402 policy, action_ids, base::Bind(&CountingPolicyTest::NoActionsDeleted));
1403 action_ids.clear();
1405 // CheckRemoveActions pushes two actions to the Activity Log database with IDs
1406 // 1 and 2.
1407 action_ids.push_back(1);
1408 action_ids.push_back(2);
1409 CheckRemoveActions(
1410 policy, action_ids, base::Bind(&CountingPolicyTest::AllActionsDeleted));
1411 action_ids.clear();
1413 action_ids.push_back(1);
1414 CheckRemoveActions(
1415 policy, action_ids, base::Bind(&CountingPolicyTest::Action1Deleted));
1416 action_ids.clear();
1418 action_ids.push_back(2);
1419 CheckRemoveActions(
1420 policy, action_ids, base::Bind(&CountingPolicyTest::Action2Deleted));
1421 action_ids.clear();
1423 policy->Close();
1426 } // namespace extensions