//===- llvm/unittest/XRay/FDRRecordPrinterTest.cpp --------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "llvm/Support/raw_ostream.h" #include "llvm/XRay/FDRRecords.h" #include "llvm/XRay/RecordPrinter.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include <string> namespace llvm { namespace xray { namespace { using ::testing::Eq; template <class RecordType> struct Helper {}; template <> struct Helper<BufferExtents> { static std::unique_ptr<Record> construct() { return std::make_unique<BufferExtents>(1); } static const char *expected() { return "<Buffer: size = 1 bytes>"; } }; template <> struct Helper<WallclockRecord> { static std::unique_ptr<Record> construct() { return std::make_unique<WallclockRecord>(1, 2); } static const char *expected() { return "<Wall Time: seconds = 1.000002>"; } }; template <> struct Helper<NewCPUIDRecord> { static std::unique_ptr<Record> construct() { return std::make_unique<NewCPUIDRecord>(1, 2); } static const char *expected() { return "<CPU: id = 1, tsc = 2>"; } }; template <> struct Helper<TSCWrapRecord> { static std::unique_ptr<Record> construct() { return std::make_unique<TSCWrapRecord>(1); } static const char *expected() { return "<TSC Wrap: base = 1>"; } }; template <> struct Helper<CustomEventRecord> { static std::unique_ptr<Record> construct() { return std::make_unique<CustomEventRecord>(4, 1, 2, "data"); } static const char *expected() { return "<Custom Event: tsc = 1, cpu = 2, size = 4, data = 'data'>"; } }; template <> struct Helper<CallArgRecord> { static std::unique_ptr<Record> construct() { return std::make_unique<CallArgRecord>(1); } static const char *expected() { return "<Call Argument: data = 1 (hex = 0x1)>"; } }; template <> struct Helper<PIDRecord> { static std::unique_ptr<Record> construct() { return std::make_unique<PIDRecord>(1); } static const char *expected() { return "<PID: 1>"; } }; template <> struct Helper<NewBufferRecord> { static std::unique_ptr<Record> construct() { return std::make_unique<NewBufferRecord>(1); } static const char *expected() { return "<Thread ID: 1>"; } }; template <> struct Helper<EndBufferRecord> { static std::unique_ptr<Record> construct() { return std::make_unique<EndBufferRecord>(); } static const char *expected() { return "<End of Buffer>"; } }; template <class T> class PrinterTest : public ::testing::Test { protected: std::string Data; raw_string_ostream OS; RecordPrinter P; std::unique_ptr<Record> R; public: PrinterTest() : Data(), OS(Data), P(OS), R(Helper<T>::construct()) {} }; TYPED_TEST_CASE_P(PrinterTest); TYPED_TEST_P(PrinterTest, PrintsRecord) { ASSERT_NE(nullptr, this->R); ASSERT_FALSE(errorToBool(this->R->apply(this->P))); this->OS.flush(); EXPECT_THAT(this->Data, Eq(Helper<TypeParam>::expected())); } REGISTER_TYPED_TEST_CASE_P(PrinterTest, PrintsRecord); using FDRRecordTypes = ::testing::Types<BufferExtents, NewBufferRecord, EndBufferRecord, NewCPUIDRecord, TSCWrapRecord, WallclockRecord, CustomEventRecord, CallArgRecord, BufferExtents, PIDRecord>; INSTANTIATE_TYPED_TEST_CASE_P(Records, PrinterTest, FDRRecordTypes); TEST(FDRRecordPrinterTest, WriteFunctionRecordEnter) { std::string Data; raw_string_ostream OS(Data); RecordPrinter P(OS); FunctionRecord R(RecordTypes::ENTER, 1, 2); ASSERT_FALSE(errorToBool(R.apply(P))); OS.flush(); EXPECT_THAT(Data, Eq("<Function Enter: #1 delta = +2>")); } TEST(FDRRecordPrinterTest, WriteFunctionRecordExit) { std::string Data; raw_string_ostream OS(Data); RecordPrinter P(OS); FunctionRecord R(RecordTypes::EXIT, 1, 2); ASSERT_FALSE(errorToBool(R.apply(P))); OS.flush(); EXPECT_THAT(Data, Eq("<Function Exit: #1 delta = +2>")); } TEST(FDRRecordPrinterTest, WriteFunctionRecordTailExit) { std::string Data; raw_string_ostream OS(Data); RecordPrinter P(OS); FunctionRecord R(RecordTypes::TAIL_EXIT, 1, 2); ASSERT_FALSE(errorToBool(R.apply(P))); OS.flush(); EXPECT_THAT(Data, Eq("<Function Tail Exit: #1 delta = +2>")); } TEST(FDRRecordPrinterTest, WriteFunctionRecordEnterArg) { std::string Data; raw_string_ostream OS(Data); RecordPrinter P(OS); FunctionRecord R(RecordTypes::ENTER_ARG, 1, 2); ASSERT_FALSE(errorToBool(R.apply(P))); OS.flush(); EXPECT_THAT(Data, Eq("<Function Enter With Arg: #1 delta = +2>")); } } // namespace } // namespace xray } // namespace llvm