blob: 000176b4b39598915db3c5ae7397baf065ba4712 [file] [log] [blame]
Alex Deymo391ad9f2014-01-29 14:36:20 -08001// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Alex Deymo63784a52014-05-28 10:46:14 -07005#include "update_engine/update_manager/variable.h"
Alex Deymo53556ec2014-03-17 10:05:57 -07006
Alex Deymoa07a1232014-02-25 14:19:50 -08007#include <vector>
8
Alex Deymo509dd532015-06-10 14:11:05 -07009#include <chromeos/message_loops/fake_message_loop.h>
10#include <chromeos/message_loops/message_loop.h>
11#include <chromeos/message_loops/message_loop_utils.h>
Alex Deymo391ad9f2014-01-29 14:36:20 -080012#include <gtest/gtest.h>
13
Alex Deymoa8033932014-02-25 10:33:13 -080014using base::TimeDelta;
Alex Deymo509dd532015-06-10 14:11:05 -070015using chromeos::MessageLoop;
16using chromeos::MessageLoopRunMaxIterations;
Alex Deymo391ad9f2014-01-29 14:36:20 -080017using std::string;
Alex Deymoa07a1232014-02-25 14:19:50 -080018using std::vector;
Alex Deymo391ad9f2014-01-29 14:36:20 -080019
Alex Deymo63784a52014-05-28 10:46:14 -070020namespace chromeos_update_manager {
Alex Deymo391ad9f2014-01-29 14:36:20 -080021
22// Variable class that returns a value constructed with the default value.
23template <typename T>
24class DefaultVariable : public Variable<T> {
25 public:
Alex Deymo0e433692014-02-20 07:23:03 -080026 DefaultVariable(const string& name, VariableMode mode)
27 : Variable<T>(name, mode) {}
Alex Deymoa8033932014-02-25 10:33:13 -080028 DefaultVariable(const string& name, const TimeDelta& poll_interval)
29 : Variable<T>(name, poll_interval) {}
Alex Deymo610277e2014-11-11 21:18:11 -080030 ~DefaultVariable() override {}
Alex Deymo391ad9f2014-01-29 14:36:20 -080031
32 protected:
Yunlian Jiang35866ed2015-01-29 13:09:20 -080033 const T* GetValue(TimeDelta /* timeout */,
34 string* /* errmsg */) override {
Alex Deymo391ad9f2014-01-29 14:36:20 -080035 return new T();
36 }
37
38 private:
39 DISALLOW_COPY_AND_ASSIGN(DefaultVariable);
40};
41
Alex Deymo509dd532015-06-10 14:11:05 -070042class UmBaseVariableTest : public ::testing::Test {
43 protected:
44 void SetUp() override {
45 loop_.SetAsCurrent();
46 }
47
48 chromeos::FakeMessageLoop loop_{nullptr};
49};
50
51TEST_F(UmBaseVariableTest, GetNameTest) {
Alex Deymo0e433692014-02-20 07:23:03 -080052 DefaultVariable<int> var("var", kVariableModeConst);
Alex Deymo391ad9f2014-01-29 14:36:20 -080053 EXPECT_EQ(var.GetName(), string("var"));
54}
55
Alex Deymo509dd532015-06-10 14:11:05 -070056TEST_F(UmBaseVariableTest, GetModeTest) {
Alex Deymo0e433692014-02-20 07:23:03 -080057 DefaultVariable<int> var("var", kVariableModeConst);
58 EXPECT_EQ(var.GetMode(), kVariableModeConst);
59 DefaultVariable<int> other_var("other_var", kVariableModePoll);
60 EXPECT_EQ(other_var.GetMode(), kVariableModePoll);
61}
62
Alex Deymo509dd532015-06-10 14:11:05 -070063TEST_F(UmBaseVariableTest, DefaultPollIntervalTest) {
Alex Deymoa8033932014-02-25 10:33:13 -080064 DefaultVariable<int> const_var("const_var", kVariableModeConst);
65 EXPECT_EQ(const_var.GetPollInterval(), TimeDelta());
66 DefaultVariable<int> poll_var("poll_var", kVariableModePoll);
67 EXPECT_EQ(poll_var.GetPollInterval(), TimeDelta::FromMinutes(5));
68}
69
Alex Deymo509dd532015-06-10 14:11:05 -070070TEST_F(UmBaseVariableTest, GetPollIntervalTest) {
Alex Deymoa8033932014-02-25 10:33:13 -080071 DefaultVariable<int> var("var", TimeDelta::FromMinutes(3));
72 EXPECT_EQ(var.GetMode(), kVariableModePoll);
73 EXPECT_EQ(var.GetPollInterval(), TimeDelta::FromMinutes(3));
74}
75
Alex Deymo53556ec2014-03-17 10:05:57 -070076class BaseVariableObserver : public BaseVariable::ObserverInterface {
Alex Deymoa07a1232014-02-25 14:19:50 -080077 public:
78 void ValueChanged(BaseVariable* variable) {
79 calls_.push_back(variable);
80 }
81
82 // List of called functions.
83 vector<BaseVariable*> calls_;
84};
85
Alex Deymo509dd532015-06-10 14:11:05 -070086TEST_F(UmBaseVariableTest, RepeatedObserverTest) {
Alex Deymoa07a1232014-02-25 14:19:50 -080087 DefaultVariable<int> var("var", kVariableModeAsync);
88 BaseVariableObserver observer;
89 var.AddObserver(&observer);
90 EXPECT_EQ(var.observer_list_.size(), 1);
91 var.AddObserver(&observer);
92 EXPECT_EQ(var.observer_list_.size(), 1);
93 var.RemoveObserver(&observer);
94 EXPECT_EQ(var.observer_list_.size(), 0);
95 var.RemoveObserver(&observer);
96 EXPECT_EQ(var.observer_list_.size(), 0);
97}
98
Alex Deymo509dd532015-06-10 14:11:05 -070099TEST_F(UmBaseVariableTest, NotifyValueChangedTest) {
Alex Deymoa07a1232014-02-25 14:19:50 -0800100 DefaultVariable<int> var("var", kVariableModeAsync);
101 BaseVariableObserver observer1;
102 var.AddObserver(&observer1);
103 // Simulate a value change on the variable's implementation.
104 var.NotifyValueChanged();
Alex Deymo53556ec2014-03-17 10:05:57 -0700105 ASSERT_EQ(0, observer1.calls_.size());
Alex Deymo509dd532015-06-10 14:11:05 -0700106 MessageLoopRunMaxIterations(MessageLoop::current(), 100);
Alex Deymoa07a1232014-02-25 14:19:50 -0800107
Alex Deymo53556ec2014-03-17 10:05:57 -0700108 ASSERT_EQ(1, observer1.calls_.size());
Alex Deymoa07a1232014-02-25 14:19:50 -0800109 // Check that the observer is called with the right argument.
Alex Deymo53556ec2014-03-17 10:05:57 -0700110 EXPECT_EQ(&var, observer1.calls_[0]);
Alex Deymoa07a1232014-02-25 14:19:50 -0800111
112 BaseVariableObserver observer2;
113 var.AddObserver(&observer2);
114 var.NotifyValueChanged();
Alex Deymo509dd532015-06-10 14:11:05 -0700115 MessageLoopRunMaxIterations(MessageLoop::current(), 100);
Alex Deymoa07a1232014-02-25 14:19:50 -0800116
117 // Check that all the observers are called.
Alex Deymo53556ec2014-03-17 10:05:57 -0700118 EXPECT_EQ(2, observer1.calls_.size());
119 EXPECT_EQ(1, observer2.calls_.size());
Alex Deymoa5856e42014-03-31 18:01:36 -0700120
121 var.RemoveObserver(&observer1);
122 var.RemoveObserver(&observer2);
123}
124
125class BaseVariableObserverRemover : public BaseVariable::ObserverInterface {
126 public:
127 BaseVariableObserverRemover() : calls_(0) {}
128
129 void ValueChanged(BaseVariable* variable) override {
130 for (auto& observer : remove_observers_) {
131 variable->RemoveObserver(observer);
132 }
133 calls_++;
134 }
135
136 void OnCallRemoveObserver(BaseVariable::ObserverInterface* observer) {
137 remove_observers_.push_back(observer);
138 }
139
140 int get_calls() { return calls_; }
141
142 private:
143 vector<BaseVariable::ObserverInterface*> remove_observers_;
144 int calls_;
145};
146
147// Tests that we can remove an observer from a Variable on the ValueChanged()
148// call to that observer.
Alex Deymo509dd532015-06-10 14:11:05 -0700149TEST_F(UmBaseVariableTest, NotifyValueRemovesObserversTest) {
Alex Deymoa5856e42014-03-31 18:01:36 -0700150 DefaultVariable<int> var("var", kVariableModeAsync);
151 BaseVariableObserverRemover observer1;
152 BaseVariableObserverRemover observer2;
153
154 var.AddObserver(&observer1);
155 var.AddObserver(&observer2);
156
157 // Make each observer remove both observers on ValueChanged.
158 observer1.OnCallRemoveObserver(&observer1);
159 observer1.OnCallRemoveObserver(&observer2);
160 observer2.OnCallRemoveObserver(&observer1);
161 observer2.OnCallRemoveObserver(&observer2);
162
163 var.NotifyValueChanged();
Alex Deymo509dd532015-06-10 14:11:05 -0700164 MessageLoopRunMaxIterations(MessageLoop::current(), 100);
Alex Deymoa5856e42014-03-31 18:01:36 -0700165
166 EXPECT_EQ(1, observer1.get_calls() + observer2.get_calls());
Alex Deymoa07a1232014-02-25 14:19:50 -0800167}
168
Alex Deymo63784a52014-05-28 10:46:14 -0700169} // namespace chromeos_update_manager