1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-08 19:46:02 +01:00

JSON impl for DummyStore

This commit is contained in:
John Ericson 2025-09-28 02:15:20 -04:00
parent 12760756bb
commit f7dcfd1072
7 changed files with 266 additions and 0 deletions

View file

@ -0,0 +1,6 @@
{
"build-trace": {},
"contents": {},
"derivations": {},
"store-dir": "/nix/store"
}

View file

@ -0,0 +1,18 @@
{
"build-trace": {},
"contents": {},
"derivations": {
"rlqjbbb65ggcx9hy577hvnn929wz1aj0-foo.drv": {
"args": [],
"builder": "",
"env": {},
"inputDrvs": {},
"inputSrcs": [],
"name": "foo",
"outputs": {},
"system": "",
"version": 4
}
},
"store-dir": "/nix/store"
}

View file

@ -0,0 +1,35 @@
{
"build-trace": {},
"contents": {
"5hizn7xyyrhxr0k2magvxl5ccvk0ci9n-my-file": {
"contents": {
"contents": "asdf",
"executable": false,
"type": "regular"
},
"info": {
"ca": {
"hash": {
"algorithm": "sha256",
"format": "base64",
"hash": "f1eduuSIYC1BofXA1tycF79Ai2NSMJQtUErx5DxLYSU="
},
"method": "nar"
},
"deriver": null,
"narHash": {
"algorithm": "sha256",
"format": "base64",
"hash": "f1eduuSIYC1BofXA1tycF79Ai2NSMJQtUErx5DxLYSU="
},
"narSize": 120,
"references": [],
"registrationTime": null,
"signatures": [],
"ultimate": false
}
}
},
"derivations": {},
"store-dir": "/nix/store"
}

View file

@ -1,11 +1,32 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <nlohmann/json.hpp>
#include "nix/util/memory-source-accessor.hh"
#include "nix/store/dummy-store-impl.hh" #include "nix/store/dummy-store-impl.hh"
#include "nix/store/globals.hh" #include "nix/store/globals.hh"
#include "nix/store/realisation.hh" #include "nix/store/realisation.hh"
#include "nix/util/tests/json-characterization.hh"
namespace nix { namespace nix {
class DummyStoreTest : public virtual CharacterizationTest
{
std::filesystem::path unitTestData = getUnitTestData() / "dummy-store";
public:
std::filesystem::path goldenMaster(std::string_view testStem) const override
{
return unitTestData / testStem;
}
static void SetUpTestSuite()
{
initLibStore(false);
}
};
TEST(DummyStore, realisation_read) TEST(DummyStore, realisation_read)
{ {
initLibStore(/*loadConfig=*/false); initLibStore(/*loadConfig=*/false);
@ -35,4 +56,76 @@ TEST(DummyStore, realisation_read)
EXPECT_EQ(*value2, value); EXPECT_EQ(*value2, value);
} }
/* ----------------------------------------------------------------------------
* JSON
* --------------------------------------------------------------------------*/
using nlohmann::json;
struct DummyStoreJsonTest : DummyStoreTest,
JsonCharacterizationTest<ref<DummyStore>>,
::testing::WithParamInterface<std::pair<std::string_view, ref<DummyStore>>>
{};
TEST_P(DummyStoreJsonTest, from_json)
{
auto & [name, expected] = GetParam();
using namespace nlohmann;
/* Cannot use `readJsonTest` because need to dereference the stores
for equality. */
readTest(Path{name} + ".json", [&](const auto & encodedRaw) {
auto encoded = json::parse(encodedRaw);
ref<DummyStore> decoded = adl_serializer<ref<DummyStore>>::from_json(encoded);
ASSERT_EQ(*decoded, *expected);
});
}
TEST_P(DummyStoreJsonTest, to_json)
{
auto & [name, value] = GetParam();
writeJsonTest(name, value);
}
INSTANTIATE_TEST_SUITE_P(DummyStoreJSON, DummyStoreJsonTest, [] {
initLibStore(false);
auto writeCfg = make_ref<DummyStore::Config>(DummyStore::Config::Params{});
writeCfg->readOnly = false;
return ::testing::Values(
std::pair{
"empty",
make_ref<DummyStore::Config>(DummyStore::Config::Params{})->openDummyStore(),
},
std::pair{
"one-flat-file",
[&] {
auto store = writeCfg->openDummyStore();
store->addToStore(
"my-file",
SourcePath{
[] {
auto sc = make_ref<MemorySourceAccessor>();
sc->root = MemorySourceAccessor::File{MemorySourceAccessor::File::Regular{
.executable = false,
.contents = "asdf",
}};
return sc;
}(),
},
ContentAddressMethod::Raw::NixArchive,
HashAlgorithm::SHA256);
return store;
}(),
},
std::pair{
"one-derivation",
[&] {
auto store = writeCfg->openDummyStore();
Derivation drv;
drv.name = "foo";
store->writeDerivation(drv);
return store;
}(),
});
}());
} // namespace nix } // namespace nix

View file

@ -2,6 +2,7 @@
#include "nix/util/archive.hh" #include "nix/util/archive.hh"
#include "nix/util/callback.hh" #include "nix/util/callback.hh"
#include "nix/util/memory-source-accessor.hh" #include "nix/util/memory-source-accessor.hh"
#include "nix/util/json-utils.hh"
#include "nix/store/dummy-store-impl.hh" #include "nix/store/dummy-store-impl.hh"
#include "nix/store/realisation.hh" #include "nix/store/realisation.hh"
@ -16,6 +17,16 @@ std::string DummyStoreConfig::doc()
; ;
} }
bool DummyStore::PathInfoAndContents::operator==(const PathInfoAndContents & other) const
{
return info == other.info && contents->root == other.contents->root;
}
bool DummyStore::operator==(const DummyStore & other) const
{
return contents == other.contents && buildTrace == other.buildTrace;
}
namespace { namespace {
class WholeStoreViewAccessor : public SourceAccessor class WholeStoreViewAccessor : public SourceAccessor
@ -377,3 +388,89 @@ ref<DummyStore> DummyStore::Config::openDummyStore() const
static RegisterStoreImplementation<DummyStore::Config> regDummyStore; static RegisterStoreImplementation<DummyStore::Config> regDummyStore;
} // namespace nix } // namespace nix
namespace nlohmann {
using namespace nix;
DummyStore::PathInfoAndContents adl_serializer<DummyStore::PathInfoAndContents>::from_json(const json & json)
{
auto & obj = getObject(json);
return DummyStore::PathInfoAndContents{
.info = valueAt(obj, "info"),
.contents = make_ref<MemorySourceAccessor>(valueAt(obj, "contents")),
};
}
void adl_serializer<DummyStore::PathInfoAndContents>::to_json(json & json, const DummyStore::PathInfoAndContents & val)
{
json = {
{"info", val.info},
{"contents", *val.contents},
};
}
ref<DummyStore> adl_serializer<ref<DummyStore>>::from_json(const json & json)
{
auto & obj = getObject(json);
ref<DummyStore> res = [&] {
auto cfg = make_ref<DummyStore::Config>(DummyStore::Config::Params{});
const_cast<PathSetting &>(cfg->storeDir_).set(getString(valueAt(obj, "store-dir")));
cfg->readOnly = true;
return cfg->openDummyStore();
}();
for (auto & [k, v] : getObject(valueAt(obj, "contents")))
res->contents.insert({StorePath{k}, v});
for (auto & [k, v] : getObject(valueAt(obj, "derivations")))
res->derivations.insert({StorePath{k}, v});
for (auto & [k0, v] : getObject(valueAt(obj, "build-trace"))) {
for (auto & [k1, v2] : getObject(v)) {
auto vref = make_ref<UnkeyedRealisation>(v2);
res->buildTrace.insert_or_visit(
{
Hash::parseExplicitFormatUnprefixed(k0, HashAlgorithm::SHA256, HashFormat::Base64),
{{k1, vref}},
},
[&](auto & kv) { kv.second.insert_or_assign(k1, vref); });
}
}
return res;
}
void adl_serializer<ref<DummyStore>>::to_json(json & json, const ref<DummyStore> & val)
{
json = {
{"store-dir", val->storeDir},
{"contents",
[&] {
auto obj = json::object();
val->contents.cvisit_all([&](const auto & kv) {
auto & [k, v] = kv;
obj[k.to_string()] = v;
});
return obj;
}()},
{"derivations",
[&] {
auto obj = json::object();
val->derivations.cvisit_all([&](const auto & kv) {
auto & [k, v] = kv;
obj[k.to_string()] = v;
});
return obj;
}()},
{"build-trace",
[&] {
auto obj = json::object();
val->buildTrace.cvisit_all([&](const auto & kv) {
auto & [k, v] = kv;
auto & obj2 = obj[k.to_string(HashFormat::Base64, false)] = json::object();
for (auto & [k2, v2] : kv.second)
obj2[k2] = *v2;
});
return obj;
}()},
};
}
} // namespace nlohmann

View file

@ -23,6 +23,8 @@ struct DummyStore : virtual Store
{ {
UnkeyedValidPathInfo info; UnkeyedValidPathInfo info;
ref<MemorySourceAccessor> contents; ref<MemorySourceAccessor> contents;
bool operator==(const PathInfoAndContents &) const;
}; };
/** /**
@ -54,6 +56,14 @@ struct DummyStore : virtual Store
, config(config) , config(config)
{ {
} }
bool operator==(const DummyStore &) const;
}; };
template<>
struct json_avoids_null<DummyStore::PathInfoAndContents> : std::true_type
{};
} // namespace nix } // namespace nix
JSON_IMPL(nix::DummyStore::PathInfoAndContents)

View file

@ -2,6 +2,7 @@
///@file ///@file
#include "nix/store/store-api.hh" #include "nix/store/store-api.hh"
#include "nix/util/json-impls.hh"
#include <boost/unordered/concurrent_flat_map.hpp> #include <boost/unordered/concurrent_flat_map.hpp>
@ -65,4 +66,10 @@ struct DummyStoreConfig : public std::enable_shared_from_this<DummyStoreConfig>,
} }
}; };
template<>
struct json_avoids_null<ref<nix::DummyStore>> : std::true_type
{};
} // namespace nix } // namespace nix
JSON_IMPL(nix::ref<nix::DummyStore>)