File: pass_manager.cpp

package info (click to toggle)
bpftrace 0.24.1-1.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,496 kB
  • sloc: cpp: 60,982; ansic: 10,952; python: 953; yacc: 665; sh: 536; lex: 295; makefile: 22
file content (137 lines) | stat: -rw-r--r-- 2,874 bytes parent folder | download
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