1#ifndef BACKENDS_P4TOOLS_MODULES_TESTGEN_LIB_TEST_FRAMEWORK_H_
2#define BACKENDS_P4TOOLS_MODULES_TESTGEN_LIB_TEST_FRAMEWORK_H_
13#include <inja/inja.hpp>
15#include "backends/p4tools/common/lib/format_int.h"
16#include "backends/p4tools/common/lib/trace_event.h"
17#include "lib/castable.h"
18#include "lib/cstring.h"
20#include "backends/p4tools/modules/testgen/lib/test_backend_configuration.h"
21#include "backends/p4tools/modules/testgen/lib/test_object.h"
22#include "backends/p4tools/modules/testgen/lib/test_spec.h"
24namespace P4::P4Tools::P4Testgen {
26using namespace P4::literals;
33using AbstractTestReferenceOrError = std::optional<AbstractTestReference>;
34using AbstractTestList = std::vector<AbstractTestReference>;
38template <
class ConcreteTest,
39 typename = std::enable_if_t<std::is_base_of_v<AbstractTest, ConcreteTest>>>
40std::vector<const ConcreteTest *> convertAbstractTestsToConcreteTests(
41 const P4Tools::P4Testgen::AbstractTestList &testList) {
42 std::vector<const ConcreteTest *> result;
43 std::transform(testList.begin(), testList.end(), std::back_inserter(result),
44 [](AbstractTestReference test) { return test->checkedTo<ConcreteTest>(); });
50using OptionalFilePath = std::optional<std::filesystem::path>;
57 std::reference_wrapper<const TestBackendConfiguration> testBackendConfiguration;
67 inja::json traceList = inja::json::array();
68 const auto *traces = testSpec->
getTraces();
69 if (traces !=
nullptr) {
70 for (
const auto &trace : *traces) {
73 std::string traceStr = ss.str();
75 traceStr.erase(std::remove(traceStr.begin(), traceStr.end(),
'\n'),
78 traceList.push_back(traceStr);
86 template <
class ProfileType,
class SelectorType>
89 const auto *apObject = tblConfig->
getProperty(
"action_profile"_cs,
false);
90 if (apObject !=
nullptr) {
91 const auto *actionProfile = apObject->checkedTo<ProfileType>();
92 tblJson[
"has_ap"] =
true;
93 tblJson[
"action_profile"] = actionProfile->getProfileDecl()->controlPlaneName();
97 const auto *asObject = tblConfig->
getProperty(
"action_selector"_cs,
false);
98 if (asObject !=
nullptr) {
99 const auto *actionSelector = asObject->checkedTo<SelectorType>();
100 apAsMap[actionProfile->getProfileDecl()->controlPlaneName()] =
101 actionSelector->getSelectorDecl()->controlPlaneName();
102 tblJson[
"has_as"] =
true;
103 tblJson[
"action_selector"] = actionSelector->getSelectorDecl()->controlPlaneName();
111 const auto *defaultOverrideObj =
112 tblConfig->
getProperty(
"overriden_default_action"_cs,
false);
113 if (defaultOverrideObj !=
nullptr) {
114 const auto *defaultAction = defaultOverrideObj->checkedTo<
ActionCall>();
117 auto const *actionArgs = defaultAction->getArgs();
118 inja::json b = inja::json::array();
119 for (
const auto &actArg : *actionArgs) {
121 j[
"param"] = actArg.getActionParamName().c_str();
126 tblJson[
"default_override"] = a;
131 template <
class ProfileType>
133 inja::json &controlPlaneJson,
134 const std::map<cstring, cstring> &apAsMap) {
136 if (!actionProfiles.empty()) {
137 controlPlaneJson[
"action_profiles"] = inja::json::array();
139 for (
auto const &testObject : actionProfiles) {
140 const auto *
const actionProfile = testObject.second->checkedTo<ProfileType>();
141 const auto *actions = actionProfile->getActions();
143 j[
"profile"] = actionProfile->getProfileDecl()->controlPlaneName();
144 j[
"actions"] = inja::json::array();
145 for (
size_t idx = 0; idx < actions->size(); ++idx) {
146 const auto &action = actions->at(idx);
147 auto actionName = action.first;
148 auto actionArgs = action.second;
150 a[
"action_name"] = actionName;
151 a[
"action_idx"] = std::to_string(idx);
152 inja::json b = inja::json::array();
153 for (
const auto &actArg : actionArgs) {
155 c[
"param"] = actArg.getActionParamName().c_str();
156 c[
"value"] =
formatHexExpr(actArg.getEvaluatedValue()).c_str();
160 j[
"actions"].push_back(a);
163 if (apAsMap.find(actionProfile->getProfileDecl()->controlPlaneName()) !=
165 j[
"selector"] = apAsMap.at(actionProfile->getProfileDecl()->controlPlaneName());
167 controlPlaneJson[
"action_profiles"].push_back(j);
186 float currentCoverage) = 0;
194 size_t testIdx,
float currentCoverage);