libuav original
Dependents: UAVCAN UAVCAN_Subscriber
log.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/log.hpp> 00007 #include "../event_tracer.hpp" 00008 #include "../../helpers.hpp" 00009 #include "../memory_storage_backend.hpp" 00010 00011 00012 static const unsigned NumEntriesInStorageWithEmptyLog = 4; // last index + 3 items per log entry 00013 00014 00015 TEST(dynamic_node_id_server_Log, Initialization) 00016 { 00017 using namespace uavcan::dynamic_node_id_server::distributed; 00018 00019 EventTracer tracer; 00020 // No log data in the storage - initializing empty log 00021 { 00022 MemoryStorageBackend storage; 00023 uavcan::dynamic_node_id_server::distributed::Log log(storage, tracer); 00024 00025 ASSERT_EQ(0, storage.getNumKeys()); 00026 ASSERT_LE(0, log.init()); 00027 ASSERT_EQ(NumEntriesInStorageWithEmptyLog, storage.getNumKeys()); 00028 ASSERT_EQ(0, log.getLastIndex()); 00029 ASSERT_EQ(0, log.getEntryAtIndex(0)->term); 00030 ASSERT_EQ(0, log.getEntryAtIndex(0)->node_id); 00031 ASSERT_EQ(uavcan::protocol::dynamic_node_id::server::Entry::FieldTypes::unique_id(), 00032 log.getEntryAtIndex(0)->unique_id); 00033 } 00034 // Nonempty storage, one item 00035 { 00036 MemoryStorageBackend storage; 00037 Log log(storage, tracer); 00038 00039 storage.set("log_last_index", "0"); 00040 ASSERT_LE(-uavcan::ErrFailure, log.init()); // Expected one entry, none found 00041 ASSERT_EQ(1, storage.getNumKeys()); 00042 00043 storage.set("log0_term", "0"); 00044 storage.set("log0_unique_id", "00000000000000000000000000000000"); 00045 storage.set("log0_node_id", "0"); 00046 ASSERT_LE(0, log.init()); // OK now 00047 ASSERT_EQ(NumEntriesInStorageWithEmptyLog, storage.getNumKeys()); 00048 ASSERT_EQ(0, log.getLastIndex()); 00049 ASSERT_EQ(0, log.getEntryAtIndex(0)->term); 00050 } 00051 // Nonempty storage, broken data 00052 { 00053 MemoryStorageBackend storage; 00054 Log log(storage, tracer); 00055 00056 storage.set("log_last_index", "foobar"); 00057 ASSERT_LE(-uavcan::ErrFailure, log.init()); // Bad value 00058 00059 storage.set("log_last_index", "128"); 00060 ASSERT_LE(-uavcan::ErrFailure, log.init()); // Bad value 00061 00062 storage.set("log_last_index", "0"); 00063 ASSERT_LE(-uavcan::ErrFailure, log.init()); // No log items 00064 ASSERT_EQ(1, storage.getNumKeys()); 00065 00066 storage.set("log0_term", "0"); 00067 storage.set("log0_unique_id", "00000000000000000000000000000000"); 00068 storage.set("log0_node_id", "128"); // Bad value (127 max) 00069 ASSERT_LE(-uavcan::ErrFailure, log.init()); // Failed 00070 ASSERT_EQ(0, log.getLastIndex()); 00071 ASSERT_EQ(0, log.getEntryAtIndex(0)->term); 00072 ASSERT_EQ(4, storage.getNumKeys()); 00073 } 00074 // Nonempty storage, many items 00075 { 00076 MemoryStorageBackend storage; 00077 Log log(storage, tracer); 00078 00079 storage.set("log_last_index", "1"); // 2 items - 0, 1 00080 storage.set("log0_term", "0"); 00081 storage.set("log0_unique_id", "00000000000000000000000000000000"); 00082 storage.set("log0_node_id", "0"); 00083 storage.set("log1_term", "1"); 00084 storage.set("log1_unique_id", "0123456789abcdef0123456789abcdef"); 00085 storage.set("log1_node_id", "127"); 00086 00087 ASSERT_LE(0, log.init()); // OK now 00088 ASSERT_EQ(7, storage.getNumKeys()); 00089 ASSERT_EQ(1, log.getLastIndex()); 00090 00091 ASSERT_EQ(0, log.getEntryAtIndex(0)->term); 00092 ASSERT_EQ(0, log.getEntryAtIndex(0)->node_id); 00093 ASSERT_EQ(uavcan::protocol::dynamic_node_id::server::Entry::FieldTypes::unique_id(), 00094 log.getEntryAtIndex(0)->unique_id); 00095 00096 ASSERT_EQ(1, log.getEntryAtIndex(1)->term); 00097 ASSERT_EQ(127, log.getEntryAtIndex(1)->node_id); 00098 uavcan::protocol::dynamic_node_id::server::Entry::FieldTypes::unique_id uid; 00099 uid[0] = 0x01; 00100 uid[1] = 0x23; 00101 uid[2] = 0x45; 00102 uid[3] = 0x67; 00103 uid[4] = 0x89; 00104 uid[5] = 0xab; 00105 uid[6] = 0xcd; 00106 uid[7] = 0xef; 00107 uavcan::copy(uid.begin(), uid.begin() + 8, uid.begin() + 8); 00108 ASSERT_EQ(uid, log.getEntryAtIndex(1)->unique_id); 00109 } 00110 } 00111 00112 00113 TEST(dynamic_node_id_server_Log, Append) 00114 { 00115 using namespace uavcan::dynamic_node_id_server::distributed; 00116 00117 EventTracer tracer; 00118 MemoryStorageBackend storage; 00119 Log log(storage, tracer); 00120 00121 ASSERT_EQ(0, storage.getNumKeys()); 00122 ASSERT_LE(0, log.init()); 00123 storage.print(); 00124 ASSERT_EQ(NumEntriesInStorageWithEmptyLog, storage.getNumKeys()); 00125 00126 /* 00127 * Entry at the index 0 always exists, and it's always zero-initialized. 00128 */ 00129 ASSERT_EQ("0", storage.get("log_last_index")); 00130 ASSERT_EQ("0", storage.get("log0_term")); 00131 ASSERT_EQ("00000000000000000000000000000000", storage.get("log0_unique_id")); 00132 ASSERT_EQ("0", storage.get("log0_node_id")); 00133 00134 /* 00135 * Adding one entry to the log, making sure it appears in the storage 00136 */ 00137 uavcan::protocol::dynamic_node_id::server::Entry entry; 00138 entry.term = 1; 00139 entry.node_id = 1; 00140 entry.unique_id[0] = 1; 00141 ASSERT_LE(0, log.append(entry)); 00142 00143 ASSERT_EQ("1", storage.get("log_last_index")); 00144 ASSERT_EQ("1", storage.get("log1_term")); 00145 ASSERT_EQ("01000000000000000000000000000000", storage.get("log1_unique_id")); 00146 ASSERT_EQ("1", storage.get("log1_node_id")); 00147 00148 ASSERT_EQ(1, log.getLastIndex()); 00149 ASSERT_TRUE(entry == *log.getEntryAtIndex(1)); 00150 00151 /* 00152 * Adding another entry while storage is failing 00153 */ 00154 storage.failOnSetCalls(true); 00155 00156 ASSERT_EQ(7, storage.getNumKeys()); 00157 00158 entry.term = 2; 00159 entry.node_id = 2; 00160 entry.unique_id[0] = 2; 00161 ASSERT_GT(0, log.append(entry)); 00162 00163 ASSERT_EQ(7, storage.getNumKeys()); // No new entries, we failed 00164 00165 ASSERT_EQ(1, log.getLastIndex()); 00166 00167 /* 00168 * Making sure append() fails when the log is full 00169 */ 00170 storage.failOnSetCalls(false); 00171 00172 while (log.getLastIndex() < (log.Capacity - 1)) 00173 { 00174 ASSERT_LE(0, log.append(entry)); 00175 ASSERT_TRUE(entry == *log.getEntryAtIndex(log.getLastIndex())); 00176 00177 entry.term += 1; 00178 entry.node_id = uint8_t(entry.node_id + 1U); 00179 entry.unique_id[0] = uint8_t(entry.unique_id[0] + 1U); 00180 } 00181 00182 ASSERT_GT(0, log.append(entry)); // Failing because full 00183 00184 storage.print(); 00185 } 00186 00187 00188 TEST(dynamic_node_id_server_Log, Remove) 00189 { 00190 using namespace uavcan::dynamic_node_id_server::distributed; 00191 00192 EventTracer tracer; 00193 MemoryStorageBackend storage; 00194 Log log(storage, tracer); 00195 00196 /* 00197 * Filling the log fully 00198 */ 00199 uavcan::protocol::dynamic_node_id::server::Entry entry; 00200 entry.term = 1; 00201 entry.node_id = 1; 00202 entry.unique_id[0] = 1; 00203 00204 while (log.getLastIndex() < (log.Capacity - 1)) 00205 { 00206 ASSERT_LE(0, log.append(entry)); 00207 ASSERT_TRUE(entry == *log.getEntryAtIndex(log.getLastIndex())); 00208 00209 entry.term += 1; 00210 entry.node_id = uint8_t(entry.node_id + 1U); 00211 entry.unique_id[0] = uint8_t(entry.unique_id[0] + 1U); 00212 } 00213 00214 /* 00215 * Removal will fail as the storage is failing to update 00216 */ 00217 storage.failOnSetCalls(true); 00218 00219 ASSERT_EQ(log.Capacity - 1, log.getLastIndex()); 00220 ASSERT_GT(0, log.removeEntriesWhereIndexGreaterOrEqual(60)); // Failing 00221 ASSERT_EQ(log.Capacity - 1, log.getLastIndex()); 00222 00223 /* 00224 * Now removal must work 00225 */ 00226 storage.failOnSetCalls(false); 00227 00228 ASSERT_EQ(log.Capacity - 1, log.getLastIndex()); 00229 00230 ASSERT_LE(0, log.removeEntriesWhereIndexGreaterOrEqual(60)); 00231 ASSERT_EQ(59, log.getLastIndex()); 00232 ASSERT_EQ("59", storage.get("log_last_index")); 00233 00234 ASSERT_LE(0, log.removeEntriesWhereIndexGreater(30)); 00235 ASSERT_EQ(30, log.getLastIndex()); 00236 ASSERT_EQ("30", storage.get("log_last_index")); 00237 00238 ASSERT_LE(0, log.removeEntriesWhereIndexGreaterOrEqual(1)); 00239 ASSERT_EQ(0, log.getLastIndex()); 00240 ASSERT_EQ("0", storage.get("log_last_index")); 00241 00242 storage.print(); 00243 }
Generated on Tue Jul 12 2022 17:17:33 by 1.7.2