brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.3 KiB · 1707246 Raw
162 lines · cpp
1//===-- fdr_log_writer_test.cpp -------------------------------------------===//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// This file is a part of XRay, a function call tracing system.10//11//===----------------------------------------------------------------------===//12#include <time.h>13 14#include "test_helpers.h"15#include "xray/xray_records.h"16#include "xray_fdr_log_writer.h"17#include "llvm/Support/DataExtractor.h"18#include "llvm/Testing/Support/Error.h"19#include "llvm/XRay/Trace.h"20#include "gmock/gmock.h"21#include "gtest/gtest.h"22 23namespace __xray {24namespace {25 26static constexpr size_t kSize = 4096;27 28using ::llvm::HasValue;29using ::llvm::xray::testing::FuncId;30using ::llvm::xray::testing::RecordType;31using ::testing::AllOf;32using ::testing::ElementsAre;33using ::testing::Eq;34using ::testing::IsEmpty;35using ::testing::IsNull;36 37// Exercise the common code path where we initialize a buffer and are able to38// write some records successfully.39TEST(FdrLogWriterTest, WriteSomeRecords) {40  bool Success = false;41  BufferQueue Buffers(kSize, 1, Success);42  BufferQueue::Buffer B;43  ASSERT_EQ(Buffers.getBuffer(B), BufferQueue::ErrorCode::Ok);44 45  FDRLogWriter Writer(B);46  MetadataRecord Preamble[] = {47      createMetadataRecord<MetadataRecord::RecordKinds::NewBuffer>(int32_t{1}),48      createMetadataRecord<MetadataRecord::RecordKinds::WalltimeMarker>(49          int64_t{1}, int32_t{2}),50      createMetadataRecord<MetadataRecord::RecordKinds::Pid>(int32_t{1}),51  };52  ASSERT_THAT(Writer.writeMetadataRecords(Preamble),53              Eq(sizeof(MetadataRecord) * 3));54  ASSERT_TRUE(Writer.writeMetadata<MetadataRecord::RecordKinds::NewCPUId>(1));55  ASSERT_TRUE(56      Writer.writeFunction(FDRLogWriter::FunctionRecordKind::Enter, 1, 1));57  ASSERT_TRUE(58      Writer.writeFunction(FDRLogWriter::FunctionRecordKind::Exit, 1, 1));59  ASSERT_EQ(Buffers.releaseBuffer(B), BufferQueue::ErrorCode::Ok);60  ASSERT_EQ(B.Data, nullptr);61  ASSERT_EQ(Buffers.finalize(), BufferQueue::ErrorCode::Ok);62 63  // We then need to go through each element of the Buffers, and re-create a64  // flat buffer that we would see if they were laid out in a file. This also65  // means we need to write out the header manually.66  std::string Serialized = serialize(Buffers, 3);67  llvm::DataExtractor DE(Serialized, true, 8);68  auto TraceOrErr = llvm::xray::loadTrace(DE);69  EXPECT_THAT_EXPECTED(70      TraceOrErr,71      HasValue(ElementsAre(72          AllOf(FuncId(1), RecordType(llvm::xray::RecordTypes::ENTER)),73          AllOf(FuncId(1), RecordType(llvm::xray::RecordTypes::EXIT)))));74}75 76// Ensure that we can handle buffer re-use.77TEST(FdrLogWriterTest, ReuseBuffers) {78  bool Success = false;79  BufferQueue Buffers(kSize, 1, Success);80  BufferQueue::Buffer B;81  ASSERT_EQ(Buffers.getBuffer(B), BufferQueue::ErrorCode::Ok);82 83  FDRLogWriter Writer(B);84  MetadataRecord Preamble[] = {85      createMetadataRecord<MetadataRecord::RecordKinds::NewBuffer>(int32_t{1}),86      createMetadataRecord<MetadataRecord::RecordKinds::WalltimeMarker>(87          int64_t{1}, int32_t{2}),88      createMetadataRecord<MetadataRecord::RecordKinds::Pid>(int32_t{1}),89  };90 91  // First we write the first set of records into the single buffer in the92  // queue which includes one enter and one exit record.93  ASSERT_THAT(Writer.writeMetadataRecords(Preamble),94              Eq(sizeof(MetadataRecord) * 3));95  ASSERT_TRUE(Writer.writeMetadata<MetadataRecord::RecordKinds::NewCPUId>(96      uint16_t{1}, uint64_t{1}));97  uint64_t TSC = 1;98  ASSERT_TRUE(99      Writer.writeFunction(FDRLogWriter::FunctionRecordKind::Enter, 1, TSC++));100  ASSERT_TRUE(101      Writer.writeFunction(FDRLogWriter::FunctionRecordKind::Exit, 1, TSC++));102  ASSERT_EQ(Buffers.releaseBuffer(B), BufferQueue::ErrorCode::Ok);103  ASSERT_THAT(B.Data, IsNull());104 105  // Then we re-use the buffer, but only write one record.106  ASSERT_EQ(Buffers.getBuffer(B), BufferQueue::ErrorCode::Ok);107  Writer.resetRecord();108  ASSERT_THAT(Writer.writeMetadataRecords(Preamble),109              Eq(sizeof(MetadataRecord) * 3));110  ASSERT_TRUE(Writer.writeMetadata<MetadataRecord::RecordKinds::NewCPUId>(111      uint16_t{1}, uint64_t{1}));112  ASSERT_TRUE(113      Writer.writeFunction(FDRLogWriter::FunctionRecordKind::Enter, 1, TSC++));114  ASSERT_EQ(Buffers.releaseBuffer(B), BufferQueue::ErrorCode::Ok);115  ASSERT_THAT(B.Data, IsNull());116  ASSERT_EQ(Buffers.finalize(), BufferQueue::ErrorCode::Ok);117 118  // Then we validate that we only see the single enter record.119  std::string Serialized = serialize(Buffers, 3);120  llvm::DataExtractor DE(Serialized, true, 8);121  auto TraceOrErr = llvm::xray::loadTrace(DE);122  EXPECT_THAT_EXPECTED(123      TraceOrErr, HasValue(ElementsAre(AllOf(124                      FuncId(1), RecordType(llvm::xray::RecordTypes::ENTER)))));125}126 127TEST(FdrLogWriterTest, UnwriteRecords) {128  bool Success = false;129  BufferQueue Buffers(kSize, 1, Success);130  BufferQueue::Buffer B;131  ASSERT_EQ(Buffers.getBuffer(B), BufferQueue::ErrorCode::Ok);132 133  FDRLogWriter Writer(B);134  MetadataRecord Preamble[] = {135      createMetadataRecord<MetadataRecord::RecordKinds::NewBuffer>(int32_t{1}),136      createMetadataRecord<MetadataRecord::RecordKinds::WalltimeMarker>(137          int64_t{1}, int32_t{2}),138      createMetadataRecord<MetadataRecord::RecordKinds::Pid>(int32_t{1}),139  };140  ASSERT_THAT(Writer.writeMetadataRecords(Preamble),141              Eq(sizeof(MetadataRecord) * 3));142  ASSERT_TRUE(Writer.writeMetadata<MetadataRecord::RecordKinds::NewCPUId>(1));143  ASSERT_TRUE(144      Writer.writeFunction(FDRLogWriter::FunctionRecordKind::Enter, 1, 1));145  ASSERT_TRUE(146      Writer.writeFunction(FDRLogWriter::FunctionRecordKind::Exit, 1, 1));147  Writer.undoWrites(sizeof(FunctionRecord) * 2);148  ASSERT_EQ(Buffers.releaseBuffer(B), BufferQueue::ErrorCode::Ok);149  ASSERT_EQ(B.Data, nullptr);150  ASSERT_EQ(Buffers.finalize(), BufferQueue::ErrorCode::Ok);151 152  // We've un-done the two function records we've written, and now we expect153  // that we don't have any function records in the trace.154  std::string Serialized = serialize(Buffers, 3);155  llvm::DataExtractor DE(Serialized, true, 8);156  auto TraceOrErr = llvm::xray::loadTrace(DE);157  EXPECT_THAT_EXPECTED(TraceOrErr, HasValue(IsEmpty()));158}159 160} // namespace161} // namespace __xray162