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 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
#include "ast/pass_manager.h"
#include "ast/location.h"
#include "util/result.h"
#include "gtest/gtest.h"
using bpftrace::ast::Pass;
using bpftrace::ast::PassManager;
namespace bpftrace::test::passes {
class Error1 : public ErrorInfo<Error1> {
public:
static char ID;
void log(llvm::raw_ostream & /*OS*/) const override
{
}
};
class Error2 : public ErrorInfo<Error2> {
public:
static char ID;
void log(llvm::raw_ostream & /*OS*/) const override
{
}
};
char Error1::ID;
char Error2::ID;
Pass CreateTest1Pass(bool error = false)
{
return Pass::create("test1", [error]() -> Result<> {
if (error) {
return make_error<Error1>();
}
return OK();
});
}
class Test2Output : public ast::State<"test2output"> {};
Pass CreateTest2Pass(bool error = false)
{
return Pass::create("test2", [error]() -> Result<Test2Output> {
if (error) {
return make_error<Error2>();
}
return Test2Output();
});
}
class Test3Output : public ast::State<"test3output"> {};
Pass CreateTest3Pass()
{
return Pass::create("test3", [](Test2Output &) -> Result<Test3Output> {
return Test3Output();
});
}
TEST(PassManager, noop_pass)
{
PassManager pm;
pm.add(Pass::create("void", []() {}));
EXPECT_TRUE(bool(pm.run()));
}
TEST(PassManager, single_pass)
{
PassManager pm;
pm.add(CreateTest1Pass());
EXPECT_TRUE(bool(pm.run()));
}
TEST(PassManager, single_pass_with_output)
{
PassManager pm;
pm.add(CreateTest2Pass());
auto out = pm.run();
EXPECT_TRUE(bool(out));
out->get<Test2Output>(); // Should work.
EXPECT_DEATH(out->get<Test3Output>(), ""); // Should die.
}
TEST(PassManager, single_pass_with_error)
{
PassManager pm;
pm.add(CreateTest1Pass(true));
auto out = pm.run();
EXPECT_FALSE(bool(out));
EXPECT_TRUE(bool(handleErrors(std::move(out), [](const Error1 &) {})));
}
TEST(PassManager, multiple_passes)
{
PassManager pm;
pm.add(CreateTest1Pass());
pm.add(CreateTest1Pass());
EXPECT_TRUE(bool(pm.run()));
}
TEST(PassManager, multiple_passes_with_dependencies)
{
PassManager pm;
pm.add(CreateTest2Pass());
pm.add(CreateTest3Pass());
EXPECT_TRUE(bool(pm.run()));
}
TEST(PassManager, multiple_passes_with_bad_dependencies)
{
PassManager pm;
pm.add(CreateTest1Pass());
EXPECT_DEATH(pm.add(CreateTest3Pass()), ""); // Should assert fail.
}
TEST(PassManager, multiple_passes_with_partial_success)
{
PassManager pm;
pm.add(CreateTest1Pass());
pm.add(CreateTest2Pass(true));
auto out = pm.run();
EXPECT_FALSE(bool(out));
EXPECT_TRUE(bool(handleErrors(std::move(out), [](const Error2 &) {})));
}
TEST(PassManager, multiple_passes_complex)
{
PassManager pm;
pm.add(CreateTest1Pass());
pm.add(CreateTest2Pass());
pm.add(CreateTest1Pass());
pm.add(CreateTest3Pass());
EXPECT_TRUE(bool(pm.run()));
}
} // namespace bpftrace::test::passes
|