blob: 575d0b75df72e4ab275b5bcadad9aaef93b529c1 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/connectivity/overnet/lib/links/packet_stuffer.h"
#include <gtest/gtest.h>
#include "src/connectivity/overnet/lib/testing/test_timer.h"
namespace overnet {
namespace packet_stuffer_test {
constexpr TimeStamp kDummyTimestamp123 =
TimeStamp::AfterEpoch(TimeDelta::FromMicroseconds(123));
Message DummyMessage() {
return Message{std::move(RoutableMessage(NodeId(1)).AddDestination(
NodeId(2), StreamId(1), SeqNum(1, 1))),
ForwardingPayloadFactory(Slice::FromContainer({1, 2, 3})),
kDummyTimestamp123};
}
template <class T>
void IgnoreResult(T&& value) {}
TEST(PacketStuffer, NoOp) { PacketStuffer stuffer(NodeId(1), NodeId(2)); }
TEST(PacketStuffer, ForwardReturnValue) {
PacketStuffer stuffer(NodeId(1), NodeId(2));
EXPECT_TRUE(stuffer.Forward(DummyMessage()));
EXPECT_FALSE(stuffer.Forward(DummyMessage()));
}
TEST(PacketStuffer, CanDropMessages) {
PacketStuffer stuffer(NodeId(1), NodeId(2));
EXPECT_FALSE(stuffer.HasPendingMessages());
EXPECT_TRUE(stuffer.Forward(DummyMessage()));
EXPECT_TRUE(stuffer.HasPendingMessages());
stuffer.DropPendingMessages();
EXPECT_FALSE(stuffer.HasPendingMessages());
}
struct PacketVerificationArgs {
std::vector<Slice> messages;
size_t max_serialize_length;
Slice expected_bytes;
};
struct PacketStufferSerialization
: public ::testing::TestWithParam<PacketVerificationArgs> {};
TEST_P(PacketStufferSerialization, Write) {
PacketStuffer stuffer(NodeId(1), NodeId(2));
int i = 0;
for (auto msg : GetParam().messages) {
IgnoreResult(stuffer.Forward(Message{
std::move(RoutableMessage(NodeId(1)).AddDestination(
NodeId(3), StreamId(1), SeqNum(i++, GetParam().messages.size()))),
ForwardingPayloadFactory(msg), kDummyTimestamp123}));
}
EXPECT_EQ(stuffer.BuildPacket(
LazySliceArgs{Border::None(), GetParam().max_serialize_length}),
GetParam().expected_bytes);
}
TEST_P(PacketStufferSerialization, Read) {
TestTimer timer;
Router router(&timer, NodeId(2), false);
std::vector<Slice> got_messages;
class MockLink final : public Link {
public:
MockLink(std::vector<Slice>* got_messages) : got_messages_(got_messages) {}
void Close(Callback<void> quiesced) override {}
fuchsia::overnet::protocol::LinkStatus GetLinkStatus() override {
return fuchsia::overnet::protocol::LinkStatus{NodeId(2).as_fidl(),
NodeId(3).as_fidl(), 1, 1};
}
const LinkStats* GetStats() const override { return nullptr; }
void Forward(Message message) override {
EXPECT_EQ(message.header.src(), NodeId(1));
EXPECT_EQ(message.header.destinations().size(), size_t(1));
EXPECT_EQ(message.header.destinations()[0].dst(), NodeId(3));
got_messages_->emplace_back(message.make_payload(
LazySliceArgs{Border::None(), std::numeric_limits<size_t>::max()}));
}
private:
std::vector<Slice>* const got_messages_;
};
router.RegisterLink(MakeLink<MockLink>(&got_messages));
while (!router.HasRouteTo(NodeId(3))) {
timer.StepUntilNextEvent();
}
auto status = PacketStuffer(NodeId(1), NodeId(2))
.ParseAndForwardTo(kDummyTimestamp123,
GetParam().expected_bytes, &router);
EXPECT_TRUE(status.is_ok()) << status;
EXPECT_EQ(got_messages, GetParam().messages);
}
INSTANTIATE_TEST_SUITE_P(PacketStufferSerializationSuite,
PacketStufferSerialization,
::testing::Values(PacketVerificationArgs{
{Slice::FromContainer({1, 2, 3})},
256,
Slice::FromContainer({
0x16, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x03,
})}));
} // namespace packet_stuffer_test
} // namespace overnet