Home | History | Annotate | Download | only in update_manager
      1 //
      2 // Copyright (C) 2014 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #include "update_engine/update_manager/variable.h"
     18 
     19 #include <vector>
     20 
     21 #include <brillo/message_loops/fake_message_loop.h>
     22 #include <brillo/message_loops/message_loop.h>
     23 #include <brillo/message_loops/message_loop_utils.h>
     24 #include <gtest/gtest.h>
     25 
     26 using base::TimeDelta;
     27 using brillo::MessageLoop;
     28 using brillo::MessageLoopRunMaxIterations;
     29 using std::string;
     30 using std::vector;
     31 
     32 namespace chromeos_update_manager {
     33 
     34 // Variable class that returns a value constructed with the default value.
     35 template <typename T>
     36 class DefaultVariable : public Variable<T> {
     37  public:
     38   DefaultVariable(const string& name, VariableMode mode)
     39       : Variable<T>(name, mode) {}
     40   DefaultVariable(const string& name, const TimeDelta& poll_interval)
     41       : Variable<T>(name, poll_interval) {}
     42   ~DefaultVariable() override {}
     43 
     44  protected:
     45   const T* GetValue(TimeDelta /* timeout */,
     46                     string* /* errmsg */) override {
     47     return new T();
     48   }
     49 
     50  private:
     51   DISALLOW_COPY_AND_ASSIGN(DefaultVariable);
     52 };
     53 
     54 class UmBaseVariableTest : public ::testing::Test {
     55  protected:
     56   void SetUp() override {
     57     loop_.SetAsCurrent();
     58   }
     59 
     60   brillo::FakeMessageLoop loop_{nullptr};
     61 };
     62 
     63 TEST_F(UmBaseVariableTest, GetNameTest) {
     64   DefaultVariable<int> var("var", kVariableModeConst);
     65   EXPECT_EQ(var.GetName(), string("var"));
     66 }
     67 
     68 TEST_F(UmBaseVariableTest, GetModeTest) {
     69   DefaultVariable<int> var("var", kVariableModeConst);
     70   EXPECT_EQ(var.GetMode(), kVariableModeConst);
     71   DefaultVariable<int> other_var("other_var", kVariableModePoll);
     72   EXPECT_EQ(other_var.GetMode(), kVariableModePoll);
     73 }
     74 
     75 TEST_F(UmBaseVariableTest, DefaultPollIntervalTest) {
     76   DefaultVariable<int> const_var("const_var", kVariableModeConst);
     77   EXPECT_EQ(const_var.GetPollInterval(), TimeDelta());
     78   DefaultVariable<int> poll_var("poll_var", kVariableModePoll);
     79   EXPECT_EQ(poll_var.GetPollInterval(), TimeDelta::FromMinutes(5));
     80 }
     81 
     82 TEST_F(UmBaseVariableTest, GetPollIntervalTest) {
     83   DefaultVariable<int> var("var", TimeDelta::FromMinutes(3));
     84   EXPECT_EQ(var.GetMode(), kVariableModePoll);
     85   EXPECT_EQ(var.GetPollInterval(), TimeDelta::FromMinutes(3));
     86 }
     87 
     88 class BaseVariableObserver : public BaseVariable::ObserverInterface {
     89  public:
     90   void ValueChanged(BaseVariable* variable) {
     91     calls_.push_back(variable);
     92   }
     93 
     94   // List of called functions.
     95   vector<BaseVariable*> calls_;
     96 };
     97 
     98 TEST_F(UmBaseVariableTest, RepeatedObserverTest) {
     99   DefaultVariable<int> var("var", kVariableModeAsync);
    100   BaseVariableObserver observer;
    101   var.AddObserver(&observer);
    102   EXPECT_EQ(1U, var.observer_list_.size());
    103   var.AddObserver(&observer);
    104   EXPECT_EQ(1U, var.observer_list_.size());
    105   var.RemoveObserver(&observer);
    106   EXPECT_EQ(0U, var.observer_list_.size());
    107   var.RemoveObserver(&observer);
    108   EXPECT_EQ(0U, var.observer_list_.size());
    109 }
    110 
    111 TEST_F(UmBaseVariableTest, NotifyValueChangedTest) {
    112   DefaultVariable<int> var("var", kVariableModeAsync);
    113   BaseVariableObserver observer1;
    114   var.AddObserver(&observer1);
    115   // Simulate a value change on the variable's implementation.
    116   var.NotifyValueChanged();
    117   ASSERT_EQ(0U, observer1.calls_.size());
    118   MessageLoopRunMaxIterations(MessageLoop::current(), 100);
    119 
    120   ASSERT_EQ(1U, observer1.calls_.size());
    121   // Check that the observer is called with the right argument.
    122   EXPECT_EQ(&var, observer1.calls_[0]);
    123 
    124   BaseVariableObserver observer2;
    125   var.AddObserver(&observer2);
    126   var.NotifyValueChanged();
    127   MessageLoopRunMaxIterations(MessageLoop::current(), 100);
    128 
    129   // Check that all the observers are called.
    130   EXPECT_EQ(2U, observer1.calls_.size());
    131   EXPECT_EQ(1U, observer2.calls_.size());
    132 
    133   var.RemoveObserver(&observer1);
    134   var.RemoveObserver(&observer2);
    135 }
    136 
    137 class BaseVariableObserverRemover : public BaseVariable::ObserverInterface {
    138  public:
    139   BaseVariableObserverRemover() : calls_(0) {}
    140 
    141   void ValueChanged(BaseVariable* variable) override {
    142     for (auto& observer : remove_observers_) {
    143       variable->RemoveObserver(observer);
    144     }
    145     calls_++;
    146   }
    147 
    148   void OnCallRemoveObserver(BaseVariable::ObserverInterface* observer) {
    149     remove_observers_.push_back(observer);
    150   }
    151 
    152   int get_calls() { return calls_; }
    153 
    154  private:
    155   vector<BaseVariable::ObserverInterface*> remove_observers_;
    156   int calls_;
    157 };
    158 
    159 // Tests that we can remove an observer from a Variable on the ValueChanged()
    160 // call to that observer.
    161 TEST_F(UmBaseVariableTest, NotifyValueRemovesObserversTest) {
    162   DefaultVariable<int> var("var", kVariableModeAsync);
    163   BaseVariableObserverRemover observer1;
    164   BaseVariableObserverRemover observer2;
    165 
    166   var.AddObserver(&observer1);
    167   var.AddObserver(&observer2);
    168 
    169   // Make each observer remove both observers on ValueChanged.
    170   observer1.OnCallRemoveObserver(&observer1);
    171   observer1.OnCallRemoveObserver(&observer2);
    172   observer2.OnCallRemoveObserver(&observer1);
    173   observer2.OnCallRemoveObserver(&observer2);
    174 
    175   var.NotifyValueChanged();
    176   MessageLoopRunMaxIterations(MessageLoop::current(), 100);
    177 
    178   EXPECT_EQ(1, observer1.get_calls() + observer2.get_calls());
    179 }
    180 
    181 }  // namespace chromeos_update_manager
    182