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