brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.5 KiB · 10a0cd9 Raw
148 lines · cpp
1//===----------------------------------------------------------------------===//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#include "llvm/Support/VirtualOutputBackend.h"10#include "llvm/Testing/Support/Error.h"11#include "gtest/gtest.h"12 13using namespace llvm;14using namespace llvm::vfs;15 16namespace {17 18struct MockOutputBackendData {19  int Cloned = 0;20  int FilesCreated = 0;21  std::optional<OutputConfig> LastConfig;22  unique_function<Error()> FileCreator;23};24 25struct MockOutputBackend final : public OutputBackend {26  struct MockFile final : public OutputFileImpl {27    Error keep() override { return Error::success(); }28    Error discard() override { return Error::success(); }29    raw_pwrite_stream &getOS() override { return OS; }30    raw_null_ostream OS;31  };32 33  IntrusiveRefCntPtr<OutputBackend> cloneImpl() const override {34    ++Data.Cloned;35    return const_cast<MockOutputBackend *>(this);36  }37 38  Expected<std::unique_ptr<OutputFileImpl>>39  createFileImpl(StringRef, std::optional<OutputConfig> Config) override {40    ++Data.FilesCreated;41    Data.LastConfig = Config;42    if (Data.FileCreator)43      return Data.FileCreator();44    return std::make_unique<MockFile>();45  }46 47  Expected<OutputFile>48  createAutoDiscardFile(const Twine &OutputPath,49                        std::optional<OutputConfig> Config = std::nullopt) {50    return consumeDiscardOnDestroy(createFile(OutputPath, Config));51  }52 53  MockOutputBackend(MockOutputBackendData &Data) : Data(Data) {}54  MockOutputBackendData &Data;55};56 57static IntrusiveRefCntPtr<MockOutputBackend>58createMockBackend(MockOutputBackendData &Data) {59  return makeIntrusiveRefCnt<MockOutputBackend>(Data);60}61 62static Error createCustomError() {63  return createStringError(inconvertibleErrorCode(), "custom error");64}65 66TEST(VirtualOutputBackendTest, construct) {67  MockOutputBackendData Data;68  auto B = createMockBackend(Data);69  EXPECT_EQ(0, Data.Cloned);70  EXPECT_EQ(0, Data.FilesCreated);71}72 73TEST(VirtualOutputBackendTest, clone) {74  MockOutputBackendData Data;75  auto Backend = createMockBackend(Data);76  auto Clone = Backend->clone();77  EXPECT_EQ(1, Data.Cloned);78 79  // Confirm the clone matches what the mock's cloneImpl() does.80  EXPECT_EQ(Backend.get(), Clone.get());81 82  // Make another clone.83  Backend->clone();84  EXPECT_EQ(2, Data.Cloned);85}86 87TEST(VirtualOutputBackendTest, createFile) {88  MockOutputBackendData Data;89  auto Backend = createMockBackend(Data);90 91  StringRef FilePath = "dir/file";92  OutputFile F;93  EXPECT_THAT_ERROR(Backend->createFile(Twine(FilePath)).moveInto(F),94                    Succeeded());95  EXPECT_EQ(1, Data.FilesCreated);96  EXPECT_EQ(FilePath, F.getPath());97  EXPECT_EQ(std::nullopt, Data.LastConfig);98 99  // Confirm OutputBackend has not installed a discard handler.100#if GTEST_HAS_DEATH_TEST101  EXPECT_DEATH(F = OutputFile(), "output not closed");102#endif103  consumeError(F.discard());104 105  // Create more files and specify configs.106  for (OutputConfig Config : {107           OutputConfig(),108           OutputConfig().setNoAtomicWrite().setDiscardOnSignal(),109           OutputConfig().setAtomicWrite().setNoDiscardOnSignal(),110           OutputConfig().setText(),111           OutputConfig().setTextWithCRLF(),112       }) {113    int CreatedAlready = Data.FilesCreated;114    EXPECT_THAT_ERROR(115        Backend->createAutoDiscardFile(Twine(FilePath), Config).takeError(),116        Succeeded());117    EXPECT_EQ(Config, Data.LastConfig);118    EXPECT_EQ(1 + CreatedAlready, Data.FilesCreated);119  }120}121 122TEST(VirtualOutputBackendTest, createFileInvalidConfigCRLF) {123  MockOutputBackendData Data;124  auto Backend = createMockBackend(Data);125 126  // Check that invalid configs don't make it to the backend.127  EXPECT_THAT_ERROR(128      Backend129          ->createAutoDiscardFile(Twine("dir/file"), OutputConfig().setCRLF())130          .takeError(),131      FailedWithMessage("dir/file: invalid config: {CRLF}"));132  EXPECT_EQ(0, Data.FilesCreated);133}134 135TEST(VirtualOutputBackendTest, createFileError) {136  MockOutputBackendData Data;137  Data.FileCreator = createCustomError;138  auto Backend = createMockBackend(Data);139 140  // Check that invalid configs don't make it to the backend.141  EXPECT_THAT_ERROR(142      Backend->createAutoDiscardFile(Twine("dir/file")).takeError(),143      FailedWithMessage("custom error"));144  EXPECT_EQ(1, Data.FilesCreated);145}146 147} // end namespace148