blob: c446e06298819b6be21d4a18068310a5b71bb306 [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 Deymo608a3652014-04-15 13:26:35 -070016
Alex Deymo39910dc2015-11-09 17:04:30 -080017#include "update_engine/common/fake_prefs.h"
Alex Deymo608a3652014-04-15 13:26:35 -070018
Alex Deymod6f60072015-10-12 12:22:27 -070019#include <algorithm>
20
Alex Deymo608a3652014-04-15 13:26:35 -070021#include <gtest/gtest.h>
22
Alex Deymo608a3652014-04-15 13:26:35 -070023using std::string;
24
25using chromeos_update_engine::FakePrefs;
26
27namespace {
28
29void CheckNotNull(const string& key, void* ptr) {
Amin Hassanib2689592019-01-13 17:04:28 -080030 EXPECT_NE(nullptr, ptr) << "Called Get*() for key \"" << key
31 << "\" with a null parameter.";
Alex Deymo608a3652014-04-15 13:26:35 -070032}
33
34} // namespace
35
36namespace chromeos_update_engine {
37
Alex Deymod6f60072015-10-12 12:22:27 -070038FakePrefs::~FakePrefs() {
39 EXPECT_TRUE(observers_.empty());
40}
41
Alex Deymo608a3652014-04-15 13:26:35 -070042// Compile-time type-dependent constants definitions.
Amin Hassanib2689592019-01-13 17:04:28 -080043template <>
Alex Deymo608a3652014-04-15 13:26:35 -070044FakePrefs::PrefType const FakePrefs::PrefConsts<string>::type =
45 FakePrefs::PrefType::kString;
Amin Hassanib2689592019-01-13 17:04:28 -080046template <>
47string FakePrefs::PrefValue::*const // NOLINT(runtime/string), not static str.
Alex Vakulenkod2779df2014-06-16 13:19:00 -070048 FakePrefs::PrefConsts<string>::member = &FakePrefs::PrefValue::as_str;
Alex Deymo608a3652014-04-15 13:26:35 -070049
Amin Hassanib2689592019-01-13 17:04:28 -080050template <>
Alex Deymo608a3652014-04-15 13:26:35 -070051FakePrefs::PrefType const FakePrefs::PrefConsts<int64_t>::type =
52 FakePrefs::PrefType::kInt64;
Amin Hassanib2689592019-01-13 17:04:28 -080053template <>
54int64_t FakePrefs::PrefValue::*const FakePrefs::PrefConsts<int64_t>::member =
Alex Deymo608a3652014-04-15 13:26:35 -070055 &FakePrefs::PrefValue::as_int64;
56
Amin Hassanib2689592019-01-13 17:04:28 -080057template <>
Alex Deymo608a3652014-04-15 13:26:35 -070058FakePrefs::PrefType const FakePrefs::PrefConsts<bool>::type =
59 FakePrefs::PrefType::kBool;
Amin Hassanib2689592019-01-13 17:04:28 -080060template <>
61bool FakePrefs::PrefValue::*const FakePrefs::PrefConsts<bool>::member =
Alex Deymo608a3652014-04-15 13:26:35 -070062 &FakePrefs::PrefValue::as_bool;
63
Alex Deymod6f60072015-10-12 12:22:27 -070064bool FakePrefs::GetString(const string& key, string* value) const {
Alex Deymo608a3652014-04-15 13:26:35 -070065 return GetValue(key, value);
66}
67
Alex Deymof329b932014-10-30 01:37:48 -070068bool FakePrefs::SetString(const string& key, const string& value) {
Alex Deymo608a3652014-04-15 13:26:35 -070069 SetValue(key, value);
70 return true;
71}
72
Alex Deymod6f60072015-10-12 12:22:27 -070073bool FakePrefs::GetInt64(const string& key, int64_t* value) const {
Alex Deymo608a3652014-04-15 13:26:35 -070074 return GetValue(key, value);
75}
76
77bool FakePrefs::SetInt64(const string& key, const int64_t value) {
78 SetValue(key, value);
79 return true;
80}
81
Alex Deymod6f60072015-10-12 12:22:27 -070082bool FakePrefs::GetBoolean(const string& key, bool* value) const {
Alex Deymo608a3652014-04-15 13:26:35 -070083 return GetValue(key, value);
84}
85
86bool FakePrefs::SetBoolean(const string& key, const bool value) {
87 SetValue(key, value);
88 return true;
89}
90
Alex Deymod6f60072015-10-12 12:22:27 -070091bool FakePrefs::Exists(const string& key) const {
Alex Deymo608a3652014-04-15 13:26:35 -070092 return values_.find(key) != values_.end();
93}
94
95bool FakePrefs::Delete(const string& key) {
96 if (values_.find(key) == values_.end())
97 return false;
98 values_.erase(key);
Alex Deymod6f60072015-10-12 12:22:27 -070099 const auto observers_for_key = observers_.find(key);
100 if (observers_for_key != observers_.end()) {
101 std::vector<ObserverInterface*> copy_observers(observers_for_key->second);
102 for (ObserverInterface* observer : copy_observers)
103 observer->OnPrefDeleted(key);
104 }
Alex Deymo608a3652014-04-15 13:26:35 -0700105 return true;
106}
107
108string FakePrefs::GetTypeName(PrefType type) {
109 switch (type) {
110 case PrefType::kString:
111 return "string";
112 case PrefType::kInt64:
113 return "int64_t";
114 case PrefType::kBool:
115 return "bool";
116 }
117 return "Unknown";
118}
119
120void FakePrefs::CheckKeyType(const string& key, PrefType type) const {
121 auto it = values_.find(key);
122 EXPECT_TRUE(it == values_.end() || it->second.type == type)
123 << "Key \"" << key << "\" if defined as " << GetTypeName(it->second.type)
124 << " but is accessed as a " << GetTypeName(type);
125}
126
Amin Hassanib2689592019-01-13 17:04:28 -0800127template <typename T>
Alex Deymo608a3652014-04-15 13:26:35 -0700128void FakePrefs::SetValue(const string& key, const T& value) {
129 CheckKeyType(key, PrefConsts<T>::type);
130 values_[key].type = PrefConsts<T>::type;
131 values_[key].value.*(PrefConsts<T>::member) = value;
Alex Deymod6f60072015-10-12 12:22:27 -0700132 const auto observers_for_key = observers_.find(key);
133 if (observers_for_key != observers_.end()) {
134 std::vector<ObserverInterface*> copy_observers(observers_for_key->second);
135 for (ObserverInterface* observer : copy_observers)
136 observer->OnPrefSet(key);
137 }
Alex Deymo608a3652014-04-15 13:26:35 -0700138}
139
Amin Hassanib2689592019-01-13 17:04:28 -0800140template <typename T>
Alex Deymo608a3652014-04-15 13:26:35 -0700141bool FakePrefs::GetValue(const string& key, T* value) const {
142 CheckKeyType(key, PrefConsts<T>::type);
143 auto it = values_.find(key);
144 if (it == values_.end())
145 return false;
146 CheckNotNull(key, value);
147 *value = it->second.value.*(PrefConsts<T>::member);
148 return true;
149}
150
Alex Deymod6f60072015-10-12 12:22:27 -0700151void FakePrefs::AddObserver(const string& key, ObserverInterface* observer) {
152 observers_[key].push_back(observer);
153}
154
155void FakePrefs::RemoveObserver(const string& key, ObserverInterface* observer) {
156 std::vector<ObserverInterface*>& observers_for_key = observers_[key];
157 auto observer_it =
158 std::find(observers_for_key.begin(), observers_for_key.end(), observer);
159 EXPECT_NE(observer_it, observers_for_key.end())
Amin Hassanib2689592019-01-13 17:04:28 -0800160 << "Trying to remove an observer instance not watching the key " << key;
Alex Deymod6f60072015-10-12 12:22:27 -0700161 if (observer_it != observers_for_key.end())
162 observers_for_key.erase(observer_it);
163 if (observers_for_key.empty())
164 observers_.erase(key);
165}
166
Alex Deymo608a3652014-04-15 13:26:35 -0700167} // namespace chromeos_update_engine