P4C
The P4 Compiler
Loading...
Searching...
No Matches
bf_gtest_helpers.h
1
19#ifndef BF_GTEST_HELPERS_H_
20#define BF_GTEST_HELPERS_H_
21
26#include <initializer_list>
27#include <iosfwd>
28#include <regex>
29#include <string>
30#include <vector>
31
32#include <boost/operators.hpp>
33
34#include "lib/compile_context.h"
35
36// Forward declarations.
37namespace P4 {
38class Visitor;
39struct Visitor_Context;
40namespace IR {
41class P4Program;
42} // namespace IR
43namespace IR {
44namespace BFN {
45class Pipe;
46} // namespace BFN
47} // namespace IR
48} // namespace P4
49namespace BFN {
50class Backend;
51}
52class MauAsmOutput;
53
54namespace P4::Test {
55
56namespace Match {
57
63std::string trimWhiteSpace(std::string str);
64
66std::string trimAnnotations(const std::string &str);
67
69enum Flag { Raw = 0, TrimWhiteSpace = 1, TrimAnnotations = 2 };
71inline Flag operator|(Flag a, Flag b) {
72 return static_cast<Flag>(static_cast<int>(a) | static_cast<int>(b));
73}
74
93std::string convert_to_regex(const std::string &expr);
94
101constexpr size_t failed = std::string::npos;
102size_t match_basic(const std::string &expr, const std::string &str, size_t pos = 0,
103 size_t n_pos = std::string::npos);
104
109typedef std::vector<std::string> CheckList;
110
112struct Result : boost::equality_comparable<Result> {
113 bool success;
114 size_t pos;
116 size_t count;
118 std::vector<std::string> matches;
119 Result(bool success, size_t pos, size_t count) : success(success), pos(pos), count(count) {}
120 Result(bool success, size_t pos, size_t count, std::smatch match)
122 for (std::size_t n = 0; n < match.size(); ++n) matches.push_back(match[n]);
123 }
124 friend bool operator==(const Result &l, const Result &r) {
125 return l.success == r.success && l.pos == r.pos && l.count == r.count;
126 }
127};
128
134Result match(const CheckList &exprs, const std::string &str, size_t pos = 0,
135 size_t n_pos = std::string::npos, Flag flag = Raw);
136
137// 'ends' can be any two differing characters e.g. "AZ".
138inline const std::string BraceEnds() { return "{}"; }
139inline const std::string ParenEnds() { return "()"; }
140inline const std::string SquareEnds() { return "[]"; }
141inline const std::string AngleEnds() { return "<>"; }
142
144size_t find_next_end(const std::string &str, size_t pos, const std::string &ends);
145
146// 'find_next_block' finds the opening & closing ends, where 'pos' is before the opening character.
147std::pair<size_t, size_t> find_next_block(const std::string &str, size_t pos,
148 const std::string &ends);
151std::string get_ends(char opening);
152
153} // namespace Match
154
155class TestCode {
156 // AutoCompileContext adds to the stack a new compilation context for the test to run in.
157 AutoCompileContext context;
158 const IR::P4Program *program = nullptr; // Used by frontend and midend passes.
159 const IR::BFN::Pipe *pipe = nullptr; // Used by backend passes.
160 BFN::Backend *backend = nullptr; // Used by extract_asm()
161 mutable MauAsmOutput *mauasm = nullptr; // lazy initialised & used by extract_asm().
162
163 Match::Flag flag = Match::TrimWhiteSpace; // N.B. common to match() & extract_code().
164 std::regex marker; // Optional search string for the block we are interested in.
165 std::string ends; // How our optional block starts and ends.
166
167 std::string phv_log_file = {}; // path to phv log file
168
169 public:
170 const IR::P4Program *get_program() { return program; }
172 static std::string any_to_brace() { return "`([^\\{]*\\{)`"; } // viz ".*{"
173 static std::string empty_state() { return "state start {transition accept;}"; }
174 static std::string empty_appy() { return "apply {}"; }
175
181 static std::string min_control_shell(); // See cpp file for the code.
182 static std::string min_control_shell_marker() { return "control testingress" + any_to_brace(); }
183
191 static std::string tofino_shell(); // See cpp file for the code.
192 static std::string tofino_shell_parser_marker() {
193 return "parser ingress_parser" + any_to_brace();
194 }
195 static std::string tofino_shell_control_marker() {
196 return "control ingress_control" + any_to_brace();
197 }
198 static std::string tofino_shell_deparser_marker() {
199 return "control ingress_deparser" + any_to_brace();
200 }
201 // TODO would a smaller test program (as used in test_bf_gtest_helpers.cpp) be of general value?
202
210 enum class Hdr {
211 None, // You need to provide the 'package' - see min_control_shell().
212 CoreP4, // The core.p4 package.
213 TofinoMin, // For building an empty tofino_shell() - add only what you need.
214 Tofino1arch,
215 Tofino2arch, // The regular header files
216 V1model_2018,
217 V1model_2020
218 }; // The regular header files.
219
235 TestCode(Hdr header,
236 std::string code,
237 const std::initializer_list<std::string> &insertion = {},
238 const std::string &blockMarker = "",
240 const std::initializer_list<std::string> &options = {});
241
251 static TestCode TestControlBlock(const std::string &defines, const std::string &block,
252 Hdr header = Hdr::None) {
253 std::initializer_list<std::string> insert = {defines, block};
254 return TestCode(header, min_control_shell(), insert, min_control_shell_marker());
255 }
256
258 void flags(Match::Flag f) { flag = f; }
259
260 void set_phv_log_file(std::string path) { phv_log_file = path; }
261
263 bool apply_pass(Visitor &pass, const Visitor_Context *context = nullptr);
264 bool apply_pass(Visitor *pass, const Visitor_Context *context = nullptr) {
265 return apply_pass(*pass, context);
266 }
276 bool apply_pass(Pass pass);
277
283 bool CreateBlockThreadLocalInstances() {
285 }
286
289 enum class CodeBlock {
290 P4Code, // P4Code combines with `blockMarker`.
291 PhvAsm,
292 MauAsm, // Ingress & Egress.
293 HdrAsm, // Ingress & Egress.
294 ParserIAsm,
295 DeparserIAsm, // Ingress.
296 ParserEAsm,
297 DeparserEAsm
298 }; // Egress.
299
301 Match::Result match(CodeBlock blk_type, const Match::CheckList &exprs) const;
303 Match::Result match(const Match::CheckList &exprs) const {
304 return match(CodeBlock::P4Code, exprs);
305 }
306
309 std::string extract_code(CodeBlock blk_type, size_t pos = 0) const;
312 std::string extract_code(size_t pos = 0) const { return extract_code(CodeBlock::P4Code, pos); }
313
322 std::string get_field_container(const std::string &field, const std::string &str,
323 int idx = 0) const;
324
325 friend std::ostream &operator<<(std::ostream &out, const TestCode &tc) {
326 return out << tc.extract_code(CodeBlock::P4Code, 0);
327 }
328
329 private:
330 std::string extract_p4() const;
331 std::string extract_asm(CodeBlock blk_type) const;
332};
333
334} // namespace P4::Test
335
336#endif /* BF_GTEST_HELPERS_H_ */
Definition tofino/bf-p4c/backend.h:46
Definition mau/asm_output.h:85
Definition bf_gtest_helpers.h:155
TestCode(Hdr header, std::string code, const std::initializer_list< std::string > &insertion={}, const std::string &blockMarker="", const std::initializer_list< std::string > &options={})
Definition bf_gtest_helpers.cpp:426
bool CreateBackend()
Runs all the necessary passes to create a backend ready for testing.
Definition bf_gtest_helpers.h:279
CodeBlock
Definition bf_gtest_helpers.h:289
static std::string tofino_shell()
Definition bf_gtest_helpers.cpp:513
static std::string any_to_brace()
Useful strings.
Definition bf_gtest_helpers.h:172
static std::string min_control_shell()
Definition bf_gtest_helpers.cpp:503
std::string get_field_container(const std::string &field, const std::string &str, int idx=0) const
Definition bf_gtest_helpers.cpp:707
Hdr
Definition bf_gtest_helpers.h:210
bool apply_pass(Visitor &pass, const Visitor_Context *context=nullptr)
Runs the pass over either the pipe (if created) else the program.
Definition bf_gtest_helpers.cpp:549
Match::Result match(const Match::CheckList &exprs) const
Calls Match::match() on the P4 code block specified by blockMarker.
Definition bf_gtest_helpers.h:303
std::string extract_code(CodeBlock blk_type, size_t pos=0) const
Definition bf_gtest_helpers.cpp:698
Pass
Runs a preconstructed pass over the pipe or program.
Definition bf_gtest_helpers.h:268
@ FullMidend
Remove the pipe and run over the program.
@ FullBackend
Run over the pipe, creates asm CodeBlocks.
@ ConverterToBackend
Run over the program and create the pipe.
@ FullFrontend
Remove the pipe and run over the program.
@ ThreadLocalInstances
Run over the pipe.
static TestCode TestControlBlock(const std::string &defines, const std::string &block, Hdr header=Hdr::None)
Definition bf_gtest_helpers.h:251
Match::Result match(CodeBlock blk_type, const Match::CheckList &exprs) const
Calls Match::match() on the code block specified by CodeBlock.
Definition bf_gtest_helpers.cpp:629
void flags(Match::Flag f)
Sets the flags to be used by other member functions.
Definition bf_gtest_helpers.h:258
std::string extract_code(size_t pos=0) const
Definition bf_gtest_helpers.h:312
Definition visitor.h:75
Definition phv_logging.h:115
The namespace encapsulating Barefoot/Intel-specific stuff.
Definition add_t2na_meta.cpp:21
The namespace encapsulating IR node classes.
Definition json.h:34
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
Definition compile_context.h:77
'Result' is used to report how a match has proceeded.
Definition bf_gtest_helpers.h:112
size_t count
Definition bf_gtest_helpers.h:116
std::vector< std::string > matches
Match strings.
Definition bf_gtest_helpers.h:118
size_t pos
Definition bf_gtest_helpers.h:114
bool success
true if the 'CheckList' was completed.
Definition bf_gtest_helpers.h:113
Definition visitor.h:47
Definition common/field_defuse.cpp:590
Result contains either an error or all instructions for an action.
Definition action_constraint_solver.h:140