1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
#include "ast/passes/collect_nodes.h"
#include "ast/context.h"
#include "gtest/gtest.h"
#include <functional>
#include <vector>
namespace bpftrace::test::collect_nodes {
using namespace bpftrace::ast;
template <typename T>
void test(const std::vector<std::reference_wrapper<T>> &expected,
const std::vector<std::reference_wrapper<T>> &actual)
{
ASSERT_EQ(expected.size(), actual.size());
for (size_t i = 0; i < expected.size(); i++) {
EXPECT_EQ(&expected[i].get(), &actual[i].get());
}
}
TEST(CollectNodes, direct)
{
ASTContext ctx;
auto &var = *ctx.make_node<Variable>("myvar", bpftrace::location{});
CollectNodes<Variable> visitor;
visitor.visit(var);
test({ var }, visitor.nodes());
}
TEST(CollectNodes, indirect)
{
ASTContext ctx;
auto &var = *ctx.make_node<Variable>("myvar", bpftrace::location{});
auto &unop = *ctx.make_node<Unop>(
&var, Operator::INCREMENT, false, bpftrace::location{});
CollectNodes<Variable> visitor;
visitor.visit(unop);
test({ var }, visitor.nodes());
}
TEST(CollectNodes, none)
{
ASTContext ctx;
auto &map = *ctx.make_node<Map>("myvar", bpftrace::location{});
auto &unop = *ctx.make_node<Unop>(
&map, Operator::INCREMENT, false, bpftrace::location{});
CollectNodes<Variable> visitor;
visitor.visit(unop);
test({}, visitor.nodes());
}
TEST(CollectNodes, multiple_runs)
{
ASTContext ctx;
auto &var1 = *ctx.make_node<Variable>("myvar1", bpftrace::location{});
auto &unop1 = *ctx.make_node<Unop>(
&var1, Operator::INCREMENT, false, bpftrace::location{});
auto &var2 = *ctx.make_node<Variable>("myvar2", bpftrace::location{});
auto &unop2 = *ctx.make_node<Unop>(
&var2, Operator::INCREMENT, false, bpftrace::location{});
CollectNodes<Variable> visitor;
visitor.visit(unop1);
visitor.visit(unop2);
test({ var1, var2 }, visitor.nodes());
}
TEST(CollectNodes, multiple_children)
{
ASTContext ctx;
auto &var1 = *ctx.make_node<Variable>("myvar1", bpftrace::location{});
auto &var2 = *ctx.make_node<Variable>("myvar2", bpftrace::location{});
auto &binop = *ctx.make_node<Binop>(
&var1, Operator::PLUS, &var2, bpftrace::location{});
CollectNodes<Variable> visitor;
visitor.visit(binop);
test({ var1, var2 }, visitor.nodes());
}
TEST(CollectNodes, predicate)
{
ASTContext ctx;
auto &var1 = *ctx.make_node<Variable>("myvar1", bpftrace::location{});
auto &var2 = *ctx.make_node<Variable>("myvar2", bpftrace::location{});
auto &binop = *ctx.make_node<Binop>(
&var1, Operator::PLUS, &var2, bpftrace::location{});
CollectNodes<Variable> visitor;
visitor.visit(binop, [](const auto &var) { return var.ident == "myvar2"; });
test({ var2 }, visitor.nodes());
}
TEST(CollectNodes, nested)
{
ASTContext ctx;
auto &var1 = *ctx.make_node<Variable>("myvar1", bpftrace::location{});
auto &var2 = *ctx.make_node<Variable>("myvar2", bpftrace::location{});
auto &var3 = *ctx.make_node<Variable>("myvar3", bpftrace::location{});
auto &binop1 = *ctx.make_node<Binop>(
&var1, Operator::PLUS, &var2, bpftrace::location{});
auto &binop2 = *ctx.make_node<Binop>(
&binop1, Operator::MINUS, &var3, bpftrace::location{});
CollectNodes<Binop> visitor;
visitor.visit(binop2,
[](const auto &binop) { return binop.op == Operator::PLUS; });
test({ binop1 }, visitor.nodes());
}
} // namespace bpftrace::test::collect_nodes
|