[ntcore] Unify NetworkInterface and MessageHandler (#7190)

This commit is contained in:
Peter Johnson
2024-10-11 14:38:02 -07:00
committed by GitHub
parent 8ca99c7cb7
commit 96f0b2482c
21 changed files with 493 additions and 478 deletions

View File

@@ -15,6 +15,7 @@
#include "TestPrinters.h"
#include "ValueMatcher.h"
#include "gmock/gmock.h"
#include "net/MockMessageHandler.h"
#include "net/MockNetworkInterface.h"
#include "ntcore_c.h"
#include "ntcore_cpp.h"
@@ -48,7 +49,7 @@ class LocalStorageTest : public ::testing::Test {
public:
LocalStorageTest() { storage.StartNetwork(&network); }
::testing::StrictMock<net::MockNetworkInterface> network;
::testing::StrictMock<net::MockClientMessageHandler> network;
wpi::MockLogger logger;
MockListenerStorage listenerStorage;
LocalStorage storage{0, listenerStorage, logger};
@@ -79,8 +80,8 @@ TEST_F(LocalStorageTest, GetEntryEmptyName) {
}
TEST_F(LocalStorageTest, GetEntryCached) {
EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"tocache"}}),
IsDefaultPubSubOptions()));
EXPECT_CALL(network, ClientSubscribe(_, wpi::SpanEq({std::string{"tocache"}}),
IsDefaultPubSubOptions()));
auto entry1 = storage.GetEntry("tocache");
EXPECT_EQ(entry1, storage.GetEntry("tocache"));
@@ -105,9 +106,10 @@ TEST_F(LocalStorageTest, GetTopicInfoUnpublished) {
}
TEST_F(LocalStorageTest, DefaultProps) {
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(
network,
ClientPublish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
storage.Publish(fooTopic, NT_BOOLEAN, "boolean", wpi::json::object(), {});
EXPECT_FALSE(storage.GetTopicPersistent(fooTopic));
@@ -116,9 +118,10 @@ TEST_F(LocalStorageTest, DefaultProps) {
}
TEST_F(LocalStorageTest, PublishNewNoProps) {
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(
network,
ClientPublish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
storage.Publish(fooTopic, NT_BOOLEAN, "boolean", wpi::json::object(), {});
auto info = storage.GetTopicInfo(fooTopic);
@@ -126,9 +129,10 @@ TEST_F(LocalStorageTest, PublishNewNoProps) {
}
TEST_F(LocalStorageTest, PublishNewNoPropsNull) {
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(
network,
ClientPublish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {}, {});
auto info = storage.GetTopicInfo(fooTopic);
@@ -137,9 +141,9 @@ TEST_F(LocalStorageTest, PublishNewNoPropsNull) {
TEST_F(LocalStorageTest, PublishNew) {
wpi::json properties = {{"persistent", true}};
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"boolean"},
properties, IsDefaultPubSubOptions()));
EXPECT_CALL(network, ClientPublish(_, std::string_view{"foo"},
std::string_view{"boolean"}, properties,
IsDefaultPubSubOptions()));
storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {{"persistent", true}}, {});
auto info = storage.GetTopicInfo(fooTopic);
@@ -155,17 +159,18 @@ TEST_F(LocalStorageTest, PublishNew) {
}
TEST_F(LocalStorageTest, SubscribeNoTypeLocalPubPost) {
EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
EXPECT_CALL(network, ClientSubscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
auto sub = storage.Subscribe(fooTopic, NT_UNASSIGNED, "", {});
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(
network,
ClientPublish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
auto pub = storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {}, {});
auto val = Value::MakeBoolean(true, 5);
EXPECT_CALL(network, SetValue(Handle{pub}.GetIndex(), val));
EXPECT_CALL(network, ClientSetValue(Handle{pub}.GetIndex(), val));
storage.SetEntryValue(pub, val);
EXPECT_EQ(storage.GetTopicType(fooTopic), NT_BOOLEAN);
@@ -183,7 +188,7 @@ TEST_F(LocalStorageTest, SubscribeNoTypeLocalPubPost) {
EXPECT_EQ(vals[0].time, 5);
val = Value::MakeBoolean(false, 6);
EXPECT_CALL(network, SetValue(Handle{pub}.GetIndex(), val));
EXPECT_CALL(network, ClientSetValue(Handle{pub}.GetIndex(), val));
storage.SetEntryValue(pub, val);
auto vals2 = storage.ReadQueue<int64_t>(sub); // mismatched type
@@ -191,17 +196,18 @@ TEST_F(LocalStorageTest, SubscribeNoTypeLocalPubPost) {
}
TEST_F(LocalStorageTest, SubscribeNoTypeLocalPubPre) {
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(
network,
ClientPublish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
auto pub = storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {}, {});
auto val = Value::MakeBoolean(true, 5);
EXPECT_CALL(network, SetValue(Handle{pub}.GetIndex(), val));
EXPECT_CALL(network, ClientSetValue(Handle{pub}.GetIndex(), val));
storage.SetEntryValue(pub, val);
EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
EXPECT_CALL(network, ClientSubscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
auto sub = storage.Subscribe(fooTopic, NT_UNASSIGNED, "", {});
EXPECT_EQ(storage.GetTopicType(fooTopic), NT_BOOLEAN);
@@ -215,16 +221,17 @@ TEST_F(LocalStorageTest, SubscribeNoTypeLocalPubPre) {
}
TEST_F(LocalStorageTest, EntryNoTypeLocalSet) {
EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
EXPECT_CALL(network, ClientSubscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
auto entry = storage.GetEntry(fooTopic, NT_UNASSIGNED, "", {});
// results in a publish and value set
auto val = Value::MakeBoolean(true, 5);
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(network, SetValue(_, val));
EXPECT_CALL(
network,
ClientPublish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(network, ClientSetValue(_, val));
EXPECT_TRUE(storage.SetEntryValue(entry, val));
EXPECT_EQ(storage.GetTopicType(fooTopic), NT_BOOLEAN);
@@ -243,7 +250,7 @@ TEST_F(LocalStorageTest, EntryNoTypeLocalSet) {
// normal set with same type
val = Value::MakeBoolean(false, 6);
EXPECT_CALL(network, SetValue(_, val));
EXPECT_CALL(network, ClientSetValue(_, val));
EXPECT_TRUE(storage.SetEntryValue(entry, val));
auto vals2 = storage.ReadQueue<int64_t>(entry); // mismatched type
@@ -261,13 +268,14 @@ TEST_F(LocalStorageTest, EntryNoTypeLocalSet) {
}
TEST_F(LocalStorageTest, PubUnpubPub) {
EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
EXPECT_CALL(network, ClientSubscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
auto sub = storage.Subscribe(fooTopic, NT_INTEGER, "int", {});
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(
network,
ClientPublish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(logger,
Call(NT_LOG_INFO, _, _,
std::string_view{
@@ -276,7 +284,7 @@ TEST_F(LocalStorageTest, PubUnpubPub) {
auto pub = storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {}, {});
auto val = Value::MakeBoolean(true, 5);
EXPECT_CALL(network, SetValue(Handle{pub}.GetIndex(), val));
EXPECT_CALL(network, ClientSetValue(Handle{pub}.GetIndex(), val));
EXPECT_TRUE(storage.SetEntryValue(pub, val));
EXPECT_EQ(storage.GetTopicType(fooTopic), NT_BOOLEAN);
@@ -285,7 +293,7 @@ TEST_F(LocalStorageTest, PubUnpubPub) {
EXPECT_TRUE(storage.ReadQueue<int64_t>(sub).empty());
EXPECT_CALL(network, Unpublish(Handle{pub}.GetIndex()));
EXPECT_CALL(network, ClientUnpublish(Handle{pub}.GetIndex()));
storage.Unpublish(pub);
EXPECT_EQ(storage.GetTopicType(fooTopic), NT_UNASSIGNED);
@@ -293,12 +301,12 @@ TEST_F(LocalStorageTest, PubUnpubPub) {
EXPECT_FALSE(storage.GetTopicExists(fooTopic));
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"int"},
wpi::json::object(), IsDefaultPubSubOptions()));
ClientPublish(_, std::string_view{"foo"}, std::string_view{"int"},
wpi::json::object(), IsDefaultPubSubOptions()));
pub = storage.Publish(fooTopic, NT_INTEGER, "int", {}, {});
val = Value::MakeInteger(3, 5);
EXPECT_CALL(network, SetValue(Handle{pub}.GetIndex(), val));
EXPECT_CALL(network, ClientSetValue(Handle{pub}.GetIndex(), val));
EXPECT_TRUE(storage.SetEntryValue(pub, val));
EXPECT_EQ(storage.GetTopicType(fooTopic), NT_INTEGER);
@@ -309,9 +317,10 @@ TEST_F(LocalStorageTest, PubUnpubPub) {
}
TEST_F(LocalStorageTest, LocalPubConflict) {
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(
network,
ClientPublish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
auto pub1 = storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {}, {});
EXPECT_CALL(
@@ -325,36 +334,37 @@ TEST_F(LocalStorageTest, LocalPubConflict) {
EXPECT_EQ(storage.GetTopicTypeString(fooTopic), "boolean");
EXPECT_TRUE(storage.GetTopicExists(fooTopic));
EXPECT_CALL(network, SetValue(Handle{pub1}.GetIndex(), _));
EXPECT_CALL(network, ClientSetValue(Handle{pub1}.GetIndex(), _));
EXPECT_TRUE(storage.SetEntryValue(pub1, Value::MakeBoolean(true, 5)));
EXPECT_FALSE(storage.SetEntryValue(pub2, Value::MakeInteger(3, 5)));
// unpublishing pub1 will publish pub2 to the network
EXPECT_CALL(network, Unpublish(Handle{pub1}.GetIndex()));
EXPECT_CALL(network, ClientUnpublish(Handle{pub1}.GetIndex()));
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"int"},
wpi::json::object(), IsDefaultPubSubOptions()));
ClientPublish(_, std::string_view{"foo"}, std::string_view{"int"},
wpi::json::object(), IsDefaultPubSubOptions()));
storage.Unpublish(pub1);
EXPECT_EQ(storage.GetTopicType(fooTopic), NT_INTEGER);
EXPECT_EQ(storage.GetTopicTypeString(fooTopic), "int");
EXPECT_TRUE(storage.GetTopicExists(fooTopic));
EXPECT_CALL(network, SetValue(Handle{pub2}.GetIndex(), _));
EXPECT_CALL(network, ClientSetValue(Handle{pub2}.GetIndex(), _));
EXPECT_FALSE(storage.SetEntryValue(pub1, Value::MakeBoolean(true, 5)));
EXPECT_TRUE(storage.SetEntryValue(pub2, Value::MakeInteger(3, 5)));
}
TEST_F(LocalStorageTest, LocalSubConflict) {
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(
network,
ClientPublish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {}, {});
EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
EXPECT_CALL(network, ClientSubscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
EXPECT_CALL(logger,
Call(NT_LOG_INFO, _, _,
std::string_view{
@@ -364,9 +374,10 @@ TEST_F(LocalStorageTest, LocalSubConflict) {
}
TEST_F(LocalStorageTest, RemotePubConflict) {
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(
network,
ClientPublish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {}, {});
@@ -376,18 +387,20 @@ TEST_F(LocalStorageTest, RemotePubConflict) {
"network announce of 'foo' overriding local publish "
"(was 'boolean', now 'int')"}));
storage.NetworkAnnounce("foo", "int", wpi::json::object(), std::nullopt);
auto id = storage.ServerAnnounce("foo", 0, "int", wpi::json::object(),
std::nullopt);
// network overrides local
EXPECT_EQ(storage.GetTopicType(fooTopic), NT_INTEGER);
EXPECT_EQ(storage.GetTopicTypeString(fooTopic), "int");
EXPECT_TRUE(storage.GetTopicExists(fooTopic));
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(
network,
ClientPublish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
storage.NetworkUnannounce("foo");
storage.ServerUnannounce("foo", id);
EXPECT_EQ(storage.GetTopicType(fooTopic), NT_BOOLEAN);
EXPECT_EQ(storage.GetTopicTypeString(fooTopic), "boolean");
@@ -396,15 +409,15 @@ TEST_F(LocalStorageTest, RemotePubConflict) {
TEST_F(LocalStorageTest, SubNonExist) {
// makes sure no warning is emitted
EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
EXPECT_CALL(network, ClientSubscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
storage.Subscribe(fooTopic, NT_BOOLEAN, "boolean", {});
}
TEST_F(LocalStorageTest, SetDefaultSubscribe) {
// no publish, no value on wire, this is just handled locally
EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
EXPECT_CALL(network, ClientSubscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
auto sub = storage.Subscribe(fooTopic, NT_BOOLEAN, "boolean", {});
EXPECT_TRUE(storage.SetDefaultEntryValue(sub, Value::MakeBoolean(true)));
auto val = storage.GetEntryValue(sub);
@@ -414,17 +427,18 @@ TEST_F(LocalStorageTest, SetDefaultSubscribe) {
}
TEST_F(LocalStorageTest, SetDefaultPublish) {
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(
network,
ClientPublish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
auto pub = storage.Publish(fooTopic, NT_BOOLEAN, "boolean", {}, {});
// expect a value across the wire
auto expectVal = Value::MakeBoolean(true, 0);
EXPECT_CALL(network, SetValue(Handle{pub}.GetIndex(), expectVal));
EXPECT_CALL(network, ClientSetValue(Handle{pub}.GetIndex(), expectVal));
EXPECT_TRUE(storage.SetDefaultEntryValue(pub, Value::MakeBoolean(true)));
EXPECT_CALL(network, Subscribe(_, _, IsDefaultPubSubOptions()));
EXPECT_CALL(network, ClientSubscribe(_, _, IsDefaultPubSubOptions()));
auto sub = storage.Subscribe(fooTopic, NT_BOOLEAN, "boolean", {});
auto val = storage.GetEntryValue(sub);
ASSERT_TRUE(val.IsBoolean());
@@ -433,16 +447,17 @@ TEST_F(LocalStorageTest, SetDefaultPublish) {
}
TEST_F(LocalStorageTest, SetDefaultEntry) {
EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
EXPECT_CALL(network, ClientSubscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
auto entry = storage.GetEntry(fooTopic, NT_BOOLEAN, "boolean", {});
// expect a publish and value
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(
network,
ClientPublish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
auto expectVal = Value::MakeBoolean(true, 0);
EXPECT_CALL(network, SetValue(_, expectVal));
EXPECT_CALL(network, ClientSetValue(_, expectVal));
EXPECT_TRUE(storage.SetDefaultEntryValue(entry, Value::MakeBoolean(true)));
auto val = storage.GetEntryValue(entry);
@@ -452,16 +467,17 @@ TEST_F(LocalStorageTest, SetDefaultEntry) {
}
TEST_F(LocalStorageTest, SetDefaultEntryUnassigned) {
EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
EXPECT_CALL(network, ClientSubscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
auto entry = storage.GetEntry(fooTopic, NT_UNASSIGNED, "", {});
// expect a publish and value
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(
network,
ClientPublish(_, std::string_view{"foo"}, std::string_view{"boolean"},
wpi::json::object(), IsDefaultPubSubOptions()));
auto expectVal = Value::MakeBoolean(true, 0);
EXPECT_CALL(network, SetValue(_, expectVal));
EXPECT_CALL(network, ClientSetValue(_, expectVal));
EXPECT_TRUE(storage.SetDefaultEntryValue(entry, Value::MakeBoolean(true)));
ASSERT_EQ(storage.GetTopicType(fooTopic), NT_BOOLEAN);
@@ -472,9 +488,10 @@ TEST_F(LocalStorageTest, SetDefaultEntryUnassigned) {
}
TEST_F(LocalStorageTest, SetDefaultEntryDiffType) {
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"string"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(
network,
ClientPublish(_, std::string_view{"foo"}, std::string_view{"string"},
wpi::json::object(), IsDefaultPubSubOptions()));
auto pub = storage.Publish(fooTopic, NT_STRING, "string", {}, {});
EXPECT_FALSE(storage.SetDefaultEntryValue(pub, Value::MakeBoolean(true)));
@@ -482,17 +499,18 @@ TEST_F(LocalStorageTest, SetDefaultEntryDiffType) {
}
TEST_F(LocalStorageTest, SetValueEmptyValue) {
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"string"},
wpi::json::object(), IsDefaultPubSubOptions()));
EXPECT_CALL(
network,
ClientPublish(_, std::string_view{"foo"}, std::string_view{"string"},
wpi::json::object(), IsDefaultPubSubOptions()));
auto pub = storage.Publish(fooTopic, NT_STRING, "string", {}, {});
EXPECT_FALSE(storage.SetEntryValue(pub, {}));
}
TEST_F(LocalStorageTest, SetValueEmptyUntypedEntry) {
EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
EXPECT_CALL(network, ClientSubscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsDefaultPubSubOptions()));
auto entry = storage.GetEntry(fooTopic, NT_UNASSIGNED, "", {});
EXPECT_FALSE(storage.SetEntryValue(entry, {}));
}
@@ -525,17 +543,18 @@ class LocalStorageDuplicatesTest : public LocalStorageTest {
void LocalStorageDuplicatesTest::SetupPubSub(bool keepPub, bool keepSub) {
PubSubOptionsImpl pubOptions;
pubOptions.keepDuplicates = keepPub;
EXPECT_CALL(network,
Publish(_, std::string_view{"foo"}, std::string_view{"double"},
wpi::json::object(), IsPubSubOptions(pubOptions)));
EXPECT_CALL(
network,
ClientPublish(_, std::string_view{"foo"}, std::string_view{"double"},
wpi::json::object(), IsPubSubOptions(pubOptions)));
pub = storage.Publish(fooTopic, NT_DOUBLE, "double", {},
{.keepDuplicates = keepPub});
PubSubOptionsImpl subOptions;
subOptions.pollStorage = 10;
subOptions.keepDuplicates = keepSub;
EXPECT_CALL(network, Subscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsPubSubOptions(subOptions)));
EXPECT_CALL(network, ClientSubscribe(_, wpi::SpanEq({std::string{"foo"}}),
IsPubSubOptions(subOptions)));
sub = storage.Subscribe(fooTopic, NT_DOUBLE, "double",
{.pollStorage = 10, .keepDuplicates = keepSub});
}
@@ -552,8 +571,8 @@ void LocalStorageDuplicatesTest::SetValues(bool expectDuplicates) {
TEST_F(LocalStorageDuplicatesTest, Defaults) {
SetupPubSub(false, false);
EXPECT_CALL(network, SetValue(Handle{pub}.GetIndex(), val1));
EXPECT_CALL(network, SetValue(Handle{pub}.GetIndex(), val3));
EXPECT_CALL(network, ClientSetValue(Handle{pub}.GetIndex(), val1));
EXPECT_CALL(network, ClientSetValue(Handle{pub}.GetIndex(), val3));
SetValues(false);
// verify 2nd update was dropped locally
@@ -568,9 +587,9 @@ TEST_F(LocalStorageDuplicatesTest, Defaults) {
TEST_F(LocalStorageDuplicatesTest, KeepPub) {
SetupPubSub(true, false);
EXPECT_CALL(network, SetValue(Handle{pub}.GetIndex(), val1)).Times(2);
EXPECT_CALL(network, ClientSetValue(Handle{pub}.GetIndex(), val1)).Times(2);
// EXPECT_CALL(network, SetValue(pub, val2));
EXPECT_CALL(network, SetValue(Handle{pub}.GetIndex(), val3));
EXPECT_CALL(network, ClientSetValue(Handle{pub}.GetIndex(), val3));
SetValues(true);
// verify only 2 updates were received locally
@@ -582,8 +601,8 @@ TEST_F(LocalStorageDuplicatesTest, KeepSub) {
SetupPubSub(false, true);
// second update should NOT go to the network
EXPECT_CALL(network, SetValue(Handle{pub}.GetIndex(), val1));
EXPECT_CALL(network, SetValue(Handle{pub}.GetIndex(), val3));
EXPECT_CALL(network, ClientSetValue(Handle{pub}.GetIndex(), val1));
EXPECT_CALL(network, ClientSetValue(Handle{pub}.GetIndex(), val3));
SetValues(false);
// verify 2 updates were received locally
@@ -595,9 +614,9 @@ TEST_F(LocalStorageDuplicatesTest, KeepPubSub) {
SetupPubSub(true, true);
// second update SHOULD go to the network
EXPECT_CALL(network, SetValue(Handle{pub}.GetIndex(), val1)).Times(2);
EXPECT_CALL(network, ClientSetValue(Handle{pub}.GetIndex(), val1)).Times(2);
// EXPECT_CALL(network, SetValue(pub, val2));
EXPECT_CALL(network, SetValue(Handle{pub}.GetIndex(), val3));
EXPECT_CALL(network, ClientSetValue(Handle{pub}.GetIndex(), val3));
SetValues(true);
// verify all 3 updates were received locally
@@ -609,12 +628,12 @@ TEST_F(LocalStorageDuplicatesTest, FromNetworkDefault) {
SetupPubSub(false, false);
// incoming from the network are treated like a normal local publish
auto topic = storage.NetworkAnnounce("foo", "double", {{}}, std::nullopt);
storage.NetworkSetValue(topic, val1);
storage.NetworkSetValue(topic, val2);
auto topic = storage.ServerAnnounce("foo", 0, "double", {{}}, std::nullopt);
storage.ServerSetValue(topic, val1);
storage.ServerSetValue(topic, val2);
// verify the timestamp was updated
EXPECT_EQ(storage.GetEntryLastChange(sub), val2.time());
storage.NetworkSetValue(topic, val3);
storage.ServerSetValue(topic, val3);
// verify 2nd update was dropped for local subscriber
auto values = storage.ReadQueue<double>(sub);
@@ -629,12 +648,12 @@ TEST_F(LocalStorageDuplicatesTest, FromNetworkKeepPub) {
SetupPubSub(true, false);
// incoming from the network are treated like a normal local publish
auto topic = storage.NetworkAnnounce("foo", "double", {{}}, std::nullopt);
storage.NetworkSetValue(topic, val1);
storage.NetworkSetValue(topic, val2);
auto topic = storage.ServerAnnounce("foo", 0, "double", {{}}, std::nullopt);
storage.ServerSetValue(topic, val1);
storage.ServerSetValue(topic, val2);
// verify the timestamp was updated
EXPECT_EQ(storage.GetEntryLastChange(sub), val2.time());
storage.NetworkSetValue(topic, val3);
storage.ServerSetValue(topic, val3);
// verify 2nd update was dropped for local subscriber
auto values = storage.ReadQueue<double>(sub);
@@ -648,12 +667,12 @@ TEST_F(LocalStorageDuplicatesTest, FromNetworkKeepSub) {
SetupPubSub(false, true);
// incoming from the network are treated like a normal local publish
auto topic = storage.NetworkAnnounce("foo", "double", {{}}, std::nullopt);
storage.NetworkSetValue(topic, val1);
storage.NetworkSetValue(topic, val2);
auto topic = storage.ServerAnnounce("foo", 0, "double", {{}}, std::nullopt);
storage.ServerSetValue(topic, val1);
storage.ServerSetValue(topic, val2);
// verify the timestamp was updated
EXPECT_EQ(storage.GetEntryLastChange(sub), val2.time());
storage.NetworkSetValue(topic, val3);
storage.ServerSetValue(topic, val3);
// verify 2nd update was received by local subscriber
auto values = storage.ReadQueue<double>(sub);
@@ -670,12 +689,12 @@ TEST_F(LocalStorageDuplicatesTest, FromNetworkKeepPubSub) {
SetupPubSub(true, true);
// incoming from the network are treated like a normal local publish
auto topic = storage.NetworkAnnounce("foo", "double", {{}}, std::nullopt);
storage.NetworkSetValue(topic, val1);
storage.NetworkSetValue(topic, val2);
auto topic = storage.ServerAnnounce("foo", 0, "double", {{}}, std::nullopt);
storage.ServerSetValue(topic, val1);
storage.ServerSetValue(topic, val2);
// verify the timestamp was updated
EXPECT_EQ(storage.GetEntryLastChange(sub), val2.time());
storage.NetworkSetValue(topic, val3);
storage.ServerSetValue(topic, val3);
// verify 2nd update was received by local subscriber
auto values = storage.ReadQueue<double>(sub);
@@ -745,9 +764,9 @@ void LocalStorageNumberVariantsTest::CreateSubscribersArray() {
}
TEST_F(LocalStorageNumberVariantsTest, GetEntryPubAfter) {
EXPECT_CALL(network, Subscribe(_, _, _)).Times(5);
EXPECT_CALL(network, Publish(_, _, _, _, _)).Times(1);
EXPECT_CALL(network, SetValue(_, _)).Times(1);
EXPECT_CALL(network, ClientSubscribe(_, _, _)).Times(5);
EXPECT_CALL(network, ClientPublish(_, _, _, _, _)).Times(1);
EXPECT_CALL(network, ClientSetValue(_, _)).Times(1);
CreateSubscribers();
auto pub = storage.Publish(fooTopic, NT_DOUBLE, "double", {}, {});
storage.SetEntryValue(pub, Value::MakeDouble(1.0, 50));
@@ -767,9 +786,9 @@ TEST_F(LocalStorageNumberVariantsTest, GetEntryPubAfter) {
}
TEST_F(LocalStorageNumberVariantsTest, GetEntryPubBefore) {
EXPECT_CALL(network, Subscribe(_, _, _)).Times(5);
EXPECT_CALL(network, Publish(_, _, _, _, _)).Times(1);
EXPECT_CALL(network, SetValue(_, _)).Times(1);
EXPECT_CALL(network, ClientSubscribe(_, _, _)).Times(5);
EXPECT_CALL(network, ClientPublish(_, _, _, _, _)).Times(1);
EXPECT_CALL(network, ClientSetValue(_, _)).Times(1);
auto pub = storage.Publish(fooTopic, NT_DOUBLE, "double", {}, {});
CreateSubscribers();
storage.SetEntryValue(pub, Value::MakeDouble(1.0, 50));
@@ -794,9 +813,9 @@ template <typename T>
}
TEST_F(LocalStorageNumberVariantsTest, GetAtomic) {
EXPECT_CALL(network, Subscribe(_, _, _)).Times(5);
EXPECT_CALL(network, Publish(_, _, _, _, _)).Times(1);
EXPECT_CALL(network, SetValue(_, _)).Times(1);
EXPECT_CALL(network, ClientSubscribe(_, _, _)).Times(5);
EXPECT_CALL(network, ClientPublish(_, _, _, _, _)).Times(1);
EXPECT_CALL(network, ClientSetValue(_, _)).Times(1);
auto pub = storage.Publish(fooTopic, NT_DOUBLE, "double", {}, {});
CreateSubscribers();
storage.SetEntryValue(pub, Value::MakeDouble(1.0, 50));
@@ -822,9 +841,9 @@ template <typename T, typename U>
}
TEST_F(LocalStorageNumberVariantsTest, GetAtomicArray) {
EXPECT_CALL(network, Subscribe(_, _, _)).Times(5);
EXPECT_CALL(network, Publish(_, _, _, _, _)).Times(1);
EXPECT_CALL(network, SetValue(_, _)).Times(1);
EXPECT_CALL(network, ClientSubscribe(_, _, _)).Times(5);
EXPECT_CALL(network, ClientPublish(_, _, _, _, _)).Times(1);
EXPECT_CALL(network, ClientSetValue(_, _)).Times(1);
auto pub = storage.Publish(fooTopic, NT_DOUBLE_ARRAY, "double[]", {}, {});
CreateSubscribersArray();
storage.SetEntryValue(pub, Value::MakeDoubleArray({1.0}, 50));
@@ -846,9 +865,9 @@ TEST_F(LocalStorageNumberVariantsTest, GetAtomicArray) {
}
TEST_F(LocalStorageNumberVariantsTest, ReadQueue) {
EXPECT_CALL(network, Subscribe(_, _, _)).Times(5);
EXPECT_CALL(network, Publish(_, _, _, _, _)).Times(1);
EXPECT_CALL(network, SetValue(_, _)).Times(4);
EXPECT_CALL(network, ClientSubscribe(_, _, _)).Times(5);
EXPECT_CALL(network, ClientPublish(_, _, _, _, _)).Times(1);
EXPECT_CALL(network, ClientSetValue(_, _)).Times(4);
auto pub = storage.Publish(fooTopic, NT_DOUBLE, "double", {}, {});
CreateSubscribers();
@@ -893,9 +912,9 @@ TEST_F(LocalStorageNumberVariantsTest, ReadQueue) {
}
TEST_F(LocalStorageTest, MultiSubSpecial) {
EXPECT_CALL(network, Subscribe(_, _, _)).Times(2);
EXPECT_CALL(network, Publish(_, _, _, _, _)).Times(2);
EXPECT_CALL(network, SetValue(_, _)).Times(2);
EXPECT_CALL(network, ClientSubscribe(_, _, _)).Times(2);
EXPECT_CALL(network, ClientPublish(_, _, _, _, _)).Times(2);
EXPECT_CALL(network, ClientSetValue(_, _)).Times(2);
EXPECT_CALL(listenerStorage, Activate(_, _, _)).Times(2);
auto subnormal = storage.SubscribeMultiple({{""}}, {});
@@ -921,26 +940,26 @@ TEST_F(LocalStorageTest, MultiSubSpecial) {
}
TEST_F(LocalStorageTest, NetworkDuplicateDetect) {
EXPECT_CALL(network, Publish(_, _, _, _, _));
EXPECT_CALL(network, ClientPublish(_, _, _, _, _));
auto pub = storage.Publish(fooTopic, NT_DOUBLE, "double", {}, {});
auto remoteTopic = storage.NetworkAnnounce("foo", "double",
wpi::json::object(), std::nullopt);
auto remoteTopic = storage.ServerAnnounce("foo", 0, "double",
wpi::json::object(), std::nullopt);
// local set
EXPECT_CALL(network, SetValue(_, _));
EXPECT_CALL(network, ClientSetValue(_, _));
storage.SetEntryValue(pub, Value::MakeDouble(1.0, 50));
// 2nd local set with same value - no SetValue call to network
storage.SetEntryValue(pub, Value::MakeDouble(1.0, 60));
// network set with different value
storage.NetworkSetValue(remoteTopic, Value::MakeDouble(2.0, 70));
storage.ServerSetValue(remoteTopic, Value::MakeDouble(2.0, 70));
// 3rd local set with same value generates a SetValue call to network
EXPECT_CALL(network, SetValue(_, _));
EXPECT_CALL(network, ClientSetValue(_, _));
storage.SetEntryValue(pub, Value::MakeDouble(1.0, 80));
}
TEST_F(LocalStorageTest, ReadQueueLocalRemote) {
EXPECT_CALL(network, Subscribe(_, _, _)).Times(3);
EXPECT_CALL(network, Publish(_, _, _, _, _)).Times(1);
EXPECT_CALL(network, ClientSubscribe(_, _, _)).Times(3);
EXPECT_CALL(network, ClientPublish(_, _, _, _, _)).Times(1);
auto subBoth =
storage.Subscribe(fooTopic, NT_DOUBLE, "double", kDefaultPubSubOptions);
@@ -949,11 +968,11 @@ TEST_F(LocalStorageTest, ReadQueueLocalRemote) {
auto subRemote =
storage.Subscribe(fooTopic, NT_DOUBLE, "double", {.disableLocal = true});
auto pub = storage.Publish(fooTopic, NT_DOUBLE, "double", {}, {});
auto remoteTopic = storage.NetworkAnnounce("foo", "double",
wpi::json::object(), std::nullopt);
auto remoteTopic = storage.ServerAnnounce("foo", 0, "double",
wpi::json::object(), std::nullopt);
// local set
EXPECT_CALL(network, SetValue(_, _));
EXPECT_CALL(network, ClientSetValue(_, _));
storage.SetEntryValue(pub, Value::MakeDouble(1.0, 50));
EXPECT_THAT(storage.ReadQueue<double>(subBoth),
ElementsAre(TSEq<TimestampedDouble>(1.0, 50)));
@@ -962,7 +981,7 @@ TEST_F(LocalStorageTest, ReadQueueLocalRemote) {
EXPECT_THAT(storage.ReadQueue<double>(subRemote), IsEmpty());
// network set
storage.NetworkSetValue(remoteTopic, Value::MakeDouble(2.0, 60));
storage.ServerSetValue(remoteTopic, Value::MakeDouble(2.0, 60));
EXPECT_THAT(storage.ReadQueue<double>(subBoth),
ElementsAre(TSEq<TimestampedDouble>(2.0, 60)));
EXPECT_THAT(storage.ReadQueue<double>(subRemote),
@@ -971,25 +990,25 @@ TEST_F(LocalStorageTest, ReadQueueLocalRemote) {
}
TEST_F(LocalStorageTest, SubExcludePub) {
EXPECT_CALL(network, Subscribe(_, _, _)).Times(2);
EXPECT_CALL(network, Publish(_, _, _, _, _)).Times(1);
EXPECT_CALL(network, ClientSubscribe(_, _, _)).Times(2);
EXPECT_CALL(network, ClientPublish(_, _, _, _, _)).Times(1);
auto pub = storage.Publish(fooTopic, NT_DOUBLE, "double", {}, {});
auto subActive = storage.Subscribe(fooTopic, NT_DOUBLE, "double", {});
auto subExclude = storage.Subscribe(fooTopic, NT_DOUBLE, "double",
{.excludePublisher = pub});
auto remoteTopic = storage.NetworkAnnounce("foo", "double",
wpi::json::object(), std::nullopt);
auto remoteTopic = storage.ServerAnnounce("foo", 0, "double",
wpi::json::object(), std::nullopt);
// local set
EXPECT_CALL(network, SetValue(_, _));
EXPECT_CALL(network, ClientSetValue(_, _));
storage.SetEntryValue(pub, Value::MakeDouble(1.0, 50));
EXPECT_THAT(storage.ReadQueue<double>(subActive),
ElementsAre(TSEq<TimestampedDouble>(1.0, 50)));
EXPECT_THAT(storage.ReadQueue<double>(subExclude), IsEmpty());
// network set
storage.NetworkSetValue(remoteTopic, Value::MakeDouble(2.0, 60));
storage.ServerSetValue(remoteTopic, Value::MakeDouble(2.0, 60));
EXPECT_THAT(storage.ReadQueue<double>(subActive),
ElementsAre(TSEq<TimestampedDouble>(2.0, 60)));
EXPECT_THAT(storage.ReadQueue<double>(subExclude),
@@ -997,29 +1016,29 @@ TEST_F(LocalStorageTest, SubExcludePub) {
}
TEST_F(LocalStorageTest, EntryExcludeSelf) {
EXPECT_CALL(network, Subscribe(_, _, _));
EXPECT_CALL(network, ClientSubscribe(_, _, _));
auto entry =
storage.GetEntry(fooTopic, NT_DOUBLE, "double", {.excludeSelf = true});
auto remoteTopic = storage.NetworkAnnounce("foo", "double",
wpi::json::object(), std::nullopt);
auto remoteTopic = storage.ServerAnnounce("foo", 0, "double",
wpi::json::object(), std::nullopt);
// local set
EXPECT_CALL(network, Publish(_, _, _, _, _));
EXPECT_CALL(network, SetValue(_, _));
EXPECT_CALL(network, ClientPublish(_, _, _, _, _));
EXPECT_CALL(network, ClientSetValue(_, _));
storage.SetEntryValue(entry, Value::MakeDouble(1.0, 50));
EXPECT_THAT(storage.ReadQueue<double>(entry), IsEmpty());
// network set
storage.NetworkSetValue(remoteTopic, Value::MakeDouble(2.0, 60));
storage.ServerSetValue(remoteTopic, Value::MakeDouble(2.0, 60));
EXPECT_THAT(storage.ReadQueue<double>(entry),
ElementsAre(TSEq<TimestampedDouble>(2.0, 60)));
}
TEST_F(LocalStorageTest, ReadQueueInitialLocal) {
EXPECT_CALL(network, Publish(_, _, _, _, _));
EXPECT_CALL(network, SetValue(_, _));
EXPECT_CALL(network, Subscribe(_, _, _)).Times(3);
EXPECT_CALL(network, ClientPublish(_, _, _, _, _));
EXPECT_CALL(network, ClientSetValue(_, _));
EXPECT_CALL(network, ClientSubscribe(_, _, _)).Times(3);
auto pub = storage.Publish(fooTopic, NT_DOUBLE, "double", {}, {});
storage.SetEntryValue(pub, Value::MakeDouble(1.0, 50));
@@ -1039,11 +1058,11 @@ TEST_F(LocalStorageTest, ReadQueueInitialLocal) {
}
TEST_F(LocalStorageTest, ReadQueueInitialRemote) {
EXPECT_CALL(network, Subscribe(_, _, _)).Times(3);
EXPECT_CALL(network, ClientSubscribe(_, _, _)).Times(3);
auto remoteTopic = storage.NetworkAnnounce("foo", "double",
wpi::json::object(), std::nullopt);
storage.NetworkSetValue(remoteTopic, Value::MakeDouble(2.0, 60));
auto remoteTopic = storage.ServerAnnounce("foo", 0, "double",
wpi::json::object(), std::nullopt);
storage.ServerSetValue(remoteTopic, Value::MakeDouble(2.0, 60));
auto subBoth =
storage.Subscribe(fooTopic, NT_DOUBLE, "double", kDefaultPubSubOptions);

View File

@@ -0,0 +1,50 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <string>
#include <wpi/json.h>
#include "PubSubOptions.h"
#include "gmock/gmock.h"
#include "net/MessageHandler.h"
namespace nt::net {
class MockClientMessageHandler : public net::ClientMessageHandler {
public:
MOCK_METHOD(void, ClientPublish,
(int pubuid, std::string_view name, std::string_view typeStr,
const wpi::json& properties, const PubSubOptionsImpl& options),
(override));
MOCK_METHOD(void, ClientUnpublish, (int pubuid), (override));
MOCK_METHOD(void, ClientSetProperties,
(std::string_view name, const wpi::json& update), (override));
MOCK_METHOD(void, ClientSubscribe,
(int subuid, std::span<const std::string> prefixes,
const PubSubOptionsImpl& options),
(override));
MOCK_METHOD(void, ClientUnsubscribe, (int subuid), (override));
MOCK_METHOD(void, ClientSetValue, (int pubuid, const Value& value),
(override));
};
class MockServerMessageHandler : public net::ServerMessageHandler {
public:
MOCK_METHOD(int, ServerAnnounce,
(std::string_view name, int id, std::string_view typeStr,
const wpi::json& properties, std::optional<int> pubuid),
(override));
MOCK_METHOD(void, ServerUnannounce, (std::string_view name, int id),
(override));
MOCK_METHOD(void, ServerPropertiesUpdate,
(std::string_view name, const wpi::json& update, bool ack),
(override));
MOCK_METHOD(void, ServerSetValue, (int topicuid, const Value& value),
(override));
};
} // namespace nt::net

View File

@@ -4,60 +4,27 @@
#pragma once
#include <string>
#include <wpi/json.h>
#include "PubSubOptions.h"
#include "gmock/gmock.h"
#include "net/NetworkInterface.h"
namespace nt::net {
class MockLocalInterface : public LocalInterface {
public:
MOCK_METHOD(NT_Topic, NetworkAnnounce,
(std::string_view name, std::string_view typeStr,
const wpi::json& properties, std::optional<int> pubuid),
(override));
MOCK_METHOD(void, NetworkUnannounce, (std::string_view name), (override));
MOCK_METHOD(void, NetworkPropertiesUpdate,
(std::string_view name, const wpi::json& update, bool ack),
(override));
MOCK_METHOD(void, NetworkSetValue, (NT_Topic topicHandle, const Value& value),
(override));
};
class MockNetworkInterface : public NetworkInterface {
public:
MOCK_METHOD(void, Publish,
(int pubuid, std::string_view name, std::string_view typeStr,
const wpi::json& properties, const PubSubOptionsImpl& options),
(override));
MOCK_METHOD(void, Unpublish, (int pubuid), (override));
MOCK_METHOD(void, SetProperties,
(std::string_view name, const wpi::json& update), (override));
MOCK_METHOD(void, Subscribe,
(int subuid, std::span<const std::string> prefixes,
const PubSubOptionsImpl& options),
(override));
MOCK_METHOD(void, Unsubscribe, (int subuid), (override));
MOCK_METHOD(void, SetValue, (int pubuid, const Value& value), (override));
};
class MockLocalStorage : public ILocalStorage {
public:
MOCK_METHOD(NT_Topic, NetworkAnnounce,
(std::string_view name, std::string_view typeStr,
MOCK_METHOD(int, ServerAnnounce,
(std::string_view name, int id, std::string_view typeStr,
const wpi::json& properties, std::optional<int> pubuid),
(override));
MOCK_METHOD(void, NetworkUnannounce, (std::string_view name), (override));
MOCK_METHOD(void, NetworkPropertiesUpdate,
MOCK_METHOD(void, ServerUnannounce, (std::string_view name, int id),
(override));
MOCK_METHOD(void, ServerPropertiesUpdate,
(std::string_view name, const wpi::json& update, bool ack),
(override));
MOCK_METHOD(void, NetworkSetValue, (NT_Topic topicHandle, const Value& value),
MOCK_METHOD(void, ServerSetValue, (int topicId, const Value& value),
(override));
MOCK_METHOD(void, StartNetwork, (NetworkInterface * network), (override));
MOCK_METHOD(void, StartNetwork, (ClientMessageHandler * network), (override));
MOCK_METHOD(void, ClearNetwork, (), (override));
};

View File

@@ -18,7 +18,7 @@
#include "../TestPrinters.h"
#include "../ValueMatcher.h"
#include "Handle.h"
#include "MockNetworkInterface.h"
#include "MockMessageHandler.h"
#include "MockWireConnection.h"
#include "gmock/gmock.h"
#include "net/Message.h"
@@ -44,7 +44,7 @@ namespace nt {
class ServerImplTest : public ::testing::Test {
public:
::testing::StrictMock<net::MockLocalInterface> local;
::testing::StrictMock<net::MockServerMessageHandler> local;
wpi::MockLogger logger;
net::ServerImpl server{logger};
};
@@ -150,17 +150,18 @@ TEST_F(ServerImplTest, PublishLocal) {
constexpr int pubuid3 = 3;
{
::testing::InSequence seq;
EXPECT_CALL(local, NetworkAnnounce(
std::string_view{"test"}, std::string_view{"double"},
wpi::json::object(), std::optional<int>{pubuid}));
EXPECT_CALL(
local,
NetworkAnnounce(std::string_view{"test2"}, std::string_view{"double"},
wpi::json::object(), std::optional<int>{pubuid2}));
ServerAnnounce(std::string_view{"test"}, 0, std::string_view{"double"},
wpi::json::object(), std::optional<int>{pubuid}));
EXPECT_CALL(
local,
NetworkAnnounce(std::string_view{"test3"}, std::string_view{"double"},
wpi::json::object(), std::optional<int>{pubuid3}));
ServerAnnounce(std::string_view{"test2"}, 0, std::string_view{"double"},
wpi::json::object(), std::optional<int>{pubuid2}));
EXPECT_CALL(
local,
ServerAnnounce(std::string_view{"test3"}, 0, std::string_view{"double"},
wpi::json::object(), std::optional<int>{pubuid3}));
}
{
@@ -235,9 +236,10 @@ TEST_F(ServerImplTest, ClientSubTopicOnlyThenValue) {
// publish before client connect
server.SetLocal(&local);
constexpr int pubuid = 1;
EXPECT_CALL(local, NetworkAnnounce(
std::string_view{"test"}, std::string_view{"double"},
wpi::json::object(), std::optional<int>{pubuid}));
EXPECT_CALL(
local,
ServerAnnounce(std::string_view{"test"}, 0, std::string_view{"double"},
wpi::json::object(), std::optional<int>{pubuid}));
{
std::vector<net::ClientMessage> msgs;
@@ -311,12 +313,13 @@ TEST_F(ServerImplTest, ClientDisconnectUnpublish) {
::testing::InSequence seq;
EXPECT_CALL(
local,
NetworkAnnounce(std::string_view{"test2"}, std::string_view{"double"},
wpi::json::object(), std::optional<int>{pubuidLocal}));
EXPECT_CALL(local, NetworkAnnounce(
std::string_view{"test"}, std::string_view{"double"},
wpi::json::object(), std::optional<int>{}));
EXPECT_CALL(local, NetworkUnannounce(std::string_view{"test"}));
ServerAnnounce(std::string_view{"test2"}, 0, std::string_view{"double"},
wpi::json::object(), std::optional<int>{pubuidLocal}));
EXPECT_CALL(
local,
ServerAnnounce(std::string_view{"test"}, 0, std::string_view{"double"},
wpi::json::object(), std::optional<int>{}));
EXPECT_CALL(local, ServerUnannounce(std::string_view{"test"}, 0));
}
{
@@ -381,12 +384,13 @@ TEST_F(ServerImplTest, ZeroTimestampNegativeTime) {
Value value = Value::MakeDouble(5, -10);
{
::testing::InSequence seq;
EXPECT_CALL(local, NetworkAnnounce(
std::string_view{"test"}, std::string_view{"double"},
wpi::json::object(), std::optional<int>{pubuid}))
EXPECT_CALL(
local,
ServerAnnounce(std::string_view{"test"}, 0, std::string_view{"double"},
wpi::json::object(), std::optional<int>{pubuid}))
.WillOnce(Return(topicHandle));
EXPECT_CALL(local, NetworkSetValue(topicHandle, defaultValue));
EXPECT_CALL(local, NetworkSetValue(topicHandle, value));
EXPECT_CALL(local, ServerSetValue(topicHandle, defaultValue));
EXPECT_CALL(local, ServerSetValue(topicHandle, value));
}
{

View File

@@ -9,9 +9,12 @@
#include <wpi/raw_ostream.h>
#include "../MockLogger.h"
#include "../PubSubOptionsMatcher.h"
#include "../TestPrinters.h"
#include "MockMessageHandler.h"
#include "PubSubOptions.h"
#include "gmock/gmock.h"
#include "net/Message.h"
#include "net/MessageHandler.h"
#include "net/WireDecoder.h"
#include "networktables/NetworkTableValue.h"
@@ -22,39 +25,15 @@ using testing::StrictMock;
namespace nt {
class MockClientMessageHandler : public net::ClientMessageHandler {
public:
MOCK_METHOD4(ClientPublish,
void(int pubuid, std::string_view name, std::string_view typeStr,
const wpi::json& properties));
MOCK_METHOD1(ClientUnpublish, void(int pubuid));
MOCK_METHOD2(ClientSetProperties,
void(std::string_view name, const wpi::json& update));
MOCK_METHOD3(ClientSubscribe,
void(int subuid, std::span<const std::string> prefixes,
const PubSubOptionsImpl& options));
MOCK_METHOD1(ClientUnsubscribe, void(int subuid));
};
class MockServerMessageHandler : public net::ServerMessageHandler {
public:
MOCK_METHOD5(ServerAnnounce,
void(std::string_view name, int id, std::string_view typeStr,
const wpi::json& properties, std::optional<int> pubuid));
MOCK_METHOD2(ServerUnannounce, void(std::string_view name, int id));
MOCK_METHOD3(ServerPropertiesUpdate,
void(std::string_view name, const wpi::json& update, bool ack));
};
class WireDecodeTextClientTest : public ::testing::Test {
public:
StrictMock<MockClientMessageHandler> handler;
StrictMock<net::MockClientMessageHandler> handler;
StrictMock<wpi::MockLogger> logger;
};
class WireDecodeTextServerTest : public ::testing::Test {
public:
StrictMock<MockServerMessageHandler> handler;
StrictMock<net::MockServerMessageHandler> handler;
StrictMock<wpi::MockLogger> logger;
};
@@ -129,17 +108,17 @@ TEST_F(WireDecodeTextClientTest, ErrorUnknownMethod) {
}
TEST_F(WireDecodeTextClientTest, PublishPropsEmpty) {
EXPECT_CALL(handler,
ClientPublish(5, std::string_view{"test"},
std::string_view{"double"}, wpi::json::object()));
EXPECT_CALL(handler, ClientPublish(5, std::string_view{"test"},
std::string_view{"double"},
wpi::json::object(), PubSubOptionsEq({})));
net::WireDecodeText(
"[{\"method\":\"publish\",\"params\":{"
"\"name\":\"test\",\"properties\":{},\"pubuid\":5,\"type\":\"double\"}}]",
handler, logger);
EXPECT_CALL(handler,
ClientPublish(5, std::string_view{"test"},
std::string_view{"double"}, wpi::json::object()));
EXPECT_CALL(handler, ClientPublish(5, std::string_view{"test"},
std::string_view{"double"},
wpi::json::object(), PubSubOptionsEq({})));
net::WireDecodeText(
"[{\"method\":\"publish\",\"params\":{"
"\"name\":\"test\",\"pubuid\":5,\"type\":\"double\"}}]",
@@ -149,7 +128,8 @@ TEST_F(WireDecodeTextClientTest, PublishPropsEmpty) {
TEST_F(WireDecodeTextClientTest, PublishProps) {
wpi::json props = {{"k", 6}};
EXPECT_CALL(handler, ClientPublish(5, std::string_view{"test"},
std::string_view{"double"}, props));
std::string_view{"double"}, props,
PubSubOptionsEq({})));
net::WireDecodeText(
"[{\"method\":\"publish\",\"params\":{"
"\"name\":\"test\",\"properties\":{\"k\":6},"