From f2bcebc4503c72ba8ad0406058db31a4f883ad0b Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 22 May 2024 23:12:23 -0400 Subject: [PATCH] Restore exposing machine file parsing This was accidentally removed in e989c83b44d7c4d8ffe2e5f4231e4861c5f7732f. I restored it and also did a few other cleanups: - Make a static method for namespacing purposes - Put the test files in the data dir with the other test data - Avoid mutating globals in the machine config tests This will be used by Hydra. --- src/libstore/machines.cc | 19 ++-- src/libstore/machines.hh | 22 ++++- .../machines/bad_format} | 0 .../machines.valid => data/machines/valid} | 0 tests/unit/libstore/machines.cc | 88 ++++++++----------- .../libutil-support/tests/characterization.hh | 4 +- 6 files changed, 72 insertions(+), 61 deletions(-) rename tests/unit/libstore/{test-data/machines.bad_format => data/machines/bad_format} (100%) rename tests/unit/libstore/{test-data/machines.valid => data/machines/valid} (100%) diff --git a/src/libstore/machines.cc b/src/libstore/machines.cc index 644762242..b4df658b1 100644 --- a/src/libstore/machines.cc +++ b/src/libstore/machines.cc @@ -131,7 +131,7 @@ static std::vector expandBuilderLines(const std::string & builders) return result; } -static Machine parseBuilderLine(const std::string & line) +static Machine parseBuilderLine(const std::set & defaultSystems, const std::string & line) { const auto tokens = tokenizeString>(line); @@ -170,7 +170,7 @@ static Machine parseBuilderLine(const std::string & line) return { tokens[0], - isSet(1) ? tokenizeString>(tokens[1], ",") : std::set{settings.thisSystem}, + isSet(1) ? tokenizeString>(tokens[1], ",") : defaultSystems, isSet(2) ? tokens[2] : "", isSet(3) ? parseUnsignedIntField(3) : 1U, isSet(4) ? parseFloatField(4) : 1.0f, @@ -180,17 +180,24 @@ static Machine parseBuilderLine(const std::string & line) }; } -static Machines parseBuilderLines(const std::vector & builders) +static Machines parseBuilderLines(const std::set & defaultSystems, const std::vector & builders) { Machines result; - std::transform(builders.begin(), builders.end(), std::back_inserter(result), parseBuilderLine); + std::transform( + builders.begin(), builders.end(), std::back_inserter(result), + [&](auto && line) { return parseBuilderLine(defaultSystems, line); }); return result; } +Machines Machine::parseConfig(const std::set & defaultSystems, const std::string & s) +{ + const auto builderLines = expandBuilderLines(s); + return parseBuilderLines(defaultSystems, builderLines); +} + Machines getMachines() { - const auto builderLines = expandBuilderLines(settings.builders); - return parseBuilderLines(builderLines); + return Machine::parseConfig({settings.thisSystem}, settings.builders); } } diff --git a/src/libstore/machines.hh b/src/libstore/machines.hh index 97980df8d..2a55c4456 100644 --- a/src/libstore/machines.hh +++ b/src/libstore/machines.hh @@ -8,6 +8,10 @@ namespace nix { class Store; +struct Machine; + +typedef std::vector Machines; + struct Machine { const StoreReference storeUri; @@ -63,12 +67,22 @@ struct Machine { * ``` */ ref openStore() const; + + /** + * Parse a machine configuration. + * + * Every machine is specified on its own line, and lines beginning + * with `@` are interpreted as paths to other configuration files in + * the same format. + */ + static Machines parseConfig(const std::set & defaultSystems, const std::string & config); }; -typedef std::vector Machines; - -void parseMachines(const std::string & s, Machines & machines); - +/** + * Parse machines from the global config + * + * @todo Remove, globals are bad. + */ Machines getMachines(); } diff --git a/tests/unit/libstore/test-data/machines.bad_format b/tests/unit/libstore/data/machines/bad_format similarity index 100% rename from tests/unit/libstore/test-data/machines.bad_format rename to tests/unit/libstore/data/machines/bad_format diff --git a/tests/unit/libstore/test-data/machines.valid b/tests/unit/libstore/data/machines/valid similarity index 100% rename from tests/unit/libstore/test-data/machines.valid rename to tests/unit/libstore/data/machines/valid diff --git a/tests/unit/libstore/machines.cc b/tests/unit/libstore/machines.cc index 4107ba655..2307f4d62 100644 --- a/tests/unit/libstore/machines.cc +++ b/tests/unit/libstore/machines.cc @@ -1,8 +1,9 @@ #include "machines.hh" -#include "globals.hh" #include "file-system.hh" #include "util.hh" +#include "tests/characterization.hh" + #include #include @@ -14,23 +15,13 @@ using testing::SizeIs; using namespace nix; -class Environment : public ::testing::Environment { - public: - void SetUp() override { settings.thisSystem = "TEST_ARCH-TEST_OS"; } -}; - -testing::Environment* const foo_env = - testing::AddGlobalTestEnvironment(new Environment); - TEST(machines, getMachinesWithEmptyBuilders) { - settings.builders = ""; - Machines actual = getMachines(); + auto actual = Machine::parseConfig({}, ""); ASSERT_THAT(actual, SizeIs(0)); } TEST(machines, getMachinesUriOnly) { - settings.builders = "nix@scratchy.labs.cs.uu.nl"; - Machines actual = getMachines(); + auto actual = Machine::parseConfig({"TEST_ARCH-TEST_OS"}, "nix@scratchy.labs.cs.uu.nl"); ASSERT_THAT(actual, SizeIs(1)); EXPECT_THAT(actual[0], Field(&Machine::storeUri, Eq(StoreReference::parse("ssh://nix@scratchy.labs.cs.uu.nl")))); EXPECT_THAT(actual[0], Field(&Machine::systemTypes, ElementsAre("TEST_ARCH-TEST_OS"))); @@ -43,8 +34,7 @@ TEST(machines, getMachinesUriOnly) { } TEST(machines, getMachinesDefaults) { - settings.builders = "nix@scratchy.labs.cs.uu.nl - - - - - - -"; - Machines actual = getMachines(); + auto actual = Machine::parseConfig({"TEST_ARCH-TEST_OS"}, "nix@scratchy.labs.cs.uu.nl - - - - - - -"); ASSERT_THAT(actual, SizeIs(1)); EXPECT_THAT(actual[0], Field(&Machine::storeUri, Eq(StoreReference::parse("ssh://nix@scratchy.labs.cs.uu.nl")))); EXPECT_THAT(actual[0], Field(&Machine::systemTypes, ElementsAre("TEST_ARCH-TEST_OS"))); @@ -68,26 +58,24 @@ MATCHER_P(AuthorityMatches, authority, "") { } TEST(machines, getMachinesWithNewLineSeparator) { - settings.builders = "nix@scratchy.labs.cs.uu.nl\nnix@itchy.labs.cs.uu.nl"; - Machines actual = getMachines(); + auto actual = Machine::parseConfig({}, "nix@scratchy.labs.cs.uu.nl\nnix@itchy.labs.cs.uu.nl"); ASSERT_THAT(actual, SizeIs(2)); EXPECT_THAT(actual, Contains(Field(&Machine::storeUri, AuthorityMatches("nix@scratchy.labs.cs.uu.nl")))); EXPECT_THAT(actual, Contains(Field(&Machine::storeUri, AuthorityMatches("nix@itchy.labs.cs.uu.nl")))); } TEST(machines, getMachinesWithSemicolonSeparator) { - settings.builders = "nix@scratchy.labs.cs.uu.nl ; nix@itchy.labs.cs.uu.nl"; - Machines actual = getMachines(); + auto actual = Machine::parseConfig({}, "nix@scratchy.labs.cs.uu.nl ; nix@itchy.labs.cs.uu.nl"); EXPECT_THAT(actual, SizeIs(2)); EXPECT_THAT(actual, Contains(Field(&Machine::storeUri, AuthorityMatches("nix@scratchy.labs.cs.uu.nl")))); EXPECT_THAT(actual, Contains(Field(&Machine::storeUri, AuthorityMatches("nix@itchy.labs.cs.uu.nl")))); } TEST(machines, getMachinesWithCorrectCompleteSingleBuilder) { - settings.builders = "nix@scratchy.labs.cs.uu.nl i686-linux " - "/home/nix/.ssh/id_scratchy_auto 8 3 kvm " - "benchmark SSH+HOST+PUBLIC+KEY+BASE64+ENCODED=="; - Machines actual = getMachines(); + auto actual = Machine::parseConfig({}, + "nix@scratchy.labs.cs.uu.nl i686-linux " + "/home/nix/.ssh/id_scratchy_auto 8 3 kvm " + "benchmark SSH+HOST+PUBLIC+KEY+BASE64+ENCODED=="); ASSERT_THAT(actual, SizeIs(1)); EXPECT_THAT(actual[0], Field(&Machine::storeUri, AuthorityMatches("nix@scratchy.labs.cs.uu.nl"))); EXPECT_THAT(actual[0], Field(&Machine::systemTypes, ElementsAre("i686-linux"))); @@ -101,11 +89,10 @@ TEST(machines, getMachinesWithCorrectCompleteSingleBuilder) { TEST(machines, getMachinesWithCorrectCompleteSingleBuilderWithTabColumnDelimiter) { - settings.builders = + auto actual = Machine::parseConfig({}, "nix@scratchy.labs.cs.uu.nl\ti686-linux\t/home/nix/.ssh/" "id_scratchy_auto\t8\t3\tkvm\tbenchmark\tSSH+HOST+PUBLIC+" - "KEY+BASE64+ENCODED=="; - Machines actual = getMachines(); + "KEY+BASE64+ENCODED=="); ASSERT_THAT(actual, SizeIs(1)); EXPECT_THAT(actual[0], Field(&Machine::storeUri, AuthorityMatches("nix@scratchy.labs.cs.uu.nl"))); EXPECT_THAT(actual[0], Field(&Machine::systemTypes, ElementsAre("i686-linux"))); @@ -118,10 +105,10 @@ TEST(machines, } TEST(machines, getMachinesWithMultiOptions) { - settings.builders = "nix@scratchy.labs.cs.uu.nl Arch1,Arch2 - - - " - "SupportedFeature1,SupportedFeature2 " - "MandatoryFeature1,MandatoryFeature2"; - Machines actual = getMachines(); + auto actual = Machine::parseConfig({}, + "nix@scratchy.labs.cs.uu.nl Arch1,Arch2 - - - " + "SupportedFeature1,SupportedFeature2 " + "MandatoryFeature1,MandatoryFeature2"); ASSERT_THAT(actual, SizeIs(1)); EXPECT_THAT(actual[0], Field(&Machine::storeUri, AuthorityMatches("nix@scratchy.labs.cs.uu.nl"))); EXPECT_THAT(actual[0], Field(&Machine::systemTypes, ElementsAre("Arch1", "Arch2"))); @@ -130,24 +117,28 @@ TEST(machines, getMachinesWithMultiOptions) { } TEST(machines, getMachinesWithIncorrectFormat) { - settings.builders = "nix@scratchy.labs.cs.uu.nl - - eight"; - EXPECT_THROW(getMachines(), FormatError); - settings.builders = "nix@scratchy.labs.cs.uu.nl - - -1"; - EXPECT_THROW(getMachines(), FormatError); - settings.builders = "nix@scratchy.labs.cs.uu.nl - - 8 three"; - EXPECT_THROW(getMachines(), FormatError); - settings.builders = "nix@scratchy.labs.cs.uu.nl - - 8 -3"; - EXPECT_THROW(getMachines(), UsageError); - settings.builders = "nix@scratchy.labs.cs.uu.nl - - 8 3 - - BAD_BASE64"; - EXPECT_THROW(getMachines(), FormatError); + EXPECT_THROW( + Machine::parseConfig({}, "nix@scratchy.labs.cs.uu.nl - - eight"), + FormatError); + EXPECT_THROW( + Machine::parseConfig({}, "nix@scratchy.labs.cs.uu.nl - - -1"), + FormatError); + EXPECT_THROW( + Machine::parseConfig({}, "nix@scratchy.labs.cs.uu.nl - - 8 three"), + FormatError); + EXPECT_THROW( + Machine::parseConfig({}, "nix@scratchy.labs.cs.uu.nl - - 8 -3"), + UsageError); + EXPECT_THROW( + Machine::parseConfig({}, "nix@scratchy.labs.cs.uu.nl - - 8 3 - - BAD_BASE64"), + FormatError); } TEST(machines, getMachinesWithCorrectFileReference) { - auto path = absPath("tests/unit/libstore/test-data/machines.valid"); + auto path = absPath(getUnitTestData() + "/machines/valid"); ASSERT_TRUE(pathExists(path)); - settings.builders = std::string("@") + path; - Machines actual = getMachines(); + auto actual = Machine::parseConfig({}, "@" + path); ASSERT_THAT(actual, SizeIs(3)); EXPECT_THAT(actual, Contains(Field(&Machine::storeUri, AuthorityMatches("nix@scratchy.labs.cs.uu.nl")))); EXPECT_THAT(actual, Contains(Field(&Machine::storeUri, AuthorityMatches("nix@itchy.labs.cs.uu.nl")))); @@ -158,18 +149,17 @@ TEST(machines, getMachinesWithCorrectFileReferenceToEmptyFile) { auto path = "/dev/null"; ASSERT_TRUE(pathExists(path)); - settings.builders = std::string("@") + path; - Machines actual = getMachines(); + auto actual = Machine::parseConfig({}, std::string{"@"} + path); ASSERT_THAT(actual, SizeIs(0)); } TEST(machines, getMachinesWithIncorrectFileReference) { - settings.builders = std::string("@") + absPath("/not/a/file"); - Machines actual = getMachines(); + auto actual = Machine::parseConfig({}, "@" + absPath("/not/a/file")); ASSERT_THAT(actual, SizeIs(0)); } TEST(machines, getMachinesWithCorrectFileReferenceToIncorrectFile) { - settings.builders = std::string("@") + absPath("tests/unit/libstore/test-data/machines.bad_format"); - EXPECT_THROW(getMachines(), FormatError); + EXPECT_THROW( + Machine::parseConfig({}, "@" + absPath(getUnitTestData() + "/machines/bad_format")), + FormatError); } diff --git a/tests/unit/libutil-support/tests/characterization.hh b/tests/unit/libutil-support/tests/characterization.hh index 9d6c850f0..c2f686dbf 100644 --- a/tests/unit/libutil-support/tests/characterization.hh +++ b/tests/unit/libutil-support/tests/characterization.hh @@ -12,7 +12,7 @@ namespace nix { * The path to the unit test data directory. See the contributing guide * in the manual for further details. */ -static Path getUnitTestData() { +static inline Path getUnitTestData() { return getEnv("_NIX_TEST_UNIT_DATA").value(); } @@ -21,7 +21,7 @@ static Path getUnitTestData() { * against them. See the contributing guide in the manual for further * details. */ -static bool testAccept() { +static inline bool testAccept() { return getEnv("_NIX_TEST_ACCEPT") == "1"; }