#include #include #include #include "lix/libstore/common-protocol.hh" #include "lix/libstore/common-protocol-impl.hh" #include "lix/libstore/build-result.hh" #include "protocol.hh" #include "tests/characterization.hh" namespace nix { const char commonProtoDir[] = "common-protocol"; class CommonProtoTest : public ProtoTest { public: /** * Golden test for `T` reading */ template void readTest(PathView testStem, T value) { if (testAccept()) { GTEST_SKIP() << cannotReadGoldenMaster; } else { auto encoded = readFile(goldenMaster(testStem)); T got = ({ StringSource from { encoded }; CommonProto::Serialise::read( *store, CommonProto::ReadConn { .from = from }); }); ASSERT_EQ(got, value); } } /** * Golden test for `T` write */ template void writeTest(PathView testStem, const T & value) { auto file = goldenMaster(testStem); StringSink to; to << CommonProto::write( *store, CommonProto::WriteConn {}, value); if (testAccept()) { createDirs(dirOf(file)); writeFile(file, to.s); GTEST_SKIP() << updatingGoldenMaster; } else { auto expected = readFile(file); ASSERT_EQ(to.s, expected); } } }; #define CHARACTERIZATION_TEST(NAME, STEM, VALUE) \ TEST_F(CommonProtoTest, NAME ## _read) { \ readTest(STEM, VALUE); \ } \ TEST_F(CommonProtoTest, NAME ## _write) { \ writeTest(STEM, VALUE); \ } CHARACTERIZATION_TEST( string, "string", (std::tuple { "", "hi", "white rabbit", "大白兔", "oh no \0\0\0 what was that!", })) CHARACTERIZATION_TEST( storePath, "store-path", (std::tuple { StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" }, StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo-bar" }, })) CHARACTERIZATION_TEST( contentAddress, "content-address", (std::tuple { ContentAddress { .method = TextIngestionMethod {}, .hash = hashString(HashType::SHA256, "Derive(...)"), }, ContentAddress { .method = FileIngestionMethod::Flat, .hash = hashString(HashType::SHA1, "blob blob..."), }, ContentAddress { .method = FileIngestionMethod::Recursive, .hash = hashString(HashType::SHA256, "(...)"), }, })) CHARACTERIZATION_TEST( drvOutput, "drv-output", (std::tuple { { .drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="), .outputName = "baz", }, DrvOutput { .drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="), .outputName = "quux", }, })) CHARACTERIZATION_TEST( realisation, "realisation", (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" }, }, }, }, })) CHARACTERIZATION_TEST( vector, "vector", (std::tuple, std::vector, std::vector, std::vector>> { { }, { "" }, { "", "foo", "bar" }, { {}, { "" }, { "", "1", "2" } }, })) CHARACTERIZATION_TEST( set, "set", (std::tuple, std::set, std::set, std::set>> { { }, { "" }, { "", "foo", "bar" }, { {}, { "" }, { "", "1", "2" } }, })) CHARACTERIZATION_TEST( optionalStorePath, "optional-store-path", (std::tuple, std::optional> { std::nullopt, std::optional { StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo-bar" }, }, })) CHARACTERIZATION_TEST( optionalContentAddress, "optional-content-address", (std::tuple, std::optional> { std::nullopt, std::optional { ContentAddress { .method = FileIngestionMethod::Flat, .hash = hashString(HashType::SHA1, "blob blob..."), }, }, })) }