blob: 144002aea68d30c0de82dbf72fca21d2c06e6f28 [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
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//
Alex Deymo391ad9f2014-01-29 14:36:20 -080016
Alex Deymo63784a52014-05-28 10:46:14 -070017#include "update_engine/update_manager/variable.h"
Alex Deymo53556ec2014-03-17 10:05:57 -070018
Alex Deymoa07a1232014-02-25 14:19:50 -080019#include <vector>
20
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070021#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>
Alex Deymo391ad9f2014-01-29 14:36:20 -080024#include <gtest/gtest.h>
25
Alex Deymoa8033932014-02-25 10:33:13 -080026using base::TimeDelta;
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070027using brillo::MessageLoop;
28using brillo::MessageLoopRunMaxIterations;
Alex Deymo391ad9f2014-01-29 14:36:20 -080029using std::string;
Alex Deymoa07a1232014-02-25 14:19:50 -080030using std::vector;
Alex Deymo391ad9f2014-01-29 14:36:20 -080031
Alex Deymo63784a52014-05-28 10:46:14 -070032namespace chromeos_update_manager {
Alex Deymo391ad9f2014-01-29 14:36:20 -080033
34// Variable class that returns a value constructed with the default value.
35template <typename T>
36class DefaultVariable : public Variable<T> {
37 public:
Alex Deymo0e433692014-02-20 07:23:03 -080038 DefaultVariable(const string& name, VariableMode mode)
39 : Variable<T>(name, mode) {}
Alex Deymoa8033932014-02-25 10:33:13 -080040 DefaultVariable(const string& name, const TimeDelta& poll_interval)
41 : Variable<T>(name, poll_interval) {}
Alex Deymo610277e2014-11-11 21:18:11 -080042 ~DefaultVariable() override {}
Alex Deymo391ad9f2014-01-29 14:36:20 -080043
44 protected:
Yunlian Jiang35866ed2015-01-29 13:09:20 -080045 const T* GetValue(TimeDelta /* timeout */,
46 string* /* errmsg */) override {
Alex Deymo391ad9f2014-01-29 14:36:20 -080047 return new T();
48 }
49
50 private:
51 DISALLOW_COPY_AND_ASSIGN(DefaultVariable);
52};
53
Alex Deymo509dd532015-06-10 14:11:05 -070054class UmBaseVariableTest : public ::testing::Test {
55 protected:
56 void SetUp() override {
57 loop_.SetAsCurrent();
58 }
59
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070060 brillo::FakeMessageLoop loop_{nullptr};
Alex Deymo509dd532015-06-10 14:11:05 -070061};
62
63TEST_F(UmBaseVariableTest, GetNameTest) {
Alex Deymo0e433692014-02-20 07:23:03 -080064 DefaultVariable<int> var("var", kVariableModeConst);
Alex Deymo391ad9f2014-01-29 14:36:20 -080065 EXPECT_EQ(var.GetName(), string("var"));
66}
67
Alex Deymo509dd532015-06-10 14:11:05 -070068TEST_F(UmBaseVariableTest, GetModeTest) {
Alex Deymo0e433692014-02-20 07:23:03 -080069 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
Alex Deymo509dd532015-06-10 14:11:05 -070075TEST_F(UmBaseVariableTest, DefaultPollIntervalTest) {
Alex Deymoa8033932014-02-25 10:33:13 -080076 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
Alex Deymo509dd532015-06-10 14:11:05 -070082TEST_F(UmBaseVariableTest, GetPollIntervalTest) {
Alex Deymoa8033932014-02-25 10:33:13 -080083 DefaultVariable<int> var("var", TimeDelta::FromMinutes(3));
84 EXPECT_EQ(var.GetMode(), kVariableModePoll);
85 EXPECT_EQ(var.GetPollInterval(), TimeDelta::FromMinutes(3));
86}
87
Alex Deymo53556ec2014-03-17 10:05:57 -070088class BaseVariableObserver : public BaseVariable::ObserverInterface {
Alex Deymoa07a1232014-02-25 14:19:50 -080089 public:
90 void ValueChanged(BaseVariable* variable) {
91 calls_.push_back(variable);
92 }
93
94 // List of called functions.
95 vector<BaseVariable*> calls_;
96};
97
Alex Deymo509dd532015-06-10 14:11:05 -070098TEST_F(UmBaseVariableTest, RepeatedObserverTest) {
Alex Deymoa07a1232014-02-25 14:19:50 -080099 DefaultVariable<int> var("var", kVariableModeAsync);
100 BaseVariableObserver observer;
101 var.AddObserver(&observer);
Alex Deymo80f70ff2016-02-10 16:08:11 -0800102 EXPECT_EQ(1U, var.observer_list_.size());
Alex Deymoa07a1232014-02-25 14:19:50 -0800103 var.AddObserver(&observer);
Alex Deymo80f70ff2016-02-10 16:08:11 -0800104 EXPECT_EQ(1U, var.observer_list_.size());
Alex Deymoa07a1232014-02-25 14:19:50 -0800105 var.RemoveObserver(&observer);
Alex Deymo80f70ff2016-02-10 16:08:11 -0800106 EXPECT_EQ(0U, var.observer_list_.size());
Alex Deymoa07a1232014-02-25 14:19:50 -0800107 var.RemoveObserver(&observer);
Alex Deymo80f70ff2016-02-10 16:08:11 -0800108 EXPECT_EQ(0U, var.observer_list_.size());
Alex Deymoa07a1232014-02-25 14:19:50 -0800109}
110
Alex Deymo509dd532015-06-10 14:11:05 -0700111TEST_F(UmBaseVariableTest, NotifyValueChangedTest) {
Alex Deymoa07a1232014-02-25 14:19:50 -0800112 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();
Alex Deymo80f70ff2016-02-10 16:08:11 -0800117 ASSERT_EQ(0U, observer1.calls_.size());
Alex Deymo509dd532015-06-10 14:11:05 -0700118 MessageLoopRunMaxIterations(MessageLoop::current(), 100);
Alex Deymoa07a1232014-02-25 14:19:50 -0800119
Alex Deymo80f70ff2016-02-10 16:08:11 -0800120 ASSERT_EQ(1U, observer1.calls_.size());
Alex Deymoa07a1232014-02-25 14:19:50 -0800121 // Check that the observer is called with the right argument.
Alex Deymo53556ec2014-03-17 10:05:57 -0700122 EXPECT_EQ(&var, observer1.calls_[0]);
Alex Deymoa07a1232014-02-25 14:19:50 -0800123
124 BaseVariableObserver observer2;
125 var.AddObserver(&observer2);
126 var.NotifyValueChanged();
Alex Deymo509dd532015-06-10 14:11:05 -0700127 MessageLoopRunMaxIterations(MessageLoop::current(), 100);
Alex Deymoa07a1232014-02-25 14:19:50 -0800128
129 // Check that all the observers are called.
Alex Deymo80f70ff2016-02-10 16:08:11 -0800130 EXPECT_EQ(2U, observer1.calls_.size());
131 EXPECT_EQ(1U, observer2.calls_.size());
Alex Deymoa5856e42014-03-31 18:01:36 -0700132
133 var.RemoveObserver(&observer1);
134 var.RemoveObserver(&observer2);
135}
136
137class 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.
Alex Deymo509dd532015-06-10 14:11:05 -0700161TEST_F(UmBaseVariableTest, NotifyValueRemovesObserversTest) {
Alex Deymoa5856e42014-03-31 18:01:36 -0700162 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();
Alex Deymo509dd532015-06-10 14:11:05 -0700176 MessageLoopRunMaxIterations(MessageLoop::current(), 100);
Alex Deymoa5856e42014-03-31 18:01:36 -0700177
178 EXPECT_EQ(1, observer1.get_calls() + observer2.get_calls());
Alex Deymoa07a1232014-02-25 14:19:50 -0800179}
180
Alex Deymo63784a52014-05-28 10:46:14 -0700181} // namespace chromeos_update_manager