Proper log initialization

This commit is contained in:
Pavel Kirienko
2015-05-03 20:10:45 +03:00
parent b1f5313fcb
commit a7dd5f9aea
3 changed files with 58 additions and 9 deletions
@@ -143,6 +143,8 @@ private:
int readEntryFromStorage(Index index, protocol::dynamic_node_id::server::Entry& out_entry);
int writeEntryToStorage(Index index, const protocol::dynamic_node_id::server::Entry& entry);
int initEmptyLogStorage();
public:
Log(IDynamicNodeIDStorageBackend& storage)
: storage_(storage)
@@ -224,9 +224,37 @@ int Log::writeEntryToStorage(Index index, const protocol::dynamic_node_id::serve
return (temp == entry) ? 0 : -ErrFailure;
}
int Log::initEmptyLogStorage()
{
MarshallingStorageDecorator io(storage_);
// Initializing last index
last_index_ = 0;
uint32_t stored_index = 0;
int res = io.setAndGetBack(getLastIndexKey(), stored_index);
if (res < 0)
{
return res;
}
if (stored_index != 0)
{
return -ErrFailure;
}
// Writing the zero entry - it must always be default-initialized
entries_[0] = protocol::dynamic_node_id::server::Entry();
res = writeEntryToStorage(0, entries_[0]);
if (res < 0)
{
return res;
}
return 0;
}
int Log::init()
{
const MarshallingStorageDecorator io(storage_);
MarshallingStorageDecorator io(storage_);
// Reading max index
{
@@ -235,10 +263,8 @@ int Log::init()
{
if (storage_.get(getLastIndexKey()).empty())
{
// It appears like there's no log in the storage - initializing empty log then
last_index_ = 0;
UAVCAN_TRACE("dynamic_node_id_server_impl::Log", "Initializing empty log");
return 0;
UAVCAN_TRACE("dynamic_node_id_server_impl::Log", "Initializing empty storage");
return initEmptyLogStorage();
}
else
{
@@ -253,7 +279,7 @@ int Log::init()
last_index_ = Index(value);
}
// Restoring log entries
// Restoring log entries - note that index 0 always exists
for (Index index = 0; index <= last_index_; index++)
{
const int result = readEntryFromStorage(index, entries_[index]);
@@ -9,10 +9,16 @@
class StorageBackend : public uavcan::IDynamicNodeIDStorageBackend
{
public:
typedef std::map<String, String> Container;
Container container_;
bool fail_;
public:
StorageBackend()
: fail_(false)
{ }
virtual String get(const String& key) const
{
const Container::const_iterator it = container_.find(key);
@@ -28,7 +34,13 @@ public:
container_[key] = value;
}
void printContainer() const
void failOnSetCalls(bool really) { fail_ = really; }
void reset() { container_.clear(); }
unsigned getNumKeys() const { return unsigned(container_.size()); }
void print() const
{
for (Container::const_iterator it = container_.begin(); it != container_.end(); ++it)
{
@@ -122,12 +134,16 @@ TEST(DynamicNodeIDAllocationServer, MarshallingStorageDecorator)
TEST(DynamicNodeIDAllocationServer, LogInitialization)
{
const unsigned NumEntriesInStorageWithEmptyLog = 4; // last index + 3 items per log entry
// No log data in the storage - initializing empty log
{
StorageBackend storage;
uavcan::dynamic_node_id_server_impl::Log log(storage);
ASSERT_EQ(0, storage.getNumKeys());
ASSERT_LE(0, log.init());
ASSERT_EQ(NumEntriesInStorageWithEmptyLog, storage.getNumKeys());
ASSERT_EQ(0, log.getLastIndex());
ASSERT_EQ(0, log.getEntryAtIndex(0)->term);
ASSERT_EQ(0, log.getEntryAtIndex(0)->node_id);
@@ -141,11 +157,13 @@ TEST(DynamicNodeIDAllocationServer, LogInitialization)
storage.set("log_last_index", "0");
ASSERT_LE(-uavcan::ErrFailure, log.init()); // Expected one entry, none found
ASSERT_EQ(1, storage.getNumKeys());
storage.set("log0_term", "0");
storage.set("log0_unique_id", "00000000000000000000000000000000");
storage.set("log0_node_id", "0");
ASSERT_LE(0, log.init()); // OK now
ASSERT_EQ(NumEntriesInStorageWithEmptyLog, storage.getNumKeys());
ASSERT_EQ(0, log.getLastIndex());
ASSERT_EQ(0, log.getEntryAtIndex(0)->term);
}
@@ -161,7 +179,8 @@ TEST(DynamicNodeIDAllocationServer, LogInitialization)
ASSERT_LE(-uavcan::ErrFailure, log.init()); // Bad value
storage.set("log_last_index", "0");
ASSERT_LE(-uavcan::ErrFailure, log.init()); // OK
ASSERT_LE(-uavcan::ErrFailure, log.init()); // No log items
ASSERT_EQ(1, storage.getNumKeys());
storage.set("log0_term", "0");
storage.set("log0_unique_id", "00000000000000000000000000000000");
@@ -169,6 +188,7 @@ TEST(DynamicNodeIDAllocationServer, LogInitialization)
ASSERT_LE(-uavcan::ErrFailure, log.init()); // Failed
ASSERT_EQ(0, log.getLastIndex());
ASSERT_EQ(0, log.getEntryAtIndex(0)->term);
ASSERT_EQ(4, storage.getNumKeys());
}
// Nonempty storage, many items
{
@@ -184,6 +204,7 @@ TEST(DynamicNodeIDAllocationServer, LogInitialization)
storage.set("log1_node_id", "127");
ASSERT_LE(0, log.init()); // OK now
ASSERT_EQ(7, storage.getNumKeys());
ASSERT_EQ(1, log.getLastIndex());
ASSERT_EQ(0, log.getEntryAtIndex(0)->term);