libuav original

Dependents:   UAVCAN UAVCAN_Subscriber

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers persistent_state.cpp Source File

persistent_state.cpp

00001 /*
00002  * Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com>
00003  */
00004 
00005 #include <gtest/gtest.h>
00006 #include <uavcan/protocol/dynamic_node_id_server/distributed/persistent_state.hpp>
00007 #include "../event_tracer.hpp"
00008 #include "../memory_storage_backend.hpp"
00009 
00010 
00011 TEST(dynamic_node_id_server_PersistentState, Initialization)
00012 {
00013     using namespace uavcan::dynamic_node_id_server::distributed;
00014 
00015     EventTracer tracer;
00016     /*
00017      * First initialization
00018      */
00019     {
00020         MemoryStorageBackend storage;
00021         PersistentState pers(storage, tracer);
00022 
00023         ASSERT_EQ(0, storage.getNumKeys());
00024         ASSERT_LE(0, pers.init());
00025 
00026         ASSERT_LE(3, storage.getNumKeys());
00027         ASSERT_EQ("0", storage.get("log_last_index"));
00028         ASSERT_EQ("0", storage.get("current_term"));
00029         ASSERT_EQ("0", storage.get("voted_for"));
00030     }
00031     /*
00032      * Partial recovery - only empty log is recovered
00033      */
00034     {
00035         MemoryStorageBackend storage;
00036 
00037         {
00038             // This log is used to initialize the storage
00039             Log log(storage, tracer);
00040             ASSERT_LE(0, log.init());
00041         }
00042         ASSERT_LE(1, storage.getNumKeys());
00043 
00044         PersistentState pers(storage, tracer);
00045 
00046         ASSERT_LE(0, pers.init());
00047 
00048         ASSERT_LE(3, storage.getNumKeys());
00049         ASSERT_EQ("0", storage.get("log_last_index"));
00050         ASSERT_EQ("0", storage.get("current_term"));
00051         ASSERT_EQ("0", storage.get("voted_for"));
00052     }
00053     /*
00054      * Partial recovery - log and current term are recovered
00055      */
00056     {
00057         MemoryStorageBackend storage;
00058 
00059         {
00060             // This log is used to initialize the storage
00061             Log log(storage, tracer);
00062             ASSERT_LE(0, log.init());
00063         }
00064         ASSERT_LE(1, storage.getNumKeys());
00065 
00066         storage.set("current_term", "1");
00067 
00068         PersistentState pers(storage, tracer);
00069 
00070         ASSERT_GT(0, pers.init());              // Fails because current term is not zero
00071 
00072         storage.set("current_term", "0");
00073 
00074         ASSERT_LE(0, pers.init());              // OK now
00075 
00076         ASSERT_LE(3, storage.getNumKeys());
00077         ASSERT_EQ("0", storage.get("log_last_index"));
00078         ASSERT_EQ("0", storage.get("current_term"));
00079         ASSERT_EQ("0", storage.get("voted_for"));
00080     }
00081     /*
00082      * Full recovery
00083      */
00084     {
00085         MemoryStorageBackend storage;
00086 
00087         {
00088             // This log is used to initialize the storage
00089             Log log(storage, tracer);
00090             ASSERT_LE(0, log.init());
00091 
00092             uavcan::protocol::dynamic_node_id::server::Entry entry;
00093             entry.term = 1;
00094             entry.node_id = 1;
00095             entry.unique_id[0] = 1;
00096             ASSERT_LE(0, log.append(entry));
00097         }
00098         ASSERT_LE(4, storage.getNumKeys());
00099 
00100         PersistentState pers(storage, tracer);
00101 
00102         ASSERT_GT(0, pers.init());              // Fails because log is not empty
00103 
00104         storage.set("current_term", "0");
00105         storage.set("voted_for", "0");
00106         ASSERT_GT(0, pers.init());              // Fails because of bad currentTerm
00107 
00108         storage.set("current_term", "1");       // OK
00109         storage.set("voted_for", "128");        // Invalid value
00110         ASSERT_GT(0, pers.init());              // Fails because of bad votedFor
00111 
00112         storage.set("voted_for", "0");          // OK now
00113         ASSERT_LE(0, pers.init());
00114 
00115         ASSERT_LE(3, storage.getNumKeys());
00116         ASSERT_EQ("1", storage.get("log_last_index"));
00117         ASSERT_EQ("1", storage.get("current_term"));
00118         ASSERT_EQ("0", storage.get("voted_for"));
00119     }
00120 }
00121 
00122 
00123 TEST(dynamic_node_id_server_PersistentState, Basic)
00124 {
00125     using namespace uavcan::dynamic_node_id_server::distributed;
00126 
00127     EventTracer tracer;
00128     MemoryStorageBackend storage;
00129     PersistentState pers(storage, tracer);
00130 
00131     /*
00132      * Initializing
00133      */
00134     ASSERT_LE(0, pers.init());
00135 
00136     ASSERT_EQ("0", storage.get("log_last_index"));
00137     ASSERT_EQ("0", storage.get("current_term"));
00138     ASSERT_EQ("0", storage.get("voted_for"));
00139 
00140     /*
00141      * Inserting some log entries
00142      */
00143     uavcan::protocol::dynamic_node_id::server::Entry entry;
00144     entry.term = 1;
00145     entry.node_id = 1;
00146     entry.unique_id[0] = 1;
00147     ASSERT_LE(0, pers.getLog().append(entry));
00148 
00149     ASSERT_EQ("1", storage.get("log_last_index"));
00150     ASSERT_EQ("0", storage.get("current_term"));
00151     ASSERT_EQ("0", storage.get("voted_for"));
00152 
00153     /*
00154      * Changing current term
00155      */
00156     ASSERT_EQ(0, pers.getCurrentTerm());
00157     ASSERT_LE(0, pers.setCurrentTerm(2));
00158     ASSERT_EQ(2, pers.getCurrentTerm());
00159 
00160     ASSERT_EQ("1", storage.get("log_last_index"));
00161     ASSERT_EQ("2", storage.get("current_term"));
00162     ASSERT_EQ("0", storage.get("voted_for"));
00163 
00164     /*
00165      * Changing votedFor
00166      */
00167     ASSERT_FALSE(pers.isVotedForSet());
00168     ASSERT_EQ(0, pers.getVotedFor().get());
00169     ASSERT_LE(0, pers.setVotedFor(0));
00170     ASSERT_EQ(0, pers.getVotedFor().get());
00171     ASSERT_LE(0, pers.setVotedFor(45));
00172     ASSERT_EQ(45, pers.getVotedFor().get());
00173     ASSERT_TRUE(pers.isVotedForSet());
00174 
00175     ASSERT_EQ("1", storage.get("log_last_index"));
00176     ASSERT_EQ("2", storage.get("current_term"));
00177     ASSERT_EQ("45", storage.get("voted_for"));
00178 
00179     ASSERT_LE(0, pers.resetVotedFor());
00180     ASSERT_EQ(0, pers.getVotedFor().get());
00181     ASSERT_FALSE(pers.isVotedForSet());
00182     ASSERT_EQ("0", storage.get("voted_for"));
00183 
00184     ASSERT_LE(0, pers.setVotedFor(45));
00185     ASSERT_TRUE(pers.isVotedForSet());
00186     ASSERT_EQ("45", storage.get("voted_for"));
00187 
00188     /*
00189      * Handling errors
00190      */
00191     storage.failOnSetCalls(true);
00192 
00193     ASSERT_EQ(2, pers.getCurrentTerm());
00194     ASSERT_GT(0, pers.setCurrentTerm(7893));
00195     ASSERT_EQ(2, pers.getCurrentTerm());
00196 
00197     ASSERT_EQ(45, pers.getVotedFor().get());
00198     ASSERT_GT(0, pers.setVotedFor(78));
00199     ASSERT_EQ(45, pers.getVotedFor().get());
00200 
00201     ASSERT_EQ("1", storage.get("log_last_index"));
00202     ASSERT_EQ("2", storage.get("current_term"));
00203     ASSERT_EQ("45", storage.get("voted_for"));
00204 
00205     /*
00206      * Final checks
00207      */
00208     ASSERT_GT(10, storage.getNumKeys());  // Making sure there's some sane number of keys in the storage
00209 }