Adds SetDefault methods to NetworkTables (#54)

There was no way to atomically check for a key in the table,
and then setting if it if non existant. Back before persistent
this was not a problem, however now it is, as its possible for
values to be added before team's robot programs start. This makes
the old method of calling Put*** methods in RobotInit invalid.
This adds SetDefault methods, which do this atomically.
This commit is contained in:
Thad House
2016-07-13 00:31:03 -07:00
committed by Peter Johnson
parent 6615a34e99
commit 58092c5190
15 changed files with 785 additions and 1 deletions

View File

@@ -288,6 +288,106 @@ TEST_P(StorageTestEmpty, SetEntryValueEmptyValue) {
EXPECT_TRUE(outgoing.empty());
}
TEST_P(StorageTestEmpty, SetDefaultEntryAssignNew) {
// brand new entry
auto value = Value::MakeBoolean(true);
auto ret_val = storage.SetDefaultEntryValue("foo", value);
EXPECT_TRUE(ret_val);
EXPECT_EQ(value, GetEntry("foo")->value);
ASSERT_EQ(1u, outgoing.size());
EXPECT_FALSE(outgoing[0].only);
EXPECT_FALSE(outgoing[0].except);
auto msg = outgoing[0].msg;
EXPECT_EQ(Message::kEntryAssign, msg->type());
EXPECT_EQ("foo", msg->str());
if (GetParam())
EXPECT_EQ(0u, msg->id()); // assigned as server
else
EXPECT_EQ(0xffffu, msg->id()); // not assigned as client
EXPECT_EQ(0u, msg->seq_num_uid());
EXPECT_EQ(value, msg->value());
EXPECT_EQ(0u, msg->flags());
}
TEST_P(StorageTestPopulateOne, SetDefaultEntryExistsSameType) {
// existing entry
auto value = Value::MakeBoolean(true);
auto ret_val = storage.SetDefaultEntryValue("foo", value);
EXPECT_TRUE(ret_val);
EXPECT_NE(value, GetEntry("foo")->value);
EXPECT_TRUE(outgoing.empty());
}
TEST_P(StorageTestPopulateOne, SetDefaultEntryExistsDifferentType) {
// existing entry is boolean
auto value = Value::MakeDouble(2.0);
auto ret_val = storage.SetDefaultEntryValue("foo", value);
EXPECT_FALSE(ret_val);
// should not have updated value in table if it already existed.
EXPECT_NE(value, GetEntry("foo")->value);
EXPECT_TRUE(outgoing.empty());
}
TEST_P(StorageTestEmpty, SetDefaultEntryEmptyName) {
auto value = Value::MakeBoolean(true);
auto ret_val = storage.SetDefaultEntryValue("", value);
EXPECT_FALSE(ret_val);
auto entry = GetEntry("foo");
EXPECT_FALSE(entry->value);
EXPECT_EQ(0u, entry->flags);
EXPECT_EQ("foobar", entry->name); // since GetEntry uses the tmp_entry.
EXPECT_EQ(0xffffu, entry->id);
EXPECT_EQ(SequenceNumber(), entry->seq_num);
EXPECT_TRUE(entries().empty());
EXPECT_TRUE(idmap().empty());
EXPECT_TRUE(outgoing.empty());
}
TEST_P(StorageTestEmpty, SetDefaultEntryEmptyValue) {
auto value = Value::MakeBoolean(true);
auto ret_val = storage.SetDefaultEntryValue("", nullptr);
EXPECT_FALSE(ret_val);
auto entry = GetEntry("foo");
EXPECT_FALSE(entry->value);
EXPECT_EQ(0u, entry->flags);
EXPECT_EQ("foobar", entry->name); // since GetEntry uses the tmp_entry.
EXPECT_EQ(0xffffu, entry->id);
EXPECT_EQ(SequenceNumber(), entry->seq_num);
EXPECT_TRUE(entries().empty());
EXPECT_TRUE(idmap().empty());
EXPECT_TRUE(outgoing.empty());
}
TEST_P(StorageTestPopulated, SetDefaultEntryEmptyName) {
auto value = Value::MakeBoolean(true);
auto ret_val = storage.SetDefaultEntryValue("", value);
EXPECT_FALSE(ret_val);
// assert that no entries get added
EXPECT_EQ(4u, entries().size());
if (GetParam())
EXPECT_EQ(4u, idmap().size());
else
EXPECT_EQ(0u, idmap().size());
EXPECT_TRUE(outgoing.empty());
}
TEST_P(StorageTestPopulated, SetDefaultEntryEmptyValue) {
auto value = Value::MakeBoolean(true);
auto ret_val = storage.SetDefaultEntryValue("", nullptr);
EXPECT_FALSE(ret_val);
// assert that no entries get added
EXPECT_EQ(4u, entries().size());
if (GetParam())
EXPECT_EQ(4u, idmap().size());
else
EXPECT_EQ(0u, idmap().size());
EXPECT_TRUE(outgoing.empty());
}
TEST_P(StorageTestEmpty, SetEntryFlagsNew) {
// flags setting doesn't create an entry
storage.SetEntryFlags("foo", 0u);