blob: 86b478a5a4588eabca303272de206e2844284e4d [file] [log] [blame]
Dean Michael Berrisdd01efc2018-09-11 00:22:53 +00001//===- FDRRecords.cpp - Unit Tests for XRay FDR Record Loading ------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include "gmock/gmock.h"
10#include "gtest/gtest.h"
11
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"
18
19namespace llvm {
20namespace xray {
21namespace {
22
23using ::testing::Eq;
24using ::testing::Not;
25
26TEST(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)
34 .add<PIDRecord>(1)
35 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
36 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
Dean Michael Berris59439dd2018-11-07 04:37:42 +000037 .add<CustomEventRecordV5>(1, 4, "XRAY")
38 .add<TypedEventRecord>(1, 4, 2, "XRAY")
Dean Michael Berrisdd01efc2018-09-11 00:22:53 +000039 .consume();
40 auto Block1 = LogBuilder()
41 .add<BufferExtents>(100)
42 .add<NewBufferRecord>(1)
43 .add<WallclockRecord>(1, 2)
44 .add<PIDRecord>(1)
45 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
46 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
Dean Michael Berris59439dd2018-11-07 04:37:42 +000047 .add<CustomEventRecordV5>(1, 4, "XRAY")
48 .add<TypedEventRecord>(1, 4, 2, "XRAY")
Dean Michael Berrisdd01efc2018-09-11 00:22:53 +000049 .consume();
50 auto Block2 = LogBuilder()
51 .add<BufferExtents>(100)
52 .add<NewBufferRecord>(2)
53 .add<WallclockRecord>(1, 3)
54 .add<PIDRecord>(1)
55 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
56 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
Dean Michael Berris59439dd2018-11-07 04:37:42 +000057 .add<CustomEventRecordV5>(1, 4, "XRAY")
58 .add<TypedEventRecord>(1, 4, 2, "XRAY")
Dean Michael Berrisdd01efc2018-09-11 00:22:53 +000059 .consume();
60 BlockIndexer::Index Index;
61 BlockIndexer Indexer(Index);
62 for (auto B : {std::ref(Block0), std::ref(Block1), std::ref(Block2)}) {
63 for (auto &R : B.get())
64 ASSERT_FALSE(errorToBool(R->apply(Indexer)));
65 ASSERT_FALSE(errorToBool(Indexer.flush()));
66 }
67
68 // We have two threads worth of blocks.
69 ASSERT_THAT(Index.size(), Eq(2u));
70 auto T1Blocks = Index.find({1, 1});
71 ASSERT_THAT(T1Blocks, Not(Eq(Index.end())));
72 ASSERT_THAT(T1Blocks->second.size(), Eq(2u));
73 auto T2Blocks = Index.find({1, 2});
74 ASSERT_THAT(T2Blocks, Not(Eq(Index.end())));
75 ASSERT_THAT(T2Blocks->second.size(), Eq(1u));
76}
77
78TEST(XRayFDRTest, BuilderAndBlockVerifier) {
79 auto Block = LogBuilder()
80 .add<BufferExtents>(48)
81 .add<NewBufferRecord>(1)
82 .add<WallclockRecord>(1, 1)
83 .add<PIDRecord>(1)
Dean Michael Berrisd2c50402018-09-11 06:36:51 +000084 .add<NewCPUIDRecord>(1, 2)
Dean Michael Berrisdd01efc2018-09-11 00:22:53 +000085 .consume();
86 BlockVerifier Verifier;
87 for (auto &R : Block)
88 ASSERT_FALSE(errorToBool(R->apply(Verifier)));
89 ASSERT_FALSE(errorToBool(Verifier.verify()));
90}
91
92TEST(XRayFDRTest, IndexAndVerifyBlocks) {
93 auto Block0 = LogBuilder()
94 .add<BufferExtents>(64)
95 .add<NewBufferRecord>(1)
96 .add<WallclockRecord>(1, 1)
97 .add<PIDRecord>(1)
Dean Michael Berrisd2c50402018-09-11 06:36:51 +000098 .add<NewCPUIDRecord>(1, 2)
Dean Michael Berrisdd01efc2018-09-11 00:22:53 +000099 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
100 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
Dean Michael Berris59439dd2018-11-07 04:37:42 +0000101 .add<CustomEventRecordV5>(1, 4, "XRAY")
102 .add<TypedEventRecord>(1, 4, 2, "XRAY")
Dean Michael Berrisdd01efc2018-09-11 00:22:53 +0000103 .consume();
104 auto Block1 = LogBuilder()
105 .add<BufferExtents>(64)
106 .add<NewBufferRecord>(1)
107 .add<WallclockRecord>(1, 1)
108 .add<PIDRecord>(1)
Dean Michael Berrisd2c50402018-09-11 06:36:51 +0000109 .add<NewCPUIDRecord>(1, 2)
Dean Michael Berrisdd01efc2018-09-11 00:22:53 +0000110 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
111 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
Dean Michael Berris59439dd2018-11-07 04:37:42 +0000112 .add<CustomEventRecordV5>(1, 4, "XRAY")
113 .add<TypedEventRecord>(1, 4, 2, "XRAY")
Dean Michael Berrisdd01efc2018-09-11 00:22:53 +0000114 .consume();
115 auto Block2 = LogBuilder()
116 .add<BufferExtents>(64)
117 .add<NewBufferRecord>(1)
118 .add<WallclockRecord>(1, 1)
119 .add<PIDRecord>(1)
Dean Michael Berrisd2c50402018-09-11 06:36:51 +0000120 .add<NewCPUIDRecord>(1, 2)
Dean Michael Berrisdd01efc2018-09-11 00:22:53 +0000121 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
122 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
Dean Michael Berris59439dd2018-11-07 04:37:42 +0000123 .add<CustomEventRecordV5>(1, 4, "XRAY")
124 .add<TypedEventRecord>(1, 4, 2, "XRAY")
Dean Michael Berrisdd01efc2018-09-11 00:22:53 +0000125 .consume();
126
127 // First, index the records in different blocks.
128 BlockIndexer::Index Index;
129 BlockIndexer Indexer(Index);
130 for (auto B : {std::ref(Block0), std::ref(Block1), std::ref(Block2)}) {
131 for (auto &R : B.get())
132 ASSERT_FALSE(errorToBool(R->apply(Indexer)));
133 ASSERT_FALSE(errorToBool(Indexer.flush()));
134 }
135
136 // Next, verify that each block is consistently defined.
137 BlockVerifier Verifier;
138 for (auto &ProcessThreadBlocks : Index) {
139 auto &Blocks = ProcessThreadBlocks.second;
140 for (auto &B : Blocks) {
141 for (auto *R : B.Records)
142 ASSERT_FALSE(errorToBool(R->apply(Verifier)));
143 ASSERT_FALSE(errorToBool(Verifier.verify()));
144 Verifier.reset();
145 }
146 }
147
148 // Then set up the printing mechanisms.
149 std::string Output;
150 raw_string_ostream OS(Output);
151 RecordPrinter RP(OS);
152 BlockPrinter BP(OS, RP);
153 for (auto &ProcessThreadBlocks : Index) {
154 auto &Blocks = ProcessThreadBlocks.second;
155 for (auto &B : Blocks) {
156 for (auto *R : B.Records)
157 ASSERT_FALSE(errorToBool(R->apply(BP)));
158 BP.reset();
159 }
160 }
161
162 OS.flush();
163 EXPECT_THAT(Output, Not(Eq("")));
164}
165
166} // namespace
167} // namespace xray
168} // namespace llvm