Skip to content

Commit

Permalink
Use common libraries for hash tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
kishanps authored and divyagayathri-hcl committed Jan 26, 2025
1 parent 6638d88 commit 6f6133b
Show file tree
Hide file tree
Showing 2 changed files with 224 additions and 0 deletions.
51 changes: 51 additions & 0 deletions tests/forwarding/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,57 @@ cc_library(
],
)

cc_library(
name = "hash_testfixture",
testonly = True,
hdrs = ["hash_testfixture.h"],
deps = [
":group_programming_util",
":packet_test_util",
":util",
"//gutil:proto_matchers",
"//gutil:status",
"//gutil:status_matchers",
"//gutil:testing",
"//lib/gnmi:gnmi_helper",
"//lib/p4rt:p4rt_port",
"//lib/validator:validator_lib",
"//p4_pdpi:ir",
"//p4_pdpi:ir_cc_proto",
"//p4_pdpi:p4_runtime_session",
"//p4_pdpi:pd",
"//p4_pdpi/packetlib",
"//p4_pdpi/packetlib:packetlib_cc_proto",
"//sai_p4/instantiations/google:sai_pd_cc_proto",
"//tests:thinkit_sanity_tests",
"//tests/lib:switch_test_setup_helpers",
"//thinkit:mirror_testbed",
"//thinkit:mirror_testbed_fixture",
"//thinkit:switch",
"//thinkit:test_environment",
"@com_github_gnoi//system:system_cc_proto",
"@com_github_google_glog//:glog",
"@com_github_grpc_grpc//:grpc++",
"@com_github_p4lang_p4runtime//:p4info_cc_proto",
"@com_github_p4lang_p4runtime//:p4runtime_cc_proto",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:btree",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:node_hash_map",
"@com_google_absl//absl/functional:bind_front",
"@com_google_absl//absl/meta:type_traits",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
"@com_google_absl//absl/utility",
"@com_google_googletest//:gtest",
"@com_googlesource_code_re2//:re2",
],
alwayslink = True,
)

cc_library(
name = "ouroboros_test",
testonly = True,
Expand Down
173 changes: 173 additions & 0 deletions tests/forwarding/hash_testfixture.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef PINS_TESTS_FORWARDING_HASH_TESTFIXTURE_H_
#define PINS_TESTS_FORWARDING_HASH_TESTFIXTURE_H_

#include <string>
#include <utility>
#include <vector>

#include "absl/base/thread_annotations.h"
#include "absl/container/btree_map.h"
#include "absl/container/btree_set.h"
#include "absl/container/node_hash_map.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "lib/p4rt/p4rt_port.h"
#include "p4/config/v1/p4info.pb.h"
#include "p4_pdpi/ir.pb.h"
#include "p4_pdpi/packetlib/packetlib.pb.h"
#include "tests/forwarding/group_programming_util.h"
#include "tests/forwarding/packet_test_util.h"
#include "thinkit/mirror_testbed_fixture.h"
#include "thinkit/switch.h"
#include "thinkit/test_environment.h"

namespace pins_test {

using TestConfigurationMap =
absl::btree_map<std::string, pins::TestConfiguration>;

// This class stores and reports data on received packets. Particularly, it
// keeps track of packets based on the egress port for the SUT / ingress port of
// the Control Switch.
// Test class for the hash config test.
class HashTest : public thinkit::MirrorTestbedFixture {
public:
class TestData {
public:
// Map of port to the set of indices of received packets.
// Sorted (btree) maps and sets help to make error messages more readable
// when doing container comparisons.
using ResultMap = absl::btree_map<std::string, absl::btree_set<int>>;

// Return the results of the received packets.
ResultMap Results() const ABSL_LOCKS_EXCLUDED(mutex_) {
absl::MutexLock lock(&mutex_);
return packets_by_port_;
}

// Add a received packet to this test data holder.
void AddPacket(absl::string_view egress_port, packetlib::Packet packet)
ABSL_LOCKS_EXCLUDED(mutex_);

// Return the number of packets that have been received.
int PacketCount() const ABSL_LOCKS_EXCLUDED(mutex_) {
absl::MutexLock lock(&mutex_);
return received_packets_.size();
}

// Log the packets while holding the mutex lock so we don't need to create
// and return copy of received_packets_.
absl::Status Log(thinkit::TestEnvironment &environment,
absl::string_view artifact_name)
ABSL_LOCKS_EXCLUDED(mutex_);

protected:
// Mutex to guard the data values. Values are written by the receiver thread
// and read by the main thread.
mutable absl::Mutex mutex_;

// Results as the set of packets arriving at each port.
ResultMap packets_by_port_ ABSL_GUARDED_BY(mutex_);

// In-order log of all the received packets paired with the egress port.
// Useful for logging.
std::vector<std::pair<std::string, packetlib::Packet>>
received_packets_ ABSL_GUARDED_BY(mutex_);
};

void SetUp() override;

void TearDown() override;

// Record the P4Info file for debugging.
absl::Status RecordP4Info(absl::string_view test_stage,
const p4::config::v1::P4Info &p4info);

// Reboot the SUT switch and wait for it to be ready.
// The switch is considered ready when the test ports are up and the P4Runtime
// session is reachable.
void RebootSut();

// Send and receive packets for all test configs. Save the resulting test
// data as a map of TestConfiguration name to TestData.
void SendPacketsAndRecordResultsPerTestConfig(
const TestConfigurationMap &test_configs,
const p4::config::v1::P4Info &p4info, absl::string_view test_stage,
int num_packets,
absl::node_hash_map<std::string, TestData> &output_record);

// Initializes the forwarding pipeline to forward all packets to the provided
// group members distributed according to their weight.
// Adds the nexthop-id to all members.
void ForwardAllPacketsToMembers(const p4::config::v1::P4Info &p4info,
std::vector<pins::GroupMember> &members);

// Initializes the forwarding pipeline to forward all packets to the provided
// ports with an equal distribution.
void ForwardAllPacketsToPorts(const p4::config::v1::P4Info &p4info,
const absl::btree_set<P4rtPortId> &port_ids) {
std::vector<pins::GroupMember> members;
for (const auto &port_id : port_ids) {
members.push_back(
{.weight = 1,
.port = static_cast<int>(port_id.GetOpenConfigEncoding())});
}
return ForwardAllPacketsToMembers(p4info, members);
}

// Returns the port IDs available to this test.
const absl::btree_set<P4rtPortId> &PortIds() { return port_ids_; }

protected:
// Send and receive packets for a particular test config. Save the resulting
// test data.
void SendAndReceivePackets(const pdpi::IrP4Info &ir_p4info,
absl::string_view record_prefix, int num_packets,
const pins::TestConfiguration &test_config,
TestData &test_data);

// Returns true if the target switch has no P4Info or has the P4Info
// associated with the test parameter (p4_info()).
absl::StatusOr<bool> HasDefaultOrNoP4Info(thinkit::Switch &target);

private:
// Set of interfaces to hash against. There is a 1:1 mapping of interfaces_ to
// port_ids_, but we don't care about the mapping in the test.
std::vector<std::string> interfaces_;

// Set of port IDs to hash against.
absl::btree_set<P4rtPortId> port_ids_;
};

// Return the list of all packet TestConfigurations to be tested. Each
// TestConfiguration should result in a hash difference.
const TestConfigurationMap &HashingTestConfigs();

// Returns the list of all HashingTestConfigs() test names.
const std::vector<std::string> &HashingTestConfigNames();

// Return the list of all possible packet TestConfigurations that do not result
// in a hash difference.
const TestConfigurationMap &NonHashingTestConfigs();

// Returns the list of all NonHashingTestConfigs() test names.
const std::vector<std::string> &NonHashingTestConfigNames();

} // namespace pins_test

#endif // PINS_TESTS_FORWARDING_HASH_TESTFIXTURE_H_

0 comments on commit 6f6133b

Please sign in to comment.