1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2014 The Android Open Source Project 3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License"); 5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License. 6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at 7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// http://www.apache.org/licenses/LICENSE-2.0 9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software 11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS, 12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and 14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License. 15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 16391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo 1763784a578dd26880454d70797519358a2326291bAlex Deymo#include "update_engine/update_manager/variable.h" 1853556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo 19a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo#include <vector> 20a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo 213f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko#include <brillo/message_loops/fake_message_loop.h> 223f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko#include <brillo/message_loops/message_loop.h> 233f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko#include <brillo/message_loops/message_loop_utils.h> 24391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo#include <gtest/gtest.h> 25391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo 26a80339362c7a5175c2b7019095c0f04b388380cbAlex Deymousing base::TimeDelta; 273f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkousing brillo::MessageLoop; 283f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenkousing brillo::MessageLoopRunMaxIterations; 29391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymousing std::string; 30a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymousing std::vector; 31391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo 3263784a578dd26880454d70797519358a2326291bAlex Deymonamespace chromeos_update_manager { 33391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo 34391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo// Variable class that returns a value constructed with the default value. 35391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymotemplate <typename T> 36391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymoclass DefaultVariable : public Variable<T> { 37391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo public: 380e433699df9ac4462c9587ce398c8a2561adb929Alex Deymo DefaultVariable(const string& name, VariableMode mode) 390e433699df9ac4462c9587ce398c8a2561adb929Alex Deymo : Variable<T>(name, mode) {} 40a80339362c7a5175c2b7019095c0f04b388380cbAlex Deymo DefaultVariable(const string& name, const TimeDelta& poll_interval) 41a80339362c7a5175c2b7019095c0f04b388380cbAlex Deymo : Variable<T>(name, poll_interval) {} 42610277efc6f7e5239158dfa4bb3b1021804326e0Alex Deymo ~DefaultVariable() override {} 43391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo 44391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo protected: 4535866ed08bcefa9d8bffab9ca64cf994ad0f4290Yunlian Jiang const T* GetValue(TimeDelta /* timeout */, 4635866ed08bcefa9d8bffab9ca64cf994ad0f4290Yunlian Jiang string* /* errmsg */) override { 47391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo return new T(); 48391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo } 49391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo 50391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo private: 51391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo DISALLOW_COPY_AND_ASSIGN(DefaultVariable); 52391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo}; 53391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo 54509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymoclass UmBaseVariableTest : public ::testing::Test { 55509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo protected: 56509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo void SetUp() override { 57509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo loop_.SetAsCurrent(); 58509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo } 59509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo 603f39d5cc753905874d8d93bef94f857b8808f19eAlex Vakulenko brillo::FakeMessageLoop loop_{nullptr}; 61509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo}; 62509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo 63509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex DeymoTEST_F(UmBaseVariableTest, GetNameTest) { 640e433699df9ac4462c9587ce398c8a2561adb929Alex Deymo DefaultVariable<int> var("var", kVariableModeConst); 65391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo EXPECT_EQ(var.GetName(), string("var")); 66391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo} 67391ad9f1b6ac96dc80d4c1b740245444fdae5765Alex Deymo 68509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex DeymoTEST_F(UmBaseVariableTest, GetModeTest) { 690e433699df9ac4462c9587ce398c8a2561adb929Alex Deymo DefaultVariable<int> var("var", kVariableModeConst); 700e433699df9ac4462c9587ce398c8a2561adb929Alex Deymo EXPECT_EQ(var.GetMode(), kVariableModeConst); 710e433699df9ac4462c9587ce398c8a2561adb929Alex Deymo DefaultVariable<int> other_var("other_var", kVariableModePoll); 720e433699df9ac4462c9587ce398c8a2561adb929Alex Deymo EXPECT_EQ(other_var.GetMode(), kVariableModePoll); 730e433699df9ac4462c9587ce398c8a2561adb929Alex Deymo} 740e433699df9ac4462c9587ce398c8a2561adb929Alex Deymo 75509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex DeymoTEST_F(UmBaseVariableTest, DefaultPollIntervalTest) { 76a80339362c7a5175c2b7019095c0f04b388380cbAlex Deymo DefaultVariable<int> const_var("const_var", kVariableModeConst); 77a80339362c7a5175c2b7019095c0f04b388380cbAlex Deymo EXPECT_EQ(const_var.GetPollInterval(), TimeDelta()); 78a80339362c7a5175c2b7019095c0f04b388380cbAlex Deymo DefaultVariable<int> poll_var("poll_var", kVariableModePoll); 79a80339362c7a5175c2b7019095c0f04b388380cbAlex Deymo EXPECT_EQ(poll_var.GetPollInterval(), TimeDelta::FromMinutes(5)); 80a80339362c7a5175c2b7019095c0f04b388380cbAlex Deymo} 81a80339362c7a5175c2b7019095c0f04b388380cbAlex Deymo 82509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex DeymoTEST_F(UmBaseVariableTest, GetPollIntervalTest) { 83a80339362c7a5175c2b7019095c0f04b388380cbAlex Deymo DefaultVariable<int> var("var", TimeDelta::FromMinutes(3)); 84a80339362c7a5175c2b7019095c0f04b388380cbAlex Deymo EXPECT_EQ(var.GetMode(), kVariableModePoll); 85a80339362c7a5175c2b7019095c0f04b388380cbAlex Deymo EXPECT_EQ(var.GetPollInterval(), TimeDelta::FromMinutes(3)); 86a80339362c7a5175c2b7019095c0f04b388380cbAlex Deymo} 87a80339362c7a5175c2b7019095c0f04b388380cbAlex Deymo 8853556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymoclass BaseVariableObserver : public BaseVariable::ObserverInterface { 89a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo public: 90a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo void ValueChanged(BaseVariable* variable) { 91a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo calls_.push_back(variable); 92a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo } 93a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo 94a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo // List of called functions. 95a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo vector<BaseVariable*> calls_; 96a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo}; 97a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo 98509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex DeymoTEST_F(UmBaseVariableTest, RepeatedObserverTest) { 99a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo DefaultVariable<int> var("var", kVariableModeAsync); 100a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo BaseVariableObserver observer; 101a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo var.AddObserver(&observer); 10280f70ff45f8ea9a679c0c3ed0dc143dd2fe2b63eAlex Deymo EXPECT_EQ(1U, var.observer_list_.size()); 103a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo var.AddObserver(&observer); 10480f70ff45f8ea9a679c0c3ed0dc143dd2fe2b63eAlex Deymo EXPECT_EQ(1U, var.observer_list_.size()); 105a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo var.RemoveObserver(&observer); 10680f70ff45f8ea9a679c0c3ed0dc143dd2fe2b63eAlex Deymo EXPECT_EQ(0U, var.observer_list_.size()); 107a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo var.RemoveObserver(&observer); 10880f70ff45f8ea9a679c0c3ed0dc143dd2fe2b63eAlex Deymo EXPECT_EQ(0U, var.observer_list_.size()); 109a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo} 110a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo 111509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex DeymoTEST_F(UmBaseVariableTest, NotifyValueChangedTest) { 112a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo DefaultVariable<int> var("var", kVariableModeAsync); 113a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo BaseVariableObserver observer1; 114a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo var.AddObserver(&observer1); 115a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo // Simulate a value change on the variable's implementation. 116a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo var.NotifyValueChanged(); 11780f70ff45f8ea9a679c0c3ed0dc143dd2fe2b63eAlex Deymo ASSERT_EQ(0U, observer1.calls_.size()); 118509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo MessageLoopRunMaxIterations(MessageLoop::current(), 100); 119a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo 12080f70ff45f8ea9a679c0c3ed0dc143dd2fe2b63eAlex Deymo ASSERT_EQ(1U, observer1.calls_.size()); 121a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo // Check that the observer is called with the right argument. 12253556eccd206bacd5c9c8bb6605bcceb1bcb6190Alex Deymo EXPECT_EQ(&var, observer1.calls_[0]); 123a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo 124a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo BaseVariableObserver observer2; 125a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo var.AddObserver(&observer2); 126a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo var.NotifyValueChanged(); 127509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo MessageLoopRunMaxIterations(MessageLoop::current(), 100); 128a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo 129a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo // Check that all the observers are called. 13080f70ff45f8ea9a679c0c3ed0dc143dd2fe2b63eAlex Deymo EXPECT_EQ(2U, observer1.calls_.size()); 13180f70ff45f8ea9a679c0c3ed0dc143dd2fe2b63eAlex Deymo EXPECT_EQ(1U, observer2.calls_.size()); 132a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo 133a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo var.RemoveObserver(&observer1); 134a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo var.RemoveObserver(&observer2); 135a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo} 136a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo 137a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymoclass BaseVariableObserverRemover : public BaseVariable::ObserverInterface { 138a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo public: 139a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo BaseVariableObserverRemover() : calls_(0) {} 140a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo 141a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo void ValueChanged(BaseVariable* variable) override { 142a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo for (auto& observer : remove_observers_) { 143a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo variable->RemoveObserver(observer); 144a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo } 145a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo calls_++; 146a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo } 147a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo 148a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo void OnCallRemoveObserver(BaseVariable::ObserverInterface* observer) { 149a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo remove_observers_.push_back(observer); 150a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo } 151a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo 152a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo int get_calls() { return calls_; } 153a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo 154a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo private: 155a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo vector<BaseVariable::ObserverInterface*> remove_observers_; 156a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo int calls_; 157a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo}; 158a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo 159a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo// Tests that we can remove an observer from a Variable on the ValueChanged() 160a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo// call to that observer. 161509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex DeymoTEST_F(UmBaseVariableTest, NotifyValueRemovesObserversTest) { 162a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo DefaultVariable<int> var("var", kVariableModeAsync); 163a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo BaseVariableObserverRemover observer1; 164a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo BaseVariableObserverRemover observer2; 165a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo 166a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo var.AddObserver(&observer1); 167a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo var.AddObserver(&observer2); 168a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo 169a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo // Make each observer remove both observers on ValueChanged. 170a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo observer1.OnCallRemoveObserver(&observer1); 171a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo observer1.OnCallRemoveObserver(&observer2); 172a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo observer2.OnCallRemoveObserver(&observer1); 173a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo observer2.OnCallRemoveObserver(&observer2); 174a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo 175a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo var.NotifyValueChanged(); 176509dd5376f47e38d18fe7d29da776e3dc9a9786dAlex Deymo MessageLoopRunMaxIterations(MessageLoop::current(), 100); 177a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo 178a5856e431d7be09dbbde0ab274fdddca868bb269Alex Deymo EXPECT_EQ(1, observer1.get_calls() + observer2.get_calls()); 179a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo} 180a07a1234e8ca7654af91048fccff152ab3db8420Alex Deymo 18163784a578dd26880454d70797519358a2326291bAlex Deymo} // namespace chromeos_update_manager 182