xref: /aosp_15_r20/external/pigweed/pw_router/static_router_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker // Copyright 2021 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker //
3*61c4878aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker // the License at
6*61c4878aSAndroid Build Coastguard Worker //
7*61c4878aSAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker //
9*61c4878aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker // the License.
14*61c4878aSAndroid Build Coastguard Worker 
15*61c4878aSAndroid Build Coastguard Worker #include "pw_router/static_router.h"
16*61c4878aSAndroid Build Coastguard Worker 
17*61c4878aSAndroid Build Coastguard Worker #include "pw_assert/check.h"
18*61c4878aSAndroid Build Coastguard Worker #include "pw_router/egress_function.h"
19*61c4878aSAndroid Build Coastguard Worker #include "pw_unit_test/framework.h"
20*61c4878aSAndroid Build Coastguard Worker 
21*61c4878aSAndroid Build Coastguard Worker namespace pw::router {
22*61c4878aSAndroid Build Coastguard Worker namespace {
23*61c4878aSAndroid Build Coastguard Worker 
24*61c4878aSAndroid Build Coastguard Worker struct BasicPacket {
25*61c4878aSAndroid Build Coastguard Worker   static constexpr uint32_t kMagic = 0x8badf00d;
26*61c4878aSAndroid Build Coastguard Worker 
BasicPacketpw::router::__anone2f307ac0111::BasicPacket27*61c4878aSAndroid Build Coastguard Worker   constexpr BasicPacket(uint32_t addr, uint64_t data)
28*61c4878aSAndroid Build Coastguard Worker       : magic(kMagic), address(addr), priority(0), payload(data) {}
29*61c4878aSAndroid Build Coastguard Worker 
BasicPacketpw::router::__anone2f307ac0111::BasicPacket30*61c4878aSAndroid Build Coastguard Worker   constexpr BasicPacket(uint32_t addr, uint32_t prio, uint64_t data)
31*61c4878aSAndroid Build Coastguard Worker       : magic(kMagic), address(addr), priority(prio), payload(data) {}
32*61c4878aSAndroid Build Coastguard Worker 
datapw::router::__anone2f307ac0111::BasicPacket33*61c4878aSAndroid Build Coastguard Worker   ConstByteSpan data() const { return as_bytes(span(this, 1)); }
34*61c4878aSAndroid Build Coastguard Worker 
35*61c4878aSAndroid Build Coastguard Worker   uint32_t magic;
36*61c4878aSAndroid Build Coastguard Worker   uint32_t address;
37*61c4878aSAndroid Build Coastguard Worker   uint32_t priority;
38*61c4878aSAndroid Build Coastguard Worker   uint64_t payload;
39*61c4878aSAndroid Build Coastguard Worker };
40*61c4878aSAndroid Build Coastguard Worker 
41*61c4878aSAndroid Build Coastguard Worker class BasicPacketParser : public PacketParser {
42*61c4878aSAndroid Build Coastguard Worker  public:
BasicPacketParser()43*61c4878aSAndroid Build Coastguard Worker   constexpr BasicPacketParser() : packet_(nullptr) {}
44*61c4878aSAndroid Build Coastguard Worker 
Parse(pw::ConstByteSpan packet)45*61c4878aSAndroid Build Coastguard Worker   bool Parse(pw::ConstByteSpan packet) final {
46*61c4878aSAndroid Build Coastguard Worker     packet_ = reinterpret_cast<const BasicPacket*>(packet.data());
47*61c4878aSAndroid Build Coastguard Worker     return packet_->magic == BasicPacket::kMagic;
48*61c4878aSAndroid Build Coastguard Worker   }
49*61c4878aSAndroid Build Coastguard Worker 
GetDestinationAddress() const50*61c4878aSAndroid Build Coastguard Worker   std::optional<uint32_t> GetDestinationAddress() const final {
51*61c4878aSAndroid Build Coastguard Worker     PW_DCHECK_NOTNULL(packet_);
52*61c4878aSAndroid Build Coastguard Worker     return packet_->address;
53*61c4878aSAndroid Build Coastguard Worker   }
54*61c4878aSAndroid Build Coastguard Worker 
priority() const55*61c4878aSAndroid Build Coastguard Worker   uint32_t priority() const {
56*61c4878aSAndroid Build Coastguard Worker     PW_DCHECK_NOTNULL(packet_);
57*61c4878aSAndroid Build Coastguard Worker     return packet_->priority;
58*61c4878aSAndroid Build Coastguard Worker   }
59*61c4878aSAndroid Build Coastguard Worker 
60*61c4878aSAndroid Build Coastguard Worker  private:
61*61c4878aSAndroid Build Coastguard Worker   const BasicPacket* packet_;
62*61c4878aSAndroid Build Coastguard Worker };
63*61c4878aSAndroid Build Coastguard Worker 
__anone2f307ac0202(ConstByteSpan, const PacketParser&) 64*61c4878aSAndroid Build Coastguard Worker EgressFunction GoodEgress(+[](ConstByteSpan, const PacketParser&) {
65*61c4878aSAndroid Build Coastguard Worker   return OkStatus();
66*61c4878aSAndroid Build Coastguard Worker });
__anone2f307ac0302(ConstByteSpan, const PacketParser&) 67*61c4878aSAndroid Build Coastguard Worker EgressFunction BadEgress(+[](ConstByteSpan, const PacketParser&) {
68*61c4878aSAndroid Build Coastguard Worker   return Status::ResourceExhausted();
69*61c4878aSAndroid Build Coastguard Worker });
70*61c4878aSAndroid Build Coastguard Worker 
TEST(StaticRouter,RoutePacket_RoutesToAnEgress)71*61c4878aSAndroid Build Coastguard Worker TEST(StaticRouter, RoutePacket_RoutesToAnEgress) {
72*61c4878aSAndroid Build Coastguard Worker   BasicPacketParser parser;
73*61c4878aSAndroid Build Coastguard Worker   constexpr StaticRouter::Route routes[] = {{1, GoodEgress}, {2, BadEgress}};
74*61c4878aSAndroid Build Coastguard Worker   StaticRouter router(routes);
75*61c4878aSAndroid Build Coastguard Worker 
76*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(router.RoutePacket(BasicPacket(1, 0xdddd).data(), parser),
77*61c4878aSAndroid Build Coastguard Worker             OkStatus());
78*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(router.RoutePacket(BasicPacket(2, 0xdddd).data(), parser),
79*61c4878aSAndroid Build Coastguard Worker             Status::Unavailable());
80*61c4878aSAndroid Build Coastguard Worker }
81*61c4878aSAndroid Build Coastguard Worker 
TEST(StaticRouter,RoutePacket_ForwardsPacketParser)82*61c4878aSAndroid Build Coastguard Worker TEST(StaticRouter, RoutePacket_ForwardsPacketParser) {
83*61c4878aSAndroid Build Coastguard Worker   uint32_t parser_priority = 0xffffffff;
84*61c4878aSAndroid Build Coastguard Worker 
85*61c4878aSAndroid Build Coastguard Worker   EgressFunction parser_egress(
86*61c4878aSAndroid Build Coastguard Worker       [&parser_priority](ConstByteSpan, const PacketParser& parser) {
87*61c4878aSAndroid Build Coastguard Worker         const BasicPacketParser& basic_parser =
88*61c4878aSAndroid Build Coastguard Worker             static_cast<const BasicPacketParser&>(parser);
89*61c4878aSAndroid Build Coastguard Worker         parser_priority = basic_parser.priority();
90*61c4878aSAndroid Build Coastguard Worker         return OkStatus();
91*61c4878aSAndroid Build Coastguard Worker       });
92*61c4878aSAndroid Build Coastguard Worker 
93*61c4878aSAndroid Build Coastguard Worker   StaticRouter::Route routes[] = {{1, parser_egress}};
94*61c4878aSAndroid Build Coastguard Worker   StaticRouter router(routes);
95*61c4878aSAndroid Build Coastguard Worker   BasicPacketParser parser;
96*61c4878aSAndroid Build Coastguard Worker 
97*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(router.RoutePacket(BasicPacket(1, 71, 0xdddd).data(), parser),
98*61c4878aSAndroid Build Coastguard Worker             OkStatus());
99*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(parser_priority, 71u);
100*61c4878aSAndroid Build Coastguard Worker }
101*61c4878aSAndroid Build Coastguard Worker 
TEST(StaticRouter,RoutePacket_ReturnsParserError)102*61c4878aSAndroid Build Coastguard Worker TEST(StaticRouter, RoutePacket_ReturnsParserError) {
103*61c4878aSAndroid Build Coastguard Worker   BasicPacketParser parser;
104*61c4878aSAndroid Build Coastguard Worker   constexpr StaticRouter::Route routes[] = {{1, GoodEgress}, {2, BadEgress}};
105*61c4878aSAndroid Build Coastguard Worker   StaticRouter router(routes);
106*61c4878aSAndroid Build Coastguard Worker 
107*61c4878aSAndroid Build Coastguard Worker   BasicPacket bad_magic(1, 0xdddd);
108*61c4878aSAndroid Build Coastguard Worker   bad_magic.magic = 0x1badda7a;
109*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(router.RoutePacket(bad_magic.data(), parser), Status::DataLoss());
110*61c4878aSAndroid Build Coastguard Worker }
111*61c4878aSAndroid Build Coastguard Worker 
TEST(StaticRouter,RoutePacket_ReturnsNotFoundOnInvalidRoute)112*61c4878aSAndroid Build Coastguard Worker TEST(StaticRouter, RoutePacket_ReturnsNotFoundOnInvalidRoute) {
113*61c4878aSAndroid Build Coastguard Worker   BasicPacketParser parser;
114*61c4878aSAndroid Build Coastguard Worker   constexpr StaticRouter::Route routes[] = {{1, GoodEgress}, {2, BadEgress}};
115*61c4878aSAndroid Build Coastguard Worker   StaticRouter router(routes);
116*61c4878aSAndroid Build Coastguard Worker 
117*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(router.RoutePacket(BasicPacket(42, 0xdddd).data(), parser),
118*61c4878aSAndroid Build Coastguard Worker             Status::NotFound());
119*61c4878aSAndroid Build Coastguard Worker }
120*61c4878aSAndroid Build Coastguard Worker 
TEST(StaticRouter,RoutePacket_TracksNumberOfDrops)121*61c4878aSAndroid Build Coastguard Worker TEST(StaticRouter, RoutePacket_TracksNumberOfDrops) {
122*61c4878aSAndroid Build Coastguard Worker   BasicPacketParser parser;
123*61c4878aSAndroid Build Coastguard Worker   constexpr StaticRouter::Route routes[] = {{1, GoodEgress}, {2, BadEgress}};
124*61c4878aSAndroid Build Coastguard Worker   StaticRouter router(routes);
125*61c4878aSAndroid Build Coastguard Worker 
126*61c4878aSAndroid Build Coastguard Worker   // Good
127*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(router.RoutePacket(BasicPacket(1, 0xdddd).data(), parser),
128*61c4878aSAndroid Build Coastguard Worker             OkStatus());
129*61c4878aSAndroid Build Coastguard Worker 
130*61c4878aSAndroid Build Coastguard Worker   // Egress error
131*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(router.RoutePacket(BasicPacket(2, 0xdddd).data(), parser),
132*61c4878aSAndroid Build Coastguard Worker             Status::Unavailable());
133*61c4878aSAndroid Build Coastguard Worker 
134*61c4878aSAndroid Build Coastguard Worker   // Parser error
135*61c4878aSAndroid Build Coastguard Worker   BasicPacket bad_magic(1, 0xdddd);
136*61c4878aSAndroid Build Coastguard Worker   bad_magic.magic = 0x1badda7a;
137*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(router.RoutePacket(bad_magic.data(), parser), Status::DataLoss());
138*61c4878aSAndroid Build Coastguard Worker 
139*61c4878aSAndroid Build Coastguard Worker   // Good
140*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(router.RoutePacket(BasicPacket(1, 0xdddd).data(), parser),
141*61c4878aSAndroid Build Coastguard Worker             OkStatus());
142*61c4878aSAndroid Build Coastguard Worker 
143*61c4878aSAndroid Build Coastguard Worker   // Bad route
144*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(router.RoutePacket(BasicPacket(42, 0xdddd).data(), parser),
145*61c4878aSAndroid Build Coastguard Worker             Status::NotFound());
146*61c4878aSAndroid Build Coastguard Worker 
147*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(router.dropped_packets(), 3u);
148*61c4878aSAndroid Build Coastguard Worker }
149*61c4878aSAndroid Build Coastguard Worker 
150*61c4878aSAndroid Build Coastguard Worker }  // namespace
151*61c4878aSAndroid Build Coastguard Worker }  // namespace pw::router
152