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 {
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),
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;
96 const auto *asObject = tblConfig->
getProperty(
"action_selector"_cs,
false);
97 if (asObject !=
nullptr) {
98 const auto *actionSelector = asObject->checkedTo<SelectorType>();
99 apAsMap[actionProfile->getProfileDecl()->controlPlaneName()] =
100 actionSelector->getSelectorDecl()->controlPlaneName();
101 tblJson[
"has_as"] =
true;
109 const auto *defaultOverrideObj =
110 tblConfig->
getProperty(
"overriden_default_action"_cs,
false);
111 if (defaultOverrideObj !=
nullptr) {
112 const auto *defaultAction = defaultOverrideObj->checkedTo<
ActionCall>();
115 auto const *actionArgs = defaultAction->getArgs();
116 inja::json b = inja::json::array();
117 for (
const auto &actArg : *actionArgs) {
119 j[
"param"] = actArg.getActionParamName().c_str();
124 tblJson[
"default_override"] = a;
129 template <
class ProfileType>
131 inja::json &controlPlaneJson,
132 const std::map<cstring, cstring> &apAsMap) {
134 if (!actionProfiles.empty()) {
135 controlPlaneJson[
"action_profiles"] = inja::json::array();
137 for (
auto const &testObject : actionProfiles) {
138 const auto *
const actionProfile = testObject.second->checkedTo<ProfileType>();
139 const auto *actions = actionProfile->getActions();
141 j[
"profile"] = actionProfile->getProfileDecl()->controlPlaneName();
142 j[
"actions"] = inja::json::array();
143 for (
size_t idx = 0; idx < actions->size(); ++idx) {
144 const auto &action = actions->at(idx);
145 auto actionName = action.first;
146 auto actionArgs = action.second;
148 a[
"action_name"] = actionName;
149 a[
"action_idx"] = std::to_string(idx);
150 inja::json b = inja::json::array();
151 for (
const auto &actArg : actionArgs) {
153 c[
"param"] = actArg.getActionParamName().c_str();
154 c[
"value"] =
formatHexExpr(actArg.getEvaluatedValue()).c_str();
158 j[
"actions"].push_back(a);
161 if (apAsMap.find(actionProfile->getProfileDecl()->controlPlaneName()) !=
163 j[
"selector"] = apAsMap.at(actionProfile->getProfileDecl()->controlPlaneName());
165 controlPlaneJson[
"action_profiles"].push_back(j);
184 float currentCoverage) = 0;
192 size_t testIdx,
float currentCoverage);