forked from lix-project/lix
WIP: add TestingStore store implementation
Change-Id: I1e57895030665fb63d1c47cb4fc2b959b5761618
This commit is contained in:
parent
20981461d4
commit
31c21e8568
|
@ -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',
|
||||||
|
|
217
src/libstore/testing-store.cc
Normal file
217
src/libstore/testing-store.cc
Normal 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;
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue