Merge pull request #9157 from obsidiansystems/protocol-versions
Add protocol versions to `{Worker,Serve}Proto::*Conn`
(cherry picked from commit 4d17c59d8d059a5b39f1d1da2b58f2ec8da44861)
Change-Id: I497af39deb792e50c157a1305d8c9e722798740b
This commit is contained in:
parent
5ddd1a9166
commit
ab40b2c5d0
|
@ -45,9 +45,9 @@ struct TunnelLogger : public Logger
|
||||||
|
|
||||||
Sync<State> state_;
|
Sync<State> state_;
|
||||||
|
|
||||||
unsigned int clientVersion;
|
WorkerProto::Version clientVersion;
|
||||||
|
|
||||||
TunnelLogger(FdSink & to, unsigned int clientVersion)
|
TunnelLogger(FdSink & to, WorkerProto::Version clientVersion)
|
||||||
: to(to), clientVersion(clientVersion) { }
|
: to(to), clientVersion(clientVersion) { }
|
||||||
|
|
||||||
void enqueueMsg(const std::string & s)
|
void enqueueMsg(const std::string & s)
|
||||||
|
@ -261,7 +261,7 @@ struct ClientSettings
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<DerivedPath> readDerivedPaths(Store & store, unsigned int clientVersion, WorkerProto::ReadConn conn)
|
static std::vector<DerivedPath> readDerivedPaths(Store & store, WorkerProto::Version clientVersion, WorkerProto::ReadConn conn)
|
||||||
{
|
{
|
||||||
std::vector<DerivedPath> reqs;
|
std::vector<DerivedPath> reqs;
|
||||||
if (GET_PROTOCOL_MINOR(clientVersion) >= 30) {
|
if (GET_PROTOCOL_MINOR(clientVersion) >= 30) {
|
||||||
|
@ -274,11 +274,17 @@ static std::vector<DerivedPath> readDerivedPaths(Store & store, unsigned int cli
|
||||||
}
|
}
|
||||||
|
|
||||||
static void performOp(TunnelLogger * logger, ref<Store> store,
|
static void performOp(TunnelLogger * logger, ref<Store> store,
|
||||||
TrustedFlag trusted, RecursiveFlag recursive, unsigned int clientVersion,
|
TrustedFlag trusted, RecursiveFlag recursive, WorkerProto::Version clientVersion,
|
||||||
Source & from, BufferedSink & to, WorkerProto::Op op)
|
Source & from, BufferedSink & to, WorkerProto::Op op)
|
||||||
{
|
{
|
||||||
WorkerProto::ReadConn rconn { .from = from };
|
WorkerProto::ReadConn rconn {
|
||||||
WorkerProto::WriteConn wconn { .to = to };
|
.from = from,
|
||||||
|
.version = clientVersion,
|
||||||
|
};
|
||||||
|
WorkerProto::WriteConn wconn {
|
||||||
|
.to = to,
|
||||||
|
.version = clientVersion,
|
||||||
|
};
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
|
||||||
|
@ -1017,7 +1023,7 @@ void processConnection(
|
||||||
if (magic != WORKER_MAGIC_1) throw Error("protocol mismatch");
|
if (magic != WORKER_MAGIC_1) throw Error("protocol mismatch");
|
||||||
to << WORKER_MAGIC_2 << PROTOCOL_VERSION;
|
to << WORKER_MAGIC_2 << PROTOCOL_VERSION;
|
||||||
to.flush();
|
to.flush();
|
||||||
unsigned int clientVersion = readInt(from);
|
WorkerProto::Version clientVersion = readInt(from);
|
||||||
|
|
||||||
if (clientVersion < 0x10a)
|
if (clientVersion < 0x10a)
|
||||||
throw Error("the Nix client version is too old");
|
throw Error("the Nix client version is too old");
|
||||||
|
@ -1052,7 +1058,10 @@ void processConnection(
|
||||||
auto temp = trusted
|
auto temp = trusted
|
||||||
? store->isTrustedClient()
|
? store->isTrustedClient()
|
||||||
: std::optional { NotTrusted };
|
: std::optional { NotTrusted };
|
||||||
WorkerProto::WriteConn wconn { .to = to };
|
WorkerProto::WriteConn wconn {
|
||||||
|
.to = to,
|
||||||
|
.version = clientVersion,
|
||||||
|
};
|
||||||
WorkerProto::write(*store, wconn, temp);
|
WorkerProto::write(*store, wconn, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ struct LegacySSHStore : public virtual LegacySSHStoreConfig, public virtual Stor
|
||||||
std::unique_ptr<SSHMaster::Connection> sshConn;
|
std::unique_ptr<SSHMaster::Connection> sshConn;
|
||||||
FdSink to;
|
FdSink to;
|
||||||
FdSource from;
|
FdSource from;
|
||||||
int remoteVersion;
|
ServeProto::Version remoteVersion;
|
||||||
bool good = true;
|
bool good = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,6 +60,7 @@ struct LegacySSHStore : public virtual LegacySSHStoreConfig, public virtual Stor
|
||||||
{
|
{
|
||||||
return ServeProto::ReadConn {
|
return ServeProto::ReadConn {
|
||||||
.from = from,
|
.from = from,
|
||||||
|
.version = remoteVersion,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +76,7 @@ struct LegacySSHStore : public virtual LegacySSHStoreConfig, public virtual Stor
|
||||||
{
|
{
|
||||||
return ServeProto::WriteConn {
|
return ServeProto::WriteConn {
|
||||||
.to = to,
|
.to = to,
|
||||||
|
.version = remoteVersion,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -141,7 +141,10 @@ ValidPathInfo ValidPathInfo::read(Source & source, const Store & store, unsigned
|
||||||
ValidPathInfo info(path, narHash);
|
ValidPathInfo info(path, narHash);
|
||||||
if (deriver != "") info.deriver = store.parseStorePath(deriver);
|
if (deriver != "") info.deriver = store.parseStorePath(deriver);
|
||||||
info.references = WorkerProto::Serialise<StorePathSet>::read(store,
|
info.references = WorkerProto::Serialise<StorePathSet>::read(store,
|
||||||
WorkerProto::ReadConn { .from = source });
|
WorkerProto::ReadConn {
|
||||||
|
.from = source,
|
||||||
|
.version = format,
|
||||||
|
});
|
||||||
source >> info.registrationTime >> info.narSize;
|
source >> info.registrationTime >> info.narSize;
|
||||||
if (format >= 16) {
|
if (format >= 16) {
|
||||||
source >> info.ultimate;
|
source >> info.ultimate;
|
||||||
|
@ -163,7 +166,10 @@ void ValidPathInfo::write(
|
||||||
sink << (deriver ? store.printStorePath(*deriver) : "")
|
sink << (deriver ? store.printStorePath(*deriver) : "")
|
||||||
<< narHash.to_string(Base16, false);
|
<< narHash.to_string(Base16, false);
|
||||||
WorkerProto::write(store,
|
WorkerProto::write(store,
|
||||||
WorkerProto::WriteConn { .to = sink },
|
WorkerProto::WriteConn {
|
||||||
|
.to = sink,
|
||||||
|
.version = format,
|
||||||
|
},
|
||||||
references);
|
references);
|
||||||
sink << registrationTime << narSize;
|
sink << registrationTime << narSize;
|
||||||
if (format >= 16) {
|
if (format >= 16) {
|
||||||
|
|
|
@ -30,7 +30,7 @@ struct RemoteStore::Connection
|
||||||
* sides support. (If the maximum doesn't exist, we would fail to
|
* sides support. (If the maximum doesn't exist, we would fail to
|
||||||
* establish a connection and produce a value of this type.)
|
* establish a connection and produce a value of this type.)
|
||||||
*/
|
*/
|
||||||
unsigned int daemonVersion;
|
WorkerProto::Version daemonVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the remote side trusts us or not.
|
* Whether the remote side trusts us or not.
|
||||||
|
@ -70,6 +70,7 @@ struct RemoteStore::Connection
|
||||||
{
|
{
|
||||||
return WorkerProto::ReadConn {
|
return WorkerProto::ReadConn {
|
||||||
.from = from,
|
.from = from,
|
||||||
|
.version = daemonVersion,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +86,7 @@ struct RemoteStore::Connection
|
||||||
{
|
{
|
||||||
return WorkerProto::WriteConn {
|
return WorkerProto::WriteConn {
|
||||||
.to = to,
|
.to = to,
|
||||||
|
.version = daemonVersion,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,26 +30,29 @@ struct ServeProto
|
||||||
*/
|
*/
|
||||||
enum struct Command : uint64_t;
|
enum struct Command : uint64_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version type for the protocol.
|
||||||
|
*
|
||||||
|
* @todo Convert to struct with separate major vs minor fields.
|
||||||
|
*/
|
||||||
|
using Version = unsigned int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A unidirectional read connection, to be used by the read half of the
|
* A unidirectional read connection, to be used by the read half of the
|
||||||
* canonical serializers below.
|
* canonical serializers below.
|
||||||
*
|
|
||||||
* This currently is just a `Source &`, but more fields will be added
|
|
||||||
* later.
|
|
||||||
*/
|
*/
|
||||||
struct ReadConn {
|
struct ReadConn {
|
||||||
Source & from;
|
Source & from;
|
||||||
|
Version version;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A unidirectional write connection, to be used by the write half of the
|
* A unidirectional write connection, to be used by the write half of the
|
||||||
* canonical serializers below.
|
* canonical serializers below.
|
||||||
*
|
|
||||||
* This currently is just a `Sink &`, but more fields will be added
|
|
||||||
* later.
|
|
||||||
*/
|
*/
|
||||||
struct WriteConn {
|
struct WriteConn {
|
||||||
Sink & to;
|
Sink & to;
|
||||||
|
Version version;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -47,26 +47,29 @@ struct WorkerProto
|
||||||
*/
|
*/
|
||||||
enum struct Op : uint64_t;
|
enum struct Op : uint64_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version type for the protocol.
|
||||||
|
*
|
||||||
|
* @todo Convert to struct with separate major vs minor fields.
|
||||||
|
*/
|
||||||
|
using Version = unsigned int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A unidirectional read connection, to be used by the read half of the
|
* A unidirectional read connection, to be used by the read half of the
|
||||||
* canonical serializers below.
|
* canonical serializers below.
|
||||||
*
|
|
||||||
* This currently is just a `Source &`, but more fields will be added
|
|
||||||
* later.
|
|
||||||
*/
|
*/
|
||||||
struct ReadConn {
|
struct ReadConn {
|
||||||
Source & from;
|
Source & from;
|
||||||
|
Version version;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A unidirectional write connection, to be used by the write half of the
|
* A unidirectional write connection, to be used by the write half of the
|
||||||
* canonical serializers below.
|
* canonical serializers below.
|
||||||
*
|
|
||||||
* This currently is just a `Sink &`, but more fields will be added
|
|
||||||
* later.
|
|
||||||
*/
|
*/
|
||||||
struct WriteConn {
|
struct WriteConn {
|
||||||
Sink & to;
|
Sink & to;
|
||||||
|
Version version;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -818,10 +818,16 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||||
if (magic != SERVE_MAGIC_1) throw Error("protocol mismatch");
|
if (magic != SERVE_MAGIC_1) throw Error("protocol mismatch");
|
||||||
out << SERVE_MAGIC_2 << SERVE_PROTOCOL_VERSION;
|
out << SERVE_MAGIC_2 << SERVE_PROTOCOL_VERSION;
|
||||||
out.flush();
|
out.flush();
|
||||||
unsigned int clientVersion = readInt(in);
|
ServeProto::Version clientVersion = readInt(in);
|
||||||
|
|
||||||
ServeProto::ReadConn rconn { .from = in };
|
ServeProto::ReadConn rconn {
|
||||||
ServeProto::WriteConn wconn { .to = out };
|
.from = in,
|
||||||
|
.version = clientVersion,
|
||||||
|
};
|
||||||
|
ServeProto::WriteConn wconn {
|
||||||
|
.to = out,
|
||||||
|
.version = clientVersion,
|
||||||
|
};
|
||||||
|
|
||||||
auto getBuildSettings = [&]() {
|
auto getBuildSettings = [&]() {
|
||||||
// FIXME: changing options here doesn't work if we're
|
// FIXME: changing options here doesn't work if we're
|
||||||
|
|
|
@ -13,10 +13,71 @@ namespace nix {
|
||||||
|
|
||||||
const char commonProtoDir[] = "common-protocol";
|
const char commonProtoDir[] = "common-protocol";
|
||||||
|
|
||||||
using CommonProtoTest = ProtoTest<CommonProto, commonProtoDir>;
|
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(
|
CHARACTERIZATION_TEST(
|
||||||
CommonProtoTest,
|
|
||||||
string,
|
string,
|
||||||
"string",
|
"string",
|
||||||
(std::tuple<std::string, std::string, std::string, std::string, std::string> {
|
(std::tuple<std::string, std::string, std::string, std::string, std::string> {
|
||||||
|
@ -28,7 +89,6 @@ CHARACTERIZATION_TEST(
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
CHARACTERIZATION_TEST(
|
||||||
CommonProtoTest,
|
|
||||||
storePath,
|
storePath,
|
||||||
"store-path",
|
"store-path",
|
||||||
(std::tuple<StorePath, StorePath> {
|
(std::tuple<StorePath, StorePath> {
|
||||||
|
@ -37,7 +97,6 @@ CHARACTERIZATION_TEST(
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
CHARACTERIZATION_TEST(
|
||||||
CommonProtoTest,
|
|
||||||
contentAddress,
|
contentAddress,
|
||||||
"content-address",
|
"content-address",
|
||||||
(std::tuple<ContentAddress, ContentAddress, ContentAddress> {
|
(std::tuple<ContentAddress, ContentAddress, ContentAddress> {
|
||||||
|
@ -56,7 +115,6 @@ CHARACTERIZATION_TEST(
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
CHARACTERIZATION_TEST(
|
||||||
CommonProtoTest,
|
|
||||||
drvOutput,
|
drvOutput,
|
||||||
"drv-output",
|
"drv-output",
|
||||||
(std::tuple<DrvOutput, DrvOutput> {
|
(std::tuple<DrvOutput, DrvOutput> {
|
||||||
|
@ -71,7 +129,6 @@ CHARACTERIZATION_TEST(
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
CHARACTERIZATION_TEST(
|
||||||
CommonProtoTest,
|
|
||||||
realisation,
|
realisation,
|
||||||
"realisation",
|
"realisation",
|
||||||
(std::tuple<Realisation, Realisation> {
|
(std::tuple<Realisation, Realisation> {
|
||||||
|
@ -103,7 +160,6 @@ CHARACTERIZATION_TEST(
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
CHARACTERIZATION_TEST(
|
||||||
CommonProtoTest,
|
|
||||||
vector,
|
vector,
|
||||||
"vector",
|
"vector",
|
||||||
(std::tuple<std::vector<std::string>, std::vector<std::string>, std::vector<std::string>, std::vector<std::vector<std::string>>> {
|
(std::tuple<std::vector<std::string>, std::vector<std::string>, std::vector<std::string>, std::vector<std::vector<std::string>>> {
|
||||||
|
@ -114,7 +170,6 @@ CHARACTERIZATION_TEST(
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
CHARACTERIZATION_TEST(
|
||||||
CommonProtoTest,
|
|
||||||
set,
|
set,
|
||||||
"set",
|
"set",
|
||||||
(std::tuple<std::set<std::string>, std::set<std::string>, std::set<std::string>, std::set<std::set<std::string>>> {
|
(std::tuple<std::set<std::string>, std::set<std::string>, std::set<std::string>, std::set<std::set<std::string>>> {
|
||||||
|
@ -125,7 +180,6 @@ CHARACTERIZATION_TEST(
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
CHARACTERIZATION_TEST(
|
||||||
CommonProtoTest,
|
|
||||||
optionalStorePath,
|
optionalStorePath,
|
||||||
"optional-store-path",
|
"optional-store-path",
|
||||||
(std::tuple<std::optional<StorePath>, std::optional<StorePath>> {
|
(std::tuple<std::optional<StorePath>, std::optional<StorePath>> {
|
||||||
|
@ -136,7 +190,6 @@ CHARACTERIZATION_TEST(
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
CHARACTERIZATION_TEST(
|
||||||
CommonProtoTest,
|
|
||||||
optionalContentAddress,
|
optionalContentAddress,
|
||||||
"optional-content-address",
|
"optional-content-address",
|
||||||
(std::tuple<std::optional<ContentAddress>, std::optional<ContentAddress>> {
|
(std::tuple<std::optional<ContentAddress>, std::optional<ContentAddress>> {
|
||||||
|
|
|
@ -9,26 +9,23 @@ namespace nix {
|
||||||
template<class Proto, const char * protocolDir>
|
template<class Proto, const char * protocolDir>
|
||||||
class ProtoTest : public LibStoreTest
|
class ProtoTest : public LibStoreTest
|
||||||
{
|
{
|
||||||
/**
|
protected:
|
||||||
* Read this as simply `using S = Inner::Serialise;`.
|
|
||||||
*
|
|
||||||
* See `LengthPrefixedProtoHelper::S` for the same trick, and its
|
|
||||||
* rationale.
|
|
||||||
*/
|
|
||||||
template<typename U> using S = typename Proto::template Serialise<U>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Path unitTestData = getUnitTestData() + "/libstore/" + protocolDir;
|
Path unitTestData = getUnitTestData() + "/libstore/" + protocolDir;
|
||||||
|
|
||||||
Path goldenMaster(std::string_view testStem) {
|
Path goldenMaster(std::string_view testStem) {
|
||||||
return unitTestData + "/" + testStem + ".bin";
|
return unitTestData + "/" + testStem + ".bin";
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Proto, const char * protocolDir>
|
||||||
|
class VersionedProtoTest : public ProtoTest<Proto, protocolDir>
|
||||||
|
{
|
||||||
|
public:
|
||||||
/**
|
/**
|
||||||
* Golden test for `T` reading
|
* Golden test for `T` reading
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void readTest(PathView testStem, T value)
|
void readTest(PathView testStem, typename Proto::Version version, T value)
|
||||||
{
|
{
|
||||||
if (testAccept())
|
if (testAccept())
|
||||||
{
|
{
|
||||||
|
@ -36,13 +33,16 @@ public:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto expected = readFile(goldenMaster(testStem));
|
auto expected = readFile(ProtoTest<Proto, protocolDir>::goldenMaster(testStem));
|
||||||
|
|
||||||
T got = ({
|
T got = ({
|
||||||
StringSource from { expected };
|
StringSource from { expected };
|
||||||
S<T>::read(
|
Proto::template Serialise<T>::read(
|
||||||
*store,
|
*LibStoreTest::store,
|
||||||
typename Proto::ReadConn { .from = from });
|
typename Proto::ReadConn {
|
||||||
|
.from = from,
|
||||||
|
.version = version,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
ASSERT_EQ(got, value);
|
ASSERT_EQ(got, value);
|
||||||
|
@ -53,14 +53,17 @@ public:
|
||||||
* Golden test for `T` write
|
* Golden test for `T` write
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void writeTest(PathView testStem, const T & value)
|
void writeTest(PathView testStem, typename Proto::Version version, const T & value)
|
||||||
{
|
{
|
||||||
auto file = goldenMaster(testStem);
|
auto file = ProtoTest<Proto, protocolDir>::goldenMaster(testStem);
|
||||||
|
|
||||||
StringSink to;
|
StringSink to;
|
||||||
Proto::write(
|
Proto::write(
|
||||||
*store,
|
*LibStoreTest::store,
|
||||||
typename Proto::WriteConn { .to = to },
|
typename Proto::WriteConn {
|
||||||
|
.to = to,
|
||||||
|
.version = version,
|
||||||
|
},
|
||||||
value);
|
value);
|
||||||
|
|
||||||
if (testAccept())
|
if (testAccept())
|
||||||
|
@ -77,12 +80,12 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CHARACTERIZATION_TEST(FIXTURE, NAME, STEM, VALUE) \
|
#define VERSIONED_CHARACTERIZATION_TEST(FIXTURE, NAME, STEM, VERSION, VALUE) \
|
||||||
TEST_F(FIXTURE, NAME ## _read) { \
|
TEST_F(FIXTURE, NAME ## _read) { \
|
||||||
readTest(STEM, VALUE); \
|
readTest(STEM, VERSION, VALUE); \
|
||||||
} \
|
} \
|
||||||
TEST_F(FIXTURE, NAME ## _write) { \
|
TEST_F(FIXTURE, NAME ## _write) { \
|
||||||
writeTest(STEM, VALUE); \
|
writeTest(STEM, VERSION, VALUE); \
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,14 +11,22 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
const char commonProtoDir[] = "serve-protocol";
|
const char serveProtoDir[] = "serve-protocol";
|
||||||
|
|
||||||
using ServeProtoTest = ProtoTest<ServeProto, commonProtoDir>;
|
struct ServeProtoTest : VersionedProtoTest<ServeProto, serveProtoDir>
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* For serializers that don't care about the minimum version, we
|
||||||
|
* used the oldest one: 1.0.
|
||||||
|
*/
|
||||||
|
ServeProto::Version defaultVersion = 1 << 8 | 0;
|
||||||
|
};
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
ServeProtoTest,
|
ServeProtoTest,
|
||||||
string,
|
string,
|
||||||
"string",
|
"string",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<std::string, std::string, std::string, std::string, std::string> {
|
(std::tuple<std::string, std::string, std::string, std::string, std::string> {
|
||||||
"",
|
"",
|
||||||
"hi",
|
"hi",
|
||||||
|
@ -27,19 +35,21 @@ CHARACTERIZATION_TEST(
|
||||||
"oh no \0\0\0 what was that!",
|
"oh no \0\0\0 what was that!",
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
ServeProtoTest,
|
ServeProtoTest,
|
||||||
storePath,
|
storePath,
|
||||||
"store-path",
|
"store-path",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<StorePath, StorePath> {
|
(std::tuple<StorePath, StorePath> {
|
||||||
StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" },
|
StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" },
|
||||||
StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo-bar" },
|
StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo-bar" },
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
ServeProtoTest,
|
ServeProtoTest,
|
||||||
contentAddress,
|
contentAddress,
|
||||||
"content-address",
|
"content-address",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<ContentAddress, ContentAddress, ContentAddress> {
|
(std::tuple<ContentAddress, ContentAddress, ContentAddress> {
|
||||||
ContentAddress {
|
ContentAddress {
|
||||||
.method = TextIngestionMethod {},
|
.method = TextIngestionMethod {},
|
||||||
|
@ -55,10 +65,11 @@ CHARACTERIZATION_TEST(
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
ServeProtoTest,
|
ServeProtoTest,
|
||||||
drvOutput,
|
drvOutput,
|
||||||
"drv-output",
|
"drv-output",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<DrvOutput, DrvOutput> {
|
(std::tuple<DrvOutput, DrvOutput> {
|
||||||
{
|
{
|
||||||
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
||||||
|
@ -70,10 +81,11 @@ CHARACTERIZATION_TEST(
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
ServeProtoTest,
|
ServeProtoTest,
|
||||||
realisation,
|
realisation,
|
||||||
"realisation",
|
"realisation",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<Realisation, Realisation> {
|
(std::tuple<Realisation, Realisation> {
|
||||||
Realisation {
|
Realisation {
|
||||||
.id = DrvOutput {
|
.id = DrvOutput {
|
||||||
|
@ -102,10 +114,11 @@ CHARACTERIZATION_TEST(
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
ServeProtoTest,
|
ServeProtoTest,
|
||||||
vector,
|
vector,
|
||||||
"vector",
|
"vector",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<std::vector<std::string>, std::vector<std::string>, std::vector<std::string>, std::vector<std::vector<std::string>>> {
|
(std::tuple<std::vector<std::string>, std::vector<std::string>, std::vector<std::string>, std::vector<std::vector<std::string>>> {
|
||||||
{ },
|
{ },
|
||||||
{ "" },
|
{ "" },
|
||||||
|
@ -113,10 +126,11 @@ CHARACTERIZATION_TEST(
|
||||||
{ {}, { "" }, { "", "1", "2" } },
|
{ {}, { "" }, { "", "1", "2" } },
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
ServeProtoTest,
|
ServeProtoTest,
|
||||||
set,
|
set,
|
||||||
"set",
|
"set",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<std::set<std::string>, std::set<std::string>, std::set<std::string>, std::set<std::set<std::string>>> {
|
(std::tuple<std::set<std::string>, std::set<std::string>, std::set<std::string>, std::set<std::set<std::string>>> {
|
||||||
{ },
|
{ },
|
||||||
{ "" },
|
{ "" },
|
||||||
|
@ -124,10 +138,11 @@ CHARACTERIZATION_TEST(
|
||||||
{ {}, { "" }, { "", "1", "2" } },
|
{ {}, { "" }, { "", "1", "2" } },
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
ServeProtoTest,
|
ServeProtoTest,
|
||||||
optionalStorePath,
|
optionalStorePath,
|
||||||
"optional-store-path",
|
"optional-store-path",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<std::optional<StorePath>, std::optional<StorePath>> {
|
(std::tuple<std::optional<StorePath>, std::optional<StorePath>> {
|
||||||
std::nullopt,
|
std::nullopt,
|
||||||
std::optional {
|
std::optional {
|
||||||
|
@ -135,10 +150,11 @@ CHARACTERIZATION_TEST(
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
ServeProtoTest,
|
ServeProtoTest,
|
||||||
optionalContentAddress,
|
optionalContentAddress,
|
||||||
"optional-content-address",
|
"optional-content-address",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<std::optional<ContentAddress>, std::optional<ContentAddress>> {
|
(std::tuple<std::optional<ContentAddress>, std::optional<ContentAddress>> {
|
||||||
std::nullopt,
|
std::nullopt,
|
||||||
std::optional {
|
std::optional {
|
||||||
|
|
|
@ -14,12 +14,21 @@ namespace nix {
|
||||||
|
|
||||||
const char workerProtoDir[] = "worker-protocol";
|
const char workerProtoDir[] = "worker-protocol";
|
||||||
|
|
||||||
using WorkerProtoTest = ProtoTest<WorkerProto, workerProtoDir>;
|
struct WorkerProtoTest : VersionedProtoTest<WorkerProto, workerProtoDir>
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* For serializers that don't care about the minimum version, we
|
||||||
|
* used the oldest one: 1.0.
|
||||||
|
*/
|
||||||
|
WorkerProto::Version defaultVersion = 1 << 8 | 0;
|
||||||
|
};
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
|
||||||
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
WorkerProtoTest,
|
WorkerProtoTest,
|
||||||
string,
|
string,
|
||||||
"string",
|
"string",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<std::string, std::string, std::string, std::string, std::string> {
|
(std::tuple<std::string, std::string, std::string, std::string, std::string> {
|
||||||
"",
|
"",
|
||||||
"hi",
|
"hi",
|
||||||
|
@ -28,19 +37,21 @@ CHARACTERIZATION_TEST(
|
||||||
"oh no \0\0\0 what was that!",
|
"oh no \0\0\0 what was that!",
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
WorkerProtoTest,
|
WorkerProtoTest,
|
||||||
storePath,
|
storePath,
|
||||||
"store-path",
|
"store-path",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<StorePath, StorePath> {
|
(std::tuple<StorePath, StorePath> {
|
||||||
StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" },
|
StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" },
|
||||||
StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo-bar" },
|
StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo-bar" },
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
WorkerProtoTest,
|
WorkerProtoTest,
|
||||||
contentAddress,
|
contentAddress,
|
||||||
"content-address",
|
"content-address",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<ContentAddress, ContentAddress, ContentAddress> {
|
(std::tuple<ContentAddress, ContentAddress, ContentAddress> {
|
||||||
ContentAddress {
|
ContentAddress {
|
||||||
.method = TextIngestionMethod {},
|
.method = TextIngestionMethod {},
|
||||||
|
@ -56,10 +67,11 @@ CHARACTERIZATION_TEST(
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
WorkerProtoTest,
|
WorkerProtoTest,
|
||||||
derivedPath,
|
derivedPath,
|
||||||
"derived-path",
|
"derived-path",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<DerivedPath, DerivedPath> {
|
(std::tuple<DerivedPath, DerivedPath> {
|
||||||
DerivedPath::Opaque {
|
DerivedPath::Opaque {
|
||||||
.path = StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" },
|
.path = StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo" },
|
||||||
|
@ -72,10 +84,11 @@ CHARACTERIZATION_TEST(
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
WorkerProtoTest,
|
WorkerProtoTest,
|
||||||
drvOutput,
|
drvOutput,
|
||||||
"drv-output",
|
"drv-output",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<DrvOutput, DrvOutput> {
|
(std::tuple<DrvOutput, DrvOutput> {
|
||||||
{
|
{
|
||||||
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
.drvHash = Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
||||||
|
@ -87,10 +100,11 @@ CHARACTERIZATION_TEST(
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
WorkerProtoTest,
|
WorkerProtoTest,
|
||||||
realisation,
|
realisation,
|
||||||
"realisation",
|
"realisation",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<Realisation, Realisation> {
|
(std::tuple<Realisation, Realisation> {
|
||||||
Realisation {
|
Realisation {
|
||||||
.id = DrvOutput {
|
.id = DrvOutput {
|
||||||
|
@ -119,10 +133,11 @@ CHARACTERIZATION_TEST(
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
WorkerProtoTest,
|
WorkerProtoTest,
|
||||||
buildResult,
|
buildResult,
|
||||||
"build-result",
|
"build-result",
|
||||||
|
defaultVersion,
|
||||||
({
|
({
|
||||||
using namespace std::literals::chrono_literals;
|
using namespace std::literals::chrono_literals;
|
||||||
std::tuple<BuildResult, BuildResult, BuildResult> t {
|
std::tuple<BuildResult, BuildResult, BuildResult> t {
|
||||||
|
@ -177,10 +192,11 @@ CHARACTERIZATION_TEST(
|
||||||
t;
|
t;
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
WorkerProtoTest,
|
WorkerProtoTest,
|
||||||
keyedBuildResult,
|
keyedBuildResult,
|
||||||
"keyed-build-result",
|
"keyed-build-result",
|
||||||
|
defaultVersion,
|
||||||
({
|
({
|
||||||
using namespace std::literals::chrono_literals;
|
using namespace std::literals::chrono_literals;
|
||||||
std::tuple<KeyedBuildResult, KeyedBuildResult/*, KeyedBuildResult*/> t {
|
std::tuple<KeyedBuildResult, KeyedBuildResult/*, KeyedBuildResult*/> t {
|
||||||
|
@ -213,20 +229,22 @@ CHARACTERIZATION_TEST(
|
||||||
t;
|
t;
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
WorkerProtoTest,
|
WorkerProtoTest,
|
||||||
optionalTrustedFlag,
|
optionalTrustedFlag,
|
||||||
"optional-trusted-flag",
|
"optional-trusted-flag",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<std::optional<TrustedFlag>, std::optional<TrustedFlag>, std::optional<TrustedFlag>> {
|
(std::tuple<std::optional<TrustedFlag>, std::optional<TrustedFlag>, std::optional<TrustedFlag>> {
|
||||||
std::nullopt,
|
std::nullopt,
|
||||||
std::optional { Trusted },
|
std::optional { Trusted },
|
||||||
std::optional { NotTrusted },
|
std::optional { NotTrusted },
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
WorkerProtoTest,
|
WorkerProtoTest,
|
||||||
vector,
|
vector,
|
||||||
"vector",
|
"vector",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<std::vector<std::string>, std::vector<std::string>, std::vector<std::string>, std::vector<std::vector<std::string>>> {
|
(std::tuple<std::vector<std::string>, std::vector<std::string>, std::vector<std::string>, std::vector<std::vector<std::string>>> {
|
||||||
{ },
|
{ },
|
||||||
{ "" },
|
{ "" },
|
||||||
|
@ -234,10 +252,11 @@ CHARACTERIZATION_TEST(
|
||||||
{ {}, { "" }, { "", "1", "2" } },
|
{ {}, { "" }, { "", "1", "2" } },
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
WorkerProtoTest,
|
WorkerProtoTest,
|
||||||
set,
|
set,
|
||||||
"set",
|
"set",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<std::set<std::string>, std::set<std::string>, std::set<std::string>, std::set<std::set<std::string>>> {
|
(std::tuple<std::set<std::string>, std::set<std::string>, std::set<std::string>, std::set<std::set<std::string>>> {
|
||||||
{ },
|
{ },
|
||||||
{ "" },
|
{ "" },
|
||||||
|
@ -245,10 +264,11 @@ CHARACTERIZATION_TEST(
|
||||||
{ {}, { "" }, { "", "1", "2" } },
|
{ {}, { "" }, { "", "1", "2" } },
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
WorkerProtoTest,
|
WorkerProtoTest,
|
||||||
optionalStorePath,
|
optionalStorePath,
|
||||||
"optional-store-path",
|
"optional-store-path",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<std::optional<StorePath>, std::optional<StorePath>> {
|
(std::tuple<std::optional<StorePath>, std::optional<StorePath>> {
|
||||||
std::nullopt,
|
std::nullopt,
|
||||||
std::optional {
|
std::optional {
|
||||||
|
@ -256,10 +276,11 @@ CHARACTERIZATION_TEST(
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
WorkerProtoTest,
|
WorkerProtoTest,
|
||||||
optionalContentAddress,
|
optionalContentAddress,
|
||||||
"optional-content-address",
|
"optional-content-address",
|
||||||
|
defaultVersion,
|
||||||
(std::tuple<std::optional<ContentAddress>, std::optional<ContentAddress>> {
|
(std::tuple<std::optional<ContentAddress>, std::optional<ContentAddress>> {
|
||||||
std::nullopt,
|
std::nullopt,
|
||||||
std::optional {
|
std::optional {
|
||||||
|
|
Loading…
Reference in a new issue