WIP: add TestingStore store implementation

Change-Id: I1e57895030665fb63d1c47cb4fc2b959b5761618
This commit is contained in:
Qyriad 2024-05-20 18:25:12 -06:00
parent 1f86d81834
commit 53c6f7eb35
2 changed files with 218 additions and 0 deletions

View file

@ -40,6 +40,7 @@ libstore_sources = files(
'derived-path.cc', 'derived-path.cc',
'downstream-placeholder.cc', 'downstream-placeholder.cc',
'dummy-store.cc', 'dummy-store.cc',
'testing-store.cc',
'export-import.cc', 'export-import.cc',
'filetransfer.cc', 'filetransfer.cc',
'gc.cc', 'gc.cc',

View file

@ -0,0 +1,217 @@
#include <iostream>
#include <string>
#include <set>
#include <vector>
#include <boost/core/demangle.hpp>
#include "content-address.hh"
#include "hash.hh"
#include "path-info.hh"
#include "store-api.hh"
namespace nix
{
struct TestingStoreConfig : virtual StoreConfig
{
using StoreConfig::StoreConfig;
std::string const name() override
{
return "Testing Store";
}
std::string doc() override
{
return "<TODO>";
}
};
/** Like DummyStore, but keeps some track of what it's done and stubs rather than fails unsupported operations.
*
* Don't expect any operations on this to be at all fast lmao.
*/
struct TestingStore : public virtual TestingStoreConfig, public virtual Store
{
struct AddedPath
{
StorePath storePath;
ValidPathInfo pathInfo;
};
struct AddedText
{
std::string name;
std::string text;
StorePath storePath;
};
static std::set<std::string> uriSchemes()
{
return {"testing"};
}
std::vector<AddedPath> addedPaths;
std::vector<AddedText> addedText;
TestingStore(std::string const scheme, std::string const uri, Params const & params)
: TestingStore(params)
{ }
TestingStore(Params const & params)
: StoreConfig(params)
, TestingStoreConfig(params)
, Store(params)
{ }
virtual std::optional<TrustedFlag> isTrustedClient() override
{
return Trusted;
}
std::string getUri() override
{
return *this->uriSchemes().begin();
}
void addToStore(
ValidPathInfo const & info,
Source & source,
RepairFlag repair,
CheckSigsFlag checkSigs
) override
{
notice("testing store: adding path '%s'", this->printStorePath(info.path));
AddedPath added{
.storePath = info.path,
.pathInfo = info,
};
this->addedPaths.push_back(added);
}
virtual StorePath addToStoreFromDump(
Source & dump,
std::string_view name,
FileIngestionMethod method = FileIngestionMethod::Recursive,
HashType hashAlgo = htSHA256,
RepairFlag repair = NoRepair,
StorePathSet const & references = {}
) override
{
notice("testing store: adding path from Source %s", boost::core::demangle(typeid(dump).name()));
HashSink hashSink(hashAlgo);
TeeSource tee(dump, hashSink);
static constexpr uint64_t BUFSIZE = 32ULL * 1024ULL * 1024ULL;
std::vector<char> all;
char buffer[4096] = {0};
size_t got = tee.read(buffer, BUFSIZE);
while (got > 0) {
for (size_t i = 0; i < got; i++) {
all.push_back(buffer[i]);
}
got = tee.read(buffer, 4096);
}
auto const [hash, size] = hashSink.finish();
ContentAddressWithReferences caDesc(FixedOutputInfo{
.method = method,
.hash = hash,
.references = {
.others = references,
.self = false,
},
});
StorePath const dstPath = makeFixedOutputPathFromCA(name, caDesc);
HashSink narSink(htSHA256);
ValidPathInfo pathInfo{
*this,
name,
std::move(caDesc),
Hash(htSHA256),
};
AddedPath added{
.storePath = dstPath,
.pathInfo = pathInfo,
};
this->addedPaths.push_back(added);
return dstPath;
}
StorePath addTextToStore(
std::string_view name,
std::string_view text,
StorePathSet const & references,
[[maybe_unused]] RepairFlag repair
) override
{
auto const hash = hashString(htSHA256, text);
StorePath const dstPath = makeTextPath(name, TextInfo {
.hash = hash,
.references = references,
});
AddedText added{
.name = std::string(name),
.text = std::string(text),
.storePath = dstPath,
};
this->addedText.push_back(added);
return dstPath;
}
void narFromPath(StorePath const & path, Sink & sink) override
{
this->unsupported("narFromPath");
}
std::optional<StorePath> queryPathFromHashPart(std::string const & hashPart) override
{
for (auto const & addedPath : this->addedPaths) {
if (addedPath.storePath.hashPart() == hashPart) {
return std::make_optional(addedPath.storePath);
}
}
return std::nullopt;
}
std::shared_ptr<ValidPathInfo const> queryPathInfoUncached(StorePath const & path) override
{
for (auto const & addedPath : this->addedPaths) {
if (addedPath.storePath == path) {
return std::shared_ptr<ValidPathInfo const>(&addedPath.pathInfo);
}
}
return nullptr;
}
std::shared_ptr<Realisation const> queryRealisationUncached(DrvOutput const &) override
{
this->unsupported("queryRealisationUncached");
// return nullptr;
}
virtual ref<FSAccessor> getFSAccessor() override
{
this->unsupported("getFSAccessor");
}
};
static RegisterStoreImplementation<TestingStore, TestingStoreConfig> regTestingStore;
}