blob: 3c53942605009b9c5c5803a2071659d1e1bebe1e [file] [log] [blame]
// Copyright 2018 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 "garnet/lib/overnet/protocol/routable_message.h"
#include "gtest/gtest.h"
namespace overnet {
namespace routing_header_test {
typedef std::vector<uint8_t> BinVec;
template <class T>
BinVec Encode(const T& x) {
auto sz = x.wire_length();
BinVec out;
out.resize(sz);
x.Write(out.data());
return out;
}
template <class T>
BinVec EncodeVarint(const T& x) {
auto sz = x.wire_length();
BinVec out;
out.resize(sz);
x.Write(sz, out.data());
return out;
}
TEST(BaseTypes, NodeId) {
NodeId one(1);
NodeId two(2);
NodeId also_one(1);
EXPECT_EQ(one, also_one);
EXPECT_NE(one, two);
EXPECT_EQ((BinVec{1, 0, 0, 0, 0, 0, 0, 0}), Encode(one));
EXPECT_EQ((BinVec{2, 0, 0, 0, 0, 0, 0, 0}), Encode(two));
}
TEST(BaseTypes, StreamId) {
StreamId one(1);
StreamId two(2);
StreamId also_one(1);
EXPECT_EQ(one, also_one);
EXPECT_NE(one, two);
EXPECT_EQ((BinVec{1}), EncodeVarint(one));
EXPECT_EQ((BinVec{2}), EncodeVarint(two));
}
static void RoundTrip(const RoutableMessage& rh, NodeId sender, NodeId receiver,
Slice payload) {
auto enc = rh.Write(sender, receiver, payload);
auto prs_status = RoutableMessage::Parse(enc, receiver, sender);
EXPECT_TRUE(prs_status.is_ok()) << prs_status.AsStatus();
EXPECT_EQ(rh, prs_status->message);
EXPECT_EQ(payload, prs_status->payload);
}
TEST(RoutableMessage, PayloadWrite1) {
auto rh = std::move(RoutableMessage(NodeId(1)).AddDestination(
NodeId(2), StreamId(1), SeqNum(1, 10)));
auto body = Slice::FromContainer({1, 2, 3});
// encode locally
EXPECT_EQ(Slice::FromContainer({// flags
0,
// dests {
// [0] =
// stream_id
1,
// seqnum
1,
// }
// payload
1, 2, 3}),
rh.Write(NodeId(1), NodeId(2), body));
RoundTrip(rh, NodeId(1), NodeId(2), body);
}
TEST(RoutableMessage, PayloadWrite2) {
auto rh = std::move(RoutableMessage(NodeId(1)).AddDestination(
NodeId(2), StreamId(1), SeqNum(1, 10)));
auto body = Slice::FromContainer({1, 2, 3});
// encode along a different route
EXPECT_EQ(Slice::FromContainer({// flags
(1 << 4),
// src
1, 0, 0, 0, 0, 0, 0, 0,
// dests {
// [0] =
// node
2, 0, 0, 0, 0, 0, 0, 0,
// stream_id
1,
// seqnum
1,
// }
// payload
1, 2, 3}),
rh.Write(NodeId(4), NodeId(2), body));
RoundTrip(rh, NodeId(4), NodeId(2), body);
}
TEST(RoutableMessage, PayloadWrite3) {
auto rh =
std::move(RoutableMessage(NodeId(1))
.AddDestination(NodeId(2), StreamId(1), SeqNum(1, 10))
.AddDestination(NodeId(3), StreamId(42), SeqNum(7, 10)));
auto body = Slice::FromContainer({7, 8, 9});
EXPECT_EQ(Slice::FromContainer({// flags
(2 << 4),
// src
1, 0, 0, 0, 0, 0, 0, 0,
// dests {
// [0] =
// node
2, 0, 0, 0, 0, 0, 0, 0,
// stream_id
1,
// seqnum
1,
// [1] =
// node
3, 0, 0, 0, 0, 0, 0, 0,
// stream_id
42,
// seqnum
7,
// }
// payload
7, 8, 9}),
rh.Write(NodeId(1), NodeId(2), body));
RoundTrip(rh, NodeId(1), NodeId(2), body);
}
} // namespace routing_header_test
} // namespace overnet