#include "llvm/XRay/FDRTraceWriter.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/XRay/FDRLogBuilder.h"
#include "llvm/XRay/FDRRecords.h"
#include "llvm/XRay/Trace.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <string>
namespace llvm {
namespace xray {
namespace {
using testing::ElementsAre;
using testing::Eq;
using testing::Field;
using testing::IsEmpty;
using testing::Not;
TEST(FDRTraceWriterTest, WriteToStringBufferVersion3) {
std::string Data;
raw_string_ostream OS(Data);
XRayFileHeader H;
H.Version = 3;
H.Type = 1;
H.ConstantTSC = true;
H.NonstopTSC = true;
H.CycleFrequency = 3e9;
FDRTraceWriter Writer(OS, H);
auto L = LogBuilder()
.add<BufferExtents>(80)
.add<NewBufferRecord>(1)
.add<WallclockRecord>(1, 1)
.add<PIDRecord>(1)
.add<NewCPUIDRecord>(1, 2)
.add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
.add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
.consume();
for (auto &P : L)
ASSERT_FALSE(errorToBool(P->apply(Writer)));
OS.flush();
DataExtractor DE(Data, sys::IsLittleEndianHost, 8);
auto TraceOrErr = loadTrace(DE, true);
if (!TraceOrErr)
FAIL() << TraceOrErr.takeError();
auto &Trace = TraceOrErr.get();
ASSERT_THAT(Trace, Not(IsEmpty()));
EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::FuncId, Eq(1)),
Field(&XRayRecord::FuncId, Eq(1))));
EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::TId, Eq(1u)),
Field(&XRayRecord::TId, Eq(1u))));
EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::PId, Eq(1u)),
Field(&XRayRecord::PId, Eq(1u))));
EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::CPU, Eq(1u)),
Field(&XRayRecord::CPU, Eq(1u))));
EXPECT_THAT(Trace,
ElementsAre(Field(&XRayRecord::Type, Eq(RecordTypes::ENTER)),
Field(&XRayRecord::Type, Eq(RecordTypes::EXIT))));
}
TEST(FDRTraceWriterTest, WriteToStringBufferVersion2) {
std::string Data;
raw_string_ostream OS(Data);
XRayFileHeader H;
H.Version = 2;
H.Type = 1;
H.ConstantTSC = true;
H.NonstopTSC = true;
H.CycleFrequency = 3e9;
FDRTraceWriter Writer(OS, H);
auto L = LogBuilder()
.add<BufferExtents>(64)
.add<NewBufferRecord>(1)
.add<WallclockRecord>(1, 1)
.add<NewCPUIDRecord>(1, 2)
.add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
.add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
.consume();
for (auto &P : L)
ASSERT_FALSE(errorToBool(P->apply(Writer)));
OS.flush();
DataExtractor DE(Data, sys::IsLittleEndianHost, 8);
auto TraceOrErr = loadTrace(DE, true);
if (!TraceOrErr)
FAIL() << TraceOrErr.takeError();
auto &Trace = TraceOrErr.get();
ASSERT_THAT(Trace, Not(IsEmpty()));
EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::FuncId, Eq(1)),
Field(&XRayRecord::FuncId, Eq(1))));
EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::TId, Eq(1u)),
Field(&XRayRecord::TId, Eq(1u))));
EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::CPU, Eq(1u)),
Field(&XRayRecord::CPU, Eq(1u))));
EXPECT_THAT(Trace,
ElementsAre(Field(&XRayRecord::Type, Eq(RecordTypes::ENTER)),
Field(&XRayRecord::Type, Eq(RecordTypes::EXIT))));
}
TEST(FDRTraceWriterTest, WriteToStringBufferVersion1) {
std::string Data;
raw_string_ostream OS(Data);
XRayFileHeader H;
H.Version = 1;
H.Type = 1;
H.ConstantTSC = true;
H.NonstopTSC = true;
H.CycleFrequency = 3e9;
constexpr uint64_t BufferSize = 4096;
std::memcpy(H.FreeFormData, reinterpret_cast<const char *>(&BufferSize),
sizeof(BufferSize));
FDRTraceWriter Writer(OS, H);
OS.flush();
ASSERT_THAT(Data.size(), Eq(32u));
auto L = LogBuilder()
.add<NewBufferRecord>(1)
.add<WallclockRecord>(1, 1)
.add<NewCPUIDRecord>(1, 2)
.add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
.add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
.add<EndBufferRecord>()
.consume();
for (auto &P : L)
ASSERT_FALSE(errorToBool(P->apply(Writer)));
OS.write_zeros(4016);
OS.flush();
ASSERT_THAT(Data.size(), Eq(BufferSize + 32));
DataExtractor DE(Data, sys::IsLittleEndianHost, 8);
auto TraceOrErr = loadTrace(DE, true);
if (!TraceOrErr)
FAIL() << TraceOrErr.takeError();
auto &Trace = TraceOrErr.get();
ASSERT_THAT(Trace, Not(IsEmpty()));
EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::FuncId, Eq(1)),
Field(&XRayRecord::FuncId, Eq(1))));
EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::TId, Eq(1u)),
Field(&XRayRecord::TId, Eq(1u))));
EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::CPU, Eq(1u)),
Field(&XRayRecord::CPU, Eq(1u))));
EXPECT_THAT(Trace,
ElementsAre(Field(&XRayRecord::Type, Eq(RecordTypes::ENTER)),
Field(&XRayRecord::Type, Eq(RecordTypes::EXIT))));
}
} } }