1#ifndef BACKENDS_P4TOOLS_MODULES_TESTGEN_TEST_SMALL_STEP_UTIL_H_
2#define BACKENDS_P4TOOLS_MODULES_TESTGEN_TEST_SMALL_STEP_UTIL_H_
4#include <gtest/gtest.h>
13#include "backends/p4tools/common/compiler/compiler_target.h"
14#include "backends/p4tools/common/core/z3_solver.h"
15#include "backends/p4tools/common/lib/namespace_context.h"
16#include "backends/p4tools/common/lib/symbolic_env.h"
17#include "ir/declaration.h"
18#include "ir/indexed_vector.h"
21#include "lib/cstring.h"
22#include "lib/enumerator.h"
24#include "backends/p4tools/modules/testgen/core/small_step/small_step.h"
25#include "backends/p4tools/modules/testgen/core/target.h"
26#include "backends/p4tools/modules/testgen/lib/continuation.h"
27#include "backends/p4tools/modules/testgen/lib/execution_state.h"
28#include "backends/p4tools/modules/testgen/test/gtest_utils.h"
32using Body = P4Tools::P4Testgen::Continuation::Body;
33using Continuation = P4Tools::P4Testgen::Continuation;
34using ExecutionState = P4Tools::P4Testgen::ExecutionState;
35using NamespaceContext = P4Tools::NamespaceContext;
36using Return = P4Tools::P4Testgen::Continuation::Return;
37using SmallStepEvaluator = P4Tools::P4Testgen::SmallStepEvaluator;
44 static ExecutionState
mkState(Body body) {
return ExecutionState(std::move(body)); }
47namespace SmallStepUtil {
53std::optional<const P4ToolsTestCase> createSmallStepExprTest(
const std::string &,
58const T *extractExpr(
const IR::P4Program &program) {
60 auto *decl = program.getDeclsByName(
"mau"_cs)->single();
64 const auto *control = decl->checkedTo<IR::P4Control>();
65 if (control->body->components.size() != 1) {
70 const auto *mcStmt = control->body->components[0]->to<IR::MethodCallStatement>();
76 const auto *mcArgs = mcStmt->methodCall->arguments;
77 if (mcArgs->size() != 1) {
80 return (*mcArgs)[0]->expression->to<T>();
85void stepAndExamineValue(
const T *value,
const P4Tools::CompilerResult &compilerResult) {
88 ASSERT_TRUE(progInfo);
92 Body bodyBase({Return(v->param)});
93 Continuation continuationBase(v, bodyBase);
98 auto &testState = esBase.clone();
99 Body body({Return(value)});
100 testState.replaceBody(body);
101 testState.pushContinuation(
103 SmallStepEvaluator eval(solver, *progInfo);
104 auto *successors = eval.step(testState);
105 ASSERT_EQ(successors->size(), 1u);
108 const auto branch = (*successors)[0];
109 const auto *constraint = branch.constraint;
110 auto executionState = branch.nextState;
111 ASSERT_TRUE(constraint->checkedTo<IR::BoolLiteral>()->value);
113 ASSERT_TRUE(executionState.get().getSymbolicEnv().getInternalMap().empty());
116 Body finalBody = executionState.get().getBody();
117 ASSERT_EQ(finalBody, Body({Return(value)}));
120 ASSERT_EQ(executionState.get().getStack().empty(),
true);
128void stepAndExamineOp(
129 const T *op,
const IR::Expression *subexpr,
const P4Tools::CompilerResult &compilerResult,
130 std::function<
const IR::Expression *(
const IR::PathExpression *)> rebuildNode) {
133 ASSERT_TRUE(progInfo);
137 Body body({Return(op)});
139 SmallStepEvaluator eval(solver, *progInfo);
140 auto *successors = eval.step(es);
141 ASSERT_EQ(successors->size(), 1U);
144 const auto branch = (*successors)[0];
145 const auto *constraint = branch.constraint;
146 auto executionState = branch.nextState;
147 ASSERT_TRUE(constraint->checkedTo<IR::BoolLiteral>()->value);
149 ASSERT_TRUE(executionState.get().getSymbolicEnv().getInternalMap().empty());
152 Body finalBody = executionState.get().getBody();
153 ASSERT_EQ(finalBody, Body({Return(subexpr)}));
156 ASSERT_EQ(executionState.get().getStack().size(), 1u);
157 const auto stackFrame = executionState.get().getStack().top();
158 ASSERT_TRUE(stackFrame.get().getExceptionHandlers().empty());
162 Continuation pushedContinuation = stackFrame.get().getContinuation();
163 ASSERT_TRUE(pushedContinuation.parameterOpt);
164 Body pushedBody = pushedContinuation.body;
165 ASSERT_EQ(pushedBody, Body({Return(rebuildNode(*pushedContinuation.parameterOpt))}));
static const NamespaceContext * Empty
Represents the empty namespace context.
Definition namespace_context.h:33
Definition modules/testgen/test/small-step/util.h:41
static ExecutionState mkState(Body body)
Creates an execution state out of a continuation body.
Definition modules/testgen/test/small-step/util.h:44