7#ifndef BACKENDS_P4TOOLS_MODULES_TESTGEN_LIB_TEST_FRAMEWORK_H_
8#define BACKENDS_P4TOOLS_MODULES_TESTGEN_LIB_TEST_FRAMEWORK_H_
19#include <inja/inja.hpp>
21#include "backends/p4tools/common/lib/format_int.h"
22#include "backends/p4tools/common/lib/trace_event.h"
23#include "lib/castable.h"
24#include "lib/cstring.h"
26#include "backends/p4tools/modules/testgen/lib/test_backend_configuration.h"
27#include "backends/p4tools/modules/testgen/lib/test_object.h"
28#include "backends/p4tools/modules/testgen/lib/test_spec.h"
30namespace P4::P4Tools::P4Testgen {
32using namespace P4::literals;
39using AbstractTestReferenceOrError = std::optional<AbstractTestReference>;
40using AbstractTestList = std::vector<AbstractTestReference>;
44template <
class ConcreteTest,
45 typename = std::enable_if_t<std::is_base_of_v<AbstractTest, ConcreteTest>>>
46std::vector<const ConcreteTest *> convertAbstractTestsToConcreteTests(
47 const P4Tools::P4Testgen::AbstractTestList &testList) {
48 std::vector<const ConcreteTest *> result;
49 std::transform(testList.begin(), testList.end(), std::back_inserter(result),
50 [](AbstractTestReference test) { return test->checkedTo<ConcreteTest>(); });
56using OptionalFilePath = std::optional<std::filesystem::path>;
63 std::reference_wrapper<const TestBackendConfiguration> testBackendConfiguration;
73 inja::json traceList = inja::json::array();
74 const auto *traces = testSpec->
getTraces();
75 if (traces !=
nullptr) {
76 for (
const auto &trace : *traces) {
79 std::string traceStr = ss.str();
81 traceStr.erase(std::remove(traceStr.begin(), traceStr.end(),
'\n'),
84 traceList.push_back(traceStr);
92 template <
class ProfileType,
class SelectorType>
95 const auto *apObject = tblConfig->
getProperty(
"action_profile"_cs,
false);
96 if (apObject !=
nullptr) {
97 const auto *actionProfile = apObject->checkedTo<ProfileType>();
98 tblJson[
"has_ap"] =
true;
99 tblJson[
"action_profile"] = actionProfile->getProfileDecl()->controlPlaneName();
103 const auto *asObject = tblConfig->
getProperty(
"action_selector"_cs,
false);
104 if (asObject !=
nullptr) {
105 const auto *actionSelector = asObject->checkedTo<SelectorType>();
106 apAsMap[actionProfile->getProfileDecl()->controlPlaneName()] =
107 actionSelector->getSelectorDecl()->controlPlaneName();
108 tblJson[
"has_as"] =
true;
109 tblJson[
"action_selector"] = actionSelector->getSelectorDecl()->controlPlaneName();
117 const auto *defaultOverrideObj =
118 tblConfig->
getProperty(
"overriden_default_action"_cs,
false);
119 if (defaultOverrideObj !=
nullptr) {
120 const auto *defaultAction = defaultOverrideObj->checkedTo<
ActionCall>();
123 auto const *actionArgs = defaultAction->getArgs();
124 inja::json b = inja::json::array();
125 for (
const auto &actArg : *actionArgs) {
127 j[
"param"] = actArg.getActionParamName().c_str();
132 tblJson[
"default_override"] = a;
137 template <
class ProfileType>
139 inja::json &controlPlaneJson,
140 const std::map<cstring, cstring> &apAsMap) {
142 if (!actionProfiles.empty()) {
143 controlPlaneJson[
"action_profiles"] = inja::json::array();
145 for (
auto const &testObject : actionProfiles) {
146 const auto *
const actionProfile = testObject.second->checkedTo<ProfileType>();
147 const auto *actions = actionProfile->getActions();
149 j[
"profile"] = actionProfile->getProfileDecl()->controlPlaneName();
150 j[
"actions"] = inja::json::array();
151 for (
size_t idx = 0; idx < actions->size(); ++idx) {
152 const auto &action = actions->at(idx);
153 auto actionName = action.first;
154 auto actionArgs = action.second;
156 a[
"action_name"] = actionName;
157 a[
"action_idx"] = std::to_string(idx);
158 inja::json b = inja::json::array();
159 for (
const auto &actArg : actionArgs) {
161 c[
"param"] = actArg.getActionParamName().c_str();
162 c[
"value"] =
formatHexExpr(actArg.getEvaluatedValue()).c_str();
166 j[
"actions"].push_back(a);
169 if (apAsMap.find(actionProfile->getProfileDecl()->controlPlaneName()) !=
171 j[
"selector"] = apAsMap.at(actionProfile->getProfileDecl()->controlPlaneName());
173 controlPlaneJson[
"action_profiles"].push_back(j);
192 float currentCoverage) = 0;
200 size_t testIdx,
float currentCoverage);