Skip to content

Commit

Permalink
[P4Testgen] Look up the alias in the P4Info instead of using the full…
Browse files Browse the repository at this point in the history
…y qualified control plane name for Protobuf IR tests. (#4425)
  • Loading branch information
fruffy-g authored Feb 15, 2024
1 parent 25e793a commit 6fc5815
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,9 @@ Bmv2TestBackend::Bmv2TestBackend(const Bmv2V1ModelProgramInfo &programInfo,
} else if (testBackendString == "STF") {
testWriter = new STF(testBackendConfiguration);
} else if (testBackendString == "PROTOBUF") {
auto p4RuntimeAPI = programInfo.getP4RuntimeAPI();
testWriter = new Protobuf(testBackendConfiguration, p4RuntimeAPI);
testWriter = new Protobuf(testBackendConfiguration, programInfo.getP4RuntimeAPI());
} else if (testBackendString == "PROTOBUF_IR") {
testWriter = new ProtobufIr(testBackendConfiguration);
testWriter = new ProtobufIr(testBackendConfiguration, programInfo.getP4RuntimeAPI());
} else if (testBackendString == "METADATA") {
testWriter = new Metadata(testBackendConfiguration);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,25 @@ inja::json::array_t Bmv2TestFramework::getMeter(const TestObjectMap &meterValues
return meterJson;
}

inja::json Bmv2TestFramework::getControlPlaneTable(const TableConfig &tblConfig) const {
inja::json tblJson;
tblJson["table_name"] = tblConfig.getTable()->controlPlaneName();
const auto *tblRules = tblConfig.getRules();
tblJson["rules"] = inja::json::array();
for (const auto &tblRule : *tblRules) {
inja::json rule;
const auto *matches = tblRule.getMatches();
const auto *actionCall = tblRule.getActionCall();
const auto *actionArgs = actionCall->getArgs();
rule["action_name"] = actionCall->getActionName().c_str();
auto j = getControlPlaneForTable(*matches, *actionArgs);
rule["rules"] = std::move(j);
rule["priority"] = tblRule.getPriority();
tblJson["rules"].push_back(rule);
}
return tblJson;
}

inja::json Bmv2TestFramework::getControlPlane(const TestSpec *testSpec) const {
auto controlPlaneJson = inja::json::object();
// Map of actionProfiles and actionSelectors for easy reference.
Expand All @@ -76,22 +95,8 @@ inja::json Bmv2TestFramework::getControlPlane(const TestSpec *testSpec) const {
controlPlaneJson["tables"] = inja::json::array();
}
for (const auto &testObject : tables) {
inja::json tblJson;
tblJson["table_name"] = testObject.first.c_str();
const auto *const tblConfig = testObject.second->checkedTo<TableConfig>();
const auto *tblRules = tblConfig->getRules();
tblJson["rules"] = inja::json::array();
for (const auto &tblRule : *tblRules) {
inja::json rule;
const auto *matches = tblRule.getMatches();
const auto *actionCall = tblRule.getActionCall();
const auto *actionArgs = actionCall->getArgs();
rule["action_name"] = actionCall->getActionName().c_str();
auto j = getControlPlaneForTable(*matches, *actionArgs);
rule["rules"] = std::move(j);
rule["priority"] = tblRule.getPriority();
tblJson["rules"].push_back(rule);
}
inja::json tblJson = getControlPlaneTable(*tblConfig);

// Collect action profiles and selectors associated with the table.
checkForTableActionProfile<Bmv2V1ModelActionProfile, Bmv2V1ModelActionSelector>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class Bmv2TestFramework : public TestFramework {
/// @returns the configuration for a meter call (may set the meter to GREEN, YELLOW, or RED)
[[nodiscard]] virtual inja::json::array_t getMeter(const TestObjectMap &meterValues) const;

/// Converts a table configuration into Inja format.
[[nodiscard]] virtual inja::json getControlPlaneTable(const TableConfig &tblConfig) const;

/// Helper function for the control plane table inja objects.
[[nodiscard]] virtual inja::json getControlPlaneForTable(
const TableMatchMap &matches, const std::vector<ActionArg> &args) const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
#include <iomanip>
#include <optional>
#include <string>
#include <utility>

#include <inja/inja.hpp>

#include "backends/p4tools/common/lib/util.h"
#include "control-plane/p4infoApi.h"
#include "lib/exceptions.h"
#include "lib/log.h"
#include "nlohmann/json.hpp"
Expand All @@ -19,8 +19,9 @@

namespace P4Tools::P4Testgen::Bmv2 {

ProtobufIr::ProtobufIr(const TestBackendConfiguration &testBackendConfiguration)
: Bmv2TestFramework(testBackendConfiguration) {}
ProtobufIr::ProtobufIr(const TestBackendConfiguration &testBackendConfiguration,
P4::P4RuntimeAPI p4RuntimeApi)
: Bmv2TestFramework(testBackendConfiguration), p4RuntimeApi(p4RuntimeApi) {}

std::string ProtobufIr::getFormatOfNode(const IR::IAnnotated *node) {
const auto *formatAnnotation = node->getAnnotation("format");
Expand Down Expand Up @@ -253,6 +254,32 @@ void ProtobufIr::createKeyMatch(cstring fieldName, const TableMatch &fieldMatch,
}
}

inja::json ProtobufIr::getControlPlaneTable(const TableConfig &tblConfig) const {
inja::json tblJson;
const auto *p4RuntimeTableOpt = P4::ControlPlaneAPI::findP4RuntimeTable(
*p4RuntimeApi.p4Info, tblConfig.getTable()->controlPlaneName());
BUG_CHECK(p4RuntimeTableOpt != nullptr, "Table not found in the P4Info file.");
tblJson["table_name"] = p4RuntimeTableOpt->preamble().alias();

const auto *tblRules = tblConfig.getRules();
tblJson["rules"] = inja::json::array();
for (const auto &tblRule : *tblRules) {
inja::json rule;
const auto *matches = tblRule.getMatches();
const auto *actionCall = tblRule.getActionCall();
const auto *actionArgs = actionCall->getArgs();
const auto *p4RuntimeActionOpt = P4::ControlPlaneAPI::findP4RuntimeAction(
*p4RuntimeApi.p4Info, actionCall->getAction()->controlPlaneName());
BUG_CHECK(p4RuntimeActionOpt != nullptr, "Action not found in the P4Info file.");
rule["action_name"] = p4RuntimeActionOpt->preamble().alias();
auto j = getControlPlaneForTable(*matches, *actionArgs);
rule["rules"] = std::move(j);
rule["priority"] = tblRule.getPriority();
tblJson["rules"].push_back(rule);
}
return tblJson;
}

inja::json ProtobufIr::getControlPlaneForTable(const TableMatchMap &matches,
const std::vector<ActionArg> &args) const {
inja::json rulesJson;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <inja/inja.hpp>

#include "control-plane/p4RuntimeSerializer.h"
#include "lib/cstring.h"

#include "backends/p4tools/modules/testgen/lib/test_spec.h"
Expand All @@ -31,7 +32,8 @@ struct ProtobufIrTest : public AbstractTest {
/// Extracts information from the @testSpec to emit a Protobuf IR test case.
class ProtobufIr : public Bmv2TestFramework {
public:
explicit ProtobufIr(const TestBackendConfiguration &testBackendConfiguration);
explicit ProtobufIr(const TestBackendConfiguration &testBackendConfiguration,
P4::P4RuntimeAPI p4RuntimeApi);

~ProtobufIr() override = default;
ProtobufIr(const ProtobufIr &) = default;
Expand All @@ -46,6 +48,12 @@ class ProtobufIr : public Bmv2TestFramework {
size_t testIdx, float currentCoverage) override;

private:
/// The P4Runtime API generated by the compiler. This API can be used to look up the id of
/// tables.
P4::P4RuntimeAPI p4RuntimeApi;

[[nodiscard]] inja::json getControlPlaneTable(const TableConfig &tblConfig) const override;

[[nodiscard]] inja::json getControlPlaneForTable(
const TableMatchMap &matches, const std::vector<ActionArg> &args) const override;

Expand Down

0 comments on commit 6fc5815

Please sign in to comment.