• 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 
21 #include <gtest/gtest.h>
22 
23 using std::string;
24 
25 using chromeos_update_engine::FakePrefs;
26 
27 namespace {
28 
CheckNotNull(const string & key,void * ptr)29 void CheckNotNull(const string& key, void* ptr) {
30   EXPECT_NE(nullptr, ptr)
31       << "Called Get*() for key \"" << key << "\" with a null parameter.";
32 }
33 
34 }  // namespace
35 
36 namespace chromeos_update_engine {
37 
~FakePrefs()38 FakePrefs::~FakePrefs() {
39   EXPECT_TRUE(observers_.empty());
40 }
41 
42 // Compile-time type-dependent constants definitions.
43 template<>
44 FakePrefs::PrefType const FakePrefs::PrefConsts<string>::type =
45     FakePrefs::PrefType::kString;
46 template<>
47 string FakePrefs::PrefValue::* const  // NOLINT(runtime/string), not static str.
48     FakePrefs::PrefConsts<string>::member = &FakePrefs::PrefValue::as_str;
49 
50 template<>
51 FakePrefs::PrefType const FakePrefs::PrefConsts<int64_t>::type =
52     FakePrefs::PrefType::kInt64;
53 template<>
54 int64_t FakePrefs::PrefValue::* const FakePrefs::PrefConsts<int64_t>::member =
55     &FakePrefs::PrefValue::as_int64;
56 
57 template<>
58 FakePrefs::PrefType const FakePrefs::PrefConsts<bool>::type =
59     FakePrefs::PrefType::kBool;
60 template<>
61 bool FakePrefs::PrefValue::* const FakePrefs::PrefConsts<bool>::member =
62     &FakePrefs::PrefValue::as_bool;
63 
GetString(const string & key,string * value) const64 bool FakePrefs::GetString(const string& key, string* value) const {
65   return GetValue(key, value);
66 }
67 
SetString(const string & key,const string & value)68 bool FakePrefs::SetString(const string& key, const string& value) {
69   SetValue(key, value);
70   return true;
71 }
72 
GetInt64(const string & key,int64_t * value) const73 bool FakePrefs::GetInt64(const string& key, int64_t* value) const {
74   return GetValue(key, value);
75 }
76 
SetInt64(const string & key,const int64_t value)77 bool FakePrefs::SetInt64(const string& key, const int64_t value) {
78   SetValue(key, value);
79   return true;
80 }
81 
GetBoolean(const string & key,bool * value) const82 bool FakePrefs::GetBoolean(const string& key, bool* value) const {
83   return GetValue(key, value);
84 }
85 
SetBoolean(const string & key,const bool value)86 bool FakePrefs::SetBoolean(const string& key, const bool value) {
87   SetValue(key, value);
88   return true;
89 }
90 
Exists(const string & key) const91 bool FakePrefs::Exists(const string& key) const {
92   return values_.find(key) != values_.end();
93 }
94 
Delete(const string & key)95 bool FakePrefs::Delete(const string& key) {
96   if (values_.find(key) == values_.end())
97     return false;
98   values_.erase(key);
99   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   }
105   return true;
106 }
107 
GetTypeName(PrefType type)108 string 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 
CheckKeyType(const string & key,PrefType type) const120 void 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 
127 template<typename T>
SetValue(const string & key,const T & value)128 void 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;
132   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   }
138 }
139 
140 template<typename T>
GetValue(const string & key,T * value) const141 bool 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 
AddObserver(const string & key,ObserverInterface * observer)151 void FakePrefs::AddObserver(const string& key, ObserverInterface* observer) {
152   observers_[key].push_back(observer);
153 }
154 
RemoveObserver(const string & key,ObserverInterface * observer)155 void 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())
160       << "Trying to remove an observer instance not watching the key "
161       << key;
162   if (observer_it != observers_for_key.end())
163     observers_for_key.erase(observer_it);
164   if (observers_for_key.empty())
165     observers_.erase(key);
166 }
167 
168 }  // namespace chromeos_update_engine
169