daemon: rounds: Keep the differing output if -K is given.

Regardless of -K, we now also print which output differs.
master
Eelco Dolstra 2016-01-12 18:25:57 +01:00 committed by Ludovic Courtès
parent 56b8f56788
commit b4528110c6
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
2 changed files with 42 additions and 7 deletions

View File

@ -998,6 +998,10 @@ consecutive build results are not bit-for-bit identical. Note that this
setting can be overridden by clients such as @command{guix build} setting can be overridden by clients such as @command{guix build}
(@pxref{Invoking guix build}). (@pxref{Invoking guix build}).
When used in conjunction with @option{--keep-failed}, the differing
output is kept in the store, under @file{/gnu/store/@dots{}-check}.
This makes it easy to look for differences between the two results.
@item --debug @item --debug
Produce debugging output. Produce debugging output.

View File

@ -2320,6 +2320,8 @@ void DerivationGoal::registerOutputs()
outputs to allow hard links between outputs. */ outputs to allow hard links between outputs. */
InodesSeen inodesSeen; InodesSeen inodesSeen;
Path checkSuffix = "-check";
/* Check whether the output paths were created, and grep each /* Check whether the output paths were created, and grep each
output path to determine what other paths it references. Also make all output path to determine what other paths it references. Also make all
output paths read-only. */ output paths read-only. */
@ -2433,7 +2435,7 @@ void DerivationGoal::registerOutputs()
ValidPathInfo info = worker.store.queryPathInfo(path); ValidPathInfo info = worker.store.queryPathInfo(path);
if (hash.first != info.hash) { if (hash.first != info.hash) {
if (settings.keepFailed) { if (settings.keepFailed) {
Path dst = path + "-check"; Path dst = path + checkSuffix;
if (pathExists(dst)) deletePath(dst); if (pathExists(dst)) deletePath(dst);
if (rename(actualPath.c_str(), dst.c_str())) if (rename(actualPath.c_str(), dst.c_str()))
throw SysError(format("renaming `%1%' to `%2%'") % actualPath % dst); throw SysError(format("renaming `%1%' to `%2%'") % actualPath % dst);
@ -2487,9 +2489,11 @@ void DerivationGoal::registerOutputs()
checkRefs("disallowedReferences", false, false); checkRefs("disallowedReferences", false, false);
checkRefs("disallowedRequisites", false, true); checkRefs("disallowedRequisites", false, true);
worker.store.optimisePath(path); // FIXME: combine with scanForReferences() if (curRound == nrRounds) {
worker.store.optimisePath(path); // FIXME: combine with scanForReferences()
worker.store.markContentsGood(path); worker.store.markContentsGood(path);
}
ValidPathInfo info; ValidPathInfo info;
info.path = path; info.path = path;
@ -2502,10 +2506,37 @@ void DerivationGoal::registerOutputs()
if (buildMode == bmCheck) return; if (buildMode == bmCheck) return;
if (curRound > 1 && prevInfos != infos) /* Compare the result with the previous round, and report which
throw NotDeterministic( path is different, if any.*/
format("result of %1% differs from previous round; rejecting as non-deterministic") if (curRound > 1 && prevInfos != infos) {
% drvPath); assert(prevInfos.size() == infos.size());
for (auto i = prevInfos.begin(), j = infos.begin(); i != prevInfos.end(); ++i, ++j)
if (!(*i == *j)) {
Path prev = i->path + checkSuffix;
if (pathExists(prev))
throw NotDeterministic(
format("output %1% of %2% differs from %3% from previous round")
% i->path % drvPath % prev);
else
throw NotDeterministic(
format("output %1% of %2% differs from previous round")
% i->path % drvPath);
}
assert(false); // shouldn't happen
}
if (settings.keepFailed) {
for (auto & i : drv.outputs) {
Path prev = i.second.path + checkSuffix;
if (pathExists(prev)) deletePath(prev);
if (curRound < nrRounds) {
Path dst = i.second.path + checkSuffix;
if (rename(i.second.path.c_str(), dst.c_str()))
throw SysError(format("renaming %1% to %2%") % i.second.path % dst);
}
}
}
if (curRound < nrRounds) { if (curRound < nrRounds) {
prevInfos = infos; prevInfos = infos;