|
| 1 | +// A Luban system says what it is (xlings design 2026-10-21 §3.7, J5): its |
| 2 | +// root is declared (os-release ID=luban and /usr/lib/xlings-abi), so its |
| 3 | +// compiler's sysroot `/` is not foreign there; and its store is the home its |
| 4 | +// root record names, which `[xlings] upstream = ["/xlings"]` means for a |
| 5 | +// system made on a host (whose home is not at /xlings). |
| 6 | + |
| 7 | +#include <gtest/gtest.h> |
| 8 | + |
| 9 | +import std; |
| 10 | +import mcpp.provider; |
| 11 | +import mcpp.provider.select; |
| 12 | +import mcpp.fallback.probe_sysroot; |
| 13 | + |
| 14 | +namespace fs = std::filesystem; |
| 15 | + |
| 16 | +namespace { |
| 17 | + |
| 18 | +struct Tree { |
| 19 | + fs::path dir; |
| 20 | + Tree() { |
| 21 | + dir = fs::temp_directory_path() / std::format("mcpp-luban-root-{}-{}", ::testing::UnitTest::GetInstance()->random_seed(), |
| 22 | + std::chrono::steady_clock::now().time_since_epoch().count()); |
| 23 | + fs::create_directories(dir); |
| 24 | + } |
| 25 | + ~Tree() { std::error_code ec; fs::remove_all(dir, ec); } |
| 26 | + void write(const fs::path& rel, std::string_view text) const { |
| 27 | + fs::create_directories((dir / rel).parent_path()); |
| 28 | + std::ofstream(dir / rel) << text; |
| 29 | + } |
| 30 | +}; |
| 31 | + |
| 32 | +} // namespace |
| 33 | + |
| 34 | +TEST(LubanRoot, ALubanSystemsRootIsDeclared) { |
| 35 | + Tree t; |
| 36 | + EXPECT_FALSE(mcpp::provider::layout().declared_system_root(t.dir)); |
| 37 | + t.write("etc/os-release", "NAME=\"Luban\"\nID=luban\nVERSION_ID=2026.10.22.1\n"); |
| 38 | + EXPECT_FALSE(mcpp::provider::layout().declared_system_root(t.dir)) << "its os-release alone is not enough"; |
| 39 | + t.write("usr/lib/xlings-abi/README", ""); |
| 40 | + EXPECT_TRUE(mcpp::provider::layout().declared_system_root(t.dir)); |
| 41 | + t.write("etc/os-release", "ID=\"debian\"\n"); |
| 42 | + EXPECT_FALSE(mcpp::provider::layout().declared_system_root(t.dir)); |
| 43 | +} |
| 44 | + |
| 45 | +TEST(LubanRoot, ItsSysrootSlashIsNotForeign) { |
| 46 | + Tree t; |
| 47 | + const fs::path registry = "/home/u/.mcpp/registry", project = "/home/u/work/demo"; |
| 48 | + EXPECT_TRUE(mcpp::fallback::sysroot_is_foreign("/", registry, project, t.dir)) << "anywhere else, / is nothing declared"; |
| 49 | + t.write("etc/os-release", "ID=luban\n"); |
| 50 | + t.write("usr/lib/xlings-abi/README", ""); |
| 51 | + EXPECT_FALSE(mcpp::fallback::sysroot_is_foreign("/", registry, project, t.dir)); |
| 52 | + EXPECT_TRUE(mcpp::fallback::sysroot_is_foreign("/opt/other/sysroot", registry, project, t.dir)) << "only its own root"; |
| 53 | +} |
| 54 | + |
| 55 | +TEST(LubanRoot, ItsStoreIsTheHomeItsRootRecordNames) { |
| 56 | + Tree t; |
| 57 | + t.write("etc/os-release", "ID=luban\n"); |
| 58 | + t.write("usr/lib/xlings-abi/README", ""); |
| 59 | + EXPECT_TRUE(mcpp::provider::layout().system_home(t.dir).empty()) << "no record"; |
| 60 | + const auto home = t.dir / "host-home"; |
| 61 | + fs::create_directories(home / "subos" / "box" / "root" / "usr"); |
| 62 | + t.write("etc/xlings/usr", (home / "subos" / "box" / "root" / "usr").string() + "\n"); |
| 63 | + EXPECT_EQ(mcpp::provider::layout().system_home(t.dir), home.lexically_normal()); |
| 64 | + t.write("etc/xlings/usr", "/somewhere/else/usr\n"); |
| 65 | + EXPECT_TRUE(mcpp::provider::layout().system_home(t.dir).empty()) << "a record of another shape"; |
| 66 | +} |
0 commit comments