blob: 275667e3cf7c9844ec5e212ff61c5f7c2bd94791 [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
Vyshu Khota4c5413d2020-11-04 16:17:25 -0800109bool FakePrefs::Delete(const string& key, const vector<string>& nss) {
110 bool success = Delete(key);
111 for (const auto& ns : nss) {
112 vector<string> ns_keys;
113 success = GetSubKeys(ns, &ns_keys) && success;
114 for (const auto& sub_key : ns_keys) {
115 auto last_key_seperator = sub_key.find_last_of(kKeySeparator);
116 if (last_key_seperator != string::npos &&
117 key == sub_key.substr(last_key_seperator + 1)) {
118 success = Delete(sub_key) && success;
119 }
120 }
121 }
122 return success;
123}
124
Jae Hoon Kim29a80e02020-05-11 20:18:49 -0700125bool FakePrefs::GetSubKeys(const string& ns, vector<string>* keys) const {
126 for (const auto& pr : values_)
127 if (pr.first.compare(0, ns.length(), ns) == 0)
128 keys->push_back(pr.first);
129 return true;
130}
131
Alex Deymo608a3652014-04-15 13:26:35 -0700132string FakePrefs::GetTypeName(PrefType type) {
133 switch (type) {
134 case PrefType::kString:
135 return "string";
136 case PrefType::kInt64:
137 return "int64_t";
138 case PrefType::kBool:
139 return "bool";
140 }
141 return "Unknown";
142}
143
144void FakePrefs::CheckKeyType(const string& key, PrefType type) const {
145 auto it = values_.find(key);
146 EXPECT_TRUE(it == values_.end() || it->second.type == type)
147 << "Key \"" << key << "\" if defined as " << GetTypeName(it->second.type)
148 << " but is accessed as a " << GetTypeName(type);
149}
150
Amin Hassanib2689592019-01-13 17:04:28 -0800151template <typename T>
Alex Deymo608a3652014-04-15 13:26:35 -0700152void FakePrefs::SetValue(const string& key, const T& value) {
153 CheckKeyType(key, PrefConsts<T>::type);
154 values_[key].type = PrefConsts<T>::type;
155 values_[key].value.*(PrefConsts<T>::member) = value;
Alex Deymod6f60072015-10-12 12:22:27 -0700156 const auto observers_for_key = observers_.find(key);
157 if (observers_for_key != observers_.end()) {
158 std::vector<ObserverInterface*> copy_observers(observers_for_key->second);
159 for (ObserverInterface* observer : copy_observers)
160 observer->OnPrefSet(key);
161 }
Alex Deymo608a3652014-04-15 13:26:35 -0700162}
163
Amin Hassanib2689592019-01-13 17:04:28 -0800164template <typename T>
Alex Deymo608a3652014-04-15 13:26:35 -0700165bool FakePrefs::GetValue(const string& key, T* value) const {
166 CheckKeyType(key, PrefConsts<T>::type);
167 auto it = values_.find(key);
168 if (it == values_.end())
169 return false;
170 CheckNotNull(key, value);
171 *value = it->second.value.*(PrefConsts<T>::member);
172 return true;
173}
174
Alex Deymod6f60072015-10-12 12:22:27 -0700175void FakePrefs::AddObserver(const string& key, ObserverInterface* observer) {
176 observers_[key].push_back(observer);
177}
178
179void FakePrefs::RemoveObserver(const string& key, ObserverInterface* observer) {
180 std::vector<ObserverInterface*>& observers_for_key = observers_[key];
181 auto observer_it =
182 std::find(observers_for_key.begin(), observers_for_key.end(), observer);
183 EXPECT_NE(observer_it, observers_for_key.end())
Amin Hassanib2689592019-01-13 17:04:28 -0800184 << "Trying to remove an observer instance not watching the key " << key;
Alex Deymod6f60072015-10-12 12:22:27 -0700185 if (observer_it != observers_for_key.end())
186 observers_for_key.erase(observer_it);
187 if (observers_for_key.empty())
188 observers_.erase(key);
189}
190
Alex Deymo608a3652014-04-15 13:26:35 -0700191} // namespace chromeos_update_engine