1fbc59d92SDean Michael Berris //===- llvm/unittest/XRay/FDRRecordPrinterTest.cpp --------------*- C++ -*-===// 2fbc59d92SDean Michael Berris // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fbc59d92SDean Michael Berris // 7fbc59d92SDean Michael Berris //===----------------------------------------------------------------------===// 8fbc59d92SDean Michael Berris #include "llvm/Support/raw_ostream.h" 9fbc59d92SDean Michael Berris #include "llvm/XRay/FDRRecords.h" 10fbc59d92SDean Michael Berris #include "llvm/XRay/RecordPrinter.h" 11fbc59d92SDean Michael Berris #include "gmock/gmock.h" 12fbc59d92SDean Michael Berris #include "gtest/gtest.h" 13fbc59d92SDean Michael Berris #include <string> 14fbc59d92SDean Michael Berris 15fbc59d92SDean Michael Berris namespace llvm { 16fbc59d92SDean Michael Berris namespace xray { 17fbc59d92SDean Michael Berris namespace { 18fbc59d92SDean Michael Berris 19fbc59d92SDean Michael Berris using ::testing::Eq; 20fbc59d92SDean Michael Berris 21fbc59d92SDean Michael Berris template <class RecordType> struct Helper {}; 22fbc59d92SDean Michael Berris 23fbc59d92SDean Michael Berris template <> struct Helper<BufferExtents> { 24fbc59d92SDean Michael Berris static std::unique_ptr<Record> construct() { 250eaee545SJonas Devlieghere return std::make_unique<BufferExtents>(1); 26fbc59d92SDean Michael Berris } 27fbc59d92SDean Michael Berris 283ce07499SDean Michael Berris static const char *expected() { return "<Buffer: size = 1 bytes>"; } 29fbc59d92SDean Michael Berris }; 30fbc59d92SDean Michael Berris 31fbc59d92SDean Michael Berris template <> struct Helper<WallclockRecord> { 32fbc59d92SDean Michael Berris static std::unique_ptr<Record> construct() { 330eaee545SJonas Devlieghere return std::make_unique<WallclockRecord>(1, 2); 34fbc59d92SDean Michael Berris } 35fbc59d92SDean Michael Berris 363ce07499SDean Michael Berris static const char *expected() { return "<Wall Time: seconds = 1.000002>"; } 37fbc59d92SDean Michael Berris }; 38fbc59d92SDean Michael Berris 39fbc59d92SDean Michael Berris template <> struct Helper<NewCPUIDRecord> { 40fbc59d92SDean Michael Berris static std::unique_ptr<Record> construct() { 410eaee545SJonas Devlieghere return std::make_unique<NewCPUIDRecord>(1, 2); 42fbc59d92SDean Michael Berris } 43fbc59d92SDean Michael Berris 44d2c50408SDean Michael Berris static const char *expected() { return "<CPU: id = 1, tsc = 2>"; } 45fbc59d92SDean Michael Berris }; 46fbc59d92SDean Michael Berris 47fbc59d92SDean Michael Berris template <> struct Helper<TSCWrapRecord> { 48fbc59d92SDean Michael Berris static std::unique_ptr<Record> construct() { 490eaee545SJonas Devlieghere return std::make_unique<TSCWrapRecord>(1); 50fbc59d92SDean Michael Berris } 51fbc59d92SDean Michael Berris 523ce07499SDean Michael Berris static const char *expected() { return "<TSC Wrap: base = 1>"; } 53fbc59d92SDean Michael Berris }; 54fbc59d92SDean Michael Berris 55fbc59d92SDean Michael Berris template <> struct Helper<CustomEventRecord> { 56fbc59d92SDean Michael Berris static std::unique_ptr<Record> construct() { 570eaee545SJonas Devlieghere return std::make_unique<CustomEventRecord>(4, 1, 2, "data"); 58fbc59d92SDean Michael Berris } 59fbc59d92SDean Michael Berris 603ce07499SDean Michael Berris static const char *expected() { 616b67ff03SDean Michael Berris return "<Custom Event: tsc = 1, cpu = 2, size = 4, data = 'data'>"; 623ce07499SDean Michael Berris } 63fbc59d92SDean Michael Berris }; 64fbc59d92SDean Michael Berris 65fbc59d92SDean Michael Berris template <> struct Helper<CallArgRecord> { 66fbc59d92SDean Michael Berris static std::unique_ptr<Record> construct() { 670eaee545SJonas Devlieghere return std::make_unique<CallArgRecord>(1); 68fbc59d92SDean Michael Berris } 69fbc59d92SDean Michael Berris 703ce07499SDean Michael Berris static const char *expected() { 713ce07499SDean Michael Berris return "<Call Argument: data = 1 (hex = 0x1)>"; 723ce07499SDean Michael Berris } 73fbc59d92SDean Michael Berris }; 74fbc59d92SDean Michael Berris 75fbc59d92SDean Michael Berris template <> struct Helper<PIDRecord> { 76fbc59d92SDean Michael Berris static std::unique_ptr<Record> construct() { 770eaee545SJonas Devlieghere return std::make_unique<PIDRecord>(1); 78fbc59d92SDean Michael Berris } 79fbc59d92SDean Michael Berris 803ce07499SDean Michael Berris static const char *expected() { return "<PID: 1>"; } 81fbc59d92SDean Michael Berris }; 82fbc59d92SDean Michael Berris 83fbc59d92SDean Michael Berris template <> struct Helper<NewBufferRecord> { 84fbc59d92SDean Michael Berris static std::unique_ptr<Record> construct() { 850eaee545SJonas Devlieghere return std::make_unique<NewBufferRecord>(1); 86fbc59d92SDean Michael Berris } 87fbc59d92SDean Michael Berris 883ce07499SDean Michael Berris static const char *expected() { return "<Thread ID: 1>"; } 89fbc59d92SDean Michael Berris }; 90fbc59d92SDean Michael Berris 91fbc59d92SDean Michael Berris template <> struct Helper<EndBufferRecord> { 92fbc59d92SDean Michael Berris static std::unique_ptr<Record> construct() { 930eaee545SJonas Devlieghere return std::make_unique<EndBufferRecord>(); 94fbc59d92SDean Michael Berris } 95fbc59d92SDean Michael Berris 963ce07499SDean Michael Berris static const char *expected() { return "<End of Buffer>"; } 97fbc59d92SDean Michael Berris }; 98fbc59d92SDean Michael Berris 99fbc59d92SDean Michael Berris template <class T> class PrinterTest : public ::testing::Test { 100fbc59d92SDean Michael Berris protected: 101fbc59d92SDean Michael Berris std::string Data; 102fbc59d92SDean Michael Berris raw_string_ostream OS; 103fbc59d92SDean Michael Berris RecordPrinter P; 104fbc59d92SDean Michael Berris std::unique_ptr<Record> R; 105fbc59d92SDean Michael Berris 106fbc59d92SDean Michael Berris public: 107fbc59d92SDean Michael Berris PrinterTest() : Data(), OS(Data), P(OS), R(Helper<T>::construct()) {} 108fbc59d92SDean Michael Berris }; 109fbc59d92SDean Michael Berris 110d4d80a29SBenjamin Kramer TYPED_TEST_SUITE_P(PrinterTest); 111fbc59d92SDean Michael Berris 112fbc59d92SDean Michael Berris TYPED_TEST_P(PrinterTest, PrintsRecord) { 113fbc59d92SDean Michael Berris ASSERT_NE(nullptr, this->R); 114fbc59d92SDean Michael Berris ASSERT_FALSE(errorToBool(this->R->apply(this->P))); 1153ce07499SDean Michael Berris EXPECT_THAT(this->Data, Eq(Helper<TypeParam>::expected())); 116fbc59d92SDean Michael Berris } 117fbc59d92SDean Michael Berris 118d4d80a29SBenjamin Kramer REGISTER_TYPED_TEST_SUITE_P(PrinterTest, PrintsRecord); 119fbc59d92SDean Michael Berris using FDRRecordTypes = 120fbc59d92SDean Michael Berris ::testing::Types<BufferExtents, NewBufferRecord, EndBufferRecord, 121fbc59d92SDean Michael Berris NewCPUIDRecord, TSCWrapRecord, WallclockRecord, 122fbc59d92SDean Michael Berris CustomEventRecord, CallArgRecord, BufferExtents, 123fbc59d92SDean Michael Berris PIDRecord>; 124*05de4b41SBenjamin Kramer INSTANTIATE_TYPED_TEST_SUITE_P(Records, PrinterTest, FDRRecordTypes, ); 125fbc59d92SDean Michael Berris 126fbc59d92SDean Michael Berris TEST(FDRRecordPrinterTest, WriteFunctionRecordEnter) { 127fbc59d92SDean Michael Berris std::string Data; 128fbc59d92SDean Michael Berris raw_string_ostream OS(Data); 129fbc59d92SDean Michael Berris RecordPrinter P(OS); 130fbc59d92SDean Michael Berris FunctionRecord R(RecordTypes::ENTER, 1, 2); 131fbc59d92SDean Michael Berris ASSERT_FALSE(errorToBool(R.apply(P))); 1328a3ef6f3SDean Michael Berris EXPECT_THAT(Data, Eq("<Function Enter: #1 delta = +2>")); 133fbc59d92SDean Michael Berris } 134fbc59d92SDean Michael Berris 135fbc59d92SDean Michael Berris TEST(FDRRecordPrinterTest, WriteFunctionRecordExit) { 136fbc59d92SDean Michael Berris std::string Data; 137fbc59d92SDean Michael Berris raw_string_ostream OS(Data); 138fbc59d92SDean Michael Berris RecordPrinter P(OS); 139fbc59d92SDean Michael Berris FunctionRecord R(RecordTypes::EXIT, 1, 2); 140fbc59d92SDean Michael Berris ASSERT_FALSE(errorToBool(R.apply(P))); 1418a3ef6f3SDean Michael Berris EXPECT_THAT(Data, Eq("<Function Exit: #1 delta = +2>")); 142fbc59d92SDean Michael Berris } 143fbc59d92SDean Michael Berris 144fbc59d92SDean Michael Berris TEST(FDRRecordPrinterTest, WriteFunctionRecordTailExit) { 145fbc59d92SDean Michael Berris std::string Data; 146fbc59d92SDean Michael Berris raw_string_ostream OS(Data); 147fbc59d92SDean Michael Berris RecordPrinter P(OS); 148fbc59d92SDean Michael Berris FunctionRecord R(RecordTypes::TAIL_EXIT, 1, 2); 149fbc59d92SDean Michael Berris ASSERT_FALSE(errorToBool(R.apply(P))); 1508a3ef6f3SDean Michael Berris EXPECT_THAT(Data, Eq("<Function Tail Exit: #1 delta = +2>")); 151fbc59d92SDean Michael Berris } 152fbc59d92SDean Michael Berris 153fbc59d92SDean Michael Berris TEST(FDRRecordPrinterTest, WriteFunctionRecordEnterArg) { 154fbc59d92SDean Michael Berris std::string Data; 155fbc59d92SDean Michael Berris raw_string_ostream OS(Data); 156fbc59d92SDean Michael Berris RecordPrinter P(OS); 157fbc59d92SDean Michael Berris FunctionRecord R(RecordTypes::ENTER_ARG, 1, 2); 158fbc59d92SDean Michael Berris ASSERT_FALSE(errorToBool(R.apply(P))); 1598a3ef6f3SDean Michael Berris EXPECT_THAT(Data, Eq("<Function Enter With Arg: #1 delta = +2>")); 160fbc59d92SDean Michael Berris } 161fbc59d92SDean Michael Berris 162fbc59d92SDean Michael Berris } // namespace 163fbc59d92SDean Michael Berris } // namespace xray 164fbc59d92SDean Michael Berris } // namespace llvm 165