FileOutputBufferTest.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. //===- llvm/unittest/Support/FileOutputBuffer.cpp - unit tests ------------===//
  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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/Support/FileOutputBuffer.h"
  9. #include "llvm/Support/Errc.h"
  10. #include "llvm/Support/ErrorHandling.h"
  11. #include "llvm/Support/FileSystem.h"
  12. #include "llvm/Support/MemoryBuffer.h"
  13. #include "llvm/Support/Path.h"
  14. #include "llvm/Support/raw_ostream.h"
  15. #include "gtest/gtest.h"
  16. using namespace llvm;
  17. using namespace llvm::sys;
  18. #define ASSERT_NO_ERROR(x) \
  19. if (std::error_code ASSERT_NO_ERROR_ec = x) { \
  20. SmallString<128> MessageStorage; \
  21. raw_svector_ostream Message(MessageStorage); \
  22. Message << #x ": did not return errc::success.\n" \
  23. << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \
  24. << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \
  25. GTEST_FATAL_FAILURE_(MessageStorage.c_str()); \
  26. } else { \
  27. }
  28. namespace {
  29. TEST(FileOutputBuffer, Test) {
  30. // Create unique temporary directory for these tests
  31. SmallString<128> TestDirectory;
  32. {
  33. ASSERT_NO_ERROR(
  34. fs::createUniqueDirectory("FileOutputBuffer-test", TestDirectory));
  35. }
  36. // TEST 1: Verify commit case.
  37. SmallString<128> File1(TestDirectory);
  38. File1.append("/file1");
  39. {
  40. Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
  41. FileOutputBuffer::create(File1, 8192);
  42. ASSERT_NO_ERROR(errorToErrorCode(BufferOrErr.takeError()));
  43. std::unique_ptr<FileOutputBuffer> &Buffer = *BufferOrErr;
  44. // Start buffer with special header.
  45. memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20);
  46. // Write to end of buffer to verify it is writable.
  47. memcpy(Buffer->getBufferEnd() - 20, "AABBCCDDEEFFGGHHIIJJ", 20);
  48. // Commit buffer.
  49. ASSERT_NO_ERROR(errorToErrorCode(Buffer->commit()));
  50. }
  51. // Verify file is correct size.
  52. uint64_t File1Size;
  53. ASSERT_NO_ERROR(fs::file_size(Twine(File1), File1Size));
  54. ASSERT_EQ(File1Size, 8192ULL);
  55. ASSERT_NO_ERROR(fs::remove(File1.str()));
  56. // TEST 2: Verify abort case.
  57. SmallString<128> File2(TestDirectory);
  58. File2.append("/file2");
  59. {
  60. Expected<std::unique_ptr<FileOutputBuffer>> Buffer2OrErr =
  61. FileOutputBuffer::create(File2, 8192);
  62. ASSERT_NO_ERROR(errorToErrorCode(Buffer2OrErr.takeError()));
  63. std::unique_ptr<FileOutputBuffer> &Buffer2 = *Buffer2OrErr;
  64. // Fill buffer with special header.
  65. memcpy(Buffer2->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20);
  66. // Do *not* commit buffer.
  67. }
  68. // Verify file does not exist (because buffer not committed).
  69. ASSERT_EQ(fs::access(Twine(File2), fs::AccessMode::Exist),
  70. errc::no_such_file_or_directory);
  71. ASSERT_NO_ERROR(fs::remove(File2.str()));
  72. // TEST 3: Verify sizing down case.
  73. SmallString<128> File3(TestDirectory);
  74. File3.append("/file3");
  75. {
  76. Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
  77. FileOutputBuffer::create(File3, 8192000);
  78. ASSERT_NO_ERROR(errorToErrorCode(BufferOrErr.takeError()));
  79. std::unique_ptr<FileOutputBuffer> &Buffer = *BufferOrErr;
  80. // Start buffer with special header.
  81. memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20);
  82. // Write to end of buffer to verify it is writable.
  83. memcpy(Buffer->getBufferEnd() - 20, "AABBCCDDEEFFGGHHIIJJ", 20);
  84. ASSERT_NO_ERROR(errorToErrorCode(Buffer->commit()));
  85. }
  86. // Verify file is correct size.
  87. uint64_t File3Size;
  88. ASSERT_NO_ERROR(fs::file_size(Twine(File3), File3Size));
  89. ASSERT_EQ(File3Size, 8192000ULL);
  90. ASSERT_NO_ERROR(fs::remove(File3.str()));
  91. // TEST 4: Verify file can be made executable.
  92. SmallString<128> File4(TestDirectory);
  93. File4.append("/file4");
  94. {
  95. Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
  96. FileOutputBuffer::create(File4, 8192, FileOutputBuffer::F_executable);
  97. ASSERT_NO_ERROR(errorToErrorCode(BufferOrErr.takeError()));
  98. std::unique_ptr<FileOutputBuffer> &Buffer = *BufferOrErr;
  99. // Start buffer with special header.
  100. memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20);
  101. // Commit buffer.
  102. ASSERT_NO_ERROR(errorToErrorCode(Buffer->commit()));
  103. }
  104. // Verify file exists and is executable.
  105. fs::file_status Status;
  106. ASSERT_NO_ERROR(fs::status(Twine(File4), Status));
  107. bool IsExecutable = (Status.permissions() & fs::owner_exe);
  108. EXPECT_TRUE(IsExecutable);
  109. ASSERT_NO_ERROR(fs::remove(File4.str()));
  110. // Clean up.
  111. ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
  112. }
  113. } // anonymous namespace