blob: 09c7649472ecc83ca0aeb8ac85e08cfd532cf01e [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 Deymo391ad9f2014-01-29 14:36:20 -08009#include <gtest/gtest.h>
10
Alex Deymo53556ec2014-03-17 10:05:57 -070011#include "update_engine/test_utils.h"
Alex Deymo391ad9f2014-01-29 14:36:20 -080012
Alex Deymoa8033932014-02-25 10:33:13 -080013using base::TimeDelta;
Alex Deymo63784a52014-05-28 10:46:14 -070014using chromeos_update_engine::RunGMainLoopMaxIterations;
Alex Deymo391ad9f2014-01-29 14:36:20 -080015using std::string;
Alex Deymoa07a1232014-02-25 14:19:50 -080016using std::vector;
Alex Deymo391ad9f2014-01-29 14:36:20 -080017
Alex Deymo63784a52014-05-28 10:46:14 -070018namespace chromeos_update_manager {
Alex Deymo391ad9f2014-01-29 14:36:20 -080019
20// Variable class that returns a value constructed with the default value.
21template <typename T>
22class DefaultVariable : public Variable<T> {
23 public:
Alex Deymo0e433692014-02-20 07:23:03 -080024 DefaultVariable(const string& name, VariableMode mode)
25 : Variable<T>(name, mode) {}
Alex Deymoa8033932014-02-25 10:33:13 -080026 DefaultVariable(const string& name, const TimeDelta& poll_interval)
27 : Variable<T>(name, poll_interval) {}
Alex Deymo391ad9f2014-01-29 14:36:20 -080028 virtual ~DefaultVariable() {}
29
30 protected:
Alex Deymo53556ec2014-03-17 10:05:57 -070031 virtual const T* GetValue(TimeDelta /* timeout */,
Alex Deymo391ad9f2014-01-29 14:36:20 -080032 string* /* errmsg */) {
33 return new T();
34 }
35
36 private:
37 DISALLOW_COPY_AND_ASSIGN(DefaultVariable);
38};
39
Alex Deymo63784a52014-05-28 10:46:14 -070040TEST(UmBaseVariableTest, GetNameTest) {
Alex Deymo0e433692014-02-20 07:23:03 -080041 DefaultVariable<int> var("var", kVariableModeConst);
Alex Deymo391ad9f2014-01-29 14:36:20 -080042 EXPECT_EQ(var.GetName(), string("var"));
43}
44
Alex Deymo63784a52014-05-28 10:46:14 -070045TEST(UmBaseVariableTest, GetModeTest) {
Alex Deymo0e433692014-02-20 07:23:03 -080046 DefaultVariable<int> var("var", kVariableModeConst);
47 EXPECT_EQ(var.GetMode(), kVariableModeConst);
48 DefaultVariable<int> other_var("other_var", kVariableModePoll);
49 EXPECT_EQ(other_var.GetMode(), kVariableModePoll);
50}
51
Alex Deymo63784a52014-05-28 10:46:14 -070052TEST(UmBaseVariableTest, DefaultPollIntervalTest) {
Alex Deymoa8033932014-02-25 10:33:13 -080053 DefaultVariable<int> const_var("const_var", kVariableModeConst);
54 EXPECT_EQ(const_var.GetPollInterval(), TimeDelta());
55 DefaultVariable<int> poll_var("poll_var", kVariableModePoll);
56 EXPECT_EQ(poll_var.GetPollInterval(), TimeDelta::FromMinutes(5));
57}
58
Alex Deymo63784a52014-05-28 10:46:14 -070059TEST(UmBaseVariableTest, GetPollIntervalTest) {
Alex Deymoa8033932014-02-25 10:33:13 -080060 DefaultVariable<int> var("var", TimeDelta::FromMinutes(3));
61 EXPECT_EQ(var.GetMode(), kVariableModePoll);
62 EXPECT_EQ(var.GetPollInterval(), TimeDelta::FromMinutes(3));
63}
64
Alex Deymo53556ec2014-03-17 10:05:57 -070065class BaseVariableObserver : public BaseVariable::ObserverInterface {
Alex Deymoa07a1232014-02-25 14:19:50 -080066 public:
67 void ValueChanged(BaseVariable* variable) {
68 calls_.push_back(variable);
69 }
70
71 // List of called functions.
72 vector<BaseVariable*> calls_;
73};
74
Alex Deymo63784a52014-05-28 10:46:14 -070075TEST(UmBaseVariableTest, RepeatedObserverTest) {
Alex Deymoa07a1232014-02-25 14:19:50 -080076 DefaultVariable<int> var("var", kVariableModeAsync);
77 BaseVariableObserver observer;
78 var.AddObserver(&observer);
79 EXPECT_EQ(var.observer_list_.size(), 1);
80 var.AddObserver(&observer);
81 EXPECT_EQ(var.observer_list_.size(), 1);
82 var.RemoveObserver(&observer);
83 EXPECT_EQ(var.observer_list_.size(), 0);
84 var.RemoveObserver(&observer);
85 EXPECT_EQ(var.observer_list_.size(), 0);
86}
87
Alex Deymo63784a52014-05-28 10:46:14 -070088TEST(UmBaseVariableTest, NotifyValueChangedTest) {
Alex Deymoa07a1232014-02-25 14:19:50 -080089 DefaultVariable<int> var("var", kVariableModeAsync);
90 BaseVariableObserver observer1;
91 var.AddObserver(&observer1);
92 // Simulate a value change on the variable's implementation.
93 var.NotifyValueChanged();
Alex Deymo53556ec2014-03-17 10:05:57 -070094 ASSERT_EQ(0, observer1.calls_.size());
95 RunGMainLoopMaxIterations(100);
Alex Deymoa07a1232014-02-25 14:19:50 -080096
Alex Deymo53556ec2014-03-17 10:05:57 -070097 ASSERT_EQ(1, observer1.calls_.size());
Alex Deymoa07a1232014-02-25 14:19:50 -080098 // Check that the observer is called with the right argument.
Alex Deymo53556ec2014-03-17 10:05:57 -070099 EXPECT_EQ(&var, observer1.calls_[0]);
Alex Deymoa07a1232014-02-25 14:19:50 -0800100
101 BaseVariableObserver observer2;
102 var.AddObserver(&observer2);
103 var.NotifyValueChanged();
Alex Deymo53556ec2014-03-17 10:05:57 -0700104 RunGMainLoopMaxIterations(100);
Alex Deymoa07a1232014-02-25 14:19:50 -0800105
106 // Check that all the observers are called.
Alex Deymo53556ec2014-03-17 10:05:57 -0700107 EXPECT_EQ(2, observer1.calls_.size());
108 EXPECT_EQ(1, observer2.calls_.size());
Alex Deymoa5856e42014-03-31 18:01:36 -0700109
110 var.RemoveObserver(&observer1);
111 var.RemoveObserver(&observer2);
112}
113
114class BaseVariableObserverRemover : public BaseVariable::ObserverInterface {
115 public:
116 BaseVariableObserverRemover() : calls_(0) {}
117
118 void ValueChanged(BaseVariable* variable) override {
119 for (auto& observer : remove_observers_) {
120 variable->RemoveObserver(observer);
121 }
122 calls_++;
123 }
124
125 void OnCallRemoveObserver(BaseVariable::ObserverInterface* observer) {
126 remove_observers_.push_back(observer);
127 }
128
129 int get_calls() { return calls_; }
130
131 private:
132 vector<BaseVariable::ObserverInterface*> remove_observers_;
133 int calls_;
134};
135
136// Tests that we can remove an observer from a Variable on the ValueChanged()
137// call to that observer.
Alex Deymo63784a52014-05-28 10:46:14 -0700138TEST(UmBaseVariableTest, NotifyValueRemovesObserversTest) {
Alex Deymoa5856e42014-03-31 18:01:36 -0700139 DefaultVariable<int> var("var", kVariableModeAsync);
140 BaseVariableObserverRemover observer1;
141 BaseVariableObserverRemover observer2;
142
143 var.AddObserver(&observer1);
144 var.AddObserver(&observer2);
145
146 // Make each observer remove both observers on ValueChanged.
147 observer1.OnCallRemoveObserver(&observer1);
148 observer1.OnCallRemoveObserver(&observer2);
149 observer2.OnCallRemoveObserver(&observer1);
150 observer2.OnCallRemoveObserver(&observer2);
151
152 var.NotifyValueChanged();
153 RunGMainLoopMaxIterations(100);
154
155 EXPECT_EQ(1, observer1.get_calls() + observer2.get_calls());
Alex Deymoa07a1232014-02-25 14:19:50 -0800156}
157
Alex Deymo63784a52014-05-28 10:46:14 -0700158} // namespace chromeos_update_manager