log.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 "../../helpers.hpp"
9 #include "../memory_storage_backend.hpp"
10 
11 
12 static const unsigned NumEntriesInStorageWithEmptyLog = 4; // last index + 3 items per log entry
13 
14 
15 TEST(dynamic_node_id_server_Log, Initialization)
16 {
18 
19  EventTracer tracer;
20  // No log data in the storage - initializing empty log
21  {
22  MemoryStorageBackend storage;
24 
25  ASSERT_EQ(0, storage.getNumKeys());
26  ASSERT_LE(0, log.init());
27  ASSERT_EQ(NumEntriesInStorageWithEmptyLog, storage.getNumKeys());
28  ASSERT_EQ(0, log.getLastIndex());
29  ASSERT_EQ(0, log.getEntryAtIndex(0)->term);
30  ASSERT_EQ(0, log.getEntryAtIndex(0)->node_id);
31  ASSERT_EQ(uavcan::protocol::dynamic_node_id::server::Entry::FieldTypes::unique_id(),
32  log.getEntryAtIndex(0)->unique_id);
33  }
34  // Nonempty storage, one item
35  {
36  MemoryStorageBackend storage;
37  Log log(storage, tracer);
38 
39  storage.set("log_last_index", "0");
40  ASSERT_LE(-uavcan::ErrFailure, log.init()); // Expected one entry, none found
41  ASSERT_EQ(1, storage.getNumKeys());
42 
43  storage.set("log0_term", "0");
44  storage.set("log0_unique_id", "00000000000000000000000000000000");
45  storage.set("log0_node_id", "0");
46  ASSERT_LE(0, log.init()); // OK now
47  ASSERT_EQ(NumEntriesInStorageWithEmptyLog, storage.getNumKeys());
48  ASSERT_EQ(0, log.getLastIndex());
49  ASSERT_EQ(0, log.getEntryAtIndex(0)->term);
50  }
51  // Nonempty storage, broken data
52  {
53  MemoryStorageBackend storage;
54  Log log(storage, tracer);
55 
56  storage.set("log_last_index", "foobar");
57  ASSERT_LE(-uavcan::ErrFailure, log.init()); // Bad value
58 
59  storage.set("log_last_index", "128");
60  ASSERT_LE(-uavcan::ErrFailure, log.init()); // Bad value
61 
62  storage.set("log_last_index", "0");
63  ASSERT_LE(-uavcan::ErrFailure, log.init()); // No log items
64  ASSERT_EQ(1, storage.getNumKeys());
65 
66  storage.set("log0_term", "0");
67  storage.set("log0_unique_id", "00000000000000000000000000000000");
68  storage.set("log0_node_id", "128"); // Bad value (127 max)
69  ASSERT_LE(-uavcan::ErrFailure, log.init()); // Failed
70  ASSERT_EQ(0, log.getLastIndex());
71  ASSERT_EQ(0, log.getEntryAtIndex(0)->term);
72  ASSERT_EQ(4, storage.getNumKeys());
73  }
74  // Nonempty storage, many items
75  {
76  MemoryStorageBackend storage;
77  Log log(storage, tracer);
78 
79  storage.set("log_last_index", "1"); // 2 items - 0, 1
80  storage.set("log0_term", "0");
81  storage.set("log0_unique_id", "00000000000000000000000000000000");
82  storage.set("log0_node_id", "0");
83  storage.set("log1_term", "1");
84  storage.set("log1_unique_id", "0123456789abcdef0123456789abcdef");
85  storage.set("log1_node_id", "127");
86 
87  ASSERT_LE(0, log.init()); // OK now
88  ASSERT_EQ(7, storage.getNumKeys());
89  ASSERT_EQ(1, log.getLastIndex());
90 
91  ASSERT_EQ(0, log.getEntryAtIndex(0)->term);
92  ASSERT_EQ(0, log.getEntryAtIndex(0)->node_id);
93  ASSERT_EQ(uavcan::protocol::dynamic_node_id::server::Entry::FieldTypes::unique_id(),
94  log.getEntryAtIndex(0)->unique_id);
95 
96  ASSERT_EQ(1, log.getEntryAtIndex(1)->term);
97  ASSERT_EQ(127, log.getEntryAtIndex(1)->node_id);
98  uavcan::protocol::dynamic_node_id::server::Entry::FieldTypes::unique_id uid;
99  uid[0] = 0x01;
100  uid[1] = 0x23;
101  uid[2] = 0x45;
102  uid[3] = 0x67;
103  uid[4] = 0x89;
104  uid[5] = 0xab;
105  uid[6] = 0xcd;
106  uid[7] = 0xef;
107  uavcan::copy(uid.begin(), uid.begin() + 8, uid.begin() + 8);
108  ASSERT_EQ(uid, log.getEntryAtIndex(1)->unique_id);
109  }
110 }
111 
112 
113 TEST(dynamic_node_id_server_Log, Append)
114 {
116 
117  EventTracer tracer;
118  MemoryStorageBackend storage;
119  Log log(storage, tracer);
120 
121  ASSERT_EQ(0, storage.getNumKeys());
122  ASSERT_LE(0, log.init());
123  storage.print();
124  ASSERT_EQ(NumEntriesInStorageWithEmptyLog, storage.getNumKeys());
125 
126  /*
127  * Entry at the index 0 always exists, and it's always zero-initialized.
128  */
129  ASSERT_EQ("0", storage.get("log_last_index"));
130  ASSERT_EQ("0", storage.get("log0_term"));
131  ASSERT_EQ("00000000000000000000000000000000", storage.get("log0_unique_id"));
132  ASSERT_EQ("0", storage.get("log0_node_id"));
133 
134  /*
135  * Adding one entry to the log, making sure it appears in the storage
136  */
137  uavcan::protocol::dynamic_node_id::server::Entry entry;
138  entry.term = 1;
139  entry.node_id = 1;
140  entry.unique_id[0] = 1;
141  ASSERT_LE(0, log.append(entry));
142 
143  ASSERT_EQ("1", storage.get("log_last_index"));
144  ASSERT_EQ("1", storage.get("log1_term"));
145  ASSERT_EQ("01000000000000000000000000000000", storage.get("log1_unique_id"));
146  ASSERT_EQ("1", storage.get("log1_node_id"));
147 
148  ASSERT_EQ(1, log.getLastIndex());
149  ASSERT_TRUE(entry == *log.getEntryAtIndex(1));
150 
151  /*
152  * Adding another entry while storage is failing
153  */
154  storage.failOnSetCalls(true);
155 
156  ASSERT_EQ(7, storage.getNumKeys());
157 
158  entry.term = 2;
159  entry.node_id = 2;
160  entry.unique_id[0] = 2;
161  ASSERT_GT(0, log.append(entry));
162 
163  ASSERT_EQ(7, storage.getNumKeys()); // No new entries, we failed
164 
165  ASSERT_EQ(1, log.getLastIndex());
166 
167  /*
168  * Making sure append() fails when the log is full
169  */
170  storage.failOnSetCalls(false);
171 
172  while (log.getLastIndex() < (log.Capacity - 1))
173  {
174  ASSERT_LE(0, log.append(entry));
175  ASSERT_TRUE(entry == *log.getEntryAtIndex(log.getLastIndex()));
176 
177  entry.term += 1;
178  entry.node_id = uint8_t(entry.node_id + 1U);
179  entry.unique_id[0] = uint8_t(entry.unique_id[0] + 1U);
180  }
181 
182  ASSERT_GT(0, log.append(entry)); // Failing because full
183 
184  storage.print();
185 }
186 
187 
188 TEST(dynamic_node_id_server_Log, Remove)
189 {
191 
192  EventTracer tracer;
193  MemoryStorageBackend storage;
194  Log log(storage, tracer);
195 
196  /*
197  * Filling the log fully
198  */
199  uavcan::protocol::dynamic_node_id::server::Entry entry;
200  entry.term = 1;
201  entry.node_id = 1;
202  entry.unique_id[0] = 1;
203 
204  while (log.getLastIndex() < (log.Capacity - 1))
205  {
206  ASSERT_LE(0, log.append(entry));
207  ASSERT_TRUE(entry == *log.getEntryAtIndex(log.getLastIndex()));
208 
209  entry.term += 1;
210  entry.node_id = uint8_t(entry.node_id + 1U);
211  entry.unique_id[0] = uint8_t(entry.unique_id[0] + 1U);
212  }
213 
214  /*
215  * Removal will fail as the storage is failing to update
216  */
217  storage.failOnSetCalls(true);
218 
219  ASSERT_EQ(log.Capacity - 1, log.getLastIndex());
220  ASSERT_GT(0, log.removeEntriesWhereIndexGreaterOrEqual(60)); // Failing
221  ASSERT_EQ(log.Capacity - 1, log.getLastIndex());
222 
223  /*
224  * Now removal must work
225  */
226  storage.failOnSetCalls(false);
227 
228  ASSERT_EQ(log.Capacity - 1, log.getLastIndex());
229 
230  ASSERT_LE(0, log.removeEntriesWhereIndexGreaterOrEqual(60));
231  ASSERT_EQ(59, log.getLastIndex());
232  ASSERT_EQ("59", storage.get("log_last_index"));
233 
234  ASSERT_LE(0, log.removeEntriesWhereIndexGreater(30));
235  ASSERT_EQ(30, log.getLastIndex());
236  ASSERT_EQ("30", storage.get("log_last_index"));
237 
238  ASSERT_LE(0, log.removeEntriesWhereIndexGreaterOrEqual(1));
239  ASSERT_EQ(0, log.getLastIndex());
240  ASSERT_EQ("0", storage.get("log_last_index"));
241 
242  storage.print();
243 }
TEST
TEST(dynamic_node_id_server_Log, Initialization)
Definition: log.cpp:15
uavcan::dynamic_node_id_server::distributed::Log::init
int init()
Definition: log.hpp:152
uavcan::dynamic_node_id_server::distributed::Log::getEntryAtIndex
const Entry * getEntryAtIndex(Index index) const
Definition: log.hpp:285
NumEntriesInStorageWithEmptyLog
static const unsigned NumEntriesInStorageWithEmptyLog
Definition: log.cpp:12
MemoryStorageBackend::print
void print() const
Definition: memory_storage_backend.hpp:46
uavcan::dynamic_node_id_server::distributed::Log::append
int append(const Entry &entry)
Definition: log.hpp:202
uavcan::dynamic_node_id_server::distributed::Log::removeEntriesWhereIndexGreaterOrEqual
int removeEntriesWhereIndexGreaterOrEqual(Index index)
Definition: log.hpp:242
uavcan::uint8_t
std::uint8_t uint8_t
Definition: std.hpp:24
MemoryStorageBackend::set
virtual void set(const String &key, const String &value)
Definition: memory_storage_backend.hpp:32
MemoryStorageBackend::get
virtual String get(const String &key) const
Definition: memory_storage_backend.hpp:22
uavcan::dynamic_node_id_server::distributed::Log::removeEntriesWhereIndexGreater
int removeEntriesWhereIndexGreater(Index index)
Definition: log.hpp:276
uavcan::dynamic_node_id_server::distributed::Log::Capacity
@ Capacity
Definition: log.hpp:30
log.hpp
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::copy
UAVCAN_EXPORT OutputIt copy(InputIt first, InputIt last, OutputIt result)
Definition: templates.hpp:238
MemoryStorageBackend::getNumKeys
unsigned getNumKeys() const
Definition: memory_storage_backend.hpp:44
MemoryStorageBackend::failOnSetCalls
void failOnSetCalls(bool really)
Definition: memory_storage_backend.hpp:40
uavcan::dynamic_node_id_server::distributed::Log::getLastIndex
Index getLastIndex() const
Definition: log.hpp:291


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