persistent_state.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
5 #include <gtest/gtest.h>
7 #include "../event_tracer.hpp"
8 #include "../memory_storage_backend.hpp"
9 
10 
11 TEST(dynamic_node_id_server_PersistentState, Initialization)
12 {
14 
15  EventTracer tracer;
16  /*
17  * First initialization
18  */
19  {
20  MemoryStorageBackend storage;
21  PersistentState pers(storage, tracer);
22 
23  ASSERT_EQ(0, storage.getNumKeys());
24  ASSERT_LE(0, pers.init());
25 
26  ASSERT_LE(3, storage.getNumKeys());
27  ASSERT_EQ("0", storage.get("log_last_index"));
28  ASSERT_EQ("0", storage.get("current_term"));
29  ASSERT_EQ("0", storage.get("voted_for"));
30  }
31  /*
32  * Partial recovery - only empty log is recovered
33  */
34  {
35  MemoryStorageBackend storage;
36 
37  {
38  // This log is used to initialize the storage
39  Log log(storage, tracer);
40  ASSERT_LE(0, log.init());
41  }
42  ASSERT_LE(1, storage.getNumKeys());
43 
44  PersistentState pers(storage, tracer);
45 
46  ASSERT_LE(0, pers.init());
47 
48  ASSERT_LE(3, storage.getNumKeys());
49  ASSERT_EQ("0", storage.get("log_last_index"));
50  ASSERT_EQ("0", storage.get("current_term"));
51  ASSERT_EQ("0", storage.get("voted_for"));
52  }
53  /*
54  * Partial recovery - log and current term are recovered
55  */
56  {
57  MemoryStorageBackend storage;
58 
59  {
60  // This log is used to initialize the storage
61  Log log(storage, tracer);
62  ASSERT_LE(0, log.init());
63  }
64  ASSERT_LE(1, storage.getNumKeys());
65 
66  storage.set("current_term", "1");
67 
68  PersistentState pers(storage, tracer);
69 
70  ASSERT_GT(0, pers.init()); // Fails because current term is not zero
71 
72  storage.set("current_term", "0");
73 
74  ASSERT_LE(0, pers.init()); // OK now
75 
76  ASSERT_LE(3, storage.getNumKeys());
77  ASSERT_EQ("0", storage.get("log_last_index"));
78  ASSERT_EQ("0", storage.get("current_term"));
79  ASSERT_EQ("0", storage.get("voted_for"));
80  }
81  /*
82  * Full recovery
83  */
84  {
85  MemoryStorageBackend storage;
86 
87  {
88  // This log is used to initialize the storage
89  Log log(storage, tracer);
90  ASSERT_LE(0, log.init());
91 
92  uavcan::protocol::dynamic_node_id::server::Entry entry;
93  entry.term = 1;
94  entry.node_id = 1;
95  entry.unique_id[0] = 1;
96  ASSERT_LE(0, log.append(entry));
97  }
98  ASSERT_LE(4, storage.getNumKeys());
99 
100  PersistentState pers(storage, tracer);
101 
102  ASSERT_GT(0, pers.init()); // Fails because log is not empty
103 
104  storage.set("current_term", "0");
105  storage.set("voted_for", "0");
106  ASSERT_GT(0, pers.init()); // Fails because of bad currentTerm
107 
108  storage.set("current_term", "1"); // OK
109  storage.set("voted_for", "128"); // Invalid value
110  ASSERT_GT(0, pers.init()); // Fails because of bad votedFor
111 
112  storage.set("voted_for", "0"); // OK now
113  ASSERT_LE(0, pers.init());
114 
115  ASSERT_LE(3, storage.getNumKeys());
116  ASSERT_EQ("1", storage.get("log_last_index"));
117  ASSERT_EQ("1", storage.get("current_term"));
118  ASSERT_EQ("0", storage.get("voted_for"));
119  }
120 }
121 
122 
123 TEST(dynamic_node_id_server_PersistentState, Basic)
124 {
126 
127  EventTracer tracer;
128  MemoryStorageBackend storage;
129  PersistentState pers(storage, tracer);
130 
131  /*
132  * Initializing
133  */
134  ASSERT_LE(0, pers.init());
135 
136  ASSERT_EQ("0", storage.get("log_last_index"));
137  ASSERT_EQ("0", storage.get("current_term"));
138  ASSERT_EQ("0", storage.get("voted_for"));
139 
140  /*
141  * Inserting some log entries
142  */
143  uavcan::protocol::dynamic_node_id::server::Entry entry;
144  entry.term = 1;
145  entry.node_id = 1;
146  entry.unique_id[0] = 1;
147  ASSERT_LE(0, pers.getLog().append(entry));
148 
149  ASSERT_EQ("1", storage.get("log_last_index"));
150  ASSERT_EQ("0", storage.get("current_term"));
151  ASSERT_EQ("0", storage.get("voted_for"));
152 
153  /*
154  * Changing current term
155  */
156  ASSERT_EQ(0, pers.getCurrentTerm());
157  ASSERT_LE(0, pers.setCurrentTerm(2));
158  ASSERT_EQ(2, pers.getCurrentTerm());
159 
160  ASSERT_EQ("1", storage.get("log_last_index"));
161  ASSERT_EQ("2", storage.get("current_term"));
162  ASSERT_EQ("0", storage.get("voted_for"));
163 
164  /*
165  * Changing votedFor
166  */
167  ASSERT_FALSE(pers.isVotedForSet());
168  ASSERT_EQ(0, pers.getVotedFor().get());
169  ASSERT_LE(0, pers.setVotedFor(0));
170  ASSERT_EQ(0, pers.getVotedFor().get());
171  ASSERT_LE(0, pers.setVotedFor(45));
172  ASSERT_EQ(45, pers.getVotedFor().get());
173  ASSERT_TRUE(pers.isVotedForSet());
174 
175  ASSERT_EQ("1", storage.get("log_last_index"));
176  ASSERT_EQ("2", storage.get("current_term"));
177  ASSERT_EQ("45", storage.get("voted_for"));
178 
179  ASSERT_LE(0, pers.resetVotedFor());
180  ASSERT_EQ(0, pers.getVotedFor().get());
181  ASSERT_FALSE(pers.isVotedForSet());
182  ASSERT_EQ("0", storage.get("voted_for"));
183 
184  ASSERT_LE(0, pers.setVotedFor(45));
185  ASSERT_TRUE(pers.isVotedForSet());
186  ASSERT_EQ("45", storage.get("voted_for"));
187 
188  /*
189  * Handling errors
190  */
191  storage.failOnSetCalls(true);
192 
193  ASSERT_EQ(2, pers.getCurrentTerm());
194  ASSERT_GT(0, pers.setCurrentTerm(7893));
195  ASSERT_EQ(2, pers.getCurrentTerm());
196 
197  ASSERT_EQ(45, pers.getVotedFor().get());
198  ASSERT_GT(0, pers.setVotedFor(78));
199  ASSERT_EQ(45, pers.getVotedFor().get());
200 
201  ASSERT_EQ("1", storage.get("log_last_index"));
202  ASSERT_EQ("2", storage.get("current_term"));
203  ASSERT_EQ("45", storage.get("voted_for"));
204 
205  /*
206  * Final checks
207  */
208  ASSERT_GT(10, storage.getNumKeys()); // Making sure there's some sane number of keys in the storage
209 }
uavcan::dynamic_node_id_server::distributed::PersistentState::getLog
Log & getLog()
Definition: persistent_state.hpp:165
persistent_state.hpp
uavcan::dynamic_node_id_server::distributed::Log::init
int init()
Definition: log.hpp:152
uavcan::dynamic_node_id_server::distributed::PersistentState::isVotedForSet
bool isVotedForSet() const
Definition: persistent_state.hpp:163
TEST
TEST(dynamic_node_id_server_PersistentState, Initialization)
Definition: persistent_state.cpp:11
uavcan::NodeID::get
uint8_t get() const
Definition: transfer.hpp:132
uavcan::dynamic_node_id_server::distributed::PersistentState::setVotedFor
int setVotedFor(NodeID node_id)
Definition: persistent_state.hpp:202
uavcan::dynamic_node_id_server::distributed::PersistentState::init
int init()
Definition: persistent_state.hpp:53
uavcan::dynamic_node_id_server::distributed::Log::append
int append(const Entry &entry)
Definition: log.hpp:202
uavcan::dynamic_node_id_server::distributed::PersistentState::setCurrentTerm
int setCurrentTerm(Term term)
Definition: persistent_state.hpp:171
MemoryStorageBackend::set
virtual void set(const String &key, const String &value)
Definition: memory_storage_backend.hpp:32
uavcan::dynamic_node_id_server::distributed::PersistentState
Definition: persistent_state.hpp:25
uavcan::dynamic_node_id_server::distributed::PersistentState::resetVotedFor
int resetVotedFor()
Definition: persistent_state.hpp:230
MemoryStorageBackend::get
virtual String get(const String &key) const
Definition: memory_storage_backend.hpp:22
uavcan::dynamic_node_id_server::distributed
Definition: cluster_manager.hpp:25
MemoryStorageBackend
Definition: memory_storage_backend.hpp:10
uavcan::dynamic_node_id_server::distributed::Log
Definition: log.hpp:25
uavcan::dynamic_node_id_server::distributed::PersistentState::getCurrentTerm
Term getCurrentTerm() const
Definition: persistent_state.hpp:160
MemoryStorageBackend::getNumKeys
unsigned getNumKeys() const
Definition: memory_storage_backend.hpp:44
uavcan::dynamic_node_id_server::distributed::PersistentState::getVotedFor
NodeID getVotedFor() const
Definition: persistent_state.hpp:162
MemoryStorageBackend::failOnSetCalls
void failOnSetCalls(bool really)
Definition: memory_storage_backend.hpp:40


uavcan_communicator
Author(s):
autogenerated on Fri Dec 13 2024 03:10:02