1 | //===- llvm/unittest/XRay/FDRBlockVerifierTest.cpp --------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | #include "llvm/Testing/Support/Error.h" |
9 | #include "llvm/XRay/BlockIndexer.h" |
10 | #include "llvm/XRay/BlockVerifier.h" |
11 | #include "llvm/XRay/FDRLogBuilder.h" |
12 | #include "llvm/XRay/FDRRecords.h" |
13 | #include "gmock/gmock.h" |
14 | #include "gtest/gtest.h" |
15 | |
16 | namespace llvm { |
17 | namespace xray { |
18 | namespace { |
19 | |
20 | using ::testing::SizeIs; |
21 | |
22 | TEST(FDRBlockVerifierTest, ValidBlocksV3) { |
23 | auto Block0 = LogBuilder() |
24 | .add<BufferExtents>(A: 80) |
25 | .add<NewBufferRecord>(A: 1) |
26 | .add<WallclockRecord>(A: 1, A: 2) |
27 | .add<PIDRecord>(A: 1) |
28 | .add<NewCPUIDRecord>(A: 1, A: 2) |
29 | .add<FunctionRecord>(A: RecordTypes::ENTER, A: 1, A: 1) |
30 | .add<FunctionRecord>(A: RecordTypes::EXIT, A: 1, A: 100) |
31 | .consume(); |
32 | auto Block1 = LogBuilder() |
33 | .add<BufferExtents>(A: 80) |
34 | .add<NewBufferRecord>(A: 1) |
35 | .add<WallclockRecord>(A: 1, A: 2) |
36 | .add<PIDRecord>(A: 1) |
37 | .add<NewCPUIDRecord>(A: 1, A: 2) |
38 | .add<FunctionRecord>(A: RecordTypes::ENTER, A: 1, A: 1) |
39 | .add<FunctionRecord>(A: RecordTypes::EXIT, A: 1, A: 100) |
40 | .consume(); |
41 | auto Block2 = LogBuilder() |
42 | .add<BufferExtents>(A: 80) |
43 | .add<NewBufferRecord>(A: 2) |
44 | .add<WallclockRecord>(A: 1, A: 2) |
45 | .add<PIDRecord>(A: 1) |
46 | .add<NewCPUIDRecord>(A: 2, A: 2) |
47 | .add<FunctionRecord>(A: RecordTypes::ENTER, A: 1, A: 1) |
48 | .add<FunctionRecord>(A: RecordTypes::EXIT, A: 1, A: 100) |
49 | .consume(); |
50 | BlockIndexer::Index Index; |
51 | BlockIndexer Indexer(Index); |
52 | for (auto B : {std::ref(t&: Block0), std::ref(t&: Block1), std::ref(t&: Block2)}) { |
53 | for (auto &R : B.get()) |
54 | ASSERT_FALSE(errorToBool(R->apply(Indexer))); |
55 | ASSERT_FALSE(errorToBool(Indexer.flush())); |
56 | } |
57 | |
58 | BlockVerifier Verifier; |
59 | for (auto &ProcessThreadBlocks : Index) { |
60 | auto &Blocks = ProcessThreadBlocks.second; |
61 | for (auto &B : Blocks) { |
62 | for (auto *R : B.Records) |
63 | ASSERT_FALSE(errorToBool(R->apply(Verifier))); |
64 | ASSERT_FALSE(errorToBool(Verifier.verify())); |
65 | Verifier.reset(); |
66 | } |
67 | } |
68 | } |
69 | |
70 | TEST(FDRBlockVerifierTest, MissingPIDRecord) { |
71 | auto Block = LogBuilder() |
72 | .add<BufferExtents>(A: 20) |
73 | .add<NewBufferRecord>(A: 1) |
74 | .add<WallclockRecord>(A: 1, A: 2) |
75 | .add<NewCPUIDRecord>(A: 1, A: 2) |
76 | .add<FunctionRecord>(A: RecordTypes::ENTER, A: 1, A: 1) |
77 | .add<FunctionRecord>(A: RecordTypes::EXIT, A: 1, A: 100) |
78 | .consume(); |
79 | BlockVerifier Verifier; |
80 | for (auto &R : Block) |
81 | ASSERT_FALSE(errorToBool(R->apply(Verifier))); |
82 | ASSERT_FALSE(errorToBool(Verifier.verify())); |
83 | } |
84 | |
85 | TEST(FDRBlockVerifierTest, MissingBufferExtents) { |
86 | auto Block = LogBuilder() |
87 | .add<NewBufferRecord>(A: 1) |
88 | .add<WallclockRecord>(A: 1, A: 2) |
89 | .add<NewCPUIDRecord>(A: 1, A: 2) |
90 | .add<FunctionRecord>(A: RecordTypes::ENTER, A: 1, A: 1) |
91 | .add<FunctionRecord>(A: RecordTypes::EXIT, A: 1, A: 100) |
92 | .consume(); |
93 | BlockVerifier Verifier; |
94 | for (auto &R : Block) |
95 | ASSERT_FALSE(errorToBool(R->apply(Verifier))); |
96 | ASSERT_FALSE(errorToBool(Verifier.verify())); |
97 | } |
98 | |
99 | TEST(FDRBlockVerifierTest, IgnoreRecordsAfterEOB) { |
100 | auto Block = LogBuilder() |
101 | .add<NewBufferRecord>(A: 1) |
102 | .add<WallclockRecord>(A: 1, A: 2) |
103 | .add<NewCPUIDRecord>(A: 1, A: 2) |
104 | .add<EndBufferRecord>() |
105 | .add<FunctionRecord>(A: RecordTypes::ENTER, A: 1, A: 1) |
106 | .add<FunctionRecord>(A: RecordTypes::EXIT, A: 1, A: 100) |
107 | .consume(); |
108 | BlockVerifier Verifier; |
109 | for (auto &R : Block) |
110 | ASSERT_FALSE(errorToBool(R->apply(Verifier))); |
111 | ASSERT_FALSE(errorToBool(Verifier.verify())); |
112 | } |
113 | |
114 | TEST(FDRBlockVerifierTest, MalformedV2) { |
115 | auto Block = LogBuilder() |
116 | .add<NewBufferRecord>(A: 1) |
117 | .add<WallclockRecord>(A: 1, A: 2) |
118 | .add<NewCPUIDRecord>(A: 1, A: 2) |
119 | .add<FunctionRecord>(A: RecordTypes::ENTER, A: 1, A: 1) |
120 | .add<FunctionRecord>(A: RecordTypes::EXIT, A: 1, A: 100) |
121 | .add<NewBufferRecord>(A: 2) |
122 | .consume(); |
123 | BlockVerifier Verifier; |
124 | |
125 | ASSERT_THAT(Block, SizeIs(6u)); |
126 | EXPECT_THAT_ERROR(Block[0]->apply(Verifier), Succeeded()); |
127 | EXPECT_THAT_ERROR(Block[1]->apply(Verifier), Succeeded()); |
128 | EXPECT_THAT_ERROR(Block[2]->apply(Verifier), Succeeded()); |
129 | EXPECT_THAT_ERROR(Block[3]->apply(Verifier), Succeeded()); |
130 | EXPECT_THAT_ERROR(Block[4]->apply(Verifier), Succeeded()); |
131 | EXPECT_THAT_ERROR(Block[5]->apply(Verifier), Failed()); |
132 | } |
133 | |
134 | } // namespace |
135 | } // namespace xray |
136 | } // namespace llvm |
137 | |