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;
65 inja::json traceList = inja::json::array();
66 const auto *traces = testSpec->
getTraces();
67 if (traces !=
nullptr) {
68 for (
const auto &trace : *traces) {
71 traceList.push_back(ss.str());
79 template <
class ProfileType,
class SelectorType>
82 const auto *apObject = tblConfig->
getProperty(
"action_profile"_cs,
false);
83 if (apObject !=
nullptr) {
84 const auto *actionProfile = apObject->checkedTo<ProfileType>();
85 tblJson[
"has_ap"] =
true;
89 const auto *asObject = tblConfig->
getProperty(
"action_selector"_cs,
false);
90 if (asObject !=
nullptr) {
91 const auto *actionSelector = asObject->checkedTo<SelectorType>();
92 apAsMap[actionProfile->getProfileDecl()->controlPlaneName()] =
93 actionSelector->getSelectorDecl()->controlPlaneName();
94 tblJson[
"has_as"] =
true;
102 const auto *defaultOverrideObj =
103 tblConfig->
getProperty(
"overriden_default_action"_cs,
false);
104 if (defaultOverrideObj !=
nullptr) {
105 const auto *defaultAction = defaultOverrideObj->checkedTo<
ActionCall>();
108 auto const *actionArgs = defaultAction->getArgs();
109 inja::json b = inja::json::array();
110 for (
const auto &actArg : *actionArgs) {
112 j[
"param"] = actArg.getActionParamName().c_str();
117 tblJson[
"default_override"] = a;
122 template <
class ProfileType>
124 inja::json &controlPlaneJson,
125 const std::map<cstring, cstring> &apAsMap) {
127 if (!actionProfiles.empty()) {
128 controlPlaneJson[
"action_profiles"] = inja::json::array();
130 for (
auto const &testObject : actionProfiles) {
131 const auto *
const actionProfile = testObject.second->checkedTo<ProfileType>();
132 const auto *actions = actionProfile->getActions();
134 j[
"profile"] = actionProfile->getProfileDecl()->controlPlaneName();
135 j[
"actions"] = inja::json::array();
136 for (
size_t idx = 0; idx < actions->size(); ++idx) {
137 const auto &action = actions->at(idx);
138 auto actionName = action.first;
139 auto actionArgs = action.second;
141 a[
"action_name"] = actionName;
142 a[
"action_idx"] = std::to_string(idx);
143 inja::json b = inja::json::array();
144 for (
const auto &actArg : actionArgs) {
146 c[
"param"] = actArg.getActionParamName().c_str();
147 c[
"value"] =
formatHexExpr(actArg.getEvaluatedValue()).c_str();
151 j[
"actions"].push_back(a);
154 if (apAsMap.find(actionProfile->getProfileDecl()->controlPlaneName()) !=
156 j[
"selector"] = apAsMap.at(actionProfile->getProfileDecl()->controlPlaneName());
158 controlPlaneJson[
"action_profiles"].push_back(j);
177 float currentCoverage) = 0;
185 size_t testIdx,
float currentCoverage);