From 63efb5f50d1a8565a0374684b828e6f6b9026a61 Mon Sep 17 00:00:00 2001 From: kishanps Date: Sun, 17 Nov 2024 20:13:55 -0800 Subject: [PATCH 1/4] [Thinkit] Adding thinkit_gnmi_interface_util_tests file. --- tests/BUILD.bazel | 20 ++ tests/thinkit_gnmi_interface_util_tests.cc | 281 +++++++++++++++++++++ 2 files changed, 301 insertions(+) create mode 100644 tests/thinkit_gnmi_interface_util_tests.cc diff --git a/tests/BUILD.bazel b/tests/BUILD.bazel index 5bca0289..39939d19 100644 --- a/tests/BUILD.bazel +++ b/tests/BUILD.bazel @@ -115,3 +115,23 @@ cc_library( "@com_google_googletest//:gtest", ], ) + +cc_test( + name = "thinkit_gnmi_interface_util_tests", + srcs = ["thinkit_gnmi_interface_util_tests.cc"], + deps = [ + ":thinkit_gnmi_tests", + "//gutil:proto_matchers", + "//gutil:status_matchers", + "//thinkit:mock_ssh_client", + "//thinkit:mock_switch", + "@com_github_gnmi//proto/gnmi:gnmi_cc_proto", + "@com_github_gnmi//proto/gnmi:gnmi_cc_grpc_proto", + "@com_github_nlohmann_json//:nlohmann_json", + "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/status", + "@com_google_absl//absl/strings", + "@com_google_googletest//:gtest_main", + "@com_google_protobuf//:protobuf", + ], +) diff --git a/tests/thinkit_gnmi_interface_util_tests.cc b/tests/thinkit_gnmi_interface_util_tests.cc new file mode 100644 index 00000000..bc8923fe --- /dev/null +++ b/tests/thinkit_gnmi_interface_util_tests.cc @@ -0,0 +1,281 @@ +#include +#include +#include +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/status/status.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "gmock/gmock.h" +#include "google/protobuf/text_format.h" +#include "gtest/gtest.h" +#include "gutil/proto_matchers.h" +#include "gutil/status_matchers.h" +#include "include/nlohmann/json.hpp" +#include "proto/gnmi/gnmi.grpc.pb.h" +#include "proto/gnmi/gnmi.pb.h" +#include "proto/gnmi/gnmi_mock.grpc.pb.h" +#include "tests/thinkit_gnmi_interface_util.h" +#include "tests/thinkit_util.h" +#include "thinkit/mock_ssh_client.h" +#include "thinkit/mock_switch.h" + +namespace pins_test { +using gutil::EqualsProto; +using gutil::StatusIs; +using ::nlohmann::json; +using ::testing::_; +using ::testing::ContainerEq; +using ::testing::DoAll; +using ::testing::HasSubstr; +using ::testing::Return; +using ::testing::ReturnRefOfCopy; +using ::testing::SetArgPointee; + +class GNMIThinkitInterfaceUtilityTest : public ::testing::Test { + protected: + void SetUp() override { + ON_CALL(mock_switch_, ChassisName()) + .WillByDefault(ReturnRefOfCopy(std::string("chassis_1"))); + } + thinkit::MockSSHClient mock_ssh_client_; + thinkit::MockSwitch mock_switch_; + gnmi::MockgNMIStub mock_gnmi_stub_; +}; + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetSupportedBreakoutModesForPortAnySuccess) { + const std::string port = "Ethernet0"; + std::vector expected_breakout_modes = { + "1x400G", "2x200G", "2x100G", "2x40G", "4x100G"}; + + const std::string interface_info = + R"pb({ "breakout_modes": "1x400G, 2x200G[100G,40G], 4x100G" } + )pb"; + EXPECT_THAT(pins_test::GetSupportedBreakoutModesForPort(interface_info, port), + expected_breakout_modes); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetSupportedBreakoutModesForPortChannelizedSuccess) { + const std::string port = "Ethernet0"; + std::vector expected_breakout_modes = {"2x200G", "2x100G", + "2x40G", "4x100G"}; + + const std::string interface_info = + R"pb({ "breakout_modes": "1x400G, 2x200G[100G,40G], 4x100G" } + )pb"; + EXPECT_THAT(pins_test::GetSupportedBreakoutModesForPort( + interface_info, port, pins_test::BreakoutType::kChannelized), + expected_breakout_modes); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetSupportedBreakoutModesForPortBreakoutModesNotFoundFailure) { + const std::string port = "Ethernet0"; + const std::string interface_info = + R"pb({} + )pb"; + EXPECT_THAT( + pins_test::GetSupportedBreakoutModesForPort(interface_info, port), + StatusIs(absl::StatusCode::kInternal, + HasSubstr(absl::StrCat("Supported breakout modes not found for ", + port, " in platform.json")))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetSupportedBreakoutModesForPortNumBreakoutsIntConversionFailure) { + const std::string port = "Ethernet0"; + const std::string interface_info = + R"pb({ "breakout_modes": "Xx400G, 2x200G[100G,40G], 4x100G" } + )pb"; + EXPECT_THAT(pins_test::GetSupportedBreakoutModesForPort( + interface_info, port, pins_test::BreakoutType::kChannelized), + StatusIs(absl::StatusCode::kInternal, + HasSubstr("Failed to convert string (X) to integer"))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetRandomPortWithSupportedBreakoutModesAnySuccess) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + absl::flat_hash_map + expected_port_info; + pins_test::RandomPortBreakoutInfo r; + r.port_name = "Ethernet0"; + r.curr_breakout_mode = "1x400G"; + r.supported_breakout_mode = "2x200G"; + expected_port_info["Ethernet0"] = r; + r.port_name = "Ethernet8"; + r.curr_breakout_mode = "2x200G"; + r.supported_breakout_mode = "1x400G"; + expected_port_info["Ethernet8"] = r; + const std::string platform_json_contents = + R"pb({ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x400G", + "breakout_modes": "1x400G, 2x200G[100G,40G]" + }, + "Ethernet8": { + "default_brkout_mode": "2x200G", + "breakout_modes": "1x400G, 2x200G[100G,40G]" + }, + "Ethernet12": { "breakout_modes": "1x200G[100G,40G]" } + } + } + )pb"; + gnmi::GetRequest req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { elem { name: "interfaces" } } + type: STATE)pb", + &req)); + gnmi::GetResponse resp; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(notification { + timestamp: 1631864194292383538 + prefix { origin: "openconfig" } + update { + path { elem { name: "interfaces" } } + val { + json_ietf_val: "{\"openconfig-interfaces:interfaces\":{\"interface\":[{\"name\":\"Ethernet0\",\"state\":{\"oper-status\":\"UP\"}},{\"name\":\"Ethernet8\",\"state\":{\"oper-status\":\"UP\"}}]}}" + } + } + } + )pb", + &resp)); + EXPECT_CALL(*mock_gnmi_stub_ptr, Get(_, EqualsProto(req), _)) + .WillOnce(DoAll(SetArgPointee<2>(resp), Return(grpc::Status::OK))); + auto random_port_info = pins_test::GetRandomPortWithSupportedBreakoutModes( + *mock_gnmi_stub_ptr, platform_json_contents); + ASSERT_OK(random_port_info.status()); + EXPECT_THAT(random_port_info.value().port_name, + expected_port_info[random_port_info.value().port_name].port_name); + EXPECT_THAT(random_port_info.value().curr_breakout_mode, + expected_port_info[random_port_info.value().port_name] + .curr_breakout_mode); + EXPECT_THAT(random_port_info.value().supported_breakout_mode, + expected_port_info[random_port_info.value().port_name] + .supported_breakout_mode); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetRandomPortWithSupportedBreakoutModesChannelizedSuccess) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + absl::flat_hash_map + expected_port_info; + pins_test::RandomPortBreakoutInfo r; + r.port_name = "Ethernet0"; + r.curr_breakout_mode = "1x400G"; + r.supported_breakout_mode = "2x200G"; + expected_port_info["Ethernet0"] = r; + const std::string platform_json_contents = + R"pb({ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x400G", + "breakout_modes": "1x400G, 2x200G[100G,40G]" + }, + "Ethernet8": { + "default_brkout_mode": "1x400G", + "breakout_modes": "1x400G" + }, + "Ethernet16": { + "default_brkout_mode": "1x400G", + "breakout_modes": "1x400G" + } + } + } + )pb"; + gnmi::GetRequest req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { elem { name: "interfaces" } } + type: STATE)pb", + &req)); + gnmi::GetResponse resp; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(notification { + timestamp: 1631864194292383538 + prefix { origin: "openconfig" } + update { + path { elem { name: "interfaces" } } + val { + json_ietf_val: "{\"openconfig-interfaces:interfaces\":{\"interface\":[{\"name\":\"Ethernet0\",\"state\":{\"oper-status\":\"UP\"}},{\"name\":\"Ethernet8\",\"state\":{\"oper-status\":\"UP\"}},{\"name\":\"Ethernet16\",\"state\":{\"oper-status\":\"UP\"}}]}}" + } + } + } + )pb", + &resp)); + EXPECT_CALL(*mock_gnmi_stub_ptr, Get(_, EqualsProto(req), _)) + .WillOnce(DoAll(SetArgPointee<2>(resp), Return(grpc::Status::OK))); + auto random_port_info = pins_test::GetRandomPortWithSupportedBreakoutModes( + *mock_gnmi_stub_ptr, platform_json_contents, + pins_test::BreakoutType::kChannelized); + ASSERT_OK(random_port_info.status()); + EXPECT_THAT(random_port_info.value().port_name, + expected_port_info[random_port_info.value().port_name].port_name); + EXPECT_THAT(random_port_info.value().curr_breakout_mode, + expected_port_info[random_port_info.value().port_name] + .curr_breakout_mode); + EXPECT_THAT(random_port_info.value().supported_breakout_mode, + expected_port_info[random_port_info.value().port_name] + .supported_breakout_mode); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetRandomPortWithSupportedBreakoutModesOperStatusMapGetFailure) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + gnmi::GetRequest req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { elem { name: "interfaces" } } + type: STATE)pb", + &req)); + EXPECT_CALL(*mock_gnmi_stub_ptr, Get(_, EqualsProto(req), _)) + .WillOnce(Return(grpc::Status(grpc::StatusCode::DEADLINE_EXCEEDED, ""))); + EXPECT_THAT( + pins_test::GetRandomPortWithSupportedBreakoutModes(*mock_gnmi_stub_ptr, + ""), + StatusIs(absl::StatusCode::kDeadlineExceeded, + HasSubstr("Failed to get oper-status map for ports on switch"))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetRandomPortWithSupportedBreakoutModesIntConversionFailure) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + gnmi::GetRequest req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { elem { name: "interfaces" } } + type: STATE)pb", + &req)); + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { elem { name: "interfaces" } } + type: STATE)pb", + &req)); + gnmi::GetResponse resp; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(notification { + timestamp: 1631864194292383538 + prefix { origin: "openconfig" } + update { + path { elem { name: "interfaces" } } + val { + json_ietf_val: "{\"openconfig-interfaces:interfaces\":{\"interface\":[{\"name\":\"EthernetX\",\"state\":{\"oper-status\":\"UP\"}}, {\"name\":\"Ethernet8\",\"state\":{\"oper-status\":\"UP\"}}]}}" + } + } + } + )pb", + &resp)); + EXPECT_CALL(*mock_gnmi_stub_ptr, Get(_, EqualsProto(req), _)) + .WillOnce(DoAll(SetArgPointee<2>(resp), Return(grpc::Status::OK))); + EXPECT_THAT(pins_test::GetRandomPortWithSupportedBreakoutModes( + *mock_gnmi_stub_ptr, ""), + StatusIs(absl::StatusCode::kInternal, + HasSubstr("Failed to convert string (X) to integer"))); +} + +} // namespace pins_test From 8d8a858a8f4de9b6648f933e1c7c652cde566f33 Mon Sep 17 00:00:00 2001 From: kishanps Date: Sun, 17 Nov 2024 20:32:22 -0800 Subject: [PATCH 2/4] [Thinkit] Adding test cases to thinkit_gnmi_interface_util_tests file. --- tests/thinkit_gnmi_interface_util_tests.cc | 304 +++++++++++++++++++++ 1 file changed, 304 insertions(+) diff --git a/tests/thinkit_gnmi_interface_util_tests.cc b/tests/thinkit_gnmi_interface_util_tests.cc index bc8923fe..dadb48f9 100644 --- a/tests/thinkit_gnmi_interface_util_tests.cc +++ b/tests/thinkit_gnmi_interface_util_tests.cc @@ -278,4 +278,308 @@ TEST_F(GNMIThinkitInterfaceUtilityTest, HasSubstr("Failed to convert string (X) to integer"))); } +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetRandomPortWithSupportedBreakoutModesNoOperUpPortsFailure) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + const std::string platform_json_contents = + R"pb({ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x400G", + "breakout_modes": "1x400G, 2x200G[100G,40G]" + }, + "Ethernet8": { + "default_brkout_mode": "2x200G", + "breakout_modes": "1x400G, 2x200G[100G,40G]" + }, + "Ethernet12": { "breakout_modes": "1x200G[100G,40G]" } + } + } + )pb"; + gnmi::GetRequest req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { elem { name: "interfaces" } } + type: STATE)pb", + &req)); + gnmi::GetResponse resp; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(notification { + timestamp: 1631864194292383538 + prefix { origin: "openconfig" } + update { + path { elem { name: "interfaces" } } + val { + json_ietf_val: "{\"openconfig-interfaces:interfaces\":{\"interface\":[{\"name\":\"Ethernet0\",\"state\":{\"oper-status\":\"DOWN\"}}, {\"name\":\"Ethernet8\",\"state\":{\"oper-status\":\"DOWN\"}}]}}" + } + } + } + )pb", + &resp)); + EXPECT_CALL(*mock_gnmi_stub_ptr, Get(_, EqualsProto(req), _)) + .WillOnce(DoAll(SetArgPointee<2>(resp), Return(grpc::Status::OK))); + EXPECT_THAT( + pins_test::GetRandomPortWithSupportedBreakoutModes( + *mock_gnmi_stub_ptr, platform_json_contents), + StatusIs(absl::StatusCode::kInternal, + HasSubstr("No operationally up parent ports found on switch"))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetRandomPortWithSupportedBreakoutModesInterfacesNotFoundInFailure) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + const std::string platform_json_contents = + R"pb({} + )pb"; + gnmi::GetRequest req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { elem { name: "interfaces" } } + type: STATE)pb", + &req)); + gnmi::GetResponse resp; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(notification { + timestamp: 1631864194292383538 + prefix { origin: "openconfig" } + update { + path { elem { name: "interfaces" } } + val { + json_ietf_val: "{\"openconfig-interfaces:interfaces\":{\"interface\":[{\"name\":\"Ethernet0\",\"state\":{\"oper-status\":\"UP\"}}]}}" + } + } + } + )pb", + &resp)); + EXPECT_CALL(*mock_gnmi_stub_ptr, Get(_, EqualsProto(req), _)) + .WillOnce(DoAll(SetArgPointee<2>(resp), Return(grpc::Status::OK))); + EXPECT_THAT(pins_test::GetRandomPortWithSupportedBreakoutModes( + *mock_gnmi_stub_ptr, platform_json_contents), + StatusIs(absl::StatusCode::kInternal, + HasSubstr("Interfaces not found in platform.json"))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetRandomPortWithSupportedBreakoutModesInterfaceNotFoundFailure) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + const std::string platform_json_contents = + R"pb({ "interfaces": {} } + )pb"; + gnmi::GetRequest req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { elem { name: "interfaces" } } + type: STATE)pb", + &req)); + gnmi::GetResponse resp; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(notification { + timestamp: 1631864194292383538 + prefix { origin: "openconfig" } + update { + path { elem { name: "interfaces" } } + val { + json_ietf_val: "{\"openconfig-interfaces:interfaces\":{\"interface\":[{\"name\":\"Ethernet0\",\"state\":{\"oper-status\":\"UP\"}}]}}" + } + } + } + )pb", + &resp)); + EXPECT_CALL(*mock_gnmi_stub_ptr, Get(_, EqualsProto(req), _)) + .WillOnce(DoAll(SetArgPointee<2>(resp), Return(grpc::Status::OK))); + EXPECT_THAT( + pins_test::GetRandomPortWithSupportedBreakoutModes( + *mock_gnmi_stub_ptr, platform_json_contents), + StatusIs(absl::StatusCode::kInternal, + HasSubstr("Ethernet0 entry not found in platform.json"))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetRandomPortWithSupportedBreakoutModesDefaultModeNotFoundFailure) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + const std::string platform_json_contents = + R"pb({ + "interfaces": { + "Ethernet0": { "breakout_modes": "1x400G, 2x200G[100G,40G]" } + } + } + )pb"; + gnmi::GetRequest req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { elem { name: "interfaces" } } + type: STATE)pb", + &req)); + gnmi::GetResponse resp; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(notification { + timestamp: 1631864194292383538 + prefix { origin: "openconfig" } + update { + path { elem { name: "interfaces" } } + val { + json_ietf_val: "{\"openconfig-interfaces:interfaces\":{\"interface\":[{\"name\":\"Ethernet0\",\"state\":{\"oper-status\":\"UP\"}}]}}" + } + } + } + )pb", + &resp)); + EXPECT_CALL(*mock_gnmi_stub_ptr, Get(_, EqualsProto(req), _)) + .WillOnce(DoAll(SetArgPointee<2>(resp), Return(grpc::Status::OK))); + EXPECT_THAT(pins_test::GetRandomPortWithSupportedBreakoutModes( + *mock_gnmi_stub_ptr, platform_json_contents), + StatusIs(absl::StatusCode::kInternal, + HasSubstr("Default breakout mode not found for " + "Ethernet0 in platform.json"))); +} + +TEST_F( + GNMIThinkitInterfaceUtilityTest, + TestGetRandomPortWithSupportedBreakoutModesSupportedModesNotFoundnFailure) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + const std::string platform_json_contents = + R"pb({ + "interfaces": { "Ethernet0": { "default_brkout_mode": "1x400G" } } + } + )pb"; + gnmi::GetRequest req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { elem { name: "interfaces" } } + type: STATE)pb", + &req)); + gnmi::GetResponse resp; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(notification { + timestamp: 1631864194292383538 + prefix { origin: "openconfig" } + update { + path { elem { name: "interfaces" } } + val { + json_ietf_val: "{\"openconfig-interfaces:interfaces\":{\"interface\":[{\"name\":\"Ethernet0\",\"state\":{\"oper-status\":\"UP\"}}]}}" + } + } + } + )pb", + &resp)); + EXPECT_CALL(*mock_gnmi_stub_ptr, Get(_, EqualsProto(req), _)) + .WillOnce(DoAll(SetArgPointee<2>(resp), Return(grpc::Status::OK))); + EXPECT_THAT( + pins_test::GetRandomPortWithSupportedBreakoutModes( + *mock_gnmi_stub_ptr, platform_json_contents), + StatusIs(absl::StatusCode::kInternal, + HasSubstr( + "Breakout modes not found for Ethernet0 in platform.json"))); +} + +TEST_F( + GNMIThinkitInterfaceUtilityTest, + TestGetRandomPortWithSupportedBreakoutModesNoSupportedBreakoutTypeFailure) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + const std::string platform_json_contents = + R"pb({ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x400G", + "breakout_modes": "1x400G" + }, + "Ethernet8": { + "default_brkout_mode": "1x400G", + "breakout_modes": "1x400G" + } + } + } + )pb"; + gnmi::GetRequest req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { elem { name: "interfaces" } } + type: STATE)pb", + &req)); + gnmi::GetResponse resp; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(notification { + timestamp: 1631864194292383538 + prefix { origin: "openconfig" } + update { + path { elem { name: "interfaces" } } + val { + json_ietf_val: "{\"openconfig-interfaces:interfaces\":{\"interface\":[{\"name\":\"Ethernet0\",\"state\":{\"oper-status\":\"UP\"}},{\"name\":\"Ethernet8\",\"state\":{\"oper-status\":\"UP\"}}]}}" + } + } + } + )pb", + &resp)); + EXPECT_CALL(*mock_gnmi_stub_ptr, Get(_, EqualsProto(req), _)) + .WillOnce(DoAll(SetArgPointee<2>(resp), Return(grpc::Status::OK))); + EXPECT_THAT( + pins_test::GetRandomPortWithSupportedBreakoutModes( + *mock_gnmi_stub_ptr, platform_json_contents, + pins_test::BreakoutType::kChannelized), + StatusIs(absl::StatusCode::kInternal, + HasSubstr( + "No random interface with supported breakout modes found"))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetExpectedPortInfoForBreakoutModeUnchannelizedBreakoutModeSuccess) { + const std::string port = "Ethernet0"; + absl::string_view breakout_mode = "1x400G"; + + auto breakout_info = + pins_test::GetExpectedPortInfoForBreakoutMode(port, breakout_mode); + ASSERT_OK(breakout_info.status()); + EXPECT_EQ(breakout_info.value()["Ethernet0"].physical_channels, + "[0,1,2,3,4,5,6,7]"); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetExpectedPortInfoForBreakoutModeChannelizedBreakoutModeSuccess) { + const std::string port = "Ethernet0"; + absl::string_view breakout_mode = "2x200G"; + + auto breakout_info = + pins_test::GetExpectedPortInfoForBreakoutMode(port, breakout_mode); + ASSERT_OK(breakout_info.status()); + EXPECT_EQ(breakout_info.value()["Ethernet0"].physical_channels, "[0,1,2,3]"); + EXPECT_EQ(breakout_info.value()["Ethernet4"].physical_channels, "[4,5,6,7]"); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetExpectedPortInfoForBreakoutModeMixedBreakoutModeSuccess) { + const std::string port = "Ethernet0"; + absl::string_view breakout_mode = "1x200G+2x100G"; + + auto breakout_info = + pins_test::GetExpectedPortInfoForBreakoutMode(port, breakout_mode); + ASSERT_OK(breakout_info.status()); + EXPECT_EQ(breakout_info.value()["Ethernet0"].physical_channels, "[0,1,2,3]"); + EXPECT_EQ(breakout_info.value()["Ethernet4"].physical_channels, "[4,5]"); + EXPECT_EQ(breakout_info.value()["Ethernet6"].physical_channels, "[6,7]"); +} + +TEST_F( + GNMIThinkitInterfaceUtilityTest, + TestGetExpectedPortInfoForBreakoutModeAlternatedMixedBreakoutModeSuccess) { + const std::string port = "Ethernet0"; + absl::string_view breakout_mode = "2x100G+1x200G"; + auto breakout_info = + pins_test::GetExpectedPortInfoForBreakoutMode(port, breakout_mode); + ASSERT_OK(breakout_info.status()); + EXPECT_EQ(breakout_info.value()["Ethernet0"].physical_channels, "[0,1]"); + EXPECT_EQ(breakout_info.value()["Ethernet2"].physical_channels, "[2,3]"); + EXPECT_EQ(breakout_info.value()["Ethernet4"].physical_channels, "[4,5,6,7]"); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetExpectedPortInfoForBreakoutModeWithQuotesSuccess) { + const std::string port = "Ethernet0"; + absl::string_view breakout_mode = "\"1x400G\""; + auto breakout_info = + pins_test::GetExpectedPortInfoForBreakoutMode(port, breakout_mode); + ASSERT_OK(breakout_info.status()); + EXPECT_EQ(breakout_info.value()["Ethernet0"].physical_channels, + "[0,1,2,3,4,5,6,7]"); +} + } // namespace pins_test From 6b630dc0c5a4107f3470cf3bb298df3ec8599f48 Mon Sep 17 00:00:00 2001 From: kishanps Date: Mon, 18 Nov 2024 04:31:00 -0800 Subject: [PATCH 3/4] [Thinkit] Adding test cases to thinkit_gnmi_interface_util_tests file. --- tests/thinkit_gnmi_interface_util_tests.cc | 312 +++++++++++++++++++++ 1 file changed, 312 insertions(+) diff --git a/tests/thinkit_gnmi_interface_util_tests.cc b/tests/thinkit_gnmi_interface_util_tests.cc index dadb48f9..d25d0677 100644 --- a/tests/thinkit_gnmi_interface_util_tests.cc +++ b/tests/thinkit_gnmi_interface_util_tests.cc @@ -582,4 +582,316 @@ TEST_F(GNMIThinkitInterfaceUtilityTest, "[0,1,2,3,4,5,6,7]"); } +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetExpectedPortInfoForBreakoutModeEmptyBreakoutModeFailure) { + const std::string port = "Ethernet0"; + absl::string_view breakout_mode = ""; + + EXPECT_THAT( + pins_test::GetExpectedPortInfoForBreakoutMode(port, breakout_mode), + StatusIs(absl::StatusCode::kInternal, + HasSubstr("Found empty breakout mode"))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetExpectedPortInfoForBreakoutModePortNumberIntConversionFailure) { + const std::string port = "EthernetX"; + absl::string_view breakout_mode = "1x400G"; + + EXPECT_THAT( + pins_test::GetExpectedPortInfoForBreakoutMode(port, breakout_mode), + StatusIs(absl::StatusCode::kInternal, + HasSubstr("Failed to convert string (X) to integer"))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetExpectedPortInfoForBreakoutModeNonParentPortFailure) { + const std::string port = "Ethernet4"; + absl::string_view breakout_mode = "1x400G"; + + EXPECT_THAT( + pins_test::GetExpectedPortInfoForBreakoutMode(port, breakout_mode), + StatusIs(absl::StatusCode::kInternal, + HasSubstr("Requested port (Ethernet4) is not a parent port"))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetExpectedPortInfoForBreakoutModeNumBreakoutsIntConversionFailure) { + const std::string port = "Ethernet0"; + absl::string_view breakout_mode = "InvalidNumBreakoutsx400G"; + + EXPECT_THAT( + pins_test::GetExpectedPortInfoForBreakoutMode(port, breakout_mode), + StatusIs( + absl::StatusCode::kInternal, + HasSubstr( + "Failed to convert string (InvalidNumBreakouts) to integer"))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetExpectedPortInfoForBreakoutModeInvalidBreakoutModeFailure) { + const std::string port = "Ethernet0"; + absl::string_view breakout_mode = "3x200G+2x100G"; + + EXPECT_THAT( + pins_test::GetExpectedPortInfoForBreakoutMode(port, breakout_mode), + StatusIs(absl::StatusCode::kInternal, + HasSubstr(absl::StrCat("Invalid breakout mode (", breakout_mode, + ") found")))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetBreakoutStateInfoForPortSuccess) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + const std::string port = "Ethernet0"; + const std::string breakout_mode = "1x400G"; + gnmi::GetRequest physical_channels_req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "physical-channel" } + } + type: STATE)pb", + &physical_channels_req)); + gnmi::GetResponse physical_channels_resp; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(notification { + timestamp: 1632102697805380043 + prefix { origin: "openconfig" } + update { + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "physical-channel" } + } + val { + json_ietf_val: "{\"openconfig-platform-transceiver:physical-channel\":[0,1,2,3,4,5,6,7]}" + } + } + })pb", + &physical_channels_resp)); + gnmi::GetRequest oper_status_req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "oper-status" } + } + type: STATE)pb", + &oper_status_req)); + gnmi::GetResponse oper_status_resp; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(notification { + timestamp: 1632102697699213032 + prefix { origin: "openconfig" } + update { + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "oper-status" } + } + val { + json_ietf_val: "{\"openconfig-interfaces:oper-status\":\"UP\"}" + } + } + })pb", + &oper_status_resp)); + EXPECT_CALL(*mock_gnmi_stub_ptr, + Get(_, EqualsProto(physical_channels_req), _)) + .WillOnce(DoAll(SetArgPointee<2>(physical_channels_resp), + Return(grpc::Status::OK))); + EXPECT_CALL(*mock_gnmi_stub_ptr, Get(_, EqualsProto(oper_status_req), _)) + .WillOnce( + DoAll(SetArgPointee<2>(oper_status_resp), Return(grpc::Status::OK))); + auto breakout_state_info = pins_test::GetBreakoutStateInfoForPort( + mock_gnmi_stub_ptr.get(), port, breakout_mode); + ASSERT_OK(breakout_state_info.status()); + EXPECT_EQ(breakout_state_info.value()["Ethernet0"].physical_channels, + "[0,1,2,3,4,5,6,7]"); + EXPECT_EQ(breakout_state_info.value()["Ethernet0"].oper_status, "\"UP\""); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetBreakoutStateInfoForPortExpectedBreakoutInfoFailure) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + const std::string port = "Ethernet0"; + const std::string breakout_mode = ""; + EXPECT_THAT(pins_test::GetBreakoutStateInfoForPort(mock_gnmi_stub_ptr.get(), + port, breakout_mode), + StatusIs(absl::StatusCode::kInternal, + HasSubstr(("Found empty breakout mode")))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetBreakoutStateInfoForPortPhysicalChannelsGetFailure) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + const std::string port = "Ethernet0"; + const std::string breakout_mode = "1x400G"; + gnmi::GetRequest physical_channels_req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "physical-channel" } + } + type: STATE)pb", + &physical_channels_req)); + gnmi::GetRequest oper_status_req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "oper-status" } + } + type: STATE)pb", + &oper_status_req)); + gnmi::GetResponse oper_status_resp; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(notification { + timestamp: 1632102697699213032 + prefix { origin: "openconfig" } + update { + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "oper-status" } + } + val { + json_ietf_val: "{\"openconfig-interfaces:oper-status\":\"UP\"}" + } + } + })pb", + &oper_status_resp)); + EXPECT_CALL(*mock_gnmi_stub_ptr, Get(_, EqualsProto(oper_status_req), _)) + .WillOnce( + DoAll(SetArgPointee<2>(oper_status_resp), Return(grpc::Status::OK))); + EXPECT_CALL(*mock_gnmi_stub_ptr, + Get(_, EqualsProto(physical_channels_req), _)) + .WillOnce(Return(grpc::Status(grpc::StatusCode::DEADLINE_EXCEEDED, ""))); + EXPECT_THAT(pins_test::GetBreakoutStateInfoForPort(mock_gnmi_stub_ptr.get(), + port, breakout_mode), + StatusIs(absl::StatusCode::kDeadlineExceeded, + HasSubstr("Failed to get GNMI state path value for " + "physical-channels for port Ethernet0"))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetBreakoutStateInfoForPortOperStatusGetFailure) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + const std::string port = "Ethernet0"; + const std::string breakout_mode = "1x400G"; + gnmi::GetRequest oper_status_req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "oper-status" } + } + type: STATE)pb", + &oper_status_req)); + EXPECT_CALL(*mock_gnmi_stub_ptr, Get(_, EqualsProto(oper_status_req), _)) + .WillOnce(Return(grpc::Status(grpc::StatusCode::DEADLINE_EXCEEDED, ""))); + EXPECT_THAT(pins_test::GetBreakoutStateInfoForPort(mock_gnmi_stub_ptr.get(), + port, breakout_mode), + StatusIs(absl::StatusCode::kDeadlineExceeded, + HasSubstr("Failed to get GNMI state path value for " + "oper-status for port Ethernet0"))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetBreakoutModeConfigFromStringUnchannelizedBreakoutModeSuccess) { + const std::string port_index = "1"; + const std::string breakout_mode = "1x400G"; + gnmi::SetRequest req, expected_breakout_config; + const std::string expected_breakout_config_str = R"pb( + prefix { origin: "openconfig" } + replace { + path { + elem { name: "components" } + elem { + name: "component" + key { key: "name" value: "1/1" } + } + elem { name: "port" } + elem { name: "breakout-mode" } + } + val { + json_ietf_val: "{ \"openconfig-platform-port:groups\": { \"group\": [ {\n \"config\": {\n \"breakout-speed\": \"openconfig-if-ethernet:SPEED_400GB\",\n \"index\": 0,\n \"num-breakouts\": 1,\n \"num-physical-channels\": 8\n },\n \"index\": 0\n } ] } }" + } + } + )pb"; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + expected_breakout_config_str, &expected_breakout_config)); + ASSERT_OK(pins_test::GetBreakoutModeConfigFromString(req, port_index, + breakout_mode)); + EXPECT_THAT(req, EqualsProto(expected_breakout_config)); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetBreakoutModeConfigFromStringChannelizedBreakoutModeSuccess) { + const std::string port_index = "1"; + const std::string breakout_mode = "2x200G"; + gnmi::SetRequest req, expected_breakout_config; + const std::string expected_breakout_config_str = R"pb( + prefix { origin: "openconfig" } + replace { + path { + elem { name: "components" } + elem { + name: "component" + key { key: "name" value: "1/1" } + } + elem { name: "port" } + elem { name: "breakout-mode" } + } + val { + json_ietf_val: "{ \"openconfig-platform-port:groups\": { \"group\": [ {\n \"config\": {\n \"breakout-speed\": \"openconfig-if-ethernet:SPEED_200GB\",\n \"index\": 0,\n \"num-breakouts\": 2,\n \"num-physical-channels\": 4\n },\n \"index\": 0\n } ] } }" + } + } + )pb"; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + expected_breakout_config_str, &expected_breakout_config)); + ASSERT_OK(pins_test::GetBreakoutModeConfigFromString(req, port_index, + breakout_mode)); + EXPECT_THAT(req, EqualsProto(expected_breakout_config)); +} + } // namespace pins_test From 601b9bbdd8162cbf6e941540a03ee036cebe682c Mon Sep 17 00:00:00 2001 From: kishanps Date: Mon, 18 Nov 2024 04:51:39 -0800 Subject: [PATCH 4/4] [Thinkit] Adding few more test cases to thinkit_gnmi_interface_util_tests file. --- tests/thinkit_gnmi_interface_util_tests.cc | 383 ++++++++++++++++++++- 1 file changed, 379 insertions(+), 4 deletions(-) diff --git a/tests/thinkit_gnmi_interface_util_tests.cc b/tests/thinkit_gnmi_interface_util_tests.cc index d25d0677..32e6d582 100644 --- a/tests/thinkit_gnmi_interface_util_tests.cc +++ b/tests/thinkit_gnmi_interface_util_tests.cc @@ -867,7 +867,7 @@ TEST_F(GNMIThinkitInterfaceUtilityTest, TEST_F(GNMIThinkitInterfaceUtilityTest, TestGetBreakoutModeConfigFromStringChannelizedBreakoutModeSuccess) { - const std::string port_index = "1"; + const std::string port_index = "1"; const std::string breakout_mode = "2x200G"; gnmi::SetRequest req, expected_breakout_config; const std::string expected_breakout_config_str = R"pb( @@ -881,11 +881,40 @@ TEST_F(GNMIThinkitInterfaceUtilityTest, } elem { name: "port" } elem { name: "breakout-mode" } - } + } val { json_ietf_val: "{ \"openconfig-platform-port:groups\": { \"group\": [ {\n \"config\": {\n \"breakout-speed\": \"openconfig-if-ethernet:SPEED_200GB\",\n \"index\": 0,\n \"num-breakouts\": 2,\n \"num-physical-channels\": 4\n },\n \"index\": 0\n } ] } }" - } - } + } + } + )pb"; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + expected_breakout_config_str, &expected_breakout_config)); + ASSERT_OK(pins_test::GetBreakoutModeConfigFromString(req, port_index, + breakout_mode)); + EXPECT_THAT(req, EqualsProto(expected_breakout_config)); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetBreakoutModeConfigFromStringMixedBreakoutModeSuccess) { + const std::string port_index = "1"; + const std::string breakout_mode = "1x200G+2x100G"; + gnmi::SetRequest req, expected_breakout_config; + const std::string expected_breakout_config_str = R"pb( + prefix { origin: "openconfig" } + replace { + path { + elem { name: "components" } + elem { + name: "component" + key { key: "name" value: "1/1" } + } + elem { name: "port" } + elem { name: "breakout-mode" } + } + val { + json_ietf_val: "{ \"openconfig-platform-port:groups\": { \"group\": [ {\n \"config\": {\n \"breakout-speed\": \"openconfig-if-ethernet:SPEED_200GB\",\n \"index\": 0,\n \"num-breakouts\": 1,\n \"num-physical-channels\": 4\n },\n \"index\": 0\n },{\n \"config\": {\n \"breakout-speed\": \"openconfig-if-ethernet:SPEED_100GB\",\n \"index\": 1,\n \"num-breakouts\": 2,\n \"num-physical-channels\": 2\n },\n \"index\": 1\n } ] } }" + } + } )pb"; ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( expected_breakout_config_str, &expected_breakout_config)); @@ -894,4 +923,350 @@ TEST_F(GNMIThinkitInterfaceUtilityTest, EXPECT_THAT(req, EqualsProto(expected_breakout_config)); } +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetBreakoutModeConfigFromStringIntConversionFailure) { + const std::string port_index = "1"; + const std::string breakout_mode = "Xx400G"; + gnmi::SetRequest req; + EXPECT_THAT(pins_test::GetBreakoutModeConfigFromString(req, port_index, + breakout_mode), + StatusIs(absl::StatusCode::kInternal, + HasSubstr("Failed to convert string (X) to integer"))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetNonExistingPortsAfterBreakoutForBreakoutAppliedSuccess) { + absl::flat_hash_map + orig_breakout_info; + orig_breakout_info["Ethernet0"] = + pins_test::PortBreakoutInfo{"[0,1,2,3,4,5,6,7]", pins_test::kStateUp}; + absl::flat_hash_map + new_breakout_info; + new_breakout_info["Ethernet0"] = + pins_test::PortBreakoutInfo{"[0,1,2,3]", pins_test::kStateUp}; + new_breakout_info["Ethernet4"] = + pins_test::PortBreakoutInfo{"[4,5,6,7]", pins_test::kStateUp}; + + std::vector expected_non_existing_ports; + EXPECT_THAT(GetNonExistingPortsAfterBreakout(orig_breakout_info, + new_breakout_info, true), + ContainerEq(expected_non_existing_ports)); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetNonExistingPortsAfterBreakoutForBreakoutAppliedAlternateSuccess) { + absl::flat_hash_map + orig_breakout_info; + orig_breakout_info["Ethernet0"] = + pins_test::PortBreakoutInfo{"[0,1,2,3]", pins_test::kStateUp}; + orig_breakout_info["Ethernet4"] = + pins_test::PortBreakoutInfo{"[4,5,6,7]", pins_test::kStateUp}; + absl::flat_hash_map + new_breakout_info; + new_breakout_info["Ethernet0"] = + pins_test::PortBreakoutInfo{"[0,1,2,3,4,5,6,7]", pins_test::kStateUp}; + + std::vector expected_non_existing_ports{"Ethernet4"}; + EXPECT_THAT(GetNonExistingPortsAfterBreakout(orig_breakout_info, + new_breakout_info, true), + ContainerEq(expected_non_existing_ports)); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestGetNonExistingPortsAfterBreakoutForBreakoutNotAppliedSuccess) { + absl::flat_hash_map + orig_breakout_info; + orig_breakout_info["Ethernet0"] = + pins_test::PortBreakoutInfo{"[0,1,2,3,4,5,6,7]", pins_test::kStateUp}; + absl::flat_hash_map + new_breakout_info; + new_breakout_info["Ethernet0"] = + pins_test::PortBreakoutInfo{"[0,1,2,3]", pins_test::kStateDown}; + new_breakout_info["Ethernet4"] = + pins_test::PortBreakoutInfo{"[4,5,6,7]", pins_test::kStateDown}; + + std::vector expected_non_existing_ports{"Ethernet4"}; + EXPECT_THAT(GetNonExistingPortsAfterBreakout(orig_breakout_info, + new_breakout_info, false), + ContainerEq(expected_non_existing_ports)); +} + +TEST_F( + GNMIThinkitInterfaceUtilityTest, + TestGetNonExistingPortsAfterBreakoutForBreakoutNotAppliedAlternateSuccess) { + absl::flat_hash_map + orig_breakout_info; + orig_breakout_info["Ethernet0"] = + pins_test::PortBreakoutInfo{"[0,1,2,3]", pins_test::kStateUp}; + orig_breakout_info["Ethernet4"] = + pins_test::PortBreakoutInfo{"[4,5,6,7]", pins_test::kStateUp}; + absl::flat_hash_map + new_breakout_info; + new_breakout_info["Ethernet0"] = + pins_test::PortBreakoutInfo{"[0,1,2,3,4,5,6,7]", pins_test::kStateDown}; + + std::vector expected_non_existing_ports{}; + EXPECT_THAT(GetNonExistingPortsAfterBreakout(orig_breakout_info, + new_breakout_info, false), + ContainerEq(expected_non_existing_ports)); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestValidateBreakoutStateEmptyExpectedInfoFailure) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + absl::flat_hash_map + expected_port_info; + std::vector non_existing_port_list; + EXPECT_THAT( + pins_test::ValidateBreakoutState( + mock_gnmi_stub_ptr.get(), expected_port_info, non_existing_port_list), + StatusIs(absl::StatusCode::kInternal, + HasSubstr("Expected port info map is empty"))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestValidateBreakoutStateOperStatusMatchFailure) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + absl::flat_hash_map + expected_port_info; + expected_port_info["Ethernet0"] = + pins_test::PortBreakoutInfo{"[0,1,2,3,4,5,6,7]", pins_test::kStateUp}; + std::vector non_existing_port_list; + gnmi::GetRequest oper_status_req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "oper-status" } + } + type: STATE)pb", + &oper_status_req)); + gnmi::GetResponse oper_status_resp; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(notification { + timestamp: 1632102697699213032 + prefix { origin: "openconfig" } + update { + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "oper-status" } + } + val { + json_ietf_val: "{\"openconfig-interfaces:oper-status\":\"DOWN\"}" + } + } + })pb", + &oper_status_resp)); + EXPECT_CALL(*mock_gnmi_stub_ptr, Get(_, EqualsProto(oper_status_req), _)) + .WillOnce( + DoAll(SetArgPointee<2>(oper_status_resp), Return(grpc::Status::OK))); + EXPECT_THAT( + pins_test::ValidateBreakoutState( + mock_gnmi_stub_ptr.get(), expected_port_info, non_existing_port_list), + StatusIs(absl::StatusCode::kInternal, + HasSubstr(absl::StrCat( + "Port oper-status match failed for port Ethernet0. got: \"", + pins_test::kStateDown, + "\", want:", expected_port_info["Ethernet0"].oper_status)))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestValidateBreakoutStatePhysicalChannelsMatchFailure) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + absl::flat_hash_map + expected_port_info; + expected_port_info["Ethernet0"] = + pins_test::PortBreakoutInfo{"[0,1,2,3]", pins_test::kStateUp}; + std::vector non_existing_port_list; + gnmi::GetRequest oper_status_req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "oper-status" } + } + type: STATE)pb", + &oper_status_req)); + gnmi::GetResponse oper_status_resp; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(notification { + timestamp: 1632102697699213032 + prefix { origin: "openconfig" } + update { + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "oper-status" } + } + val { + json_ietf_val: "{\"openconfig-interfaces:oper-status\":\"UP\"}" + } + } + })pb", + &oper_status_resp)); + gnmi::GetRequest physical_channels_req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "physical-channel" } + } + type: STATE)pb", + &physical_channels_req)); + gnmi::GetResponse physical_channels_resp; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(notification { + timestamp: 1632102697805380043 + prefix { origin: "openconfig" } + update { + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "physical-channel" } + } + val { + json_ietf_val: "{\"openconfig-platform-transceiver:physical-channel\":[0,1,2,3,4,5,6,7]}" + } + } + })pb", + &physical_channels_resp)); + EXPECT_CALL(*mock_gnmi_stub_ptr, Get(_, EqualsProto(oper_status_req), _)) + .WillOnce( + DoAll(SetArgPointee<2>(oper_status_resp), Return(grpc::Status::OK))); + EXPECT_CALL(*mock_gnmi_stub_ptr, + Get(_, EqualsProto(physical_channels_req), _)) + .WillOnce(DoAll(SetArgPointee<2>(physical_channels_resp), + Return(grpc::Status::OK))); + EXPECT_THAT( + pins_test::ValidateBreakoutState( + mock_gnmi_stub_ptr.get(), expected_port_info, non_existing_port_list), + StatusIs(absl::StatusCode::kInternal, + HasSubstr(absl::StrCat( + "Physical channel match failed for port Ethernet0. got: " + "[0,1,2,3,4,5,6,7], want: ", + expected_port_info["Ethernet0"].physical_channels)))); +} + +TEST_F(GNMIThinkitInterfaceUtilityTest, + TestValidateBreakoutStateNonExistingPortListMatchFailure) { + auto mock_gnmi_stub_ptr = absl::make_unique(); + absl::flat_hash_map + expected_port_info; + expected_port_info["Ethernet0"] = + pins_test::PortBreakoutInfo{"[0,1,2,3,4,5,6,7]", pins_test::kStateUp}; + std::vector non_existing_port_list{"Ethernet0"}; + gnmi::GetRequest oper_status_req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "oper-status" } + } + type: STATE)pb", + &oper_status_req)); + gnmi::GetResponse oper_status_resp; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(notification { + timestamp: 1632102697699213032 + prefix { origin: "openconfig" } + update { + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "oper-status" } + } + val { + json_ietf_val: "{\"openconfig-interfaces:oper-status\":\"UP\"}" + } + } + })pb", + &oper_status_resp)); + gnmi::GetRequest physical_channels_req; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(prefix { origin: "openconfig" } + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "physical-channel" } + } + type: STATE)pb", + &physical_channels_req)); + gnmi::GetResponse physical_channels_resp; + ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString( + R"pb(notification { + timestamp: 1632102697805380043 + prefix { origin: "openconfig" } + update { + path { + elem { name: "interfaces" } + elem { + name: "interface" + key { key: "name" value: "Ethernet0" } + } + elem { name: "state" } + elem { name: "physical-channel" } + } + val { + json_ietf_val: "{\"openconfig-platform-transceiver:physical-channel\":[0,1,2,3,4,5,6,7]}" + } + } + })pb", + &physical_channels_resp)); + EXPECT_CALL(*mock_gnmi_stub_ptr, Get(_, EqualsProto(oper_status_req), _)) + .Times(2) + .WillRepeatedly( + DoAll(SetArgPointee<2>(oper_status_resp), Return(grpc::Status::OK))); + EXPECT_CALL(*mock_gnmi_stub_ptr, + Get(_, EqualsProto(physical_channels_req), _)) + .WillOnce(DoAll(SetArgPointee<2>(physical_channels_resp), + Return(grpc::Status::OK))); + EXPECT_THAT( + pins_test::ValidateBreakoutState( + mock_gnmi_stub_ptr.get(), expected_port_info, non_existing_port_list), + StatusIs(absl::StatusCode::kInternal, + HasSubstr("Unexpected port (Ethernet0) found after " + "application of breakout mode"))); +} + } // namespace pins_test