[ntcore] Don't update timestamp when value is unchanged (#5356)

This fixes an issue with commands run/cancel.
This commit is contained in:
Carl Hauser
2023-07-23 17:36:26 -07:00
committed by GitHub
parent 5ec7f18bdc
commit c3fab7f1f2
4 changed files with 121 additions and 30 deletions

View File

@@ -491,7 +491,7 @@ TEST_F(LocalStorageTest, SetValueInvalidHandle) {
class LocalStorageDuplicatesTest : public LocalStorageTest {
public:
void SetupPubSub(bool keepPub, bool keepSub);
void SetValues();
void SetValues(bool expectDuplicates);
NT_Publisher pub;
NT_Subscriber sub;
@@ -518,11 +518,12 @@ void LocalStorageDuplicatesTest::SetupPubSub(bool keepPub, bool keepSub) {
{.pollStorage = 10, .keepDuplicates = keepSub});
}
void LocalStorageDuplicatesTest::SetValues() {
void LocalStorageDuplicatesTest::SetValues(bool expectDuplicates) {
storage.SetEntryValue(pub, val1);
storage.SetEntryValue(pub, val2);
// verify the timestamp was updated
EXPECT_EQ(storage.GetEntryLastChange(sub), val2.time());
// verify the timestamp was updated (or not)
EXPECT_EQ(storage.GetEntryLastChange(sub),
expectDuplicates ? val2.time() : val1.time());
storage.SetEntryValue(pub, val3);
}
@@ -531,7 +532,7 @@ TEST_F(LocalStorageDuplicatesTest, Defaults) {
EXPECT_CALL(network, SetValue(pub, val1));
EXPECT_CALL(network, SetValue(pub, val3));
SetValues();
SetValues(false);
// verify 2nd update was dropped locally
auto values = storage.ReadQueueDouble(sub);
@@ -548,11 +549,11 @@ TEST_F(LocalStorageDuplicatesTest, KeepPub) {
EXPECT_CALL(network, SetValue(pub, val1)).Times(2);
// EXPECT_CALL(network, SetValue(pub, val2));
EXPECT_CALL(network, SetValue(pub, val3));
SetValues();
SetValues(true);
// verify all 3 updates were received locally
// verify only 2 updates were received locally
auto values = storage.ReadQueueDouble(sub);
ASSERT_EQ(values.size(), 3u);
ASSERT_EQ(values.size(), 2u);
}
TEST_F(LocalStorageDuplicatesTest, KeepSub) {
@@ -561,14 +562,28 @@ TEST_F(LocalStorageDuplicatesTest, KeepSub) {
// second update should NOT go to the network
EXPECT_CALL(network, SetValue(pub, val1));
EXPECT_CALL(network, SetValue(pub, val3));
SetValues();
SetValues(false);
// verify 2 updates were received locally
auto values = storage.ReadQueueDouble(sub);
ASSERT_EQ(values.size(), 2u);
}
TEST_F(LocalStorageDuplicatesTest, KeepPubSub) {
SetupPubSub(true, true);
// second update SHOULD go to the network
EXPECT_CALL(network, SetValue(pub, val1)).Times(2);
// EXPECT_CALL(network, SetValue(pub, val2));
EXPECT_CALL(network, SetValue(pub, val3));
SetValues(true);
// verify all 3 updates were received locally
auto values = storage.ReadQueueDouble(sub);
ASSERT_EQ(values.size(), 3u);
}
TEST_F(LocalStorageDuplicatesTest, FromNetwork) {
TEST_F(LocalStorageDuplicatesTest, FromNetworkDefault) {
SetupPubSub(false, false);
// incoming from the network are treated like a normal local publish
@@ -579,7 +594,7 @@ TEST_F(LocalStorageDuplicatesTest, FromNetwork) {
EXPECT_EQ(storage.GetEntryLastChange(sub), val2.time());
storage.NetworkSetValue(topic, val3);
// verify 2nd update was dropped locally
// verify 2nd update was dropped for local subscriber
auto values = storage.ReadQueueDouble(sub);
ASSERT_EQ(values.size(), 2u);
ASSERT_EQ(values[0].value, val1.GetDouble());
@@ -588,6 +603,69 @@ TEST_F(LocalStorageDuplicatesTest, FromNetwork) {
ASSERT_EQ(values[1].time, val3.time());
}
TEST_F(LocalStorageDuplicatesTest, FromNetworkKeepPub) {
SetupPubSub(true, false);
// incoming from the network are treated like a normal local publish
auto topic = storage.NetworkAnnounce("foo", "double", {{}}, 0);
storage.NetworkSetValue(topic, val1);
storage.NetworkSetValue(topic, val2);
// verify the timestamp was updated
EXPECT_EQ(storage.GetEntryLastChange(sub), val2.time());
storage.NetworkSetValue(topic, val3);
// verify 2nd update was dropped for local subscriber
auto values = storage.ReadQueueDouble(sub);
ASSERT_EQ(values.size(), 2u);
ASSERT_EQ(values[0].value, val1.GetDouble());
ASSERT_EQ(values[0].time, val1.time());
ASSERT_EQ(values[1].value, val3.GetDouble());
ASSERT_EQ(values[1].time, val3.time());
}
TEST_F(LocalStorageDuplicatesTest, FromNetworkKeepSub) {
SetupPubSub(false, true);
// incoming from the network are treated like a normal local publish
auto topic = storage.NetworkAnnounce("foo", "double", {{}}, 0);
storage.NetworkSetValue(topic, val1);
storage.NetworkSetValue(topic, val2);
// verify the timestamp was updated
EXPECT_EQ(storage.GetEntryLastChange(sub), val2.time());
storage.NetworkSetValue(topic, val3);
// verify 2nd update was received by local subscriber
auto values = storage.ReadQueueDouble(sub);
ASSERT_EQ(values.size(), 3u);
ASSERT_EQ(values[0].value, val1.GetDouble());
ASSERT_EQ(values[0].time, val1.time());
ASSERT_EQ(values[1].value, val2.GetDouble());
ASSERT_EQ(values[1].time, val2.time());
ASSERT_EQ(values[2].value, val3.GetDouble());
ASSERT_EQ(values[2].time, val3.time());
}
TEST_F(LocalStorageDuplicatesTest, FromNetworkKeepPubSub) {
SetupPubSub(true, true);
// incoming from the network are treated like a normal local publish
auto topic = storage.NetworkAnnounce("foo", "double", {{}}, 0);
storage.NetworkSetValue(topic, val1);
storage.NetworkSetValue(topic, val2);
// verify the timestamp was updated
EXPECT_EQ(storage.GetEntryLastChange(sub), val2.time());
storage.NetworkSetValue(topic, val3);
// verify 2nd update was received by local subscriber
auto values = storage.ReadQueueDouble(sub);
ASSERT_EQ(values.size(), 3u);
ASSERT_EQ(values[0].value, val1.GetDouble());
ASSERT_EQ(values[0].time, val1.time());
ASSERT_EQ(values[1].value, val2.GetDouble());
ASSERT_EQ(values[1].time, val2.time());
ASSERT_EQ(values[2].value, val3.GetDouble());
ASSERT_EQ(values[2].time, val3.time());
}
class LocalStorageNumberVariantsTest : public LocalStorageTest {
public:
void CreateSubscriber(NT_Handle* handle, std::string_view name, NT_Type type,