1 //===- FDRRecords.cpp - Unit Tests for XRay FDR Record Loading ------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
9 #include "gmock/gmock.h"
10 #include "gtest/gtest.h"
12 #include "llvm/XRay/BlockIndexer.h"
13 #include "llvm/XRay/BlockPrinter.h"
14 #include "llvm/XRay/BlockVerifier.h"
15 #include "llvm/XRay/FDRLogBuilder.h"
16 #include "llvm/XRay/FDRRecords.h"
17 #include "llvm/XRay/RecordPrinter.h"
26 TEST(XRayFDRTest
, BuilderAndBlockIndexer
) {
27 // We recreate a single block of valid records, then ensure that we find all
28 // of them belonging in the same index. We do this for three blocks, and
29 // ensure we find the same records in the blocks we deduce.
30 auto Block0
= LogBuilder()
31 .add
<BufferExtents
>(100)
32 .add
<NewBufferRecord
>(1)
33 .add
<WallclockRecord
>(1, 1)
35 .add
<FunctionRecord
>(RecordTypes::ENTER
, 1, 1)
36 .add
<FunctionRecord
>(RecordTypes::EXIT
, 1, 100)
38 auto Block1
= LogBuilder()
39 .add
<BufferExtents
>(100)
40 .add
<NewBufferRecord
>(1)
41 .add
<WallclockRecord
>(1, 2)
43 .add
<FunctionRecord
>(RecordTypes::ENTER
, 1, 1)
44 .add
<FunctionRecord
>(RecordTypes::EXIT
, 1, 100)
46 auto Block2
= LogBuilder()
47 .add
<BufferExtents
>(100)
48 .add
<NewBufferRecord
>(2)
49 .add
<WallclockRecord
>(1, 3)
51 .add
<FunctionRecord
>(RecordTypes::ENTER
, 1, 1)
52 .add
<FunctionRecord
>(RecordTypes::EXIT
, 1, 100)
54 BlockIndexer::Index Index
;
55 BlockIndexer
Indexer(Index
);
56 for (auto B
: {std::ref(Block0
), std::ref(Block1
), std::ref(Block2
)}) {
57 for (auto &R
: B
.get())
58 ASSERT_FALSE(errorToBool(R
->apply(Indexer
)));
59 ASSERT_FALSE(errorToBool(Indexer
.flush()));
62 // We have two threads worth of blocks.
63 ASSERT_THAT(Index
.size(), Eq(2u));
64 auto T1Blocks
= Index
.find({1, 1});
65 ASSERT_THAT(T1Blocks
, Not(Eq(Index
.end())));
66 ASSERT_THAT(T1Blocks
->second
.size(), Eq(2u));
67 auto T2Blocks
= Index
.find({1, 2});
68 ASSERT_THAT(T2Blocks
, Not(Eq(Index
.end())));
69 ASSERT_THAT(T2Blocks
->second
.size(), Eq(1u));
72 TEST(XRayFDRTest
, BuilderAndBlockVerifier
) {
73 auto Block
= LogBuilder()
74 .add
<BufferExtents
>(48)
75 .add
<NewBufferRecord
>(1)
76 .add
<WallclockRecord
>(1, 1)
78 .add
<NewCPUIDRecord
>(1, 2)
80 BlockVerifier Verifier
;
82 ASSERT_FALSE(errorToBool(R
->apply(Verifier
)));
83 ASSERT_FALSE(errorToBool(Verifier
.verify()));
86 TEST(XRayFDRTest
, IndexAndVerifyBlocks
) {
87 auto Block0
= LogBuilder()
88 .add
<BufferExtents
>(64)
89 .add
<NewBufferRecord
>(1)
90 .add
<WallclockRecord
>(1, 1)
92 .add
<NewCPUIDRecord
>(1, 2)
93 .add
<FunctionRecord
>(RecordTypes::ENTER
, 1, 1)
94 .add
<FunctionRecord
>(RecordTypes::EXIT
, 1, 100)
96 auto Block1
= LogBuilder()
97 .add
<BufferExtents
>(64)
98 .add
<NewBufferRecord
>(1)
99 .add
<WallclockRecord
>(1, 1)
101 .add
<NewCPUIDRecord
>(1, 2)
102 .add
<FunctionRecord
>(RecordTypes::ENTER
, 1, 1)
103 .add
<FunctionRecord
>(RecordTypes::EXIT
, 1, 100)
105 auto Block2
= LogBuilder()
106 .add
<BufferExtents
>(64)
107 .add
<NewBufferRecord
>(1)
108 .add
<WallclockRecord
>(1, 1)
110 .add
<NewCPUIDRecord
>(1, 2)
111 .add
<FunctionRecord
>(RecordTypes::ENTER
, 1, 1)
112 .add
<FunctionRecord
>(RecordTypes::EXIT
, 1, 100)
115 // First, index the records in different blocks.
116 BlockIndexer::Index Index
;
117 BlockIndexer
Indexer(Index
);
118 for (auto B
: {std::ref(Block0
), std::ref(Block1
), std::ref(Block2
)}) {
119 for (auto &R
: B
.get())
120 ASSERT_FALSE(errorToBool(R
->apply(Indexer
)));
121 ASSERT_FALSE(errorToBool(Indexer
.flush()));
124 // Next, verify that each block is consistently defined.
125 BlockVerifier Verifier
;
126 for (auto &ProcessThreadBlocks
: Index
) {
127 auto &Blocks
= ProcessThreadBlocks
.second
;
128 for (auto &B
: Blocks
) {
129 for (auto *R
: B
.Records
)
130 ASSERT_FALSE(errorToBool(R
->apply(Verifier
)));
131 ASSERT_FALSE(errorToBool(Verifier
.verify()));
136 // Then set up the printing mechanisms.
138 raw_string_ostream
OS(Output
);
139 RecordPrinter
RP(OS
);
140 BlockPrinter
BP(OS
, RP
);
141 for (auto &ProcessThreadBlocks
: Index
) {
142 auto &Blocks
= ProcessThreadBlocks
.second
;
143 for (auto &B
: Blocks
) {
144 for (auto *R
: B
.Records
)
145 ASSERT_FALSE(errorToBool(R
->apply(BP
)));
151 EXPECT_THAT(Output
, Not(Eq("")));