blob: e87e0ec2df5be8289027526f2fa398f193c868d6 [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>
Kelvin Zhangcf4600e2020-10-27 15:50:33 -040020#include <utility>
Alex Deymod6f60072015-10-12 12:22:27 -070021
Alex Deymo608a3652014-04-15 13:26:35 -070022#include <gtest/gtest.h>
23
Alex Deymo608a3652014-04-15 13:26:35 -070024using std::string;
Jae Hoon Kim29a80e02020-05-11 20:18:49 -070025using std::vector;
Alex Deymo608a3652014-04-15 13:26:35 -070026
27using chromeos_update_engine::FakePrefs;
28
29namespace {
30
Kelvin Zhang1c86a922021-05-13 10:30:48 -040031void CheckNotNull(std::string_view key, void* ptr) {
Amin Hassanib2689592019-01-13 17:04:28 -080032 EXPECT_NE(nullptr, ptr) << "Called Get*() for key \"" << key
33 << "\" with a null parameter.";
Alex Deymo608a3652014-04-15 13:26:35 -070034}
35
36} // namespace
37
38namespace chromeos_update_engine {
39
Alex Deymod6f60072015-10-12 12:22:27 -070040FakePrefs::~FakePrefs() {
41 EXPECT_TRUE(observers_.empty());
42}
43
Alex Deymo608a3652014-04-15 13:26:35 -070044// Compile-time type-dependent constants definitions.
Amin Hassanib2689592019-01-13 17:04:28 -080045template <>
Alex Deymo608a3652014-04-15 13:26:35 -070046FakePrefs::PrefType const FakePrefs::PrefConsts<string>::type =
47 FakePrefs::PrefType::kString;
Amin Hassanib2689592019-01-13 17:04:28 -080048template <>
49string FakePrefs::PrefValue::*const // NOLINT(runtime/string), not static str.
Alex Vakulenkod2779df2014-06-16 13:19:00 -070050 FakePrefs::PrefConsts<string>::member = &FakePrefs::PrefValue::as_str;
Alex Deymo608a3652014-04-15 13:26:35 -070051
Amin Hassanib2689592019-01-13 17:04:28 -080052template <>
Alex Deymo608a3652014-04-15 13:26:35 -070053FakePrefs::PrefType const FakePrefs::PrefConsts<int64_t>::type =
54 FakePrefs::PrefType::kInt64;
Amin Hassanib2689592019-01-13 17:04:28 -080055template <>
56int64_t FakePrefs::PrefValue::*const FakePrefs::PrefConsts<int64_t>::member =
Alex Deymo608a3652014-04-15 13:26:35 -070057 &FakePrefs::PrefValue::as_int64;
58
Amin Hassanib2689592019-01-13 17:04:28 -080059template <>
Alex Deymo608a3652014-04-15 13:26:35 -070060FakePrefs::PrefType const FakePrefs::PrefConsts<bool>::type =
61 FakePrefs::PrefType::kBool;
Amin Hassanib2689592019-01-13 17:04:28 -080062template <>
63bool FakePrefs::PrefValue::*const FakePrefs::PrefConsts<bool>::member =
Alex Deymo608a3652014-04-15 13:26:35 -070064 &FakePrefs::PrefValue::as_bool;
65
Kelvin Zhang1c86a922021-05-13 10:30:48 -040066bool FakePrefs::GetString(std::string_view key, string* value) const {
Alex Deymo608a3652014-04-15 13:26:35 -070067 return GetValue(key, value);
68}
69
Kelvin Zhang1c86a922021-05-13 10:30:48 -040070bool FakePrefs::SetString(std::string_view key, std::string_view value) {
Kelvin Zhangcf4600e2020-10-27 15:50:33 -040071 SetValue(key, std::string(value));
Alex Deymo608a3652014-04-15 13:26:35 -070072 return true;
73}
74
Kelvin Zhang1c86a922021-05-13 10:30:48 -040075bool FakePrefs::GetInt64(std::string_view key, int64_t* value) const {
Alex Deymo608a3652014-04-15 13:26:35 -070076 return GetValue(key, value);
77}
78
Kelvin Zhang1c86a922021-05-13 10:30:48 -040079bool FakePrefs::SetInt64(std::string_view key, const int64_t value) {
Alex Deymo608a3652014-04-15 13:26:35 -070080 SetValue(key, value);
81 return true;
82}
83
Kelvin Zhang1c86a922021-05-13 10:30:48 -040084bool FakePrefs::GetBoolean(std::string_view key, bool* value) const {
Alex Deymo608a3652014-04-15 13:26:35 -070085 return GetValue(key, value);
86}
87
Kelvin Zhang1c86a922021-05-13 10:30:48 -040088bool FakePrefs::SetBoolean(std::string_view key, const bool value) {
Alex Deymo608a3652014-04-15 13:26:35 -070089 SetValue(key, value);
90 return true;
91}
92
Kelvin Zhang1c86a922021-05-13 10:30:48 -040093bool FakePrefs::Exists(std::string_view key) const {
Alex Deymo608a3652014-04-15 13:26:35 -070094 return values_.find(key) != values_.end();
95}
96
Kelvin Zhang1c86a922021-05-13 10:30:48 -040097bool FakePrefs::Delete(std::string_view key) {
Alex Deymo608a3652014-04-15 13:26:35 -070098 if (values_.find(key) == values_.end())
99 return false;
Kelvin Zhang1c86a922021-05-13 10:30:48 -0400100 values_.erase(std::string{key});
Alex Deymod6f60072015-10-12 12:22:27 -0700101 const auto observers_for_key = observers_.find(key);
102 if (observers_for_key != observers_.end()) {
103 std::vector<ObserverInterface*> copy_observers(observers_for_key->second);
104 for (ObserverInterface* observer : copy_observers)
105 observer->OnPrefDeleted(key);
106 }
Alex Deymo608a3652014-04-15 13:26:35 -0700107 return true;
108}
109
Kelvin Zhang1c86a922021-05-13 10:30:48 -0400110bool FakePrefs::Delete(std::string_view key, const vector<string>& nss) {
Vyshu Khota4c5413d2020-11-04 16:17:25 -0800111 bool success = Delete(key);
112 for (const auto& ns : nss) {
113 vector<string> ns_keys;
114 success = GetSubKeys(ns, &ns_keys) && success;
115 for (const auto& sub_key : ns_keys) {
116 auto last_key_seperator = sub_key.find_last_of(kKeySeparator);
117 if (last_key_seperator != string::npos &&
118 key == sub_key.substr(last_key_seperator + 1)) {
119 success = Delete(sub_key) && success;
120 }
121 }
122 }
123 return success;
124}
125
Kelvin Zhang1c86a922021-05-13 10:30:48 -0400126bool FakePrefs::GetSubKeys(std::string_view ns, vector<string>* keys) const {
Jae Hoon Kim29a80e02020-05-11 20:18:49 -0700127 for (const auto& pr : values_)
128 if (pr.first.compare(0, ns.length(), ns) == 0)
129 keys->push_back(pr.first);
130 return true;
131}
132
Alex Deymo608a3652014-04-15 13:26:35 -0700133string FakePrefs::GetTypeName(PrefType type) {
134 switch (type) {
135 case PrefType::kString:
136 return "string";
137 case PrefType::kInt64:
138 return "int64_t";
139 case PrefType::kBool:
140 return "bool";
141 }
142 return "Unknown";
143}
144
Kelvin Zhang1c86a922021-05-13 10:30:48 -0400145void FakePrefs::CheckKeyType(std::string_view key, PrefType type) const {
Alex Deymo608a3652014-04-15 13:26:35 -0700146 auto it = values_.find(key);
147 EXPECT_TRUE(it == values_.end() || it->second.type == type)
148 << "Key \"" << key << "\" if defined as " << GetTypeName(it->second.type)
149 << " but is accessed as a " << GetTypeName(type);
150}
151
Amin Hassanib2689592019-01-13 17:04:28 -0800152template <typename T>
Kelvin Zhang1c86a922021-05-13 10:30:48 -0400153void FakePrefs::SetValue(std::string_view key, T value) {
154 std::string str_key{key};
Alex Deymo608a3652014-04-15 13:26:35 -0700155 CheckKeyType(key, PrefConsts<T>::type);
Kelvin Zhang1c86a922021-05-13 10:30:48 -0400156 values_[str_key].type = PrefConsts<T>::type;
157 values_[str_key].value.*(PrefConsts<T>::member) = std::move(value);
Alex Deymod6f60072015-10-12 12:22:27 -0700158 const auto observers_for_key = observers_.find(key);
159 if (observers_for_key != observers_.end()) {
160 std::vector<ObserverInterface*> copy_observers(observers_for_key->second);
161 for (ObserverInterface* observer : copy_observers)
162 observer->OnPrefSet(key);
163 }
Alex Deymo608a3652014-04-15 13:26:35 -0700164}
165
Amin Hassanib2689592019-01-13 17:04:28 -0800166template <typename T>
Kelvin Zhang1c86a922021-05-13 10:30:48 -0400167bool FakePrefs::GetValue(std::string_view key, T* value) const {
Alex Deymo608a3652014-04-15 13:26:35 -0700168 CheckKeyType(key, PrefConsts<T>::type);
169 auto it = values_.find(key);
170 if (it == values_.end())
171 return false;
172 CheckNotNull(key, value);
173 *value = it->second.value.*(PrefConsts<T>::member);
174 return true;
175}
176
Kelvin Zhang1c86a922021-05-13 10:30:48 -0400177void FakePrefs::AddObserver(std::string_view key, ObserverInterface* observer) {
178 observers_[string{key}].push_back(observer);
Alex Deymod6f60072015-10-12 12:22:27 -0700179}
180
Kelvin Zhang1c86a922021-05-13 10:30:48 -0400181void FakePrefs::RemoveObserver(std::string_view key,
182 ObserverInterface* observer) {
183 string str_key{key};
184 std::vector<ObserverInterface*>& observers_for_key = observers_[str_key];
Alex Deymod6f60072015-10-12 12:22:27 -0700185 auto observer_it =
186 std::find(observers_for_key.begin(), observers_for_key.end(), observer);
187 EXPECT_NE(observer_it, observers_for_key.end())
Amin Hassanib2689592019-01-13 17:04:28 -0800188 << "Trying to remove an observer instance not watching the key " << key;
Alex Deymod6f60072015-10-12 12:22:27 -0700189 if (observer_it != observers_for_key.end())
190 observers_for_key.erase(observer_it);
191 if (observers_for_key.empty())
Kelvin Zhang1c86a922021-05-13 10:30:48 -0400192 observers_.erase(str_key);
Alex Deymod6f60072015-10-12 12:22:27 -0700193}
194
Alex Deymo608a3652014-04-15 13:26:35 -0700195} // namespace chromeos_update_engine