[llvm-exegesis][NFC] Return many CodeTemplates instead of one.
[llvm-complete.git] / unittests / XRay / FDRProducerConsumerTest.cpp
blob838e6ca9bf19e8edc49027b4f6d8d4a441c184ce
1 //===- llvm/unittest/XRay/FDRProducerConsumerTest.cpp -----------*- C++ -*-===//
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 //
10 // Test for round-trip record writing and reading.
12 //===----------------------------------------------------------------------===//
13 #include "llvm/Support/DataExtractor.h"
14 #include "llvm/Support/raw_ostream.h"
15 #include "llvm/XRay/FDRLogBuilder.h"
16 #include "llvm/XRay/FDRRecordConsumer.h"
17 #include "llvm/XRay/FDRRecordProducer.h"
18 #include "llvm/XRay/FDRRecords.h"
19 #include "llvm/XRay/FDRTraceWriter.h"
20 #include "llvm/XRay/FileHeaderReader.h"
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include <string>
24 #include <tuple>
26 namespace llvm {
27 namespace xray {
28 namespace {
30 using ::testing::Eq;
31 using ::testing::IsEmpty;
32 using ::testing::Not;
34 template <class RecordType> std::unique_ptr<Record> MakeRecord();
36 template <> std::unique_ptr<Record> MakeRecord<BufferExtents>() {
37 return make_unique<BufferExtents>(1);
40 template <> std::unique_ptr<Record> MakeRecord<NewBufferRecord>() {
41 return make_unique<NewBufferRecord>(1);
44 template <> std::unique_ptr<Record> MakeRecord<NewCPUIDRecord>() {
45 return make_unique<NewCPUIDRecord>(1, 2);
48 template <> std::unique_ptr<Record> MakeRecord<TSCWrapRecord>() {
49 return make_unique<TSCWrapRecord>(1);
52 template <> std::unique_ptr<Record> MakeRecord<WallclockRecord>() {
53 return make_unique<WallclockRecord>(1, 2);
56 template <> std::unique_ptr<Record> MakeRecord<CustomEventRecord>() {
57 return make_unique<CustomEventRecord>(4, 1, "data");
60 template <> std::unique_ptr<Record> MakeRecord<CallArgRecord>() {
61 return make_unique<CallArgRecord>(1);
64 template <> std::unique_ptr<Record> MakeRecord<PIDRecord>() {
65 return make_unique<PIDRecord>(1);
68 template <> std::unique_ptr<Record> MakeRecord<FunctionRecord>() {
69 return make_unique<FunctionRecord>(RecordTypes::ENTER, 1, 2);
72 template <class T> class RoundTripTest : public ::testing::Test {
73 public:
74 RoundTripTest() : Data(), OS(Data) {
75 H.Version = 3;
76 H.Type = 1;
77 H.ConstantTSC = true;
78 H.NonstopTSC = true;
79 H.CycleFrequency = 3e9;
81 Writer = make_unique<FDRTraceWriter>(OS, H);
82 Rec = MakeRecord<T>();
85 protected:
86 std::string Data;
87 raw_string_ostream OS;
88 XRayFileHeader H;
89 std::unique_ptr<FDRTraceWriter> Writer;
90 std::unique_ptr<Record> Rec;
93 TYPED_TEST_CASE_P(RoundTripTest);
95 // This test ensures that the writing and reading implementations are in sync --
96 // that given write(read(write(R))) == R.
97 TYPED_TEST_P(RoundTripTest, RoundTripsSingleValue) {
98 auto &R = this->Rec;
99 ASSERT_FALSE(errorToBool(R->apply(*this->Writer)));
100 this->OS.flush();
102 DataExtractor DE(this->Data, sys::IsLittleEndianHost, 8);
103 uint32_t OffsetPtr = 0;
104 auto HeaderOrErr = readBinaryFormatHeader(DE, OffsetPtr);
105 if (!HeaderOrErr)
106 FAIL() << HeaderOrErr.takeError();
108 FileBasedRecordProducer P(HeaderOrErr.get(), DE, OffsetPtr);
109 std::vector<std::unique_ptr<Record>> Records;
110 LogBuilderConsumer C(Records);
111 while (DE.isValidOffsetForDataOfSize(OffsetPtr, 1)) {
112 auto R = P.produce();
113 if (!R)
114 FAIL() << R.takeError();
115 if (auto E = C.consume(std::move(R.get())))
116 FAIL() << E;
118 ASSERT_THAT(Records, Not(IsEmpty()));
119 std::string Data2;
120 raw_string_ostream OS2(Data2);
121 FDRTraceWriter Writer2(OS2, this->H);
122 for (auto &P : Records)
123 ASSERT_FALSE(errorToBool(P->apply(Writer2)));
124 OS2.flush();
126 EXPECT_EQ(Data2.substr(sizeof(XRayFileHeader)),
127 this->Data.substr(sizeof(XRayFileHeader)));
128 EXPECT_THAT(Records[0]->type(), Eq(R->type()));
131 REGISTER_TYPED_TEST_CASE_P(RoundTripTest, RoundTripsSingleValue);
133 using RecordTypes =
134 ::testing::Types<BufferExtents, NewBufferRecord, NewCPUIDRecord,
135 TSCWrapRecord, WallclockRecord, CustomEventRecord,
136 CallArgRecord, BufferExtents, PIDRecord, FunctionRecord>;
137 INSTANTIATE_TYPED_TEST_CASE_P(Records, RoundTripTest, RecordTypes);
139 } // namespace
140 } // namespace xray
141 } // namespace llvm