1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00
llvm-mirror/unittests/XRay/FDRBlockVerifierTest.cpp
Dean Michael Berris 665e1fb24b [XRay] Add a BlockVerifier visitor for FDR Records
Summary:
This patch implements a `BlockVerifier` type which enforces the
invariants of the log structure of FDR mode logs on a per-block basis.
This ensures that the data we encounter from an FDR mode log
semantically correct (i.e. that records follow the documented "grammar"
for FDR mode log records).

This is another part of the refactoring of D50441.

This is a slightly modified version of rL341628, avoiding the
`std::tuple<...>` constructor that is not constexpr in C++11.

Reviewers: mboerger, eizan

Subscribers: mgorny, hiraditya, llvm-commits

Differential Revision: https://reviews.llvm.org/D51723

llvm-svn: 341769
2018-09-10 02:35:25 +00:00

140 lines
5.0 KiB
C++

//===- llvm/unittest/XRay/FDRBlockVerifierTest.cpp --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Testing/Support/Error.h"
#include "llvm/XRay/BlockIndexer.h"
#include "llvm/XRay/BlockVerifier.h"
#include "llvm/XRay/FDRLogBuilder.h"
#include "llvm/XRay/FDRRecords.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace llvm {
namespace xray {
namespace {
using ::testing::ElementsAre;
using ::testing::Not;
using ::testing::SizeIs;
TEST(FDRBlockVerifierTest, ValidBlocksV3) {
auto Block0 = LogBuilder()
.add<BufferExtents>(80)
.add<NewBufferRecord>(1)
.add<WallclockRecord>(1, 2)
.add<PIDRecord>(1)
.add<NewCPUIDRecord>(1)
.add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
.add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
.consume();
auto Block1 = LogBuilder()
.add<BufferExtents>(80)
.add<NewBufferRecord>(1)
.add<WallclockRecord>(1, 2)
.add<PIDRecord>(1)
.add<NewCPUIDRecord>(1)
.add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
.add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
.consume();
auto Block2 = LogBuilder()
.add<BufferExtents>(80)
.add<NewBufferRecord>(2)
.add<WallclockRecord>(1, 2)
.add<PIDRecord>(1)
.add<NewCPUIDRecord>(2)
.add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
.add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
.consume();
BlockIndexer::Index Index;
BlockIndexer Indexer(Index);
for (auto B : {std::ref(Block0), std::ref(Block1), std::ref(Block2)}) {
for (auto &R : B.get())
ASSERT_FALSE(errorToBool(R->apply(Indexer)));
ASSERT_FALSE(errorToBool(Indexer.flush()));
}
BlockVerifier Verifier;
for (auto &ProcessThreadBlocks : Index) {
auto &Blocks = ProcessThreadBlocks.second;
for (auto &B : Blocks) {
for (auto *R : B.Records)
ASSERT_FALSE(errorToBool(R->apply(Verifier)));
ASSERT_FALSE(errorToBool(Verifier.verify()));
Verifier.reset();
}
}
}
TEST(FDRBlockVerifierTest, MissingPIDRecord) {
auto Block = LogBuilder()
.add<BufferExtents>(20)
.add<NewBufferRecord>(1)
.add<WallclockRecord>(1, 2)
.add<NewCPUIDRecord>(1)
.add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
.add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
.consume();
BlockVerifier Verifier;
for (auto &R : Block)
ASSERT_FALSE(errorToBool(R->apply(Verifier)));
ASSERT_FALSE(errorToBool(Verifier.verify()));
}
TEST(FDRBlockVerifierTest, MissingBufferExtents) {
auto Block = LogBuilder()
.add<NewBufferRecord>(1)
.add<WallclockRecord>(1, 2)
.add<NewCPUIDRecord>(1)
.add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
.add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
.consume();
BlockVerifier Verifier;
for (auto &R : Block)
ASSERT_FALSE(errorToBool(R->apply(Verifier)));
ASSERT_FALSE(errorToBool(Verifier.verify()));
}
TEST(FDRBlockVerifierTest, IgnoreRecordsAfterEOB) {
auto Block = LogBuilder()
.add<NewBufferRecord>(1)
.add<WallclockRecord>(1, 2)
.add<NewCPUIDRecord>(1)
.add<EndBufferRecord>()
.add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
.add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
.consume();
BlockVerifier Verifier;
for (auto &R : Block)
ASSERT_FALSE(errorToBool(R->apply(Verifier)));
ASSERT_FALSE(errorToBool(Verifier.verify()));
}
TEST(FDRBlockVerifierTest, MalformedV2) {
auto Block = LogBuilder()
.add<NewBufferRecord>(1)
.add<WallclockRecord>(1, 2)
.add<NewCPUIDRecord>(1)
.add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
.add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
.add<NewBufferRecord>(2)
.consume();
BlockVerifier Verifier;
ASSERT_THAT(Block, SizeIs(6u));
EXPECT_THAT_ERROR(Block[0]->apply(Verifier), Succeeded());
EXPECT_THAT_ERROR(Block[1]->apply(Verifier), Succeeded());
EXPECT_THAT_ERROR(Block[2]->apply(Verifier), Succeeded());
EXPECT_THAT_ERROR(Block[3]->apply(Verifier), Succeeded());
EXPECT_THAT_ERROR(Block[4]->apply(Verifier), Succeeded());
EXPECT_THAT_ERROR(Block[5]->apply(Verifier), Failed());
}
} // namespace
} // namespace xray
} // namespace llvm