Home | History | Annotate | Download | only in common
      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 
     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 
     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 
     64 bool FakePrefs::GetString(const string& key, string* value) const {
     65   return GetValue(key, value);
     66 }
     67 
     68 bool FakePrefs::SetString(const string& key, const string& value) {
     69   SetValue(key, value);
     70   return true;
     71 }
     72 
     73 bool FakePrefs::GetInt64(const string& key, int64_t* value) const {
     74   return GetValue(key, value);
     75 }
     76 
     77 bool FakePrefs::SetInt64(const string& key, const int64_t value) {
     78   SetValue(key, value);
     79   return true;
     80 }
     81 
     82 bool FakePrefs::GetBoolean(const string& key, bool* value) const {
     83   return GetValue(key, value);
     84 }
     85 
     86 bool FakePrefs::SetBoolean(const string& key, const bool value) {
     87   SetValue(key, value);
     88   return true;
     89 }
     90 
     91 bool FakePrefs::Exists(const string& key) const {
     92   return values_.find(key) != values_.end();
     93 }
     94 
     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 
    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 
    120 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>
    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>
    141 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 
    151 void FakePrefs::AddObserver(const string& key, ObserverInterface* observer) {
    152   observers_[key].push_back(observer);
    153 }
    154 
    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