Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Thinkit] Packet Discard Counter tests #891

Merged
merged 10 commits into from
Dec 27, 2024
2 changes: 2 additions & 0 deletions tests/forwarding/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,12 @@ cc_library(
"//p4_pdpi:pd",
"//sai_p4/instantiations/google:sai_p4info_cc",
"//sai_p4/instantiations/google:sai_pd_cc_proto",
"//tests/lib:p4rt_fixed_table_programming_helper",
"//thinkit:mirror_testbed_fixture",
"@com_github_p4lang_p4runtime//:p4info_cc_proto",
"@com_github_p4lang_p4runtime//:p4runtime_cc_proto",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/time",
"@com_google_googletest//:gtest",
"@com_google_protobuf//:protobuf",
],
Expand Down
168 changes: 164 additions & 4 deletions tests/forwarding/smoke_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,29 @@
#include "tests/forwarding/smoke_test.h"

#include "absl/strings/str_cat.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "gmock/gmock.h"
#include "google/protobuf/util/message_differencer.h"
#include "gtest/gtest.h"
#include "gutil/proto_matchers.h"
#include "gutil/status_matchers.h"
#include "gutil/testing.h"
#include "lib/gnmi/gnmi_helper.h"
#include "p4/config/v1/p4info.pb.h"
#include "p4/v1/p4runtime.pb.h"
#include "p4_pdpi/p4_runtime_session.h"
#include "p4_pdpi/pd.h"
#include "sai_p4/instantiations/google/sai_p4info.h"
#include "sai_p4/instantiations/google/sai_pd.pb.h"
#include "tests/forwarding/test_data.h"
#include "tests/lib/p4rt_fixed_table_programming_helper.h"

namespace pins_test {
namespace {

using ::gutil::StatusIs;

TEST_P(SmokeTestFixture, SessionsAreNonNull) {
ASSERT_NE(&GetSutP4RuntimeSession(), nullptr);
ASSERT_NE(&GetControlP4RuntimeSession(), nullptr);
Expand All @@ -55,9 +61,6 @@ TEST_P(SmokeTestFixture, AclTableAddDeleteOkButModifyFails) {
pdpi::PdWriteRequestToPi(
sai::GetIrP4Info(sai::Instantiation::kMiddleblock), pd_insert));

ASSERT_OK(pdpi::SetMetadataAndSendPiWriteRequest(&GetSutP4RuntimeSession(),
pi_insert));

const sai::WriteRequest pd_modify = gutil::ParseProtoOrDie<sai::WriteRequest>(
R"pb(
updates {
Expand All @@ -74,8 +77,127 @@ TEST_P(SmokeTestFixture, AclTableAddDeleteOkButModifyFails) {
ASSERT_OK_AND_ASSIGN(p4::v1::WriteRequest pi_modify,
pdpi::PdWriteRequestToPi(
sai::GetIrP4Info(sai::Instantiation::kMiddleblock), pd_modify));

const sai::WriteRequest pd_delete = gutil::ParseProtoOrDie<sai::WriteRequest>(
R"pb(
updates {
type: DELETE
table_entry {
acl_ingress_table_entry {
match { is_ip { value: "0x1" } }
priority: 10
action { acl_forward {} }
}
}
}
)pb");
ASSERT_OK_AND_ASSIGN(p4::v1::WriteRequest pi_delete,
pdpi::PdWriteRequestToPi(
sai::GetIrP4Info(sai::Instantiation::kMiddleblock), pd_delete));

// Insert works.
ASSERT_OK(pdpi::SetMetadataAndSendPiWriteRequest(&GetSutP4RuntimeSession(),
pi_insert));

// ACL table entries are expected to contain counter data. However, it's
// updated periodically and may not be avaialable immediatly after writing so
// we poll the entry for a few seconds until we see the data.
absl::Time timeout = absl::Now() + absl::Seconds(11);
p4::v1::ReadResponse pi_read_response;
p4::v1::ReadRequest pi_read_request;
pi_read_request.add_entities()->mutable_table_entry();
do {
ASSERT_OK_AND_ASSIGN(pi_read_response,
pdpi::SetMetadataAndSendPiReadRequest(
&GetSutP4RuntimeSession(), pi_read_request));
ASSERT_EQ(pi_read_response.entities_size(), 1);

if (absl::Now() > timeout) {
FAIL() << "ACL table entry does not have counter data.";
}
} while (!pi_read_response.entities(0).table_entry().has_counter_data());

// Many ACL table attribues are NOT modifiable currently due to missing SAI
// implementation. Because there are no production use-cases, these are
// de-prioritized.
ASSERT_THAT(pdpi::SetMetadataAndSendPiWriteRequest(&GetSutP4RuntimeSession(),
pi_modify),
StatusIs(absl::StatusCode::kUnknown));

// Delete works.
ASSERT_OK(pdpi::SetMetadataAndSendPiWriteRequest(&GetSutP4RuntimeSession(),
pi_delete));
}

TEST_P(SmokeTestFixture, FixedTableAddModifyDeleteOk) {
p4::v1::WriteRequest pi_request;
ASSERT_OK_AND_ASSIGN(
*pi_request.add_updates(),
pins::VrfTableUpdate(
sai::GetIrP4Info(sai::Instantiation::kMiddleblock), p4::v1::Update::INSERT, "vrf-1"));
ASSERT_OK_AND_ASSIGN(
*pi_request.add_updates(),
pins::RouterInterfaceTableUpdate(sai::GetIrP4Info(sai::Instantiation::kMiddleblock),
p4::v1::Update::INSERT,
"router-intf-1", /*port=*/"1",
/*src_mac=*/"00:01:02:03:04:05"));
ASSERT_OK_AND_ASSIGN(
*pi_request.add_updates(),
pins::NeighborTableUpdate(sai::GetIrP4Info(sai::Instantiation::kMiddleblock),
p4::v1::Update::INSERT,
"router-intf-1",
/*neighbor_id=*/"fe80::0000:00ff:fe17:5f80",
/*dst_mac=*/"00:01:02:03:04:06"));
ASSERT_OK_AND_ASSIGN(
*pi_request.add_updates(),
pins::NexthopTableUpdate(sai::GetIrP4Info(sai::Instantiation::kMiddleblock),
p4::v1::Update::INSERT,
"nexthop-1", "router-intf-1",
/*neighbor_id=*/"fe80::0000:00ff:fe17:5f80"));
ASSERT_OK(pdpi::SetMetadataAndSendPiWriteRequest(&GetSutP4RuntimeSession(),
pi_modify));
pi_request));

// Add and modify IPV4 table entry with different number of action params.
pi_request.Clear();
ASSERT_OK_AND_ASSIGN(
*pi_request.add_updates(),
pins::Ipv4TableUpdate(
sai::GetIrP4Info(sai::Instantiation::kMiddleblock),
p4::v1::Update::INSERT,
pins::IpTableOptions{
.vrf_id = "vrf-1",
.dst_addr_lpm = std::make_pair("20.0.0.1", 32),
.action = pins::IpTableOptions::Action::kSetNextHopId,
.nexthop_id = "nexthop-1",
}));
ASSERT_OK(pdpi::SetMetadataAndSendPiWriteRequest(&GetSutP4RuntimeSession(),
pi_request));
pi_request.Clear();
ASSERT_OK_AND_ASSIGN(
*pi_request.add_updates(),
pins::Ipv4TableUpdate(sai::GetIrP4Info(sai::Instantiation::kMiddleblock),
p4::v1::Update::MODIFY,
pins::IpTableOptions{
.vrf_id = "vrf-1",
.dst_addr_lpm = std::make_pair("20.0.0.1", 32),
.action = pins::IpTableOptions::Action::kDrop,
}));
ASSERT_OK(pdpi::SetMetadataAndSendPiWriteRequest(&GetSutP4RuntimeSession(),
pi_request));

pi_request.Clear();
ASSERT_OK_AND_ASSIGN(
*pi_request.add_updates(),
pins::Ipv4TableUpdate(sai::GetIrP4Info(sai::Instantiation::kMiddleblock),
p4::v1::Update::DELETE,
pins::IpTableOptions{
.vrf_id = "vrf-1",
.dst_addr_lpm = std::make_pair("20.0.0.1", 32),
.action = pins::IpTableOptions::Action::kDrop,
}));

ASSERT_OK(pdpi::SetMetadataAndSendPiWriteRequest(&GetSutP4RuntimeSession(),
pi_request));

// This used to fail with a read error.
ASSERT_OK(pdpi::ClearTableEntries(&GetSutP4RuntimeSession()));
Expand Down Expand Up @@ -209,5 +331,43 @@ TEST_P(SmokeTestFixture, EnsureClearTables) {
ASSERT_OK(pdpi::CheckNoTableEntries(session2.get()));
}

// Ensures that a GNMI Config can be pushed even with programmed flows already
// on the switch.
TEST_P(SmokeTestFixture, PushGnmiConfigWithFlows) {
thinkit::MirrorTestbed& testbed =
GetParam().mirror_testbed->GetMirrorTestbed();

// All tables should be clear after setup.
ASSERT_OK(pdpi::CheckNoTableEntries(&GetSutP4RuntimeSession()));

ASSERT_OK_AND_ASSIGN(auto sut_gnmi_stub, testbed.Sut().CreateGnmiStub());
ASSERT_OK_AND_ASSIGN(const std::string gnmi_config,
pins_test::GetGnmiConfig(*sut_gnmi_stub));

// Pushing a Gnmi Config is OK when tables are cleared.
ASSERT_OK(pins_test::PushGnmiConfig(GetMirrorTestbed().Sut(), gnmi_config));

// Sets up an example table entry.
const sai::TableEntry pd_entry = gutil::ParseProtoOrDie<sai::TableEntry>(
R"pb(
router_interface_table_entry {
match { router_interface_id: "router-interface-1" }
action {
set_port_and_src_mac { port: "1" src_mac: "02:2a:10:00:00:03" }
}
}
)pb");
ASSERT_OK_AND_ASSIGN(p4::v1::TableEntry pi_entry,
pdpi::PartialPdTableEntryToPiTableEntry(
sai::GetIrP4Info(sai::Instantiation::kMiddleblock), pd_entry));

ASSERT_OK(pdpi::InstallPiTableEntries(&GetSutP4RuntimeSession(),
sai::GetIrP4Info(sai::Instantiation::kMiddleblock), {pi_entry}));

// Pushing the same Gnmi Config is also OK when entries are programmed.
ASSERT_OK(pins_test::PushGnmiConfig(GetMirrorTestbed().Sut(), gnmi_config));
}


} // namespace
} // namespace pins
40 changes: 40 additions & 0 deletions tests/gnmi/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ cc_library(
srcs = ["ethcounter_ixia_test.cc"],
hdrs = ["ethcounter_ixia_test.h"],
deps = [
"//gutil:collections",
"//gutil:status",
"//gutil:status_matchers",
"//gutil:testing",
Expand All @@ -61,18 +62,57 @@ cc_library(
"//p4_pdpi:ir",
"//p4_pdpi:p4_runtime_session",
"//p4_pdpi:pd",
"//p4_pdpi/netaddr:mac_address",
"//p4_pdpi/packetlib",
"//p4_pdpi/packetlib:packetlib_cc_proto",
"//tests/forwarding:util",
"//tests/lib:switch_test_setup_helpers",
"//sai_p4/instantiations/google:sai_p4info_cc",
"//thinkit:generic_testbed",
"//thinkit:generic_testbed_fixture",
"//thinkit:switch",
"//thinkit/proto:generic_testbed_cc_proto",
"@com_github_google_glog//:glog",
"@com_github_nlohmann_json//:nlohmann_json",
"@com_google_absl//absl/cleanup",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/time",
"@com_google_googletest//:gtest",
],
alwayslink = True,
)

cc_library(
name = "counter_timestamp_test",
testonly = True,
srcs = ["counter_timestamp_test.cc"],
hdrs = ["ethcounter_ixia_test.h"],
deps = [
"//gutil:collections",
"//gutil:proto",
"//gutil:status_matchers",
"//gutil:testing",
"//lib:ixia_helper",
"//lib:ixia_helper_cc_proto",
"//p4_pdpi:p4_runtime_session",
"//p4_pdpi:pd",
"//p4_pdpi/netaddr:mac_address",
"//sai_p4/instantiations/google:sai_pd_cc_proto",
"//tests/forwarding:util",
"//tests/lib:switch_test_setup_helpers",
"//tests/qos:qos_test_util",
"//thinkit:generic_testbed",
"//thinkit:generic_testbed_fixture",
"//thinkit:switch",
"//thinkit/proto:generic_testbed_cc_proto",
"@com_github_google_glog//:glog",
"@com_google_absl//absl/cleanup",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/time",
"@com_google_googletest//:gtest",
],
alwayslink = True,
Expand Down
Loading
Loading