diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2019-08-02T15·07+0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2019-08-02T16·39+0200 |
commit | ec415d7166d607c92cf8f1af688f86e4b4731dff (patch) | |
tree | c9c04c9c0a68be28f81a779f47dc6c9108b9cb66 | |
parent | 320126aeebc89f8c34ee1668ebacf1fe4b512ed8 (diff) |
Add a test for auto-GC
This currently fails because we're using POSIX file locks. So when the garbage collector opens and closes its own temproots file, it causes the lock to be released and then deleted by another GC instance.
-rw-r--r-- | src/libstore/gc.cc | 9 | ||||
-rw-r--r-- | src/libstore/globals.hh | 3 | ||||
-rw-r--r-- | tests/gc-auto.sh | 59 | ||||
-rw-r--r-- | tests/local.mk | 4 |
4 files changed, 72 insertions, 3 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 83cdf13a6a64..eeb2378393ae 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -871,7 +871,12 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) void LocalStore::autoGC(bool sync) { - auto getAvail = [this]() { + static auto fakeFreeSpaceFile = getEnv("_NIX_TEST_FREE_SPACE_FILE", ""); + + auto getAvail = [this]() -> uint64_t { + if (!fakeFreeSpaceFile.empty()) + return std::stoll(readFile(fakeFreeSpaceFile)); + struct statvfs st; if (statvfs(realStoreDir.c_str(), &st)) throw SysError("getting filesystem info about '%s'", realStoreDir); @@ -892,7 +897,7 @@ void LocalStore::autoGC(bool sync) auto now = std::chrono::steady_clock::now(); - if (now < state->lastGCCheck + std::chrono::seconds(5)) return; + if (now < state->lastGCCheck + std::chrono::seconds(settings.minFreeCheckInterval)) return; auto avail = getAvail(); diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index 0af8215d1fd8..0c0a9ec544ea 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -342,6 +342,9 @@ public: Setting<uint64_t> maxFree{this, std::numeric_limits<uint64_t>::max(), "max-free", "Stop deleting garbage when free disk space is above the specified amount."}; + Setting<uint64_t> minFreeCheckInterval{this, 5, "min-free-check-interval", + "Number of seconds between checking free disk space."}; + Setting<Paths> pluginFiles{this, {}, "plugin-files", "Plugins to dynamically load at nix initialization time."}; }; diff --git a/tests/gc-auto.sh b/tests/gc-auto.sh new file mode 100644 index 000000000000..1e91282d0f99 --- /dev/null +++ b/tests/gc-auto.sh @@ -0,0 +1,59 @@ +source common.sh + +clearStore + +garbage1=$(nix add-to-store --name garbage1 ./tarball.sh) +garbage2=$(nix add-to-store --name garbage2 ./tarball.sh) +garbage3=$(nix add-to-store --name garbage3 ./tarball.sh) + +fake_free=$TEST_ROOT/fake-free +export _NIX_TEST_FREE_SPACE_FILE=$fake_free +echo 1100 > $fake_free + +expr=$(cat <<EOF +with import ./config.nix; mkDerivation { + name = "gc-A"; + buildCommand = '' + [[ \$(ls \$NIX_STORE/*-garbage? | wc -l) = 3 ]] + mkdir \$out + echo foo > \$out/bar + echo 1... + sleep 2 + echo 100 > $fake_free + echo 2... + sleep 2 + echo 3... + [[ \$(ls \$NIX_STORE/*-garbage? | wc -l) = 1 ]] + ''; +} +EOF +) + +nix build -o $TEST_ROOT/result-A -L "($expr)" \ + --min-free 1000 --max-free 2000 --min-free-check-interval 1 & +pid=$! + +expr2=$(cat <<EOF +with import ./config.nix; mkDerivation { + name = "gc-B"; + buildCommand = '' + mkdir \$out + echo foo > \$out/bar + echo 1... + sleep 2 + echo 100 > $fake_free + echo 2... + sleep 2 + echo 3... + ''; +} +EOF +) + +nix build -o $TEST_ROOT/result-B -L "($expr2)" \ + --min-free 1000 --max-free 2000 --min-free-check-interval 1 + +wait "$pid" + +[[ foo = $(cat $TEST_ROOT/result-A/bar) ]] +[[ foo = $(cat $TEST_ROOT/result-B/bar) ]] diff --git a/tests/local.mk b/tests/local.mk index 1ff68348b3c7..261e4db0de88 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -3,7 +3,9 @@ check: nix_tests = \ init.sh hash.sh lang.sh add.sh simple.sh dependencies.sh \ - gc.sh gc-concurrent.sh \ + gc.sh \ + gc-concurrent.sh \ + gc-auto.sh \ referrers.sh user-envs.sh logging.sh nix-build.sh misc.sh fixed.sh \ gc-runtime.sh check-refs.sh filter-source.sh \ remote-store.sh export.sh export-graph.sh \ |