diff options
author | Alex Deymo <deymo@chromium.org> | 2015-07-14 17:25:03 -0700 |
---|---|---|
committer | Alex Deymo <deymo@chromium.org> | 2015-07-14 17:25:03 -0700 |
commit | ba2b2eec4972893745fa2beb899b2adbdbb39d0f (patch) | |
tree | 22c30fab0c717a5068160ad0ca0be4f54557a288 /update_manager/variable_unittest.cc | |
parent | 701376dd44ec6f5212641031a65aae4eb051f777 (diff) | |
parent | 454b798705352bcfbef19759f4dddfe3f0ac490c (diff) |
Merge branch 'rewrite-update_engine' into merge-update_engine
Diffstat (limited to 'update_manager/variable_unittest.cc')
-rw-r--r-- | update_manager/variable_unittest.cc | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/update_manager/variable_unittest.cc b/update_manager/variable_unittest.cc new file mode 100644 index 00000000..000176b4 --- /dev/null +++ b/update_manager/variable_unittest.cc @@ -0,0 +1,169 @@ +// Copyright (c) 2014 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "update_engine/update_manager/variable.h" + +#include <vector> + +#include <chromeos/message_loops/fake_message_loop.h> +#include <chromeos/message_loops/message_loop.h> +#include <chromeos/message_loops/message_loop_utils.h> +#include <gtest/gtest.h> + +using base::TimeDelta; +using chromeos::MessageLoop; +using chromeos::MessageLoopRunMaxIterations; +using std::string; +using std::vector; + +namespace chromeos_update_manager { + +// Variable class that returns a value constructed with the default value. +template <typename T> +class DefaultVariable : public Variable<T> { + public: + DefaultVariable(const string& name, VariableMode mode) + : Variable<T>(name, mode) {} + DefaultVariable(const string& name, const TimeDelta& poll_interval) + : Variable<T>(name, poll_interval) {} + ~DefaultVariable() override {} + + protected: + const T* GetValue(TimeDelta /* timeout */, + string* /* errmsg */) override { + return new T(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(DefaultVariable); +}; + +class UmBaseVariableTest : public ::testing::Test { + protected: + void SetUp() override { + loop_.SetAsCurrent(); + } + + chromeos::FakeMessageLoop loop_{nullptr}; +}; + +TEST_F(UmBaseVariableTest, GetNameTest) { + DefaultVariable<int> var("var", kVariableModeConst); + EXPECT_EQ(var.GetName(), string("var")); +} + +TEST_F(UmBaseVariableTest, GetModeTest) { + DefaultVariable<int> var("var", kVariableModeConst); + EXPECT_EQ(var.GetMode(), kVariableModeConst); + DefaultVariable<int> other_var("other_var", kVariableModePoll); + EXPECT_EQ(other_var.GetMode(), kVariableModePoll); +} + +TEST_F(UmBaseVariableTest, DefaultPollIntervalTest) { + DefaultVariable<int> const_var("const_var", kVariableModeConst); + EXPECT_EQ(const_var.GetPollInterval(), TimeDelta()); + DefaultVariable<int> poll_var("poll_var", kVariableModePoll); + EXPECT_EQ(poll_var.GetPollInterval(), TimeDelta::FromMinutes(5)); +} + +TEST_F(UmBaseVariableTest, GetPollIntervalTest) { + DefaultVariable<int> var("var", TimeDelta::FromMinutes(3)); + EXPECT_EQ(var.GetMode(), kVariableModePoll); + EXPECT_EQ(var.GetPollInterval(), TimeDelta::FromMinutes(3)); +} + +class BaseVariableObserver : public BaseVariable::ObserverInterface { + public: + void ValueChanged(BaseVariable* variable) { + calls_.push_back(variable); + } + + // List of called functions. + vector<BaseVariable*> calls_; +}; + +TEST_F(UmBaseVariableTest, RepeatedObserverTest) { + DefaultVariable<int> var("var", kVariableModeAsync); + BaseVariableObserver observer; + var.AddObserver(&observer); + EXPECT_EQ(var.observer_list_.size(), 1); + var.AddObserver(&observer); + EXPECT_EQ(var.observer_list_.size(), 1); + var.RemoveObserver(&observer); + EXPECT_EQ(var.observer_list_.size(), 0); + var.RemoveObserver(&observer); + EXPECT_EQ(var.observer_list_.size(), 0); +} + +TEST_F(UmBaseVariableTest, NotifyValueChangedTest) { + DefaultVariable<int> var("var", kVariableModeAsync); + BaseVariableObserver observer1; + var.AddObserver(&observer1); + // Simulate a value change on the variable's implementation. + var.NotifyValueChanged(); + ASSERT_EQ(0, observer1.calls_.size()); + MessageLoopRunMaxIterations(MessageLoop::current(), 100); + + ASSERT_EQ(1, observer1.calls_.size()); + // Check that the observer is called with the right argument. + EXPECT_EQ(&var, observer1.calls_[0]); + + BaseVariableObserver observer2; + var.AddObserver(&observer2); + var.NotifyValueChanged(); + MessageLoopRunMaxIterations(MessageLoop::current(), 100); + + // Check that all the observers are called. + EXPECT_EQ(2, observer1.calls_.size()); + EXPECT_EQ(1, observer2.calls_.size()); + + var.RemoveObserver(&observer1); + var.RemoveObserver(&observer2); +} + +class BaseVariableObserverRemover : public BaseVariable::ObserverInterface { + public: + BaseVariableObserverRemover() : calls_(0) {} + + void ValueChanged(BaseVariable* variable) override { + for (auto& observer : remove_observers_) { + variable->RemoveObserver(observer); + } + calls_++; + } + + void OnCallRemoveObserver(BaseVariable::ObserverInterface* observer) { + remove_observers_.push_back(observer); + } + + int get_calls() { return calls_; } + + private: + vector<BaseVariable::ObserverInterface*> remove_observers_; + int calls_; +}; + +// Tests that we can remove an observer from a Variable on the ValueChanged() +// call to that observer. +TEST_F(UmBaseVariableTest, NotifyValueRemovesObserversTest) { + DefaultVariable<int> var("var", kVariableModeAsync); + BaseVariableObserverRemover observer1; + BaseVariableObserverRemover observer2; + + var.AddObserver(&observer1); + var.AddObserver(&observer2); + + // Make each observer remove both observers on ValueChanged. + observer1.OnCallRemoveObserver(&observer1); + observer1.OnCallRemoveObserver(&observer2); + observer2.OnCallRemoveObserver(&observer1); + observer2.OnCallRemoveObserver(&observer2); + + var.NotifyValueChanged(); + MessageLoopRunMaxIterations(MessageLoop::current(), 100); + + EXPECT_EQ(1, observer1.get_calls() + observer2.get_calls()); +} + +} // namespace chromeos_update_manager |