1//===- llvm/unittest/XRay/FDRRecordPrinterTest.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/Support/raw_ostream.h"
9#include "llvm/XRay/FDRRecords.h"
10#include "llvm/XRay/RecordPrinter.h"
11#include "gmock/gmock.h"
12#include "gtest/gtest.h"
13#include <string>
14
15namespace llvm {
16namespace xray {
17namespace {
18
19using ::testing::Eq;
20
21template <class RecordType> struct Helper {};
22
23template <> struct Helper<BufferExtents> {
24 static std::unique_ptr<Record> construct() {
25 return std::make_unique<BufferExtents>(args: 1);
26 }
27
28 static const char *expected() { return "<Buffer: size = 1 bytes>"; }
29};
30
31template <> struct Helper<WallclockRecord> {
32 static std::unique_ptr<Record> construct() {
33 return std::make_unique<WallclockRecord>(args: 1, args: 2);
34 }
35
36 static const char *expected() { return "<Wall Time: seconds = 1.000002>"; }
37};
38
39template <> struct Helper<NewCPUIDRecord> {
40 static std::unique_ptr<Record> construct() {
41 return std::make_unique<NewCPUIDRecord>(args: 1, args: 2);
42 }
43
44 static const char *expected() { return "<CPU: id = 1, tsc = 2>"; }
45};
46
47template <> struct Helper<TSCWrapRecord> {
48 static std::unique_ptr<Record> construct() {
49 return std::make_unique<TSCWrapRecord>(args: 1);
50 }
51
52 static const char *expected() { return "<TSC Wrap: base = 1>"; }
53};
54
55template <> struct Helper<CustomEventRecord> {
56 static std::unique_ptr<Record> construct() {
57 return std::make_unique<CustomEventRecord>(args: 4, args: 1, args: 2, args: "data");
58 }
59
60 static const char *expected() {
61 return "<Custom Event: tsc = 1, cpu = 2, size = 4, data = 'data'>";
62 }
63};
64
65template <> struct Helper<CallArgRecord> {
66 static std::unique_ptr<Record> construct() {
67 return std::make_unique<CallArgRecord>(args: 1);
68 }
69
70 static const char *expected() {
71 return "<Call Argument: data = 1 (hex = 0x1)>";
72 }
73};
74
75template <> struct Helper<PIDRecord> {
76 static std::unique_ptr<Record> construct() {
77 return std::make_unique<PIDRecord>(args: 1);
78 }
79
80 static const char *expected() { return "<PID: 1>"; }
81};
82
83template <> struct Helper<NewBufferRecord> {
84 static std::unique_ptr<Record> construct() {
85 return std::make_unique<NewBufferRecord>(args: 1);
86 }
87
88 static const char *expected() { return "<Thread ID: 1>"; }
89};
90
91template <> struct Helper<EndBufferRecord> {
92 static std::unique_ptr<Record> construct() {
93 return std::make_unique<EndBufferRecord>();
94 }
95
96 static const char *expected() { return "<End of Buffer>"; }
97};
98
99template <class T> class PrinterTest : public ::testing::Test {
100protected:
101 std::string Data;
102 raw_string_ostream OS;
103 RecordPrinter P;
104 std::unique_ptr<Record> R;
105
106public:
107 PrinterTest() : Data(), OS(Data), P(OS), R(Helper<T>::construct()) {}
108};
109
110TYPED_TEST_SUITE_P(PrinterTest);
111
112TYPED_TEST_P(PrinterTest, PrintsRecord) {
113 ASSERT_NE(nullptr, this->R);
114 ASSERT_FALSE(errorToBool(this->R->apply(this->P)));
115 this->OS.flush();
116 EXPECT_THAT(this->Data, Eq(Helper<TypeParam>::expected()));
117}
118
119REGISTER_TYPED_TEST_SUITE_P(PrinterTest, PrintsRecord);
120using FDRRecordTypes =
121 ::testing::Types<BufferExtents, NewBufferRecord, EndBufferRecord,
122 NewCPUIDRecord, TSCWrapRecord, WallclockRecord,
123 CustomEventRecord, CallArgRecord, BufferExtents,
124 PIDRecord>;
125INSTANTIATE_TYPED_TEST_SUITE_P(Records, PrinterTest, FDRRecordTypes, );
126
127TEST(FDRRecordPrinterTest, WriteFunctionRecordEnter) {
128 std::string Data;
129 raw_string_ostream OS(Data);
130 RecordPrinter P(OS);
131 FunctionRecord R(RecordTypes::ENTER, 1, 2);
132 ASSERT_FALSE(errorToBool(R.apply(P)));
133 OS.flush();
134 EXPECT_THAT(Data, Eq("<Function Enter: #1 delta = +2>"));
135}
136
137TEST(FDRRecordPrinterTest, WriteFunctionRecordExit) {
138 std::string Data;
139 raw_string_ostream OS(Data);
140 RecordPrinter P(OS);
141 FunctionRecord R(RecordTypes::EXIT, 1, 2);
142 ASSERT_FALSE(errorToBool(R.apply(P)));
143 OS.flush();
144 EXPECT_THAT(Data, Eq("<Function Exit: #1 delta = +2>"));
145}
146
147TEST(FDRRecordPrinterTest, WriteFunctionRecordTailExit) {
148 std::string Data;
149 raw_string_ostream OS(Data);
150 RecordPrinter P(OS);
151 FunctionRecord R(RecordTypes::TAIL_EXIT, 1, 2);
152 ASSERT_FALSE(errorToBool(R.apply(P)));
153 OS.flush();
154 EXPECT_THAT(Data, Eq("<Function Tail Exit: #1 delta = +2>"));
155}
156
157TEST(FDRRecordPrinterTest, WriteFunctionRecordEnterArg) {
158 std::string Data;
159 raw_string_ostream OS(Data);
160 RecordPrinter P(OS);
161 FunctionRecord R(RecordTypes::ENTER_ARG, 1, 2);
162 ASSERT_FALSE(errorToBool(R.apply(P)));
163 OS.flush();
164 EXPECT_THAT(Data, Eq("<Function Enter With Arg: #1 delta = +2>"));
165}
166
167} // namespace
168} // namespace xray
169} // namespace llvm
170

source code of llvm/unittests/XRay/FDRRecordPrinterTest.cpp