mirror of
https://github.com/NixOS/nix.git
synced 2025-11-18 08:19:35 +01:00
This will allow us to factor out logic, which is currently scattered inline, into several reusable instances The tests are also updated to support versioning. Currently all Worker and Serve protocol tests are using the minimum version, since no version-specific serialisers have been created yet. But in subsequent commits when that changes, we will test individual versions to ensure complete coverage.
205 lines
5.6 KiB
C++
205 lines
5.6 KiB
C++
#include <regex>
|
|
|
|
#include <nlohmann/json.hpp>
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "common-protocol.hh"
|
|
#include "common-protocol-impl.hh"
|
|
#include "build-result.hh"
|
|
#include "tests/protocol.hh"
|
|
#include "tests/characterization.hh"
|
|
|
|
namespace nix {
|
|
|
|
const char commonProtoDir[] = "common-protocol";
|
|
|
|
class CommonProtoTest : public ProtoTest<CommonProto, commonProtoDir>
|
|
{
|
|
public:
|
|
/**
|
|
* Golden test for `T` reading
|
|
*/
|
|
template<typename T>
|
|
void readTest(PathView testStem, T value)
|
|
{
|
|
if (testAccept())
|
|
{
|
|
GTEST_SKIP() << "Cannot read golden master because another test is also updating it";
|
|
}
|
|
else
|
|
{
|
|
auto expected = readFile(goldenMaster(testStem));
|
|
|
|
T got = ({
|
|
StringSource from { expected };
|
|
CommonProto::Serialise<T>::read(
|
|
*store,
|
|
CommonProto::ReadConn { .from = from });
|
|
});
|
|
|
|
ASSERT_EQ(got, value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Golden test for `T` write
|
|
*/
|
|
template<typename T>
|
|
void writeTest(PathView testStem, const T & value)
|
|
{
|
|
auto file = goldenMaster(testStem);
|
|
|
|
StringSink to;
|
|
CommonProto::write(
|
|
*store,
|
|
CommonProto::WriteConn { .to = to },
|
|
value);
|
|
|
|
if (testAccept())
|
|
{
|
|
createDirs(dirOf(file));
|
|
writeFile(file, to.s);
|
|
GTEST_SKIP() << "Updating golden master";
|
|
}
|
|
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<std::string, std::string, std::string, std::string, std::string> {
|
|
"",
|
|
"hi",
|
|
"white rabbit",
|
|
"大白兔",
|
|
"oh no \0\0\0 what was that!",
|
|
}))
|
|
|
|
CHARACTERIZATION_TEST(
|
|
storePath,
|
|
"store-path",
|
|
(std::tuple<StorePath, StorePath> {
|
|
StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" },
|
|
StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo-bar" },
|
|
}))
|
|
|
|
CHARACTERIZATION_TEST(
|
|
contentAddress,
|
|
"content-address",
|
|
(std::tuple<ContentAddress, ContentAddress, ContentAddress> {
|
|
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, "(...)"),
|
|
},
|
|
}))
|
|
|
|
CHARACTERIZATION_TEST(
|
|
drvOutput,
|
|
"drv-output",
|
|
(std::tuple<DrvOutput, DrvOutput> {
|
|
{
|
|
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
|
.outputName = "baz",
|
|
},
|
|
DrvOutput {
|
|
.drvHash = Hash::parseSRI("sha256-b4afnqKCO9oWXgYHb9DeQ2berSwOjS27rSd9TxXDc/U="),
|
|
.outputName = "quux",
|
|
},
|
|
}))
|
|
|
|
CHARACTERIZATION_TEST(
|
|
realisation,
|
|
"realisation",
|
|
(std::tuple<Realisation, Realisation> {
|
|
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::string>, std::vector<std::string>, std::vector<std::string>, std::vector<std::vector<std::string>>> {
|
|
{ },
|
|
{ "" },
|
|
{ "", "foo", "bar" },
|
|
{ {}, { "" }, { "", "1", "2" } },
|
|
}))
|
|
|
|
CHARACTERIZATION_TEST(
|
|
set,
|
|
"set",
|
|
(std::tuple<std::set<std::string>, std::set<std::string>, std::set<std::string>, std::set<std::set<std::string>>> {
|
|
{ },
|
|
{ "" },
|
|
{ "", "foo", "bar" },
|
|
{ {}, { "" }, { "", "1", "2" } },
|
|
}))
|
|
|
|
CHARACTERIZATION_TEST(
|
|
optionalStorePath,
|
|
"optional-store-path",
|
|
(std::tuple<std::optional<StorePath>, std::optional<StorePath>> {
|
|
std::nullopt,
|
|
std::optional {
|
|
StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo-bar" },
|
|
},
|
|
}))
|
|
|
|
CHARACTERIZATION_TEST(
|
|
optionalContentAddress,
|
|
"optional-content-address",
|
|
(std::tuple<std::optional<ContentAddress>, std::optional<ContentAddress>> {
|
|
std::nullopt,
|
|
std::optional {
|
|
ContentAddress {
|
|
.method = FileIngestionMethod::Flat,
|
|
.hash = hashString(HashType::htSHA1, "blob blob..."),
|
|
},
|
|
},
|
|
}))
|
|
|
|
}
|