blob: 73559c522b73b79e46c7b9891958fad75905077f [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;
Jae Hoon Kim29a80e02020-05-11 20:18:49 -070024using std::vector;
Alex Deymo608a3652014-04-15 13:26:35 -070025
26using chromeos_update_engine::FakePrefs;
27
28namespace {
29
30void CheckNotNull(const string& key, void* ptr) {
Amin Hassanib2689592019-01-13 17:04:28 -080031 EXPECT_NE(nullptr, ptr) << "Called Get*() for key \"" << key
32 << "\" with a null parameter.";
Alex Deymo608a3652014-04-15 13:26:35 -070033}
34
35} // namespace
36
37namespace chromeos_update_engine {
38
Alex Deymod6f60072015-10-12 12:22:27 -070039FakePrefs::~FakePrefs() {
40 EXPECT_TRUE(observers_.empty());
41}
42
Alex Deymo608a3652014-04-15 13:26:35 -070043// Compile-time type-dependent constants definitions.
Amin Hassanib2689592019-01-13 17:04:28 -080044template <>
Alex Deymo608a3652014-04-15 13:26:35 -070045FakePrefs::PrefType const FakePrefs::PrefConsts<string>::type =
46 FakePrefs::PrefType::kString;
Amin Hassanib2689592019-01-13 17:04:28 -080047template <>
48string FakePrefs::PrefValue::*const // NOLINT(runtime/string), not static str.
Alex Vakulenkod2779df2014-06-16 13:19:00 -070049 FakePrefs::PrefConsts<string>::member = &FakePrefs::PrefValue::as_str;
Alex Deymo608a3652014-04-15 13:26:35 -070050
Amin Hassanib2689592019-01-13 17:04:28 -080051template <>
Alex Deymo608a3652014-04-15 13:26:35 -070052FakePrefs::PrefType const FakePrefs::PrefConsts<int64_t>::type =
53 FakePrefs::PrefType::kInt64;
Amin Hassanib2689592019-01-13 17:04:28 -080054template <>
55int64_t FakePrefs::PrefValue::*const FakePrefs::PrefConsts<int64_t>::member =
Alex Deymo608a3652014-04-15 13:26:35 -070056 &FakePrefs::PrefValue::as_int64;
57
Amin Hassanib2689592019-01-13 17:04:28 -080058template <>
Alex Deymo608a3652014-04-15 13:26:35 -070059FakePrefs::PrefType const FakePrefs::PrefConsts<bool>::type =
60 FakePrefs::PrefType::kBool;
Amin Hassanib2689592019-01-13 17:04:28 -080061template <>
62bool FakePrefs::PrefValue::*const FakePrefs::PrefConsts<bool>::member =
Alex Deymo608a3652014-04-15 13:26:35 -070063 &FakePrefs::PrefValue::as_bool;
64
Alex Deymod6f60072015-10-12 12:22:27 -070065bool FakePrefs::GetString(const string& key, string* value) const {
Alex Deymo608a3652014-04-15 13:26:35 -070066 return GetValue(key, value);
67}
68
Alex Deymof329b932014-10-30 01:37:48 -070069bool FakePrefs::SetString(const string& key, const string& value) {
Alex Deymo608a3652014-04-15 13:26:35 -070070 SetValue(key, value);
71 return true;
72}
73
Alex Deymod6f60072015-10-12 12:22:27 -070074bool FakePrefs::GetInt64(const string& key, int64_t* value) const {
Alex Deymo608a3652014-04-15 13:26:35 -070075 return GetValue(key, value);
76}
77
78bool FakePrefs::SetInt64(const string& key, const int64_t value) {
79 SetValue(key, value);
80 return true;
81}
82
Alex Deymod6f60072015-10-12 12:22:27 -070083bool FakePrefs::GetBoolean(const string& key, bool* value) const {
Alex Deymo608a3652014-04-15 13:26:35 -070084 return GetValue(key, value);
85}
86
87bool FakePrefs::SetBoolean(const string& key, const bool value) {
88 SetValue(key, value);
89 return true;
90}
91
Alex Deymod6f60072015-10-12 12:22:27 -070092bool FakePrefs::Exists(const string& key) const {
Alex Deymo608a3652014-04-15 13:26:35 -070093 return values_.find(key) != values_.end();
94}
95
96bool FakePrefs::Delete(const string& key) {
97 if (values_.find(key) == values_.end())
98 return false;
99 values_.erase(key);
Alex Deymod6f60072015-10-12 12:22:27 -0700100 const auto observers_for_key = observers_.find(key);
101 if (observers_for_key != observers_.end()) {
102 std::vector<ObserverInterface*> copy_observers(observers_for_key->second);
103 for (ObserverInterface* observer : copy_observers)
104 observer->OnPrefDeleted(key);
105 }
Alex Deymo608a3652014-04-15 13:26:35 -0700106 return true;
107}
108
Jae Hoon Kim29a80e02020-05-11 20:18:49 -0700109bool FakePrefs::GetSubKeys(const string& ns, vector<string>* keys) const {
110 for (const auto& pr : values_)
111 if (pr.first.compare(0, ns.length(), ns) == 0)
112 keys->push_back(pr.first);
113 return true;
114}
115
Alex Deymo608a3652014-04-15 13:26:35 -0700116string FakePrefs::GetTypeName(PrefType type) {
117 switch (type) {
118 case PrefType::kString:
119 return "string";
120 case PrefType::kInt64:
121 return "int64_t";
122 case PrefType::kBool:
123 return "bool";
124 }
125 return "Unknown";
126}
127
128void FakePrefs::CheckKeyType(const string& key, PrefType type) const {
129 auto it = values_.find(key);
130 EXPECT_TRUE(it == values_.end() || it->second.type == type)
131 << "Key \"" << key << "\" if defined as " << GetTypeName(it->second.type)
132 << " but is accessed as a " << GetTypeName(type);
133}
134
Amin Hassanib2689592019-01-13 17:04:28 -0800135template <typename T>
Alex Deymo608a3652014-04-15 13:26:35 -0700136void FakePrefs::SetValue(const string& key, const T& value) {
137 CheckKeyType(key, PrefConsts<T>::type);
138 values_[key].type = PrefConsts<T>::type;
139 values_[key].value.*(PrefConsts<T>::member) = value;
Alex Deymod6f60072015-10-12 12:22:27 -0700140 const auto observers_for_key = observers_.find(key);
141 if (observers_for_key != observers_.end()) {
142 std::vector<ObserverInterface*> copy_observers(observers_for_key->second);
143 for (ObserverInterface* observer : copy_observers)
144 observer->OnPrefSet(key);
145 }
Alex Deymo608a3652014-04-15 13:26:35 -0700146}
147
Amin Hassanib2689592019-01-13 17:04:28 -0800148template <typename T>
Alex Deymo608a3652014-04-15 13:26:35 -0700149bool FakePrefs::GetValue(const string& key, T* value) const {
150 CheckKeyType(key, PrefConsts<T>::type);
151 auto it = values_.find(key);
152 if (it == values_.end())
153 return false;
154 CheckNotNull(key, value);
155 *value = it->second.value.*(PrefConsts<T>::member);
156 return true;
157}
158
Alex Deymod6f60072015-10-12 12:22:27 -0700159void FakePrefs::AddObserver(const string& key, ObserverInterface* observer) {
160 observers_[key].push_back(observer);
161}
162
163void FakePrefs::RemoveObserver(const string& key, ObserverInterface* observer) {
164 std::vector<ObserverInterface*>& observers_for_key = observers_[key];
165 auto observer_it =
166 std::find(observers_for_key.begin(), observers_for_key.end(), observer);
167 EXPECT_NE(observer_it, observers_for_key.end())
Amin Hassanib2689592019-01-13 17:04:28 -0800168 << "Trying to remove an observer instance not watching the key " << key;
Alex Deymod6f60072015-10-12 12:22:27 -0700169 if (observer_it != observers_for_key.end())
170 observers_for_key.erase(observer_it);
171 if (observers_for_key.empty())
172 observers_.erase(key);
173}
174
Alex Deymo608a3652014-04-15 13:26:35 -0700175} // namespace chromeos_update_engine