#include #include #include #include "worker-protocol.hh" #include "worker-protocol-impl.hh" #include "derived-path.hh" #include "build-result.hh" #include "tests/protocol.hh" #include "tests/characterization.hh" namespace nix { const char workerProtoDir[] = "worker-protocol"; struct WorkerProtoTest : VersionedProtoTest { /** * For serializers that don't care about the minimum version, we * used the oldest one: 1.0. */ WorkerProto::Version defaultVersion = 1 << 8 | 0; }; VERSIONED_CHARACTERIZATION_TEST( WorkerProtoTest, string, "string", defaultVersion, (std::tuple { "", "hi", "white rabbit", "大白兔", "oh no \0\0\0 what was that!", })) VERSIONED_CHARACTERIZATION_TEST( WorkerProtoTest, storePath, "store-path", defaultVersion, (std::tuple { StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" }, StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo-bar" }, })) VERSIONED_CHARACTERIZATION_TEST( WorkerProtoTest, contentAddress, "content-address", defaultVersion, (std::tuple { ContentAddress { .method = TextIngestionMethod {}, .hash = hashString(HashType::htSHA256, "Derive(...)"), }, ContentAddress { .method = FileIngestionMethod::Flat, .hash = hashString(HashType::htSHA1, "blob blob..."), }, ContentAddress { .method = FileIngestionMethod::Recursive, .hash = hashString(HashType::htSHA256, "(...)"), }, })) VERSIONED_CHARACTERIZATION_TEST( WorkerProtoTest, derivedPath_1_29, "derived-path-1.29", 1 << 8 | 29, (std::tuple { DerivedPath::Opaque { .path = StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" }, }, DerivedPath::Built { .drvPath = makeConstantStorePathRef(StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv", }), .outputs = OutputsSpec::All { }, }, DerivedPath::Built { .drvPath = makeConstantStorePathRef(StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv", }), .outputs = OutputsSpec::Names { "x", "y" }, }, })) VERSIONED_CHARACTERIZATION_TEST( WorkerProtoTest, derivedPath_1_30, "derived-path-1.30", 1 << 8 | 30, (std::tuple { DerivedPath::Opaque { .path = StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" }, }, DerivedPath::Opaque { .path = StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv" }, }, DerivedPath::Built { .drvPath = makeConstantStorePathRef(StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv", }), .outputs = OutputsSpec::All { }, }, DerivedPath::Built { .drvPath = makeConstantStorePathRef(StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv", }), .outputs = OutputsSpec::Names { "x", "y" }, }, })) VERSIONED_CHARACTERIZATION_TEST( WorkerProtoTest, drvOutput, "drv-output", defaultVersion, (std::tuple { { .drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="), .outputName = "baz", }, DrvOutput { .drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="), .outputName = "quux", }, })) VERSIONED_CHARACTERIZATION_TEST( WorkerProtoTest, realisation, "realisation", defaultVersion, (std::tuple { Realisation { .id = DrvOutput { .drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="), .outputName = "baz", }, .outPath = StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" }, .signatures = { "asdf", "qwer" }, }, Realisation { .id = { .drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="), .outputName = "baz", }, .outPath = StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" }, .signatures = { "asdf", "qwer" }, .dependentRealisations = { { DrvOutput { .drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="), .outputName = "quux", }, StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" }, }, }, }, })) VERSIONED_CHARACTERIZATION_TEST( WorkerProtoTest, buildResult, "build-result", defaultVersion, ({ using namespace std::literals::chrono_literals; std::tuple t { BuildResult { .status = BuildResult::OutputRejected, .errorMsg = "no idea why", }, BuildResult { .status = BuildResult::NotDeterministic, .errorMsg = "no idea why", .timesBuilt = 3, .isNonDeterministic = true, .startTime = 30, .stopTime = 50, }, BuildResult { .status = BuildResult::Built, .timesBuilt = 1, .builtOutputs = { { "foo", { .id = DrvOutput { .drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="), .outputName = "foo", }, .outPath = StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" }, }, }, { "bar", { .id = DrvOutput { .drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="), .outputName = "bar", }, .outPath = StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar" }, }, }, }, .startTime = 30, .stopTime = 50, #if 0 // These fields are not yet serialized. // FIXME Include in next version of protocol or document // why they are skipped. .cpuUser = std::chrono::milliseconds(500s), .cpuSystem = std::chrono::milliseconds(604s), #endif }, }; t; })) VERSIONED_CHARACTERIZATION_TEST( WorkerProtoTest, keyedBuildResult, "keyed-build-result", defaultVersion, ({ using namespace std::literals::chrono_literals; std::tuple t { KeyedBuildResult { { .status = KeyedBuildResult::OutputRejected, .errorMsg = "no idea why", }, /* .path = */ DerivedPath::Opaque { StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-xxx" }, }, }, KeyedBuildResult { { .status = KeyedBuildResult::NotDeterministic, .errorMsg = "no idea why", .timesBuilt = 3, .isNonDeterministic = true, .startTime = 30, .stopTime = 50, }, /* .path = */ DerivedPath::Built { .drvPath = makeConstantStorePathRef(StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv", }), .outputs = OutputsSpec::Names { "out" }, }, }, }; t; })) VERSIONED_CHARACTERIZATION_TEST( WorkerProtoTest, optionalTrustedFlag, "optional-trusted-flag", defaultVersion, (std::tuple, std::optional, std::optional> { std::nullopt, std::optional { Trusted }, std::optional { NotTrusted }, })) VERSIONED_CHARACTERIZATION_TEST( WorkerProtoTest, vector, "vector", defaultVersion, (std::tuple, std::vector, std::vector, std::vector>> { { }, { "" }, { "", "foo", "bar" }, { {}, { "" }, { "", "1", "2" } }, })) VERSIONED_CHARACTERIZATION_TEST( WorkerProtoTest, set, "set", defaultVersion, (std::tuple, std::set, std::set, std::set>> { { }, { "" }, { "", "foo", "bar" }, { {}, { "" }, { "", "1", "2" } }, })) VERSIONED_CHARACTERIZATION_TEST( WorkerProtoTest, optionalStorePath, "optional-store-path", defaultVersion, (std::tuple, std::optional> { std::nullopt, std::optional { StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo-bar" }, }, })) VERSIONED_CHARACTERIZATION_TEST( WorkerProtoTest, optionalContentAddress, "optional-content-address", defaultVersion, (std::tuple, std::optional> { std::nullopt, std::optional { ContentAddress { .method = FileIngestionMethod::Flat, .hash = hashString(HashType::htSHA1, "blob blob..."), }, }, })) }