diff --git a/tests/forwarding/BUILD.bazel b/tests/forwarding/BUILD.bazel index dcd90d49..71008108 100644 --- a/tests/forwarding/BUILD.bazel +++ b/tests/forwarding/BUILD.bazel @@ -115,10 +115,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", + "//sai_p4/instantiations/google/test_tools:test_entries", + "//tests/lib:p4rt_fixed_table_programming_helper", "//tests/lib:switch_test_setup_helpers", + "//thinkit:mirror_testbed", "//thinkit:mirror_testbed_fixture", - "@com_github_p4lang_p4runtime//:p4info_cc_proto", + "//thinkit:test_environment", "@com_github_p4lang_p4runtime//:p4runtime_cc_proto", "@com_google_absl//absl/strings", "@com_google_absl//absl/time", diff --git a/tests/forwarding/acl_feature_test.cc b/tests/forwarding/acl_feature_test.cc index 38a196a3..388cc551 100644 --- a/tests/forwarding/acl_feature_test.cc +++ b/tests/forwarding/acl_feature_test.cc @@ -29,6 +29,7 @@ #include "glog/logging.h" #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "gutil/proto.h" #include "gutil/status.h" // IWYU pragma: keep #include "gutil/status.h" #include "gutil/status_matchers.h" // IWYU pragma: keep @@ -38,6 +39,7 @@ #include "p4/v1/p4runtime.pb.h" #include "p4_pdpi/ir.h" #include "p4_pdpi/ir.pb.h" +#include "p4_pdpi/netaddr/mac_address.h" #include "p4_pdpi/p4_runtime_session.h" #include "p4_pdpi/p4_runtime_session_extras.h" #include "p4_pdpi/packetlib/packetlib.h" @@ -80,25 +82,33 @@ absl::Status SetUpIngressAclForwardingAllPackets( } // Helper function to build a UDP packet -dvaas::PacketTestVector UdpPacket(std::string control_port, - absl::string_view dst_mac, - absl::string_view dst_ip, - std::optional punt_action) { +dvaas::PacketTestVector UdpPacket( + absl::string_view egress_port, + const sai::NexthopRewriteOptions& rewrite_options, + std::optional punt_action) { ProtoFixtureRepository repo; repo.RegisterValue("@payload", dvaas::MakeTestPacketTagFromUniqueId(1)) - .RegisterValue("@ingress_port", control_port) - .RegisterValue("@egress_port", control_port) - .RegisterValue("@dst_ip", dst_ip) - .RegisterValue("@dst_mac", dst_mac) + .RegisterValue("@ingress_port", egress_port) + .RegisterValue("@egress_port", egress_port) + .RegisterValue("@ingress_dst_mac", "00:aa:bb:cc:cc:dd") + .RegisterValue("@ingress_src_mac", "00:00:22:22:00:00") + .RegisterValue("@egress_dst_mac", + (rewrite_options.dst_mac_rewrite.has_value() + ? rewrite_options.dst_mac_rewrite->ToString() + : "@ingress_dst_mac")) + .RegisterValue("@egress_src_mac", + (rewrite_options.src_mac_rewrite.has_value() + ? rewrite_options.src_mac_rewrite->ToString() + : "@ingress_src_mac")) .RegisterValue("@ttl", "0x10") .RegisterValue("@decremented_ttl", "0x0f"); dvaas::PacketTestVector test_vector = repo.RegisterSnippetOrDie("@ethernet", R"pb( ethernet_header { - ethernet_destination: @dst_mac, - ethernet_source: "00:00:22:22:00:00" + ethernet_destination: @ingress_dst_mac, + ethernet_source: @ingress_src_mac, ethertype: "0x0800" # Udp } )pb") @@ -115,7 +125,7 @@ dvaas::PacketTestVector UdpPacket(std::string control_port, # payload_length: filled in automatically. protocol: "0x11" ipv4_source: "10.0.0.8" - ipv4_destination: @dst_ip + ipv4_destination: "10.0.0.1" } )pb") .RegisterSnippetOrDie("@udp", R"pb( @@ -133,8 +143,8 @@ dvaas::PacketTestVector UdpPacket(std::string control_port, "@output_packet", ParsePacketAndFillInComputedFields(repo, R"pb( headers: @ethernet { ethernet_header { - ethernet_destination: "02:03:04:05:06:07" - ethernet_source: "00:01:02:03:04:05" + ethernet_destination: @egress_dst_mac + ethernet_source: @egress_src_mac } } headers: @ipv4 { ipv4_header { ttl: @decremented_ttl } } @@ -148,7 +158,17 @@ dvaas::PacketTestVector UdpPacket(std::string control_port, } acceptable_outputs { packets { port: @egress_port parsed: @output_packet } - packet_ins { parsed: @output_packet } + packet_ins { + metadata { + name: "ingress_port" + value: { str: @ingress_port } + } + metadata { + name: "target_egress_port" + value: { str: @egress_port } + } + parsed: @input_packet + } } )pb"); @@ -165,19 +185,16 @@ dvaas::PacketTestVector UdpPacket(std::string control_port, // Helper routine to install L3 route absl::Status InstallL3Route(pdpi::P4RuntimeSession* switch_session, - pdpi::IrP4Info ir_p4info, std::string given_port, + const pdpi::IrP4Info& ir_p4info, + absl::string_view egress_port, + const sai::NexthopRewriteOptions& rewrite_options, std::optional punt_action) { std::vector pi_entities; LOG(INFO) << "Installing L3 route"; sai::EntryBuilder entry_builder = - sai::EntryBuilder() - .AddVrfEntry("vrf-1") - .AddPreIngressAclEntryAssigningVrfForGivenIpType( - "vrf-1", sai::IpVersion::kIpv4) - .AddDefaultRouteForwardingAllPacketsToGivenPort( - given_port, sai::IpVersion::kIpv4, "vrf-1") - .AddEntryAdmittingAllPacketsToL3(); + sai::EntryBuilder().AddEntriesForwardingIpPacketsToGivenPort( + egress_port, sai::IpVersion::kIpv4And6, rewrite_options); if (punt_action.has_value()) { entry_builder.AddEntryPuntingAllPackets(punt_action.value()); @@ -193,22 +210,27 @@ absl::Status InstallL3Route(pdpi::P4RuntimeSession* switch_session, } TEST_P(AclFeatureTestFixture, AclDenyAction) { + dvaas::PacketTestVector test_vector; const AclFeatureTestParams& params = GetParam(); + dvaas::DataplaneValidationParams dvaas_params = params.dvaas_params; thinkit::MirrorTestbed& testbed = GetParam().mirror_testbed->GetMirrorTestbed(); - std::unique_ptr sut_p4rt_session, - control_switch_p4rt_session; + // Initialize the connection, clear all entities, and (for the SUT) push + // P4Info. ASSERT_OK_AND_ASSIGN( - std::tie(sut_p4rt_session, control_switch_p4rt_session), - pins_test::ConfigureSwitchPairAndReturnP4RuntimeSessionPair( - testbed.Sut(), testbed.ControlSwitch(), std::nullopt, - GetParam().p4info)); - - // Initialize the connection, clear table entries, and push GNMI - // configuration (if given) for the SUT and Control switch. + std::unique_ptr sut_p4rt_session, + pins_test::ConfigureSwitchAndReturnP4RuntimeSession( + testbed.Sut(), /*gnmi_config=*/std::nullopt, GetParam().sut_p4info)); + ASSERT_OK_AND_ASSIGN( + std::unique_ptr control_switch_p4rt_session, + pins_test::ConfigureSwitchAndReturnP4RuntimeSession( + testbed.ControlSwitch(), /*gnmi_config=*/std::nullopt, + /*p4info=*/std::nullopt)); ASSERT_NE(sut_p4rt_session, nullptr); + ASSERT_NE(control_switch_p4rt_session, nullptr); + ASSERT_OK_AND_ASSIGN( p4::v1::GetForwardingPipelineConfigResponse sut_config, pdpi::GetForwardingPipelineConfig(sut_p4rt_session.get())); @@ -217,8 +239,6 @@ TEST_P(AclFeatureTestFixture, AclDenyAction) { ASSERT_OK_AND_ASSIGN(pdpi::IrP4Info sut_ir_p4info, pdpi::CreateIrP4Info(sut_config.config().p4info())); - ASSERT_OK(pdpi::ClearTableEntries(sut_p4rt_session.get())); - // Get control ports to test on. ASSERT_OK_AND_ASSIGN( auto gnmi_stub_control, @@ -226,24 +246,151 @@ TEST_P(AclFeatureTestFixture, AclDenyAction) { ASSERT_OK_AND_ASSIGN(std::string control_port, pins_test::GetAnyUpInterfacePortId(*gnmi_stub_control)); + // Since we don't care about the egress packet's source and destination mac, + // we use the default rewrite options. + const sai::NexthopRewriteOptions rewrite_options; + ASSERT_OK(InstallL3Route(sut_p4rt_session.get(), sut_ir_p4info, control_port, - params.punt_action)); + rewrite_options, params.punt_action)); + + test_vector = UdpPacket(control_port, rewrite_options, params.punt_action); - // remove the skip + // Run test with custom packet test vector. + dvaas_params.packet_test_vector_override = {test_vector}; + ASSERT_OK_AND_ASSIGN( + dvaas::ValidationResult validation_result, + GetParam().dvaas->ValidateDataplane(testbed, dvaas_params)); + + // Log statistics and check that things succeeded. + validation_result.LogStatistics(); + EXPECT_OK(validation_result.HasSuccessRateOfAtLeast(1.0)); + + ASSERT_OK_AND_ASSIGN(sut_p4rt_session, + pdpi::P4RuntimeSession::Create(testbed.Sut())); + + // Install AclDeny + ASSERT_OK_AND_ASSIGN(auto proto_entry, + gutil::ParseTextProto( + R"pb(table_name: "acl_ingress_security_table" + priority: 1 + action { name: "acl_deny" } + )pb")); + + EXPECT_OK(pdpi::InstallIrTableEntry(*sut_p4rt_session.get(), proto_entry)); + for (dvaas::SwitchOutput& output : + *test_vector.mutable_acceptable_outputs()) { + output.clear_packet_ins(); + output.clear_packets(); + } + + dvaas_params.packet_test_vector_override = {test_vector}; + ASSERT_OK_AND_ASSIGN( + dvaas::ValidationResult validation_result2, + GetParam().dvaas->ValidateDataplane(testbed, dvaas_params)); + + // Log statistics and check that things succeeded. + validation_result2.LogStatistics(); + EXPECT_OK(validation_result2.HasSuccessRateOfAtLeast(1.0)); +} + +TEST_P(AclFeatureTestFixture, AclEgressTable) { + dvaas::PacketTestVector test_vector; + const AclFeatureTestParams& params = GetParam(); + dvaas::DataplaneValidationParams dvaas_params = params.dvaas_params; + dvaas_params.artifact_prefix = "sanity_dvaas"; + const netaddr::MacAddress output_src_mac(0x1, 0x2, 0x3, 0x1, 0x2, 0x3); + + // we are not testing punt action in this test + // so skip for those variants if (params.punt_action.has_value()) { - // Run test with custom packet test vector. - dvaas::DataplaneValidationParams dvaas_params = params.dvaas_params; - dvaas_params.packet_test_vector_override = { - UdpPacket(control_port, /*dst_mac=*/"00:aa:bb:cc:cc:dd", - /*dst_ip=*/"10.0.0.1", params.punt_action)}; - ASSERT_OK_AND_ASSIGN( - dvaas::ValidationResult validation_result, - GetParam().dvaas->ValidateDataplane(testbed, dvaas_params)); - - // Log statistics and check that things succeeded. - validation_result.LogStatistics(); - EXPECT_OK(validation_result.HasSuccessRateOfAtLeast(1.0)); + GTEST_SKIP(); + } + + thinkit::MirrorTestbed& testbed = + GetParam().mirror_testbed->GetMirrorTestbed(); + + + // Initialize the connection, clear all entities, and (for the SUT) push + // P4Info. + ASSERT_OK_AND_ASSIGN( + std::unique_ptr sut_p4rt_session, + pins_test::ConfigureSwitchAndReturnP4RuntimeSession( + testbed.Sut(), /*gnmi_config=*/std::nullopt, GetParam().sut_p4info)); + ASSERT_OK_AND_ASSIGN( + std::unique_ptr control_switch_p4rt_session, + pins_test::ConfigureSwitchAndReturnP4RuntimeSession( + testbed.ControlSwitch(), /*gnmi_config=*/std::nullopt, + /*p4info=*/std::nullopt)); + ASSERT_NE(sut_p4rt_session, nullptr); + ASSERT_NE(control_switch_p4rt_session, nullptr); + + ASSERT_OK_AND_ASSIGN( + p4::v1::GetForwardingPipelineConfigResponse sut_config, + pdpi::GetForwardingPipelineConfig(sut_p4rt_session.get())); + ASSERT_OK(testbed.Environment().StoreTestArtifact( + "sut_p4Info.textproto", sut_config.config().p4info().DebugString())); + ASSERT_OK_AND_ASSIGN(pdpi::IrP4Info sut_ir_p4info, + pdpi::CreateIrP4Info(sut_config.config().p4info())); + + // Get control ports to test on. + ASSERT_OK_AND_ASSIGN( + auto gnmi_stub_control, + GetParam().mirror_testbed->GetMirrorTestbed().Sut().CreateGnmiStub()); + ASSERT_OK_AND_ASSIGN(std::string control_port, + pins_test::GetAnyUpInterfacePortId(*gnmi_stub_control)); + + const sai::NexthopRewriteOptions rewrite_options = {.src_mac_rewrite = + output_src_mac}; + + ASSERT_OK(InstallL3Route(sut_p4rt_session.get(), sut_ir_p4info, control_port, + rewrite_options, /*punt_action=*/std::nullopt)); + + test_vector = + UdpPacket(control_port, rewrite_options, /*punt_action=*/std::nullopt); + + // Run test with custom packet test vector. + dvaas_params.packet_test_vector_override = {test_vector}; + ASSERT_OK_AND_ASSIGN( + dvaas::ValidationResult validation_result, + GetParam().dvaas->ValidateDataplane(testbed, dvaas_params)); + + // Log statistics and check that things succeeded. + validation_result.LogStatistics(); + EXPECT_OK(validation_result.HasSuccessRateOfAtLeast(1.0)); + + ASSERT_OK_AND_ASSIGN(sut_p4rt_session, + pdpi::P4RuntimeSession::Create(testbed.Sut())); + + // Install AclEgress Drop + ASSERT_OK_AND_ASSIGN(auto proto_entry, + gutil::ParseTextProto( + R"pb(table_name: "acl_egress_table" + priority: 1 + matches { + name: "src_mac" + ternary { + value { mac: "01:02:03:01:02:03" } + mask { mac: "ff:ff:ff:ff:ff:ff" } + } + } + action { name: "acl_drop" } + )pb")); + + EXPECT_OK(pdpi::InstallIrTableEntry(*sut_p4rt_session.get(), proto_entry)); + + for (dvaas::SwitchOutput& output : + *test_vector.mutable_acceptable_outputs()) { + output.clear_packets(); } + dvaas_params.packet_test_vector_override = {test_vector}; + dvaas_params.artifact_prefix = "real_test_dvaas"; + ASSERT_OK_AND_ASSIGN( + dvaas::ValidationResult validation_result2, + GetParam().dvaas->ValidateDataplane(testbed, dvaas_params)); + + // Log statistics and check that things succeeded. + validation_result2.LogStatistics(); + EXPECT_OK(validation_result2.HasSuccessRateOfAtLeast(1.0)); } } // namespace diff --git a/tests/forwarding/acl_feature_test.h b/tests/forwarding/acl_feature_test.h index 866420f7..72818e09 100644 --- a/tests/forwarding/acl_feature_test.h +++ b/tests/forwarding/acl_feature_test.h @@ -15,13 +15,14 @@ #ifndef PINS_TESTS_FORWARDING_ACL_FEATURE_TEST_H_ #define PINS_TESTS_FORWARDING_ACL_FEATURE_TEST_H_ +#include #include -#include +#include #include "dvaas/dataplane_validation.h" -#include "dvaas/test_vector.h" #include "dvaas/test_vector.pb.h" -#include "dvaas/validation_result.h" +#include "gtest/gtest.h" +#include "p4/config/v1/p4info.pb.h" #include "sai_p4/instantiations/google/test_tools/test_entries.h" #include "thinkit/mirror_testbed_fixture.h" @@ -31,7 +32,9 @@ struct AclFeatureTestParams { // Using a shared_ptr because parameterized tests require objects to be // copyable. std::shared_ptr mirror_testbed; - std::optional p4info; + // Pushed to the SUT if given, otherwise assumes the correct one is already + // configured. + std::optional sut_p4info; std::string test_name; // ACL action variant to test out different behavior std::optional punt_action; diff --git a/tests/forwarding/smoke_test.cc b/tests/forwarding/smoke_test.cc index 753e71c4..6dbe7b11 100644 --- a/tests/forwarding/smoke_test.cc +++ b/tests/forwarding/smoke_test.cc @@ -16,8 +16,13 @@ #include #include +#include +#include +#include +#include #include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" #include "absl/time/clock.h" #include "absl/time/time.h" #include "google/protobuf/util/message_differencer.h" @@ -25,25 +30,28 @@ #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/ir.h" #include "p4_pdpi/ir.pb.h" #include "p4_pdpi/p4_runtime_session.h" #include "p4_pdpi/p4_runtime_session_extras.h" #include "p4_pdpi/pd.h" -#include "sai_p4/instantiations/google/sai_p4info.h" #include "sai_p4/instantiations/google/sai_pd.pb.h" +#include "sai_p4/instantiations/google/test_tools/test_entries.h" #include "tests/forwarding/test_data.h" #include "tests/lib/p4rt_fixed_table_programming_helper.h" #include "tests/lib/switch_test_setup_helpers.h" #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "thinkit/mirror_testbed.h" +#include "thinkit/test_environment.h" namespace pins_test { namespace { +using ::gutil::EqualsProto; using ::gutil::IsOk; +using ::testing::ElementsAre; using ::testing::Not; TEST_P(SmokeTestFixture, CanEstablishConnections) { @@ -301,8 +309,7 @@ TEST_P(SmokeTestFixture, InsertTableEntryWithRandomCharacterId) { ASSERT_OK(pdpi::InstallPiTableEntry(sut_p4rt_session.get(), pi_entry)); ASSERT_OK_AND_ASSIGN(auto entries, pdpi::ReadPiTableEntries(sut_p4rt_session.get())); - EXPECT_EQ(entries.size(), 1); - EXPECT_THAT(entries[0], gutil::EqualsProto(pi_entry)); + EXPECT_THAT(entries, ElementsAre(EqualsProto(pi_entry))); // An auxiliary RedisDB tool that takes a snapshot of the database has issues // with reading non-UTF-8 compliant characters. This is only used for @@ -476,9 +483,8 @@ TEST_P(SmokeTestFixture, DISABLED_PushGnmiConfigWithFlows) { ASSERT_OK(pins_test::PushGnmiConfig(testbed.Sut(), sut_gnmi_config)); } -// TODO: Enable when this test passes due to the bug being fixed. -TEST_P(SmokeTestFixture, DISABLED_DeleteReferencedEntryNotOk) { - thinkit::MirrorTestbed &testbed = +TEST_P(SmokeTestFixture, DeleteReferencedEntryNotOk) { + thinkit::MirrorTestbed& testbed = GetParam().mirror_testbed->GetMirrorTestbed(); ASSERT_OK_AND_ASSIGN(pdpi::IrP4Info ir_p4info, pdpi::CreateIrP4Info(GetParam().p4info)); @@ -504,18 +510,29 @@ TEST_P(SmokeTestFixture, DISABLED_DeleteReferencedEntryNotOk) { pins::RouterInterfaceTableUpdate( ir_p4info, p4::v1::Update::INSERT, kRifId, /*port=*/"1", /*src_mac=*/"00:02:03:04:05:06")); - ASSERT_OK_AND_ASSIGN( - const p4::v1::Update tunnel_update, - pins::TunnelTableUpdate( - ir_p4info, p4::v1::Update::INSERT, /*tunnel_id=*/"tid", - /*encap_dst_ip=*/kNeighborId, /*encap_src_ip=*/"::2", kRifId)); + // Install RIF then Neighbor entries. ASSERT_OK(pdpi::SendPiUpdates( - sut_p4rt_session.get(), - {insert_and_delete_neighbor_update, rif_update, tunnel_update})); + sut_p4rt_session.get(), {rif_update, insert_and_delete_neighbor_update})); + + // Install either a tunnel or a nexthop depending on if tunnels are supported. + if (GetParam().does_not_support_gre_tunnels) { + ASSERT_OK_AND_ASSIGN( + const p4::v1::Update nexthop_update, + pins::NexthopTableUpdate(ir_p4info, p4::v1::Update::INSERT, + /*nexthop_id=*/"nid", kRifId, kNeighborId)); + ASSERT_OK(pdpi::SendPiUpdates(sut_p4rt_session.get(), {nexthop_update})); + } else { + ASSERT_OK_AND_ASSIGN( + const p4::v1::Update tunnel_update, + pins::TunnelTableUpdate( + ir_p4info, p4::v1::Update::INSERT, /*tunnel_id=*/"tid", + /*encap_dst_ip=*/kNeighborId, /*encap_src_ip=*/"::2", kRifId)); + ASSERT_OK(pdpi::SendPiUpdates(sut_p4rt_session.get(), {tunnel_update})); + } // Cannot delete the neighbor table entry because it is used by the tunnel - // entry. + // entry or the nexthop entry. insert_and_delete_neighbor_update.set_type(p4::v1::Update::DELETE); EXPECT_THAT(pdpi::SendPiUpdates(sut_p4rt_session.get(), {insert_and_delete_neighbor_update}), @@ -525,9 +542,94 @@ TEST_P(SmokeTestFixture, DISABLED_DeleteReferencedEntryNotOk) { // Otherwise, the switch is in a corrupted state. ASSERT_OK_AND_ASSIGN(const pdpi::IrTableEntries read_entries, pdpi::ReadIrTableEntries(*sut_p4rt_session)); - ASSERT_OK(pdpi::ClearTableEntries(sut_p4rt_session.get())); + ASSERT_OK(pdpi::ClearEntities(*sut_p4rt_session)); EXPECT_OK(pdpi::InstallIrTableEntries(*sut_p4rt_session, read_entries)); } +// Check that unicast routes with a multicast destination range are accepted by +// the switch. We may disallow this via a p4-constraint in the future, but need +// the capability as a temporary workaround as of 2023-12-08. +TEST_P(SmokeTestFixture, CanInstallIpv4TableEntriesWithMulticastDstIp) { + thinkit::MirrorTestbed& testbed = + GetParam().mirror_testbed->GetMirrorTestbed(); + ASSERT_OK_AND_ASSIGN( + std::unique_ptr sut, + pins_test::ConfigureSwitchAndReturnP4RuntimeSession( + testbed.Sut(), GetParam().gnmi_config, GetParam().p4info)); + ASSERT_OK_AND_ASSIGN(pdpi::IrP4Info p4info, pdpi::GetIrP4Info(*sut)); + ASSERT_OK_AND_ASSIGN( + std::vector pi_entities, + sai::EntryBuilder().AddVrfEntry("vrf").GetDedupedPiEntities(p4info)); + ASSERT_OK(pdpi::InstallPiEntities(sut.get(), p4info, pi_entities)); + ASSERT_OK(pdpi::InstallPdTableEntries(*sut, R"pb( + entries { + ipv4_table_entry { + match { + vrf_id: "vrf" + ipv4_dst { value: "224.0.0.0" prefix_length: 8 } + } + action { drop {} } + } + } + entries { + ipv4_table_entry { + match { + vrf_id: "vrf" + ipv4_dst { value: "224.2.3.4" prefix_length: 32 } + } + action { drop {} } + } + } + )pb")); +} + +// Check that unicast routes with a multicast destination range are accepted by +// the switch. We may disallow this via a p4-constraint in the future, but need +// the capability as a temporary workaround as of 2023-12-08. +TEST_P(SmokeTestFixture, CanInstallIpv6TableEntriesWithMulticastDstIp) { + thinkit::MirrorTestbed& testbed = + GetParam().mirror_testbed->GetMirrorTestbed(); + ASSERT_OK_AND_ASSIGN( + std::unique_ptr sut, + pins_test::ConfigureSwitchAndReturnP4RuntimeSession( + testbed.Sut(), GetParam().gnmi_config, GetParam().p4info)); + ASSERT_OK_AND_ASSIGN(pdpi::IrP4Info p4info, pdpi::GetIrP4Info(*sut)); + ASSERT_OK_AND_ASSIGN( + std::vector pi_entities, + sai::EntryBuilder().AddVrfEntry("vrf").GetDedupedPiEntities(p4info)); + ASSERT_OK(pdpi::InstallPiEntities(sut.get(), p4info, pi_entities)); + // TODO: Use `sai::EntryBuilder` instead of hard-coding the entries + // here. + ASSERT_OK(pdpi::InstallPdTableEntries(*sut, R"pb( + entries { + ipv6_table_entry { + match { + vrf_id: "vrf" + ipv6_dst { value: "ff00::" prefix_length: 8 } + } + action { drop {} } + } + } + entries { + ipv6_table_entry { + match { + vrf_id: "vrf" + ipv6_dst { value: "ff00:1234:5678:9012::" prefix_length: 64 } + } + action { drop {} } + } + } + entries { + ipv6_table_entry { + match { + vrf_id: "vrf" + ipv6_dst { value: "ff00::1234" prefix_length: 128 } + } + action { drop {} } + } + } + )pb")); +} + } // namespace } // namespace pins diff --git a/tests/forwarding/smoke_test.h b/tests/forwarding/smoke_test.h index 909a84c6..cc852cda 100644 --- a/tests/forwarding/smoke_test.h +++ b/tests/forwarding/smoke_test.h @@ -28,6 +28,9 @@ struct SmokeTestParams { // given (default), or otherwise pushes the given config before starting. std::optional gnmi_config; p4::config::v1::P4Info p4info; + // Use on platforms that don't support GRE tunnels to avoid using them in + // tests. + bool does_not_support_gre_tunnels; }; class SmokeTestFixture : public testing::TestWithParam { diff --git a/tests/forwarding/watch_port_test.cc b/tests/forwarding/watch_port_test.cc index f026fc06..48e7f799 100644 --- a/tests/forwarding/watch_port_test.cc +++ b/tests/forwarding/watch_port_test.cc @@ -581,6 +581,10 @@ void WatchPortTestFixture::TearDown() { ASSERT_OK(testbed.SaveSwitchLogs("before_reboot_")); LOG(INFO) << "Switch is in critical state, rebooting the switch."; pins_test::TestGnoiSystemColdReboot(testbed.GetMirrorTestbed().Sut()); + EXPECT_OK(control_p4_session_->Finish()); + if (receive_packet_thread_.joinable()) { + receive_packet_thread_.join(); + } pins_test::TestGnoiSystemColdReboot( testbed.GetMirrorTestbed().ControlSwitch()); @@ -593,6 +597,23 @@ void WatchPortTestFixture::TearDown() { EXPECT_OK(pdpi::ClearTableEntries(sut_p4_session_.get())); EXPECT_OK(sut_p4_session_->Finish()); } + // Stop RPC sessions. + if (control_p4_session_ != nullptr) { + EXPECT_OK(pdpi::ClearTableEntries(control_p4_session_.get())); + EXPECT_OK(control_p4_session_->Finish()); + } + if (receive_packet_thread_.joinable()) { + receive_packet_thread_.join(); + } + if (control_gnmi_stub_) { + ASSERT_OK_AND_ASSIGN(const auto port_name_per_port_id, + GetPortNamePerPortId(*control_gnmi_stub_)); + // Restore the admin state to UP. + for (const auto& [port_id, name] : port_name_per_port_id) { + EXPECT_OK(SetInterfaceAdminState(*control_gnmi_stub_, name, + InterfaceState::kUp)); + } + } testbed.TearDown(); } diff --git a/tests/mtu_tests/BUILD.bazel b/tests/mtu_tests/BUILD.bazel index ee463e76..eb3f6e57 100644 --- a/tests/mtu_tests/BUILD.bazel +++ b/tests/mtu_tests/BUILD.bazel @@ -48,6 +48,7 @@ cc_library( "//p4_pdpi/packetlib:packetlib_cc_proto", "//sai_p4/instantiations/google:sai_pd_cc_proto", "//tests/forwarding:util", + "//tests/lib:switch_test_setup_helpers", "//thinkit:control_device", "//thinkit:generic_testbed", "//thinkit:generic_testbed_fixture", diff --git a/tests/mtu_tests/mtu_tests.cc b/tests/mtu_tests/mtu_tests.cc index 58f6b912..bdf42c6e 100644 --- a/tests/mtu_tests/mtu_tests.cc +++ b/tests/mtu_tests/mtu_tests.cc @@ -38,6 +38,7 @@ #include "sai_p4/instantiations/google/instantiations.h" #include "sai_p4/instantiations/google/sai_pd.pb.h" #include "tests/forwarding/util.h" +#include "tests/lib/switch_test_setup_helpers.h" #include "thinkit/control_device.h" #include "thinkit/generic_testbed.h" #include "thinkit/proto/generic_testbed.pb.h" @@ -252,10 +253,10 @@ TEST_P(MtuRoutingTestFixture, MtuTest) { ASSERT_TRUE(absl::SimpleAtoi(state_path_response, &orig_mtu)); // Set up a route between the source and destination interfaces. - ASSERT_OK_AND_ASSIGN( - std::unique_ptr p4_session, - pdpi::P4RuntimeSession::CreateWithP4InfoAndClearTables( - testbed_->Sut(), MtuRoutingTestFixture::GetParam().p4_info)); + ASSERT_OK_AND_ASSIGN(std::unique_ptr p4_session, + pins_test::ConfigureSwitchAndReturnP4RuntimeSession( + testbed_->Sut(), /*gnmi_config=*/std::nullopt, + MtuRoutingTestFixture::GetParam().p4_info)); P4rtProgrammingContext p4rt_context(p4_session.get(), pdpi::SetMetadataAndSendPiWriteRequest); ASSERT_OK(SetupRoute(&p4rt_context)); @@ -319,10 +320,10 @@ TEST_P(MtuRoutingTestFixture, VerifyTrafficWithMtuChangeTest) { std::to_string(kMtu4500)); // Set up a route between the source and destination interfaces. - ASSERT_OK_AND_ASSIGN( - std::unique_ptr p4_session, - pdpi::P4RuntimeSession::CreateWithP4InfoAndClearTables( - testbed_->Sut(), MtuRoutingTestFixture::GetParam().p4_info)); + ASSERT_OK_AND_ASSIGN(std::unique_ptr p4_session, + pins_test::ConfigureSwitchAndReturnP4RuntimeSession( + testbed_->Sut(), /*gnmi_config=*/std::nullopt, + MtuRoutingTestFixture::GetParam().p4_info)); P4rtProgrammingContext p4rt_context(p4_session.get(), pdpi::SetMetadataAndSendPiWriteRequest); ASSERT_OK(SetupRoute(&p4rt_context)); diff --git a/tests/qos/BUILD.bazel b/tests/qos/BUILD.bazel index b06a5222..5d3510b9 100644 --- a/tests/qos/BUILD.bazel +++ b/tests/qos/BUILD.bazel @@ -169,6 +169,8 @@ cc_test( deps = [ ":gnmi_parsers", "//gutil:proto", + "//gutil:status", + "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", "@com_google_protobuf//:protobuf", ], @@ -214,6 +216,7 @@ cc_library( hdrs = ["packet_in_receiver.h"], deps = [ "//p4_pdpi:p4_runtime_session", - "@com_google_absl//absl/synchronization", + "@com_google_absl//absl/synchronization", + "@com_google_absl//absl/time", ], ) diff --git a/tests/qos/gnmi_parsers_test.expected.output b/tests/qos/gnmi_parsers_test.expected.output index 95fb88ae..e9b6c73c 100644 --- a/tests/qos/gnmi_parsers_test.expected.output +++ b/tests/qos/gnmi_parsers_test.expected.output @@ -193,6 +193,8 @@ qos { -- INPUT ----------------------------------------------------------------------- { +"openconfig-qos:qos" : { + "scheduler-policies" : { "scheduler-policy": [ { "name": "cpu_scheduler", @@ -679,16 +681,18 @@ qos { } } ] + } +} } -- OUTPUT: gutil::ParseJsonAsProto -- qos { scheduler_policies { scheduler_policy { - name: "scheduler_1gb" + name: "cpu_scheduler" schedulers { scheduler { sequence: 0 - config { + state { priority: "STRICT" sequence: 0 type: "openconfig-qos-types:TWO_RATE_THREE_COLOR" @@ -696,23 +700,215 @@ qos { inputs { input { id: "AF4" - config { + state { id: "AF4" input_type: "QUEUE" queue: "AF4" + weight: "0" } } } two_rate_three_color { - config { + state { + } + } + } + scheduler { + sequence: 1 + state { + priority: "STRICT" + sequence: 1 + type: "openconfig-qos-types:TWO_RATE_THREE_COLOR" + } + inputs { + input { + id: "NC1" + state { + id: "NC1" + input_type: "QUEUE" + queue: "NC1" + weight: "0" + } + } + } + two_rate_three_color { + state { + } + } + } + scheduler { + sequence: 2 + state { + priority: "DWRR" + sequence: 2 + type: "openconfig-qos-types:TWO_RATE_THREE_COLOR" + } + inputs { + input { + id: "AF3" + state { + id: "AF3" + input_type: "QUEUE" + queue: "AF3" + weight: "12" + } + } + } + two_rate_three_color { + state { + } + } + } + scheduler { + sequence: 3 + state { + priority: "DWRR" + sequence: 3 + type: "openconfig-qos-types:TWO_RATE_THREE_COLOR" + } + inputs { + input { + id: "LLQ2" + state { + id: "LLQ2" + input_type: "QUEUE" + queue: "LLQ2" + weight: "8" + } + } + } + two_rate_three_color { + state { + } + } + } + scheduler { + sequence: 4 + state { + priority: "DWRR" + sequence: 4 + type: "openconfig-qos-types:TWO_RATE_THREE_COLOR" + } + inputs { + input { + id: "AF1" + state { + id: "AF1" + input_type: "QUEUE" + queue: "AF1" + weight: "4" + } + } + } + two_rate_three_color { + state { + } + } + } + scheduler { + sequence: 5 + state { + priority: "DWRR" + sequence: 5 + type: "openconfig-qos-types:TWO_RATE_THREE_COLOR" + } + inputs { + input { + id: "AF2" + state { + id: "AF2" + input_type: "QUEUE" + queue: "AF2" + weight: "4" + } + } + } + two_rate_three_color { + state { + } + } + } + scheduler { + sequence: 6 + state { + priority: "DWRR" + sequence: 6 + type: "openconfig-qos-types:TWO_RATE_THREE_COLOR" + } + inputs { + input { + id: "BE1" + state { + id: "BE1" + input_type: "QUEUE" + queue: "BE1" + weight: "1" + } + } + } + two_rate_three_color { + state { + } + } + } + scheduler { + sequence: 7 + state { + priority: "DWRR" + sequence: 7 + type: "openconfig-qos-types:TWO_RATE_THREE_COLOR" + } + inputs { + input { + id: "LLQ1" + state { + id: "LLQ1" + input_type: "QUEUE" + queue: "LLQ1" + weight: "1" + } + } + } + two_rate_three_color { + state { + } + } + } + } + } + scheduler_policy { + name: "scheduler_100gb" + schedulers { + scheduler { + sequence: 0 + state { + priority: "STRICT" + sequence: 0 + type: "openconfig-qos-types:TWO_RATE_THREE_COLOR" + } + inputs { + input { + id: "AF4" + state { + id: "AF4" + input_type: "QUEUE" + queue: "AF4" + weight: "0" + } + } + } + two_rate_three_color { + state { cir: "0" - pir: "1000000000" + pir: "100000000000" + bc: 0 + be: 0 } } } scheduler { sequence: 1 - config { + state { priority: "STRICT" sequence: 1 type: "openconfig-qos-types:TWO_RATE_THREE_COLOR" @@ -720,20 +916,416 @@ qos { inputs { input { id: "NC1" - config { + state { id: "NC1" input_type: "QUEUE" queue: "NC1" + weight: "0" } } } two_rate_three_color { - config { - cir: "10000000" - pir: "20000000" + state { + cir: "1000000000" + pir: "2000000000" + bc: 0 + be: 0 + } + } + } + scheduler { + sequence: 2 + state { + priority: "DWRR" + sequence: 2 + type: "openconfig-qos-types:TWO_RATE_THREE_COLOR" + } + inputs { + input { + id: "AF3" + state { + id: "AF3" + input_type: "QUEUE" + queue: "AF3" + weight: "12" + } + } + } + two_rate_three_color { + state { + cir: "0" + pir: "100000000000" + bc: 0 + be: 0 } } } + scheduler { + sequence: 3 + state { + priority: "DWRR" + sequence: 3 + type: "openconfig-qos-types:TWO_RATE_THREE_COLOR" + } + inputs { + input { + id: "LLQ2" + state { + id: "LLQ2" + input_type: "QUEUE" + queue: "LLQ2" + weight: "8" + } + } + } + two_rate_three_color { + state { + cir: "0" + pir: "100000000000" + bc: 0 + be: 0 + } + } + } + scheduler { + sequence: 4 + state { + priority: "DWRR" + sequence: 4 + type: "openconfig-qos-types:TWO_RATE_THREE_COLOR" + } + inputs { + input { + id: "AF1" + state { + id: "AF1" + input_type: "QUEUE" + queue: "AF1" + weight: "4" + } + } + } + two_rate_three_color { + state { + cir: "0" + pir: "100000000000" + bc: 0 + be: 0 + } + } + } + scheduler { + sequence: 5 + state { + priority: "DWRR" + sequence: 5 + type: "openconfig-qos-types:TWO_RATE_THREE_COLOR" + } + inputs { + input { + id: "AF2" + state { + id: "AF2" + input_type: "QUEUE" + queue: "AF2" + weight: "4" + } + } + } + two_rate_three_color { + state { + cir: "0" + pir: "100000000000" + bc: 0 + be: 0 + } + } + } + scheduler { + sequence: 6 + state { + priority: "DWRR" + sequence: 6 + type: "openconfig-qos-types:TWO_RATE_THREE_COLOR" + } + inputs { + input { + id: "BE1" + state { + id: "BE1" + input_type: "QUEUE" + queue: "BE1" + weight: "1" + } + } + } + two_rate_three_color { + state { + cir: "0" + pir: "100000000000" + bc: 0 + be: 0 + } + } + } + scheduler { + sequence: 7 + state { + priority: "DWRR" + sequence: 7 + type: "openconfig-qos-types:TWO_RATE_THREE_COLOR" + } + inputs { + input { + id: "LLQ1" + state { + id: "LLQ1" + input_type: "QUEUE" + queue: "LLQ1" + weight: "1" + } + } + } + two_rate_three_color { + state { + cir: "0" + pir: "100000000000" + bc: 0 + be: 0 + } + } + } + } + } + } +} + +-- INPUT ----------------------------------------------------------------------- +{ +"openconfig-qos:qos" : { + "buffer-allocation-profiles": { + "buffer-allocation-profile": [ + { + "name": "staggered_8queue", + "queues": { + "queue": [ + { + "name": "AF1", + "config": { + "name": "AF1", + "dedicated-buffer": "0", + "use-shared-buffer": true, + "shared-buffer-limit-type": "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR", + "static-shared-buffer-limit": 0, + "dynamic-limit-scaling-factor": 1 + } + }, + { + "name": "AF2", + "config": { + "name": "AF2", + "dedicated-buffer": "0", + "use-shared-buffer": true, + "shared-buffer-limit-type": "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR", + "static-shared-buffer-limit": 0, + "dynamic-limit-scaling-factor": 3 + } + }, + { + "name": "AF3", + "config": { + "name": "AF3", + "dedicated-buffer": "0", + "use-shared-buffer": true, + "shared-buffer-limit-type": "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR", + "static-shared-buffer-limit": 0, + "dynamic-limit-scaling-factor": 3 + } + }, + { + "name": "AF4", + "config": { + "name": "AF4", + "dedicated-buffer": "0", + "use-shared-buffer": true, + "shared-buffer-limit-type": "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR", + "static-shared-buffer-limit": 0, + "dynamic-limit-scaling-factor": 3 + } + }, + { + "name": "BE1", + "config": { + "name": "BE1", + "dedicated-buffer": "0", + "use-shared-buffer": true, + "shared-buffer-limit-type": "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR", + "static-shared-buffer-limit": 0, + "dynamic-limit-scaling-factor": -1 + } + }, + { + "name": "LLQ1", + "config": { + "name": "LLQ1", + "dedicated-buffer": "0", + "use-shared-buffer": true, + "shared-buffer-limit-type": "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR", + "static-shared-buffer-limit": 0, + "dynamic-limit-scaling-factor": 1 + } + }, + { + "name": "LLQ2", + "config": { + "name": "LLQ2", + "dedicated-buffer": "0", + "use-shared-buffer": true, + "shared-buffer-limit-type": "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR", + "static-shared-buffer-limit": 0, + "dynamic-limit-scaling-factor": 3 + } + }, + { + "name": "NC1", + "config": { + "name": "NC1", + "dedicated-buffer": "0", + "use-shared-buffer": true, + "shared-buffer-limit-type": "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR", + "static-shared-buffer-limit": 0, + "dynamic-limit-scaling-factor": 3 + } + } + ] + } + } + ] + }, + "interfaces": { + "interface": [ + { + "interface-id": "Ethernet1/1/1", + "config": { + "interface-id": "Ethernet1/1/1" + }, + "output": { + "config": { + "buffer-allocation-profile": "staggered_8queue" + } + } + } + ] + } +} +} +-- OUTPUT: gutil::ParseJsonAsProto -- +qos { + buffer_allocation_profiles { + buffer_allocation_profile { + name: "staggered_8queue" + queues { + queue { + name: "AF1" + config { + name: "AF1" + dedicated_buffer: "0" + use_shared_buffer: true + shared_buffer_limit_type: "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR" + static_shared_buffer_limit: 0 + dynamic_limit_scaling_factor: 1 + } + } + queue { + name: "AF2" + config { + name: "AF2" + dedicated_buffer: "0" + use_shared_buffer: true + shared_buffer_limit_type: "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR" + static_shared_buffer_limit: 0 + dynamic_limit_scaling_factor: 3 + } + } + queue { + name: "AF3" + config { + name: "AF3" + dedicated_buffer: "0" + use_shared_buffer: true + shared_buffer_limit_type: "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR" + static_shared_buffer_limit: 0 + dynamic_limit_scaling_factor: 3 + } + } + queue { + name: "AF4" + config { + name: "AF4" + dedicated_buffer: "0" + use_shared_buffer: true + shared_buffer_limit_type: "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR" + static_shared_buffer_limit: 0 + dynamic_limit_scaling_factor: 3 + } + } + queue { + name: "BE1" + config { + name: "BE1" + dedicated_buffer: "0" + use_shared_buffer: true + shared_buffer_limit_type: "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR" + static_shared_buffer_limit: 0 + dynamic_limit_scaling_factor: -1 + } + } + queue { + name: "LLQ1" + config { + name: "LLQ1" + dedicated_buffer: "0" + use_shared_buffer: true + shared_buffer_limit_type: "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR" + static_shared_buffer_limit: 0 + dynamic_limit_scaling_factor: 1 + } + } + queue { + name: "LLQ2" + config { + name: "LLQ2" + dedicated_buffer: "0" + use_shared_buffer: true + shared_buffer_limit_type: "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR" + static_shared_buffer_limit: 0 + dynamic_limit_scaling_factor: 3 + } + } + queue { + name: "NC1" + config { + name: "NC1" + dedicated_buffer: "0" + use_shared_buffer: true + shared_buffer_limit_type: "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR" + static_shared_buffer_limit: 0 + dynamic_limit_scaling_factor: 3 + } + } + } + } + } + interfaces { + interface { + interface_id: "Ethernet1/1/1" + config { + interface_id: "Ethernet1/1/1" + } + output { + config { + buffer_allocation_profile: "staggered_8queue" + } } } } diff --git a/tests/qos/gnmi_parsers_test_runner.cc b/tests/qos/gnmi_parsers_test_runner.cc index 573375df..db868b53 100644 --- a/tests/qos/gnmi_parsers_test_runner.cc +++ b/tests/qos/gnmi_parsers_test_runner.cc @@ -1,3 +1,4 @@ +#include #include #include "absl/strings/ascii.h" @@ -5,6 +6,7 @@ #include "absl/strings/string_view.h" #include "google/protobuf/message.h" #include "gutil/proto.h" +#include "gutil/status.h" #include "tests/qos/gnmi_parsers.h" // -- Pretty priners for golden testing ---------------------------------------- @@ -29,16 +31,6 @@ std::ostream& operator<<(std::ostream& os, const std::variant& t_or_u) { } // namespace std -namespace absl { - -template -std::ostream& operator<<(std::ostream& os, const absl::StatusOr& statusor) { - if (statusor.ok()) return os << *statusor; - return os << statusor.status().code() << ": " << statusor.status().message(); -} - -} // namespace absl - namespace google::protobuf { std::ostream& operator<<(std::ostream& os, const Message& message) { @@ -190,6 +182,8 @@ static constexpr absl::string_view kTestGnmiQosConfig = static constexpr absl::string_view kTestGnmiQosConfig2 = R"json( { +"openconfig-qos:qos" : { + "scheduler-policies" : { "scheduler-policy": [ { "name": "cpu_scheduler", @@ -676,6 +670,129 @@ static constexpr absl::string_view kTestGnmiQosConfig2 = R"json( } } ] + } +} +} +)json"; + +static constexpr absl::string_view kTestGnmiQosConfig3 = R"json( +{ +"openconfig-qos:qos" : { + "buffer-allocation-profiles": { + "buffer-allocation-profile": [ + { + "name": "staggered_8queue", + "queues": { + "queue": [ + { + "name": "AF1", + "config": { + "name": "AF1", + "dedicated-buffer": "0", + "use-shared-buffer": true, + "shared-buffer-limit-type": "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR", + "static-shared-buffer-limit": 0, + "dynamic-limit-scaling-factor": 1 + } + }, + { + "name": "AF2", + "config": { + "name": "AF2", + "dedicated-buffer": "0", + "use-shared-buffer": true, + "shared-buffer-limit-type": "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR", + "static-shared-buffer-limit": 0, + "dynamic-limit-scaling-factor": 3 + } + }, + { + "name": "AF3", + "config": { + "name": "AF3", + "dedicated-buffer": "0", + "use-shared-buffer": true, + "shared-buffer-limit-type": "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR", + "static-shared-buffer-limit": 0, + "dynamic-limit-scaling-factor": 3 + } + }, + { + "name": "AF4", + "config": { + "name": "AF4", + "dedicated-buffer": "0", + "use-shared-buffer": true, + "shared-buffer-limit-type": "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR", + "static-shared-buffer-limit": 0, + "dynamic-limit-scaling-factor": 3 + } + }, + { + "name": "BE1", + "config": { + "name": "BE1", + "dedicated-buffer": "0", + "use-shared-buffer": true, + "shared-buffer-limit-type": "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR", + "static-shared-buffer-limit": 0, + "dynamic-limit-scaling-factor": -1 + } + }, + { + "name": "LLQ1", + "config": { + "name": "LLQ1", + "dedicated-buffer": "0", + "use-shared-buffer": true, + "shared-buffer-limit-type": "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR", + "static-shared-buffer-limit": 0, + "dynamic-limit-scaling-factor": 1 + } + }, + { + "name": "LLQ2", + "config": { + "name": "LLQ2", + "dedicated-buffer": "0", + "use-shared-buffer": true, + "shared-buffer-limit-type": "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR", + "static-shared-buffer-limit": 0, + "dynamic-limit-scaling-factor": 3 + } + }, + { + "name": "NC1", + "config": { + "name": "NC1", + "dedicated-buffer": "0", + "use-shared-buffer": true, + "shared-buffer-limit-type": "openconfig-qos:DYNAMIC_BASED_ON_SCALING_FACTOR", + "static-shared-buffer-limit": 0, + "dynamic-limit-scaling-factor": 3 + } + } + ] + } + } + ] + }, + "interfaces": { + "interface": [ + { + "interface-id": "Ethernet1/1/1", + "config": { + "interface-id": "Ethernet1/1/1" + }, + "output": { + "config": { + "buffer-allocation-profile": "staggered_8queue" + } + } + } + ] + } +} } )json"; @@ -685,32 +802,50 @@ void RunAllParsersAndPrintTheirOutput() { // Test ParseLoopbackIps. std::cout << "-- OUTPUT: ParseLoopbackIps --\n"; - std::cout << ParseLoopbackIps(kTestGnmiInterfaceConfig) << "\n"; + std::cout << gutil::StreamableStatusOr( + ParseLoopbackIps(kTestGnmiInterfaceConfig)) + << "\n"; // Test ParseLoopbackIpv4s. std::cout << "-- OUTPUT: ParseLoopbackIpv4s --\n"; - std::cout << ParseLoopbackIpv4s(kTestGnmiInterfaceConfig) << "\n"; + std::cout << gutil::StreamableStatusOr( + ParseLoopbackIpv4s(kTestGnmiInterfaceConfig)) + << "\n"; // Test ParseLoopbackIpv6s. std::cout << "-- OUTPUT: ParseLoopbackIpv6s --\n"; - std::cout << ParseLoopbackIpv6s(kTestGnmiInterfaceConfig) << "\n"; + std::cout << gutil::StreamableStatusOr( + ParseLoopbackIpv6s(kTestGnmiInterfaceConfig)) + << "\n"; // Test openconfig::Qos parsing. std::cout << kInputBanner << absl::StripAsciiWhitespace(kTestGnmiQosConfig) << "\n"; std::cout << "-- OUTPUT: gutil::ParseJsonAsProto --\n"; - std::cout << gutil::ParseJsonAsProto( - kTestGnmiQosConfig, - /*ignore_unknown_fields=*/true) + std::cout << gutil::StreamableStatusOr( + gutil::ParseJsonAsProto( + kTestGnmiQosConfig, + /*ignore_unknown_fields=*/true)) << "\n"; // Test openconfig::Qos parsing. std::cout << kInputBanner << absl::StripAsciiWhitespace(kTestGnmiQosConfig2) << "\n"; std::cout << "-- OUTPUT: gutil::ParseJsonAsProto --\n"; - std::cout << gutil::ParseJsonAsProto( - kTestGnmiQosConfig, - /*ignore_unknown_fields=*/true) + std::cout << gutil::StreamableStatusOr( + gutil::ParseJsonAsProto( + kTestGnmiQosConfig2, + /*ignore_unknown_fields=*/true)) + << "\n"; + + // Test openconfig::Qos parsing. + std::cout << kInputBanner << absl::StripAsciiWhitespace(kTestGnmiQosConfig3) + << "\n"; + std::cout << "-- OUTPUT: gutil::ParseJsonAsProto --\n"; + std::cout << gutil::StreamableStatusOr( + gutil::ParseJsonAsProto( + kTestGnmiQosConfig3, + /*ignore_unknown_fields=*/true)) << "\n"; } diff --git a/tests/qos/packet_in_receiver.h b/tests/qos/packet_in_receiver.h index 4bdb7417..62b2a020 100644 --- a/tests/qos/packet_in_receiver.h +++ b/tests/qos/packet_in_receiver.h @@ -4,6 +4,7 @@ #include // NOLINT #include "absl/synchronization/notification.h" +#include "absl/time/time.h" #include "p4_pdpi/p4_runtime_session.h" namespace pins_test { @@ -22,11 +23,12 @@ class PacketInReceiver final { PacketInReceiver(pdpi::P4RuntimeSession &session, std::function callback) : session_(session), receiver_([this, callback = std::move(callback)]() { - p4::v1::StreamMessageResponse pi_response; + absl::StatusOr pi_response; // To break out of this loop invoke Destroy(). - while (session_.StreamChannelRead(pi_response)) { - if (pi_response.has_packet()) { - callback(std::move(pi_response)); + while (!stop_receiving_.HasBeenNotified()) { + pi_response = session_.GetNextStreamMessage(absl::Seconds(1)); + if (pi_response.ok() && pi_response->has_packet()) { + callback(*std::move(pi_response)); } } }) {} @@ -35,7 +37,6 @@ class PacketInReceiver final { // It's ok to call this function multiple times. void Destroy() { - session_.Finish(); if (receiver_.joinable()) { stop_receiving_.Notify(); receiver_.join(); diff --git a/tests/sflow/sflow_test.cc b/tests/sflow/sflow_test.cc index 4b445315..e93adda1 100644 --- a/tests/sflow/sflow_test.cc +++ b/tests/sflow/sflow_test.cc @@ -2318,32 +2318,12 @@ void SflowMirrorTestFixture::TearDown() { CollectSflowDebugs(GetParam().ssh_client, testbed.Sut().ChassisName(), /*prefix=*/"posttest_", testbed.Environment()); if (sut_p4_session_ != nullptr) { - EXPECT_OK(OutputTableEntriesToArtifact( - *sut_p4_session_, testbed.Environment(), - /*artifact_name=*/"posttest_SUT_table_entries.txt")); + EXPECT_OK(pdpi::ClearTableEntries(sut_p4_session_.get())); + EXPECT_OK(sut_p4_session_->Finish()); } if (control_p4_session_ != nullptr) { - EXPECT_OK(OutputTableEntriesToArtifact( - *control_p4_session_, testbed.Environment(), - /*artifact_name=*/"posttest_control_table_entries.txt")); - } - - // Restore config on SUT and clear table entries. - if (sut_gnmi_stub_ != nullptr) { - ASSERT_OK_AND_ASSIGN(auto sflow_enabled, - IsSflowConfigEnabled(GetParam().sut_gnmi_config)); - ASSERT_OK(SetSflowConfigEnabled(sut_gnmi_stub_.get(), sflow_enabled)); - } - ASSERT_OK_AND_ASSIGN( - sut_p4_session_, - pins_test::ConfigureSwitchAndReturnP4RuntimeSession( - testbed.Sut(), GetParam().sut_gnmi_config, GetSutP4Info())); - - // Restores control switch config and clear table entries. - if (control_gnmi_stub_ != nullptr) { - ASSERT_OK_AND_ASSIGN(auto sflow_enabled, - IsSflowConfigEnabled(GetParam().control_gnmi_config)); - ASSERT_OK(SetSflowConfigEnabled(control_gnmi_stub_.get(), sflow_enabled)); + EXPECT_OK(pdpi::ClearTableEntries(control_p4_session_.get())); + EXPECT_OK(control_p4_session_->Finish()); } ASSERT_OK_AND_ASSIGN(control_p4_session_, pins_test::ConfigureSwitchAndReturnP4RuntimeSession(