xref: /llvm-project/llvm/unittests/XRay/FDRBlockVerifierTest.cpp (revision 3b34c117db175ae6a1404f7c07857c4aa6fc1ae3)
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 
TEST(FDRBlockVerifierTest,ValidBlocksV3)22 TEST(FDRBlockVerifierTest, ValidBlocksV3) {
23   auto Block0 = LogBuilder()
24                     .add<BufferExtents>(80)
25                     .add<NewBufferRecord>(1)
26                     .add<WallclockRecord>(1, 2)
27                     .add<PIDRecord>(1)
28                     .add<NewCPUIDRecord>(1, 2)
29                     .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
30                     .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
31                     .consume();
32   auto Block1 = LogBuilder()
33                     .add<BufferExtents>(80)
34                     .add<NewBufferRecord>(1)
35                     .add<WallclockRecord>(1, 2)
36                     .add<PIDRecord>(1)
37                     .add<NewCPUIDRecord>(1, 2)
38                     .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
39                     .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
40                     .consume();
41   auto Block2 = LogBuilder()
42                     .add<BufferExtents>(80)
43                     .add<NewBufferRecord>(2)
44                     .add<WallclockRecord>(1, 2)
45                     .add<PIDRecord>(1)
46                     .add<NewCPUIDRecord>(2, 2)
47                     .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
48                     .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
49                     .consume();
50   BlockIndexer::Index Index;
51   BlockIndexer Indexer(Index);
52   for (auto B : {std::ref(Block0), std::ref(Block1), std::ref(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 
TEST(FDRBlockVerifierTest,MissingPIDRecord)70 TEST(FDRBlockVerifierTest, MissingPIDRecord) {
71   auto Block = LogBuilder()
72                    .add<BufferExtents>(20)
73                    .add<NewBufferRecord>(1)
74                    .add<WallclockRecord>(1, 2)
75                    .add<NewCPUIDRecord>(1, 2)
76                    .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
77                    .add<FunctionRecord>(RecordTypes::EXIT, 1, 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 
TEST(FDRBlockVerifierTest,MissingBufferExtents)85 TEST(FDRBlockVerifierTest, MissingBufferExtents) {
86   auto Block = LogBuilder()
87                    .add<NewBufferRecord>(1)
88                    .add<WallclockRecord>(1, 2)
89                    .add<NewCPUIDRecord>(1, 2)
90                    .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
91                    .add<FunctionRecord>(RecordTypes::EXIT, 1, 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 
TEST(FDRBlockVerifierTest,IgnoreRecordsAfterEOB)99 TEST(FDRBlockVerifierTest, IgnoreRecordsAfterEOB) {
100   auto Block = LogBuilder()
101                    .add<NewBufferRecord>(1)
102                    .add<WallclockRecord>(1, 2)
103                    .add<NewCPUIDRecord>(1, 2)
104                    .add<EndBufferRecord>()
105                    .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
106                    .add<FunctionRecord>(RecordTypes::EXIT, 1, 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 
TEST(FDRBlockVerifierTest,MalformedV2)114 TEST(FDRBlockVerifierTest, MalformedV2) {
115   auto Block = LogBuilder()
116                    .add<NewBufferRecord>(1)
117                    .add<WallclockRecord>(1, 2)
118                    .add<NewCPUIDRecord>(1, 2)
119                    .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
120                    .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
121                    .add<NewBufferRecord>(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