1aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 2aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Copyright (C) 2014 The Android Open Source Project 3aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 4aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License"); 5aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// you may not use this file except in compliance with the License. 6aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// You may obtain a copy of the License at 7aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 8aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// http://www.apache.org/licenses/LICENSE-2.0 9aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 10aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// Unless required by applicable law or agreed to in writing, software 11aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS, 12aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// See the License for the specific language governing permissions and 14aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// limitations under the License. 15aea4c1cea20dda7ae7e85fc8924a2d784f70d806Alex Deymo// 16608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 1739910dcd1d68987ccee7c3031dc269233a8490bbAlex Deymo#include "update_engine/common/fake_prefs.h" 18608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 19d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo#include <algorithm> 20d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo 21608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo#include <gtest/gtest.h> 22608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 23608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymousing std::string; 24608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 25608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymousing chromeos_update_engine::FakePrefs; 26608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 27608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymonamespace { 28608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 29608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymovoid CheckNotNull(const string& key, void* ptr) { 30608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo EXPECT_NE(nullptr, ptr) 3188b591f24cb3f94f982d7024c2e8ed25c2cc26a2Alex Vakulenko << "Called Get*() for key \"" << key << "\" with a null parameter."; 32608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo} 33608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 34608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo} // namespace 35608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 36608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymonamespace chromeos_update_engine { 37608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 38d6f60079258fa385b583dac9e770afd2ea3c9aebAlex DeymoFakePrefs::~FakePrefs() { 39d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo EXPECT_TRUE(observers_.empty()); 40d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo} 41d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo 42608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo// Compile-time type-dependent constants definitions. 43608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymotemplate<> 44608a36586dd4a990b63b0e7a195bfef191db5c69Alex DeymoFakePrefs::PrefType const FakePrefs::PrefConsts<string>::type = 45608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo FakePrefs::PrefType::kString; 46608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymotemplate<> 47d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenkostring FakePrefs::PrefValue::* const // NOLINT(runtime/string), not static str. 48d2779df63aaad8b65fc5d4badee7dbc9bed7f2b6Alex Vakulenko FakePrefs::PrefConsts<string>::member = &FakePrefs::PrefValue::as_str; 49608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 50608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymotemplate<> 51608a36586dd4a990b63b0e7a195bfef191db5c69Alex DeymoFakePrefs::PrefType const FakePrefs::PrefConsts<int64_t>::type = 52608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo FakePrefs::PrefType::kInt64; 53608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymotemplate<> 54608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymoint64_t FakePrefs::PrefValue::* const FakePrefs::PrefConsts<int64_t>::member = 55608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo &FakePrefs::PrefValue::as_int64; 56608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 57608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymotemplate<> 58608a36586dd4a990b63b0e7a195bfef191db5c69Alex DeymoFakePrefs::PrefType const FakePrefs::PrefConsts<bool>::type = 59608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo FakePrefs::PrefType::kBool; 60608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymotemplate<> 61608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymobool FakePrefs::PrefValue::* const FakePrefs::PrefConsts<bool>::member = 62608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo &FakePrefs::PrefValue::as_bool; 63608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 64d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymobool FakePrefs::GetString(const string& key, string* value) const { 65608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo return GetValue(key, value); 66608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo} 67608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 68f329b933db41d26644a97afef928eb1b319d6d99Alex Deymobool FakePrefs::SetString(const string& key, const string& value) { 69608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo SetValue(key, value); 70608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo return true; 71608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo} 72608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 73d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymobool FakePrefs::GetInt64(const string& key, int64_t* value) const { 74608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo return GetValue(key, value); 75608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo} 76608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 77608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymobool FakePrefs::SetInt64(const string& key, const int64_t value) { 78608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo SetValue(key, value); 79608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo return true; 80608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo} 81608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 82d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymobool FakePrefs::GetBoolean(const string& key, bool* value) const { 83608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo return GetValue(key, value); 84608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo} 85608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 86608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymobool FakePrefs::SetBoolean(const string& key, const bool value) { 87608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo SetValue(key, value); 88608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo return true; 89608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo} 90608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 91d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymobool FakePrefs::Exists(const string& key) const { 92608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo return values_.find(key) != values_.end(); 93608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo} 94608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 95608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymobool FakePrefs::Delete(const string& key) { 96608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo if (values_.find(key) == values_.end()) 97608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo return false; 98608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo values_.erase(key); 99d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo const auto observers_for_key = observers_.find(key); 100d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo if (observers_for_key != observers_.end()) { 101d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo std::vector<ObserverInterface*> copy_observers(observers_for_key->second); 102d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo for (ObserverInterface* observer : copy_observers) 103d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo observer->OnPrefDeleted(key); 104d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo } 105608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo return true; 106608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo} 107608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 108608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymostring FakePrefs::GetTypeName(PrefType type) { 109608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo switch (type) { 110608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo case PrefType::kString: 111608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo return "string"; 112608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo case PrefType::kInt64: 113608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo return "int64_t"; 114608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo case PrefType::kBool: 115608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo return "bool"; 116608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo } 117608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo return "Unknown"; 118608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo} 119608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 120608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymovoid FakePrefs::CheckKeyType(const string& key, PrefType type) const { 121608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo auto it = values_.find(key); 122608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo EXPECT_TRUE(it == values_.end() || it->second.type == type) 123608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo << "Key \"" << key << "\" if defined as " << GetTypeName(it->second.type) 124608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo << " but is accessed as a " << GetTypeName(type); 125608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo} 126608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 127608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymotemplate<typename T> 128608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymovoid FakePrefs::SetValue(const string& key, const T& value) { 129608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo CheckKeyType(key, PrefConsts<T>::type); 130608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo values_[key].type = PrefConsts<T>::type; 131608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo values_[key].value.*(PrefConsts<T>::member) = value; 132d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo const auto observers_for_key = observers_.find(key); 133d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo if (observers_for_key != observers_.end()) { 134d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo std::vector<ObserverInterface*> copy_observers(observers_for_key->second); 135d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo for (ObserverInterface* observer : copy_observers) 136d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo observer->OnPrefSet(key); 137d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo } 138608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo} 139608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 140608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymotemplate<typename T> 141608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymobool FakePrefs::GetValue(const string& key, T* value) const { 142608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo CheckKeyType(key, PrefConsts<T>::type); 143608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo auto it = values_.find(key); 144608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo if (it == values_.end()) 145608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo return false; 146608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo CheckNotNull(key, value); 147608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo *value = it->second.value.*(PrefConsts<T>::member); 148608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo return true; 149608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo} 150608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo 151d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymovoid FakePrefs::AddObserver(const string& key, ObserverInterface* observer) { 152d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo observers_[key].push_back(observer); 153d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo} 154d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo 155d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymovoid FakePrefs::RemoveObserver(const string& key, ObserverInterface* observer) { 156d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo std::vector<ObserverInterface*>& observers_for_key = observers_[key]; 157d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo auto observer_it = 158d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo std::find(observers_for_key.begin(), observers_for_key.end(), observer); 159d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo EXPECT_NE(observer_it, observers_for_key.end()) 160d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo << "Trying to remove an observer instance not watching the key " 161d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo << key; 162d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo if (observer_it != observers_for_key.end()) 163d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo observers_for_key.erase(observer_it); 164d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo if (observers_for_key.empty()) 165d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo observers_.erase(key); 166d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo} 167d6f60079258fa385b583dac9e770afd2ea3c9aebAlex Deymo 168608a36586dd4a990b63b0e7a195bfef191db5c69Alex Deymo} // namespace chromeos_update_engine 169