blob: 24ff7a5ad51350a15660e37adefc4da1a541d902 [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)
37 .consume();
38 auto Block1 = LogBuilder()
39 .add<BufferExtents>(100)
40 .add<NewBufferRecord>(1)
41 .add<WallclockRecord>(1, 2)
42 .add<PIDRecord>(1)
43 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
44 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
45 .consume();
46 auto Block2 = LogBuilder()
47 .add<BufferExtents>(100)
48 .add<NewBufferRecord>(2)
49 .add<WallclockRecord>(1, 3)
50 .add<PIDRecord>(1)
51 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
52 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
53 .consume();
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()));
60 }
61
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));
70}
71
72TEST(XRayFDRTest, BuilderAndBlockVerifier) {
73 auto Block = LogBuilder()
74 .add<BufferExtents>(48)
75 .add<NewBufferRecord>(1)
76 .add<WallclockRecord>(1, 1)
77 .add<PIDRecord>(1)
78 .add<NewCPUIDRecord>(1)
79 .consume();
80 BlockVerifier Verifier;
81 for (auto &R : Block)
82 ASSERT_FALSE(errorToBool(R->apply(Verifier)));
83 ASSERT_FALSE(errorToBool(Verifier.verify()));
84}
85
86TEST(XRayFDRTest, IndexAndVerifyBlocks) {
87 auto Block0 = LogBuilder()
88 .add<BufferExtents>(64)
89 .add<NewBufferRecord>(1)
90 .add<WallclockRecord>(1, 1)
91 .add<PIDRecord>(1)
92 .add<NewCPUIDRecord>(1)
93 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
94 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
95 .consume();
96 auto Block1 = LogBuilder()
97 .add<BufferExtents>(64)
98 .add<NewBufferRecord>(1)
99 .add<WallclockRecord>(1, 1)
100 .add<PIDRecord>(1)
101 .add<NewCPUIDRecord>(1)
102 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
103 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
104 .consume();
105 auto Block2 = LogBuilder()
106 .add<BufferExtents>(64)
107 .add<NewBufferRecord>(1)
108 .add<WallclockRecord>(1, 1)
109 .add<PIDRecord>(1)
110 .add<NewCPUIDRecord>(1)
111 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
112 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
113 .consume();
114
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()));
122 }
123
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()));
132 Verifier.reset();
133 }
134 }
135
136 // Then set up the printing mechanisms.
137 std::string Output;
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)));
146 BP.reset();
147 }
148 }
149
150 OS.flush();
151 EXPECT_THAT(Output, Not(Eq("")));
152}
153
154} // namespace
155} // namespace xray
156} // namespace llvm