-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use common libraries for hash tests.
- Loading branch information
1 parent
6638d88
commit 6f6133b
Showing
2 changed files
with
224 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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_ |