blob: fe40ce584cc72f2ec63ab622dd1486bd8e54550b [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:
Amin Hassani4b717432019-01-14 16:24:20 -080045 const T* GetValue(TimeDelta /* timeout */, string* /* errmsg */) override {
Alex Deymo391ad9f2014-01-29 14:36:20 -080046 return new T();
47 }
48
49 private:
50 DISALLOW_COPY_AND_ASSIGN(DefaultVariable);
51};
52
Alex Deymo509dd532015-06-10 14:11:05 -070053class UmBaseVariableTest : public ::testing::Test {
54 protected:
Amin Hassani4b717432019-01-14 16:24:20 -080055 void SetUp() override { loop_.SetAsCurrent(); }
Alex Deymo509dd532015-06-10 14:11:05 -070056
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070057 brillo::FakeMessageLoop loop_{nullptr};
Alex Deymo509dd532015-06-10 14:11:05 -070058};
59
60TEST_F(UmBaseVariableTest, GetNameTest) {
Alex Deymo0e433692014-02-20 07:23:03 -080061 DefaultVariable<int> var("var", kVariableModeConst);
Alex Deymo391ad9f2014-01-29 14:36:20 -080062 EXPECT_EQ(var.GetName(), string("var"));
63}
64
Alex Deymo509dd532015-06-10 14:11:05 -070065TEST_F(UmBaseVariableTest, GetModeTest) {
Alex Deymo0e433692014-02-20 07:23:03 -080066 DefaultVariable<int> var("var", kVariableModeConst);
67 EXPECT_EQ(var.GetMode(), kVariableModeConst);
68 DefaultVariable<int> other_var("other_var", kVariableModePoll);
69 EXPECT_EQ(other_var.GetMode(), kVariableModePoll);
70}
71
Alex Deymo509dd532015-06-10 14:11:05 -070072TEST_F(UmBaseVariableTest, DefaultPollIntervalTest) {
Alex Deymoa8033932014-02-25 10:33:13 -080073 DefaultVariable<int> const_var("const_var", kVariableModeConst);
74 EXPECT_EQ(const_var.GetPollInterval(), TimeDelta());
75 DefaultVariable<int> poll_var("poll_var", kVariableModePoll);
76 EXPECT_EQ(poll_var.GetPollInterval(), TimeDelta::FromMinutes(5));
77}
78
Alex Deymo509dd532015-06-10 14:11:05 -070079TEST_F(UmBaseVariableTest, GetPollIntervalTest) {
Alex Deymoa8033932014-02-25 10:33:13 -080080 DefaultVariable<int> var("var", TimeDelta::FromMinutes(3));
81 EXPECT_EQ(var.GetMode(), kVariableModePoll);
82 EXPECT_EQ(var.GetPollInterval(), TimeDelta::FromMinutes(3));
83}
84
Alex Deymo53556ec2014-03-17 10:05:57 -070085class BaseVariableObserver : public BaseVariable::ObserverInterface {
Alex Deymoa07a1232014-02-25 14:19:50 -080086 public:
Amin Hassani4b717432019-01-14 16:24:20 -080087 void ValueChanged(BaseVariable* variable) { calls_.push_back(variable); }
Alex Deymoa07a1232014-02-25 14:19:50 -080088
89 // List of called functions.
90 vector<BaseVariable*> calls_;
91};
92
Alex Deymo509dd532015-06-10 14:11:05 -070093TEST_F(UmBaseVariableTest, RepeatedObserverTest) {
Alex Deymoa07a1232014-02-25 14:19:50 -080094 DefaultVariable<int> var("var", kVariableModeAsync);
95 BaseVariableObserver observer;
96 var.AddObserver(&observer);
Alex Deymo80f70ff2016-02-10 16:08:11 -080097 EXPECT_EQ(1U, var.observer_list_.size());
Alex Deymoa07a1232014-02-25 14:19:50 -080098 var.AddObserver(&observer);
Alex Deymo80f70ff2016-02-10 16:08:11 -080099 EXPECT_EQ(1U, var.observer_list_.size());
Alex Deymoa07a1232014-02-25 14:19:50 -0800100 var.RemoveObserver(&observer);
Alex Deymo80f70ff2016-02-10 16:08:11 -0800101 EXPECT_EQ(0U, var.observer_list_.size());
Alex Deymoa07a1232014-02-25 14:19:50 -0800102 var.RemoveObserver(&observer);
Alex Deymo80f70ff2016-02-10 16:08:11 -0800103 EXPECT_EQ(0U, var.observer_list_.size());
Alex Deymoa07a1232014-02-25 14:19:50 -0800104}
105
Alex Deymo509dd532015-06-10 14:11:05 -0700106TEST_F(UmBaseVariableTest, NotifyValueChangedTest) {
Alex Deymoa07a1232014-02-25 14:19:50 -0800107 DefaultVariable<int> var("var", kVariableModeAsync);
108 BaseVariableObserver observer1;
109 var.AddObserver(&observer1);
110 // Simulate a value change on the variable's implementation.
111 var.NotifyValueChanged();
Alex Deymo80f70ff2016-02-10 16:08:11 -0800112 ASSERT_EQ(0U, observer1.calls_.size());
Alex Deymo509dd532015-06-10 14:11:05 -0700113 MessageLoopRunMaxIterations(MessageLoop::current(), 100);
Alex Deymoa07a1232014-02-25 14:19:50 -0800114
Alex Deymo80f70ff2016-02-10 16:08:11 -0800115 ASSERT_EQ(1U, observer1.calls_.size());
Alex Deymoa07a1232014-02-25 14:19:50 -0800116 // Check that the observer is called with the right argument.
Alex Deymo53556ec2014-03-17 10:05:57 -0700117 EXPECT_EQ(&var, observer1.calls_[0]);
Alex Deymoa07a1232014-02-25 14:19:50 -0800118
119 BaseVariableObserver observer2;
120 var.AddObserver(&observer2);
121 var.NotifyValueChanged();
Alex Deymo509dd532015-06-10 14:11:05 -0700122 MessageLoopRunMaxIterations(MessageLoop::current(), 100);
Alex Deymoa07a1232014-02-25 14:19:50 -0800123
124 // Check that all the observers are called.
Alex Deymo80f70ff2016-02-10 16:08:11 -0800125 EXPECT_EQ(2U, observer1.calls_.size());
126 EXPECT_EQ(1U, observer2.calls_.size());
Alex Deymoa5856e42014-03-31 18:01:36 -0700127
128 var.RemoveObserver(&observer1);
129 var.RemoveObserver(&observer2);
130}
131
132class BaseVariableObserverRemover : public BaseVariable::ObserverInterface {
133 public:
134 BaseVariableObserverRemover() : calls_(0) {}
135
136 void ValueChanged(BaseVariable* variable) override {
137 for (auto& observer : remove_observers_) {
138 variable->RemoveObserver(observer);
139 }
140 calls_++;
141 }
142
143 void OnCallRemoveObserver(BaseVariable::ObserverInterface* observer) {
144 remove_observers_.push_back(observer);
145 }
146
147 int get_calls() { return calls_; }
148
149 private:
150 vector<BaseVariable::ObserverInterface*> remove_observers_;
151 int calls_;
152};
153
154// Tests that we can remove an observer from a Variable on the ValueChanged()
155// call to that observer.
Alex Deymo509dd532015-06-10 14:11:05 -0700156TEST_F(UmBaseVariableTest, NotifyValueRemovesObserversTest) {
Alex Deymoa5856e42014-03-31 18:01:36 -0700157 DefaultVariable<int> var("var", kVariableModeAsync);
158 BaseVariableObserverRemover observer1;
159 BaseVariableObserverRemover observer2;
160
161 var.AddObserver(&observer1);
162 var.AddObserver(&observer2);
163
164 // Make each observer remove both observers on ValueChanged.
165 observer1.OnCallRemoveObserver(&observer1);
166 observer1.OnCallRemoveObserver(&observer2);
167 observer2.OnCallRemoveObserver(&observer1);
168 observer2.OnCallRemoveObserver(&observer2);
169
170 var.NotifyValueChanged();
Alex Deymo509dd532015-06-10 14:11:05 -0700171 MessageLoopRunMaxIterations(MessageLoop::current(), 100);
Alex Deymoa5856e42014-03-31 18:01:36 -0700172
173 EXPECT_EQ(1, observer1.get_calls() + observer2.get_calls());
Alex Deymoa07a1232014-02-25 14:19:50 -0800174}
175
Alex Deymo63784a52014-05-28 10:46:14 -0700176} // namespace chromeos_update_manager