#include #include #include #include "nix/store/common-protocol.hh" #include "nix/store/common-protocol-impl.hh" #include "nix/store/build-result.hh" #include "nix/store/tests/protocol.hh" #include "nix/util/tests/characterization.hh" namespace nix { const char commonProtoDir[] = "common-protocol"; class CommonProtoTest : public ProtoTest { public: /** * Golden test for `T` reading */ template void readProtoTest(PathView testStem, const T & expected) { CharacterizationTest::readTest(testStem, [&](const auto & encoded) { T got = ({ StringSource from{encoded}; CommonProto::Serialise::read(store, CommonProto::ReadConn{.from = from}); }); ASSERT_EQ(got, expected); }); } /** * Golden test for `T` write */ template void writeProtoTest(PathView testStem, const T & decoded) { CharacterizationTest::writeTest(testStem, [&]() -> std::string { StringSink to; CommonProto::Serialise::write(store, CommonProto::WriteConn{.to = to}, decoded); return to.s; }); } }; #define CHARACTERIZATION_TEST(NAME, STEM, VALUE) \ TEST_F(CommonProtoTest, NAME##_read) \ { \ readProtoTest(STEM, VALUE); \ } \ TEST_F(CommonProtoTest, NAME##_write) \ { \ writeProtoTest(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 = ContentAddressMethod::Raw::Text, .hash = hashString(HashAlgorithm::SHA256, "Derive(...)"), }, ContentAddress{ .method = ContentAddressMethod::Raw::Flat, .hash = hashString(HashAlgorithm::SHA1, "blob blob..."), }, ContentAddress{ .method = ContentAddressMethod::Raw::NixArchive, .hash = hashString(HashAlgorithm::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{ { .outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"}, .signatures = {"asdf", "qwer"}, }, DrvOutput{ .drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="), .outputName = "baz", }, }, Realisation{ { .outPath = StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"}, .signatures = {"asdf", "qwer"}, .dependentRealisations = { { DrvOutput{ .drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="), .outputName = "quux", }, StorePath{"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo"}, }, }, }, { .drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="), .outputName = "baz", }, }, })) CHARACTERIZATION_TEST( vector, "vector", (std::tuple< std::vector, std::vector, std::vector, std::vector>>{ {}, {""}, {"", "foo", "bar"}, {{}, {""}, {"", "1", "2"}}, })) CHARACTERIZATION_TEST( set, "set", (std::tuple>{ {}, {""}, {"", "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 = ContentAddressMethod::Raw::Flat, .hash = hashString(HashAlgorithm::SHA1, "blob blob..."), }, }, })) } // namespace nix