Merge remote-tracking branch 'me/no-stringly-typed-derivation-output' into validPathInfo-ca-proper-datatype

This commit is contained in:
John Ericson 2020-06-19 15:18:19 +00:00
commit 2f0e395c99
14 changed files with 108 additions and 42 deletions

View file

@ -776,7 +776,10 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
if (!jsonObject) drv.env["out"] = state.store->printStorePath(outPath); if (!jsonObject) drv.env["out"] = state.store->printStorePath(outPath);
drv.outputs.insert_or_assign("out", DerivationOutput { drv.outputs.insert_or_assign("out", DerivationOutput {
.path = std::move(outPath), .path = std::move(outPath),
.hash = FileSystemHash { ingestionMethod, std::move(h) }, .hash = FixedOutputHash {
.method = ingestionMethod,
.hash = std::move(h),
},
}); });
} }
@ -792,7 +795,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
drv.outputs.insert_or_assign(i, drv.outputs.insert_or_assign(i,
DerivationOutput { DerivationOutput {
.path = StorePath::dummy, .path = StorePath::dummy,
.hash = std::optional<FileSystemHash> {}, .hash = std::optional<FixedOutputHash> {},
}); });
} }
@ -804,7 +807,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
drv.outputs.insert_or_assign(i, drv.outputs.insert_or_assign(i,
DerivationOutput { DerivationOutput {
.path = std::move(outPath), .path = std::move(outPath),
.hash = std::optional<FileSystemHash>(), .hash = std::optional<FixedOutputHash>(),
}); });
} }
} }

View file

@ -70,7 +70,7 @@ DownloadFileResult downloadFile(
ValidPathInfo info(store->makeFixedOutputPath(FileIngestionMethod::Flat, hash, name)); ValidPathInfo info(store->makeFixedOutputPath(FileIngestionMethod::Flat, hash, name));
info.narHash = hashString(htSHA256, *sink.s); info.narHash = hashString(htSHA256, *sink.s);
info.narSize = sink.s->size(); info.narSize = sink.s->size();
info.ca = FileSystemHash { info.ca = FixedOutputHash {
FileIngestionMethod::Flat, FileIngestionMethod::Flat,
hash, hash,
}; };

View file

@ -3764,7 +3764,7 @@ void DerivationGoal::registerOutputs()
else else
assert(worker.store.parseStorePath(path) == dest); assert(worker.store.parseStorePath(path) == dest);
ca = FileSystemHash { i.second.hash->method, h2 }; ca = FixedOutputHash { i.second.hash->method, h2 };
} }
/* Get rid of all weird permissions. This also checks that /* Get rid of all weird permissions. This also checks that

View file

@ -2,7 +2,7 @@
namespace nix { namespace nix {
std::string FileSystemHash::printMethodAlgo() const { std::string FixedOutputHash::printMethodAlgo() const {
return makeFileIngestionPrefix(method) + printHashType(*hash.type); return makeFileIngestionPrefix(method) + printHashType(*hash.type);
} }
@ -33,7 +33,7 @@ std::string renderContentAddress(ContentAddress ca) {
[](TextHash th) { [](TextHash th) {
return "text:" + th.hash.to_string(Base32, true); return "text:" + th.hash.to_string(Base32, true);
}, },
[](FileSystemHash fsh) { [](FixedOutputHash fsh) {
return makeFixedOutputCA(fsh.method, fsh.hash); return makeFixedOutputCA(fsh.method, fsh.hash);
} }
}, ca); }, ca);
@ -55,10 +55,10 @@ ContentAddress parseContentAddress(std::string_view rawCa) {
auto methodAndHash = rawCa.substr(prefixSeparator+1, string::npos); auto methodAndHash = rawCa.substr(prefixSeparator+1, string::npos);
if (methodAndHash.substr(0,2) == "r:") { if (methodAndHash.substr(0,2) == "r:") {
std::string_view hashRaw = methodAndHash.substr(2,string::npos); std::string_view hashRaw = methodAndHash.substr(2,string::npos);
return FileSystemHash { FileIngestionMethod::Recursive, Hash(string(hashRaw)) }; return FixedOutputHash { FileIngestionMethod::Recursive, Hash(string(hashRaw)) };
} else { } else {
std::string_view hashRaw = methodAndHash; std::string_view hashRaw = methodAndHash;
return FileSystemHash { FileIngestionMethod::Flat, Hash(string(hashRaw)) }; return FixedOutputHash { FileIngestionMethod::Flat, Hash(string(hashRaw)) };
} }
} else { } else {
throw Error("parseContentAddress: format not recognized; has to be text or fixed"); throw Error("parseContentAddress: format not recognized; has to be text or fixed");

View file

@ -12,22 +12,12 @@ enum struct FileIngestionMethod : uint8_t {
struct TextHash { struct TextHash {
Hash hash; Hash hash;
TextHash(const TextHash &) = default;
TextHash(TextHash &&) = default;
TextHash & operator = (const TextHash &) = default;
}; };
/// Pair of a hash, and how the file system was ingested /// Pair of a hash, and how the file system was ingested
struct FileSystemHash { struct FixedOutputHash {
FileIngestionMethod method; FileIngestionMethod method;
Hash hash; Hash hash;
FileSystemHash(FileIngestionMethod method, Hash hash)
: method(std::move(method))
, hash(std::move(hash))
{ }
FileSystemHash(const FileSystemHash &) = default;
FileSystemHash(FileSystemHash &&) = default;
FileSystemHash & operator = (const FileSystemHash &) = default;
std::string printMethodAlgo() const; std::string printMethodAlgo() const;
}; };
@ -44,7 +34,7 @@ struct FileSystemHash {
*/ */
typedef std::variant< typedef std::variant<
TextHash, // for paths computed by makeTextPath() / addTextToStore TextHash, // for paths computed by makeTextPath() / addTextToStore
FileSystemHash // for path computed by makeFixedOutputPath FixedOutputHash // for path computed by makeFixedOutputPath
> ContentAddress; > ContentAddress;
/* Compute the prefix to the hash algorithm which indicates how the files were /* Compute the prefix to the hash algorithm which indicates how the files were

View file

@ -108,7 +108,7 @@ static DerivationOutput parseDerivationOutput(const Store & store, istringstream
expect(str, ","); const auto hash = parseString(str); expect(str, ","); const auto hash = parseString(str);
expect(str, ")"); expect(str, ")");
std::optional<FileSystemHash> fsh; std::optional<FixedOutputHash> fsh;
if (hashAlgo != "") { if (hashAlgo != "") {
auto method = FileIngestionMethod::Flat; auto method = FileIngestionMethod::Flat;
if (string(hashAlgo, 0, 2) == "r:") { if (string(hashAlgo, 0, 2) == "r:") {
@ -116,9 +116,9 @@ static DerivationOutput parseDerivationOutput(const Store & store, istringstream
hashAlgo = string(hashAlgo, 2); hashAlgo = string(hashAlgo, 2);
} }
const HashType hashType = parseHashType(hashAlgo); const HashType hashType = parseHashType(hashAlgo);
fsh = FileSystemHash { fsh = FixedOutputHash {
std::move(method), .method = std::move(method),
Hash(hash, hashType), .hash = Hash(hash, hashType),
}; };
} }
@ -406,7 +406,7 @@ static DerivationOutput readDerivationOutput(Source & in, const Store & store)
auto hashAlgo = readString(in); auto hashAlgo = readString(in);
const auto hash = readString(in); const auto hash = readString(in);
std::optional<FileSystemHash> fsh; std::optional<FixedOutputHash> fsh;
if (hashAlgo != "") { if (hashAlgo != "") {
auto method = FileIngestionMethod::Flat; auto method = FileIngestionMethod::Flat;
if (string(hashAlgo, 0, 2) == "r:") { if (string(hashAlgo, 0, 2) == "r:") {
@ -414,9 +414,9 @@ static DerivationOutput readDerivationOutput(Source & in, const Store & store)
hashAlgo = string(hashAlgo, 2); hashAlgo = string(hashAlgo, 2);
} }
const HashType hashType = parseHashType(hashAlgo); const HashType hashType = parseHashType(hashAlgo);
fsh = FileSystemHash { fsh = FixedOutputHash {
std::move(method), .method = std::move(method),
Hash(hash, hashType), .hash = Hash(hash, hashType),
}; };
} }

View file

@ -16,7 +16,7 @@ namespace nix {
struct DerivationOutput struct DerivationOutput
{ {
StorePath path; StorePath path;
std::optional<FileSystemHash> hash; /* hash used for expected hash computation */ std::optional<FixedOutputHash> hash; /* hash used for expected hash computation */
}; };
typedef std::map<string, DerivationOutput> DerivationOutputs; typedef std::map<string, DerivationOutput> DerivationOutputs;

View file

@ -1079,7 +1079,7 @@ StorePath LocalStore::addToStoreFromDump(const string & dump, const string & nam
ValidPathInfo info(dstPath); ValidPathInfo info(dstPath);
info.narHash = hash.first; info.narHash = hash.first;
info.narSize = hash.second; info.narSize = hash.second;
info.ca = FileSystemHash { method, h }; info.ca = FixedOutputHash { method, h };
registerValidPath(info); registerValidPath(info);
} }

View file

@ -769,7 +769,7 @@ bool ValidPathInfo::isContentAddressed(const Store & store) const
[&](TextHash th) { [&](TextHash th) {
return store.makeTextPath(path.name(), th.hash, references); return store.makeTextPath(path.name(), th.hash, references);
}, },
[&](FileSystemHash fsh) { [&](FixedOutputHash fsh) {
auto refs = references; auto refs = references;
bool hasSelfReference = false; bool hasSelfReference = false;
if (refs.count(path)) { if (refs.count(path)) {

View file

@ -48,12 +48,6 @@ struct Hash
// hash type must be part of string // hash type must be part of string
Hash(std::string_view s); Hash(std::string_view s);
Hash(const Hash &) = default;
Hash(Hash &&) = default;
Hash & operator = (const Hash &) = default;
void init(); void init();
/* Check whether a hash is set. */ /* Check whether a hash is set. */

View file

@ -0,0 +1,78 @@
#include "compression.hh"
#include <gtest/gtest.h>
namespace nix {
/* ----------------------------------------------------------------------------
* compress / decompress
* --------------------------------------------------------------------------*/
TEST(compress, compressWithUnknownMethod) {
ASSERT_THROW(compress("invalid-method", "something-to-compress"), UnknownCompressionMethod);
}
TEST(compress, noneMethodDoesNothingToTheInput) {
ref<std::string> o = compress("none", "this-is-a-test");
ASSERT_EQ(*o, "this-is-a-test");
}
TEST(decompress, decompressXzCompressed) {
auto method = "xz";
auto str = "slfja;sljfklsa;jfklsjfkl;sdjfkl;sadjfkl;sdjf;lsdfjsadlf";
ref<std::string> o = decompress(method, *compress(method, str));
ASSERT_EQ(*o, str);
}
TEST(decompress, decompressBzip2Compressed) {
auto method = "bzip2";
auto str = "slfja;sljfklsa;jfklsjfkl;sdjfkl;sadjfkl;sdjf;lsdfjsadlf";
ref<std::string> o = decompress(method, *compress(method, str));
ASSERT_EQ(*o, str);
}
TEST(decompress, decompressBrCompressed) {
auto method = "br";
auto str = "slfja;sljfklsa;jfklsjfkl;sdjfkl;sadjfkl;sdjf;lsdfjsadlf";
ref<std::string> o = decompress(method, *compress(method, str));
ASSERT_EQ(*o, str);
}
TEST(decompress, decompressInvalidInputThrowsCompressionError) {
auto method = "bzip2";
auto str = "this is a string that does not qualify as valid bzip2 data";
ASSERT_THROW(decompress(method, str), CompressionError);
}
/* ----------------------------------------------------------------------------
* compression sinks
* --------------------------------------------------------------------------*/
TEST(makeCompressionSink, noneSinkDoesNothingToInput) {
StringSink strSink;
auto inputString = "slfja;sljfklsa;jfklsjfkl;sdjfkl;sadjfkl;sdjf;lsdfjsadlf";
auto sink = makeCompressionSink("none", strSink);
(*sink)(inputString);
sink->finish();
ASSERT_STREQ((*strSink.s).c_str(), inputString);
}
TEST(makeCompressionSink, compressAndDecompress) {
StringSink strSink;
auto inputString = "slfja;sljfklsa;jfklsjfkl;sdjfkl;sadjfkl;sdjf;lsdfjsadlf";
auto decompressionSink = makeDecompressionSink("bzip2", strSink);
auto sink = makeCompressionSink("bzip2", *decompressionSink);
(*sink)(inputString);
sink->finish();
decompressionSink->finish();
ASSERT_STREQ((*strSink.s).c_str(), inputString);
}
}

View file

@ -48,7 +48,7 @@ struct CmdAddToStore : MixDryRun, StoreCommand
ValidPathInfo info(store->makeFixedOutputPath(FileIngestionMethod::Recursive, narHash, *namePart)); ValidPathInfo info(store->makeFixedOutputPath(FileIngestionMethod::Recursive, narHash, *namePart));
info.narHash = narHash; info.narHash = narHash;
info.narSize = sink.s->size(); info.narSize = sink.s->size();
info.ca = std::optional { FileSystemHash { info.ca = std::optional { FixedOutputHash {
FileIngestionMethod::Recursive, FileIngestionMethod::Recursive,
info.narHash, info.narHash,
} }; } };

View file

@ -137,8 +137,9 @@ StorePath getDerivationEnvironment(ref<Store> store, const StorePath & drvPath)
auto shellOutPath = store->makeOutputPath("out", h, drvName); auto shellOutPath = store->makeOutputPath("out", h, drvName);
drv.outputs.insert_or_assign("out", DerivationOutput { drv.outputs.insert_or_assign("out", DerivationOutput {
.path = shellOutPath, .path = shellOutPath,
.hash = FileSystemHash { .hash = FixedOutputHash {
FileIngestionMethod::Flat, Hash { } .method = FileIngestionMethod::Flat,
.hash = Hash { },
}, },
}); });
drv.env["out"] = store->printStorePath(shellOutPath); drv.env["out"] = store->printStorePath(shellOutPath);

View file

@ -82,7 +82,7 @@ struct CmdMakeContentAddressable : StorePathsCommand, MixJSON
if (hasSelfReference) info.references.insert(info.path); if (hasSelfReference) info.references.insert(info.path);
info.narHash = narHash; info.narHash = narHash;
info.narSize = sink.s->size(); info.narSize = sink.s->size();
info.ca = FileSystemHash { info.ca = FixedOutputHash {
FileIngestionMethod::Recursive, FileIngestionMethod::Recursive,
info.narHash, info.narHash,
}; };