aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2024-01-11 07:21:16 -0500
committerShea Levy <shea@shealevy.com>2024-01-11 07:21:16 -0500
commitba48ab4b954dd1c8af388d1c5a33bbd62373c6f5 (patch)
treef17f8492bed32f78c04d9d4e9ffd2b672af85943 /src/libstore
parente7c2b35827e9f4ddbec4248c5cf1ad793a2988ad (diff)
parent4dd5171652018e29bf9e496522df3be51d615a2c (diff)
Merge branch '2.18-maintenance' into ifd-buildStore-2.18
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/build/create-derivation-and-realise-goal.cc157
-rw-r--r--src/libstore/build/create-derivation-and-realise-goal.hh96
-rw-r--r--src/libstore/build/derivation-goal.cc33
-rw-r--r--src/libstore/build/derivation-goal.hh5
-rw-r--r--src/libstore/build/entry-points.cc11
-rw-r--r--src/libstore/build/goal.hh10
-rw-r--r--src/libstore/build/worker.cc110
-rw-r--r--src/libstore/build/worker.hh24
-rw-r--r--src/libstore/derived-path-map.cc3
-rw-r--r--src/libstore/derived-path-map.hh7
-rw-r--r--src/libstore/gc.cc2
-rw-r--r--src/libstore/globals.cc31
-rw-r--r--src/libstore/globals.hh1
-rw-r--r--src/libstore/path-regex.hh2
-rw-r--r--src/libstore/path.cc2
-rw-r--r--src/libstore/tests/derivation.cc369
-rw-r--r--src/libstore/tests/derived-path.cc153
-rw-r--r--src/libstore/tests/derived-path.hh39
-rw-r--r--src/libstore/tests/downstream-placeholder.cc41
-rw-r--r--src/libstore/tests/libstore.hh26
-rw-r--r--src/libstore/tests/local.mk29
-rw-r--r--src/libstore/tests/machines.cc169
-rw-r--r--src/libstore/tests/nar-info-disk-cache.cc123
-rw-r--r--src/libstore/tests/outputs-spec.cc239
-rw-r--r--src/libstore/tests/outputs-spec.hh18
-rw-r--r--src/libstore/tests/path.cc157
-rw-r--r--src/libstore/tests/path.hh29
-rw-r--r--src/libstore/tests/references.cc45
-rw-r--r--src/libstore/tests/test-data/machines.bad_format1
-rw-r--r--src/libstore/tests/test-data/machines.valid3
30 files changed, 88 insertions, 1847 deletions
diff --git a/src/libstore/build/create-derivation-and-realise-goal.cc b/src/libstore/build/create-derivation-and-realise-goal.cc
deleted file mode 100644
index 60f67956d..000000000
--- a/src/libstore/build/create-derivation-and-realise-goal.cc
+++ /dev/null
@@ -1,157 +0,0 @@
-#include "create-derivation-and-realise-goal.hh"
-#include "worker.hh"
-
-namespace nix {
-
-CreateDerivationAndRealiseGoal::CreateDerivationAndRealiseGoal(ref<SingleDerivedPath> drvReq,
- const OutputsSpec & wantedOutputs, Worker & worker, BuildMode buildMode)
- : Goal(worker, DerivedPath::Built { .drvPath = drvReq, .outputs = wantedOutputs })
- , drvReq(drvReq)
- , wantedOutputs(wantedOutputs)
- , buildMode(buildMode)
-{
- state = &CreateDerivationAndRealiseGoal::getDerivation;
- name = fmt(
- "outer obtaining drv from '%s' and then building outputs %s",
- drvReq->to_string(worker.store),
- std::visit(overloaded {
- [&](const OutputsSpec::All) -> std::string {
- return "* (all of them)";
- },
- [&](const OutputsSpec::Names os) {
- return concatStringsSep(", ", quoteStrings(os));
- },
- }, wantedOutputs.raw));
- trace("created outer");
-
- worker.updateProgress();
-}
-
-
-CreateDerivationAndRealiseGoal::~CreateDerivationAndRealiseGoal()
-{
-}
-
-
-static StorePath pathPartOfReq(const SingleDerivedPath & req)
-{
- return std::visit(overloaded {
- [&](const SingleDerivedPath::Opaque & bo) {
- return bo.path;
- },
- [&](const SingleDerivedPath::Built & bfd) {
- return pathPartOfReq(*bfd.drvPath);
- },
- }, req.raw());
-}
-
-
-std::string CreateDerivationAndRealiseGoal::key()
-{
- /* Ensure that derivations get built in order of their name,
- i.e. a derivation named "aardvark" always comes before "baboon". And
- substitution goals and inner derivation goals always happen before
- derivation goals (due to "b$"). */
- return "c$" + std::string(pathPartOfReq(*drvReq).name()) + "$" + drvReq->to_string(worker.store);
-}
-
-
-void CreateDerivationAndRealiseGoal::timedOut(Error && ex)
-{
-}
-
-
-void CreateDerivationAndRealiseGoal::work()
-{
- (this->*state)();
-}
-
-
-void CreateDerivationAndRealiseGoal::addWantedOutputs(const OutputsSpec & outputs)
-{
- /* If we already want all outputs, there is nothing to do. */
- auto newWanted = wantedOutputs.union_(outputs);
- bool needRestart = !newWanted.isSubsetOf(wantedOutputs);
- wantedOutputs = newWanted;
-
- if (!needRestart) return;
-
- if (!optDrvPath)
- // haven't started steps where the outputs matter yet
- return;
- worker.makeDerivationGoal(*optDrvPath, outputs, buildMode);
-}
-
-
-void CreateDerivationAndRealiseGoal::getDerivation()
-{
- trace("outer init");
-
- /* The first thing to do is to make sure that the derivation
- exists. If it doesn't, it may be created through a
- substitute. */
- if (auto optDrvPath = [this]() -> std::optional<StorePath> {
- if (buildMode != bmNormal) return std::nullopt;
-
- auto drvPath = StorePath::dummy;
- try {
- drvPath = resolveDerivedPath(worker.store, *drvReq);
- } catch (MissingRealisation &) {
- return std::nullopt;
- }
- return worker.evalStore.isValidPath(drvPath) || worker.store.isValidPath(drvPath)
- ? std::optional { drvPath }
- : std::nullopt;
- }()) {
- trace(fmt("already have drv '%s' for '%s', can go straight to building",
- worker.store.printStorePath(*optDrvPath),
- drvReq->to_string(worker.store)));
-
- loadAndBuildDerivation();
- } else {
- trace("need to obtain drv we want to build");
-
- addWaitee(worker.makeGoal(DerivedPath::fromSingle(*drvReq)));
-
- state = &CreateDerivationAndRealiseGoal::loadAndBuildDerivation;
- if (waitees.empty()) work();
- }
-}
-
-
-void CreateDerivationAndRealiseGoal::loadAndBuildDerivation()
-{
- trace("outer load and build derivation");
-
- if (nrFailed != 0) {
- amDone(ecFailed, Error("cannot build missing derivation '%s'", drvReq->to_string(worker.store)));
- return;
- }
-
- StorePath drvPath = resolveDerivedPath(worker.store, *drvReq);
- /* Build this step! */
- concreteDrvGoal = worker.makeDerivationGoal(drvPath, wantedOutputs, buildMode);
- addWaitee(upcast_goal(concreteDrvGoal));
- state = &CreateDerivationAndRealiseGoal::buildDone;
- optDrvPath = std::move(drvPath);
- if (waitees.empty()) work();
-}
-
-
-void CreateDerivationAndRealiseGoal::buildDone()
-{
- trace("outer build done");
-
- buildResult = upcast_goal(concreteDrvGoal)->getBuildResult(DerivedPath::Built {
- .drvPath = drvReq,
- .outputs = wantedOutputs,
- });
-
- if (buildResult.success())
- amDone(ecSuccess);
- else
- amDone(ecFailed, Error("building '%s' failed", drvReq->to_string(worker.store)));
-}
-
-
-}
diff --git a/src/libstore/build/create-derivation-and-realise-goal.hh b/src/libstore/build/create-derivation-and-realise-goal.hh
deleted file mode 100644
index ca936fc95..000000000
--- a/src/libstore/build/create-derivation-and-realise-goal.hh
+++ /dev/null
@@ -1,96 +0,0 @@
-#pragma once
-
-#include "parsed-derivations.hh"
-#include "lock.hh"
-#include "store-api.hh"
-#include "pathlocks.hh"
-#include "goal.hh"
-
-namespace nix {
-
-struct DerivationGoal;
-
-/**
- * This goal type is essentially the serial composition (like function
- * composition) of a goal for getting a derivation, and then a
- * `DerivationGoal` using the newly-obtained derivation.
- *
- * In the (currently experimental) general inductive case of derivations
- * that are themselves build outputs, that first goal will be *another*
- * `CreateDerivationAndRealiseGoal`. In the (much more common) base-case
- * where the derivation has no provence and is just referred to by
- * (content-addressed) store path, that first goal is a
- * `SubstitutionGoal`.
- *
- * If we already have the derivation (e.g. if the evalutator has created
- * the derivation locally and then instructured the store to build it),
- * we can skip the first goal entirely as a small optimization.
- */
-struct CreateDerivationAndRealiseGoal : public Goal
-{
- /**
- * How to obtain a store path of the derivation to build.
- */
- ref<SingleDerivedPath> drvReq;
-
- /**
- * The path of the derivation, once obtained.
- **/
- std::optional<StorePath> optDrvPath;
-
- /**
- * The goal for the corresponding concrete derivation.
- **/
- std::shared_ptr<DerivationGoal> concreteDrvGoal;
-
- /**
- * The specific outputs that we need to build.
- */
- OutputsSpec wantedOutputs;
-
- typedef void (CreateDerivationAndRealiseGoal::*GoalState)();
- GoalState state;
-
- /**
- * The final output paths of the build.
- *
- * - For input-addressed derivations, always the precomputed paths
- *
- * - For content-addressed derivations, calcuated from whatever the
- * hash ends up being. (Note that fixed outputs derivations that
- * produce the "wrong" output still install that data under its
- * true content-address.)
- */
- OutputPathMap finalOutputs;
-
- BuildMode buildMode;
-
- CreateDerivationAndRealiseGoal(ref<SingleDerivedPath> drvReq,
- const OutputsSpec & wantedOutputs, Worker & worker,
- BuildMode buildMode = bmNormal);
- virtual ~CreateDerivationAndRealiseGoal();
-
- void timedOut(Error && ex) override;
-
- std::string key() override;
-
- void work() override;
-
- /**
- * Add wanted outputs to an already existing derivation goal.
- */
- void addWantedOutputs(const OutputsSpec & outputs);
-
- /**
- * The states.
- */
- void getDerivation();
- void loadAndBuildDerivation();
- void buildDone();
-
- JobCategory jobCategory() const override {
- return JobCategory::Administration;
- };
-};
-
-}
diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc
index 6472ecd99..83c0a3135 100644
--- a/src/libstore/build/derivation-goal.cc
+++ b/src/libstore/build/derivation-goal.cc
@@ -71,7 +71,7 @@ DerivationGoal::DerivationGoal(const StorePath & drvPath,
, wantedOutputs(wantedOutputs)
, buildMode(buildMode)
{
- state = &DerivationGoal::loadDerivation;
+ state = &DerivationGoal::getDerivation;
name = fmt(
"building of '%s' from .drv file",
DerivedPath::Built { makeConstantStorePathRef(drvPath), wantedOutputs }.to_string(worker.store));
@@ -164,6 +164,24 @@ void DerivationGoal::addWantedOutputs(const OutputsSpec & outputs)
}
+void DerivationGoal::getDerivation()
+{
+ trace("init");
+
+ /* The first thing to do is to make sure that the derivation
+ exists. If it doesn't, it may be created through a
+ substitute. */
+ if (buildMode == bmNormal && worker.evalStore.isValidPath(drvPath)) {
+ loadDerivation();
+ return;
+ }
+
+ addWaitee(upcast_goal(worker.makePathSubstitutionGoal(drvPath)));
+
+ state = &DerivationGoal::loadDerivation;
+}
+
+
void DerivationGoal::loadDerivation()
{
trace("loading derivation");
@@ -1498,24 +1516,23 @@ void DerivationGoal::waiteeDone(GoalPtr waitee, ExitCode result)
if (!useDerivation) return;
auto & fullDrv = *dynamic_cast<Derivation *>(drv.get());
- std::optional info = tryGetConcreteDrvGoal(waitee);
- if (!info) return;
- const auto & [dg, drvReq] = *info;
+ auto * dg = dynamic_cast<DerivationGoal *>(&*waitee);
+ if (!dg) return;
- auto * nodeP = fullDrv.inputDrvs.findSlot(drvReq.get());
+ auto * nodeP = fullDrv.inputDrvs.findSlot(DerivedPath::Opaque { .path = dg->drvPath });
if (!nodeP) return;
auto & outputs = nodeP->value;
for (auto & outputName : outputs) {
- auto buildResult = dg.get().getBuildResult(DerivedPath::Built {
- .drvPath = makeConstantStorePathRef(dg.get().drvPath),
+ auto buildResult = dg->getBuildResult(DerivedPath::Built {
+ .drvPath = makeConstantStorePathRef(dg->drvPath),
.outputs = OutputsSpec::Names { outputName },
});
if (buildResult.success()) {
auto i = buildResult.builtOutputs.find(outputName);
if (i != buildResult.builtOutputs.end())
inputDrvOutputs.insert_or_assign(
- { dg.get().drvPath, outputName },
+ { dg->drvPath, outputName },
i->second.outPath);
}
}
diff --git a/src/libstore/build/derivation-goal.hh b/src/libstore/build/derivation-goal.hh
index 62b122c27..ddb5ee1e3 100644
--- a/src/libstore/build/derivation-goal.hh
+++ b/src/libstore/build/derivation-goal.hh
@@ -52,10 +52,6 @@ struct InitialOutput {
/**
* A goal for building some or all of the outputs of a derivation.
- *
- * The derivation must already be present, either in the store in a drv
- * or in memory. If the derivation itself needs to be gotten first, a
- * `CreateDerivationAndRealiseGoal` goal must be used instead.
*/
struct DerivationGoal : public Goal
{
@@ -235,6 +231,7 @@ struct DerivationGoal : public Goal
/**
* The states.
*/
+ void getDerivation();
void loadDerivation();
void haveDerivation();
void outputsSubstitutionTried();
diff --git a/src/libstore/build/entry-points.cc b/src/libstore/build/entry-points.cc
index f0f0e5519..13ff22f45 100644
--- a/src/libstore/build/entry-points.cc
+++ b/src/libstore/build/entry-points.cc
@@ -1,6 +1,5 @@
#include "worker.hh"
#include "substitution-goal.hh"
-#include "create-derivation-and-realise-goal.hh"
#include "derivation-goal.hh"
#include "local-store.hh"
@@ -16,7 +15,7 @@ void Store::buildPaths(const std::vector<DerivedPath> & reqs, BuildMode buildMod
worker.run(goals);
- StringSet failed;
+ StorePathSet failed;
std::optional<Error> ex;
for (auto & i : goals) {
if (i->ex) {
@@ -26,10 +25,10 @@ void Store::buildPaths(const std::vector<DerivedPath> & reqs, BuildMode buildMod
ex = std::move(i->ex);
}
if (i->exitCode != Goal::ecSuccess) {
- if (auto i2 = dynamic_cast<CreateDerivationAndRealiseGoal *>(i.get()))
- failed.insert(i2->drvReq->to_string(*this));
+ if (auto i2 = dynamic_cast<DerivationGoal *>(i.get()))
+ failed.insert(i2->drvPath);
else if (auto i2 = dynamic_cast<PathSubstitutionGoal *>(i.get()))
- failed.insert(printStorePath(i2->storePath));
+ failed.insert(i2->storePath);
}
}
@@ -38,7 +37,7 @@ void Store::buildPaths(const std::vector<DerivedPath> & reqs, BuildMode buildMod
throw std::move(*ex);
} else if (!failed.empty()) {
if (ex) logError(ex->info());
- throw Error(worker.failingExitStatus(), "build of %s failed", concatStringsSep(", ", quoteStrings(failed)));
+ throw Error(worker.failingExitStatus(), "build of %s failed", showPaths(failed));
}
}
diff --git a/src/libstore/build/goal.hh b/src/libstore/build/goal.hh
index 01d3c3491..9af083230 100644
--- a/src/libstore/build/goal.hh
+++ b/src/libstore/build/goal.hh
@@ -49,16 +49,6 @@ enum struct JobCategory {
* A substitution an arbitrary store object; it will use network resources.
*/
Substitution,
- /**
- * A goal that does no "real" work by itself, and just exists to depend on
- * other goals which *do* do real work. These goals therefore are not
- * limited.
- *
- * These goals cannot infinitely create themselves, so there is no risk of
- * a "fork bomb" type situation (which would be a problem even though the
- * goal do no real work) either.
- */
- Administration,
};
struct Goal : public std::enable_shared_from_this<Goal>
diff --git a/src/libstore/build/worker.cc b/src/libstore/build/worker.cc
index b4a634e7b..37cb86b91 100644
--- a/src/libstore/build/worker.cc
+++ b/src/libstore/build/worker.cc
@@ -2,7 +2,6 @@
#include "worker.hh"
#include "substitution-goal.hh"
#include "drv-output-substitution-goal.hh"
-#include "create-derivation-and-realise-goal.hh"
#include "local-derivation-goal.hh"
#include "hook-instance.hh"
@@ -42,24 +41,6 @@ Worker::~Worker()
}
-std::shared_ptr<CreateDerivationAndRealiseGoal> Worker::makeCreateDerivationAndRealiseGoal(
- ref<SingleDerivedPath> drvReq,
- const OutputsSpec & wantedOutputs,
- BuildMode buildMode)
-{
- std::weak_ptr<CreateDerivationAndRealiseGoal> & goal_weak = outerDerivationGoals.ensureSlot(*drvReq).value;
- std::shared_ptr<CreateDerivationAndRealiseGoal> goal = goal_weak.lock();
- if (!goal) {
- goal = std::make_shared<CreateDerivationAndRealiseGoal>(drvReq, wantedOutputs, *this, buildMode);
- goal_weak = goal;
- wakeUp(goal);
- } else {
- goal->addWantedOutputs(wantedOutputs);
- }
- return goal;
-}
-
-
std::shared_ptr<DerivationGoal> Worker::makeDerivationGoalCommon(
const StorePath & drvPath,
const OutputsSpec & wantedOutputs,
@@ -130,7 +111,10 @@ GoalPtr Worker::makeGoal(const DerivedPath & req, BuildMode buildMode)
{
return std::visit(overloaded {
[&](const DerivedPath::Built & bfd) -> GoalPtr {
- return makeCreateDerivationAndRealiseGoal(bfd.drvPath, bfd.outputs, buildMode);
+ if (auto bop = std::get_if<DerivedPath::Opaque>(&*bfd.drvPath))
+ return makeDerivationGoal(bop->path, bfd.outputs, buildMode);
+ else
+ throw UnimplementedError("Building dynamic derivations in one shot is not yet implemented.");
},
[&](const DerivedPath::Opaque & bo) -> GoalPtr {
return makePathSubstitutionGoal(bo.path, buildMode == bmRepair ? Repair : NoRepair);
@@ -139,46 +123,24 @@ GoalPtr Worker::makeGoal(const DerivedPath & req, BuildMode buildMode)
}
-template<typename K, typename V, typename F>
-static void cullMap(std::map<K, V> & goalMap, F f)
-{
- for (auto i = goalMap.begin(); i != goalMap.end();)
- if (!f(i->second))
- i = goalMap.erase(i);
- else ++i;
-}
-
-
template<typename K, typename G>
static void removeGoal(std::shared_ptr<G> goal, std::map<K, std::weak_ptr<G>> & goalMap)
{
/* !!! inefficient */
- cullMap(goalMap, [&](const std::weak_ptr<G> & gp) -> bool {
- return gp.lock() != goal;
- });
-}
-
-template<typename K>
-static void removeGoal(std::shared_ptr<CreateDerivationAndRealiseGoal> goal, std::map<K, DerivedPathMap<std::weak_ptr<CreateDerivationAndRealiseGoal>>::ChildNode> & goalMap);
-
-template<typename K>
-static void removeGoal(std::shared_ptr<CreateDerivationAndRealiseGoal> goal, std::map<K, DerivedPathMap<std::weak_ptr<CreateDerivationAndRealiseGoal>>::ChildNode> & goalMap)
-{
- /* !!! inefficient */
- cullMap(goalMap, [&](DerivedPathMap<std::weak_ptr<CreateDerivationAndRealiseGoal>>::ChildNode & node) -> bool {
- if (node.value.lock() == goal)
- node.value.reset();
- removeGoal(goal, node.childMap);
- return !node.value.expired() || !node.childMap.empty();
- });
+ for (auto i = goalMap.begin();
+ i != goalMap.end(); )
+ if (i->second.lock() == goal) {
+ auto j = i; ++j;
+ goalMap.erase(i);
+ i = j;
+ }
+ else ++i;
}
void Worker::removeGoal(GoalPtr goal)
{
- if (auto drvGoal = std::dynamic_pointer_cast<CreateDerivationAndRealiseGoal>(goal))
- nix::removeGoal(drvGoal, outerDerivationGoals.map);
- else if (auto drvGoal = std::dynamic_pointer_cast<DerivationGoal>(goal))
+ if (auto drvGoal = std::dynamic_pointer_cast<DerivationGoal>(goal))
nix::removeGoal(drvGoal, derivationGoals);
else if (auto subGoal = std::dynamic_pointer_cast<PathSubstitutionGoal>(goal))
nix::removeGoal(subGoal, substitutionGoals);
@@ -236,19 +198,8 @@ void Worker::childStarted(GoalPtr goal, const std::set<int> & fds,
child.respectTimeouts = respectTimeouts;
children.emplace_back(child);
if (inBuildSlot) {
- switch (goal->jobCategory()) {
- case JobCategory::Substitution:
- nrSubstitutions++;
- break;
- case JobCategory::Build:
- nrLocalBuilds++;
- break;
- case JobCategory::Administration:
- /* Intentionally not limited, see docs */
- break;
- default:
- abort();
- }
+ if (goal->jobCategory() == JobCategory::Substitution) nrSubstitutions++;
+ else nrLocalBuilds++;
}
}
@@ -260,20 +211,12 @@ void Worker::childTerminated(Goal * goal, bool wakeSleepers)
if (i == children.end()) return;
if (i->inBuildSlot) {
- switch (goal->jobCategory()) {
- case JobCategory::Substitution:
+ if (goal->jobCategory() == JobCategory::Substitution) {
assert(nrSubstitutions > 0);
nrSubstitutions--;
- break;
- case JobCategory::Build:
+ } else {
assert(nrLocalBuilds > 0);
nrLocalBuilds--;
- break;
- case JobCategory::Administration:
- /* Intentionally not limited, see docs */
- break;
- default:
- abort();
}
}
@@ -324,9 +267,9 @@ void Worker::run(const Goals & _topGoals)
for (auto & i : _topGoals) {
topGoals.insert(i);
- if (auto goal = dynamic_cast<CreateDerivationAndRealiseGoal *>(i.get())) {
+ if (auto goal = dynamic_cast<DerivationGoal *>(i.get())) {
topPaths.push_back(DerivedPath::Built {
- .drvPath = goal->drvReq,
+ .drvPath = makeConstantStorePathRef(goal->drvPath),
.outputs = goal->wantedOutputs,
});
} else if (auto goal = dynamic_cast<PathSubstitutionGoal *>(i.get())) {
@@ -589,19 +532,4 @@ GoalPtr upcast_goal(std::shared_ptr<DrvOutputSubstitutionGoal> subGoal)
return subGoal;
}
-GoalPtr upcast_goal(std::shared_ptr<DerivationGoal> subGoal)
-{
- return subGoal;
-}
-
-std::optional<std::pair<std::reference_wrapper<const DerivationGoal>, std::reference_wrapper<const SingleDerivedPath>>> tryGetConcreteDrvGoal(GoalPtr waitee)
-{
- auto * odg = dynamic_cast<CreateDerivationAndRealiseGoal *>(&*waitee);
- if (!odg) return std::nullopt;
- return {{
- std::cref(*odg->concreteDrvGoal),
- std::cref(*odg->drvReq),
- }};
-}
-
}
diff --git a/src/libstore/build/worker.hh b/src/libstore/build/worker.hh
index 6f6d25d7d..23ad87914 100644
--- a/src/libstore/build/worker.hh
+++ b/src/libstore/build/worker.hh
@@ -4,7 +4,6 @@
#include "types.hh"
#include "lock.hh"
#include "store-api.hh"
-#include "derived-path-map.hh"
#include "goal.hh"
#include "realisation.hh"
@@ -14,7 +13,6 @@
namespace nix {
/* Forward definition. */
-struct CreateDerivationAndRealiseGoal;
struct DerivationGoal;
struct PathSubstitutionGoal;
class DrvOutputSubstitutionGoal;
@@ -33,26 +31,10 @@ class DrvOutputSubstitutionGoal;
*/
GoalPtr upcast_goal(std::shared_ptr<PathSubstitutionGoal> subGoal);
GoalPtr upcast_goal(std::shared_ptr<DrvOutputSubstitutionGoal> subGoal);
-GoalPtr upcast_goal(std::shared_ptr<DerivationGoal> subGoal);
typedef std::chrono::time_point<std::chrono::steady_clock> steady_time_point;
/**
- * The current implementation of impure derivations has
- * `DerivationGoal`s accumulate realisations from their waitees.
- * Unfortunately, `DerivationGoal`s don't directly depend on other
- * goals, but instead depend on `CreateDerivationAndRealiseGoal`s.
- *
- * We try not to share any of the details of any goal type with any
- * other, for sake of modularity and quicker rebuilds. This means we
- * cannot "just" downcast and fish out the field. So as an escape hatch,
- * we have made the function, written in `worker.cc` where all the goal
- * types are visible, and use it instead.
- */
-
-std::optional<std::pair<std::reference_wrapper<const DerivationGoal>, std::reference_wrapper<const SingleDerivedPath>>> tryGetConcreteDrvGoal(GoalPtr waitee);
-
-/**
* A mapping used to remember for each child process to what goal it
* belongs, and file descriptors for receiving log data and output
* path creation commands.
@@ -119,9 +101,6 @@ private:
* Maps used to prevent multiple instantiations of a goal for the
* same derivation / path.
*/
-
- DerivedPathMap<std::weak_ptr<CreateDerivationAndRealiseGoal>> outerDerivationGoals;
-
std::map<StorePath, std::weak_ptr<DerivationGoal>> derivationGoals;
std::map<StorePath, std::weak_ptr<PathSubstitutionGoal>> substitutionGoals;
std::map<DrvOutput, std::weak_ptr<DrvOutputSubstitutionGoal>> drvOutputSubstitutionGoals;
@@ -209,9 +188,6 @@ public:
* @ref DerivationGoal "derivation goal"
*/
private:
- std::shared_ptr<CreateDerivationAndRealiseGoal> makeCreateDerivationAndRealiseGoal(
- ref<SingleDerivedPath> drvPath,
- const OutputsSpec & wantedOutputs, BuildMode buildMode = bmNormal);
std::shared_ptr<DerivationGoal> makeDerivationGoalCommon(
const StorePath & drvPath, const OutputsSpec & wantedOutputs,
std::function<std::shared_ptr<DerivationGoal>()> mkDrvGoal);
diff --git a/src/libstore/derived-path-map.cc b/src/libstore/derived-path-map.cc
index 437b6a71a..5982c04b3 100644
--- a/src/libstore/derived-path-map.cc
+++ b/src/libstore/derived-path-map.cc
@@ -51,11 +51,8 @@ typename DerivedPathMap<V>::ChildNode * DerivedPathMap<V>::findSlot(const Single
// instantiations
-#include "create-derivation-and-realise-goal.hh"
namespace nix {
-template struct DerivedPathMap<std::weak_ptr<CreateDerivationAndRealiseGoal>>;
-
GENERATE_CMP_EXT(
template<>,
DerivedPathMap<std::set<std::string>>::ChildNode,
diff --git a/src/libstore/derived-path-map.hh b/src/libstore/derived-path-map.hh
index 4a2c90733..4d72b301e 100644
--- a/src/libstore/derived-path-map.hh
+++ b/src/libstore/derived-path-map.hh
@@ -20,11 +20,8 @@ namespace nix {
*
* @param V A type to instantiate for each output. It should probably
* should be an "optional" type so not every interior node has to have a
- * value. For example, the scheduler uses
- * `DerivedPathMap<std::weak_ptr<CreateDerivationAndRealiseGoal>>` to
- * remember which goals correspond to which outputs. `* const Something`
- * or `std::optional<Something>` would also be good choices for
- * "optional" types.
+ * value. `* const Something` or `std::optional<Something>` would be
+ * good choices for "optional" types.
*/
template<typename V>
struct DerivedPathMap {
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 26c87391c..516cbef83 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -776,7 +776,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
}
};
- /* Synchronisation point for testing, see tests/gc-concurrent.sh. */
+ /* Synchronisation point for testing, see tests/functional/gc-concurrent.sh. */
if (auto p = getEnv("_NIX_TEST_GC_SYNC"))
readFile(*p);
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index 5a4cb1824..9c25d9868 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -24,6 +24,9 @@
#include "config-impl.hh"
+#ifdef __APPLE__
+#include <sys/sysctl.h>
+#endif
namespace nix {
@@ -154,6 +157,29 @@ unsigned int Settings::getDefaultCores()
return concurrency;
}
+#if __APPLE__
+static bool hasVirt() {
+
+ int hasVMM;
+ int hvSupport;
+ size_t size;
+
+ size = sizeof(hasVMM);
+ if (sysctlbyname("kern.hv_vmm_present", &hasVMM, &size, NULL, 0) == 0) {
+ if (hasVMM)
+ return false;
+ }
+
+ // whether the kernel and hardware supports virt
+ size = sizeof(hvSupport);
+ if (sysctlbyname("kern.hv_support", &hvSupport, &size, NULL, 0) == 0) {
+ return hvSupport == 1;
+ } else {
+ return false;
+ }
+}
+#endif
+
StringSet Settings::getDefaultSystemFeatures()
{
/* For backwards compatibility, accept some "features" that are
@@ -170,6 +196,11 @@ StringSet Settings::getDefaultSystemFeatures()
features.insert("kvm");
#endif
+ #if __APPLE__
+ if (hasVirt())
+ features.insert("apple-virt");
+ #endif
+
return features;
}
diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh
index cf10edebd..dba7d78ef 100644
--- a/src/libstore/globals.hh
+++ b/src/libstore/globals.hh
@@ -708,6 +708,7 @@ public:
`kvm` feature.
This setting by default includes `kvm` if `/dev/kvm` is accessible,
+ `apple-virt` if hardware virtualization is available on macOS,
and the pseudo-features `nixos-test`, `benchmark` and `big-parallel`
that are used in Nixpkgs to route builds to specific machines.
)", {}, false};
diff --git a/src/libstore/path-regex.hh b/src/libstore/path-regex.hh
index 4f8dc4c1f..a44e6a2eb 100644
--- a/src/libstore/path-regex.hh
+++ b/src/libstore/path-regex.hh
@@ -3,6 +3,6 @@
namespace nix {
-static constexpr std::string_view nameRegexStr = R"([0-9a-zA-Z\+\-\._\?=]+)";
+static constexpr std::string_view nameRegexStr = R"([0-9a-zA-Z\+\-_\?=][0-9a-zA-Z\+\-\._\?=]*)";
}
diff --git a/src/libstore/path.cc b/src/libstore/path.cc
index 552e83114..3c6b9fc10 100644
--- a/src/libstore/path.cc
+++ b/src/libstore/path.cc
@@ -11,6 +11,8 @@ static void checkName(std::string_view path, std::string_view name)
if (name.size() > StorePath::MaxPathLen)
throw BadStorePath("store path '%s' has a name longer than %d characters",
path, StorePath::MaxPathLen);
+ if (name[0] == '.')
+ throw BadStorePath("store path '%s' starts with illegal character '.'", path);
// See nameRegexStr for the definition
for (auto c : name)
if (!((c >= '0' && c <= '9')
diff --git a/src/libstore/tests/derivation.cc b/src/libstore/tests/derivation.cc
deleted file mode 100644
index c360c9707..000000000
--- a/src/libstore/tests/derivation.cc
+++ /dev/null
@@ -1,369 +0,0 @@
-#include <nlohmann/json.hpp>
-#include <gtest/gtest.h>
-
-#include "experimental-features.hh"
-#include "derivations.hh"
-
-#include "tests/libstore.hh"
-
-namespace nix {
-
-class DerivationTest : public LibStoreTest
-{
-public:
- /**
- * We set these in tests rather than the regular globals so we don't have
- * to worry about race conditions if the tests run concurrently.
- */
- ExperimentalFeatureSettings mockXpSettings;
-};
-
-class CaDerivationTest : public DerivationTest
-{
- void SetUp() override
- {
- mockXpSettings.set("experimental-features", "ca-derivations");
- }
-};
-
-class DynDerivationTest : public DerivationTest
-{
- void SetUp() override
- {
- mockXpSettings.set("experimental-features", "dynamic-derivations ca-derivations");
- }
-};
-
-class ImpureDerivationTest : public DerivationTest
-{
- void SetUp() override
- {
- mockXpSettings.set("experimental-features", "impure-derivations");
- }
-};
-
-TEST_F(DerivationTest, BadATerm_version) {
- ASSERT_THROW(
- parseDerivation(
- *store,
- R"(DrvWithVersion("invalid-version",[],[("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv",["cat","dog"])],["/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"],"wasm-sel4","foo",["bar","baz"],[("BIG_BAD","WOLF")]))",
- "whatever",
- mockXpSettings),
- FormatError);
-}
-
-TEST_F(DynDerivationTest, BadATerm_oldVersionDynDeps) {
- ASSERT_THROW(
- parseDerivation(
- *store,
- R"(Derive([],[("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv",(["cat","dog"],[("cat",["kitten"]),("goose",["gosling"])]))],["/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"],"wasm-sel4","foo",["bar","baz"],[("BIG_BAD","WOLF")]))",
- "dyn-dep-derivation",
- mockXpSettings),
- FormatError);
-}
-
-#define TEST_JSON(FIXTURE, NAME, STR, VAL, DRV_NAME, OUTPUT_NAME) \
- TEST_F(FIXTURE, DerivationOutput_ ## NAME ## _to_json) { \
- using nlohmann::literals::operator "" _json; \
- ASSERT_EQ( \
- STR ## _json, \
- (DerivationOutput { VAL }).toJSON( \
- *store, \
- DRV_NAME, \
- OUTPUT_NAME)); \
- } \
- \
- TEST_F(FIXTURE, DerivationOutput_ ## NAME ## _from_json) { \
- using nlohmann::literals::operator "" _json; \
- ASSERT_EQ( \
- DerivationOutput { VAL }, \
- DerivationOutput::fromJSON( \
- *store, \
- DRV_NAME, \
- OUTPUT_NAME, \
- STR ## _json, \
- mockXpSettings)); \
- }
-
-TEST_JSON(DerivationTest, inputAddressed,
- R"({
- "path": "/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-drv-name-output-name"
- })",
- (DerivationOutput::InputAddressed {
- .path = store->parseStorePath("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-drv-name-output-name"),
- }),
- "drv-name", "output-name")
-
-TEST_JSON(DerivationTest, caFixedFlat,
- R"({
- "hashAlgo": "sha256",
- "hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f",
- "path": "/nix/store/rhcg9h16sqvlbpsa6dqm57sbr2al6nzg-drv-name-output-name"
- })",
- (DerivationOutput::CAFixed {
- .ca = {
- .method = FileIngestionMethod::Flat,
- .hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="),
- },
- }),
- "drv-name", "output-name")
-
-TEST_JSON(DerivationTest, caFixedNAR,
- R"({
- "hashAlgo": "r:sha256",
- "hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f",
- "path": "/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-drv-name-output-name"
- })",
- (DerivationOutput::CAFixed {
- .ca = {
- .method = FileIngestionMethod::Recursive,
- .hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="),
- },
- }),
- "drv-name", "output-name")
-
-TEST_JSON(DynDerivationTest, caFixedText,
- R"({
- "hashAlgo": "text:sha256",
- "hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f",
- "path": "/nix/store/6s1zwabh956jvhv4w9xcdb5jiyanyxg1-drv-name-output-name"
- })",
- (DerivationOutput::CAFixed {
- .ca = {
- .hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="),
- },
- }),
- "drv-name", "output-name")
-
-TEST_JSON(CaDerivationTest, caFloating,
- R"({
- "hashAlgo": "r:sha256"
- })",
- (DerivationOutput::CAFloating {
- .method = FileIngestionMethod::Recursive,
- .hashType = htSHA256,
- }),
- "drv-name", "output-name")
-
-TEST_JSON(DerivationTest, deferred,
- R"({ })",
- DerivationOutput::Deferred { },
- "drv-name", "output-name")
-
-TEST_JSON(ImpureDerivationTest, impure,
- R"({
- "hashAlgo": "r:sha256",
- "impure": true
- })",
- (DerivationOutput::Impure {
- .method = FileIngestionMethod::Recursive,
- .hashType = htSHA256,
- }),
- "drv-name", "output-name")
-
-#undef TEST_JSON
-
-#define TEST_JSON(FIXTURE, NAME, STR, VAL) \
- TEST_F(FIXTURE, Derivation_ ## NAME ## _to_json) { \
- using nlohmann::literals::operator "" _json; \
- ASSERT_EQ( \
- STR ## _json, \
- (VAL).toJSON(*store)); \
- } \
- \
- TEST_F(FIXTURE, Derivation_ ## NAME ## _from_json) { \
- using nlohmann::literals::operator "" _json; \
- ASSERT_EQ( \
- (VAL), \
- Derivation::fromJSON( \
- *store, \
- STR ## _json, \
- mockXpSettings)); \
- }
-
-#define TEST_ATERM(FIXTURE, NAME, STR, VAL, DRV_NAME) \
- TEST_F(FIXTURE, Derivation_ ## NAME ## _to_aterm) { \
- ASSERT_EQ( \
- STR, \
- (VAL).unparse(*store, false)); \
- } \
- \
- TEST_F(FIXTURE, Derivation_ ## NAME ## _from_aterm) { \
- auto parsed = parseDerivation( \
- *store, \
- STR, \
- DRV_NAME, \
- mockXpSettings); \
- ASSERT_EQ( \
- (VAL).toJSON(*store), \
- parsed.toJSON(*store)); \
- ASSERT_EQ( \
- (VAL), \
- parsed); \
- }
-
-Derivation makeSimpleDrv(const Store & store) {
- Derivation drv;
- drv.name = "simple-derivation";
- drv.inputSrcs = {
- store.parseStorePath("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"),
- };
- drv.inputDrvs = {
- .map = {
- {
- store.parseStorePath("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv"),
- {
- .value = {
- "cat",
- "dog",
- },
- },
- },
- },
- };
- drv.platform = "wasm-sel4";
- drv.builder = "foo";
- drv.args = {
- "bar",
- "baz",
- };
- drv.env = {
- {
- "BIG_BAD",
- "WOLF",
- },
- };
- return drv;
-}
-
-TEST_JSON(DerivationTest, simple,
- R"({
- "name": "simple-derivation",
- "inputSrcs": [
- "/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"
- ],
- "inputDrvs": {
- "/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv": {
- "dynamicOutputs": {},
- "outputs": [
- "cat",
- "dog"
- ]
- }
- },
- "system": "wasm-sel4",
- "builder": "foo",
- "args": [
- "bar",
- "baz"
- ],
- "env": {
- "BIG_BAD": "WOLF"
- },
- "outputs": {}
- })",
- makeSimpleDrv(*store))
-
-TEST_ATERM(DerivationTest, simple,
- R"(Derive([],[("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv",["cat","dog"])],["/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"],"wasm-sel4","foo",["bar","baz"],[("BIG_BAD","WOLF")]))",
- makeSimpleDrv(*store),
- "simple-derivation")
-
-Derivation makeDynDepDerivation(const Store & store) {
- Derivation drv;
- drv.name = "dyn-dep-derivation";
- drv.inputSrcs = {
- store.parseStorePath("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"),
- };
- drv.inputDrvs = {
- .map = {
- {
- store.parseStorePath("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv"),
- DerivedPathMap<StringSet>::ChildNode {
- .value = {
- "cat",
- "dog",
- },
- .childMap = {
- {
- "cat",
- DerivedPathMap<StringSet>::ChildNode {
- .value = {
- "kitten",
- },
- },
- },
- {
- "goose",
- DerivedPathMap<StringSet>::ChildNode {
- .value = {
- "gosling",
- },
- },
- },
- },
- },
- },
- },
- };
- drv.platform = "wasm-sel4";
- drv.builder = "foo";
- drv.args = {
- "bar",
- "baz",
- };
- drv.env = {
- {
- "BIG_BAD",
- "WOLF",
- },
- };
- return drv;
-}
-
-TEST_JSON(DynDerivationTest, dynDerivationDeps,
- R"({
- "name": "dyn-dep-derivation",
- "inputSrcs": [
- "/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"
- ],
- "inputDrvs": {
- "/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv": {
- "dynamicOutputs": {
- "cat": {
- "dynamicOutputs": {},
- "outputs": ["kitten"]
- },
- "goose": {
- "dynamicOutputs": {},
- "outputs": ["gosling"]
- }
- },
- "outputs": [
- "cat",
- "dog"
- ]
- }
- },
- "system": "wasm-sel4",
- "builder": "foo",
- "args": [
- "bar",
- "baz"
- ],
- "env": {
- "BIG_BAD": "WOLF"
- },
- "outputs": {}
- })",
- makeDynDepDerivation(*store))
-
-TEST_ATERM(DynDerivationTest, dynDerivationDeps,
- R"(DrvWithVersion("xp-dyn-drv",[],[("/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep2.drv",(["cat","dog"],[("cat",["kitten"]),("goose",["gosling"])]))],["/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-dep1"],"wasm-sel4","foo",["bar","baz"],[("BIG_BAD","WOLF")]))",
- makeDynDepDerivation(*store),
- "dyn-dep-derivation")
-
-#undef TEST_JSON
-#undef TEST_ATERM
-
-}
diff --git a/src/libstore/tests/derived-path.cc b/src/libstore/tests/derived-path.cc
deleted file mode 100644
index 3fa3c0801..000000000
--- a/src/libstore/tests/derived-path.cc
+++ /dev/null
@@ -1,153 +0,0 @@
-#include <regex>
-
-#include <nlohmann/json.hpp>
-#include <gtest/gtest.h>
-#include <rapidcheck/gtest.h>
-
-#include "tests/derived-path.hh"
-#include "tests/libstore.hh"
-
-namespace rc {
-using namespace nix;
-
-Gen<DerivedPath::Opaque> Arbitrary<DerivedPath::Opaque>::arbitrary()
-{
- return gen::just(DerivedPath::Opaque {
- .path = *gen::arbitrary<StorePath>(),
- });
-}
-
-Gen<SingleDerivedPath::Built> Arbitrary<SingleDerivedPath::Built>::arbitrary()
-{
- return gen::just(SingleDerivedPath::Built {
- .drvPath = make_ref<SingleDerivedPath>(*gen::arbitrary<SingleDerivedPath>()),
- .output = (*gen::arbitrary<StorePathName>()).name,
- });
-}
-
-Gen<DerivedPath::Built> Arbitrary<DerivedPath::Built>::arbitrary()
-{
- return gen::just(DerivedPath::Built {
- .drvPath = make_ref<SingleDerivedPath>(*gen::arbitrary<SingleDerivedPath>()),
- .outputs = *gen::arbitrary<OutputsSpec>(),
- });
-}
-
-Gen<SingleDerivedPath> Arbitrary<SingleDerivedPath>::arbitrary()
-{
- switch (*gen::inRange<uint8_t>(0, std::variant_size_v<SingleDerivedPath::Raw>)) {
- case 0:
- return gen::just<SingleDerivedPath>(*gen::arbitrary<SingleDerivedPath::Opaque>());
- case 1:
- return gen::just<SingleDerivedPath>(*gen::arbitrary<SingleDerivedPath::Built>());
- default:
- assert(false);
- }
-}
-
-Gen<DerivedPath> Arbitrary<DerivedPath>::arbitrary()
-{
- switch (*gen::inRange<uint8_t>(0, std::variant_size_v<DerivedPath::Raw>)) {
- case 0:
- return gen::just<DerivedPath>(*gen::arbitrary<DerivedPath::Opaque>());
- case 1:
- return gen::just<DerivedPath>(*gen::arbitrary<DerivedPath::Built>());
- default:
- assert(false);
- }
-}
-
-}
-
-namespace nix {
-
-class DerivedPathTest : public LibStoreTest
-{
-};
-
-/**
- * Round trip (string <-> data structure) test for
- * `DerivedPath::Opaque`.
- */
-TEST_F(DerivedPathTest, opaque) {
- std::string_view opaque = "/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-x";
- auto elem = DerivedPath::parse(*store, opaque);
- auto * p = std::get_if<DerivedPath::Opaque>(&elem);
- ASSERT_TRUE(p);
- ASSERT_EQ(p->path, store->parseStorePath(opaque));
- ASSERT_EQ(elem.to_string(*store), opaque);
-}
-
-/**
- * Round trip (string <-> data structure) test for a simpler
- * `DerivedPath::Built`.
- */
-TEST_F(DerivedPathTest, built_opaque) {
- std::string_view built = "/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-x.drv^bar,foo";
- auto elem = DerivedPath::parse(*store, built);
- auto * p = std::get_if<DerivedPath::Built>(&elem);
- ASSERT_TRUE(p);
- ASSERT_EQ(p->outputs, ((OutputsSpec) OutputsSpec::Names { "foo", "bar" }));
- ASSERT_EQ(*p->drvPath, ((SingleDerivedPath) SingleDerivedPath::Opaque {
- .path = store->parseStorePath(built.substr(0, 49)),
- }));
- ASSERT_EQ(elem.to_string(*store), built);
-}
-
-/**
- * Round trip (string <-> data structure) test for a more complex,
- * inductive `DerivedPath::Built`.
- */
-TEST_F(DerivedPathTest, built_built) {
- /**
- * We set these in tests rather than the regular globals so we don't have
- * to worry about race conditions if the tests run concurrently.
- */
- ExperimentalFeatureSettings mockXpSettings;
- mockXpSettings.set("experimental-features", "dynamic-derivations ca-derivations");
-
- std::string_view built = "/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-x.drv^foo^bar,baz";
- auto elem = DerivedPath::parse(*store, built, mockXpSettings);
- auto * p = std::get_if<DerivedPath::Built>(&elem);
- ASSERT_TRUE(p);
- ASSERT_EQ(p->outputs, ((OutputsSpec) OutputsSpec::Names { "bar", "baz" }));
- auto * drvPath = std::get_if<SingleDerivedPath::Built>(&*p->drvPath);
- ASSERT_TRUE(drvPath);
- ASSERT_EQ(drvPath->output, "foo");
- ASSERT_EQ(*drvPath->drvPath, ((SingleDerivedPath) SingleDerivedPath::Opaque {
- .path = store->parseStorePath(built.substr(0, 49)),
- }));
- ASSERT_EQ(elem.to_string(*store), built);
-}
-
-/**
- * Without the right experimental features enabled, we cannot parse a
- * complex inductive derived path.
- */
-TEST_F(DerivedPathTest, built_built_xp) {
- ASSERT_THROW(
- DerivedPath::parse(*store, "/nix/store/g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-x.drv^foo^bar,baz"),
- MissingExperimentalFeature);
-}
-
-#ifndef COVERAGE
-
-RC_GTEST_FIXTURE_PROP(
- DerivedPathTest,
- prop_legacy_round_rip,
- (const DerivedPath & o))
-{
- RC_ASSERT(o == DerivedPath::parseLegacy(*store, o.to_string_legacy(*store)));
-}
-
-RC_GTEST_FIXTURE_PROP(
- DerivedPathTest,
- prop_round_rip,
- (const DerivedPath & o))
-{
- RC_ASSERT(o == DerivedPath::parse(*store, o.to_string(*store)));
-}
-
-#endif
-
-}
diff --git a/src/libstore/tests/derived-path.hh b/src/libstore/tests/derived-path.hh
deleted file mode 100644
index 98d61f228..000000000
--- a/src/libstore/tests/derived-path.hh
+++ /dev/null
@@ -1,39 +0,0 @@
-#pragma once
-///@file
-
-#include <rapidcheck/gen/Arbitrary.h>
-
-#include <derived-path.hh>
-
-#include "tests/path.hh"
-#include "tests/outputs-spec.hh"
-
-namespace rc {
-using namespace nix;
-
-template<>
-struct Arbitrary<SingleDerivedPath::Opaque> {
- static Gen<SingleDerivedPath::Opaque> arbitrary();
-};
-
-template<>
-struct Arbitrary<SingleDerivedPath::Built> {
- static Gen<SingleDerivedPath::Built> arbitrary();
-};
-
-template<>
-struct Arbitrary<SingleDerivedPath> {
- static Gen<SingleDerivedPath> arbitrary();
-};
-
-template<>
-struct Arbitrary<DerivedPath::Built> {
- static Gen<DerivedPath::Built> arbitrary();
-};
-
-template<>
-struct Arbitrary<DerivedPath> {
- static Gen<DerivedPath> arbitrary();
-};
-
-}
diff --git a/src/libstore/tests/downstream-placeholder.cc b/src/libstore/tests/downstream-placeholder.cc
deleted file mode 100644
index fd29530ac..000000000
--- a/src/libstore/tests/downstream-placeholder.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-#include <gtest/gtest.h>
-
-#include "downstream-placeholder.hh"
-
-namespace nix {
-
-TEST(DownstreamPlaceholder, unknownCaOutput) {
- /**
- * We set these in tests rather than the regular globals so we don't have
- * to worry about race conditions if the tests run concurrently.
- */
- ExperimentalFeatureSettings mockXpSettings;
- mockXpSettings.set("experimental-features", "ca-derivations");
-
- ASSERT_EQ(
- DownstreamPlaceholder::unknownCaOutput(
- StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv" },
- "out",
- mockXpSettings).render(),
- "/0c6rn30q4frawknapgwq386zq358m8r6msvywcvc89n6m5p2dgbz");
-}
-
-TEST(DownstreamPlaceholder, unknownDerivation) {
- /**
- * Same reason as above
- */
- ExperimentalFeatureSettings mockXpSettings;
- mockXpSettings.set("experimental-features", "dynamic-derivations ca-derivations");
-
- ASSERT_EQ(
- DownstreamPlaceholder::unknownDerivation(
- DownstreamPlaceholder::unknownCaOutput(
- StorePath { "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv.drv" },
- "out",
- mockXpSettings),
- "out",
- mockXpSettings).render(),
- "/0gn6agqxjyyalf0dpihgyf49xq5hqxgw100f0wydnj6yqrhqsb3w");
-}
-
-}
diff --git a/src/libstore/tests/libstore.hh b/src/libstore/tests/libstore.hh
deleted file mode 100644
index ef93457b5..000000000
--- a/src/libstore/tests/libstore.hh
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-///@file
-
-#include <gtest/gtest.h>
-#include <gmock/gmock.h>
-
-#include "store-api.hh"
-
-namespace nix {
-
-class LibStoreTest : public ::testing::Test {
- public:
- static void SetUpTestSuite() {
- initLibStore();
- }
-
- protected:
- LibStoreTest()
- : store(openStore("dummy://"))
- { }
-
- ref<Store> store;
-};
-
-
-} /* namespace nix */
diff --git a/src/libstore/tests/local.mk b/src/libstore/tests/local.mk
deleted file mode 100644
index 03becc7d1..000000000
--- a/src/libstore/tests/local.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-check: libstore-tests-exe_RUN
-
-programs += libstore-tests-exe
-
-libstore-tests-exe_NAME = libnixstore-tests
-
-libstore-tests-exe_DIR := $(d)
-
-libstore-tests-exe_INSTALL_DIR :=
-
-libstore-tests-exe_LIBS = libstore-tests
-
-libstore-tests-exe_LDFLAGS := $(GTEST_LIBS)
-
-libraries += libstore-tests
-
-libstore-tests_NAME = libnixstore-tests
-
-libstore-tests_DIR := $(d)
-
-libstore-tests_INSTALL_DIR :=
-
-libstore-tests_SOURCES := $(wildcard $(d)/*.cc)
-
-libstore-tests_CXXFLAGS += -I src/libstore -I src/libutil
-
-libstore-tests_LIBS = libutil-tests libstore libutil
-
-libstore-tests_LDFLAGS := -lrapidcheck $(GTEST_LIBS)
diff --git a/src/libstore/tests/machines.cc b/src/libstore/tests/machines.cc
deleted file mode 100644
index f51052b14..000000000
--- a/src/libstore/tests/machines.cc
+++ /dev/null
@@ -1,169 +0,0 @@
-#include "machines.hh"
-#include "globals.hh"
-
-#include <gmock/gmock-matchers.h>
-
-using testing::Contains;
-using testing::ElementsAre;
-using testing::EndsWith;
-using testing::Eq;
-using testing::Field;
-using testing::SizeIs;
-
-using nix::absPath;
-using nix::FormatError;
-using nix::getMachines;
-using nix::Machine;
-using nix::Machines;
-using nix::pathExists;
-using nix::Settings;
-using nix::settings;
-
-class Environment : public ::testing::Environment {
- public:
- void SetUp() override { settings.thisSystem = "TEST_ARCH-TEST_OS"; }
-};
-
-testing::Environment* const foo_env =
- testing::AddGlobalTestEnvironment(new Environment);
-
-TEST(machines, getMachinesWithEmptyBuilders) {
- settings.builders = "";
- Machines actual = getMachines();
- ASSERT_THAT(actual, SizeIs(0));
-}
-
-TEST(machines, getMachinesUriOnly) {
- settings.builders = "nix@scratchy.labs.cs.uu.nl";
- Machines actual = getMachines();
- ASSERT_THAT(actual, SizeIs(1));
- EXPECT_THAT(actual[0], Field(&Machine::storeUri, Eq("ssh://nix@scratchy.labs.cs.uu.nl")));
- EXPECT_THAT(actual[0], Field(&Machine::systemTypes, ElementsAre("TEST_ARCH-TEST_OS")));
- EXPECT_THAT(actual[0], Field(&Machine::sshKey, SizeIs(0)));
- EXPECT_THAT(actual[0], Field(&Machine::maxJobs, Eq(1)));
- EXPECT_THAT(actual[0], Field(&Machine::speedFactor, Eq(1)));
- EXPECT_THAT(actual[0], Field(&Machine::supportedFeatures, SizeIs(0)));
- EXPECT_THAT(actual[0], Field(&Machine::mandatoryFeatures, SizeIs(0)));
- EXPECT_THAT(actual[0], Field(&Machine::sshPublicHostKey, SizeIs(0)));
-}
-
-TEST(machines, getMachinesDefaults) {
- settings.builders = "nix@scratchy.labs.cs.uu.nl - - - - - - -";
- Machines actual = getMachines();
- ASSERT_THAT(actual, SizeIs(1));
- EXPECT_THAT(actual[0], Field(&Machine::storeUri, Eq("ssh://nix@scratchy.labs.cs.uu.nl")));
- EXPECT_THAT(actual[0], Field(&Machine::systemTypes, ElementsAre("TEST_ARCH-TEST_OS")));
- EXPECT_THAT(actual[0], Field(&Machine::sshKey, SizeIs(0)));
- EXPECT_THAT(actual[0], Field(&Machine::maxJobs, Eq(1)));
- EXPECT_THAT(actual[0], Field(&Machine::speedFactor, Eq(1)));
- EXPECT_THAT(actual[0], Field(&Machine::supportedFeatures, SizeIs(0)));
- EXPECT_THAT(actual[0], Field(&Machine::mandatoryFeatures, SizeIs(0)));
- EXPECT_THAT(actual[0], Field(&Machine::sshPublicHostKey, SizeIs(0)));
-}
-
-TEST(machines, getMachinesWithNewLineSeparator) {
- settings.builders = "nix@scratchy.labs.cs.uu.nl\nnix@itchy.labs.cs.uu.nl";
- Machines actual = getMachines();
- ASSERT_THAT(actual, SizeIs(2));
- EXPECT_THAT(actual, Contains(Field(&Machine::storeUri, EndsWith("nix@scratchy.labs.cs.uu.nl"))));
- EXPECT_THAT(actual, Contains(Field(&Machine::storeUri, EndsWith("nix@itchy.labs.cs.uu.nl"))));
-}
-
-TEST(machines, getMachinesWithSemicolonSeparator) {
- settings.builders = "nix@scratchy.labs.cs.uu.nl ; nix@itchy.labs.cs.uu.nl";
- Machines actual = getMachines();
- EXPECT_THAT(actual, SizeIs(2));
- EXPECT_THAT(actual, Contains(Field(&Machine::storeUri, EndsWith("nix@scratchy.labs.cs.uu.nl"))));
- EXPECT_THAT(actual, Contains(Field(&Machine::storeUri, EndsWith("nix@itchy.labs.cs.uu.nl"))));
-}
-
-TEST(machines, getMachinesWithCorrectCompleteSingleBuilder) {
- settings.builders = "nix@scratchy.labs.cs.uu.nl i686-linux "
- "/home/nix/.ssh/id_scratchy_auto 8 3 kvm "
- "benchmark SSH+HOST+PUBLIC+KEY+BASE64+ENCODED==";
- Machines actual = getMachines();
- ASSERT_THAT(actual, SizeIs(1));
- EXPECT_THAT(actual[0], Field(&Machine::storeUri, EndsWith("nix@scratchy.labs.cs.uu.nl")));
- EXPECT_THAT(actual[0], Field(&Machine::systemTypes, ElementsAre("i686-linux")));
- EXPECT_THAT(actual[0], Field(&Machine::sshKey, Eq("/home/nix/.ssh/id_scratchy_auto")));
- EXPECT_THAT(actual[0], Field(&Machine::maxJobs, Eq(8)));
- EXPECT_THAT(actual[0], Field(&Machine::speedFactor, Eq(3)));
- EXPECT_THAT(actual[0], Field(&Machine::supportedFeatures, ElementsAre("kvm")));
- EXPECT_THAT(actual[0], Field(&Machine::mandatoryFeatures, ElementsAre("benchmark")));
- EXPECT_THAT(actual[0], Field(&Machine::sshPublicHostKey, Eq("SSH+HOST+PUBLIC+KEY+BASE64+ENCODED==")));
-}
-
-TEST(machines,
- getMachinesWithCorrectCompleteSingleBuilderWithTabColumnDelimiter) {
- settings.builders =
- "nix@scratchy.labs.cs.uu.nl\ti686-linux\t/home/nix/.ssh/"
- "id_scratchy_auto\t8\t3\tkvm\tbenchmark\tSSH+HOST+PUBLIC+"
- "KEY+BASE64+ENCODED==";
- Machines actual = getMachines();
- ASSERT_THAT(actual, SizeIs(1));
- EXPECT_THAT(actual[0], Field(&Machine::storeUri, EndsWith("nix@scratchy.labs.cs.uu.nl")));
- EXPECT_THAT(actual[0], Field(&Machine::systemTypes, ElementsAre("i686-linux")));
- EXPECT_THAT(actual[0], Field(&Machine::sshKey, Eq("/home/nix/.ssh/id_scratchy_auto")));
- EXPECT_THAT(actual[0], Field(&Machine::maxJobs, Eq(8)));
- EXPECT_THAT(actual[0], Field(&Machine::speedFactor, Eq(3)));
- EXPECT_THAT(actual[0], Field(&Machine::supportedFeatures, ElementsAre("kvm")));
- EXPECT_THAT(actual[0], Field(&Machine::mandatoryFeatures, ElementsAre("benchmark")));
- EXPECT_THAT(actual[0], Field(&Machine::sshPublicHostKey, Eq("SSH+HOST+PUBLIC+KEY+BASE64+ENCODED==")));
-}
-
-TEST(machines, getMachinesWithMultiOptions) {
- settings.builders = "nix@scratchy.labs.cs.uu.nl Arch1,Arch2 - - - "
- "SupportedFeature1,SupportedFeature2 "
- "MandatoryFeature1,MandatoryFeature2";
- Machines actual = getMachines();
- ASSERT_THAT(actual, SizeIs(1));
- EXPECT_THAT(actual[0], Field(&Machine::storeUri, EndsWith("nix@scratchy.labs.cs.uu.nl")));
- EXPECT_THAT(actual[0], Field(&Machine::systemTypes, ElementsAre("Arch1", "Arch2")));
- EXPECT_THAT(actual[0], Field(&Machine::supportedFeatures, ElementsAre("SupportedFeature1", "SupportedFeature2")));
- EXPECT_THAT(actual[0], Field(&Machine::mandatoryFeatures, ElementsAre("MandatoryFeature1", "MandatoryFeature2")));
-}
-
-TEST(machines, getMachinesWithIncorrectFormat) {
- settings.builders = "nix@scratchy.labs.cs.uu.nl - - eight";
- EXPECT_THROW(getMachines(), FormatError);
- settings.builders = "nix@scratchy.labs.cs.uu.nl - - -1";
- EXPECT_THROW(getMachines(), FormatError);
- settings.builders = "nix@scratchy.labs.cs.uu.nl - - 8 three";
- EXPECT_THROW(getMachines(), FormatError);
- settings.builders = "nix@scratchy.labs.cs.uu.nl - - 8 -3";
- EXPECT_THROW(getMachines(), FormatError);
- settings.builders = "nix@scratchy.labs.cs.uu.nl - - 8 3 - - BAD_BASE64";
- EXPECT_THROW(getMachines(), FormatError);
-}
-
-TEST(machines, getMachinesWithCorrectFileReference) {
- auto path = absPath("src/libstore/tests/test-data/machines.valid");
- ASSERT_TRUE(pathExists(path));
-
- settings.builders = std::string("@") + path;
- Machines actual = getMachines();
- ASSERT_THAT(actual, SizeIs(3));
- EXPECT_THAT(actual, Contains(Field(&Machine::storeUri, EndsWith("nix@scratchy.labs.cs.uu.nl"))));
- EXPECT_THAT(actual, Contains(Field(&Machine::storeUri, EndsWith("nix@itchy.labs.cs.uu.nl"))));
- EXPECT_THAT(actual, Contains(Field(&Machine::storeUri, EndsWith("nix@poochie.labs.cs.uu.nl"))));
-}
-
-TEST(machines, getMachinesWithCorrectFileReferenceToEmptyFile) {
- auto path = "/dev/null";
- ASSERT_TRUE(pathExists(path));
-
- settings.builders = std::string("@") + path;
- Machines actual = getMachines();
- ASSERT_THAT(actual, SizeIs(0));
-}
-
-TEST(machines, getMachinesWithIncorrectFileReference) {
- settings.builders = std::string("@") + absPath("/not/a/file");
- Machines actual = getMachines();
- ASSERT_THAT(actual, SizeIs(0));
-}
-
-TEST(machines, getMachinesWithCorrectFileReferenceToIncorrectFile) {
- settings.builders = std::string("@") + absPath("src/libstore/tests/test-data/machines.bad_format");
- EXPECT_THROW(getMachines(), FormatError);
-}
diff --git a/src/libstore/tests/nar-info-disk-cache.cc b/src/libstore/tests/nar-info-disk-cache.cc
deleted file mode 100644
index b4bdb8329..000000000
--- a/src/libstore/tests/nar-info-disk-cache.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-#include "nar-info-disk-cache.hh"
-
-#include <gtest/gtest.h>
-#include <rapidcheck/gtest.h>
-#include "sqlite.hh"
-#include <sqlite3.h>
-
-
-namespace nix {
-
-TEST(NarInfoDiskCacheImpl, create_and_read) {
- // This is a large single test to avoid some setup overhead.
-
- int prio = 12345;
- bool wantMassQuery = true;
-
- Path tmpDir = createTempDir();
- AutoDelete delTmpDir(tmpDir);
- Path dbPath(tmpDir + "/test-narinfo-disk-cache.sqlite");
-
- int savedId;
- int barId;
- SQLite db;
- SQLiteStmt getIds;
-
- {
- auto cache = getTestNarInfoDiskCache(dbPath);
-
- // Set up "background noise" and check that different caches receive different ids
- {
- auto bc1 = cache->createCache("https://bar", "/nix/storedir", wantMassQuery, prio);
- auto bc2 = cache->createCache("https://xyz", "/nix/storedir", false, 12);
- ASSERT_NE(bc1, bc2);
- barId = bc1;
- }
-
- // Check that the fields are saved and returned correctly. This does not test
- // the select statement yet, because of in-memory caching.
- savedId = cache->createCache("http://foo", "/nix/storedir", wantMassQuery, prio);;
- {
- auto r = cache->upToDateCacheExists("http://foo");
- ASSERT_TRUE(r);
- ASSERT_EQ(r->priority, prio);
- ASSERT_EQ(r->wantMassQuery, wantMassQuery);
- ASSERT_EQ(savedId, r->id);
- }
-
- // We're going to pay special attention to the id field because we had a bug
- // that changed it.
- db = SQLite(dbPath);
- getIds.create(db, "select id from BinaryCaches where url = 'http://foo'");
-
- {
- auto q(getIds.use());
- ASSERT_TRUE(q.next());
- ASSERT_EQ(savedId, q.getInt(0));
- ASSERT_FALSE(q.next());
- }
-
- // Pretend that the caches are older, but keep one up to date, as "background noise"
- db.exec("update BinaryCaches set timestamp = timestamp - 1 - 7 * 24 * 3600 where url <> 'https://xyz';");
-
- // This shows that the in-memory cache works
- {
- auto r = cache->upToDateCacheExists("http://foo");
- ASSERT_TRUE(r);
- ASSERT_EQ(r->priority, prio);
- ASSERT_EQ(r->wantMassQuery, wantMassQuery);
- }
- }
-
- {
- // We can't clear the in-memory cache, so we use a new cache object. This is
- // more realistic anyway.
- auto cache2 = getTestNarInfoDiskCache(dbPath);
-
- {
- auto r = cache2->upToDateCacheExists("http://foo");
- ASSERT_FALSE(r);
- }
-
- // "Update", same data, check that the id number is reused
- cache2->createCache("http://foo", "/nix/storedir", wantMassQuery, prio);
-
- {
- auto r = cache2->upToDateCacheExists("http://foo");
- ASSERT_TRUE(r);
- ASSERT_EQ(r->priority, prio);
- ASSERT_EQ(r->wantMassQuery, wantMassQuery);
- ASSERT_EQ(r->id, savedId);
- }
-
- {
- auto q(getIds.use());
- ASSERT_TRUE(q.next());
- auto currentId = q.getInt(0);
- ASSERT_FALSE(q.next());
- ASSERT_EQ(currentId, savedId);
- }
-
- // Check that the fields can be modified, and the id remains the same
- {
- auto r0 = cache2->upToDateCacheExists("https://bar");
- ASSERT_FALSE(r0);
-
- cache2->createCache("https://bar", "/nix/storedir", !wantMassQuery, prio + 10);
- auto r = cache2->upToDateCacheExists("https://bar");
- ASSERT_EQ(r->wantMassQuery, !wantMassQuery);
- ASSERT_EQ(r->priority, prio + 10);
- ASSERT_EQ(r->id, barId);
- }
-
- // // Force update (no use case yet; we only retrieve cache metadata when stale based on timestamp)
- // {
- // cache2->createCache("https://bar", "/nix/storedir", wantMassQuery, prio + 20);
- // auto r = cache2->upToDateCacheExists("https://bar");
- // ASSERT_EQ(r->wantMassQuery, wantMassQuery);
- // ASSERT_EQ(r->priority, prio + 20);
- // }
- }
-}
-
-}
diff --git a/src/libstore/tests/outputs-spec.cc b/src/libstore/tests/outputs-spec.cc
deleted file mode 100644
index 952945185..000000000
--- a/src/libstore/tests/outputs-spec.cc
+++ /dev/null
@@ -1,239 +0,0 @@
-#include "outputs-spec.hh"
-
-#include <nlohmann/json.hpp>
-#include <gtest/gtest.h>
-#include <rapidcheck/gtest.h>
-
-namespace nix {
-
-#ifndef NDEBUG
-TEST(OutputsSpec, no_empty_names) {
- ASSERT_DEATH(OutputsSpec::Names { std::set<std::string> { } }, "");
-}
-#endif
-
-#define TEST_DONT_PARSE(NAME, STR) \
- TEST(OutputsSpec, bad_ ## NAME) { \
- std::optional OutputsSpecOpt = \
- OutputsSpec::parseOpt(STR); \
- ASSERT_FALSE(OutputsSpecOpt); \
- }
-
-TEST_DONT_PARSE(empty, "")
-TEST_DONT_PARSE(garbage, "&*()")
-TEST_DONT_PARSE(double_star, "**")
-TEST_DONT_PARSE(star_first, "*,foo")
-TEST_DONT_PARSE(star_second, "foo,*")
-
-#undef TEST_DONT_PARSE
-
-TEST(OutputsSpec, all) {
- std::string_view str = "*";
- OutputsSpec expected = OutputsSpec::All { };
- ASSERT_EQ(OutputsSpec::parse(str), expected);
- ASSERT_EQ(expected.to_string(), str);
-}
-
-TEST(OutputsSpec, names_out) {
- std::string_view str = "out";
- OutputsSpec expected = OutputsSpec::Names { "out" };
- ASSERT_EQ(OutputsSpec::parse(str), expected);
- ASSERT_EQ(expected.to_string(), str);
-}
-
-TEST(OutputsSpec, names_underscore) {
- std::string_view str = "a_b";
- OutputsSpec expected = OutputsSpec::Names { "a_b" };
- ASSERT_EQ(OutputsSpec::parse(str), expected);
- ASSERT_EQ(expected.to_string(), str);
-}
-
-TEST(OutputsSpec, names_numberic) {
- std::string_view str = "01";
- OutputsSpec expected = OutputsSpec::Names { "01" };
- ASSERT_EQ(OutputsSpec::parse(str), expected);
- ASSERT_EQ(expected.to_string(), str);
-}
-
-TEST(OutputsSpec, names_out_bin) {
- OutputsSpec expected = OutputsSpec::Names { "out", "bin" };
- ASSERT_EQ(OutputsSpec::parse("out,bin"), expected);
- // N.B. This normalization is OK.
- ASSERT_EQ(expected.to_string(), "bin,out");
-}
-
-#define TEST_SUBSET(X, THIS, THAT) \
- X((OutputsSpec { THIS }).isSubsetOf(THAT));
-
-TEST(OutputsSpec, subsets_all_all) {
- TEST_SUBSET(ASSERT_TRUE, OutputsSpec::All { }, OutputsSpec::All { });
-}
-
-TEST(OutputsSpec, subsets_names_all) {
- TEST_SUBSET(ASSERT_TRUE, OutputsSpec::Names { "a" }, OutputsSpec::All { });
-}
-
-TEST(OutputsSpec, subsets_names_names_eq) {
- TEST_SUBSET(ASSERT_TRUE, OutputsSpec::Names { "a" }, OutputsSpec::Names { "a" });
-}
-
-TEST(OutputsSpec, subsets_names_names_noneq) {
- TEST_SUBSET(ASSERT_TRUE, OutputsSpec::Names { "a" }, (OutputsSpec::Names { "a", "b" }));
-}
-
-TEST(OutputsSpec, not_subsets_all_names) {
- TEST_SUBSET(ASSERT_FALSE, OutputsSpec::All { }, OutputsSpec::Names { "a" });
-}
-
-TEST(OutputsSpec, not_subsets_names_names) {
- TEST_SUBSET(ASSERT_FALSE, (OutputsSpec::Names { "a", "b" }), (OutputsSpec::Names { "a" }));
-}
-
-#undef TEST_SUBSET
-
-#define TEST_UNION(RES, THIS, THAT) \
- ASSERT_EQ(OutputsSpec { RES }, (OutputsSpec { THIS }).union_(THAT));
-
-TEST(OutputsSpec, union_all_all) {
- TEST_UNION(OutputsSpec::All { }, OutputsSpec::All { }, OutputsSpec::All { });
-}
-
-TEST(OutputsSpec, union_all_names) {
- TEST_UNION(OutputsSpec::All { }, OutputsSpec::All { }, OutputsSpec::Names { "a" });
-}
-
-TEST(OutputsSpec, union_names_all) {
- TEST_UNION(OutputsSpec::All { }, OutputsSpec::Names { "a" }, OutputsSpec::All { });
-}
-
-TEST(OutputsSpec, union_names_names) {
- TEST_UNION((OutputsSpec::Names { "a", "b" }), OutputsSpec::Names { "a" }, OutputsSpec::Names { "b" });
-}
-
-#undef TEST_UNION
-
-#define TEST_DONT_PARSE(NAME, STR) \
- TEST(ExtendedOutputsSpec, bad_ ## NAME) { \
- std::optional extendedOutputsSpecOpt = \
- ExtendedOutputsSpec::parseOpt(STR); \
- ASSERT_FALSE(extendedOutputsSpecOpt); \
- }
-
-TEST_DONT_PARSE(carot_empty, "^")
-TEST_DONT_PARSE(prefix_carot_empty, "foo^")
-TEST_DONT_PARSE(garbage, "^&*()")
-TEST_DONT_PARSE(double_star, "^**")
-TEST_DONT_PARSE(star_first, "^*,foo")
-TEST_DONT_PARSE(star_second, "^foo,*")
-
-#undef TEST_DONT_PARSE
-
-TEST(ExtendedOutputsSpec, defeault) {
- std::string_view str = "foo";
- auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse(str);
- ASSERT_EQ(prefix, "foo");
- ExtendedOutputsSpec expected = ExtendedOutputsSpec::Default { };
- ASSERT_EQ(extendedOutputsSpec, expected);
- ASSERT_EQ(std::string { prefix } + expected.to_string(), str);
-}
-
-TEST(ExtendedOutputsSpec, all) {
- std::string_view str = "foo^*";
- auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse(str);
- ASSERT_EQ(prefix, "foo");
- ExtendedOutputsSpec expected = OutputsSpec::All { };
- ASSERT_EQ(extendedOutputsSpec, expected);
- ASSERT_EQ(std::string { prefix } + expected.to_string(), str);
-}
-
-TEST(ExtendedOutputsSpec, out) {
- std::string_view str = "foo^out";
- auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse(str);
- ASSERT_EQ(prefix, "foo");
- ExtendedOutputsSpec expected = OutputsSpec::Names { "out" };
- ASSERT_EQ(extendedOutputsSpec, expected);
- ASSERT_EQ(std::string { prefix } + expected.to_string(), str);
-}
-
-TEST(ExtendedOutputsSpec, out_bin) {
- auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse("foo^out,bin");
- ASSERT_EQ(prefix, "foo");
- ExtendedOutputsSpec expected = OutputsSpec::Names { "out", "bin" };
- ASSERT_EQ(extendedOutputsSpec, expected);
- ASSERT_EQ(std::string { prefix } + expected.to_string(), "foo^bin,out");
-}
-
-TEST(ExtendedOutputsSpec, many_carrot) {
- auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse("foo^bar^out,bin");
- ASSERT_EQ(prefix, "foo^bar");
- ExtendedOutputsSpec expected = OutputsSpec::Names { "out", "bin" };
- ASSERT_EQ(extendedOutputsSpec, expected);
- ASSERT_EQ(std::string { prefix } + expected.to_string(), "foo^bar^bin,out");
-}
-
-
-#define TEST_JSON(TYPE, NAME, STR, VAL) \
- \
- TEST(TYPE, NAME ## _to_json) { \
- using nlohmann::literals::operator "" _json; \
- ASSERT_EQ( \
- STR ## _json, \
- ((nlohmann::json) TYPE { VAL })); \
- } \
- \
- TEST(TYPE, NAME ## _from_json) { \
- using nlohmann::literals::operator "" _json; \
- ASSERT_EQ( \
- TYPE { VAL }, \
- (STR ## _json).get<TYPE>()); \
- }
-
-TEST_JSON(OutputsSpec, all, R"(["*"])", OutputsSpec::All { })
-TEST_JSON(OutputsSpec, name, R"(["a"])", OutputsSpec::Names { "a" })
-TEST_JSON(OutputsSpec, names, R"(["a","b"])", (OutputsSpec::Names { "a", "b" }))
-
-TEST_JSON(ExtendedOutputsSpec, def, R"(null)", ExtendedOutputsSpec::Default { })
-TEST_JSON(ExtendedOutputsSpec, all, R"(["*"])", ExtendedOutputsSpec::Explicit { OutputsSpec::All { } })
-TEST_JSON(ExtendedOutputsSpec, name, R"(["a"])", ExtendedOutputsSpec::Explicit { OutputsSpec::Names { "a" } })
-TEST_JSON(ExtendedOutputsSpec, names, R"(["a","b"])", (ExtendedOutputsSpec::Explicit { OutputsSpec::Names { "a", "b" } }))
-
-#undef TEST_JSON
-
-}
-
-namespace rc {
-using namespace nix;
-
-Gen<OutputsSpec> Arbitrary<OutputsSpec>::arbitrary()
-{
- switch (*gen::inRange<uint8_t>(0, std::variant_size_v<OutputsSpec::Raw>)) {
- case 0:
- return gen::just((OutputsSpec) OutputsSpec::All { });
- case 1:
- return gen::just((OutputsSpec) OutputsSpec::Names {
- *gen::nonEmpty(gen::container<StringSet>(gen::map(
- gen::arbitrary<StorePathName>(),
- [](StorePathName n) { return n.name; }))),
- });
- default:
- assert(false);
- }
-}
-
-}
-
-namespace nix {
-
-#ifndef COVERAGE
-
-RC_GTEST_PROP(
- OutputsSpec,
- prop_round_rip,
- (const OutputsSpec & o))
-{
- RC_ASSERT(o == OutputsSpec::parse(o.to_string()));
-}
-
-#endif
-
-}
diff --git a/src/libstore/tests/outputs-spec.hh b/src/libstore/tests/outputs-spec.hh
deleted file mode 100644
index ded331b33..000000000
--- a/src/libstore/tests/outputs-spec.hh
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-///@file
-
-#include <rapidcheck/gen/Arbitrary.h>
-
-#include <outputs-spec.hh>
-
-#include <tests/path.hh>
-
-namespace rc {
-using namespace nix;
-
-template<>
-struct Arbitrary<OutputsSpec> {
- static Gen<OutputsSpec> arbitrary();
-};
-
-}
diff --git a/src/libstore/tests/path.cc b/src/libstore/tests/path.cc
deleted file mode 100644
index efa35ef2b..000000000
--- a/src/libstore/tests/path.cc
+++ /dev/null
@@ -1,157 +0,0 @@
-#include <regex>
-
-#include <nlohmann/json.hpp>
-#include <gtest/gtest.h>
-#include <rapidcheck/gtest.h>
-
-#include "path-regex.hh"
-#include "store-api.hh"
-
-#include "tests/hash.hh"
-#include "tests/libstore.hh"
-#include "tests/path.hh"
-
-namespace nix {
-
-#define STORE_DIR "/nix/store/"
-#define HASH_PART "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q"
-
-class StorePathTest : public LibStoreTest
-{
-};
-
-static std::regex nameRegex { std::string { nameRegexStr } };
-
-#define TEST_DONT_PARSE(NAME, STR) \
- TEST_F(StorePathTest, bad_ ## NAME) { \
- std::string_view str = \
- STORE_DIR HASH_PART "-" STR; \
- ASSERT_THROW( \
- store->parseStorePath(str), \
- BadStorePath); \
- std::string name { STR }; \
- EXPECT_FALSE(std::regex_match(name, nameRegex)); \
- }
-
-TEST_DONT_PARSE(empty, "")
-TEST_DONT_PARSE(garbage, "&*()")
-TEST_DONT_PARSE(double_star, "**")
-TEST_DONT_PARSE(star_first, "*,foo")
-TEST_DONT_PARSE(star_second, "foo,*")
-TEST_DONT_PARSE(bang, "foo!o")
-
-#undef TEST_DONT_PARSE
-
-#define TEST_DO_PARSE(NAME, STR) \
- TEST_F(StorePathTest, good_ ## NAME) { \
- std::string_view str = \
- STORE_DIR HASH_PART "-" STR; \
- auto p = store->parseStorePath(str); \
- std::string name { p.name() }; \
- EXPECT_TRUE(std::regex_match(name, nameRegex)); \
- }
-
-// 0-9 a-z A-Z + - . _ ? =
-
-TEST_DO_PARSE(numbers, "02345")
-TEST_DO_PARSE(lower_case, "foo")
-TEST_DO_PARSE(upper_case, "FOO")
-TEST_DO_PARSE(plus, "foo+bar")
-TEST_DO_PARSE(dash, "foo-dev")
-TEST_DO_PARSE(underscore, "foo_bar")
-TEST_DO_PARSE(period, "foo.txt")
-TEST_DO_PARSE(question_mark, "foo?why")
-TEST_DO_PARSE(equals_sign, "foo=foo")
-
-#undef TEST_DO_PARSE
-
-// For rapidcheck
-void showValue(const StorePath & p, std::ostream & os) {
- os << p.to_string();
-}
-
-}
-
-namespace rc {
-using namespace nix;
-
-Gen<StorePathName> Arbitrary<StorePathName>::arbitrary()
-{
- auto len = *gen::inRange<size_t>(
- 1,
- StorePath::MaxPathLen - std::string_view { HASH_PART }.size());
-
- std::string pre;
- pre.reserve(len);
-
- for (size_t c = 0; c < len; ++c) {
- switch (auto i = *gen::inRange<uint8_t>(0, 10 + 2 * 26 + 6)) {
- case 0 ... 9:
- pre += '0' + i;
- case 10 ... 35:
- pre += 'A' + (i - 10);
- break;
- case 36 ... 61:
- pre += 'a' + (i - 36);
- break;
- case 62:
- pre += '+';
- break;
- case 63:
- pre += '-';
- break;
- case 64:
- pre += '.';
- break;
- case 65:
- pre += '_';
- break;
- case 66:
- pre += '?';
- break;
- case 67:
- pre += '=';
- break;
- default:
- assert(false);
- }
- }
-
- return gen::just(StorePathName {
- .name = std::move(pre),
- });
-}
-
-Gen<StorePath> Arbitrary<StorePath>::arbitrary()
-{
- return gen::just(StorePath {
- *gen::arbitrary<Hash>(),
- (*gen::arbitrary<StorePathName>()).name,
- });
-}
-
-} // namespace rc
-
-namespace nix {
-
-#ifndef COVERAGE
-
-RC_GTEST_FIXTURE_PROP(
- StorePathTest,
- prop_regex_accept,
- (const StorePath & p))
-{
- RC_ASSERT(std::regex_match(std::string { p.name() }, nameRegex));
-}
-
-RC_GTEST_FIXTURE_PROP(
- StorePathTest,
- prop_round_rip,
- (const StorePath & p))
-{
- RC_ASSERT(p == store->parseStorePath(store->printStorePath(p)));
-}
-
-#endif
-
-}
diff --git a/src/libstore/tests/path.hh b/src/libstore/tests/path.hh
deleted file mode 100644
index 21cb62310..000000000
--- a/src/libstore/tests/path.hh
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-///@file
-
-#include <rapidcheck/gen/Arbitrary.h>
-
-#include <path.hh>
-
-namespace nix {
-
-struct StorePathName {
- std::string name;
-};
-
-}
-
-namespace rc {
-using namespace nix;
-
-template<>
-struct Arbitrary<StorePathName> {
- static Gen<StorePathName> arbitrary();
-};
-
-template<>
-struct Arbitrary<StorePath> {
- static Gen<StorePath> arbitrary();
-};
-
-}
diff --git a/src/libstore/tests/references.cc b/src/libstore/tests/references.cc
deleted file mode 100644
index d91d1cedd..000000000
--- a/src/libstore/tests/references.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "references.hh"
-
-#include <gtest/gtest.h>
-
-namespace nix {
-
-TEST(references, scan)
-{
- std::string hash1 = "dc04vv14dak1c1r48qa0m23vr9jy8sm0";
- std::string hash2 = "zc842j0rz61mjsp3h3wp5ly71ak6qgdn";
-
- {
- RefScanSink scanner(StringSet{hash1});
- auto s = "foobar";
- scanner(s);
- ASSERT_EQ(scanner.getResult(), StringSet{});
- }
-
- {
- RefScanSink scanner(StringSet{hash1});
- auto s = "foobar" + hash1 + "xyzzy";
- scanner(s);
- ASSERT_EQ(scanner.getResult(), StringSet{hash1});
- }
-
- {
- RefScanSink scanner(StringSet{hash1, hash2});
- auto s = "foobar" + hash1 + "xyzzy" + hash2;
- scanner(((std::string_view) s).substr(0, 10));
- scanner(((std::string_view) s).substr(10, 5));
- scanner(((std::string_view) s).substr(15, 5));
- scanner(((std::string_view) s).substr(20));
- ASSERT_EQ(scanner.getResult(), StringSet({hash1, hash2}));
- }
-
- {
- RefScanSink scanner(StringSet{hash1, hash2});
- auto s = "foobar" + hash1 + "xyzzy" + hash2;
- for (auto & i : s)
- scanner(std::string(1, i));
- ASSERT_EQ(scanner.getResult(), StringSet({hash1, hash2}));
- }
-}
-
-}
diff --git a/src/libstore/tests/test-data/machines.bad_format b/src/libstore/tests/test-data/machines.bad_format
deleted file mode 100644
index 7255a1216..000000000
--- a/src/libstore/tests/test-data/machines.bad_format
+++ /dev/null
@@ -1 +0,0 @@
-nix@scratchy.labs.cs.uu.nl - - eight
diff --git a/src/libstore/tests/test-data/machines.valid b/src/libstore/tests/test-data/machines.valid
deleted file mode 100644
index 1a6c8017c..000000000
--- a/src/libstore/tests/test-data/machines.valid
+++ /dev/null
@@ -1,3 +0,0 @@
-nix@scratchy.labs.cs.uu.nl i686-linux /home/nix/.ssh/id_scratchy_auto 8 1 kvm
-nix@itchy.labs.cs.uu.nl i686-linux /home/nix/.ssh/id_scratchy_auto 8 2
-nix@poochie.labs.cs.uu.nl i686-linux /home/nix/.ssh/id_scratchy_auto 1 2 kvm benchmark c3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFDQVFDWWV5R1laNTNzd1VjMUZNSHBWL1BCcXlKaFR5S1JoRkpWWVRpRHlQN2h5c1JGa0w4VDlLOGdhL2Y2L3c3QjN2SjNHSFRIUFkybENiUEdZbGNLd2h6M2ZRbFNNOEViNi95b3ZLajdvM1FsMEx5Y0dzdGJvRmcwWkZKNldncUxsR0ltS0NobUlxOGZ3TW5ZTWUxbnRQeTBUZFZjSU1tOTV3YzF3SjBMd2c3cEVMRmtHazdkeTVvYnM4a3lGZ0pORDVRSmFwQWJjeWp4Z1QzdzdMcktNZ2xzeWhhd01JNVpkMGZsQTVudW5OZ3pid3plYVhLaUsyTW0vdGJXYTU1YTd4QmNYdHpIZGlPSWdSajJlRWxaMGh5bk10YjBmcklsdmxIcEtLaVFaZ3pQdCtIVXQ2bXpRMkRVME52MGYyYnNSU0krOGpJU2pQcmdlcVVHRldMUzVIUTg2N2xSMlpiaWtyclhZNTdqbVFEZk5DRHY1VFBHZU9UekFEd2pjMDc2aFZ3VFJCd3VTZFhtaWNxTS95b3lrWitkV1dnZ25MenE5QU1tdlNZcDhmZkZDcS9CSDBZNUFXWTFHay9vS3hMVTNaOWt3ZDd2UWNFQWFCQ2dxdnVZRGdTaHE1RlhndDM3OVZESWtEL05ZSTg2QXVvajVDRmVNTzlRM2pJSlRadlh6c1VldjVoSnA2djcxSVh5ODVtbTY5R20zcXdicVE1SjVQZDU1Um56SitpaW5BNjZxTEFSc0Y4amNsSnd5ekFXclBoYU9DRVY2bjVMeVhVazhzMW9EVVR4V1pWN25rVkFTbHJ0MllGcjN5dzdjRTRXQVhsemhHcDhocmdLMVVkMUlyeDVnZWRaSnBWcy9uNWVybmJFMUxmb2x5UHUvRUFIWlh6VGd4dHVDUFNobXc9PQo=