brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.6 KiB · 32c75e4 Raw
179 lines · cpp
1//===- llvm/unittest/XRay/FDRTraceWriterTest.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-exception6//7//===----------------------------------------------------------------------===//8//9// Test a utility that can write out XRay FDR Mode formatted trace files.10//11//===----------------------------------------------------------------------===//12#include "llvm/XRay/FDRTraceWriter.h"13#include "llvm/Support/raw_ostream.h"14#include "llvm/XRay/FDRLogBuilder.h"15#include "llvm/XRay/FDRRecords.h"16#include "llvm/XRay/Trace.h"17#include "gmock/gmock.h"18#include "gtest/gtest.h"19#include <string>20 21namespace llvm {22namespace xray {23namespace {24 25using testing::ElementsAre;26using testing::Eq;27using testing::Field;28using testing::IsEmpty;29using testing::Not;30 31// We want to be able to create an instance of an FDRTraceWriter and associate32// it with a stream, which could be loaded and turned into a Trace instance.33// This test writes out version 3 trace logs.34TEST(FDRTraceWriterTest, WriteToStringBufferVersion3) {35  std::string Data;36  raw_string_ostream OS(Data);37  XRayFileHeader H;38  H.Version = 3;39  H.Type = 1;40  H.ConstantTSC = true;41  H.NonstopTSC = true;42  H.CycleFrequency = 3e9;43  FDRTraceWriter Writer(OS, H);44  auto L = LogBuilder()45               .add<BufferExtents>(80)46               .add<NewBufferRecord>(1)47               .add<WallclockRecord>(1, 1)48               .add<PIDRecord>(1)49               .add<NewCPUIDRecord>(1, 2)50               .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)51               .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)52               .consume();53  for (auto &P : L)54    ASSERT_FALSE(errorToBool(P->apply(Writer)));55 56  // Then from here we load the Trace file.57  DataExtractor DE(Data, sys::IsLittleEndianHost, 8);58  auto TraceOrErr = loadTrace(DE, true);59  if (!TraceOrErr)60    FAIL() << TraceOrErr.takeError();61  auto &Trace = TraceOrErr.get();62 63  ASSERT_THAT(Trace, Not(IsEmpty()));64  EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::FuncId, Eq(1)),65                                 Field(&XRayRecord::FuncId, Eq(1))));66  EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::TId, Eq(1u)),67                                 Field(&XRayRecord::TId, Eq(1u))));68  EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::PId, Eq(1u)),69                                 Field(&XRayRecord::PId, Eq(1u))));70  EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::CPU, Eq(1u)),71                                 Field(&XRayRecord::CPU, Eq(1u))));72  EXPECT_THAT(Trace,73              ElementsAre(Field(&XRayRecord::Type, Eq(RecordTypes::ENTER)),74                          Field(&XRayRecord::Type, Eq(RecordTypes::EXIT))));75}76 77// This version is almost exactly the same as above, except writing version 278// logs, without the PID records.79TEST(FDRTraceWriterTest, WriteToStringBufferVersion2) {80  std::string Data;81  raw_string_ostream OS(Data);82  XRayFileHeader H;83  H.Version = 2;84  H.Type = 1;85  H.ConstantTSC = true;86  H.NonstopTSC = true;87  H.CycleFrequency = 3e9;88  FDRTraceWriter Writer(OS, H);89  auto L = LogBuilder()90               .add<BufferExtents>(64)91               .add<NewBufferRecord>(1)92               .add<WallclockRecord>(1, 1)93               .add<NewCPUIDRecord>(1, 2)94               .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)95               .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)96               .consume();97  for (auto &P : L)98    ASSERT_FALSE(errorToBool(P->apply(Writer)));99 100  // Then from here we load the Trace file.101  DataExtractor DE(Data, sys::IsLittleEndianHost, 8);102  auto TraceOrErr = loadTrace(DE, true);103  if (!TraceOrErr)104    FAIL() << TraceOrErr.takeError();105  auto &Trace = TraceOrErr.get();106 107  ASSERT_THAT(Trace, Not(IsEmpty()));108  EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::FuncId, Eq(1)),109                                 Field(&XRayRecord::FuncId, Eq(1))));110  EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::TId, Eq(1u)),111                                 Field(&XRayRecord::TId, Eq(1u))));112  EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::CPU, Eq(1u)),113                                 Field(&XRayRecord::CPU, Eq(1u))));114  EXPECT_THAT(Trace,115              ElementsAre(Field(&XRayRecord::Type, Eq(RecordTypes::ENTER)),116                          Field(&XRayRecord::Type, Eq(RecordTypes::EXIT))));117}118 119// This covers version 1 of the log, without a BufferExtents record but has an120// explicit EndOfBuffer record.121TEST(FDRTraceWriterTest, WriteToStringBufferVersion1) {122  std::string Data;123  raw_string_ostream OS(Data);124  XRayFileHeader H;125  H.Version = 1;126  H.Type = 1;127  H.ConstantTSC = true;128  H.NonstopTSC = true;129  H.CycleFrequency = 3e9;130  // Write the size of buffers out, arbitrarily it's 4k.131  constexpr uint64_t BufferSize = 4096;132  std::memcpy(H.FreeFormData, reinterpret_cast<const char *>(&BufferSize),133              sizeof(BufferSize));134  FDRTraceWriter Writer(OS, H);135 136  // Ensure that at this point the Data buffer has the file header serialized137  // size.138  ASSERT_THAT(Data.size(), Eq(32u));139  auto L = LogBuilder()140               .add<NewBufferRecord>(1)141               .add<WallclockRecord>(1, 1)142               .add<NewCPUIDRecord>(1, 2)143               .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)144               .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)145               .add<EndBufferRecord>()146               .consume();147  for (auto &P : L)148    ASSERT_FALSE(errorToBool(P->apply(Writer)));149 150  // We need to pad the buffer with 4016 (4096 - 80) bytes of zeros.151  OS.write_zeros(4016);152 153  // For version 1 of the log, we need the whole buffer to be the size of the154  // file header plus 32.155  ASSERT_THAT(Data.size(), Eq(BufferSize + 32));156 157  // Then from here we load the Trace file.158  DataExtractor DE(Data, sys::IsLittleEndianHost, 8);159  auto TraceOrErr = loadTrace(DE, true);160  if (!TraceOrErr)161    FAIL() << TraceOrErr.takeError();162  auto &Trace = TraceOrErr.get();163 164  ASSERT_THAT(Trace, Not(IsEmpty()));165  EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::FuncId, Eq(1)),166                                 Field(&XRayRecord::FuncId, Eq(1))));167  EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::TId, Eq(1u)),168                                 Field(&XRayRecord::TId, Eq(1u))));169  EXPECT_THAT(Trace, ElementsAre(Field(&XRayRecord::CPU, Eq(1u)),170                                 Field(&XRayRecord::CPU, Eq(1u))));171  EXPECT_THAT(Trace,172              ElementsAre(Field(&XRayRecord::Type, Eq(RecordTypes::ENTER)),173                          Field(&XRayRecord::Type, Eq(RecordTypes::EXIT))));174}175 176} // namespace177} // namespace xray178} // namespace llvm179