blob: 46602f7ece050329324c9ea98b9b8e429168c816 [file] [edit]
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file contains unit tests for ContiguousBlobAccumulator.
///
//===----------------------------------------------------------------------===//
#include "llvm/ObjectYAML/ContiguousBlobAccumulator.h"
#include "llvm/ObjectYAML/YAML.h"
#include "llvm/Testing/Support/Error.h"
using namespace llvm;
using namespace llvm::yaml;
static std::string getData(const ContiguousBlobAccumulator &CBA) {
SmallString<16> Data;
raw_svector_ostream OS(Data);
CBA.writeBlobToStream(OS);
return std::string(OS.str());
}
TEST(ContiguousBlobAccumulatorTest, Normal) {
constexpr uint64_t BaseOffset = 4;
ContiguousBlobAccumulator CBA(BaseOffset, /*SizeLimit=*/64);
EXPECT_EQ(CBA.tell(), 0u);
EXPECT_EQ(CBA.getOffset(), BaseOffset);
raw_ostream *OS = CBA.getRawOS(1);
ASSERT_NE(OS, nullptr);
*OS << 'a';
CBA.write("bc", 2);
CBA.write(static_cast<unsigned char>('d'));
CBA.writeZeros(1);
CBA.write(static_cast<uint16_t>(0x1234), llvm::endianness::big);
CBA.write(static_cast<uint16_t>(0x5678), llvm::endianness::little);
BinaryRef Bin("333435");
CBA.writeAsBinary(Bin, 2);
EXPECT_EQ(CBA.tell(), 11u);
EXPECT_EQ(CBA.padToAlignment(8), 16u);
EXPECT_EQ(CBA.tell(), 12u);
EXPECT_EQ(CBA.writeULEB128(0x7f), 1u);
EXPECT_EQ(CBA.writeSLEB128(-2), 1u);
const std::string ExpectedBeforeUpdate = {'a', 'b', 'c', 'd', '\0',
0x12, 0x34, 0x78, 0x56, 0x33,
0x34, '\0', 0x7f, 0x7e};
EXPECT_EQ(getData(CBA), ExpectedBeforeUpdate);
CBA.updateDataAt(/*Pos=*/BaseOffset, "ABCD", 4);
CBA.updateDataAt(/*Pos=*/BaseOffset + 5, static_cast<uint16_t>(0x3536),
llvm::endianness::little);
CBA.updateDataAt(/*Pos=*/BaseOffset + 7, static_cast<uint16_t>(0x3738),
llvm::endianness::big);
const std::string ExpectedAfterUpdate = {'A', 'B', 'C', 'D', '\0',
0x36, 0x35, 0x37, 0x38, 0x33,
0x34, '\0', 0x7f, 0x7e};
EXPECT_EQ(CBA.getOffset(), BaseOffset + ExpectedAfterUpdate.size());
EXPECT_EQ(getData(CBA), ExpectedAfterUpdate);
EXPECT_THAT_ERROR(CBA.takeLimitError(), Succeeded());
}
TEST(ContiguousBlobAccumulatorTest, ReachedLimit) {
constexpr uint64_t BaseOffset = 0, SizeLimit = 4;
ContiguousBlobAccumulator CBA(BaseOffset, SizeLimit);
CBA.write("abcd", SizeLimit);
EXPECT_EQ(CBA.getOffset(), BaseOffset + SizeLimit);
// Trigger the size limit error so the out-of-bounds update below is ignored.
CBA.write("e", 1);
CBA.updateDataAt(/*Pos=*/BaseOffset + 1, "XY", 2);
CBA.updateDataAt(/*Pos=*/BaseOffset + SizeLimit, "Z", 1);
EXPECT_EQ(getData(CBA), "aXYd");
EXPECT_THAT_ERROR(CBA.takeLimitError(),
FailedWithMessage("reached the output size limit"));
}