1 // Copyright 2014 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. 4 5 #include "chrome/browser/safe_browsing/incident_reporting/delayed_callback_runner.h" 6 7 #include <map> 8 #include <string> 9 10 #include "base/callback.h" 11 #include "base/macros.h" 12 #include "base/test/test_simple_task_runner.h" 13 #include "base/thread_task_runner_handle.h" 14 #include "testing/gtest/include/gtest/gtest.h" 15 16 namespace { 17 18 // A class of objects that invoke a callback upon destruction. This is used as 19 // an owned argument on callbacks given to a DelayedCallbackRunner under test. 20 class CallbackArgument { 21 public: 22 explicit CallbackArgument(const base::Closure& on_delete) 23 : on_delete_(on_delete) {} 24 ~CallbackArgument() { on_delete_.Run(); } 25 26 private: 27 base::Closure on_delete_; 28 29 DISALLOW_COPY_AND_ASSIGN(CallbackArgument); 30 }; 31 32 } // namespace 33 34 // A test fixture that prepares a DelayedCallbackRunner instance for use and 35 // tracks the lifecycle of callbacks sent to it. 36 class DelayedCallbackRunnerTest : public testing::Test { 37 public: 38 // Registers a callback that will record its running and destruction to the 39 // test fixture under the given name. 40 void RegisterTestCallback(const std::string& name) { 41 callbacks_[name] = CallbackState(); 42 instance_->RegisterCallback(MakeCallback(name)); 43 } 44 45 protected: 46 DelayedCallbackRunnerTest() 47 : task_runner_(new base::TestSimpleTaskRunner), 48 thread_task_runner_handle_(task_runner_) {} 49 50 virtual void SetUp() OVERRIDE { 51 instance_.reset(new safe_browsing::DelayedCallbackRunner( 52 base::TimeDelta::FromMilliseconds(1), // ignored by simple runner. 53 task_runner_)); 54 } 55 56 virtual void TearDown() OVERRIDE { instance_.reset(); } 57 58 void OnRun(const std::string& name, CallbackArgument* arg) { 59 EXPECT_FALSE(callbacks_[name].run); 60 callbacks_[name].run = true; 61 } 62 63 void OnDelete(const std::string& name) { 64 EXPECT_FALSE(callbacks_[name].deleted); 65 callbacks_[name].deleted = true; 66 } 67 68 // Returns a callback argument that calls the test fixture's OnDelete method 69 // on behalf of the given callback name. 70 scoped_ptr<CallbackArgument> MakeCallbackArgument(const std::string& name) { 71 return make_scoped_ptr(new CallbackArgument(base::Bind( 72 &DelayedCallbackRunnerTest::OnDelete, base::Unretained(this), name))); 73 } 74 75 // Returns a closure that calls |OnRun| when run and |OnDelete| when deleted 76 // on behalf of the given callback name. 77 base::Closure MakeCallback(const std::string& name) { 78 return base::Bind(&DelayedCallbackRunnerTest::OnRun, 79 base::Unretained(this), 80 name, 81 base::Owned(MakeCallbackArgument(name).release())); 82 } 83 84 bool CallbackWasRun(const std::string& name) { return callbacks_[name].run; } 85 86 bool CallbackWasDeleted(const std::string& name) { 87 return callbacks_[name].deleted; 88 } 89 90 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; 91 base::ThreadTaskRunnerHandle thread_task_runner_handle_; 92 scoped_ptr<safe_browsing::DelayedCallbackRunner> instance_; 93 94 private: 95 struct CallbackState { 96 CallbackState() : run(), deleted() {} 97 bool run; 98 bool deleted; 99 }; 100 101 std::map<std::string, CallbackState> callbacks_; 102 }; 103 104 // Tests that a callback is deleted when not run before the runner is destroyed. 105 TEST_F(DelayedCallbackRunnerTest, NotRunDeleted) { 106 const std::string name("one"); 107 RegisterTestCallback(name); 108 instance_.reset(); 109 EXPECT_FALSE(CallbackWasRun(name)); 110 EXPECT_TRUE(CallbackWasDeleted(name)); 111 } 112 113 // Tests that a callback is run and deleted while the runner is alive. 114 TEST_F(DelayedCallbackRunnerTest, RunDeleted) { 115 const std::string name("one"); 116 RegisterTestCallback(name); 117 instance_->Start(); 118 task_runner_->RunUntilIdle(); 119 EXPECT_TRUE(CallbackWasRun(name)); 120 EXPECT_TRUE(CallbackWasDeleted(name)); 121 } 122 123 // Tests that a callback registered after Start() is called is also run and 124 // deleted. 125 TEST_F(DelayedCallbackRunnerTest, AddWhileRunningRun) { 126 const std::string name("one"); 127 const std::string name2("two"); 128 129 // Post a task to register a new callback after Start() is called. 130 task_runner_->PostTask( 131 FROM_HERE, 132 base::Bind(&DelayedCallbackRunnerTest::RegisterTestCallback, 133 base::Unretained(this), 134 name2)); 135 136 RegisterTestCallback(name); 137 instance_->Start(); 138 task_runner_->RunUntilIdle(); 139 EXPECT_TRUE(CallbackWasRun(name)); 140 EXPECT_TRUE(CallbackWasDeleted(name)); 141 EXPECT_TRUE(CallbackWasRun(name2)); 142 EXPECT_TRUE(CallbackWasDeleted(name2)); 143 } 144 145 TEST_F(DelayedCallbackRunnerTest, MultipleRuns) { 146 const std::string name("one"); 147 const std::string name2("two"); 148 149 RegisterTestCallback(name); 150 instance_->Start(); 151 task_runner_->RunUntilIdle(); 152 EXPECT_TRUE(CallbackWasRun(name)); 153 EXPECT_TRUE(CallbackWasDeleted(name)); 154 155 RegisterTestCallback(name2); 156 instance_->Start(); 157 task_runner_->RunUntilIdle(); 158 EXPECT_TRUE(CallbackWasRun(name2)); 159 EXPECT_TRUE(CallbackWasDeleted(name2)); 160 } 161