• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
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 //
16 
17 #include "update_engine/common/fake_prefs.h"
18 
19 #include <algorithm>
20 #include <utility>
21 
22 #include <gtest/gtest.h>
23 
24 using std::string;
25 using std::vector;
26 
27 using chromeos_update_engine::FakePrefs;
28 
29 namespace {
30 
CheckNotNull(const string & key,void * ptr)31 void CheckNotNull(const string& key, void* ptr) {
32   EXPECT_NE(nullptr, ptr) << "Called Get*() for key \"" << key
33                           << "\" with a null parameter.";
34 }
35 
36 }  // namespace
37 
38 namespace chromeos_update_engine {
39 
~FakePrefs()40 FakePrefs::~FakePrefs() {
41   EXPECT_TRUE(observers_.empty());
42 }
43 
44 // Compile-time type-dependent constants definitions.
45 template <>
46 FakePrefs::PrefType const FakePrefs::PrefConsts<string>::type =
47     FakePrefs::PrefType::kString;
48 template <>
49 string FakePrefs::PrefValue::*const  // NOLINT(runtime/string), not static str.
50     FakePrefs::PrefConsts<string>::member = &FakePrefs::PrefValue::as_str;
51 
52 template <>
53 FakePrefs::PrefType const FakePrefs::PrefConsts<int64_t>::type =
54     FakePrefs::PrefType::kInt64;
55 template <>
56 int64_t FakePrefs::PrefValue::*const FakePrefs::PrefConsts<int64_t>::member =
57     &FakePrefs::PrefValue::as_int64;
58 
59 template <>
60 FakePrefs::PrefType const FakePrefs::PrefConsts<bool>::type =
61     FakePrefs::PrefType::kBool;
62 template <>
63 bool FakePrefs::PrefValue::*const FakePrefs::PrefConsts<bool>::member =
64     &FakePrefs::PrefValue::as_bool;
65 
GetString(const string & key,string * value) const66 bool FakePrefs::GetString(const string& key, string* value) const {
67   return GetValue(key, value);
68 }
69 
SetString(const string & key,std::string_view value)70 bool FakePrefs::SetString(const string& key, std::string_view value) {
71   SetValue(key, std::string(value));
72   return true;
73 }
74 
GetInt64(const string & key,int64_t * value) const75 bool FakePrefs::GetInt64(const string& key, int64_t* value) const {
76   return GetValue(key, value);
77 }
78 
SetInt64(const string & key,const int64_t value)79 bool FakePrefs::SetInt64(const string& key, const int64_t value) {
80   SetValue(key, value);
81   return true;
82 }
83 
GetBoolean(const string & key,bool * value) const84 bool FakePrefs::GetBoolean(const string& key, bool* value) const {
85   return GetValue(key, value);
86 }
87 
SetBoolean(const string & key,const bool value)88 bool FakePrefs::SetBoolean(const string& key, const bool value) {
89   SetValue(key, value);
90   return true;
91 }
92 
Exists(const string & key) const93 bool FakePrefs::Exists(const string& key) const {
94   return values_.find(key) != values_.end();
95 }
96 
Delete(const string & key)97 bool FakePrefs::Delete(const string& key) {
98   if (values_.find(key) == values_.end())
99     return false;
100   values_.erase(key);
101   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   }
107   return true;
108 }
109 
Delete(const string & key,const vector<string> & nss)110 bool FakePrefs::Delete(const string& key, const vector<string>& nss) {
111   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 
GetSubKeys(const string & ns,vector<string> * keys) const126 bool FakePrefs::GetSubKeys(const string& ns, vector<string>* keys) const {
127   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 
GetTypeName(PrefType type)133 string 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 
CheckKeyType(const string & key,PrefType type) const145 void FakePrefs::CheckKeyType(const string& key, PrefType type) const {
146   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 
152 template <typename T>
SetValue(const string & key,T value)153 void FakePrefs::SetValue(const string& key, T value) {
154   CheckKeyType(key, PrefConsts<T>::type);
155   values_[key].type = PrefConsts<T>::type;
156   values_[key].value.*(PrefConsts<T>::member) = std::move(value);
157   const auto observers_for_key = observers_.find(key);
158   if (observers_for_key != observers_.end()) {
159     std::vector<ObserverInterface*> copy_observers(observers_for_key->second);
160     for (ObserverInterface* observer : copy_observers)
161       observer->OnPrefSet(key);
162   }
163 }
164 
165 template <typename T>
GetValue(const string & key,T * value) const166 bool FakePrefs::GetValue(const string& key, T* value) const {
167   CheckKeyType(key, PrefConsts<T>::type);
168   auto it = values_.find(key);
169   if (it == values_.end())
170     return false;
171   CheckNotNull(key, value);
172   *value = it->second.value.*(PrefConsts<T>::member);
173   return true;
174 }
175 
AddObserver(const string & key,ObserverInterface * observer)176 void FakePrefs::AddObserver(const string& key, ObserverInterface* observer) {
177   observers_[key].push_back(observer);
178 }
179 
RemoveObserver(const string & key,ObserverInterface * observer)180 void FakePrefs::RemoveObserver(const string& key, ObserverInterface* observer) {
181   std::vector<ObserverInterface*>& observers_for_key = observers_[key];
182   auto observer_it =
183       std::find(observers_for_key.begin(), observers_for_key.end(), observer);
184   EXPECT_NE(observer_it, observers_for_key.end())
185       << "Trying to remove an observer instance not watching the key " << key;
186   if (observer_it != observers_for_key.end())
187     observers_for_key.erase(observer_it);
188   if (observers_for_key.empty())
189     observers_.erase(key);
190 }
191 
192 }  // namespace chromeos_update_engine
193