busybox_info_test.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "toolchain/install/busybox_info.h"
  5. #include <gmock/gmock.h>
  6. #include <gtest/gtest.h>
  7. #include <cstdlib>
  8. #include <fstream>
  9. #include "common/check.h"
  10. namespace Carbon {
  11. namespace {
  12. using ::testing::Eq;
  13. class BusyboxInfoTest : public ::testing::Test {
  14. public:
  15. // Set up a temp directory for the test case.
  16. explicit BusyboxInfoTest() {
  17. const char* tmpdir = std::getenv("TEST_TMPDIR");
  18. CARBON_CHECK(tmpdir);
  19. dir_ = MakeDir(std::filesystem::absolute(
  20. std::filesystem::path(tmpdir) /
  21. ::testing::UnitTest::GetInstance()->current_test_info()->name()));
  22. }
  23. // Delete the test case's temp directory.
  24. ~BusyboxInfoTest() override {
  25. std::error_code ec;
  26. std::filesystem::remove_all(dir_, ec);
  27. CARBON_CHECK(!ec, "error removing {0}: {1}", dir_, ec.message());
  28. }
  29. // Creates a stub file. Returns the input file for easier use.
  30. auto MakeFile(std::filesystem::path file) -> std::filesystem::path {
  31. std::ofstream out(file.c_str());
  32. out << "stub";
  33. CARBON_CHECK(out, "error creating {0}", file);
  34. return file;
  35. }
  36. // Creates a symlink to the target. Returns the input file for easier use.
  37. auto MakeSymlink(std::filesystem::path file, auto target)
  38. -> std::filesystem::path {
  39. std::error_code ec;
  40. std::filesystem::create_symlink(target, file, ec);
  41. CARBON_CHECK(!ec, "error creating {0}: {1}", file, ec.message());
  42. return file;
  43. }
  44. // Creates a directory. Returns the input file for easier use.
  45. auto MakeDir(std::filesystem::path dir) -> std::filesystem::path {
  46. std::error_code ec;
  47. std::filesystem::create_directory(dir, ec);
  48. CARBON_CHECK(!ec, "error creating {0}: {1}", dir, ec.message());
  49. return dir;
  50. }
  51. // The test's temp directory, deleted on destruction.
  52. std::filesystem::path dir_;
  53. };
  54. TEST_F(BusyboxInfoTest, Direct) {
  55. auto busybox = MakeFile(dir_ / "carbon-busybox");
  56. auto info = GetBusyboxInfo(busybox.string());
  57. ASSERT_TRUE(info.ok()) << info.error();
  58. EXPECT_THAT(info->bin_path, Eq(busybox));
  59. EXPECT_THAT(info->mode, Eq(std::nullopt));
  60. }
  61. TEST_F(BusyboxInfoTest, SymlinkInCurrentDirectory) {
  62. MakeFile(dir_ / "carbon-busybox");
  63. auto target = MakeSymlink(dir_ / "carbon", "carbon-busybox");
  64. auto info = GetBusyboxInfo(target.string());
  65. ASSERT_TRUE(info.ok()) << info.error();
  66. EXPECT_THAT(info->bin_path, Eq(dir_ / "carbon-busybox"));
  67. EXPECT_THAT(info->mode, Eq("carbon"));
  68. }
  69. TEST_F(BusyboxInfoTest, SymlinkInCurrentDirectoryWithDot) {
  70. MakeFile(dir_ / "carbon-busybox");
  71. auto target = MakeSymlink(dir_ / "carbon", "./carbon-busybox");
  72. auto info = GetBusyboxInfo(target.string());
  73. ASSERT_TRUE(info.ok()) << info.error();
  74. EXPECT_THAT(info->bin_path, Eq(dir_ / "./carbon-busybox"));
  75. EXPECT_THAT(info->mode, Eq("carbon"));
  76. }
  77. TEST_F(BusyboxInfoTest, ExtraSymlink) {
  78. MakeFile(dir_ / "carbon-busybox");
  79. MakeSymlink(dir_ / "carbon", "carbon-busybox");
  80. auto target = MakeSymlink(dir_ / "c", "carbon");
  81. auto info = GetBusyboxInfo(target.string());
  82. ASSERT_TRUE(info.ok()) << info.error();
  83. EXPECT_THAT(info->bin_path, Eq(dir_ / "carbon-busybox"));
  84. EXPECT_THAT(info->mode, Eq("carbon"));
  85. }
  86. TEST_F(BusyboxInfoTest, BusyboxIsSymlink) {
  87. MakeFile(dir_ / "actual-busybox");
  88. auto target = MakeSymlink(dir_ / "carbon-busybox", "actual-busybox");
  89. auto info = GetBusyboxInfo(target.string());
  90. ASSERT_TRUE(info.ok()) << info.error();
  91. EXPECT_THAT(info->bin_path, Eq(target));
  92. EXPECT_THAT(info->mode, Eq(std::nullopt));
  93. }
  94. TEST_F(BusyboxInfoTest, BusyboxIsSymlinkToNowhere) {
  95. auto target = MakeSymlink(dir_ / "carbon-busybox", "nonexistent");
  96. auto info = GetBusyboxInfo(target.string());
  97. ASSERT_TRUE(info.ok()) << info.error();
  98. EXPECT_THAT(info->bin_path, Eq(dir_ / "carbon-busybox"));
  99. EXPECT_THAT(info->mode, Eq(std::nullopt));
  100. }
  101. TEST_F(BusyboxInfoTest, RelativeSymlink) {
  102. MakeDir(dir_ / "lib");
  103. MakeDir(dir_ / "lib/carbon");
  104. MakeFile(dir_ / "lib/carbon/carbon-busybox");
  105. MakeDir(dir_ / "bin");
  106. auto target =
  107. MakeSymlink(dir_ / "bin/carbon", "../lib/carbon/carbon-busybox");
  108. auto info = GetBusyboxInfo(target.string());
  109. ASSERT_TRUE(info.ok()) << info.error();
  110. EXPECT_THAT(info->bin_path, Eq(dir_ / "bin/../lib/carbon/carbon-busybox"));
  111. EXPECT_THAT(info->mode, Eq("carbon"));
  112. }
  113. TEST_F(BusyboxInfoTest, AbsoluteSymlink) {
  114. MakeDir(dir_ / "lib");
  115. MakeDir(dir_ / "lib/carbon");
  116. auto busybox = MakeFile(dir_ / "lib/carbon/carbon-busybox");
  117. ASSERT_TRUE(busybox.is_absolute());
  118. MakeDir(dir_ / "bin");
  119. auto target = MakeSymlink(dir_ / "bin/carbon", busybox);
  120. auto info = GetBusyboxInfo(target.string());
  121. ASSERT_TRUE(info.ok()) << info.error();
  122. EXPECT_THAT(info->bin_path, Eq(busybox));
  123. EXPECT_THAT(info->mode, Eq("carbon"));
  124. }
  125. TEST_F(BusyboxInfoTest, NotBusyboxFile) {
  126. auto target = MakeFile(dir_ / "file");
  127. auto info = GetBusyboxInfo(target.string());
  128. EXPECT_FALSE(info.ok());
  129. }
  130. TEST_F(BusyboxInfoTest, NotBusyboxSymlink) {
  131. MakeFile(dir_ / "file");
  132. auto target = MakeSymlink(dir_ / "carbon", "file");
  133. auto info = GetBusyboxInfo(target.string());
  134. EXPECT_FALSE(info.ok());
  135. }
  136. } // namespace
  137. } // namespace Carbon