Home | History | Annotate | Download | only in incident_reporting
      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