Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2016 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 "fake_storage.h"
     18 
     19 #include <nvram/messages/blob.h>
     20 #include <nvram/messages/compiler.h>
     21 
     22 #define countof(a) (sizeof(a) / sizeof((a)[0]))
     23 
     24 namespace nvram {
     25 namespace storage {
     26 
     27 namespace {
     28 
     29 class StorageSlot {
     30  public:
     31   Status Load(Blob* blob) {
     32     if (read_error_) {
     33       return Status::kStorageError;
     34     }
     35 
     36     if (!present_) {
     37       return Status::kNotFound;
     38     }
     39 
     40     NVRAM_CHECK(blob->Assign(blob_.data(), blob_.size()));
     41     return Status::kSuccess;
     42   }
     43 
     44   Status Store(const Blob& blob) {
     45     if (write_error_) {
     46       return Status::kStorageError;
     47     }
     48 
     49     NVRAM_CHECK(blob_.Assign(blob.data(), blob.size()));
     50     present_ = true;
     51     return Status::kSuccess;
     52   }
     53 
     54   Status Delete() {
     55     if (write_error_) {
     56       return Status::kStorageError;
     57     }
     58 
     59     NVRAM_CHECK(blob_.Resize(0));
     60     present_ = false;
     61     return Status::kSuccess;
     62   }
     63 
     64   void Clear() {
     65     present_ = false;
     66     read_error_ = false;
     67     write_error_ = false;
     68     NVRAM_CHECK(blob_.Resize(0));
     69   }
     70 
     71   bool present() const { return present_; }
     72   void set_present(bool present) { present_ = present; }
     73   void set_read_error(bool error) { read_error_ = error; }
     74   void set_write_error(bool error) { write_error_ = error; }
     75 
     76  private:
     77   bool present_ = false;
     78   bool read_error_ = false;
     79   bool write_error_ = false;
     80   Blob blob_;
     81 };
     82 
     83 // Header storage.
     84 StorageSlot g_header;
     85 
     86 // Space blob storage.
     87 struct SpaceStorageSlot {
     88   uint32_t index;
     89   StorageSlot slot;
     90 };
     91 
     92 SpaceStorageSlot g_spaces[256];
     93 
     94 // Find the position in |g_spaces| corresponding to a given space |index|.
     95 // Returns the slot pointer or |nullptr| if not found.
     96 StorageSlot* FindSlotForIndex(uint32_t index) {
     97   for (size_t i = 0; i < countof(g_spaces); ++i) {
     98     if (g_spaces[i].slot.present() && g_spaces[i].index == index) {
     99       return &g_spaces[i].slot;
    100     }
    101   }
    102 
    103   return nullptr;
    104 }
    105 
    106 // Finds or creates the slot for |index|. Returns the slot pointer or |nullptr|
    107 // if not found.
    108 StorageSlot* FindOrCreateSlotForIndex(uint32_t index) {
    109   StorageSlot* slot = FindSlotForIndex(index);
    110   if (slot) {
    111     return slot;
    112   }
    113 
    114 
    115   for (size_t i = 0; i < countof(g_spaces); ++i) {
    116     if (!g_spaces[i].slot.present()) {
    117       g_spaces[i].index = index;
    118       return &g_spaces[i].slot;
    119     }
    120   }
    121 
    122   return nullptr;
    123 }
    124 
    125 }  // namespace
    126 
    127 Status LoadHeader(Blob* blob) {
    128   return g_header.Load(blob);
    129 }
    130 
    131 Status StoreHeader(const Blob& blob) {
    132   return g_header.Store(blob);
    133 }
    134 
    135 void SetHeaderReadError(bool error) {
    136   g_header.set_read_error(error);
    137 }
    138 
    139 void SetHeaderWriteError(bool error) {
    140   g_header.set_write_error(error);
    141 }
    142 
    143 Status LoadSpace(uint32_t index, Blob* blob) {
    144   StorageSlot* slot = FindSlotForIndex(index);
    145   return slot ? slot->Load(blob) : Status::kNotFound;
    146 }
    147 
    148 Status StoreSpace(uint32_t index, const Blob& blob) {
    149   StorageSlot* slot = FindOrCreateSlotForIndex(index);
    150   return slot ? slot->Store(blob) : Status::kStorageError;
    151 }
    152 
    153 Status DeleteSpace(uint32_t index) {
    154   StorageSlot* slot = FindSlotForIndex(index);
    155   return slot ? slot->Delete() : Status::kNotFound;
    156 }
    157 
    158 void Clear() {
    159   g_header.Clear();
    160   for (size_t i = 0; i < countof(g_spaces); ++i) {
    161     g_spaces[i].slot.Clear();
    162   }
    163 }
    164 
    165 void SetSpaceReadError(uint32_t index, bool error) {
    166   StorageSlot* slot = FindOrCreateSlotForIndex(index);
    167   if (slot) {
    168     slot->set_read_error(error);
    169   }
    170 }
    171 
    172 void SetSpaceWriteError(uint32_t index, bool error) {
    173   StorageSlot* slot = FindOrCreateSlotForIndex(index);
    174   if (slot) {
    175     slot->set_write_error(error);
    176   }
    177 }
    178 
    179 }  // namespace storage
    180 }  // namespace nvram
    181