item = BupSubprocTestFile.from_parent(parent, fspath=path)
except AttributeError:
item = BupSubprocTestFile(path, parent)
- if base == 'test-release-archive.sh':
+ if base == 'test-release-archive':
item.add_marker(pytest.mark.release)
return item
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+
+set -o pipefail
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+
+WVPASS bup init
+WVPASS cd "$tmpdir"
+
+WVSTART "cat-file"
+WVPASS mkdir src
+WVPASS date > src/foo
+WVPASS bup index src
+WVPASS bup save -n src src
+WVPASS bup cat-file "src/latest/$(pwd)/src/foo" > cat-foo
+WVPASS diff -u src/foo cat-foo
+
+WVSTART "cat-file --meta"
+WVPASS bup meta --create --no-paths src/foo > src-foo.meta
+WVPASS bup cat-file --meta "src/latest/$(pwd)/src/foo" > cat-foo.meta
+
+WVPASS bup meta -tvvf src-foo.meta | WVPASS grep -vE '^atime: ' > src-foo.list
+WVPASS bup meta -tvvf cat-foo.meta | WVPASS grep -vE '^atime: ' > cat-foo.list
+WVPASS diff -u src-foo.list cat-foo.list
+
+WVSTART "cat-file --bupm"
+WVPASS bup cat-file --bupm "src/latest/$(pwd)/src/" > bup-cat-bupm
+src_hash=$(WVPASS bup ls -s "src/latest/$(pwd)" | cut -d' ' -f 1) || exit $?
+bupm_hash=$(WVPASS git ls-tree "$src_hash" | grep -F .bupm | cut -d' ' -f 3) \
+ || exit $?
+bupm_hash=$(WVPASS echo "$bupm_hash" | cut -d' ' -f 1) || exit $?
+WVPASS "$top/dev/git-cat-tree" "$bupm_hash" > git-cat-bupm
+if ! cmp git-cat-bupm bup-cat-bupm; then
+ cmp -l git-cat-bupm bup-cat-bupm
+ diff -uN <(bup meta -tvvf git-cat-bupm) <(bup meta -tvvf bup-cat-bupm)
+ WVPASS cmp git-cat-bupm bup-cat-bupm
+fi
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-
-set -o pipefail
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-
-WVPASS bup init
-WVPASS cd "$tmpdir"
-
-WVSTART "cat-file"
-WVPASS mkdir src
-WVPASS date > src/foo
-WVPASS bup index src
-WVPASS bup save -n src src
-WVPASS bup cat-file "src/latest/$(pwd)/src/foo" > cat-foo
-WVPASS diff -u src/foo cat-foo
-
-WVSTART "cat-file --meta"
-WVPASS bup meta --create --no-paths src/foo > src-foo.meta
-WVPASS bup cat-file --meta "src/latest/$(pwd)/src/foo" > cat-foo.meta
-
-WVPASS bup meta -tvvf src-foo.meta | WVPASS grep -vE '^atime: ' > src-foo.list
-WVPASS bup meta -tvvf cat-foo.meta | WVPASS grep -vE '^atime: ' > cat-foo.list
-WVPASS diff -u src-foo.list cat-foo.list
-
-WVSTART "cat-file --bupm"
-WVPASS bup cat-file --bupm "src/latest/$(pwd)/src/" > bup-cat-bupm
-src_hash=$(WVPASS bup ls -s "src/latest/$(pwd)" | cut -d' ' -f 1) || exit $?
-bupm_hash=$(WVPASS git ls-tree "$src_hash" | grep -F .bupm | cut -d' ' -f 3) \
- || exit $?
-bupm_hash=$(WVPASS echo "$bupm_hash" | cut -d' ' -f 1) || exit $?
-WVPASS "$top/dev/git-cat-tree" "$bupm_hash" > git-cat-bupm
-if ! cmp git-cat-bupm bup-cat-bupm; then
- cmp -l git-cat-bupm bup-cat-bupm
- diff -uN <(bup meta -tvvf git-cat-bupm) <(bup meta -tvvf bup-cat-bupm)
- WVPASS cmp git-cat-bupm bup-cat-bupm
-fi
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+
+set -o pipefail
+
+WVSTART 'all'
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+
+WVPASS mkdir "$tmpdir/foo"
+
+bup index "$tmpdir/foo" &> /dev/null
+index_rc=$?
+WVPASSEQ "$index_rc" "15"
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-
-set -o pipefail
-
-WVSTART 'all'
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-export BUP_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-
-WVPASS mkdir "$tmpdir/foo"
-
-bup index "$tmpdir/foo" &> /dev/null
-index_rc=$?
-WVPASSEQ "$index_rc" "15"
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+. dev/lib.sh || exit $?
+
+set -o pipefail
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+fs-size() { tar cf - "$@" | wc -c; }
+
+WVSTART "compression"
+WVPASS cd "$tmpdir"
+
+D=compression0.tmp
+WVPASS force-delete "$BUP_DIR"
+WVPASS bup init
+WVPASS mkdir $D
+WVPASS bup index "$top/Documentation"
+WVPASS bup save -n compression -0 --strip "$top/Documentation"
+# Some platforms set -A by default when root, so just use it everywhere.
+expected="$(WVPASS ls -A "$top/Documentation" | WVPASS sort)" || exit $?
+actual="$(WVPASS bup ls -A compression/latest/ | WVPASS sort)" || exit $?
+WVPASSEQ "$actual" "$expected"
+compression_0_size=$(WVPASS fs-size "$BUP_DIR") || exit $?
+
+D=compression9.tmp
+WVPASS force-delete "$BUP_DIR"
+WVPASS bup init
+WVPASS mkdir $D
+WVPASS bup index "$top/Documentation"
+WVPASS bup save -n compression -9 --strip "$top/Documentation"
+expected="$(ls -A "$top/Documentation" | sort)" || exit $?
+actual="$(bup ls -A compression/latest/ | sort)" || exit $?
+WVPASSEQ "$actual" "$expected"
+compression_9_size=$(WVPASS fs-size "$BUP_DIR") || exit $?
+
+WVPASS [ "$compression_9_size" -lt "$compression_0_size" ]
+
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-. dev/lib.sh || exit $?
-
-set -o pipefail
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-fs-size() { tar cf - "$@" | wc -c; }
-
-WVSTART "compression"
-WVPASS cd "$tmpdir"
-
-D=compression0.tmp
-WVPASS force-delete "$BUP_DIR"
-WVPASS bup init
-WVPASS mkdir $D
-WVPASS bup index "$top/Documentation"
-WVPASS bup save -n compression -0 --strip "$top/Documentation"
-# Some platforms set -A by default when root, so just use it everywhere.
-expected="$(WVPASS ls -A "$top/Documentation" | WVPASS sort)" || exit $?
-actual="$(WVPASS bup ls -A compression/latest/ | WVPASS sort)" || exit $?
-WVPASSEQ "$actual" "$expected"
-compression_0_size=$(WVPASS fs-size "$BUP_DIR") || exit $?
-
-D=compression9.tmp
-WVPASS force-delete "$BUP_DIR"
-WVPASS bup init
-WVPASS mkdir $D
-WVPASS bup index "$top/Documentation"
-WVPASS bup save -n compression -9 --strip "$top/Documentation"
-expected="$(ls -A "$top/Documentation" | sort)" || exit $?
-actual="$(bup ls -A compression/latest/ | sort)" || exit $?
-WVPASSEQ "$actual" "$expected"
-compression_9_size=$(WVPASS fs-size "$BUP_DIR") || exit $?
-
-WVPASS [ "$compression_9_size" -lt "$compression_0_size" ]
-
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+. dev/lib.sh || exit $?
+
+set -o pipefail
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+
+WVPASS cd "$tmpdir"
+
+# These tests aren't comprehensive, but test-save-restore-excludes.sh
+# exercises some of the same code more thoroughly via index, and
+# --xdev is handled in test-xdev.sh.
+
+WVSTART "drecurse"
+WVPASS bup init
+WVPASS mkdir src src/a src/b
+WVPASS touch src/a/1 src/a/2 src/b/1 src/b/2 src/c
+(cd src && WVPASS ln -s a a-link)
+WVPASSEQ "$(bup drecurse src)" "src/c
+src/b/2
+src/b/1
+src/b/
+src/a/2
+src/a/1
+src/a/
+src/a-link
+src/"
+
+WVSTART "drecurse --exclude (file)"
+WVPASSEQ "$(bup drecurse --exclude src/b/2 src)" "src/c
+src/b/1
+src/b/
+src/a/2
+src/a/1
+src/a/
+src/a-link
+src/"
+
+WVSTART "drecurse --exclude (dir)"
+WVPASSEQ "$(bup drecurse --exclude src/b/ src)" "src/c
+src/a/2
+src/a/1
+src/a/
+src/a-link
+src/"
+
+WVSTART "drecurse --exclude (symlink)"
+WVPASSEQ "$(bup drecurse --exclude src/a-link src)" "src/c
+src/b/2
+src/b/1
+src/b/
+src/a/2
+src/a/1
+src/a/
+src/"
+
+WVSTART "drecurse --exclude (absolute path)"
+WVPASSEQ "$(bup drecurse --exclude src/b/2 "$(pwd)/src")" "$(pwd)/src/c
+$(pwd)/src/b/1
+$(pwd)/src/b/
+$(pwd)/src/a/2
+$(pwd)/src/a/1
+$(pwd)/src/a/
+$(pwd)/src/a-link
+$(pwd)/src/"
+
+WVSTART "drecurse --exclude-from"
+WVPASS echo "src/b" > exclude-list
+WVPASSEQ "$(bup drecurse --exclude-from exclude-list src)" "src/c
+src/a/2
+src/a/1
+src/a/
+src/a-link
+src/"
+
+WVSTART "drecurse --exclude-rx (trivial)"
+WVPASSEQ "$(bup drecurse --exclude-rx '^src/b' src)" "src/c
+src/a/2
+src/a/1
+src/a/
+src/a-link
+src/"
+
+WVSTART "drecurse --exclude-rx (trivial - absolute path)"
+WVPASSEQ "$(bup drecurse --exclude-rx "^$(pwd)/src/b" "$(pwd)/src")" \
+"$(pwd)/src/c
+$(pwd)/src/a/2
+$(pwd)/src/a/1
+$(pwd)/src/a/
+$(pwd)/src/a-link
+$(pwd)/src/"
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-. dev/lib.sh || exit $?
-
-set -o pipefail
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-
-WVPASS cd "$tmpdir"
-
-# These tests aren't comprehensive, but test-save-restore-excludes.sh
-# exercises some of the same code more thoroughly via index, and
-# --xdev is handled in test-xdev.sh.
-
-WVSTART "drecurse"
-WVPASS bup init
-WVPASS mkdir src src/a src/b
-WVPASS touch src/a/1 src/a/2 src/b/1 src/b/2 src/c
-(cd src && WVPASS ln -s a a-link)
-WVPASSEQ "$(bup drecurse src)" "src/c
-src/b/2
-src/b/1
-src/b/
-src/a/2
-src/a/1
-src/a/
-src/a-link
-src/"
-
-WVSTART "drecurse --exclude (file)"
-WVPASSEQ "$(bup drecurse --exclude src/b/2 src)" "src/c
-src/b/1
-src/b/
-src/a/2
-src/a/1
-src/a/
-src/a-link
-src/"
-
-WVSTART "drecurse --exclude (dir)"
-WVPASSEQ "$(bup drecurse --exclude src/b/ src)" "src/c
-src/a/2
-src/a/1
-src/a/
-src/a-link
-src/"
-
-WVSTART "drecurse --exclude (symlink)"
-WVPASSEQ "$(bup drecurse --exclude src/a-link src)" "src/c
-src/b/2
-src/b/1
-src/b/
-src/a/2
-src/a/1
-src/a/
-src/"
-
-WVSTART "drecurse --exclude (absolute path)"
-WVPASSEQ "$(bup drecurse --exclude src/b/2 "$(pwd)/src")" "$(pwd)/src/c
-$(pwd)/src/b/1
-$(pwd)/src/b/
-$(pwd)/src/a/2
-$(pwd)/src/a/1
-$(pwd)/src/a/
-$(pwd)/src/a-link
-$(pwd)/src/"
-
-WVSTART "drecurse --exclude-from"
-WVPASS echo "src/b" > exclude-list
-WVPASSEQ "$(bup drecurse --exclude-from exclude-list src)" "src/c
-src/a/2
-src/a/1
-src/a/
-src/a-link
-src/"
-
-WVSTART "drecurse --exclude-rx (trivial)"
-WVPASSEQ "$(bup drecurse --exclude-rx '^src/b' src)" "src/c
-src/a/2
-src/a/1
-src/a/
-src/a-link
-src/"
-
-WVSTART "drecurse --exclude-rx (trivial - absolute path)"
-WVPASSEQ "$(bup drecurse --exclude-rx "^$(pwd)/src/b" "$(pwd)/src")" \
-"$(pwd)/src/c
-$(pwd)/src/a/2
-$(pwd)/src/a/1
-$(pwd)/src/a/
-$(pwd)/src/a-link
-$(pwd)/src/"
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+
+set -o pipefail
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+bup() { "$top/bup" "$@"; }
+
+WVPASS "$top/dev/sync-tree" "$top/test/sampledata/" "$tmpdir/src/"
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+
+WVPASS bup init
+WVPASS cd "$tmpdir"
+
+WVSTART "fsck"
+
+WVPASS bup index src
+WVPASS bup save -n fsck-test src/b2
+WVPASS bup save -n fsck-test src/var/cmd
+WVPASS bup save -n fsck-test src/var/doc
+WVPASS bup save -n fsck-test src/var/lib
+WVPASS bup save -n fsck-test src/y
+WVPASS bup fsck
+WVPASS bup fsck "$BUP_DIR"/objects/pack/pack-*.pack
+WVPASS bup fsck --quick
+if bup fsck --par2-ok; then
+ WVSTART "fsck (par2)"
+else
+ WVSTART "fsck (PAR2 IS MISSING)"
+fi
+WVPASS bup fsck -g
+WVPASS bup fsck -r
+WVPASS bup damage "$BUP_DIR"/objects/pack/*.pack -n10 -s1 -S0
+WVFAIL bup fsck --quick
+WVFAIL bup fsck --quick --disable-par2
+WVPASS chmod u+w "$BUP_DIR"/objects/pack/*.idx
+WVPASS bup damage "$BUP_DIR"/objects/pack/*.idx -n10 -s1 -S0
+WVFAIL bup fsck --quick -j4
+WVPASS bup damage "$BUP_DIR"/objects/pack/*.pack -n10 -s1024 --percent 0.4 -S0
+WVFAIL bup fsck --quick
+WVFAIL bup fsck --quick -rvv -j99 # fails because repairs were needed
+if bup fsck --par2-ok; then
+ WVPASS bup fsck -r # ok because of repairs from last time
+ WVPASS bup damage "$BUP_DIR"/objects/pack/*.pack -n202 -s1 --equal -S0
+ WVFAIL bup fsck
+ WVFAIL bup fsck -rvv # too many errors to be repairable
+ WVFAIL bup fsck -r # too many errors to be repairable
+else
+ WVFAIL bup fsck --quick -r # still fails because par2 was missing
+fi
+
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-
-set -o pipefail
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-bup() { "$top/bup" "$@"; }
-
-WVPASS "$top/dev/sync-tree" "$top/test/sampledata/" "$tmpdir/src/"
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$tmpdir/bup"
-
-WVPASS bup init
-WVPASS cd "$tmpdir"
-
-WVSTART "fsck"
-
-WVPASS bup index src
-WVPASS bup save -n fsck-test src/b2
-WVPASS bup save -n fsck-test src/var/cmd
-WVPASS bup save -n fsck-test src/var/doc
-WVPASS bup save -n fsck-test src/var/lib
-WVPASS bup save -n fsck-test src/y
-WVPASS bup fsck
-WVPASS bup fsck "$BUP_DIR"/objects/pack/pack-*.pack
-WVPASS bup fsck --quick
-if bup fsck --par2-ok; then
- WVSTART "fsck (par2)"
-else
- WVSTART "fsck (PAR2 IS MISSING)"
-fi
-WVPASS bup fsck -g
-WVPASS bup fsck -r
-WVPASS bup damage "$BUP_DIR"/objects/pack/*.pack -n10 -s1 -S0
-WVFAIL bup fsck --quick
-WVFAIL bup fsck --quick --disable-par2
-WVPASS chmod u+w "$BUP_DIR"/objects/pack/*.idx
-WVPASS bup damage "$BUP_DIR"/objects/pack/*.idx -n10 -s1 -S0
-WVFAIL bup fsck --quick -j4
-WVPASS bup damage "$BUP_DIR"/objects/pack/*.pack -n10 -s1024 --percent 0.4 -S0
-WVFAIL bup fsck --quick
-WVFAIL bup fsck --quick -rvv -j99 # fails because repairs were needed
-if bup fsck --par2-ok; then
- WVPASS bup fsck -r # ok because of repairs from last time
- WVPASS bup damage "$BUP_DIR"/objects/pack/*.pack -n202 -s1 --equal -S0
- WVFAIL bup fsck
- WVFAIL bup fsck -rvv # too many errors to be repairable
- WVFAIL bup fsck -r # too many errors to be repairable
-else
- WVFAIL bup fsck --quick -r # still fails because par2 was missing
-fi
-
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+. dev/lib.sh || exit $?
+
+set -o pipefail
+
+unset BLOCKSIZE BLOCK_SIZE DF_BLOCK_SIZE
+
+root_status="$(dev/root-status)" || exit $?
+
+if ! bup-python -c 'import fuse' 2> /dev/null; then
+ WVSTART 'unable to import fuse; skipping test'
+ exit 0
+fi
+
+if test -n "$(type -p modprobe)" && ! modprobe fuse; then
+ echo 'Unable to load fuse module; skipping dependent tests.' 1>&2
+ exit 0
+fi
+
+if ! fusermount -V; then
+ echo 'skipping FUSE tests: fusermount does not appear to work'
+ exit 0
+fi
+
+if ! groups | grep -q fuse && test "$root_status" != root; then
+ echo 'skipping FUSE tests: you are not root and not in the fuse group'
+ exit 0
+fi
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+
+# Some versions of bash's printf don't support the relevant date expansion.
+savename()
+{
+ readonly secs="$1"
+ WVPASS bup-cfg-py -c "from time import strftime, localtime; \
+ print(strftime('%Y-%m-%d-%H%M%S', localtime($secs)))"
+}
+
+export TZ=UTC
+
+WVPASS bup init
+WVPASS cd "$tmpdir"
+
+savestamp1=$(WVPASS bup-cfg-py -c 'import time; print(int(time.time()))') || exit $?
+savestamp2=$(($savestamp1 + 1))
+
+savename1="$(savename "$savestamp1")" || exit $?
+savename2="$(savename "$savestamp2")" || exit $?
+
+WVPASS mkdir src
+WVPASS echo content > src/foo
+WVPASS chmod 644 src/foo
+WVPASS touch -t 201111111111 src/foo
+# FUSE, python-fuse, something, can't handle negative epoch times.
+# Use pre-epoch to make sure bup properly "bottoms out" at 0 for now.
+WVPASS echo content > src/pre-epoch
+WVPASS chmod 644 src/pre-epoch
+WVPASS touch -t 196907202018 src/pre-epoch
+WVPASS bup index src
+WVPASS bup save -n src -d "$savestamp1" --strip src
+
+WVSTART "basics"
+WVPASS mkdir mnt
+WVPASS bup fuse mnt
+
+result=$(WVPASS ls mnt) || exit $?
+WVPASSEQ src "$result"
+
+result=$(WVPASS ls mnt/src) || exit $?
+WVPASSEQ "$result" "$savename1
+latest"
+
+result=$(WVPASS ls mnt/src/latest) || exit $?
+WVPASSEQ "$result" "foo
+pre-epoch"
+
+result=$(WVPASS cat mnt/src/latest/foo) || exit $?
+WVPASSEQ "$result" "content"
+
+# Right now we don't detect new saves.
+WVPASS bup save -n src -d "$savestamp2" --strip src
+result=$(WVPASS ls mnt/src) || exit $?
+WVPASSEQ "$result" "$savename1
+latest"
+
+WVPASS fusermount -uz mnt
+
+WVSTART "extended metadata"
+WVPASS bup fuse --meta mnt
+readonly user=$(WVPASS id -un) || $?
+readonly group=$(WVPASS id -gn) || $?
+result="$(stat --format='%A %U %G %x' mnt/src/latest/foo)"
+WVPASSEQ "$result" "-rw-r--r-- $user $group 2011-11-11 11:11:00.000000000 +0000"
+result="$(stat --format='%A %U %G %x' mnt/src/latest/pre-epoch)"
+WVPASSEQ "$result" "-rw-r--r-- $user $group 1970-01-01 00:00:00.000000000 +0000"
+
+WVPASS fusermount -uz mnt
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-. dev/lib.sh || exit $?
-
-set -o pipefail
-
-unset BLOCKSIZE BLOCK_SIZE DF_BLOCK_SIZE
-
-root_status="$(dev/root-status)" || exit $?
-
-if ! bup-python -c 'import fuse' 2> /dev/null; then
- WVSTART 'unable to import fuse; skipping test'
- exit 0
-fi
-
-if test -n "$(type -p modprobe)" && ! modprobe fuse; then
- echo 'Unable to load fuse module; skipping dependent tests.' 1>&2
- exit 0
-fi
-
-if ! fusermount -V; then
- echo 'skipping FUSE tests: fusermount does not appear to work'
- exit 0
-fi
-
-if ! groups | grep -q fuse && test "$root_status" != root; then
- echo 'skipping FUSE tests: you are not root and not in the fuse group'
- exit 0
-fi
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-
-# Some versions of bash's printf don't support the relevant date expansion.
-savename()
-{
- readonly secs="$1"
- WVPASS bup-cfg-py -c "from time import strftime, localtime; \
- print(strftime('%Y-%m-%d-%H%M%S', localtime($secs)))"
-}
-
-export TZ=UTC
-
-WVPASS bup init
-WVPASS cd "$tmpdir"
-
-savestamp1=$(WVPASS bup-cfg-py -c 'import time; print(int(time.time()))') || exit $?
-savestamp2=$(($savestamp1 + 1))
-
-savename1="$(savename "$savestamp1")" || exit $?
-savename2="$(savename "$savestamp2")" || exit $?
-
-WVPASS mkdir src
-WVPASS echo content > src/foo
-WVPASS chmod 644 src/foo
-WVPASS touch -t 201111111111 src/foo
-# FUSE, python-fuse, something, can't handle negative epoch times.
-# Use pre-epoch to make sure bup properly "bottoms out" at 0 for now.
-WVPASS echo content > src/pre-epoch
-WVPASS chmod 644 src/pre-epoch
-WVPASS touch -t 196907202018 src/pre-epoch
-WVPASS bup index src
-WVPASS bup save -n src -d "$savestamp1" --strip src
-
-WVSTART "basics"
-WVPASS mkdir mnt
-WVPASS bup fuse mnt
-
-result=$(WVPASS ls mnt) || exit $?
-WVPASSEQ src "$result"
-
-result=$(WVPASS ls mnt/src) || exit $?
-WVPASSEQ "$result" "$savename1
-latest"
-
-result=$(WVPASS ls mnt/src/latest) || exit $?
-WVPASSEQ "$result" "foo
-pre-epoch"
-
-result=$(WVPASS cat mnt/src/latest/foo) || exit $?
-WVPASSEQ "$result" "content"
-
-# Right now we don't detect new saves.
-WVPASS bup save -n src -d "$savestamp2" --strip src
-result=$(WVPASS ls mnt/src) || exit $?
-WVPASSEQ "$result" "$savename1
-latest"
-
-WVPASS fusermount -uz mnt
-
-WVSTART "extended metadata"
-WVPASS bup fuse --meta mnt
-readonly user=$(WVPASS id -un) || $?
-readonly group=$(WVPASS id -gn) || $?
-result="$(stat --format='%A %U %G %x' mnt/src/latest/foo)"
-WVPASSEQ "$result" "-rw-r--r-- $user $group 2011-11-11 11:11:00.000000000 +0000"
-result="$(stat --format='%A %U %G %x' mnt/src/latest/pre-epoch)"
-WVPASSEQ "$result" "-rw-r--r-- $user $group 1970-01-01 00:00:00.000000000 +0000"
-
-WVPASS fusermount -uz mnt
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh
+
+set -o pipefail
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+
+GC_OPTS=--unsafe
+
+bup() { "$top/bup" "$@"; }
+compare-trees() { "$top/dev/compare-trees" "$@"; }
+data-size() { "$top/dev/data-size" "$@"; }
+
+WVPASS cd "$tmpdir"
+WVPASS bup init
+
+
+WVSTART "gc (unchanged repo)"
+
+WVPASS mkdir src-1
+WVPASS bup random 1k > src-1/1
+WVPASS bup index src-1
+WVPASS bup save --strip -n src-1 src-1
+
+WVPASS bup gc $GC_OPTS -v
+
+WVPASS bup restore -C "$tmpdir/restore" /src-1/latest
+WVPASS compare-trees src-1/ "$tmpdir/restore/latest/"
+
+
+WVSTART "gc (unchanged, new branch)"
+
+WVPASS mkdir src-2
+WVPASS bup random 10M > src-2/1
+WVPASS bup index src-2
+WVPASS bup save --strip -n src-2 src-2
+
+WVPASS bup gc $GC_OPTS -v
+
+WVPASS rm -r "$tmpdir/restore"
+WVPASS bup restore -C "$tmpdir/restore" /src-1/latest
+WVPASS compare-trees src-1/ "$tmpdir/restore/latest/"
+
+WVPASS rm -r "$tmpdir/restore"
+WVPASS bup restore -C "$tmpdir/restore" /src-2/latest
+WVPASS compare-trees src-2/ "$tmpdir/restore/latest/"
+
+
+WVSTART "gc (removed branch)"
+
+size_before=$(WVPASS data-size "$BUP_DIR") || exit $?
+WVPASS rm "$BUP_DIR/refs/heads/src-2"
+WVPASS bup gc $GC_OPTS -v
+size_after=$(WVPASS data-size "$BUP_DIR") || exit $?
+
+WVPASS [ "$size_before" -gt 5000000 ]
+WVPASS [ "$size_after" -lt 50000 ]
+
+WVPASS rm -r "$tmpdir/restore"
+WVPASS bup restore -C "$tmpdir/restore" /src-1/latest
+WVPASS compare-trees src-1/ "$tmpdir/restore/latest/"
+
+WVPASS rm -r "$tmpdir/restore"
+WVFAIL bup restore -C "$tmpdir/restore" /src-2/latest
+
+
+WVPASS mkdir src-ab-clean src-ab-clean/a src-ab-clean/b
+WVPASS bup random 1k > src-ab-clean/a/1
+WVPASS bup random 10M > src-ab-clean/b/1
+
+
+WVSTART "gc (rewriting)"
+
+WVPASS rm -rf "$BUP_DIR"
+WVPASS bup init
+WVPASS rm -rf src-ab
+WVPASS cp -pPR src-ab-clean src-ab
+
+WVPASS bup index src-ab
+WVPASS bup save --strip -n src-ab src-ab
+WVPASS bup index --clear
+WVPASS bup index src-ab
+WVPASS bup save -vvv --strip -n a src-ab/a
+
+size_before=$(WVPASS data-size "$BUP_DIR") || exit $?
+WVPASS rm "$BUP_DIR/refs/heads/src-ab"
+WVPASS bup gc $GC_OPTS -v
+size_after=$(WVPASS data-size "$BUP_DIR") || exit $?
+
+WVPASS [ "$size_before" -gt 5000000 ]
+WVPASS [ "$size_after" -lt 100000 ]
+
+WVPASS rm -r "$tmpdir/restore"
+WVPASS bup restore -C "$tmpdir/restore" /a/latest
+WVPASS compare-trees src-ab/a/ "$tmpdir/restore/latest/"
+
+WVPASS rm -r "$tmpdir/restore"
+WVFAIL bup restore -C "$tmpdir/restore" /src-ab/latest
+
+
+WVSTART "gc (save -r after repo rewriting)"
+
+WVPASS rm -rf "$BUP_DIR"
+WVPASS bup init
+WVPASS bup -d bup-remote init
+WVPASS rm -rf src-ab
+WVPASS cp -pPR src-ab-clean src-ab
+
+WVPASS bup index src-ab
+WVPASS bup save -r :bup-remote --strip -n src-ab src-ab
+WVPASS bup index --clear
+WVPASS bup index src-ab
+WVPASS bup save -r :bup-remote -vvv --strip -n a src-ab/a
+
+size_before=$(WVPASS data-size bup-remote) || exit $?
+WVPASS rm bup-remote/refs/heads/src-ab
+WVPASS bup -d bup-remote gc $GC_OPTS -v
+size_after=$(WVPASS data-size bup-remote) || exit $?
+
+WVPASS [ "$size_before" -gt 5000000 ]
+WVPASS [ "$size_after" -lt 100000 ]
+
+WVPASS rm -rf "$tmpdir/restore"
+WVPASS bup -d bup-remote restore -C "$tmpdir/restore" /a/latest
+WVPASS compare-trees src-ab/a/ "$tmpdir/restore/latest/"
+
+WVPASS rm -r "$tmpdir/restore"
+WVFAIL bup -d bup-remote restore -C "$tmpdir/restore" /src-ab/latest
+
+# Make sure a post-gc index/save that includes gc-ed data works
+WVPASS bup index src-ab
+WVPASS bup save -r :bup-remote --strip -n src-ab src-ab
+WVPASS rm -r "$tmpdir/restore"
+WVPASS bup -d bup-remote restore -C "$tmpdir/restore" /src-ab/latest
+WVPASS compare-trees src-ab/ "$tmpdir/restore/latest/"
+
+
+WVSTART "gc (bup on after repo rewriting)"
+
+WVPASS rm -rf "$BUP_DIR"
+WVPASS bup init
+WVPASS rm -rf src-ab
+WVPASS cp -pPR src-ab-clean src-ab
+
+WVPASS bup on - index src-ab
+WVPASS bup on - save --strip -n src-ab src-ab
+WVPASS bup index --clear
+WVPASS bup on - index src-ab
+WVPASS bup on - save -vvv --strip -n a src-ab/a
+
+size_before=$(WVPASS data-size "$BUP_DIR") || exit $?
+WVPASS rm "$BUP_DIR/refs/heads/src-ab"
+WVPASS bup gc $GC_OPTS -v
+size_after=$(WVPASS data-size "$BUP_DIR") || exit $?
+
+WVPASS [ "$size_before" -gt 5000000 ]
+WVPASS [ "$size_after" -lt 100000 ]
+
+WVPASS rm -r "$tmpdir/restore"
+WVPASS bup restore -C "$tmpdir/restore" /a/latest
+WVPASS compare-trees src-ab/a/ "$tmpdir/restore/latest/"
+
+WVPASS rm -r "$tmpdir/restore"
+WVFAIL bup restore -C "$tmpdir/restore" /src-ab/latest
+
+# Make sure a post-gc index/save that includes gc-ed data works
+WVPASS bup on - index src-ab
+WVPASS bup on - save --strip -n src-ab src-ab
+WVPASS rm -r "$tmpdir/restore"
+WVPASS bup restore -C "$tmpdir/restore" /src-ab/latest
+WVPASS compare-trees src-ab/ "$tmpdir/restore/latest/"
+
+
+WVSTART "gc (threshold)"
+
+WVPASS rm -rf "$BUP_DIR"
+WVPASS bup init
+WVPASS rm -rf src && mkdir src
+WVPASS echo 0 > src/0
+WVPASS echo 1 > src/1
+
+WVPASS bup index src
+WVPASS bup save -n src-1 src
+WVPASS rm src/0
+WVPASS bup index src
+WVPASS bup save -n src-2 src
+
+WVPASS bup rm --unsafe src-1
+packs_before="$(ls "$BUP_DIR/objects/pack/"*.pack)" || exit $?
+WVPASS bup gc -v $GC_OPTS --threshold 99 2>&1 | tee gc.log
+packs_after="$(ls "$BUP_DIR/objects/pack/"*.pack)" || exit $?
+WVPASSEQ 0 "$(grep -cE '^rewriting ' gc.log)"
+WVPASSEQ "$packs_before" "$packs_after"
+
+WVPASS bup gc -v $GC_OPTS --threshold 1 2>&1 | tee gc.log
+packs_after="$(ls "$BUP_DIR/objects/pack/"*.pack)" || exit $?
+WVPASSEQ 1 "$(grep -cE '^rewriting ' gc.log)"
+
+# Check that only one pack was rewritten
+
+# Accommodate some systems that apparently used to change the default
+# ls sort order which must match LC_COLLATE for comm to work.
+packs_before="$(sort <(echo "$packs_before"))" || die $?
+packs_after="$(sort <(echo "$packs_after"))" || die $?
+
+only_in_before="$(comm -2 -3 <(echo "$packs_before") <(echo "$packs_after"))" \
+ || die $?
+
+only_in_after="$(comm -1 -3 <(echo "$packs_before") <(echo "$packs_after"))" \
+ || die $?
+
+in_both="$(comm -1 -2 <(echo "$packs_before") <(echo "$packs_after"))" || die $?
+
+WVPASSEQ 1 $(echo "$only_in_before" | wc -l)
+WVPASSEQ 1 $(echo "$only_in_after" | wc -l)
+WVPASSEQ 1 $(echo "$in_both" | wc -l)
+
+WVSTART "gc (threshold 0)"
+
+WVPASS rm -rf "$BUP_DIR"
+WVPASS bup init
+WVPASS rm -rf src && mkdir src
+WVPASS echo 0 > src/0
+WVPASS echo 1 > src/1
+
+WVPASS bup index src
+WVPASS bup save -n src-1 src
+
+packs_before="$(ls "$BUP_DIR/objects/pack/"*.pack)" || exit $?
+WVPASS bup gc -v $GC_OPTS --threshold 0 2>&1 | tee gc.log
+packs_after="$(ls "$BUP_DIR/objects/pack/"*.pack)" || exit $?
+# Check that the pack was rewritten, but not removed (since the
+# result-pack is equal to the source pack)
+WVPASSEQ 1 "$(grep -cE '^rewriting ' gc.log)"
+WVPASSEQ "$packs_before" "$packs_after"
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh
-
-set -o pipefail
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$tmpdir/bup"
-
-GC_OPTS=--unsafe
-
-bup() { "$top/bup" "$@"; }
-compare-trees() { "$top/dev/compare-trees" "$@"; }
-data-size() { "$top/dev/data-size" "$@"; }
-
-WVPASS cd "$tmpdir"
-WVPASS bup init
-
-
-WVSTART "gc (unchanged repo)"
-
-WVPASS mkdir src-1
-WVPASS bup random 1k > src-1/1
-WVPASS bup index src-1
-WVPASS bup save --strip -n src-1 src-1
-
-WVPASS bup gc $GC_OPTS -v
-
-WVPASS bup restore -C "$tmpdir/restore" /src-1/latest
-WVPASS compare-trees src-1/ "$tmpdir/restore/latest/"
-
-
-WVSTART "gc (unchanged, new branch)"
-
-WVPASS mkdir src-2
-WVPASS bup random 10M > src-2/1
-WVPASS bup index src-2
-WVPASS bup save --strip -n src-2 src-2
-
-WVPASS bup gc $GC_OPTS -v
-
-WVPASS rm -r "$tmpdir/restore"
-WVPASS bup restore -C "$tmpdir/restore" /src-1/latest
-WVPASS compare-trees src-1/ "$tmpdir/restore/latest/"
-
-WVPASS rm -r "$tmpdir/restore"
-WVPASS bup restore -C "$tmpdir/restore" /src-2/latest
-WVPASS compare-trees src-2/ "$tmpdir/restore/latest/"
-
-
-WVSTART "gc (removed branch)"
-
-size_before=$(WVPASS data-size "$BUP_DIR") || exit $?
-WVPASS rm "$BUP_DIR/refs/heads/src-2"
-WVPASS bup gc $GC_OPTS -v
-size_after=$(WVPASS data-size "$BUP_DIR") || exit $?
-
-WVPASS [ "$size_before" -gt 5000000 ]
-WVPASS [ "$size_after" -lt 50000 ]
-
-WVPASS rm -r "$tmpdir/restore"
-WVPASS bup restore -C "$tmpdir/restore" /src-1/latest
-WVPASS compare-trees src-1/ "$tmpdir/restore/latest/"
-
-WVPASS rm -r "$tmpdir/restore"
-WVFAIL bup restore -C "$tmpdir/restore" /src-2/latest
-
-
-WVPASS mkdir src-ab-clean src-ab-clean/a src-ab-clean/b
-WVPASS bup random 1k > src-ab-clean/a/1
-WVPASS bup random 10M > src-ab-clean/b/1
-
-
-WVSTART "gc (rewriting)"
-
-WVPASS rm -rf "$BUP_DIR"
-WVPASS bup init
-WVPASS rm -rf src-ab
-WVPASS cp -pPR src-ab-clean src-ab
-
-WVPASS bup index src-ab
-WVPASS bup save --strip -n src-ab src-ab
-WVPASS bup index --clear
-WVPASS bup index src-ab
-WVPASS bup save -vvv --strip -n a src-ab/a
-
-size_before=$(WVPASS data-size "$BUP_DIR") || exit $?
-WVPASS rm "$BUP_DIR/refs/heads/src-ab"
-WVPASS bup gc $GC_OPTS -v
-size_after=$(WVPASS data-size "$BUP_DIR") || exit $?
-
-WVPASS [ "$size_before" -gt 5000000 ]
-WVPASS [ "$size_after" -lt 100000 ]
-
-WVPASS rm -r "$tmpdir/restore"
-WVPASS bup restore -C "$tmpdir/restore" /a/latest
-WVPASS compare-trees src-ab/a/ "$tmpdir/restore/latest/"
-
-WVPASS rm -r "$tmpdir/restore"
-WVFAIL bup restore -C "$tmpdir/restore" /src-ab/latest
-
-
-WVSTART "gc (save -r after repo rewriting)"
-
-WVPASS rm -rf "$BUP_DIR"
-WVPASS bup init
-WVPASS bup -d bup-remote init
-WVPASS rm -rf src-ab
-WVPASS cp -pPR src-ab-clean src-ab
-
-WVPASS bup index src-ab
-WVPASS bup save -r :bup-remote --strip -n src-ab src-ab
-WVPASS bup index --clear
-WVPASS bup index src-ab
-WVPASS bup save -r :bup-remote -vvv --strip -n a src-ab/a
-
-size_before=$(WVPASS data-size bup-remote) || exit $?
-WVPASS rm bup-remote/refs/heads/src-ab
-WVPASS bup -d bup-remote gc $GC_OPTS -v
-size_after=$(WVPASS data-size bup-remote) || exit $?
-
-WVPASS [ "$size_before" -gt 5000000 ]
-WVPASS [ "$size_after" -lt 100000 ]
-
-WVPASS rm -rf "$tmpdir/restore"
-WVPASS bup -d bup-remote restore -C "$tmpdir/restore" /a/latest
-WVPASS compare-trees src-ab/a/ "$tmpdir/restore/latest/"
-
-WVPASS rm -r "$tmpdir/restore"
-WVFAIL bup -d bup-remote restore -C "$tmpdir/restore" /src-ab/latest
-
-# Make sure a post-gc index/save that includes gc-ed data works
-WVPASS bup index src-ab
-WVPASS bup save -r :bup-remote --strip -n src-ab src-ab
-WVPASS rm -r "$tmpdir/restore"
-WVPASS bup -d bup-remote restore -C "$tmpdir/restore" /src-ab/latest
-WVPASS compare-trees src-ab/ "$tmpdir/restore/latest/"
-
-
-WVSTART "gc (bup on after repo rewriting)"
-
-WVPASS rm -rf "$BUP_DIR"
-WVPASS bup init
-WVPASS rm -rf src-ab
-WVPASS cp -pPR src-ab-clean src-ab
-
-WVPASS bup on - index src-ab
-WVPASS bup on - save --strip -n src-ab src-ab
-WVPASS bup index --clear
-WVPASS bup on - index src-ab
-WVPASS bup on - save -vvv --strip -n a src-ab/a
-
-size_before=$(WVPASS data-size "$BUP_DIR") || exit $?
-WVPASS rm "$BUP_DIR/refs/heads/src-ab"
-WVPASS bup gc $GC_OPTS -v
-size_after=$(WVPASS data-size "$BUP_DIR") || exit $?
-
-WVPASS [ "$size_before" -gt 5000000 ]
-WVPASS [ "$size_after" -lt 100000 ]
-
-WVPASS rm -r "$tmpdir/restore"
-WVPASS bup restore -C "$tmpdir/restore" /a/latest
-WVPASS compare-trees src-ab/a/ "$tmpdir/restore/latest/"
-
-WVPASS rm -r "$tmpdir/restore"
-WVFAIL bup restore -C "$tmpdir/restore" /src-ab/latest
-
-# Make sure a post-gc index/save that includes gc-ed data works
-WVPASS bup on - index src-ab
-WVPASS bup on - save --strip -n src-ab src-ab
-WVPASS rm -r "$tmpdir/restore"
-WVPASS bup restore -C "$tmpdir/restore" /src-ab/latest
-WVPASS compare-trees src-ab/ "$tmpdir/restore/latest/"
-
-
-WVSTART "gc (threshold)"
-
-WVPASS rm -rf "$BUP_DIR"
-WVPASS bup init
-WVPASS rm -rf src && mkdir src
-WVPASS echo 0 > src/0
-WVPASS echo 1 > src/1
-
-WVPASS bup index src
-WVPASS bup save -n src-1 src
-WVPASS rm src/0
-WVPASS bup index src
-WVPASS bup save -n src-2 src
-
-WVPASS bup rm --unsafe src-1
-packs_before="$(ls "$BUP_DIR/objects/pack/"*.pack)" || exit $?
-WVPASS bup gc -v $GC_OPTS --threshold 99 2>&1 | tee gc.log
-packs_after="$(ls "$BUP_DIR/objects/pack/"*.pack)" || exit $?
-WVPASSEQ 0 "$(grep -cE '^rewriting ' gc.log)"
-WVPASSEQ "$packs_before" "$packs_after"
-
-WVPASS bup gc -v $GC_OPTS --threshold 1 2>&1 | tee gc.log
-packs_after="$(ls "$BUP_DIR/objects/pack/"*.pack)" || exit $?
-WVPASSEQ 1 "$(grep -cE '^rewriting ' gc.log)"
-
-# Check that only one pack was rewritten
-
-# Accommodate some systems that apparently used to change the default
-# ls sort order which must match LC_COLLATE for comm to work.
-packs_before="$(sort <(echo "$packs_before"))" || die $?
-packs_after="$(sort <(echo "$packs_after"))" || die $?
-
-only_in_before="$(comm -2 -3 <(echo "$packs_before") <(echo "$packs_after"))" \
- || die $?
-
-only_in_after="$(comm -1 -3 <(echo "$packs_before") <(echo "$packs_after"))" \
- || die $?
-
-in_both="$(comm -1 -2 <(echo "$packs_before") <(echo "$packs_after"))" || die $?
-
-WVPASSEQ 1 $(echo "$only_in_before" | wc -l)
-WVPASSEQ 1 $(echo "$only_in_after" | wc -l)
-WVPASSEQ 1 $(echo "$in_both" | wc -l)
-
-WVSTART "gc (threshold 0)"
-
-WVPASS rm -rf "$BUP_DIR"
-WVPASS bup init
-WVPASS rm -rf src && mkdir src
-WVPASS echo 0 > src/0
-WVPASS echo 1 > src/1
-
-WVPASS bup index src
-WVPASS bup save -n src-1 src
-
-packs_before="$(ls "$BUP_DIR/objects/pack/"*.pack)" || exit $?
-WVPASS bup gc -v $GC_OPTS --threshold 0 2>&1 | tee gc.log
-packs_after="$(ls "$BUP_DIR/objects/pack/"*.pack)" || exit $?
-# Check that the pack was rewritten, but not removed (since the
-# result-pack is equal to the source pack)
-WVPASSEQ 1 "$(grep -cE '^rewriting ' gc.log)"
-WVPASSEQ "$packs_before" "$packs_after"
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+
+set -o pipefail
+
+if ! [ "$(type -p duplicity)" != "" ]; then
+ # FIXME: add WVSKIP.
+ echo "Cannot find duplicity; skipping test)" 1>&2
+ exit 0
+fi
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+bup() { "$top/bup" "$@"; }
+dup() { duplicity --archive-dir "$tmpdir/dup-cache" "$@"; }
+
+WVSTART "import-duplicity"
+WVPASS "$top/dev/sync-tree" "$top/test/sampledata/" "$tmpdir/src/"
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+export PASSPHRASE=bup_duplicity_passphrase
+
+WVPASS bup init
+WVPASS cd "$tmpdir"
+WVPASS mkdir duplicity
+WVPASS dup src file://duplicity
+WVPASS bup tick
+WVPASS touch src/new-file
+WVPASS dup src file://duplicity
+WVPASS bup import-duplicity "file://duplicity" import-duplicity
+WVPASSEQ $(bup ls import-duplicity/ | wc -l) 3
+WVPASSEQ "$(bup ls import-duplicity/latest/ | sort)" "$(ls src | sort)"
+WVPASS bup restore -C restore/ import-duplicity/latest/
+WVFAIL "$top/dev/compare-trees" src/ restore/ > tmp-compare-trees
+WVPASSEQ $(cat tmp-compare-trees | wc -l) 4
+# Note: OS X rsync itemize output is currently only 9 chars, not 11.
+# FreeBSD may output 12 chars instead - accept 9-12
+# Expect something like this (without the leading spaces):
+# .d..t...... ./
+# .L..t...... abs-symlink -> /home/foo/bup/test/sampledata/var/abs-symlink-target
+# .L..t...... b -> a
+# .L..t...... c -> b
+expected_diff_rx='^\.d\.\.t\.{4,7} \./$|^\.L\.\.t\.{4,7} '
+if ! grep -qE "$expected_diff_rx" tmp-compare-trees; then
+ echo -n 'tmp-compare-trees: ' 1>&2
+ cat tmp-compare-trees 1>&2
+fi
+WVPASS grep -qE "$expected_diff_rx" tmp-compare-trees
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-
-set -o pipefail
-
-if ! [ "$(type -p duplicity)" != "" ]; then
- # FIXME: add WVSKIP.
- echo "Cannot find duplicity; skipping test)" 1>&2
- exit 0
-fi
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-bup() { "$top/bup" "$@"; }
-dup() { duplicity --archive-dir "$tmpdir/dup-cache" "$@"; }
-
-WVSTART "import-duplicity"
-WVPASS "$top/dev/sync-tree" "$top/test/sampledata/" "$tmpdir/src/"
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$tmpdir/bup"
-export PASSPHRASE=bup_duplicity_passphrase
-
-WVPASS bup init
-WVPASS cd "$tmpdir"
-WVPASS mkdir duplicity
-WVPASS dup src file://duplicity
-WVPASS bup tick
-WVPASS touch src/new-file
-WVPASS dup src file://duplicity
-WVPASS bup import-duplicity "file://duplicity" import-duplicity
-WVPASSEQ $(bup ls import-duplicity/ | wc -l) 3
-WVPASSEQ "$(bup ls import-duplicity/latest/ | sort)" "$(ls src | sort)"
-WVPASS bup restore -C restore/ import-duplicity/latest/
-WVFAIL "$top/dev/compare-trees" src/ restore/ > tmp-compare-trees
-WVPASSEQ $(cat tmp-compare-trees | wc -l) 4
-# Note: OS X rsync itemize output is currently only 9 chars, not 11.
-# FreeBSD may output 12 chars instead - accept 9-12
-# Expect something like this (without the leading spaces):
-# .d..t...... ./
-# .L..t...... abs-symlink -> /home/foo/bup/test/sampledata/var/abs-symlink-target
-# .L..t...... b -> a
-# .L..t...... c -> b
-expected_diff_rx='^\.d\.\.t\.{4,7} \./$|^\.L\.\.t\.{4,7} '
-if ! grep -qE "$expected_diff_rx" tmp-compare-trees; then
- echo -n 'tmp-compare-trees: ' 1>&2
- cat tmp-compare-trees 1>&2
-fi
-WVPASS grep -qE "$expected_diff_rx" tmp-compare-trees
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+
+set -o pipefail
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+
+if ! [ "$(type -p rdiff-backup)" != "" ]; then
+ # FIXME: add WVSKIP.
+ echo "Cannot find rdiff-backup; skipping test)" 1>&2
+ exit 0
+fi
+
+D=rdiff-backup.tmp
+WVSTART "import-rdiff-backup"
+WVPASS bup init
+WVPASS cd "$tmpdir"
+WVPASS mkdir rdiff-backup
+WVPASS rdiff-backup "$top/lib/cmd" rdiff-backup
+WVPASS bup tick
+WVPASS rdiff-backup "$top/Documentation" rdiff-backup
+WVPASS bup import-rdiff-backup rdiff-backup import-rdiff-backup
+WVPASSEQ $(bup ls import-rdiff-backup/ | wc -l) 3
+WVPASSEQ "$(bup ls -A import-rdiff-backup/latest/ | sort)" \
+ "$(ls -A "$top/Documentation" | sort)"
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-
-set -o pipefail
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-
-if ! [ "$(type -p rdiff-backup)" != "" ]; then
- # FIXME: add WVSKIP.
- echo "Cannot find rdiff-backup; skipping test)" 1>&2
- exit 0
-fi
-
-D=rdiff-backup.tmp
-WVSTART "import-rdiff-backup"
-WVPASS bup init
-WVPASS cd "$tmpdir"
-WVPASS mkdir rdiff-backup
-WVPASS rdiff-backup "$top/lib/cmd" rdiff-backup
-WVPASS bup tick
-WVPASS rdiff-backup "$top/Documentation" rdiff-backup
-WVPASS bup import-rdiff-backup rdiff-backup import-rdiff-backup
-WVPASSEQ $(bup ls import-rdiff-backup/ | wc -l) 3
-WVPASSEQ "$(bup ls -A import-rdiff-backup/latest/ | sort)" \
- "$(ls -A "$top/Documentation" | sort)"
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. wvtest.sh
+. wvtest-bup.sh
+. dev/lib.sh
+
+set -o pipefail
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+export BUP_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+
+WVPASS cd "$tmpdir"
+
+WVPASS bup init
+
+WVSTART "index"
+D=bupdata.tmp
+WVPASS force-delete $D
+WVPASS mkdir $D
+WVFAIL bup index --exclude-from $D/cannot-exist $D
+WVPASSEQ "$(bup index --check -p)" ""
+WVPASSEQ "$(bup index --check -p $D)" ""
+WVFAIL [ -e $D.fake ]
+WVFAIL bup index --check -u $D.fake
+WVPASS bup index --check -u $D
+WVPASSEQ "$(bup index --check -p $D)" "$D/"
+WVPASS touch $D/a
+WVPASS bup random 128k >$D/b
+WVPASS mkdir $D/d $D/d/e
+WVPASS bup random 512 >$D/f
+WVPASS ln -s non-existent-file $D/g
+WVPASSEQ "$(bup index -s $D/)" "A $D/"
+WVPASSEQ "$(bup index -s $D/b)" ""
+WVPASSEQ "$(bup index --check -us $D/b)" "A $D/b"
+WVPASSEQ "$(bup index --check -us $D/b $D/d)" \
+"A $D/d/e/
+A $D/d/
+A $D/b"
+WVPASS touch $D/d/z
+WVPASS bup tick
+WVPASSEQ "$(bup index --check -usx $D)" \
+"A $D/g
+A $D/f
+A $D/d/z
+A $D/d/e/
+A $D/d/
+A $D/b
+A $D/a
+A $D/"
+WVPASSEQ "$(bup index --check -us $D/a $D/b --fake-valid)" \
+" $D/b
+ $D/a"
+WVPASSEQ "$(bup index --check -us $D/a)" " $D/a" # stays unmodified
+WVPASSEQ "$(bup index --check -us $D/d --fake-valid)" \
+" $D/d/z
+ $D/d/e/
+ $D/d/"
+WVPASS touch $D/d/z
+WVPASS bup index -u $D/d/z # becomes modified
+WVPASSEQ "$(bup index -s $D/a $D $D/b)" \
+"A $D/g
+A $D/f
+M $D/d/z
+ $D/d/e/
+M $D/d/
+ $D/b
+ $D/a
+A $D/"
+
+WVPASS bup index -u $D/d/e $D/a --fake-invalid
+WVPASSEQ "$(cd $D && bup index -m .)" \
+"./g
+./f
+./d/z
+./d/e/
+./d/
+./a
+./"
+WVPASSEQ "$(cd $D && bup index -m)" \
+"g
+f
+d/z
+d/e/
+d/
+a
+./"
+WVPASSEQ "$(cd $D && bup index -s .)" "$(cd $D && bup index -s .)"
+
+WVFAIL bup save -t $D/doesnt-exist-filename
+
+WVPASS mv "$BUP_DIR/bupindex" "$BUP_DIR/bi.old"
+WVFAIL bup save -t $D/d/e/fifotest
+WVPASS mkfifo $D/d/e/fifotest
+WVPASS bup index -u $D/d/e/fifotest
+WVPASS bup save -t $D/d/e/fifotest
+WVPASS bup save -t $D/d/e
+WVPASS rm -f $D/d/e/fifotest
+WVPASS bup index -u $D/d/e
+WVFAIL bup save -t $D/d/e/fifotest
+WVPASS mv "$BUP_DIR/bi.old" "$BUP_DIR/bupindex"
+
+WVPASS bup index -u $D/d/e
+WVPASS bup save -t $D/d/e
+WVPASSEQ "$(cd $D && bup index -m)" \
+"g
+f
+d/z
+d/
+a
+./"
+WVPASS bup save -t $D/d
+WVPASS bup index --fake-invalid $D/d/z
+WVPASS bup save -t $D/d/z
+WVPASS bup save -t $D/d/z # test regenerating trees when no files are changed
+WVPASS bup save -t $D/d
+WVPASSEQ "$(cd $D && bup index -m)" \
+"g
+f
+a
+./"
+WVPASS bup save -r ":$BUP_DIR" -n r-test $D
+WVFAIL bup save -r ":$BUP_DIR/fake/path" -n r-test $D
+WVFAIL bup save -r ":$BUP_DIR" -n r-test $D/fake/path
+
+WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+. ./dev/lib.sh || exit $?
+
+set -o pipefail
+
+root_status="$(dev/root-status)" || exit $?
+
+if [ "$root_status" != root ]; then
+ echo 'Not root: skipping --check-device tests.'
+ exit 0 # FIXME: add WVSKIP.
+fi
+
+if test -n "$(type -p modprobe)" && ! modprobe loop; then
+ echo 'Unable to load loopback module; skipping --check-device test.' 1>&2
+ exit 0
+fi
+
+if test -z "$(type -p losetup)"; then
+ echo 'Unable to find losetup: skipping --check-device tests.' 1>&2
+ exit 0 # FIXME: add WVSKIP.
+fi
+
+if test -z "$(type -p mke2fs)"; then
+ echo 'Unable to find mke2fs: skipping --check-device tests.' 1>&2
+ exit 0 # FIXME: add WVSKIP.
+fi
+
+WVSTART '--check-device'
+
+top="$(pwd)"
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+
+srcmnt="$(WVPASS wvmkmountpt)" || exit $?
+tmpmnt1="$(WVPASS wvmkmountpt)" || exit $?
+tmpmnt2="$(WVPASS wvmkmountpt)" || exit $?
+
+WVPASS cd "$tmpdir"
+
+WVPASS dd if=/dev/zero of=testfs.img bs=1M count=32
+WVPASS mke2fs -F -j -m 0 testfs.img
+WVPASS mount -o loop testfs.img "$tmpmnt1"
+# Hide, so that tests can't create risks.
+WVPASS chown root:root "$tmpmnt1"
+WVPASS chmod 0700 "$tmpmnt1"
+
+# Create trivial content.
+WVPASS date > "$tmpmnt1/foo"
+WVPASS umount "$tmpmnt1"
+
+# Mount twice, so we'll have the same content with different devices.
+WVPASS cp -pP testfs.img testfs2.img
+WVPASS mount -oro,loop testfs.img "$tmpmnt1"
+WVPASS mount -oro,loop testfs2.img "$tmpmnt2"
+
+# Test default behavior: --check-device.
+WVPASS mount -oro --bind "$tmpmnt1" "$srcmnt"
+WVPASS bup init
+WVPASS bup index --fake-valid "$srcmnt"
+WVPASS umount "$srcmnt"
+WVPASS mount -oro --bind "$tmpmnt2" "$srcmnt"
+WVPASS bup index "$srcmnt"
+WVPASSEQ "$(bup index --status "$srcmnt")" \
+"M $srcmnt/lost+found/
+M $srcmnt/foo
+M $srcmnt/"
+WVPASS umount "$srcmnt"
+
+WVSTART '--no-check-device'
+WVPASS mount -oro --bind "$tmpmnt1" "$srcmnt"
+WVPASS bup index --clear
+WVPASS bup index --fake-valid "$srcmnt"
+WVPASS umount "$srcmnt"
+WVPASS mount -oro --bind "$tmpmnt2" "$srcmnt"
+WVPASS bup index --no-check-device "$srcmnt"
+WVPASS bup index --status "$srcmnt"
+WVPASSEQ "$(bup index --status "$srcmnt")" \
+" $srcmnt/lost+found/
+ $srcmnt/foo
+ $srcmnt/"
+
+WVPASS umount "$srcmnt"
+WVPASS umount "$tmpmnt1"
+WVPASS umount "$tmpmnt2"
+WVPASS rm -r "$tmpmnt1" "$tmpmnt2" "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-. ./dev/lib.sh || exit $?
-
-set -o pipefail
-
-root_status="$(dev/root-status)" || exit $?
-
-if [ "$root_status" != root ]; then
- echo 'Not root: skipping --check-device tests.'
- exit 0 # FIXME: add WVSKIP.
-fi
-
-if test -n "$(type -p modprobe)" && ! modprobe loop; then
- echo 'Unable to load loopback module; skipping --check-device test.' 1>&2
- exit 0
-fi
-
-if test -z "$(type -p losetup)"; then
- echo 'Unable to find losetup: skipping --check-device tests.' 1>&2
- exit 0 # FIXME: add WVSKIP.
-fi
-
-if test -z "$(type -p mke2fs)"; then
- echo 'Unable to find mke2fs: skipping --check-device tests.' 1>&2
- exit 0 # FIXME: add WVSKIP.
-fi
-
-WVSTART '--check-device'
-
-top="$(pwd)"
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-export BUP_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-
-srcmnt="$(WVPASS wvmkmountpt)" || exit $?
-tmpmnt1="$(WVPASS wvmkmountpt)" || exit $?
-tmpmnt2="$(WVPASS wvmkmountpt)" || exit $?
-
-WVPASS cd "$tmpdir"
-
-WVPASS dd if=/dev/zero of=testfs.img bs=1M count=32
-WVPASS mke2fs -F -j -m 0 testfs.img
-WVPASS mount -o loop testfs.img "$tmpmnt1"
-# Hide, so that tests can't create risks.
-WVPASS chown root:root "$tmpmnt1"
-WVPASS chmod 0700 "$tmpmnt1"
-
-# Create trivial content.
-WVPASS date > "$tmpmnt1/foo"
-WVPASS umount "$tmpmnt1"
-
-# Mount twice, so we'll have the same content with different devices.
-WVPASS cp -pP testfs.img testfs2.img
-WVPASS mount -oro,loop testfs.img "$tmpmnt1"
-WVPASS mount -oro,loop testfs2.img "$tmpmnt2"
-
-# Test default behavior: --check-device.
-WVPASS mount -oro --bind "$tmpmnt1" "$srcmnt"
-WVPASS bup init
-WVPASS bup index --fake-valid "$srcmnt"
-WVPASS umount "$srcmnt"
-WVPASS mount -oro --bind "$tmpmnt2" "$srcmnt"
-WVPASS bup index "$srcmnt"
-WVPASSEQ "$(bup index --status "$srcmnt")" \
-"M $srcmnt/lost+found/
-M $srcmnt/foo
-M $srcmnt/"
-WVPASS umount "$srcmnt"
-
-WVSTART '--no-check-device'
-WVPASS mount -oro --bind "$tmpmnt1" "$srcmnt"
-WVPASS bup index --clear
-WVPASS bup index --fake-valid "$srcmnt"
-WVPASS umount "$srcmnt"
-WVPASS mount -oro --bind "$tmpmnt2" "$srcmnt"
-WVPASS bup index --no-check-device "$srcmnt"
-WVPASS bup index --status "$srcmnt"
-WVPASSEQ "$(bup index --status "$srcmnt")" \
-" $srcmnt/lost+found/
- $srcmnt/foo
- $srcmnt/"
-
-WVPASS umount "$srcmnt"
-WVPASS umount "$tmpmnt1"
-WVPASS umount "$tmpmnt2"
-WVPASS rm -r "$tmpmnt1" "$tmpmnt2" "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+
+set -o pipefail
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+
+
+WVPASS bup init
+WVPASS cd "$tmpdir"
+
+
+WVSTART "index --clear"
+WVPASS mkdir src
+WVPASS touch src/foo src/bar
+WVPASS bup index -u src
+WVPASSEQ "$(bup index -p)" "src/foo
+src/bar
+src/
+./"
+WVPASS rm src/foo
+WVPASS bup index --clear
+WVPASS bup index -u src
+expected="$(WVPASS bup index -p)" || exit $?
+WVPASSEQ "$expected" "src/bar
+src/
+./"
+
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-
-set -o pipefail
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-
-
-WVPASS bup init
-WVPASS cd "$tmpdir"
-
-
-WVSTART "index --clear"
-WVPASS mkdir src
-WVPASS touch src/foo src/bar
-WVPASS bup index -u src
-WVPASSEQ "$(bup index -p)" "src/foo
-src/bar
-src/
-./"
-WVPASS rm src/foo
-WVPASS bup index --clear
-WVPASS bup index -u src
-expected="$(WVPASS bup index -p)" || exit $?
-WVPASSEQ "$expected" "src/bar
-src/
-./"
-
-
-WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. wvtest.sh
-. wvtest-bup.sh
-. dev/lib.sh
-
-set -o pipefail
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-export BUP_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-
-WVPASS cd "$tmpdir"
-
-WVPASS bup init
-
-WVSTART "index"
-D=bupdata.tmp
-WVPASS force-delete $D
-WVPASS mkdir $D
-WVFAIL bup index --exclude-from $D/cannot-exist $D
-WVPASSEQ "$(bup index --check -p)" ""
-WVPASSEQ "$(bup index --check -p $D)" ""
-WVFAIL [ -e $D.fake ]
-WVFAIL bup index --check -u $D.fake
-WVPASS bup index --check -u $D
-WVPASSEQ "$(bup index --check -p $D)" "$D/"
-WVPASS touch $D/a
-WVPASS bup random 128k >$D/b
-WVPASS mkdir $D/d $D/d/e
-WVPASS bup random 512 >$D/f
-WVPASS ln -s non-existent-file $D/g
-WVPASSEQ "$(bup index -s $D/)" "A $D/"
-WVPASSEQ "$(bup index -s $D/b)" ""
-WVPASSEQ "$(bup index --check -us $D/b)" "A $D/b"
-WVPASSEQ "$(bup index --check -us $D/b $D/d)" \
-"A $D/d/e/
-A $D/d/
-A $D/b"
-WVPASS touch $D/d/z
-WVPASS bup tick
-WVPASSEQ "$(bup index --check -usx $D)" \
-"A $D/g
-A $D/f
-A $D/d/z
-A $D/d/e/
-A $D/d/
-A $D/b
-A $D/a
-A $D/"
-WVPASSEQ "$(bup index --check -us $D/a $D/b --fake-valid)" \
-" $D/b
- $D/a"
-WVPASSEQ "$(bup index --check -us $D/a)" " $D/a" # stays unmodified
-WVPASSEQ "$(bup index --check -us $D/d --fake-valid)" \
-" $D/d/z
- $D/d/e/
- $D/d/"
-WVPASS touch $D/d/z
-WVPASS bup index -u $D/d/z # becomes modified
-WVPASSEQ "$(bup index -s $D/a $D $D/b)" \
-"A $D/g
-A $D/f
-M $D/d/z
- $D/d/e/
-M $D/d/
- $D/b
- $D/a
-A $D/"
-
-WVPASS bup index -u $D/d/e $D/a --fake-invalid
-WVPASSEQ "$(cd $D && bup index -m .)" \
-"./g
-./f
-./d/z
-./d/e/
-./d/
-./a
-./"
-WVPASSEQ "$(cd $D && bup index -m)" \
-"g
-f
-d/z
-d/e/
-d/
-a
-./"
-WVPASSEQ "$(cd $D && bup index -s .)" "$(cd $D && bup index -s .)"
-
-WVFAIL bup save -t $D/doesnt-exist-filename
-
-WVPASS mv "$BUP_DIR/bupindex" "$BUP_DIR/bi.old"
-WVFAIL bup save -t $D/d/e/fifotest
-WVPASS mkfifo $D/d/e/fifotest
-WVPASS bup index -u $D/d/e/fifotest
-WVPASS bup save -t $D/d/e/fifotest
-WVPASS bup save -t $D/d/e
-WVPASS rm -f $D/d/e/fifotest
-WVPASS bup index -u $D/d/e
-WVFAIL bup save -t $D/d/e/fifotest
-WVPASS mv "$BUP_DIR/bi.old" "$BUP_DIR/bupindex"
-
-WVPASS bup index -u $D/d/e
-WVPASS bup save -t $D/d/e
-WVPASSEQ "$(cd $D && bup index -m)" \
-"g
-f
-d/z
-d/
-a
-./"
-WVPASS bup save -t $D/d
-WVPASS bup index --fake-invalid $D/d/z
-WVPASS bup save -t $D/d/z
-WVPASS bup save -t $D/d/z # test regenerating trees when no files are changed
-WVPASS bup save -t $D/d
-WVPASSEQ "$(cd $D && bup index -m)" \
-"g
-f
-a
-./"
-WVPASS bup save -r ":$BUP_DIR" -n r-test $D
-WVFAIL bup save -r ":$BUP_DIR/fake/path" -n r-test $D
-WVFAIL bup save -r ":$BUP_DIR" -n r-test $D/fake/path
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. wvtest-bup.sh || exit $?
+. dev/lib.sh || exit $?
+
+set -o pipefail
+
+TOP="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+export BUP_DIR="$tmpdir/bup"
+
+bup()
+{
+ "$TOP/bup" "$@"
+}
+
+WVSTART 'bup list-idx'
+
+WVPASS bup init
+WVPASS cd "$tmpdir"
+WVPASS mkdir src
+WVPASS bup random 1k > src/data
+WVPASS bup index src
+WVPASS bup save -n src src
+WVPASS bup list-idx "$BUP_DIR"/objects/pack/*.idx
+hash1="$(WVPASS bup list-idx "$BUP_DIR"/objects/pack/*.idx)" || exit $?
+hash1="${hash1##* }"
+WVPASS bup list-idx --find "${hash1}" "$BUP_DIR"/objects/pack/*.idx \
+ > list-idx.log || exit $?
+found="$(cat list-idx.log)" || exit $?
+found="${found##* }"
+WVPASSEQ "$found" "$hash1"
+WVPASSEQ "$(wc -l < list-idx.log | tr -d ' ')" 1
+
+WVPASS rm -r "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. wvtest-bup.sh || exit $?
-. dev/lib.sh || exit $?
-
-set -o pipefail
-
-TOP="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-export BUP_DIR="$tmpdir/bup"
-
-bup()
-{
- "$TOP/bup" "$@"
-}
-
-WVSTART 'bup list-idx'
-
-WVPASS bup init
-WVPASS cd "$tmpdir"
-WVPASS mkdir src
-WVPASS bup random 1k > src/data
-WVPASS bup index src
-WVPASS bup save -n src src
-WVPASS bup list-idx "$BUP_DIR"/objects/pack/*.idx
-hash1="$(WVPASS bup list-idx "$BUP_DIR"/objects/pack/*.idx)" || exit $?
-hash1="${hash1##* }"
-WVPASS bup list-idx --find "${hash1}" "$BUP_DIR"/objects/pack/*.idx \
- > list-idx.log || exit $?
-found="$(cat list-idx.log)" || exit $?
-found="${found##* }"
-WVPASSEQ "$found" "$hash1"
-WVPASSEQ "$(wc -l < list-idx.log | tr -d ' ')" 1
-
-WVPASS rm -r "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. wvtest-bup.sh || exit $?
+. dev/lib.sh || exit $?
+
+set -o pipefail
+
+TOP="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+export BUP_DIR="$tmpdir/bup"
+
+bup()
+{
+ "$TOP/bup" "$@"
+}
+
+WVSTART 'main'
+
+bup
+rc=$?
+WVPASSEQ "$rc" 99
+
+WVPASS rm -r "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. wvtest-bup.sh || exit $?
-. dev/lib.sh || exit $?
-
-set -o pipefail
-
-TOP="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-export BUP_DIR="$tmpdir/bup"
-
-bup()
-{
- "$TOP/bup" "$@"
-}
-
-WVSTART 'main'
-
-bup
-rc=$?
-WVPASSEQ "$rc" 99
-
-WVPASS rm -r "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. wvtest-bup.sh || exit $?
+. dev/lib.sh || exit $?
+
+set -o pipefail
+
+root_status="$(dev/root-status)" || exit $?
+
+TOP="$(WVPASS pwd)" || exit $?
+export PATH="$TOP/test/bin:$PATH"
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+export BUP_DIR="$tmpdir/bup"
+
+# Assume that mvmktempdir will always use the same dir.
+timestamp_resolutions="$(dev/ns-timestamp-resolutions "$tmpdir/canary")" \
+ || exit $?
+atime_resolution="$(echo $timestamp_resolutions | WVPASS cut -d' ' -f 1)" \
+ || exit $?
+mtime_resolution="$(echo $timestamp_resolutions | WVPASS cut -d' ' -f 2)" \
+ || exit $?
+WVPASS rm "$tmpdir/canary"
+
+bup()
+{
+ "$TOP/bup" "$@"
+}
+
+hardlink-sets()
+{
+ "$TOP/dev/hardlink-sets" "$@"
+}
+
+id-other-than()
+{
+ "$TOP/dev/id-other-than" "$@"
+}
+
+# Very simple metadata tests -- create a test tree then check that bup
+# meta can reproduce the metadata correctly (according to bup xstat)
+# via create, extract, start-extract, and finish-extract. The current
+# tests are crude, and this does not fully test devices, varying
+# users/groups, acls, attrs, etc.
+
+genstat()
+{
+ (
+ export PATH="$TOP/bin:$PATH" # pick up bup
+ bup version
+ # Skip atime (test elsewhere) to avoid the observer effect.
+ WVPASS find . -print0 | WVPASS sort-z \
+ | WVPASS xargs -0 bup xstat \
+ --mtime-resolution "$mtime_resolution"ns \
+ --exclude-fields ctime,atime,size
+ )
+}
+
+test-src-create-extract()
+{
+ # Test bup meta create/extract for ./src -> ./src-restore.
+ # Also writes to ./src-stat and ./src-restore-stat.
+ (
+ (WVPASS cd src; WVPASS genstat) > src-stat || exit $?
+ WVPASS bup meta --create --recurse --file src.meta src
+ # Test extract.
+ WVPASS force-delete src-restore
+ WVPASS mkdir src-restore
+ WVPASS cd src-restore
+ WVPASS bup meta --extract --file ../src.meta
+ WVPASS test -d src
+ (WVPASS cd src; WVPASS genstat >../../src-restore-stat) || exit $?
+ WVPASS diff -U5 ../src-stat ../src-restore-stat
+ # Test start/finish extract.
+ WVPASS force-delete src
+ WVPASS bup meta --start-extract --file ../src.meta
+ WVPASS test -d src
+ WVPASS bup meta --finish-extract --file ../src.meta
+ (WVPASS cd src; WVPASS genstat >../../src-restore-stat) || exit $?
+ WVPASS diff -U5 ../src-stat ../src-restore-stat
+ )
+}
+
+test-src-save-restore()
+{
+ # Test bup save/restore metadata for ./src -> ./src-restore. Also
+ # writes to BUP_DIR. Note that for now this just tests the
+ # restore below src/, in order to avoid having to worry about
+ # operations that require root (like chown /home).
+ (
+ WVPASS rm -rf "$BUP_DIR"
+ WVPASS bup init
+ WVPASS bup index src
+ WVPASS bup save -t -n src src
+ # Test extract.
+ WVPASS force-delete src-restore
+ WVPASS mkdir src-restore
+ WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
+ WVPASS test -d src-restore/src
+ WVPASS "$TOP/dev/compare-trees" -c src/ src-restore/src/
+ WVPASS rm -rf src.bup
+ )
+}
+
+setup-test-tree()
+{
+ WVPASS "$TOP/dev/sync-tree" "$TOP/test/sampledata/" "$tmpdir/src/"
+
+ # Add some hard links for the general tests.
+ (
+ WVPASS cd "$tmpdir"/src
+ WVPASS touch hardlink-target
+ WVPASS ln hardlink-target hardlink-1
+ WVPASS ln hardlink-target hardlink-2
+ WVPASS ln hardlink-target hardlink-3
+ ) || exit $?
+
+ # Add some trivial files for the index, modify, save tests.
+ (
+ WVPASS cd "$tmpdir"/src
+ WVPASS mkdir volatile
+ WVPASS touch volatile/{1,2,3}
+ ) || exit $?
+
+ # Regression test for metadata sort order. Previously, these two
+ # entries would sort in the wrong order because the metadata
+ # entries were being sorted by mangled name, but the index isn't.
+ WVPASS dd if=/dev/zero of="$tmpdir"/src/foo bs=1k count=33
+ WVPASS touch -t 201111111111 "$tmpdir"/src/foo
+ WVPASS touch -t 201112121111 "$tmpdir"/src/foo-bar
+
+ dev/mksock "$tmpdir"/src/test-socket || true
+}
+
+# Use the test tree to check bup meta.
+WVSTART 'meta --create/--extract'
+(
+ tmpdir="$(WVPASS wvmktempdir)" || exit $?
+ export BUP_DIR="$tmpdir/bup"
+ WVPASS setup-test-tree
+ WVPASS cd "$tmpdir"
+ WVPASS test-src-create-extract
+
+ # Test a top-level file (not dir).
+ WVPASS touch src-file
+ WVPASS bup meta -cf src-file.meta src-file
+ WVPASS mkdir dest
+ WVPASS cd dest
+ WVPASS bup meta -xf ../src-file.meta
+ WVPASS rm -r "$tmpdir"
+) || exit $?
+
+# Use the test tree to check bup save/restore metadata.
+WVSTART 'metadata save/restore (general)'
+(
+ tmpdir="$(WVPASS wvmktempdir)" || exit $?
+ export BUP_DIR="$tmpdir/bup"
+ WVPASS setup-test-tree
+ WVPASS cd "$tmpdir"
+ WVPASS test-src-save-restore
+
+ # Test a deeper subdir/ to make sure top-level non-dir metadata is
+ # restored correctly. We need at least one dir and one non-dir at
+ # the "top-level".
+ WVPASS test -d src/var/cmd
+ WVPASS test -f src/var/cmd/save-cmd.py
+ WVPASS rm -rf "$BUP_DIR"
+ WVPASS bup init
+ WVPASS touch -t 201111111111 src-restore # Make sure the top won't match.
+ WVPASS bup index src
+ WVPASS bup save -t -n src src
+ WVPASS force-delete src-restore
+ WVPASS bup restore -C src-restore "/src/latest$(pwd)/src/var/."
+ WVPASS touch -t 201211111111 src-restore # Make sure the top won't match.
+ # Check that the only difference is the top dir.
+ WVFAIL $TOP/dev/compare-trees -c src/var/ src-restore/ > tmp-compare-trees
+ WVPASSEQ $(cat tmp-compare-trees | wc -l) 1
+ # The number of rsync status characters varies, so accept any
+ # number of trailing dots. For example OS X native rsync produces
+ # 9, but Homebrew's produces 12, while on other platforms, 11 is
+ # common.
+ expected_diff_rx='^\.d\.\.t\.\.\.(\.)+ \./$'
+ if ! grep -qE "$expected_diff_rx" tmp-compare-trees; then
+ echo -n 'tmp-compare-trees: ' 1>&2
+ cat tmp-compare-trees 1>&2
+ fi
+ WVPASS grep -qE "$expected_diff_rx" tmp-compare-trees
+ WVPASS rm -r "$tmpdir"
+) || exit $?
+
+# Test that we pull the index (not filesystem) metadata for any
+# unchanged files whenever we're saving other files in a given
+# directory.
+WVSTART 'metadata save/restore (using index metadata)'
+(
+ tmpdir="$(WVPASS wvmktempdir)" || exit $?
+ export BUP_DIR="$tmpdir/bup"
+ WVPASS setup-test-tree
+ WVPASS cd "$tmpdir"
+
+ # ...for now -- might be a problem with hardlink restores that was
+ # causing noise wrt this test.
+ WVPASS rm -rf src/hardlink*
+
+ # Pause here to keep the filesystem changes far enough away from
+ # the first index run that bup won't cap their index timestamps
+ # (see "bup help index" for more information). Without this
+ # sleep, the compare-trees test below "Bup should *not* pick up
+ # these metadata..." may fail.
+ WVPASS sleep 1
+
+ WVPASS rm -rf "$BUP_DIR"
+ WVPASS bup init
+ WVPASS bup index src
+ WVPASS bup save -t -n src src
+
+ WVPASS force-delete src-restore-1
+ WVPASS mkdir src-restore-1
+ WVPASS bup restore -C src-restore-1 "/src/latest$(pwd)/"
+ WVPASS test -d src-restore-1/src
+ WVPASS "$TOP/dev/compare-trees" -c src/ src-restore-1/src/
+
+ WVPASS echo "blarg" > src/volatile/1
+ WVPASS cp -pP src/volatile/1 src-restore-1/src/volatile/
+ WVPASS bup index src
+
+ # Bup should *not* pick up these metadata changes.
+ WVPASS touch src/volatile/2
+
+ WVPASS bup save -t -n src src
+
+ WVPASS force-delete src-restore-2
+ WVPASS mkdir src-restore-2
+ WVPASS bup restore -C src-restore-2 "/src/latest$(pwd)/"
+ WVPASS test -d src-restore-2/src
+ WVPASS "$TOP/dev/compare-trees" -c src-restore-1/src/ src-restore-2/src/
+
+ WVPASS rm -r "$tmpdir"
+
+) || exit $?
+
+
+setup-hardlink-test()
+{
+ WVPASS rm -rf "$tmpdir/src" "$BUP_DIR"
+ WVPASS bup init
+ WVPASS mkdir "$tmpdir/src"
+}
+
+hardlink-test-run-restore()
+{
+ WVPASS force-delete src-restore
+ WVPASS mkdir src-restore
+ WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
+ WVPASS test -d src-restore/src
+}
+
+# Test hardlinks more carefully.
+WVSTART 'metadata save/restore (hardlinks)'
+(
+ tmpdir="$(WVPASS wvmktempdir)" || exit $?
+ export BUP_DIR="$tmpdir/bup"
+
+ WVPASS setup-hardlink-test
+ WVPASS cd "$tmpdir"
+
+ # Test trivial case - single hardlink.
+ (
+ WVPASS cd src
+ WVPASS touch hardlink-target
+ WVPASS ln hardlink-target hardlink-1
+ ) || exit $?
+ WVPASS bup index src
+ WVPASS bup save -t -n src src
+ WVPASS hardlink-test-run-restore
+ WVPASS "$TOP/dev/compare-trees" -c src/ src-restore/src/
+
+ # Test the case where the hardlink hasn't changed, but the tree
+ # needs to be saved again. i.e. the save-cmd.py "if hashvalid:"
+ # case.
+ (
+ WVPASS cd src
+ WVPASS echo whatever > something-new
+ ) || exit $?
+ WVPASS bup index src
+ WVPASS bup save -t -n src src
+ WVPASS hardlink-test-run-restore
+ WVPASS "$TOP/dev/compare-trees" -c src/ src-restore/src/
+
+ # Test hardlink changes between index runs.
+ #
+ WVPASS setup-hardlink-test
+ WVPASS cd src
+ WVPASS touch hardlink-target-a
+ WVPASS touch hardlink-target-b
+ WVPASS ln hardlink-target-a hardlink-b-1
+ WVPASS ln hardlink-target-a hardlink-a-1
+ WVPASS cd ..
+ WVPASS bup index -vv src
+ WVPASS rm src/hardlink-b-1
+ WVPASS ln src/hardlink-target-b src/hardlink-b-1
+ WVPASS bup index -vv src
+ WVPASS bup save -t -n src src
+ WVPASS hardlink-test-run-restore
+ WVPASS echo ./src/hardlink-a-1 > hardlink-sets.expected
+ WVPASS echo ./src/hardlink-target-a >> hardlink-sets.expected
+ WVPASS echo >> hardlink-sets.expected
+ WVPASS echo ./src/hardlink-b-1 >> hardlink-sets.expected
+ WVPASS echo ./src/hardlink-target-b >> hardlink-sets.expected
+ (WVPASS cd src-restore; WVPASS hardlink-sets .) > hardlink-sets.restored \
+ || exit $?
+ WVPASS diff -u hardlink-sets.expected hardlink-sets.restored
+
+ # Test hardlink changes between index and save -- hardlink set [a
+ # b c d] changes to [a b] [c d]. At least right now bup should
+ # notice and recreate the latter.
+ WVPASS setup-hardlink-test
+ WVPASS cd "$tmpdir"/src
+ WVPASS touch a
+ WVPASS ln a b
+ WVPASS ln a c
+ WVPASS ln a d
+ WVPASS cd ..
+ WVPASS bup index -vv src
+ WVPASS rm src/c src/d
+ WVPASS touch src/c
+ WVPASS ln src/c src/d
+ WVPASS bup save -t -n src src
+ WVPASS hardlink-test-run-restore
+ WVPASS echo ./src/a > hardlink-sets.expected
+ WVPASS echo ./src/b >> hardlink-sets.expected
+ WVPASS echo >> hardlink-sets.expected
+ WVPASS echo ./src/c >> hardlink-sets.expected
+ WVPASS echo ./src/d >> hardlink-sets.expected
+ (WVPASS cd src-restore; WVPASS hardlink-sets .) > hardlink-sets.restored \
+ || exit $?
+ WVPASS diff -u hardlink-sets.expected hardlink-sets.restored
+
+ # Test that we don't link outside restore tree.
+ WVPASS setup-hardlink-test
+ WVPASS cd "$tmpdir"
+ WVPASS mkdir src/a src/b
+ WVPASS touch src/a/1
+ WVPASS ln src/a/1 src/b/1
+ WVPASS bup index -vv src
+ WVPASS bup save -t -n src src
+ WVPASS force-delete src-restore
+ WVPASS mkdir src-restore
+ WVPASS bup restore -C src-restore "/src/latest$(pwd)/src/a/"
+ WVPASS test -e src-restore/1
+ WVPASS echo -n > hardlink-sets.expected
+ (WVPASS cd src-restore; WVPASS hardlink-sets .) > hardlink-sets.restored \
+ || exit $?
+ WVPASS diff -u hardlink-sets.expected hardlink-sets.restored
+
+ # Test that we do link within separate sub-trees.
+ WVPASS setup-hardlink-test
+ WVPASS cd "$tmpdir"
+ WVPASS mkdir src/a src/b
+ WVPASS touch src/a/1
+ WVPASS ln src/a/1 src/b/1
+ WVPASS bup index -vv src/a src/b
+ WVPASS bup save -t -n src src/a src/b
+ WVPASS hardlink-test-run-restore
+ WVPASS echo ./src/a/1 > hardlink-sets.expected
+ WVPASS echo ./src/b/1 >> hardlink-sets.expected
+ (WVPASS cd src-restore; WVPASS hardlink-sets .) > hardlink-sets.restored \
+ || exit $?
+ WVPASS diff -u hardlink-sets.expected hardlink-sets.restored
+
+ WVPASS rm -r "$tmpdir"
+
+) || exit $?
+
+WVSTART 'meta --edit'
+(
+ tmpdir="$(WVPASS wvmktempdir)" || exit $?
+ WVPASS cd "$tmpdir"
+ WVPASS mkdir src
+
+ WVPASS bup meta -cf src.meta src
+
+ WVPASS bup meta --edit --set-uid 0 src.meta | WVPASS bup meta -tvvf - \
+ | WVPASS grep -qE '^uid: 0'
+ WVPASS bup meta --edit --set-uid 1000 src.meta | WVPASS bup meta -tvvf - \
+ | WVPASS grep -qE '^uid: 1000'
+
+ WVPASS bup meta --edit --set-gid 0 src.meta | WVPASS bup meta -tvvf - \
+ | WVPASS grep -qE '^gid: 0'
+ WVPASS bup meta --edit --set-gid 1000 src.meta | WVPASS bup meta -tvvf - \
+ | WVPASS grep -qE '^gid: 1000'
+
+ WVPASS bup meta --edit --set-user foo src.meta | WVPASS bup meta -tvvf - \
+ | WVPASS grep -qE '^user: foo'
+ WVPASS bup meta --edit --set-user bar src.meta | WVPASS bup meta -tvvf - \
+ | WVPASS grep -qE '^user: bar'
+ WVPASS bup meta --edit --unset-user src.meta | WVPASS bup meta -tvvf - \
+ | WVPASS grep -qE '^user:'
+ WVPASS bup meta --edit --set-user bar --unset-user src.meta \
+ | WVPASS bup meta -tvvf - | WVPASS grep -qE '^user:'
+ WVPASS bup meta --edit --unset-user --set-user bar src.meta \
+ | WVPASS bup meta -tvvf - | WVPASS grep -qE '^user: bar'
+
+ WVPASS bup meta --edit --set-group foo src.meta | WVPASS bup meta -tvvf - \
+ | WVPASS grep -qE '^group: foo'
+ WVPASS bup meta --edit --set-group bar src.meta | WVPASS bup meta -tvvf - \
+ | WVPASS grep -qE '^group: bar'
+ WVPASS bup meta --edit --unset-group src.meta | WVPASS bup meta -tvvf - \
+ | WVPASS grep -qE '^group:'
+ WVPASS bup meta --edit --set-group bar --unset-group src.meta \
+ | WVPASS bup meta -tvvf - | WVPASS grep -qE '^group:'
+ WVPASS bup meta --edit --unset-group --set-group bar src.meta \
+ | WVPASS bup meta -tvvf - | grep -qE '^group: bar'
+
+ WVPASS rm -r "$tmpdir"
+
+) || exit $?
+
+WVSTART 'meta --no-recurse'
+(
+ tmpdir="$(WVPASS wvmktempdir)" || exit $?
+ WVPASS cd "$tmpdir"
+ WVPASS mkdir src
+ WVPASS mkdir src/foo
+ WVPASS touch src/foo/{1,2,3}
+ WVPASS bup meta -cf src.meta src
+ WVPASSEQ "$(bup meta -tf src.meta | LC_ALL=C sort)" "src/
+src/foo/
+src/foo/1
+src/foo/2
+src/foo/3"
+ WVPASS bup meta --no-recurse -cf src.meta src
+ WVPASSEQ "$(bup meta -tf src.meta | LC_ALL=C sort)" "src/"
+ WVPASS rm -r "$tmpdir"
+) || exit $?
+
+# Test ownership restoration (when not root or fakeroot).
+(
+ if [ "$root_status" != none ]; then
+ exit 0
+ fi
+
+ tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+ # FIXME: binary groups
+ first_group="$(WVPASS bup-cfg-py -c 'import os,grp; \
+ print(grp.getgrgid(os.getgroups()[0])[0])')" || exit $?
+ last_group="$(bup-cfg-py -c 'import os,grp; \
+ print(grp.getgrgid(os.getgroups()[-1])[0])')" || exit $?
+ last_group_erx="$(escape-erx "$last_group")"
+
+ WVSTART 'metadata (restoration of ownership)'
+ WVPASS cd "$tmpdir"
+ WVPASS touch src
+ # Some systems always assign the parent dir group to new paths
+ # (sgid). Make sure the group is one we're in.
+ WVPASS chgrp -R "$first_group" src
+
+ WVPASS bup meta -cf src.meta src
+
+ WVPASS mkdir dest
+ WVPASS cd dest
+ # Make sure we don't change (or try to change) the user when not root.
+ WVPASS bup meta --edit --set-user root ../src.meta | WVPASS bup meta -x
+ WVPASS bup xstat src | WVPASS grep -qvE '^user: root'
+ WVPASS rm -rf src
+ WVPASS bup meta --edit --unset-user --set-uid 0 ../src.meta \
+ | WVPASS bup meta -x
+ WVPASS bup xstat src | WVPASS grep -qvE '^user: root'
+
+ # Make sure we can restore one of the user's groups.
+ WVPASS rm -rf src
+ WVPASS bup meta --edit --set-group "$last_group" ../src.meta \
+ | WVPASS bup meta -x
+ WVPASS bup xstat src | WVPASS grep -qE "^group: $last_group_erx"
+
+ # Make sure we can restore one of the user's gids.
+ user_gids="$(id -G)" || exit $?
+ last_gid="$(echo ${user_gids/* /})" || exit $?
+ WVPASS rm -rf src
+ WVPASS bup meta --edit --unset-group --set-gid "$last_gid" ../src.meta \
+ | WVPASS bup meta -x
+ WVPASS bup xstat src | WVPASS grep -qE "^gid: $last_gid"
+
+ # Test --numeric-ids (gid).
+ WVPASS rm -rf src
+ current_gidx=$(bup meta -tvvf ../src.meta | grep -ae '^gid:') || exit $?
+ WVPASS bup meta --edit --set-group "$last_group" ../src.meta \
+ | WVPASS bup meta -x --numeric-ids
+ new_gidx=$(bup xstat src | grep -ae '^gid:') || exit $?
+ WVPASSEQ "$current_gidx" "$new_gidx"
+
+ # Test that restoring an unknown user works.
+ unknown_user=$("$TOP"/dev/unknown-owner --user) || exit $?
+ WVPASS rm -rf src
+ current_uidx=$(bup meta -tvvf ../src.meta | grep -ae '^uid:') || exit $?
+ WVPASS bup meta --edit --set-user "$unknown_user" ../src.meta \
+ | WVPASS bup meta -x
+ new_uidx=$(bup xstat src | grep -ae '^uid:') || exit $?
+ WVPASSEQ "$current_uidx" "$new_uidx"
+
+ # Test that restoring an unknown group works.
+ unknown_group=$("$TOP"/dev/unknown-owner --group) || exit $?
+ WVPASS rm -rf src
+ current_gidx=$(bup meta -tvvf ../src.meta | grep -ae '^gid:') || exit $?
+ WVPASS bup meta --edit --set-group "$unknown_group" ../src.meta \
+ | WVPASS bup meta -x
+ new_gidx=$(bup xstat src | grep -ae '^gid:') || exit $?
+ WVPASSEQ "$current_gidx" "$new_gidx"
+
+ WVPASS rm -r "$tmpdir"
+
+) || exit $?
+
+# Test ownership restoration (when root or fakeroot).
+(
+ if [ "$root_status" = none ]; then
+ exit 0
+ fi
+
+ tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+ uid=$(WVPASS id -un) || exit $?
+ gid=$(WVPASS id -gn) || exit $?
+
+ WVSTART 'metadata (restoration of ownership as root)'
+ WVPASS cd "$tmpdir"
+ WVPASS touch src
+ WVPASS chown "$uid:$gid" src # In case the parent dir is sgid, etc.
+ WVPASS bup meta -cf src.meta src
+
+ WVPASS mkdir dest
+ WVPASS chmod 700 dest # so we can't accidentally do something insecure
+ WVPASS cd dest
+
+ other_uinfo="$(id-other-than --user "$uid")" || exit $?
+ other_user="${other_uinfo%%:*}"
+ other_uid="${other_uinfo##*:}"
+
+ other_ginfo="$(id-other-than --group "$gid")" || exit $?
+ other_group="${other_ginfo%%:*}"
+ other_gid="${other_ginfo##*:}"
+
+ # Make sure we can restore a uid (must be in /etc/passwd b/c cygwin).
+ WVPASS bup meta --edit --unset-user --set-uid "$other_uid" ../src.meta \
+ | WVPASS bup meta -x
+ WVPASS bup xstat src | WVPASS grep -qE "^uid: $other_uid"
+
+ # Make sure we can restore a gid (must be in /etc/group b/c cygwin).
+ WVPASS bup meta --edit --unset-group --set-gid "$other_gid" ../src.meta \
+ | WVPASS bup meta -x
+ WVPASS bup xstat src | WVPASS grep -qE "^gid: $other_gid"
+
+ other_uinfo2="$(id-other-than --user "$(id -un)" "$other_user")" || exit $?
+ other_user2="${other_uinfo2%%:*}"
+ other_user2_erx="$(escape-erx "$other_user2")" || exit $?
+ other_uid2="${other_uinfo2##*:}"
+
+ other_ginfo2="$(id-other-than --group "$(id -gn)" "$other_group")" || exit $?
+ other_group2="${other_ginfo2%%:*}"
+ other_group2_erx="$(escape-erx "$other_group2")" || exit $?
+ other_gid2="${other_ginfo2##*:}"
+
+ # Try to restore a user (and see that user trumps uid when uid is not 0).
+ WVPASS bup meta --edit \
+ --set-uid "$other_uid" --set-user "$other_user2" ../src.meta \
+ | WVPASS bup meta -x
+ WVPASS bup xstat src | WVPASS grep -qE "^user: $other_user2_erx"
+
+ # Try to restore a group (and see that group trumps gid when gid is not 0).
+ WVPASS bup meta --edit \
+ --set-gid "$other_gid" --set-group "$other_group2" ../src.meta \
+ | WVPASS bup meta -x
+ WVPASS bup xstat src | WVPASS grep -qE "^group: $other_group2_erx"
+
+ # Test --numeric-ids (uid). Note the name 'root' is not handled
+ # specially, so we use that here as the test user name. We assume
+ # that the root user's uid is never 42.
+ WVPASS rm -rf src
+ WVPASS bup meta --edit --set-user root --set-uid "$other_uid" ../src.meta \
+ | WVPASS bup meta -x --numeric-ids
+ new_uidx=$(bup xstat src | grep -e '^uid:') || exit $?
+ WVPASSEQ "$new_uidx" "uid: $other_uid"
+
+ # Test --numeric-ids (gid). Note the name 'root' is not handled
+ # specially, so we use that here as the test group name. We
+ # assume that the root group's gid is never 42.
+ WVPASS rm -rf src
+ WVPASS bup meta --edit --set-group root --set-gid "$other_gid" ../src.meta \
+ | WVPASS bup meta -x --numeric-ids
+ new_gidx=$(bup xstat src | grep -e '^gid:') || exit $?
+ WVPASSEQ "$new_gidx" "gid: $other_gid"
+
+ # Test that restoring an unknown user works.
+ unknown_user=$("$TOP"/dev/unknown-owner --user) || exit $?
+ WVPASS rm -rf src
+ WVPASS bup meta --edit \
+ --set-uid "$other_uid" --set-user "$unknown_user" ../src.meta \
+ | WVPASS bup meta -x
+ new_uidx=$(bup xstat src | grep -e '^uid:') || exit $?
+ WVPASSEQ "$new_uidx" "uid: $other_uid"
+
+ # Test that restoring an unknown group works.
+ unknown_group=$("$TOP"/dev/unknown-owner --group) || exit $?
+ WVPASS rm -rf src
+ WVPASS bup meta --edit \
+ --set-gid "$other_gid" --set-group "$unknown_group" ../src.meta \
+ | WVPASS bup meta -x
+ new_gidx=$(bup xstat src | grep -e '^gid:') || exit $?
+ WVPASSEQ "$new_gidx" "gid: $other_gid"
+
+ if ! [[ $(uname) =~ CYGWIN ]]; then
+ # For now, skip these on Cygwin because it doesn't allow
+ # restoring an unknown uid/gid.
+
+ # Make sure a uid of 0 trumps a non-root user.
+ WVPASS bup meta --edit --set-user "$other_user2" ../src.meta \
+ | WVPASS bup meta -x
+ WVPASS bup xstat src | WVPASS grep -qvE "^user: $other_user2_erx"
+ WVPASS bup xstat src | WVPASS grep -qE "^uid: 0"
+
+ # Make sure a gid of 0 trumps a non-root group.
+ WVPASS bup meta --edit --set-group "$other_group2" ../src.meta \
+ | WVPASS bup meta -x
+ WVPASS bup xstat src | WVPASS grep -qvE "^group: $other_group2_erx"
+ WVPASS bup xstat src | WVPASS grep -qE "^gid: 0"
+ fi
+
+ WVPASS rm -r "$tmpdir"
+
+) || exit $?
+
+
+# Root-only tests that require an FS with all the trimmings: ACLs,
+# Linux attr, Linux xattr, etc.
+if [ "$root_status" = root ]; then
+ (
+ # Some cleanup handled in universal-cleanup() above.
+ # These tests are only likely to work under Linux for now
+ # (patches welcome).
+ [[ $(uname) =~ Linux ]] || exit 0
+
+ if ! modprobe loop; then
+ echo 'Unable to load loopback module; skipping dependent tests.' 1>&2
+ exit 0
+ fi
+
+ testfs="$(WVPASS wvmkmountpt)" || exit $?
+ testfs_limited="$(WVPASS wvmkmountpt)" || exit $?
+ tmpdir="$(WVPASS wvmktempdir)" || exit $?
+ export BUP_DIR="$tmpdir/bup"
+
+ WVSTART 'meta - general (as root)'
+ WVPASS setup-test-tree
+ WVPASS cd "$tmpdir"
+
+ umount "$testfs"
+ WVPASS dd if=/dev/zero of=testfs.img bs=1M count=32
+ # Make sure we have all the options the chattr test needs
+ # (i.e. create a "normal" ext4 filesystem).
+ WVPASS mke2fs -F -m 0 \
+ -I 256 \
+ -O has_journal,extent,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize \
+ testfs.img
+ WVPASS mount -o loop,acl,user_xattr testfs.img "$testfs"
+ # Hide, so that tests can't create risks.
+ WVPASS chown root:root "$testfs"
+ WVPASS chmod 0700 "$testfs"
+
+ umount "$testfs_limited"
+ WVPASS dd if=/dev/zero of=testfs-limited.img bs=1M count=32
+ WVPASS mkfs -t vfat testfs-limited.img
+ WVPASS mount -o loop,uid=root,gid=root,umask=0077 \
+ testfs-limited.img "$testfs_limited"
+
+ WVPASS cp -pPR src "$testfs"/src
+ (WVPASS cd "$testfs"; WVPASS test-src-create-extract) || exit $?
+
+ WVSTART 'meta - atime (as root)'
+ WVPASS force-delete "$testfs"/src
+ WVPASS mkdir "$testfs"/src
+ (
+ WVPASS mkdir "$testfs"/src/foo
+ WVPASS touch "$testfs"/src/bar
+ WVPASS bup-python -c "from bup import xstat; \
+ x = xstat.timespec_to_nsecs((42, 0));\
+ xstat.utime(b'$testfs/src/foo', (x, x));\
+ xstat.utime(b'$testfs/src/bar', (x, x));"
+ WVPASS cd "$testfs"
+ WVPASS bup meta -v --create --recurse --file src.meta src
+ WVPASS bup meta -tvf src.meta
+ # Test extract.
+ WVPASS force-delete src-restore
+ WVPASS mkdir src-restore
+ WVPASS cd src-restore
+ WVPASS bup meta --extract --file ../src.meta
+ WVPASSEQ "$(bup xstat --include-fields=atime src/foo)" "atime: 42"
+ WVPASSEQ "$(bup xstat --include-fields=atime src/bar)" "atime: 42"
+ # Test start/finish extract.
+ WVPASS force-delete src
+ WVPASS bup meta --start-extract --file ../src.meta
+ WVPASS test -d src
+ WVPASS bup meta --finish-extract --file ../src.meta
+ WVPASSEQ "$(bup xstat --include-fields=atime src/foo)" "atime: 42"
+ WVPASSEQ "$(bup xstat --include-fields=atime src/bar)" "atime: 42"
+ ) || exit $?
+
+ WVSTART 'meta - Linux attr (as root)'
+ WVPASS force-delete "$testfs"/src
+ WVPASS mkdir "$testfs"/src
+ (
+ WVPASS touch "$testfs"/src/foo
+ WVPASS mkdir "$testfs"/src/bar
+ WVPASS chattr +acdeijstuADS "$testfs"/src/foo
+ WVPASS chattr +acdeijstuADST "$testfs"/src/bar
+ (WVPASS cd "$testfs"; WVPASS test-src-create-extract) || exit $?
+ # Test restoration to a limited filesystem (vfat).
+ (
+ WVPASS bup meta --create --recurse --file "$testfs"/src.meta \
+ "$testfs"/src
+ WVPASS force-delete "$testfs_limited"/src-restore
+ WVPASS mkdir "$testfs_limited"/src-restore
+ WVPASS cd "$testfs_limited"/src-restore
+ WVFAIL bup meta --extract --file "$testfs"/src.meta 2>&1 \
+ | WVPASS grep -e '^Linux chattr:' \
+ | WVPASS bup-cfg-py -c \
+ 'import sys; exit(not len(sys.stdin.readlines()) == 3)'
+ ) || exit $?
+ ) || exit $?
+
+ WVSTART 'meta - Linux xattr (as root)'
+ WVPASS force-delete "$testfs"/src
+ WVPASS mkdir "$testfs"/src
+ WVPASS touch "$testfs"/src/foo
+ WVPASS mkdir "$testfs"/src/bar
+ WVPASS attr -s foo -V bar "$testfs"/src/foo
+ WVPASS attr -s foo -V bar "$testfs"/src/bar
+ (WVPASS cd "$testfs"; WVPASS test-src-create-extract) || exit $?
+
+ # Test restoration to a limited filesystem (vfat).
+ (
+ WVPASS bup meta --create --recurse --file "$testfs"/src.meta \
+ "$testfs"/src
+ WVPASS force-delete "$testfs_limited"/src-restore
+ WVPASS mkdir "$testfs_limited"/src-restore
+ WVPASS cd "$testfs_limited"/src-restore
+ WVFAIL bup meta --extract --file "$testfs"/src.meta
+ WVFAIL bup meta --extract --file "$testfs"/src.meta 2>&1 \
+ | WVPASS grep -e "^xattr\.set u\?'" \
+ | WVPASS bup-cfg-py -c \
+ 'import sys; exit(not len(sys.stdin.readlines()) == 2)'
+ ) || exit $?
+
+ WVSTART 'meta - POSIX.1e ACLs (as root)'
+ WVPASS force-delete "$testfs"/src
+ WVPASS mkdir "$testfs"/src
+ WVPASS touch "$testfs"/src/foo
+ WVPASS mkdir "$testfs"/src/bar
+ WVPASS setfacl -m u:root:r "$testfs"/src/foo
+ WVPASS setfacl -m u:root:r "$testfs"/src/bar
+ (WVPASS cd "$testfs"; WVPASS test-src-create-extract) || exit $?
+
+ # Test restoration to a limited filesystem (vfat).
+ (
+ WVPASS bup meta --create --recurse --file "$testfs"/src.meta \
+ "$testfs"/src
+ WVPASS force-delete "$testfs_limited"/src-restore
+ WVPASS mkdir "$testfs_limited"/src-restore
+ WVPASS cd "$testfs_limited"/src-restore
+ WVFAIL bup meta --extract --file "$testfs"/src.meta 2>&1 \
+ | WVPASS grep -e '^POSIX1e ACL applyto:' \
+ | WVPASS bup-cfg-py -c \
+ 'import sys; exit(not len(sys.stdin.readlines()) == 2)'
+ ) || exit $?
+
+ WVPASS umount "$testfs"
+ WVPASS umount "$testfs_limited"
+ WVPASS rm -r "$testfs" "$testfs_limited"
+
+ WVPASS rm -r "$tmpdir"
+
+ ) || exit $?
+fi
+
+WVPASS rm -r "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. wvtest-bup.sh || exit $?
-. dev/lib.sh || exit $?
-
-set -o pipefail
-
-root_status="$(dev/root-status)" || exit $?
-
-TOP="$(WVPASS pwd)" || exit $?
-export PATH="$TOP/test/bin:$PATH"
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-export BUP_DIR="$tmpdir/bup"
-
-# Assume that mvmktempdir will always use the same dir.
-timestamp_resolutions="$(dev/ns-timestamp-resolutions "$tmpdir/canary")" \
- || exit $?
-atime_resolution="$(echo $timestamp_resolutions | WVPASS cut -d' ' -f 1)" \
- || exit $?
-mtime_resolution="$(echo $timestamp_resolutions | WVPASS cut -d' ' -f 2)" \
- || exit $?
-WVPASS rm "$tmpdir/canary"
-
-bup()
-{
- "$TOP/bup" "$@"
-}
-
-hardlink-sets()
-{
- "$TOP/dev/hardlink-sets" "$@"
-}
-
-id-other-than()
-{
- "$TOP/dev/id-other-than" "$@"
-}
-
-# Very simple metadata tests -- create a test tree then check that bup
-# meta can reproduce the metadata correctly (according to bup xstat)
-# via create, extract, start-extract, and finish-extract. The current
-# tests are crude, and this does not fully test devices, varying
-# users/groups, acls, attrs, etc.
-
-genstat()
-{
- (
- export PATH="$TOP/bin:$PATH" # pick up bup
- bup version
- # Skip atime (test elsewhere) to avoid the observer effect.
- WVPASS find . -print0 | WVPASS sort-z \
- | WVPASS xargs -0 bup xstat \
- --mtime-resolution "$mtime_resolution"ns \
- --exclude-fields ctime,atime,size
- )
-}
-
-test-src-create-extract()
-{
- # Test bup meta create/extract for ./src -> ./src-restore.
- # Also writes to ./src-stat and ./src-restore-stat.
- (
- (WVPASS cd src; WVPASS genstat) > src-stat || exit $?
- WVPASS bup meta --create --recurse --file src.meta src
- # Test extract.
- WVPASS force-delete src-restore
- WVPASS mkdir src-restore
- WVPASS cd src-restore
- WVPASS bup meta --extract --file ../src.meta
- WVPASS test -d src
- (WVPASS cd src; WVPASS genstat >../../src-restore-stat) || exit $?
- WVPASS diff -U5 ../src-stat ../src-restore-stat
- # Test start/finish extract.
- WVPASS force-delete src
- WVPASS bup meta --start-extract --file ../src.meta
- WVPASS test -d src
- WVPASS bup meta --finish-extract --file ../src.meta
- (WVPASS cd src; WVPASS genstat >../../src-restore-stat) || exit $?
- WVPASS diff -U5 ../src-stat ../src-restore-stat
- )
-}
-
-test-src-save-restore()
-{
- # Test bup save/restore metadata for ./src -> ./src-restore. Also
- # writes to BUP_DIR. Note that for now this just tests the
- # restore below src/, in order to avoid having to worry about
- # operations that require root (like chown /home).
- (
- WVPASS rm -rf "$BUP_DIR"
- WVPASS bup init
- WVPASS bup index src
- WVPASS bup save -t -n src src
- # Test extract.
- WVPASS force-delete src-restore
- WVPASS mkdir src-restore
- WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
- WVPASS test -d src-restore/src
- WVPASS "$TOP/dev/compare-trees" -c src/ src-restore/src/
- WVPASS rm -rf src.bup
- )
-}
-
-setup-test-tree()
-{
- WVPASS "$TOP/dev/sync-tree" "$TOP/test/sampledata/" "$tmpdir/src/"
-
- # Add some hard links for the general tests.
- (
- WVPASS cd "$tmpdir"/src
- WVPASS touch hardlink-target
- WVPASS ln hardlink-target hardlink-1
- WVPASS ln hardlink-target hardlink-2
- WVPASS ln hardlink-target hardlink-3
- ) || exit $?
-
- # Add some trivial files for the index, modify, save tests.
- (
- WVPASS cd "$tmpdir"/src
- WVPASS mkdir volatile
- WVPASS touch volatile/{1,2,3}
- ) || exit $?
-
- # Regression test for metadata sort order. Previously, these two
- # entries would sort in the wrong order because the metadata
- # entries were being sorted by mangled name, but the index isn't.
- WVPASS dd if=/dev/zero of="$tmpdir"/src/foo bs=1k count=33
- WVPASS touch -t 201111111111 "$tmpdir"/src/foo
- WVPASS touch -t 201112121111 "$tmpdir"/src/foo-bar
-
- dev/mksock "$tmpdir"/src/test-socket || true
-}
-
-# Use the test tree to check bup meta.
-WVSTART 'meta --create/--extract'
-(
- tmpdir="$(WVPASS wvmktempdir)" || exit $?
- export BUP_DIR="$tmpdir/bup"
- WVPASS setup-test-tree
- WVPASS cd "$tmpdir"
- WVPASS test-src-create-extract
-
- # Test a top-level file (not dir).
- WVPASS touch src-file
- WVPASS bup meta -cf src-file.meta src-file
- WVPASS mkdir dest
- WVPASS cd dest
- WVPASS bup meta -xf ../src-file.meta
- WVPASS rm -r "$tmpdir"
-) || exit $?
-
-# Use the test tree to check bup save/restore metadata.
-WVSTART 'metadata save/restore (general)'
-(
- tmpdir="$(WVPASS wvmktempdir)" || exit $?
- export BUP_DIR="$tmpdir/bup"
- WVPASS setup-test-tree
- WVPASS cd "$tmpdir"
- WVPASS test-src-save-restore
-
- # Test a deeper subdir/ to make sure top-level non-dir metadata is
- # restored correctly. We need at least one dir and one non-dir at
- # the "top-level".
- WVPASS test -d src/var/cmd
- WVPASS test -f src/var/cmd/save-cmd.py
- WVPASS rm -rf "$BUP_DIR"
- WVPASS bup init
- WVPASS touch -t 201111111111 src-restore # Make sure the top won't match.
- WVPASS bup index src
- WVPASS bup save -t -n src src
- WVPASS force-delete src-restore
- WVPASS bup restore -C src-restore "/src/latest$(pwd)/src/var/."
- WVPASS touch -t 201211111111 src-restore # Make sure the top won't match.
- # Check that the only difference is the top dir.
- WVFAIL $TOP/dev/compare-trees -c src/var/ src-restore/ > tmp-compare-trees
- WVPASSEQ $(cat tmp-compare-trees | wc -l) 1
- # The number of rsync status characters varies, so accept any
- # number of trailing dots. For example OS X native rsync produces
- # 9, but Homebrew's produces 12, while on other platforms, 11 is
- # common.
- expected_diff_rx='^\.d\.\.t\.\.\.(\.)+ \./$'
- if ! grep -qE "$expected_diff_rx" tmp-compare-trees; then
- echo -n 'tmp-compare-trees: ' 1>&2
- cat tmp-compare-trees 1>&2
- fi
- WVPASS grep -qE "$expected_diff_rx" tmp-compare-trees
- WVPASS rm -r "$tmpdir"
-) || exit $?
-
-# Test that we pull the index (not filesystem) metadata for any
-# unchanged files whenever we're saving other files in a given
-# directory.
-WVSTART 'metadata save/restore (using index metadata)'
-(
- tmpdir="$(WVPASS wvmktempdir)" || exit $?
- export BUP_DIR="$tmpdir/bup"
- WVPASS setup-test-tree
- WVPASS cd "$tmpdir"
-
- # ...for now -- might be a problem with hardlink restores that was
- # causing noise wrt this test.
- WVPASS rm -rf src/hardlink*
-
- # Pause here to keep the filesystem changes far enough away from
- # the first index run that bup won't cap their index timestamps
- # (see "bup help index" for more information). Without this
- # sleep, the compare-trees test below "Bup should *not* pick up
- # these metadata..." may fail.
- WVPASS sleep 1
-
- WVPASS rm -rf "$BUP_DIR"
- WVPASS bup init
- WVPASS bup index src
- WVPASS bup save -t -n src src
-
- WVPASS force-delete src-restore-1
- WVPASS mkdir src-restore-1
- WVPASS bup restore -C src-restore-1 "/src/latest$(pwd)/"
- WVPASS test -d src-restore-1/src
- WVPASS "$TOP/dev/compare-trees" -c src/ src-restore-1/src/
-
- WVPASS echo "blarg" > src/volatile/1
- WVPASS cp -pP src/volatile/1 src-restore-1/src/volatile/
- WVPASS bup index src
-
- # Bup should *not* pick up these metadata changes.
- WVPASS touch src/volatile/2
-
- WVPASS bup save -t -n src src
-
- WVPASS force-delete src-restore-2
- WVPASS mkdir src-restore-2
- WVPASS bup restore -C src-restore-2 "/src/latest$(pwd)/"
- WVPASS test -d src-restore-2/src
- WVPASS "$TOP/dev/compare-trees" -c src-restore-1/src/ src-restore-2/src/
-
- WVPASS rm -r "$tmpdir"
-
-) || exit $?
-
-
-setup-hardlink-test()
-{
- WVPASS rm -rf "$tmpdir/src" "$BUP_DIR"
- WVPASS bup init
- WVPASS mkdir "$tmpdir/src"
-}
-
-hardlink-test-run-restore()
-{
- WVPASS force-delete src-restore
- WVPASS mkdir src-restore
- WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
- WVPASS test -d src-restore/src
-}
-
-# Test hardlinks more carefully.
-WVSTART 'metadata save/restore (hardlinks)'
-(
- tmpdir="$(WVPASS wvmktempdir)" || exit $?
- export BUP_DIR="$tmpdir/bup"
-
- WVPASS setup-hardlink-test
- WVPASS cd "$tmpdir"
-
- # Test trivial case - single hardlink.
- (
- WVPASS cd src
- WVPASS touch hardlink-target
- WVPASS ln hardlink-target hardlink-1
- ) || exit $?
- WVPASS bup index src
- WVPASS bup save -t -n src src
- WVPASS hardlink-test-run-restore
- WVPASS "$TOP/dev/compare-trees" -c src/ src-restore/src/
-
- # Test the case where the hardlink hasn't changed, but the tree
- # needs to be saved again. i.e. the save-cmd.py "if hashvalid:"
- # case.
- (
- WVPASS cd src
- WVPASS echo whatever > something-new
- ) || exit $?
- WVPASS bup index src
- WVPASS bup save -t -n src src
- WVPASS hardlink-test-run-restore
- WVPASS "$TOP/dev/compare-trees" -c src/ src-restore/src/
-
- # Test hardlink changes between index runs.
- #
- WVPASS setup-hardlink-test
- WVPASS cd src
- WVPASS touch hardlink-target-a
- WVPASS touch hardlink-target-b
- WVPASS ln hardlink-target-a hardlink-b-1
- WVPASS ln hardlink-target-a hardlink-a-1
- WVPASS cd ..
- WVPASS bup index -vv src
- WVPASS rm src/hardlink-b-1
- WVPASS ln src/hardlink-target-b src/hardlink-b-1
- WVPASS bup index -vv src
- WVPASS bup save -t -n src src
- WVPASS hardlink-test-run-restore
- WVPASS echo ./src/hardlink-a-1 > hardlink-sets.expected
- WVPASS echo ./src/hardlink-target-a >> hardlink-sets.expected
- WVPASS echo >> hardlink-sets.expected
- WVPASS echo ./src/hardlink-b-1 >> hardlink-sets.expected
- WVPASS echo ./src/hardlink-target-b >> hardlink-sets.expected
- (WVPASS cd src-restore; WVPASS hardlink-sets .) > hardlink-sets.restored \
- || exit $?
- WVPASS diff -u hardlink-sets.expected hardlink-sets.restored
-
- # Test hardlink changes between index and save -- hardlink set [a
- # b c d] changes to [a b] [c d]. At least right now bup should
- # notice and recreate the latter.
- WVPASS setup-hardlink-test
- WVPASS cd "$tmpdir"/src
- WVPASS touch a
- WVPASS ln a b
- WVPASS ln a c
- WVPASS ln a d
- WVPASS cd ..
- WVPASS bup index -vv src
- WVPASS rm src/c src/d
- WVPASS touch src/c
- WVPASS ln src/c src/d
- WVPASS bup save -t -n src src
- WVPASS hardlink-test-run-restore
- WVPASS echo ./src/a > hardlink-sets.expected
- WVPASS echo ./src/b >> hardlink-sets.expected
- WVPASS echo >> hardlink-sets.expected
- WVPASS echo ./src/c >> hardlink-sets.expected
- WVPASS echo ./src/d >> hardlink-sets.expected
- (WVPASS cd src-restore; WVPASS hardlink-sets .) > hardlink-sets.restored \
- || exit $?
- WVPASS diff -u hardlink-sets.expected hardlink-sets.restored
-
- # Test that we don't link outside restore tree.
- WVPASS setup-hardlink-test
- WVPASS cd "$tmpdir"
- WVPASS mkdir src/a src/b
- WVPASS touch src/a/1
- WVPASS ln src/a/1 src/b/1
- WVPASS bup index -vv src
- WVPASS bup save -t -n src src
- WVPASS force-delete src-restore
- WVPASS mkdir src-restore
- WVPASS bup restore -C src-restore "/src/latest$(pwd)/src/a/"
- WVPASS test -e src-restore/1
- WVPASS echo -n > hardlink-sets.expected
- (WVPASS cd src-restore; WVPASS hardlink-sets .) > hardlink-sets.restored \
- || exit $?
- WVPASS diff -u hardlink-sets.expected hardlink-sets.restored
-
- # Test that we do link within separate sub-trees.
- WVPASS setup-hardlink-test
- WVPASS cd "$tmpdir"
- WVPASS mkdir src/a src/b
- WVPASS touch src/a/1
- WVPASS ln src/a/1 src/b/1
- WVPASS bup index -vv src/a src/b
- WVPASS bup save -t -n src src/a src/b
- WVPASS hardlink-test-run-restore
- WVPASS echo ./src/a/1 > hardlink-sets.expected
- WVPASS echo ./src/b/1 >> hardlink-sets.expected
- (WVPASS cd src-restore; WVPASS hardlink-sets .) > hardlink-sets.restored \
- || exit $?
- WVPASS diff -u hardlink-sets.expected hardlink-sets.restored
-
- WVPASS rm -r "$tmpdir"
-
-) || exit $?
-
-WVSTART 'meta --edit'
-(
- tmpdir="$(WVPASS wvmktempdir)" || exit $?
- WVPASS cd "$tmpdir"
- WVPASS mkdir src
-
- WVPASS bup meta -cf src.meta src
-
- WVPASS bup meta --edit --set-uid 0 src.meta | WVPASS bup meta -tvvf - \
- | WVPASS grep -qE '^uid: 0'
- WVPASS bup meta --edit --set-uid 1000 src.meta | WVPASS bup meta -tvvf - \
- | WVPASS grep -qE '^uid: 1000'
-
- WVPASS bup meta --edit --set-gid 0 src.meta | WVPASS bup meta -tvvf - \
- | WVPASS grep -qE '^gid: 0'
- WVPASS bup meta --edit --set-gid 1000 src.meta | WVPASS bup meta -tvvf - \
- | WVPASS grep -qE '^gid: 1000'
-
- WVPASS bup meta --edit --set-user foo src.meta | WVPASS bup meta -tvvf - \
- | WVPASS grep -qE '^user: foo'
- WVPASS bup meta --edit --set-user bar src.meta | WVPASS bup meta -tvvf - \
- | WVPASS grep -qE '^user: bar'
- WVPASS bup meta --edit --unset-user src.meta | WVPASS bup meta -tvvf - \
- | WVPASS grep -qE '^user:'
- WVPASS bup meta --edit --set-user bar --unset-user src.meta \
- | WVPASS bup meta -tvvf - | WVPASS grep -qE '^user:'
- WVPASS bup meta --edit --unset-user --set-user bar src.meta \
- | WVPASS bup meta -tvvf - | WVPASS grep -qE '^user: bar'
-
- WVPASS bup meta --edit --set-group foo src.meta | WVPASS bup meta -tvvf - \
- | WVPASS grep -qE '^group: foo'
- WVPASS bup meta --edit --set-group bar src.meta | WVPASS bup meta -tvvf - \
- | WVPASS grep -qE '^group: bar'
- WVPASS bup meta --edit --unset-group src.meta | WVPASS bup meta -tvvf - \
- | WVPASS grep -qE '^group:'
- WVPASS bup meta --edit --set-group bar --unset-group src.meta \
- | WVPASS bup meta -tvvf - | WVPASS grep -qE '^group:'
- WVPASS bup meta --edit --unset-group --set-group bar src.meta \
- | WVPASS bup meta -tvvf - | grep -qE '^group: bar'
-
- WVPASS rm -r "$tmpdir"
-
-) || exit $?
-
-WVSTART 'meta --no-recurse'
-(
- tmpdir="$(WVPASS wvmktempdir)" || exit $?
- WVPASS cd "$tmpdir"
- WVPASS mkdir src
- WVPASS mkdir src/foo
- WVPASS touch src/foo/{1,2,3}
- WVPASS bup meta -cf src.meta src
- WVPASSEQ "$(bup meta -tf src.meta | LC_ALL=C sort)" "src/
-src/foo/
-src/foo/1
-src/foo/2
-src/foo/3"
- WVPASS bup meta --no-recurse -cf src.meta src
- WVPASSEQ "$(bup meta -tf src.meta | LC_ALL=C sort)" "src/"
- WVPASS rm -r "$tmpdir"
-) || exit $?
-
-# Test ownership restoration (when not root or fakeroot).
-(
- if [ "$root_status" != none ]; then
- exit 0
- fi
-
- tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
- # FIXME: binary groups
- first_group="$(WVPASS bup-cfg-py -c 'import os,grp; \
- print(grp.getgrgid(os.getgroups()[0])[0])')" || exit $?
- last_group="$(bup-cfg-py -c 'import os,grp; \
- print(grp.getgrgid(os.getgroups()[-1])[0])')" || exit $?
- last_group_erx="$(escape-erx "$last_group")"
-
- WVSTART 'metadata (restoration of ownership)'
- WVPASS cd "$tmpdir"
- WVPASS touch src
- # Some systems always assign the parent dir group to new paths
- # (sgid). Make sure the group is one we're in.
- WVPASS chgrp -R "$first_group" src
-
- WVPASS bup meta -cf src.meta src
-
- WVPASS mkdir dest
- WVPASS cd dest
- # Make sure we don't change (or try to change) the user when not root.
- WVPASS bup meta --edit --set-user root ../src.meta | WVPASS bup meta -x
- WVPASS bup xstat src | WVPASS grep -qvE '^user: root'
- WVPASS rm -rf src
- WVPASS bup meta --edit --unset-user --set-uid 0 ../src.meta \
- | WVPASS bup meta -x
- WVPASS bup xstat src | WVPASS grep -qvE '^user: root'
-
- # Make sure we can restore one of the user's groups.
- WVPASS rm -rf src
- WVPASS bup meta --edit --set-group "$last_group" ../src.meta \
- | WVPASS bup meta -x
- WVPASS bup xstat src | WVPASS grep -qE "^group: $last_group_erx"
-
- # Make sure we can restore one of the user's gids.
- user_gids="$(id -G)" || exit $?
- last_gid="$(echo ${user_gids/* /})" || exit $?
- WVPASS rm -rf src
- WVPASS bup meta --edit --unset-group --set-gid "$last_gid" ../src.meta \
- | WVPASS bup meta -x
- WVPASS bup xstat src | WVPASS grep -qE "^gid: $last_gid"
-
- # Test --numeric-ids (gid).
- WVPASS rm -rf src
- current_gidx=$(bup meta -tvvf ../src.meta | grep -ae '^gid:') || exit $?
- WVPASS bup meta --edit --set-group "$last_group" ../src.meta \
- | WVPASS bup meta -x --numeric-ids
- new_gidx=$(bup xstat src | grep -ae '^gid:') || exit $?
- WVPASSEQ "$current_gidx" "$new_gidx"
-
- # Test that restoring an unknown user works.
- unknown_user=$("$TOP"/dev/unknown-owner --user) || exit $?
- WVPASS rm -rf src
- current_uidx=$(bup meta -tvvf ../src.meta | grep -ae '^uid:') || exit $?
- WVPASS bup meta --edit --set-user "$unknown_user" ../src.meta \
- | WVPASS bup meta -x
- new_uidx=$(bup xstat src | grep -ae '^uid:') || exit $?
- WVPASSEQ "$current_uidx" "$new_uidx"
-
- # Test that restoring an unknown group works.
- unknown_group=$("$TOP"/dev/unknown-owner --group) || exit $?
- WVPASS rm -rf src
- current_gidx=$(bup meta -tvvf ../src.meta | grep -ae '^gid:') || exit $?
- WVPASS bup meta --edit --set-group "$unknown_group" ../src.meta \
- | WVPASS bup meta -x
- new_gidx=$(bup xstat src | grep -ae '^gid:') || exit $?
- WVPASSEQ "$current_gidx" "$new_gidx"
-
- WVPASS rm -r "$tmpdir"
-
-) || exit $?
-
-# Test ownership restoration (when root or fakeroot).
-(
- if [ "$root_status" = none ]; then
- exit 0
- fi
-
- tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
- uid=$(WVPASS id -un) || exit $?
- gid=$(WVPASS id -gn) || exit $?
-
- WVSTART 'metadata (restoration of ownership as root)'
- WVPASS cd "$tmpdir"
- WVPASS touch src
- WVPASS chown "$uid:$gid" src # In case the parent dir is sgid, etc.
- WVPASS bup meta -cf src.meta src
-
- WVPASS mkdir dest
- WVPASS chmod 700 dest # so we can't accidentally do something insecure
- WVPASS cd dest
-
- other_uinfo="$(id-other-than --user "$uid")" || exit $?
- other_user="${other_uinfo%%:*}"
- other_uid="${other_uinfo##*:}"
-
- other_ginfo="$(id-other-than --group "$gid")" || exit $?
- other_group="${other_ginfo%%:*}"
- other_gid="${other_ginfo##*:}"
-
- # Make sure we can restore a uid (must be in /etc/passwd b/c cygwin).
- WVPASS bup meta --edit --unset-user --set-uid "$other_uid" ../src.meta \
- | WVPASS bup meta -x
- WVPASS bup xstat src | WVPASS grep -qE "^uid: $other_uid"
-
- # Make sure we can restore a gid (must be in /etc/group b/c cygwin).
- WVPASS bup meta --edit --unset-group --set-gid "$other_gid" ../src.meta \
- | WVPASS bup meta -x
- WVPASS bup xstat src | WVPASS grep -qE "^gid: $other_gid"
-
- other_uinfo2="$(id-other-than --user "$(id -un)" "$other_user")" || exit $?
- other_user2="${other_uinfo2%%:*}"
- other_user2_erx="$(escape-erx "$other_user2")" || exit $?
- other_uid2="${other_uinfo2##*:}"
-
- other_ginfo2="$(id-other-than --group "$(id -gn)" "$other_group")" || exit $?
- other_group2="${other_ginfo2%%:*}"
- other_group2_erx="$(escape-erx "$other_group2")" || exit $?
- other_gid2="${other_ginfo2##*:}"
-
- # Try to restore a user (and see that user trumps uid when uid is not 0).
- WVPASS bup meta --edit \
- --set-uid "$other_uid" --set-user "$other_user2" ../src.meta \
- | WVPASS bup meta -x
- WVPASS bup xstat src | WVPASS grep -qE "^user: $other_user2_erx"
-
- # Try to restore a group (and see that group trumps gid when gid is not 0).
- WVPASS bup meta --edit \
- --set-gid "$other_gid" --set-group "$other_group2" ../src.meta \
- | WVPASS bup meta -x
- WVPASS bup xstat src | WVPASS grep -qE "^group: $other_group2_erx"
-
- # Test --numeric-ids (uid). Note the name 'root' is not handled
- # specially, so we use that here as the test user name. We assume
- # that the root user's uid is never 42.
- WVPASS rm -rf src
- WVPASS bup meta --edit --set-user root --set-uid "$other_uid" ../src.meta \
- | WVPASS bup meta -x --numeric-ids
- new_uidx=$(bup xstat src | grep -e '^uid:') || exit $?
- WVPASSEQ "$new_uidx" "uid: $other_uid"
-
- # Test --numeric-ids (gid). Note the name 'root' is not handled
- # specially, so we use that here as the test group name. We
- # assume that the root group's gid is never 42.
- WVPASS rm -rf src
- WVPASS bup meta --edit --set-group root --set-gid "$other_gid" ../src.meta \
- | WVPASS bup meta -x --numeric-ids
- new_gidx=$(bup xstat src | grep -e '^gid:') || exit $?
- WVPASSEQ "$new_gidx" "gid: $other_gid"
-
- # Test that restoring an unknown user works.
- unknown_user=$("$TOP"/dev/unknown-owner --user) || exit $?
- WVPASS rm -rf src
- WVPASS bup meta --edit \
- --set-uid "$other_uid" --set-user "$unknown_user" ../src.meta \
- | WVPASS bup meta -x
- new_uidx=$(bup xstat src | grep -e '^uid:') || exit $?
- WVPASSEQ "$new_uidx" "uid: $other_uid"
-
- # Test that restoring an unknown group works.
- unknown_group=$("$TOP"/dev/unknown-owner --group) || exit $?
- WVPASS rm -rf src
- WVPASS bup meta --edit \
- --set-gid "$other_gid" --set-group "$unknown_group" ../src.meta \
- | WVPASS bup meta -x
- new_gidx=$(bup xstat src | grep -e '^gid:') || exit $?
- WVPASSEQ "$new_gidx" "gid: $other_gid"
-
- if ! [[ $(uname) =~ CYGWIN ]]; then
- # For now, skip these on Cygwin because it doesn't allow
- # restoring an unknown uid/gid.
-
- # Make sure a uid of 0 trumps a non-root user.
- WVPASS bup meta --edit --set-user "$other_user2" ../src.meta \
- | WVPASS bup meta -x
- WVPASS bup xstat src | WVPASS grep -qvE "^user: $other_user2_erx"
- WVPASS bup xstat src | WVPASS grep -qE "^uid: 0"
-
- # Make sure a gid of 0 trumps a non-root group.
- WVPASS bup meta --edit --set-group "$other_group2" ../src.meta \
- | WVPASS bup meta -x
- WVPASS bup xstat src | WVPASS grep -qvE "^group: $other_group2_erx"
- WVPASS bup xstat src | WVPASS grep -qE "^gid: 0"
- fi
-
- WVPASS rm -r "$tmpdir"
-
-) || exit $?
-
-
-# Root-only tests that require an FS with all the trimmings: ACLs,
-# Linux attr, Linux xattr, etc.
-if [ "$root_status" = root ]; then
- (
- # Some cleanup handled in universal-cleanup() above.
- # These tests are only likely to work under Linux for now
- # (patches welcome).
- [[ $(uname) =~ Linux ]] || exit 0
-
- if ! modprobe loop; then
- echo 'Unable to load loopback module; skipping dependent tests.' 1>&2
- exit 0
- fi
-
- testfs="$(WVPASS wvmkmountpt)" || exit $?
- testfs_limited="$(WVPASS wvmkmountpt)" || exit $?
- tmpdir="$(WVPASS wvmktempdir)" || exit $?
- export BUP_DIR="$tmpdir/bup"
-
- WVSTART 'meta - general (as root)'
- WVPASS setup-test-tree
- WVPASS cd "$tmpdir"
-
- umount "$testfs"
- WVPASS dd if=/dev/zero of=testfs.img bs=1M count=32
- # Make sure we have all the options the chattr test needs
- # (i.e. create a "normal" ext4 filesystem).
- WVPASS mke2fs -F -m 0 \
- -I 256 \
- -O has_journal,extent,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize \
- testfs.img
- WVPASS mount -o loop,acl,user_xattr testfs.img "$testfs"
- # Hide, so that tests can't create risks.
- WVPASS chown root:root "$testfs"
- WVPASS chmod 0700 "$testfs"
-
- umount "$testfs_limited"
- WVPASS dd if=/dev/zero of=testfs-limited.img bs=1M count=32
- WVPASS mkfs -t vfat testfs-limited.img
- WVPASS mount -o loop,uid=root,gid=root,umask=0077 \
- testfs-limited.img "$testfs_limited"
-
- WVPASS cp -pPR src "$testfs"/src
- (WVPASS cd "$testfs"; WVPASS test-src-create-extract) || exit $?
-
- WVSTART 'meta - atime (as root)'
- WVPASS force-delete "$testfs"/src
- WVPASS mkdir "$testfs"/src
- (
- WVPASS mkdir "$testfs"/src/foo
- WVPASS touch "$testfs"/src/bar
- WVPASS bup-python -c "from bup import xstat; \
- x = xstat.timespec_to_nsecs((42, 0));\
- xstat.utime(b'$testfs/src/foo', (x, x));\
- xstat.utime(b'$testfs/src/bar', (x, x));"
- WVPASS cd "$testfs"
- WVPASS bup meta -v --create --recurse --file src.meta src
- WVPASS bup meta -tvf src.meta
- # Test extract.
- WVPASS force-delete src-restore
- WVPASS mkdir src-restore
- WVPASS cd src-restore
- WVPASS bup meta --extract --file ../src.meta
- WVPASSEQ "$(bup xstat --include-fields=atime src/foo)" "atime: 42"
- WVPASSEQ "$(bup xstat --include-fields=atime src/bar)" "atime: 42"
- # Test start/finish extract.
- WVPASS force-delete src
- WVPASS bup meta --start-extract --file ../src.meta
- WVPASS test -d src
- WVPASS bup meta --finish-extract --file ../src.meta
- WVPASSEQ "$(bup xstat --include-fields=atime src/foo)" "atime: 42"
- WVPASSEQ "$(bup xstat --include-fields=atime src/bar)" "atime: 42"
- ) || exit $?
-
- WVSTART 'meta - Linux attr (as root)'
- WVPASS force-delete "$testfs"/src
- WVPASS mkdir "$testfs"/src
- (
- WVPASS touch "$testfs"/src/foo
- WVPASS mkdir "$testfs"/src/bar
- WVPASS chattr +acdeijstuADS "$testfs"/src/foo
- WVPASS chattr +acdeijstuADST "$testfs"/src/bar
- (WVPASS cd "$testfs"; WVPASS test-src-create-extract) || exit $?
- # Test restoration to a limited filesystem (vfat).
- (
- WVPASS bup meta --create --recurse --file "$testfs"/src.meta \
- "$testfs"/src
- WVPASS force-delete "$testfs_limited"/src-restore
- WVPASS mkdir "$testfs_limited"/src-restore
- WVPASS cd "$testfs_limited"/src-restore
- WVFAIL bup meta --extract --file "$testfs"/src.meta 2>&1 \
- | WVPASS grep -e '^Linux chattr:' \
- | WVPASS bup-cfg-py -c \
- 'import sys; exit(not len(sys.stdin.readlines()) == 3)'
- ) || exit $?
- ) || exit $?
-
- WVSTART 'meta - Linux xattr (as root)'
- WVPASS force-delete "$testfs"/src
- WVPASS mkdir "$testfs"/src
- WVPASS touch "$testfs"/src/foo
- WVPASS mkdir "$testfs"/src/bar
- WVPASS attr -s foo -V bar "$testfs"/src/foo
- WVPASS attr -s foo -V bar "$testfs"/src/bar
- (WVPASS cd "$testfs"; WVPASS test-src-create-extract) || exit $?
-
- # Test restoration to a limited filesystem (vfat).
- (
- WVPASS bup meta --create --recurse --file "$testfs"/src.meta \
- "$testfs"/src
- WVPASS force-delete "$testfs_limited"/src-restore
- WVPASS mkdir "$testfs_limited"/src-restore
- WVPASS cd "$testfs_limited"/src-restore
- WVFAIL bup meta --extract --file "$testfs"/src.meta
- WVFAIL bup meta --extract --file "$testfs"/src.meta 2>&1 \
- | WVPASS grep -e "^xattr\.set u\?'" \
- | WVPASS bup-cfg-py -c \
- 'import sys; exit(not len(sys.stdin.readlines()) == 2)'
- ) || exit $?
-
- WVSTART 'meta - POSIX.1e ACLs (as root)'
- WVPASS force-delete "$testfs"/src
- WVPASS mkdir "$testfs"/src
- WVPASS touch "$testfs"/src/foo
- WVPASS mkdir "$testfs"/src/bar
- WVPASS setfacl -m u:root:r "$testfs"/src/foo
- WVPASS setfacl -m u:root:r "$testfs"/src/bar
- (WVPASS cd "$testfs"; WVPASS test-src-create-extract) || exit $?
-
- # Test restoration to a limited filesystem (vfat).
- (
- WVPASS bup meta --create --recurse --file "$testfs"/src.meta \
- "$testfs"/src
- WVPASS force-delete "$testfs_limited"/src-restore
- WVPASS mkdir "$testfs_limited"/src-restore
- WVPASS cd "$testfs_limited"/src-restore
- WVFAIL bup meta --extract --file "$testfs"/src.meta 2>&1 \
- | WVPASS grep -e '^POSIX1e ACL applyto:' \
- | WVPASS bup-cfg-py -c \
- 'import sys; exit(not len(sys.stdin.readlines()) == 2)'
- ) || exit $?
-
- WVPASS umount "$testfs"
- WVPASS umount "$testfs_limited"
- WVPASS rm -r "$testfs" "$testfs_limited"
-
- WVPASS rm -r "$tmpdir"
-
- ) || exit $?
-fi
-
-WVPASS rm -r "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+. ./dev/lib.sh || exit $?
+
+set -o pipefail
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+compare-trees() { "$top/dev/compare-trees" "$@"; }
+
+WVPASS bup init
+WVPASS cd "$tmpdir"
+
+WVSTART "index/save"
+WVPASS mkdir src src/foo
+WVPASS date > src/bar
+WVPASS bup random 1k > src/baz
+WVPASS bup on - index src
+WVPASS bup on - save -ctn src src > get.log
+WVPASSEQ $(WVPASS cat get.log | WVPASS wc -l) 2
+tree_id=$(WVPASS awk 'FNR == 1' get.log) || exit $?
+commit_id=$(WVPASS awk 'FNR == 2' get.log) || exit $?
+WVPASS git ls-tree "$tree_id"
+WVPASS git cat-file commit "$commit_id" | head -n 1 \
+ | WVPASS grep "^tree $tree_id\$"
+
+WVPASS bup restore -C restore "src/latest/$(pwd)/src/."
+WVPASS compare-trees src/ restore/
+WVPASS rm -r restore
+
+WVSTART "split"
+WVPASS bup on - split -ctn baz src/baz > get.log
+tree_id=$(WVPASS awk 'FNR == 1' get.log) || exit $?
+commit_id=$(WVPASS awk 'FNR == 2' get.log) || exit $?
+WVPASS git ls-tree "$tree_id"
+WVPASS git cat-file commit "$commit_id" | head -n 1 \
+ | WVPASS grep "^tree $tree_id\$"
+WVPASS bup join baz > restore-baz
+WVPASS cmp src/baz restore-baz
+
+WVSTART "index-cache"
+# the 'a-zA-Z0-9_' is '\w' from python,
+# the trailing _ is because there's no dir specified
+# and that should thus be empty
+hostname=$(uname -n)
+idxcache=$(echo "$hostname" | sed 's/[^@a-zA-Z0-9_]/_/g')_
+# there should be an index-cache now
+for idx in "$tmpdir"/bup/objects/pack/*.idx ; do
+ cachedidx="$tmpdir/bup/index-cache/$idxcache/$(basename "$idx")"
+ WVPASS cmp "$idx" "$cachedidx"
+done
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-. ./dev/lib.sh || exit $?
-
-set -o pipefail
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-compare-trees() { "$top/dev/compare-trees" "$@"; }
-
-WVPASS bup init
-WVPASS cd "$tmpdir"
-
-WVSTART "index/save"
-WVPASS mkdir src src/foo
-WVPASS date > src/bar
-WVPASS bup random 1k > src/baz
-WVPASS bup on - index src
-WVPASS bup on - save -ctn src src > get.log
-WVPASSEQ $(WVPASS cat get.log | WVPASS wc -l) 2
-tree_id=$(WVPASS awk 'FNR == 1' get.log) || exit $?
-commit_id=$(WVPASS awk 'FNR == 2' get.log) || exit $?
-WVPASS git ls-tree "$tree_id"
-WVPASS git cat-file commit "$commit_id" | head -n 1 \
- | WVPASS grep "^tree $tree_id\$"
-
-WVPASS bup restore -C restore "src/latest/$(pwd)/src/."
-WVPASS compare-trees src/ restore/
-WVPASS rm -r restore
-
-WVSTART "split"
-WVPASS bup on - split -ctn baz src/baz > get.log
-tree_id=$(WVPASS awk 'FNR == 1' get.log) || exit $?
-commit_id=$(WVPASS awk 'FNR == 2' get.log) || exit $?
-WVPASS git ls-tree "$tree_id"
-WVPASS git cat-file commit "$commit_id" | head -n 1 \
- | WVPASS grep "^tree $tree_id\$"
-WVPASS bup join baz > restore-baz
-WVPASS cmp src/baz restore-baz
-
-WVSTART "index-cache"
-# the 'a-zA-Z0-9_' is '\w' from python,
-# the trailing _ is because there's no dir specified
-# and that should thus be empty
-hostname=$(uname -n)
-idxcache=$(echo "$hostname" | sed 's/[^@a-zA-Z0-9_]/_/g')_
-# there should be an index-cache now
-for idx in "$tmpdir"/bup/objects/pack/*.idx ; do
- cachedidx="$tmpdir/bup/index-cache/$idxcache/$(basename "$idx")"
- WVPASS cmp "$idx" "$cachedidx"
-done
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+
+# Test that running save more than once with no other changes produces
+# the exact same tree.
+
+# Note: we can't compare the top-level hash (i.e. the output of "save
+# -t" because that currently pulls the metadata for unindexed parent
+# directories directly from the filesystem, and the relevant atimes
+# may change between runs. So instead we extract the roots of the
+# indexed trees for comparison via dev/subtree-hash.
+
+. ./wvtest-bup.sh || exit $?
+
+set -o pipefail
+
+WVSTART 'all'
+
+top="$(pwd)"
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$BUP_DIR"
+
+bup() { "$top/bup" "$@"; }
+
+WVPASS mkdir -p "$tmpdir/src"
+WVPASS mkdir -p "$tmpdir/src/d"
+WVPASS mkdir -p "$tmpdir/src/d/e"
+WVPASS touch "$tmpdir/src/"{f,b,a,d}
+WVPASS touch "$tmpdir/src/d/z"
+
+WVPASS bup init
+WVPASS bup index -u "$tmpdir/src"
+
+declare -a indexed_top
+IFS=/
+indexed_top="${tmpdir##/}"
+indexed_top=(${indexed_top%%/})
+unset IFS
+
+tree1=$(WVPASS bup save -t "$tmpdir/src") || exit $?
+indexed_tree1="$(WVPASS dev/subtree-hash "$tree1" "${indexed_top[@]}" src)" \
+ || exit $?
+
+result="$(WVPASS cd "$tmpdir/src"; WVPASS bup index -m)" || exit $?
+WVPASSEQ "$result" ""
+
+tree2=$(WVPASS bup save -t "$tmpdir/src") || exit $?
+indexed_tree2="$(WVPASS dev/subtree-hash "$tree2" "${indexed_top[@]}" src)" \
+ || exit $?
+
+WVPASSEQ "$indexed_tree1" "$indexed_tree2"
+
+result="$(WVPASS bup index -s / | WVFAIL grep ^D)" || exit $?
+WVPASSEQ "$result" ""
+
+tree3=$(WVPASS bup save -t /) || exit $?
+indexed_tree3="$(WVPASS dev/subtree-hash "$tree3" "${indexed_top[@]}" src)" || exit $?
+WVPASSEQ "$indexed_tree1" "$indexed_tree3"
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-
-# Test that running save more than once with no other changes produces
-# the exact same tree.
-
-# Note: we can't compare the top-level hash (i.e. the output of "save
-# -t" because that currently pulls the metadata for unindexed parent
-# directories directly from the filesystem, and the relevant atimes
-# may change between runs. So instead we extract the roots of the
-# indexed trees for comparison via dev/subtree-hash.
-
-. ./wvtest-bup.sh || exit $?
-
-set -o pipefail
-
-WVSTART 'all'
-
-top="$(pwd)"
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$BUP_DIR"
-
-bup() { "$top/bup" "$@"; }
-
-WVPASS mkdir -p "$tmpdir/src"
-WVPASS mkdir -p "$tmpdir/src/d"
-WVPASS mkdir -p "$tmpdir/src/d/e"
-WVPASS touch "$tmpdir/src/"{f,b,a,d}
-WVPASS touch "$tmpdir/src/d/z"
-
-WVPASS bup init
-WVPASS bup index -u "$tmpdir/src"
-
-declare -a indexed_top
-IFS=/
-indexed_top="${tmpdir##/}"
-indexed_top=(${indexed_top%%/})
-unset IFS
-
-tree1=$(WVPASS bup save -t "$tmpdir/src") || exit $?
-indexed_tree1="$(WVPASS dev/subtree-hash "$tree1" "${indexed_top[@]}" src)" \
- || exit $?
-
-result="$(WVPASS cd "$tmpdir/src"; WVPASS bup index -m)" || exit $?
-WVPASSEQ "$result" ""
-
-tree2=$(WVPASS bup save -t "$tmpdir/src") || exit $?
-indexed_tree2="$(WVPASS dev/subtree-hash "$tree2" "${indexed_top[@]}" src)" \
- || exit $?
-
-WVPASSEQ "$indexed_tree1" "$indexed_tree2"
-
-result="$(WVPASS bup index -s / | WVFAIL grep ^D)" || exit $?
-WVPASSEQ "$result" ""
-
-tree3=$(WVPASS bup save -t /) || exit $?
-indexed_tree3="$(WVPASS dev/subtree-hash "$tree3" "${indexed_top[@]}" src)" || exit $?
-WVPASSEQ "$indexed_tree1" "$indexed_tree3"
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+. dev/lib.sh || exit $?
+
+set -o pipefail
+
+bup_make=$(< config/config.var/bup-make)
+
+WVPASS git status > /dev/null
+
+if ! git diff-index --quiet HEAD; then
+ WVDIE "uncommitted changes; cannot continue"
+fi
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+bup() { "$top/bup" "$@"; }
+
+WVPASS cd "$tmpdir"
+
+WVPASS git clone "$top" clone
+
+for ver in 11.11 11.11.11; do
+ WVSTART "version $ver"
+ WVPASS cd clone
+ WVPASS git tag "$ver"
+ WVPASS git archive --prefix=bup-"$ver"/ -o "$tmpdir"/bup-"$ver".tgz "$ver"
+ WVPASS cd "$tmpdir"
+ WVPASS tar xzf bup-"$ver".tgz
+ WVPASS cd bup-"$ver"
+ WVPASS "$bup_make"
+ WVPASSEQ "$ver" "$(./bup version)"
+ WVPASS cd "$tmpdir"
+done
+
+WVSTART 'make check in unpacked archive'
+WVPASS cd bup-11.11.11
+if ! "$bup_make" -j5 check > archive-tests.log 2>&1; then
+ cat archive-tests.log 1>&2
+ WVPASS false
+fi
+
+WVPASS cd "$top"
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-. dev/lib.sh || exit $?
-
-set -o pipefail
-
-bup_make=$(< config/config.var/bup-make)
-
-WVPASS git status > /dev/null
-
-if ! git diff-index --quiet HEAD; then
- WVDIE "uncommitted changes; cannot continue"
-fi
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-bup() { "$top/bup" "$@"; }
-
-WVPASS cd "$tmpdir"
-
-WVPASS git clone "$top" clone
-
-for ver in 11.11 11.11.11; do
- WVSTART "version $ver"
- WVPASS cd clone
- WVPASS git tag "$ver"
- WVPASS git archive --prefix=bup-"$ver"/ -o "$tmpdir"/bup-"$ver".tgz "$ver"
- WVPASS cd "$tmpdir"
- WVPASS tar xzf bup-"$ver".tgz
- WVPASS cd bup-"$ver"
- WVPASS "$bup_make"
- WVPASSEQ "$ver" "$(./bup version)"
- WVPASS cd "$tmpdir"
-done
-
-WVSTART 'make check in unpacked archive'
-WVPASS cd bup-11.11.11
-if ! "$bup_make" -j5 check > archive-tests.log 2>&1; then
- cat archive-tests.log 1>&2
- WVPASS false
-fi
-
-WVPASS cd "$top"
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+. dev/lib.sh || exit $?
+
+root_status="$(dev/root-status)" || exit $?
+
+if [ "$root_status" != root ]; then
+ echo 'Not root: skipping restore --map-* tests.'
+ exit 0 # FIXME: add WVSKIP.
+fi
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+export BUP_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+
+uid=$(WVPASS id -u) || exit $?
+user=$(WVPASS id -un) || exit $?
+gid=$(WVPASS id -g) || exit $?
+group=$(WVPASS id -gn) || exit $?
+
+other_uinfo=$(WVPASS dev/id-other-than --user "$user") || exit $?
+other_user="${other_uinfo%%:*}"
+other_uid="${other_uinfo##*:}"
+
+other_ginfo=$(WVPASS dev/id-other-than --group "$group" 0) || exit $?
+other_group="${other_ginfo%%:*}"
+other_gid="${other_ginfo##*:}"
+
+WVPASS bup init
+WVPASS cd "$tmpdir"
+
+WVSTART "restore --map-user/group/uid/gid (control)"
+WVPASS mkdir src
+WVPASS touch src/foo
+# Some systems assign the parent dir group to new paths.
+WVPASS chgrp -R "$group" src
+WVPASS bup index src
+WVPASS bup save -n src src
+WVPASS bup restore -C dest "src/latest/$(pwd)/src/"
+WVPASS bup xstat dest/foo > foo-xstat
+WVPASS grep -qE "^user: $user\$" foo-xstat
+WVPASS grep -qE "^uid: $uid\$" foo-xstat
+WVPASS grep -qE "^group: $group\$" foo-xstat
+WVPASS grep -qE "^gid: $gid\$" foo-xstat
+
+WVSTART "restore --map-user/group/uid/gid (user/group)"
+WVPASS rm -rf dest
+# Have to remap uid/gid too because we're root and 0 would win).
+WVPASS bup restore -C dest \
+ --map-uid "$uid=$other_uid" --map-gid "$gid=$other_gid" \
+ --map-user "$user=$other_user" --map-group "$group=$other_group" \
+ "src/latest/$(pwd)/src/"
+WVPASS bup xstat dest/foo > foo-xstat
+WVPASS grep -qE "^user: $other_user\$" foo-xstat
+WVPASS grep -qE "^uid: $other_uid\$" foo-xstat
+WVPASS grep -qE "^group: $other_group\$" foo-xstat
+WVPASS grep -qE "^gid: $other_gid\$" foo-xstat
+
+WVSTART "restore --map-user/group/uid/gid (user/group trumps uid/gid)"
+WVPASS rm -rf dest
+WVPASS bup restore -C dest \
+ --map-uid "$uid=$other_uid" --map-gid "$gid=$other_gid" \
+ "src/latest/$(pwd)/src/"
+# Should be no changes.
+WVPASS bup xstat dest/foo > foo-xstat
+WVPASS grep -qE "^user: $user\$" foo-xstat
+WVPASS grep -qE "^uid: $uid\$" foo-xstat
+WVPASS grep -qE "^group: $group\$" foo-xstat
+WVPASS grep -qE "^gid: $gid\$" foo-xstat
+
+WVSTART "restore --map-user/group/uid/gid (uid/gid)"
+WVPASS rm -rf dest
+WVPASS bup restore -C dest \
+ --map-user "$user=" --map-group "$group=" \
+ --map-uid "$uid=$other_uid" --map-gid "$gid=$other_gid" \
+ "src/latest/$(pwd)/src/"
+WVPASS bup xstat dest/foo > foo-xstat
+WVPASS grep -qE "^user: $other_user\$" foo-xstat
+WVPASS grep -qE "^uid: $other_uid\$" foo-xstat
+WVPASS grep -qE "^group: $other_group\$" foo-xstat
+WVPASS grep -qE "^gid: $other_gid\$" foo-xstat
+
+has_uid_gid_0=$(WVPASS bup-cfg-py -c "
+import grp, pwd
+try:
+ pwd.getpwuid(0)
+ grp.getgrgid(0)
+ print('yes')
+except KeyError as ex:
+ pass
+") || exit $?
+if [ "$has_uid_gid_0" == yes ]
+then
+ WVSTART "restore --map-user/group/uid/gid (zero uid/gid trumps all)"
+ WVPASS rm -rf dest
+ WVPASS bup restore -C dest \
+ --map-user "$user=$other_user" --map-group "$group=$other_group" \
+ --map-uid "$uid=0" --map-gid "$gid=0" \
+ "src/latest/$(pwd)/src/"
+ WVPASS bup xstat dest/foo > foo-xstat
+ WVPASS grep -qE "^uid: 0\$" foo-xstat
+ WVPASS grep -qE "^gid: 0\$" foo-xstat
+
+ WVPASS rm -rf "$tmpdir"
+fi
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-. dev/lib.sh || exit $?
-
-root_status="$(dev/root-status)" || exit $?
-
-if [ "$root_status" != root ]; then
- echo 'Not root: skipping restore --map-* tests.'
- exit 0 # FIXME: add WVSKIP.
-fi
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-export BUP_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-
-uid=$(WVPASS id -u) || exit $?
-user=$(WVPASS id -un) || exit $?
-gid=$(WVPASS id -g) || exit $?
-group=$(WVPASS id -gn) || exit $?
-
-other_uinfo=$(WVPASS dev/id-other-than --user "$user") || exit $?
-other_user="${other_uinfo%%:*}"
-other_uid="${other_uinfo##*:}"
-
-other_ginfo=$(WVPASS dev/id-other-than --group "$group" 0) || exit $?
-other_group="${other_ginfo%%:*}"
-other_gid="${other_ginfo##*:}"
-
-WVPASS bup init
-WVPASS cd "$tmpdir"
-
-WVSTART "restore --map-user/group/uid/gid (control)"
-WVPASS mkdir src
-WVPASS touch src/foo
-# Some systems assign the parent dir group to new paths.
-WVPASS chgrp -R "$group" src
-WVPASS bup index src
-WVPASS bup save -n src src
-WVPASS bup restore -C dest "src/latest/$(pwd)/src/"
-WVPASS bup xstat dest/foo > foo-xstat
-WVPASS grep -qE "^user: $user\$" foo-xstat
-WVPASS grep -qE "^uid: $uid\$" foo-xstat
-WVPASS grep -qE "^group: $group\$" foo-xstat
-WVPASS grep -qE "^gid: $gid\$" foo-xstat
-
-WVSTART "restore --map-user/group/uid/gid (user/group)"
-WVPASS rm -rf dest
-# Have to remap uid/gid too because we're root and 0 would win).
-WVPASS bup restore -C dest \
- --map-uid "$uid=$other_uid" --map-gid "$gid=$other_gid" \
- --map-user "$user=$other_user" --map-group "$group=$other_group" \
- "src/latest/$(pwd)/src/"
-WVPASS bup xstat dest/foo > foo-xstat
-WVPASS grep -qE "^user: $other_user\$" foo-xstat
-WVPASS grep -qE "^uid: $other_uid\$" foo-xstat
-WVPASS grep -qE "^group: $other_group\$" foo-xstat
-WVPASS grep -qE "^gid: $other_gid\$" foo-xstat
-
-WVSTART "restore --map-user/group/uid/gid (user/group trumps uid/gid)"
-WVPASS rm -rf dest
-WVPASS bup restore -C dest \
- --map-uid "$uid=$other_uid" --map-gid "$gid=$other_gid" \
- "src/latest/$(pwd)/src/"
-# Should be no changes.
-WVPASS bup xstat dest/foo > foo-xstat
-WVPASS grep -qE "^user: $user\$" foo-xstat
-WVPASS grep -qE "^uid: $uid\$" foo-xstat
-WVPASS grep -qE "^group: $group\$" foo-xstat
-WVPASS grep -qE "^gid: $gid\$" foo-xstat
-
-WVSTART "restore --map-user/group/uid/gid (uid/gid)"
-WVPASS rm -rf dest
-WVPASS bup restore -C dest \
- --map-user "$user=" --map-group "$group=" \
- --map-uid "$uid=$other_uid" --map-gid "$gid=$other_gid" \
- "src/latest/$(pwd)/src/"
-WVPASS bup xstat dest/foo > foo-xstat
-WVPASS grep -qE "^user: $other_user\$" foo-xstat
-WVPASS grep -qE "^uid: $other_uid\$" foo-xstat
-WVPASS grep -qE "^group: $other_group\$" foo-xstat
-WVPASS grep -qE "^gid: $other_gid\$" foo-xstat
-
-has_uid_gid_0=$(WVPASS bup-cfg-py -c "
-import grp, pwd
-try:
- pwd.getpwuid(0)
- grp.getgrgid(0)
- print('yes')
-except KeyError as ex:
- pass
-") || exit $?
-if [ "$has_uid_gid_0" == yes ]
-then
- WVSTART "restore --map-user/group/uid/gid (zero uid/gid trumps all)"
- WVPASS rm -rf dest
- WVPASS bup restore -C dest \
- --map-user "$user=$other_user" --map-group "$group=$other_group" \
- --map-uid "$uid=0" --map-gid "$gid=0" \
- "src/latest/$(pwd)/src/"
- WVPASS bup xstat dest/foo > foo-xstat
- WVPASS grep -qE "^uid: 0\$" foo-xstat
- WVPASS grep -qE "^gid: 0\$" foo-xstat
-
- WVPASS rm -rf "$tmpdir"
-fi
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+
+set -o pipefail
+
+WVSTART 'all'
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+export BUP_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+
+WVPASS mkdir "$tmpdir/foo"
+WVPASS mkdir "$tmpdir/foo/bar" # Make sure a dir sorts before baz (regression test).
+WVPASS touch "$tmpdir/foo/baz"
+WVPASS WVPASS bup init
+WVPASS WVPASS bup index "$tmpdir/foo"
+WVPASS bup save -n foo "$tmpdir/foo"
+# Make sure the timestamps will differ if metadata isn't being restored.
+WVPASS bup tick
+WVPASS bup restore -C "$tmpdir/restore" "foo/latest/$tmpdir/foo/baz"
+WVPASS "$top/dev/compare-trees" "$tmpdir/foo/baz" "$tmpdir/restore/baz"
+
+WVPASS rm -rf "$tmpdir"
+
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-
-set -o pipefail
-
-WVSTART 'all'
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-export BUP_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-
-WVPASS mkdir "$tmpdir/foo"
-WVPASS mkdir "$tmpdir/foo/bar" # Make sure a dir sorts before baz (regression test).
-WVPASS touch "$tmpdir/foo/baz"
-WVPASS WVPASS bup init
-WVPASS WVPASS bup index "$tmpdir/foo"
-WVPASS bup save -n foo "$tmpdir/foo"
-# Make sure the timestamps will differ if metadata isn't being restored.
-WVPASS bup tick
-WVPASS bup restore -C "$tmpdir/restore" "foo/latest/$tmpdir/foo/baz"
-WVPASS "$top/dev/compare-trees" "$tmpdir/foo/baz" "$tmpdir/restore/baz"
-
-WVPASS rm -rf "$tmpdir"
-
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+. ./dev/lib.sh || exit $?
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+
+
+bup() { "$top/bup" "$@"; }
+compare-trees() { "$top/dev/compare-trees" "$@"; }
+
+wv_matches_rx()
+{
+ local caller_file=${BASH_SOURCE[0]}
+ local caller_line=${BASH_LINENO[0]}
+ local src="$caller_file:$caller_line"
+ if test $# -ne 2; then
+ echo "! $src wv_matches_rx requires 2 arguments FAILED" 1>&2
+ return
+ fi
+ local str="$1"
+ local rx="$2"
+ echo "Matching:" 1>&2 || exit $?
+ echo "$str" | sed 's/^\(.*\)/ \1/' 1>&2 || exit $?
+ echo "Against:" 1>&2 || exit $?
+ echo "$rx" | sed 's/^\(.*\)/ \1/' 1>&2 || exit $?
+ if [[ "$str" =~ ^${rx}$ ]]; then
+ echo "! $src regex matches ok" 1>&2 || exit $?
+ else
+ echo "! $src regex doesn't match FAILED" 1>&2 || exit $?
+ fi
+}
+
+
+WVPASS bup init
+WVPASS cd "$tmpdir"
+
+
+WVSTART "rm /foo (lone branch)"
+WVPASS mkdir src src/foo
+WVPASS echo twisty-maze > src/1
+WVPASS bup index src
+WVPASS bup save -n src src
+WVPASS "$top"/dev/sync-tree bup/ bup-baseline/
+# FIXME: test -n
+WVPASS bup tick # Make sure we always get the timestamp changes below
+WVPASS bup rm --unsafe /src
+observed="$(compare-trees bup/ bup-baseline/ | LC_ALL=C sort)" || exit $?
+wv_matches_rx "$observed" \
+'\*deleting[ ]+logs/refs/heads/src
+\*deleting[ ]+refs/heads/src(
+\.d\.\.t\.\.\.[.]*[ ]+\./)?
+\.d\.\.t\.\.\.[.]*[ ]+logs/refs/heads/
+\.d\.\.t\.\.\.[.]*[ ]+refs/heads/(
+>f\+\+\+\+\+\+\+\+\+[ ]+packed-refs)?'
+
+
+WVSTART "rm /foo (one of many)"
+WVPASS rm -rf bup
+WVPASS mv bup-baseline bup
+WVPASS echo twisty-maze > src/2
+WVPASS bup index src
+WVPASS bup save -n src-2 src
+WVPASS echo twisty-maze > src/3
+WVPASS bup index src
+WVPASS bup save -n src-3 src
+WVPASS "$top"/dev/sync-tree bup/ bup-baseline/
+WVPASS bup tick # Make sure we always get the timestamp changes below
+WVPASS bup rm --unsafe /src
+observed="$(compare-trees bup/ bup-baseline/ | LC_ALL=C sort)" || exit $?
+wv_matches_rx "$observed" \
+"\*deleting[ ]+logs/refs/heads/src
+\*deleting[ ]+refs/heads/src(
+\.d\.\.t\.\.\.[.]*[ ]+\./)?
+\.d\.\.t\.\.\.[.]*[ ]+logs/refs/heads/
+\.d\.\.t\.\.\.[.]*[ ]+refs/heads/(
+>f\+\+\+\+\+\+\+\+\+[ ]+packed-refs)?"
+
+
+WVSTART "rm /foo /bar (multiple of many)"
+WVPASS rm -rf bup
+WVPASS mv bup-baseline bup
+WVPASS echo twisty-maze > src/4
+WVPASS bup index src
+WVPASS bup save -n src-4 src
+WVPASS echo twisty-maze > src/5
+WVPASS bup index src
+WVPASS bup save -n src-5 src
+WVPASS "$top"/dev/sync-tree bup/ bup-baseline/
+WVPASS bup tick # Make sure we always get the timestamp changes below
+WVPASS bup rm --unsafe /src-2 /src-4
+observed="$(compare-trees bup/ bup-baseline/ | LC_ALL=C sort)" || exit $?
+wv_matches_rx "$observed" \
+"\*deleting[ ]+logs/refs/heads/src-2
+\*deleting[ ]+logs/refs/heads/src-4
+\*deleting[ ]+refs/heads/src-2
+\*deleting[ ]+refs/heads/src-4(
+\.d\.\.t\.\.\.[.]*[ ]+\./)?
+\.d\.\.t\.\.\.[.]*[ ]+logs/refs/heads/
+\.d\.\.t\.\.\.[.]*[ ]+refs/heads/(
+>f\+\+\+\+\+\+\+\+\+[ ]+packed-refs)?"
+
+
+WVSTART "rm /foo /bar (all)"
+WVPASS rm -rf bup
+WVPASS mv bup-baseline bup
+WVPASS "$top"/dev/sync-tree bup/ bup-baseline/
+WVPASS bup tick # Make sure we always get the timestamp changes below
+WVPASS bup rm --unsafe /src /src-2 /src-3 /src-4 /src-5
+observed="$(compare-trees bup/ bup-baseline/ | LC_ALL=C sort)" || exit $?
+wv_matches_rx "$observed" \
+"\*deleting[ ]+logs/refs/heads/src
+\*deleting[ ]+logs/refs/heads/src-2
+\*deleting[ ]+logs/refs/heads/src-3
+\*deleting[ ]+logs/refs/heads/src-4
+\*deleting[ ]+logs/refs/heads/src-5
+\*deleting[ ]+refs/heads/src
+\*deleting[ ]+refs/heads/src-2
+\*deleting[ ]+refs/heads/src-3
+\*deleting[ ]+refs/heads/src-4
+\*deleting[ ]+refs/heads/src-5(
+\.d\.\.t\.\.\.[.]*[ ]+\./)?
+\.d\.\.t\.\.\.[.]*[ ]+logs/refs/heads/
+\.d\.\.t\.\.\.[.]*[ ]+refs/heads/(
+>f\+\+\+\+\+\+\+\+\+[ ]+packed-refs)?"
+
+
+WVSTART "rm /foo/bar (lone save - equivalent to rm /foo)"
+WVPASS rm -rf bup bup-baseline src
+WVPASS bup init
+WVPASS mkdir src
+WVPASS echo twisty-maze > src/1
+WVPASS bup index src
+WVPASS bup save -n src src
+WVPASS bup ls src > tmp-ls
+save1="$(WVPASS head -n 1 tmp-ls)" || exit $?
+WVPASS "$top"/dev/sync-tree bup/ bup-baseline/
+WVPASS bup tick # Make sure we always get the timestamp changes below
+WVFAIL bup rm --unsafe /src/latest
+WVPASS bup rm --unsafe /src/"$save1"
+observed="$(compare-trees bup/ bup-baseline/ | LC_ALL=C sort)" || exit $?
+wv_matches_rx "$observed" \
+"\*deleting[ ]+logs/refs/heads/src
+\*deleting[ ]+refs/heads/src(
+\.d\.\.t\.\.\.[.]*[ ]+\./)?
+\.d\.\.t\.\.\.[.]*[ ]+logs/refs/heads/
+\.d\.\.t\.\.\.[.]*[ ]+refs/heads/(
+>f\+\+\+\+\+\+\+\+\+[ ]+packed-refs)?"
+
+
+verify-changes-caused-by-rewriting-save()
+{
+ local before="$1" after="$2" tmpdir
+ tmpdir="$(WVPASS wvmktempdir)" || exit $?
+ (WVPASS cd "$before" && WVPASS find . | WVPASS sort) \
+ > "$tmpdir/before" || exit $?
+ (WVPASS cd "$after" && WVPASS find . | WVPASS sort) \
+ > "$tmpdir/after" || exit $?
+ local new_paths new_idx new_pack observed
+ new_paths="$(WVPASS comm -13 "$tmpdir/before" "$tmpdir/after")" || exit $?
+ new_idx="$(echo "$new_paths" | WVPASS grep -E '^\./objects/pack/pack-.*\.idx$' | cut -b 3-)" || exit $?
+ new_pack="$(echo "$new_paths" | WVPASS grep -E '^\./objects/pack/pack-.*\.pack$' | cut -b 3-)" || exit $?
+ wv_matches_rx "$(compare-trees "$after/" "$before/")" \
+">fcst\.\.\.[.]*[ ]+logs/refs/heads/src
+\.d\.\.t\.\.\.[.]*[ ]+objects/
+\.d\.\.t\.\.\.[.]*[ ]+objects/pack/
+>fcst\.\.\.[.]*[ ]+objects/pack/bup\.bloom
+>f\+\+\+\+\+\+\+[+]*[ ]+$new_idx
+>f\+\+\+\+\+\+\+[+]*[ ]+$new_pack
+\.d\.\.t\.\.\.[.]*[ ]+refs/heads/
+>fc\.t\.\.\.[.]*[ ]+refs/heads/src"
+ WVPASS rm -rf "$tmpdir"
+}
+
+commit-hash-n()
+{
+ local n="$1" repo="$2" branch="$3"
+ GIT_DIR="$repo" WVPASS git rev-list --reverse "$branch" \
+ | WVPASS awk "FNR == $n"
+}
+
+rm-safe-cinfo()
+{
+ local n="$1" repo="$2" branch="$3" hash
+ hash="$(commit-hash-n "$n" "$repo" "$branch")" || exit $?
+ local fmt='Tree: %T%n'
+ fmt="${fmt}Author: %an <%ae> %ai%n"
+ fmt="${fmt}Committer: %cn <%ce> %ci%n"
+ fmt="${fmt}%n%s%n%b"
+ GIT_DIR="$repo" WVPASS git log -n1 --pretty=format:"$fmt" "$hash"
+}
+
+
+WVSTART 'rm /foo/BAR (setup)'
+WVPASS rm -rf bup bup-baseline src
+WVPASS bup init
+WVPASS mkdir src
+WVPASS echo twisty-maze > src/1
+WVPASS bup index src
+WVPASS bup save -n src src
+WVPASS echo twisty-maze > src/2
+WVPASS bup index src
+WVPASS bup tick
+WVPASS bup save -n src src
+WVPASS echo twisty-maze > src/3
+WVPASS bup index src
+WVPASS bup tick
+WVPASS bup save -n src src
+WVPASS mv bup bup-baseline
+WVPASS bup tick # Make sure we always get the timestamp changes below
+
+
+WVSTART "rm /foo/BAR (first of many)"
+WVPASS "$top"/dev/sync-tree bup-baseline/ bup/
+WVPASS bup ls src > tmp-ls
+victim="$(WVPASS head -n 1 tmp-ls)" || exit $?
+WVPASS bup rm --unsafe /src/"$victim"
+verify-changes-caused-by-rewriting-save bup-baseline bup
+observed=$(WVPASS git rev-list src | WVPASS wc -l) || exit $?
+WVPASSEQ 2 $observed
+WVPASSEQ "$(rm-safe-cinfo 1 bup src)" "$(rm-safe-cinfo 2 bup-baseline src)"
+WVPASSEQ "$(rm-safe-cinfo 2 bup src)" "$(rm-safe-cinfo 3 bup-baseline src)"
+
+
+WVSTART "rm /foo/BAR (one of many)"
+WVPASS "$top"/dev/sync-tree bup-baseline/ bup/
+victim="$(WVPASS bup ls src | tail -n +2 | head -n 1)" || exit $?
+WVPASS bup rm --unsafe /src/"$victim"
+verify-changes-caused-by-rewriting-save bup-baseline bup
+observed=$(git rev-list src | wc -l) || exit $?
+WVPASSEQ 2 $observed
+WVPASSEQ "$(commit-hash-n 1 bup src)" "$(commit-hash-n 1 bup-baseline src)"
+WVPASSEQ "$(rm-safe-cinfo 2 bup src)" "$(rm-safe-cinfo 3 bup-baseline src)"
+
+
+WVSTART "rm /foo/BAR (last of many)"
+WVPASS "$top"/dev/sync-tree bup-baseline/ bup/
+victim="$(WVPASS bup ls src | tail -n 2 | head -n 1)" || exit $?
+WVPASS bup rm --unsafe -vv /src/"$victim"
+observed="$(compare-trees bup/ bup-baseline/ | LC_ALL=C sort)" || exit $?
+wv_matches_rx "$observed" \
+"\.d\.\.t\.\.\.[.]*[ ]+refs/heads/
+>fc\.t\.\.\.[.]*[ ]+refs/heads/src
+>fcst\.\.\.[.]*[ ]+logs/refs/heads/src"
+observed=$(git rev-list src | wc -l) || exit $?
+WVPASSEQ 2 $observed
+WVPASSEQ "$(commit-hash-n 1 bup src)" "$(commit-hash-n 1 bup-baseline src)"
+WVPASSEQ "$(commit-hash-n 2 bup src)" "$(commit-hash-n 2 bup-baseline src)"
+
+
+# FIXME: test that committer changes when rewriting, when appropriate
+
+WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+
+set -o pipefail
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+export BUP_DIR="$tmpdir/bup"
+D="$tmpdir/data"
+
+bup() { "$top/bup" "$@"; }
+
+WVSTART "remove file"
+# Fixed in commit 8585613c1f45f3e20feec00b24fc7e3a948fa23e ("Store
+# metadata in the index....")
+WVPASS mkdir "$D"
+WVPASS bup init
+WVPASS echo "content" > "$D"/foo
+WVPASS echo "content" > "$D"/bar
+WVPASS bup tick
+WVPASS bup index -ux "$D"
+WVPASS bup save -n save-fail-missing "$D"
+WVPASS echo "content" > "$D"/baz
+WVPASS bup tick
+WVPASS bup index -ux "$D"
+WVPASS rm "$D"/foo
+# When "bup tick" is removed above, this may fail (complete with warning),
+# since the ctime/mtime of "foo" might be pushed back:
+WVPASS bup save -n save-fail-missing "$D"
+# when the save-call failed, foo is missing from output, since only
+# then bup notices, that it was removed:
+WVPASSEQ "$(bup ls -A save-fail-missing/latest/$TOP/$D/)" "bar
+baz
+foo"
+# index/save again
+WVPASS bup tick
+WVPASS bup index -ux "$D"
+WVPASS bup save -n save-fail-missing "$D"
+# now foo is gone:
+WVPASSEQ "$(bup ls -A save-fail-missing/latest/$TOP/$D/)" "bar
+baz"
+
+
+# TODO: Test for racecondition between reading a file and reading its metadata?
+
+WVSTART "remove dir"
+WVPASS rm -r "$D"
+WVPASS mkdir "$D"
+WVPASS rm -r "$BUP_DIR"
+WVPASS bup init
+WVPASS mkdir "$D"/foo
+WVPASS mkdir "$D"/bar
+WVPASS bup tick
+WVPASS bup index -ux "$D"
+WVPASS bup save -n save-fail-missing "$D"
+WVPASS touch "$D"/bar
+WVPASS mkdir "$D"/baz
+WVPASS bup tick
+WVPASS bup index -ux "$D"
+WVPASS rmdir "$D"/foo
+# with directories, bup notices that foo is missing, so it fails
+# (complete with delayed error)
+WVFAIL bup save -n save-fail-missing "$D"
+# ...but foo is still saved since it was just fine in the index
+WVPASSEQ "$(bup ls -AF save-fail-missing/latest/$TOP/$D/)" "bar/
+baz/
+foo/"
+# Index again:
+WVPASS bup tick
+WVPASS bup index -ux "$D"
+# no non-zero-exitcode anymore:
+WVPASS bup save -n save-fail-missing "$D"
+# foo is now gone
+WVPASSEQ "$(bup ls -AF save-fail-missing/latest/$TOP/$D/)" "bar/
+baz/"
+
+WVPASS rm -rf "$tmpdir"
+
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-
-set -o pipefail
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-export BUP_DIR="$tmpdir/bup"
-D="$tmpdir/data"
-
-bup() { "$top/bup" "$@"; }
-
-WVSTART "remove file"
-# Fixed in commit 8585613c1f45f3e20feec00b24fc7e3a948fa23e ("Store
-# metadata in the index....")
-WVPASS mkdir "$D"
-WVPASS bup init
-WVPASS echo "content" > "$D"/foo
-WVPASS echo "content" > "$D"/bar
-WVPASS bup tick
-WVPASS bup index -ux "$D"
-WVPASS bup save -n save-fail-missing "$D"
-WVPASS echo "content" > "$D"/baz
-WVPASS bup tick
-WVPASS bup index -ux "$D"
-WVPASS rm "$D"/foo
-# When "bup tick" is removed above, this may fail (complete with warning),
-# since the ctime/mtime of "foo" might be pushed back:
-WVPASS bup save -n save-fail-missing "$D"
-# when the save-call failed, foo is missing from output, since only
-# then bup notices, that it was removed:
-WVPASSEQ "$(bup ls -A save-fail-missing/latest/$TOP/$D/)" "bar
-baz
-foo"
-# index/save again
-WVPASS bup tick
-WVPASS bup index -ux "$D"
-WVPASS bup save -n save-fail-missing "$D"
-# now foo is gone:
-WVPASSEQ "$(bup ls -A save-fail-missing/latest/$TOP/$D/)" "bar
-baz"
-
-
-# TODO: Test for racecondition between reading a file and reading its metadata?
-
-WVSTART "remove dir"
-WVPASS rm -r "$D"
-WVPASS mkdir "$D"
-WVPASS rm -r "$BUP_DIR"
-WVPASS bup init
-WVPASS mkdir "$D"/foo
-WVPASS mkdir "$D"/bar
-WVPASS bup tick
-WVPASS bup index -ux "$D"
-WVPASS bup save -n save-fail-missing "$D"
-WVPASS touch "$D"/bar
-WVPASS mkdir "$D"/baz
-WVPASS bup tick
-WVPASS bup index -ux "$D"
-WVPASS rmdir "$D"/foo
-# with directories, bup notices that foo is missing, so it fails
-# (complete with delayed error)
-WVFAIL bup save -n save-fail-missing "$D"
-# ...but foo is still saved since it was just fine in the index
-WVPASSEQ "$(bup ls -AF save-fail-missing/latest/$TOP/$D/)" "bar/
-baz/
-foo/"
-# Index again:
-WVPASS bup tick
-WVPASS bup index -ux "$D"
-# no non-zero-exitcode anymore:
-WVPASS bup save -n save-fail-missing "$D"
-# foo is now gone
-WVPASSEQ "$(bup ls -AF save-fail-missing/latest/$TOP/$D/)" "bar/
-baz/"
-
-WVPASS rm -rf "$tmpdir"
-
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-. ./dev/lib.sh || exit $?
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$tmpdir/bup"
-
-
-bup() { "$top/bup" "$@"; }
-compare-trees() { "$top/dev/compare-trees" "$@"; }
-
-wv_matches_rx()
-{
- local caller_file=${BASH_SOURCE[0]}
- local caller_line=${BASH_LINENO[0]}
- local src="$caller_file:$caller_line"
- if test $# -ne 2; then
- echo "! $src wv_matches_rx requires 2 arguments FAILED" 1>&2
- return
- fi
- local str="$1"
- local rx="$2"
- echo "Matching:" 1>&2 || exit $?
- echo "$str" | sed 's/^\(.*\)/ \1/' 1>&2 || exit $?
- echo "Against:" 1>&2 || exit $?
- echo "$rx" | sed 's/^\(.*\)/ \1/' 1>&2 || exit $?
- if [[ "$str" =~ ^${rx}$ ]]; then
- echo "! $src regex matches ok" 1>&2 || exit $?
- else
- echo "! $src regex doesn't match FAILED" 1>&2 || exit $?
- fi
-}
-
-
-WVPASS bup init
-WVPASS cd "$tmpdir"
-
-
-WVSTART "rm /foo (lone branch)"
-WVPASS mkdir src src/foo
-WVPASS echo twisty-maze > src/1
-WVPASS bup index src
-WVPASS bup save -n src src
-WVPASS "$top"/dev/sync-tree bup/ bup-baseline/
-# FIXME: test -n
-WVPASS bup tick # Make sure we always get the timestamp changes below
-WVPASS bup rm --unsafe /src
-observed="$(compare-trees bup/ bup-baseline/ | LC_ALL=C sort)" || exit $?
-wv_matches_rx "$observed" \
-'\*deleting[ ]+logs/refs/heads/src
-\*deleting[ ]+refs/heads/src(
-\.d\.\.t\.\.\.[.]*[ ]+\./)?
-\.d\.\.t\.\.\.[.]*[ ]+logs/refs/heads/
-\.d\.\.t\.\.\.[.]*[ ]+refs/heads/(
->f\+\+\+\+\+\+\+\+\+[ ]+packed-refs)?'
-
-
-WVSTART "rm /foo (one of many)"
-WVPASS rm -rf bup
-WVPASS mv bup-baseline bup
-WVPASS echo twisty-maze > src/2
-WVPASS bup index src
-WVPASS bup save -n src-2 src
-WVPASS echo twisty-maze > src/3
-WVPASS bup index src
-WVPASS bup save -n src-3 src
-WVPASS "$top"/dev/sync-tree bup/ bup-baseline/
-WVPASS bup tick # Make sure we always get the timestamp changes below
-WVPASS bup rm --unsafe /src
-observed="$(compare-trees bup/ bup-baseline/ | LC_ALL=C sort)" || exit $?
-wv_matches_rx "$observed" \
-"\*deleting[ ]+logs/refs/heads/src
-\*deleting[ ]+refs/heads/src(
-\.d\.\.t\.\.\.[.]*[ ]+\./)?
-\.d\.\.t\.\.\.[.]*[ ]+logs/refs/heads/
-\.d\.\.t\.\.\.[.]*[ ]+refs/heads/(
->f\+\+\+\+\+\+\+\+\+[ ]+packed-refs)?"
-
-
-WVSTART "rm /foo /bar (multiple of many)"
-WVPASS rm -rf bup
-WVPASS mv bup-baseline bup
-WVPASS echo twisty-maze > src/4
-WVPASS bup index src
-WVPASS bup save -n src-4 src
-WVPASS echo twisty-maze > src/5
-WVPASS bup index src
-WVPASS bup save -n src-5 src
-WVPASS "$top"/dev/sync-tree bup/ bup-baseline/
-WVPASS bup tick # Make sure we always get the timestamp changes below
-WVPASS bup rm --unsafe /src-2 /src-4
-observed="$(compare-trees bup/ bup-baseline/ | LC_ALL=C sort)" || exit $?
-wv_matches_rx "$observed" \
-"\*deleting[ ]+logs/refs/heads/src-2
-\*deleting[ ]+logs/refs/heads/src-4
-\*deleting[ ]+refs/heads/src-2
-\*deleting[ ]+refs/heads/src-4(
-\.d\.\.t\.\.\.[.]*[ ]+\./)?
-\.d\.\.t\.\.\.[.]*[ ]+logs/refs/heads/
-\.d\.\.t\.\.\.[.]*[ ]+refs/heads/(
->f\+\+\+\+\+\+\+\+\+[ ]+packed-refs)?"
-
-
-WVSTART "rm /foo /bar (all)"
-WVPASS rm -rf bup
-WVPASS mv bup-baseline bup
-WVPASS "$top"/dev/sync-tree bup/ bup-baseline/
-WVPASS bup tick # Make sure we always get the timestamp changes below
-WVPASS bup rm --unsafe /src /src-2 /src-3 /src-4 /src-5
-observed="$(compare-trees bup/ bup-baseline/ | LC_ALL=C sort)" || exit $?
-wv_matches_rx "$observed" \
-"\*deleting[ ]+logs/refs/heads/src
-\*deleting[ ]+logs/refs/heads/src-2
-\*deleting[ ]+logs/refs/heads/src-3
-\*deleting[ ]+logs/refs/heads/src-4
-\*deleting[ ]+logs/refs/heads/src-5
-\*deleting[ ]+refs/heads/src
-\*deleting[ ]+refs/heads/src-2
-\*deleting[ ]+refs/heads/src-3
-\*deleting[ ]+refs/heads/src-4
-\*deleting[ ]+refs/heads/src-5(
-\.d\.\.t\.\.\.[.]*[ ]+\./)?
-\.d\.\.t\.\.\.[.]*[ ]+logs/refs/heads/
-\.d\.\.t\.\.\.[.]*[ ]+refs/heads/(
->f\+\+\+\+\+\+\+\+\+[ ]+packed-refs)?"
-
-
-WVSTART "rm /foo/bar (lone save - equivalent to rm /foo)"
-WVPASS rm -rf bup bup-baseline src
-WVPASS bup init
-WVPASS mkdir src
-WVPASS echo twisty-maze > src/1
-WVPASS bup index src
-WVPASS bup save -n src src
-WVPASS bup ls src > tmp-ls
-save1="$(WVPASS head -n 1 tmp-ls)" || exit $?
-WVPASS "$top"/dev/sync-tree bup/ bup-baseline/
-WVPASS bup tick # Make sure we always get the timestamp changes below
-WVFAIL bup rm --unsafe /src/latest
-WVPASS bup rm --unsafe /src/"$save1"
-observed="$(compare-trees bup/ bup-baseline/ | LC_ALL=C sort)" || exit $?
-wv_matches_rx "$observed" \
-"\*deleting[ ]+logs/refs/heads/src
-\*deleting[ ]+refs/heads/src(
-\.d\.\.t\.\.\.[.]*[ ]+\./)?
-\.d\.\.t\.\.\.[.]*[ ]+logs/refs/heads/
-\.d\.\.t\.\.\.[.]*[ ]+refs/heads/(
->f\+\+\+\+\+\+\+\+\+[ ]+packed-refs)?"
-
-
-verify-changes-caused-by-rewriting-save()
-{
- local before="$1" after="$2" tmpdir
- tmpdir="$(WVPASS wvmktempdir)" || exit $?
- (WVPASS cd "$before" && WVPASS find . | WVPASS sort) \
- > "$tmpdir/before" || exit $?
- (WVPASS cd "$after" && WVPASS find . | WVPASS sort) \
- > "$tmpdir/after" || exit $?
- local new_paths new_idx new_pack observed
- new_paths="$(WVPASS comm -13 "$tmpdir/before" "$tmpdir/after")" || exit $?
- new_idx="$(echo "$new_paths" | WVPASS grep -E '^\./objects/pack/pack-.*\.idx$' | cut -b 3-)" || exit $?
- new_pack="$(echo "$new_paths" | WVPASS grep -E '^\./objects/pack/pack-.*\.pack$' | cut -b 3-)" || exit $?
- wv_matches_rx "$(compare-trees "$after/" "$before/")" \
-">fcst\.\.\.[.]*[ ]+logs/refs/heads/src
-\.d\.\.t\.\.\.[.]*[ ]+objects/
-\.d\.\.t\.\.\.[.]*[ ]+objects/pack/
->fcst\.\.\.[.]*[ ]+objects/pack/bup\.bloom
->f\+\+\+\+\+\+\+[+]*[ ]+$new_idx
->f\+\+\+\+\+\+\+[+]*[ ]+$new_pack
-\.d\.\.t\.\.\.[.]*[ ]+refs/heads/
->fc\.t\.\.\.[.]*[ ]+refs/heads/src"
- WVPASS rm -rf "$tmpdir"
-}
-
-commit-hash-n()
-{
- local n="$1" repo="$2" branch="$3"
- GIT_DIR="$repo" WVPASS git rev-list --reverse "$branch" \
- | WVPASS awk "FNR == $n"
-}
-
-rm-safe-cinfo()
-{
- local n="$1" repo="$2" branch="$3" hash
- hash="$(commit-hash-n "$n" "$repo" "$branch")" || exit $?
- local fmt='Tree: %T%n'
- fmt="${fmt}Author: %an <%ae> %ai%n"
- fmt="${fmt}Committer: %cn <%ce> %ci%n"
- fmt="${fmt}%n%s%n%b"
- GIT_DIR="$repo" WVPASS git log -n1 --pretty=format:"$fmt" "$hash"
-}
-
-
-WVSTART 'rm /foo/BAR (setup)'
-WVPASS rm -rf bup bup-baseline src
-WVPASS bup init
-WVPASS mkdir src
-WVPASS echo twisty-maze > src/1
-WVPASS bup index src
-WVPASS bup save -n src src
-WVPASS echo twisty-maze > src/2
-WVPASS bup index src
-WVPASS bup tick
-WVPASS bup save -n src src
-WVPASS echo twisty-maze > src/3
-WVPASS bup index src
-WVPASS bup tick
-WVPASS bup save -n src src
-WVPASS mv bup bup-baseline
-WVPASS bup tick # Make sure we always get the timestamp changes below
-
-
-WVSTART "rm /foo/BAR (first of many)"
-WVPASS "$top"/dev/sync-tree bup-baseline/ bup/
-WVPASS bup ls src > tmp-ls
-victim="$(WVPASS head -n 1 tmp-ls)" || exit $?
-WVPASS bup rm --unsafe /src/"$victim"
-verify-changes-caused-by-rewriting-save bup-baseline bup
-observed=$(WVPASS git rev-list src | WVPASS wc -l) || exit $?
-WVPASSEQ 2 $observed
-WVPASSEQ "$(rm-safe-cinfo 1 bup src)" "$(rm-safe-cinfo 2 bup-baseline src)"
-WVPASSEQ "$(rm-safe-cinfo 2 bup src)" "$(rm-safe-cinfo 3 bup-baseline src)"
-
-
-WVSTART "rm /foo/BAR (one of many)"
-WVPASS "$top"/dev/sync-tree bup-baseline/ bup/
-victim="$(WVPASS bup ls src | tail -n +2 | head -n 1)" || exit $?
-WVPASS bup rm --unsafe /src/"$victim"
-verify-changes-caused-by-rewriting-save bup-baseline bup
-observed=$(git rev-list src | wc -l) || exit $?
-WVPASSEQ 2 $observed
-WVPASSEQ "$(commit-hash-n 1 bup src)" "$(commit-hash-n 1 bup-baseline src)"
-WVPASSEQ "$(rm-safe-cinfo 2 bup src)" "$(rm-safe-cinfo 3 bup-baseline src)"
-
-
-WVSTART "rm /foo/BAR (last of many)"
-WVPASS "$top"/dev/sync-tree bup-baseline/ bup/
-victim="$(WVPASS bup ls src | tail -n 2 | head -n 1)" || exit $?
-WVPASS bup rm --unsafe -vv /src/"$victim"
-observed="$(compare-trees bup/ bup-baseline/ | LC_ALL=C sort)" || exit $?
-wv_matches_rx "$observed" \
-"\.d\.\.t\.\.\.[.]*[ ]+refs/heads/
->fc\.t\.\.\.[.]*[ ]+refs/heads/src
->fcst\.\.\.[.]*[ ]+logs/refs/heads/src"
-observed=$(git rev-list src | wc -l) || exit $?
-WVPASSEQ 2 $observed
-WVPASSEQ "$(commit-hash-n 1 bup src)" "$(commit-hash-n 1 bup-baseline src)"
-WVPASSEQ "$(commit-hash-n 2 bup src)" "$(commit-hash-n 2 bup-baseline src)"
-
-
-# FIXME: test that committer changes when rewriting, when appropriate
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+
+WVSTART 'all'
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$BUP_DIR"
+
+bup() { "$top/bup" "$@"; }
+
+WVPASS mkdir -p "$tmpdir/src"
+WVPASS touch "$tmpdir/src/foo"
+WVPASS bup init
+WVPASS bup index "$tmpdir/src"
+WVPASS bup save -n src "$tmpdir/src"
+WVPASSEQ "$(git fsck --unreachable)" ""
+WVPASS bup save -n src "$tmpdir/src"
+WVPASSEQ "$(git fsck --unreachable)" ""
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-
-WVSTART 'all'
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$BUP_DIR"
-
-bup() { "$top/bup" "$@"; }
-
-WVPASS mkdir -p "$tmpdir/src"
-WVPASS touch "$tmpdir/src/foo"
-WVPASS bup init
-WVPASS bup index "$tmpdir/src"
-WVPASS bup save -n src "$tmpdir/src"
-WVPASSEQ "$(git fsck --unreachable)" ""
-WVPASS bup save -n src "$tmpdir/src"
-WVPASSEQ "$(git fsck --unreachable)" ""
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+. dev/lib.sh || exit $?
+
+set -o pipefail
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+
+WVPASS cd "$tmpdir"
+
+
+WVSTART "index excludes bupdir"
+WVPASS force-delete src "$BUP_DIR"
+WVPASS bup init
+WVPASS mkdir src
+WVPASS touch src/a
+WVPASS bup random 128k >src/b
+WVPASS mkdir src/d src/d/e
+WVPASS bup random 512 >src/f
+WVPASS bup index -ux src
+WVPASS bup save -n exclude-bupdir src
+WVPASSEQ "$(bup ls -AF "exclude-bupdir/latest/$tmpdir/src/")" "a
+b
+d/
+f"
+
+
+WVSTART "index --exclude"
+WVPASS force-delete src "$BUP_DIR"
+WVPASS bup init
+WVPASS mkdir src
+WVPASS touch src/a
+WVPASS bup random 128k >src/b
+WVPASS mkdir src/d src/d/e
+WVPASS bup random 512 >src/f
+WVPASS bup random 512 >src/j
+WVPASS bup index -ux --exclude src/d --exclude src/j src
+WVPASS bup save -n exclude src
+WVPASSEQ "$(bup ls "exclude/latest/$tmpdir/src/")" "a
+b
+f"
+WVPASS mkdir src/g src/h
+WVPASS bup index -ux --exclude src/d --exclude $tmpdir/src/g --exclude src/h \
+ --exclude "$tmpdir/src/j" src
+WVPASS bup save -n exclude src
+WVPASSEQ "$(bup ls "exclude/latest/$tmpdir/src/")" "a
+b
+f"
+
+
+WVSTART "index --exclude-from"
+WVPASS force-delete src "$BUP_DIR"
+WVPASS bup init
+WVPASS mkdir src
+WVPASS echo "src/d
+ $tmpdir/src/g
+src/h
+src/i" > exclude-list
+WVPASS touch src/a
+WVPASS bup random 128k >src/b
+WVPASS mkdir src/d src/d/e
+WVPASS bup random 512 >src/f
+WVPASS mkdir src/g src/h
+WVPASS bup random 128k > src/i
+WVPASS bup index -ux --exclude-from exclude-list src
+WVPASS bup save -n exclude-from src
+WVPASSEQ "$(bup ls "exclude-from/latest/$tmpdir/src/")" "a
+b
+f"
+WVPASS rm exclude-list
+
+
+# bup index --exclude-rx ...
+# ==========================
+
+WVSTART "index --exclude-rx '^/foo' (root anchor)"
+WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
+WVPASS bup init
+WVPASS mkdir src
+WVPASS touch src/a
+WVPASS touch src/b
+WVPASS mkdir src/sub1
+WVPASS mkdir src/sub2
+WVPASS touch src/sub1/a
+WVPASS touch src/sub2/b
+WVPASS bup index -u src --exclude-rx "^$(pwd)/src/sub1/"
+WVPASS bup save --strip -n bupdir src
+WVPASS bup restore -C buprestore.tmp /bupdir/latest/
+actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
+WVPASSEQ "$actual" ".
+./a
+./b
+./sub2
+./sub2/b"
+
+WVSTART "index --exclude-rx '/foo$' (non-dir, tail anchor)"
+WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
+WVPASS bup init
+WVPASS mkdir src
+WVPASS touch src/a
+WVPASS touch src/b
+WVPASS touch src/foo
+WVPASS mkdir src/sub
+WVPASS mkdir src/sub/foo
+WVPASS touch src/sub/foo/a
+WVPASS bup index -u src --exclude-rx '/foo$'
+WVPASS bup save --strip -n bupdir src
+WVPASS bup restore -C buprestore.tmp /bupdir/latest/
+actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
+WVPASSEQ "$actual" ".
+./a
+./b
+./sub
+./sub/foo
+./sub/foo/a"
+
+WVSTART "index --exclude-rx '/foo/$' (dir, tail anchor)"
+WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
+WVPASS bup init
+WVPASS mkdir src
+WVPASS touch src/a
+WVPASS touch src/b
+WVPASS touch src/foo
+WVPASS mkdir src/sub
+WVPASS mkdir src/sub/foo
+WVPASS touch src/sub/foo/a
+WVPASS bup index -u src --exclude-rx '/foo/$'
+WVPASS bup save --strip -n bupdir src
+WVPASS bup restore -C buprestore.tmp /bupdir/latest/
+actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
+WVPASSEQ "$actual" ".
+./a
+./b
+./foo
+./sub"
+
+WVSTART "index --exclude-rx '/foo/.' (dir content)"
+WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
+WVPASS bup init
+WVPASS mkdir src
+WVPASS touch src/a
+WVPASS touch src/b
+WVPASS touch src/foo
+WVPASS mkdir src/sub
+WVPASS mkdir src/sub/foo
+WVPASS touch src/sub/foo/a
+WVPASS bup index -u src --exclude-rx '/foo/.'
+WVPASS bup save --strip -n bupdir src
+WVPASS bup restore -C buprestore.tmp /bupdir/latest/
+actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
+WVPASSEQ "$actual" ".
+./a
+./b
+./foo
+./sub
+./sub/foo"
+
+
+# bup index --exclude-rx-from ...
+# ===============================
+WVSTART "index --exclude-rx-from"
+WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
+WVPASS bup init
+WVPASS mkdir src
+WVPASS touch src/a
+WVPASS touch src/b
+WVPASS mkdir src/sub1
+WVPASS mkdir src/sub2
+WVPASS touch src/sub1/a
+WVPASS touch src/sub2/b
+# exclude-rx-file includes blank lines to check that we ignore them.
+WVPASS echo "^$(pwd)/src/sub1/
+
+" > exclude-rx-file
+WVPASS bup index -u src --exclude-rx-from exclude-rx-file
+WVPASS bup save --strip -n bupdir src
+WVPASS bup restore -C buprestore.tmp /bupdir/latest/
+actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
+WVPASSEQ "$actual" ".
+./a
+./b
+./sub2
+./sub2/b"
+
+
+# bup restore --exclude-rx ...
+# ============================
+
+WVSTART "restore --exclude-rx '^/foo' (root anchor)"
+WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
+WVPASS bup init
+WVPASS mkdir src
+WVPASS touch src/a
+WVPASS touch src/b
+WVPASS mkdir src/sub1
+WVPASS mkdir src/sub2
+WVPASS touch src/sub1/a
+WVPASS touch src/sub2/b
+WVPASS bup index -u src
+WVPASS bup save --strip -n bupdir src
+WVPASS bup restore -C buprestore.tmp --exclude-rx "^/sub1/" /bupdir/latest/
+actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
+WVPASSEQ "$actual" ".
+./a
+./b
+./sub2
+./sub2/b"
+
+WVSTART "restore --exclude-rx '/foo$' (non-dir, tail anchor)"
+WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
+WVPASS bup init
+WVPASS mkdir src
+WVPASS touch src/a
+WVPASS touch src/b
+WVPASS touch src/foo
+WVPASS mkdir src/sub
+WVPASS mkdir src/sub/foo
+WVPASS touch src/sub/foo/a
+WVPASS bup index -u src
+WVPASS bup save --strip -n bupdir src
+WVPASS bup restore -C buprestore.tmp --exclude-rx '/foo$' /bupdir/latest/
+actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
+WVPASSEQ "$actual" ".
+./a
+./b
+./sub
+./sub/foo
+./sub/foo/a"
+
+WVSTART "restore --exclude-rx '/foo/$' (dir, tail anchor)"
+WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
+WVPASS bup init
+WVPASS mkdir src
+WVPASS touch src/a
+WVPASS touch src/b
+WVPASS touch src/foo
+WVPASS mkdir src/sub
+WVPASS mkdir src/sub/foo
+WVPASS touch src/sub/foo/a
+WVPASS bup index -u src
+WVPASS bup save --strip -n bupdir src
+WVPASS bup restore -C buprestore.tmp --exclude-rx '/foo/$' /bupdir/latest/
+actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
+WVPASSEQ "$actual" ".
+./a
+./b
+./foo
+./sub"
+
+WVSTART "restore --exclude-rx '/foo/.' (dir content)"
+WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
+WVPASS bup init
+WVPASS mkdir src
+WVPASS touch src/a
+WVPASS touch src/b
+WVPASS touch src/foo
+WVPASS mkdir src/sub
+WVPASS mkdir src/sub/foo
+WVPASS touch src/sub/foo/a
+WVPASS bup index -u src
+WVPASS bup save --strip -n bupdir src
+WVPASS bup restore -C buprestore.tmp --exclude-rx '/foo/.' /bupdir/latest/
+actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
+WVPASSEQ "$actual" ".
+./a
+./b
+./foo
+./sub
+./sub/foo"
+
+
+# bup restore --exclude-rx-from ...
+# =================================
+
+WVSTART "restore --exclude-rx-from"
+WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
+WVPASS bup init
+WVPASS mkdir src
+WVPASS touch src/a
+WVPASS touch src/b
+WVPASS mkdir src/sub1
+WVPASS mkdir src/sub2
+WVPASS touch src/sub1/a
+WVPASS touch src/sub2/b
+WVPASS bup index -u src
+WVPASS bup save --strip -n bupdir src
+WVPASS echo "^/sub1/" > exclude-rx-file
+WVPASS bup restore -C buprestore.tmp \
+ --exclude-rx-from exclude-rx-file /bupdir/latest/
+actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
+WVPASSEQ "$actual" ".
+./a
+./b
+./sub2
+./sub2/b"
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-. dev/lib.sh || exit $?
-
-set -o pipefail
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-
-WVPASS cd "$tmpdir"
-
-
-WVSTART "index excludes bupdir"
-WVPASS force-delete src "$BUP_DIR"
-WVPASS bup init
-WVPASS mkdir src
-WVPASS touch src/a
-WVPASS bup random 128k >src/b
-WVPASS mkdir src/d src/d/e
-WVPASS bup random 512 >src/f
-WVPASS bup index -ux src
-WVPASS bup save -n exclude-bupdir src
-WVPASSEQ "$(bup ls -AF "exclude-bupdir/latest/$tmpdir/src/")" "a
-b
-d/
-f"
-
-
-WVSTART "index --exclude"
-WVPASS force-delete src "$BUP_DIR"
-WVPASS bup init
-WVPASS mkdir src
-WVPASS touch src/a
-WVPASS bup random 128k >src/b
-WVPASS mkdir src/d src/d/e
-WVPASS bup random 512 >src/f
-WVPASS bup random 512 >src/j
-WVPASS bup index -ux --exclude src/d --exclude src/j src
-WVPASS bup save -n exclude src
-WVPASSEQ "$(bup ls "exclude/latest/$tmpdir/src/")" "a
-b
-f"
-WVPASS mkdir src/g src/h
-WVPASS bup index -ux --exclude src/d --exclude $tmpdir/src/g --exclude src/h \
- --exclude "$tmpdir/src/j" src
-WVPASS bup save -n exclude src
-WVPASSEQ "$(bup ls "exclude/latest/$tmpdir/src/")" "a
-b
-f"
-
-
-WVSTART "index --exclude-from"
-WVPASS force-delete src "$BUP_DIR"
-WVPASS bup init
-WVPASS mkdir src
-WVPASS echo "src/d
- $tmpdir/src/g
-src/h
-src/i" > exclude-list
-WVPASS touch src/a
-WVPASS bup random 128k >src/b
-WVPASS mkdir src/d src/d/e
-WVPASS bup random 512 >src/f
-WVPASS mkdir src/g src/h
-WVPASS bup random 128k > src/i
-WVPASS bup index -ux --exclude-from exclude-list src
-WVPASS bup save -n exclude-from src
-WVPASSEQ "$(bup ls "exclude-from/latest/$tmpdir/src/")" "a
-b
-f"
-WVPASS rm exclude-list
-
-
-# bup index --exclude-rx ...
-# ==========================
-
-WVSTART "index --exclude-rx '^/foo' (root anchor)"
-WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
-WVPASS bup init
-WVPASS mkdir src
-WVPASS touch src/a
-WVPASS touch src/b
-WVPASS mkdir src/sub1
-WVPASS mkdir src/sub2
-WVPASS touch src/sub1/a
-WVPASS touch src/sub2/b
-WVPASS bup index -u src --exclude-rx "^$(pwd)/src/sub1/"
-WVPASS bup save --strip -n bupdir src
-WVPASS bup restore -C buprestore.tmp /bupdir/latest/
-actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
-WVPASSEQ "$actual" ".
-./a
-./b
-./sub2
-./sub2/b"
-
-WVSTART "index --exclude-rx '/foo$' (non-dir, tail anchor)"
-WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
-WVPASS bup init
-WVPASS mkdir src
-WVPASS touch src/a
-WVPASS touch src/b
-WVPASS touch src/foo
-WVPASS mkdir src/sub
-WVPASS mkdir src/sub/foo
-WVPASS touch src/sub/foo/a
-WVPASS bup index -u src --exclude-rx '/foo$'
-WVPASS bup save --strip -n bupdir src
-WVPASS bup restore -C buprestore.tmp /bupdir/latest/
-actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
-WVPASSEQ "$actual" ".
-./a
-./b
-./sub
-./sub/foo
-./sub/foo/a"
-
-WVSTART "index --exclude-rx '/foo/$' (dir, tail anchor)"
-WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
-WVPASS bup init
-WVPASS mkdir src
-WVPASS touch src/a
-WVPASS touch src/b
-WVPASS touch src/foo
-WVPASS mkdir src/sub
-WVPASS mkdir src/sub/foo
-WVPASS touch src/sub/foo/a
-WVPASS bup index -u src --exclude-rx '/foo/$'
-WVPASS bup save --strip -n bupdir src
-WVPASS bup restore -C buprestore.tmp /bupdir/latest/
-actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
-WVPASSEQ "$actual" ".
-./a
-./b
-./foo
-./sub"
-
-WVSTART "index --exclude-rx '/foo/.' (dir content)"
-WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
-WVPASS bup init
-WVPASS mkdir src
-WVPASS touch src/a
-WVPASS touch src/b
-WVPASS touch src/foo
-WVPASS mkdir src/sub
-WVPASS mkdir src/sub/foo
-WVPASS touch src/sub/foo/a
-WVPASS bup index -u src --exclude-rx '/foo/.'
-WVPASS bup save --strip -n bupdir src
-WVPASS bup restore -C buprestore.tmp /bupdir/latest/
-actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
-WVPASSEQ "$actual" ".
-./a
-./b
-./foo
-./sub
-./sub/foo"
-
-
-# bup index --exclude-rx-from ...
-# ===============================
-WVSTART "index --exclude-rx-from"
-WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
-WVPASS bup init
-WVPASS mkdir src
-WVPASS touch src/a
-WVPASS touch src/b
-WVPASS mkdir src/sub1
-WVPASS mkdir src/sub2
-WVPASS touch src/sub1/a
-WVPASS touch src/sub2/b
-# exclude-rx-file includes blank lines to check that we ignore them.
-WVPASS echo "^$(pwd)/src/sub1/
-
-" > exclude-rx-file
-WVPASS bup index -u src --exclude-rx-from exclude-rx-file
-WVPASS bup save --strip -n bupdir src
-WVPASS bup restore -C buprestore.tmp /bupdir/latest/
-actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
-WVPASSEQ "$actual" ".
-./a
-./b
-./sub2
-./sub2/b"
-
-
-# bup restore --exclude-rx ...
-# ============================
-
-WVSTART "restore --exclude-rx '^/foo' (root anchor)"
-WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
-WVPASS bup init
-WVPASS mkdir src
-WVPASS touch src/a
-WVPASS touch src/b
-WVPASS mkdir src/sub1
-WVPASS mkdir src/sub2
-WVPASS touch src/sub1/a
-WVPASS touch src/sub2/b
-WVPASS bup index -u src
-WVPASS bup save --strip -n bupdir src
-WVPASS bup restore -C buprestore.tmp --exclude-rx "^/sub1/" /bupdir/latest/
-actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
-WVPASSEQ "$actual" ".
-./a
-./b
-./sub2
-./sub2/b"
-
-WVSTART "restore --exclude-rx '/foo$' (non-dir, tail anchor)"
-WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
-WVPASS bup init
-WVPASS mkdir src
-WVPASS touch src/a
-WVPASS touch src/b
-WVPASS touch src/foo
-WVPASS mkdir src/sub
-WVPASS mkdir src/sub/foo
-WVPASS touch src/sub/foo/a
-WVPASS bup index -u src
-WVPASS bup save --strip -n bupdir src
-WVPASS bup restore -C buprestore.tmp --exclude-rx '/foo$' /bupdir/latest/
-actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
-WVPASSEQ "$actual" ".
-./a
-./b
-./sub
-./sub/foo
-./sub/foo/a"
-
-WVSTART "restore --exclude-rx '/foo/$' (dir, tail anchor)"
-WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
-WVPASS bup init
-WVPASS mkdir src
-WVPASS touch src/a
-WVPASS touch src/b
-WVPASS touch src/foo
-WVPASS mkdir src/sub
-WVPASS mkdir src/sub/foo
-WVPASS touch src/sub/foo/a
-WVPASS bup index -u src
-WVPASS bup save --strip -n bupdir src
-WVPASS bup restore -C buprestore.tmp --exclude-rx '/foo/$' /bupdir/latest/
-actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
-WVPASSEQ "$actual" ".
-./a
-./b
-./foo
-./sub"
-
-WVSTART "restore --exclude-rx '/foo/.' (dir content)"
-WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
-WVPASS bup init
-WVPASS mkdir src
-WVPASS touch src/a
-WVPASS touch src/b
-WVPASS touch src/foo
-WVPASS mkdir src/sub
-WVPASS mkdir src/sub/foo
-WVPASS touch src/sub/foo/a
-WVPASS bup index -u src
-WVPASS bup save --strip -n bupdir src
-WVPASS bup restore -C buprestore.tmp --exclude-rx '/foo/.' /bupdir/latest/
-actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
-WVPASSEQ "$actual" ".
-./a
-./b
-./foo
-./sub
-./sub/foo"
-
-
-# bup restore --exclude-rx-from ...
-# =================================
-
-WVSTART "restore --exclude-rx-from"
-WVPASS rm -rf src "$BUP_DIR" buprestore.tmp
-WVPASS bup init
-WVPASS mkdir src
-WVPASS touch src/a
-WVPASS touch src/b
-WVPASS mkdir src/sub1
-WVPASS mkdir src/sub2
-WVPASS touch src/sub1/a
-WVPASS touch src/sub2/b
-WVPASS bup index -u src
-WVPASS bup save --strip -n bupdir src
-WVPASS echo "^/sub1/" > exclude-rx-file
-WVPASS bup restore -C buprestore.tmp \
- --exclude-rx-from exclude-rx-file /bupdir/latest/
-actual="$(WVPASS cd buprestore.tmp; WVPASS find . | WVPASS sort)" || exit $?
-WVPASSEQ "$actual" ".
-./a
-./b
-./sub2
-./sub2/b"
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+. dev/lib.sh || exit $?
+
+set -o pipefail
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+compare-trees() { "$top/dev/compare-trees" "$@"; }
+
+WVPASS cd "$tmpdir"
+
+
+WVSTART "save --strip"
+WVPASS force-delete "$BUP_DIR" src restore
+WVPASS bup init
+WVPASS mkdir -p src/x/y/z
+WVPASS bup random 8k > src/x/y/random-1
+WVPASS bup random 8k > src/x/y/z/random-2
+WVPASS bup index -u src
+WVPASS bup save --strip -n foo src/x/y
+WVPASS bup restore -C restore /foo/latest
+WVPASS compare-trees src/x/y/ restore/latest/
+
+
+WVSTART "save --strip-path (relative)"
+WVPASS force-delete "$BUP_DIR" src restore
+WVPASS bup init
+WVPASS mkdir -p src/x/y/z
+WVPASS bup random 8k > src/x/y/random-1
+WVPASS bup random 8k > src/x/y/z/random-2
+WVPASS bup index -u src
+WVPASS bup save --strip-path src -n foo src/x
+WVPASS bup restore -C restore /foo/latest
+WVPASS compare-trees src/ restore/latest/
+
+
+WVSTART "save --strip-path (absolute)"
+WVPASS force-delete "$BUP_DIR" src restore
+WVPASS bup init
+WVPASS mkdir -p src/x/y/z
+WVPASS bup random 8k > src/x/y/random-1
+WVPASS bup random 8k > src/x/y/z/random-2
+WVPASS bup index -u src
+WVPASS bup save --strip-path "$tmpdir" -n foo src
+WVPASS bup restore -C restore /foo/latest
+WVPASS compare-trees src/ "restore/latest/src/"
+
+
+WVSTART "save --strip-path (no match)"
+if test $(WVPASS path-filesystems . | WVPASS sort -u | WVPASS wc -l) -ne 1
+then
+ # Skip the test because the attempt to restore parent dirs to the
+ # current filesystem may fail -- i.e. running from
+ # /foo/ext4/bar/btrfs will fail when bup tries to restore linux
+ # attrs above btrfs to the restore tree *inside* btrfs.
+ # FIXME: add WVSKIP
+ echo "(running from tree with mixed filesystems; skipping test)" 1>&2
+ exit 0
+else
+ WVPASS force-delete "$BUP_DIR" src restore
+ WVPASS bup init
+ WVPASS mkdir -p src/x/y/z
+ WVPASS bup random 8k > src/x/y/random-1
+ WVPASS bup random 8k > src/x/y/z/random-2
+ WVPASS bup index -u src
+ WVPASS bup save --strip-path foo -n foo src/x
+ WVPASS bup restore -C restore /foo/latest
+ WVPASS compare-trees src/ "restore/latest/$tmpdir/src/"
+fi
+
+
+WVSTART "save --graft (empty graft points disallowed)"
+WVPASS force-delete "$BUP_DIR" src restore
+WVPASS bup init
+WVPASS mkdir src
+WVFAIL bup save --graft =/grafted -n graft-point-absolute src 2>&1 \
+ | WVPASS grep 'error: a graft point cannot be empty'
+WVFAIL bup save --graft $top/$tmp= -n graft-point-absolute src 2>&1 \
+ | WVPASS grep 'error: a graft point cannot be empty'
+
+
+WVSTART "save --graft /x/y=/a/b (relative paths)"
+WVPASS force-delete "$BUP_DIR" src restore
+WVPASS bup init
+WVPASS mkdir -p src/x/y/z
+WVPASS bup random 8k > src/x/y/random-1
+WVPASS bup random 8k > src/x/y/z/random-2
+WVPASS bup index -u src
+WVPASS bup save --graft src=x -n foo src
+WVPASS bup restore -C restore /foo/latest
+WVPASS compare-trees src/ "restore/latest/$tmpdir/x/"
+
+
+WVSTART "save --graft /x/y=/a/b (matching structure)"
+WVPASS force-delete "$BUP_DIR" src restore
+WVPASS bup init
+WVPASS mkdir -p src/x/y/z
+WVPASS bup random 8k > src/x/y/random-1
+WVPASS bup random 8k > src/x/y/z/random-2
+WVPASS bup index -u src
+WVPASS bup save -v --graft "$tmpdir/src/x/y=$tmpdir/src/a/b" -n foo src/x/y
+WVPASS bup restore -C restore /foo/latest
+WVPASS compare-trees src/x/y/ "restore/latest/$tmpdir/src/a/b/"
+
+
+WVSTART "save --graft /x/y=/a (shorter target)"
+WVPASS force-delete "$BUP_DIR" src restore
+WVPASS bup init
+WVPASS mkdir -p src/x/y/z
+WVPASS bup random 8k > src/x/y/random-1
+WVPASS bup random 8k > src/x/y/z/random-2
+WVPASS bup index -u src
+WVPASS bup save -v --graft "$tmpdir/src/x/y=/a" -n foo src/x/y
+WVPASS bup restore -C restore /foo/latest
+WVPASS compare-trees src/x/y/ "restore/latest/a/"
+
+
+WVSTART "save --graft /x=/a/b (longer target)"
+WVPASS force-delete "$BUP_DIR" src restore
+WVPASS bup init
+WVPASS mkdir -p src/x/y/z
+WVPASS bup random 8k > src/x/y/random-1
+WVPASS bup random 8k > src/x/y/z/random-2
+WVPASS bup index -u src
+WVPASS bup save -v --graft "$tmpdir/src=$tmpdir/src/a/b/c" -n foo src
+WVPASS bup restore -C restore /foo/latest
+WVPASS compare-trees src/ "restore/latest/$tmpdir/src/a/b/c/"
+
+
+WVSTART "save --graft /x=/ (root target)"
+WVPASS force-delete "$BUP_DIR" src restore
+WVPASS bup init
+WVPASS mkdir -p src/x/y/z
+WVPASS bup random 8k > src/x/y/random-1
+WVPASS bup random 8k > src/x/y/z/random-2
+WVPASS bup index -u src
+WVPASS bup save -v --graft "$tmpdir/src/x=/" -n foo src/x
+WVPASS bup restore -C restore /foo/latest
+WVPASS compare-trees src/x/ "restore/latest/"
+
+
+#WVSTART "save --graft /=/x/ (root source)"
+# FIXME: Not tested for now -- will require cleverness, or caution as root.
+
+
+WVSTART "save collision"
+WVPASS force-delete "$BUP_DIR" src restore
+WVPASS bup init
+WVPASS mkdir -p src/x/1 src/y/1
+WVPASS bup index -u src
+WVFAIL bup save --strip -n foo src/x src/y 2> tmp-err.log
+WVPASS grep -F "error: ignoring duplicate path 1 in /" tmp-err.log
+
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-. dev/lib.sh || exit $?
-
-set -o pipefail
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-compare-trees() { "$top/dev/compare-trees" "$@"; }
-
-WVPASS cd "$tmpdir"
-
-
-WVSTART "save --strip"
-WVPASS force-delete "$BUP_DIR" src restore
-WVPASS bup init
-WVPASS mkdir -p src/x/y/z
-WVPASS bup random 8k > src/x/y/random-1
-WVPASS bup random 8k > src/x/y/z/random-2
-WVPASS bup index -u src
-WVPASS bup save --strip -n foo src/x/y
-WVPASS bup restore -C restore /foo/latest
-WVPASS compare-trees src/x/y/ restore/latest/
-
-
-WVSTART "save --strip-path (relative)"
-WVPASS force-delete "$BUP_DIR" src restore
-WVPASS bup init
-WVPASS mkdir -p src/x/y/z
-WVPASS bup random 8k > src/x/y/random-1
-WVPASS bup random 8k > src/x/y/z/random-2
-WVPASS bup index -u src
-WVPASS bup save --strip-path src -n foo src/x
-WVPASS bup restore -C restore /foo/latest
-WVPASS compare-trees src/ restore/latest/
-
-
-WVSTART "save --strip-path (absolute)"
-WVPASS force-delete "$BUP_DIR" src restore
-WVPASS bup init
-WVPASS mkdir -p src/x/y/z
-WVPASS bup random 8k > src/x/y/random-1
-WVPASS bup random 8k > src/x/y/z/random-2
-WVPASS bup index -u src
-WVPASS bup save --strip-path "$tmpdir" -n foo src
-WVPASS bup restore -C restore /foo/latest
-WVPASS compare-trees src/ "restore/latest/src/"
-
-
-WVSTART "save --strip-path (no match)"
-if test $(WVPASS path-filesystems . | WVPASS sort -u | WVPASS wc -l) -ne 1
-then
- # Skip the test because the attempt to restore parent dirs to the
- # current filesystem may fail -- i.e. running from
- # /foo/ext4/bar/btrfs will fail when bup tries to restore linux
- # attrs above btrfs to the restore tree *inside* btrfs.
- # FIXME: add WVSKIP
- echo "(running from tree with mixed filesystems; skipping test)" 1>&2
- exit 0
-else
- WVPASS force-delete "$BUP_DIR" src restore
- WVPASS bup init
- WVPASS mkdir -p src/x/y/z
- WVPASS bup random 8k > src/x/y/random-1
- WVPASS bup random 8k > src/x/y/z/random-2
- WVPASS bup index -u src
- WVPASS bup save --strip-path foo -n foo src/x
- WVPASS bup restore -C restore /foo/latest
- WVPASS compare-trees src/ "restore/latest/$tmpdir/src/"
-fi
-
-
-WVSTART "save --graft (empty graft points disallowed)"
-WVPASS force-delete "$BUP_DIR" src restore
-WVPASS bup init
-WVPASS mkdir src
-WVFAIL bup save --graft =/grafted -n graft-point-absolute src 2>&1 \
- | WVPASS grep 'error: a graft point cannot be empty'
-WVFAIL bup save --graft $top/$tmp= -n graft-point-absolute src 2>&1 \
- | WVPASS grep 'error: a graft point cannot be empty'
-
-
-WVSTART "save --graft /x/y=/a/b (relative paths)"
-WVPASS force-delete "$BUP_DIR" src restore
-WVPASS bup init
-WVPASS mkdir -p src/x/y/z
-WVPASS bup random 8k > src/x/y/random-1
-WVPASS bup random 8k > src/x/y/z/random-2
-WVPASS bup index -u src
-WVPASS bup save --graft src=x -n foo src
-WVPASS bup restore -C restore /foo/latest
-WVPASS compare-trees src/ "restore/latest/$tmpdir/x/"
-
-
-WVSTART "save --graft /x/y=/a/b (matching structure)"
-WVPASS force-delete "$BUP_DIR" src restore
-WVPASS bup init
-WVPASS mkdir -p src/x/y/z
-WVPASS bup random 8k > src/x/y/random-1
-WVPASS bup random 8k > src/x/y/z/random-2
-WVPASS bup index -u src
-WVPASS bup save -v --graft "$tmpdir/src/x/y=$tmpdir/src/a/b" -n foo src/x/y
-WVPASS bup restore -C restore /foo/latest
-WVPASS compare-trees src/x/y/ "restore/latest/$tmpdir/src/a/b/"
-
-
-WVSTART "save --graft /x/y=/a (shorter target)"
-WVPASS force-delete "$BUP_DIR" src restore
-WVPASS bup init
-WVPASS mkdir -p src/x/y/z
-WVPASS bup random 8k > src/x/y/random-1
-WVPASS bup random 8k > src/x/y/z/random-2
-WVPASS bup index -u src
-WVPASS bup save -v --graft "$tmpdir/src/x/y=/a" -n foo src/x/y
-WVPASS bup restore -C restore /foo/latest
-WVPASS compare-trees src/x/y/ "restore/latest/a/"
-
-
-WVSTART "save --graft /x=/a/b (longer target)"
-WVPASS force-delete "$BUP_DIR" src restore
-WVPASS bup init
-WVPASS mkdir -p src/x/y/z
-WVPASS bup random 8k > src/x/y/random-1
-WVPASS bup random 8k > src/x/y/z/random-2
-WVPASS bup index -u src
-WVPASS bup save -v --graft "$tmpdir/src=$tmpdir/src/a/b/c" -n foo src
-WVPASS bup restore -C restore /foo/latest
-WVPASS compare-trees src/ "restore/latest/$tmpdir/src/a/b/c/"
-
-
-WVSTART "save --graft /x=/ (root target)"
-WVPASS force-delete "$BUP_DIR" src restore
-WVPASS bup init
-WVPASS mkdir -p src/x/y/z
-WVPASS bup random 8k > src/x/y/random-1
-WVPASS bup random 8k > src/x/y/z/random-2
-WVPASS bup index -u src
-WVPASS bup save -v --graft "$tmpdir/src/x=/" -n foo src/x
-WVPASS bup restore -C restore /foo/latest
-WVPASS compare-trees src/x/ "restore/latest/"
-
-
-#WVSTART "save --graft /=/x/ (root source)"
-# FIXME: Not tested for now -- will require cleverness, or caution as root.
-
-
-WVSTART "save collision"
-WVPASS force-delete "$BUP_DIR" src restore
-WVPASS bup init
-WVPASS mkdir -p src/x/1 src/y/1
-WVPASS bup index -u src
-WVFAIL bup save --strip -n foo src/x src/y 2> tmp-err.log
-WVPASS grep -F "error: ignoring duplicate path 1 in /" tmp-err.log
-
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+. dev/lib.sh || exit $?
+
+set -o pipefail
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+compare-trees() { "$top/dev/compare-trees" "$@"; }
+
+WVPASS cd "$tmpdir"
+
+# Make sure that we can explicitly save a path whose parent is up to
+# date.
+
+WVSTART "save path with up to date parent"
+WVPASS bup init
+
+WVPASS mkdir -p src/a src/b
+WVPASS touch src/a/1 src/b/2
+WVPASS bup index -u src
+WVPASS bup save -n src src
+
+WVPASS bup save -n src src/b
+WVPASS bup restore -C restore "src/latest/$(pwd)/"
+WVPASS test ! -e restore/src/a
+WVPASS "$top/dev/compare-trees" -c src/b/ restore/src/b/
+
+WVPASS bup save -n src src/a/1
+WVPASS rm -r restore
+WVPASS bup restore -C restore "src/latest/$(pwd)/"
+WVPASS test ! -e restore/src/b
+WVPASS "$top/dev/compare-trees" -c src/a/ restore/src/a/
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-. dev/lib.sh || exit $?
-
-set -o pipefail
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-compare-trees() { "$top/dev/compare-trees" "$@"; }
-
-WVPASS cd "$tmpdir"
-
-# Make sure that we can explicitly save a path whose parent is up to
-# date.
-
-WVSTART "save path with up to date parent"
-WVPASS bup init
-
-WVPASS mkdir -p src/a src/b
-WVPASS touch src/a/1 src/b/2
-WVPASS bup index -u src
-WVPASS bup save -n src src
-
-WVPASS bup save -n src src/b
-WVPASS bup restore -C restore "src/latest/$(pwd)/"
-WVPASS test ! -e restore/src/a
-WVPASS "$top/dev/compare-trees" -c src/b/ restore/src/b/
-
-WVPASS bup save -n src src/a/1
-WVPASS rm -r restore
-WVPASS bup restore -C restore "src/latest/$(pwd)/"
-WVPASS test ! -e restore/src/b
-WVPASS "$top/dev/compare-trees" -c src/a/ restore/src/a/
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+. dev/lib.sh || exit $?
+
+set -o pipefail
+
+mb=1048576
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+readonly mb top tmpdir
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+
+WVPASS cd "$tmpdir"
+
+# The 3MB guess is semi-arbitrary, but we've been informed that
+# Lustre, for example, uses 1MB, so guess higher than that, at least.
+block_size=$(bup-cfg-py -c \
+ "import os; print(getattr(os.stat('.'), 'st_blksize', 0)) or $mb * 3") \
+ || exit $?
+data_size=$((block_size * 10))
+readonly block_size data_size
+
+WVPASS dd if=/dev/zero of=test-sparse-probe seek="$data_size" bs=1 count=1
+probe_size=$(WVPASS du -k -s test-sparse-probe | WVPASS cut -f1) || exit $?
+if [ "$probe_size" -ge "$((data_size / 1024))" ]; then
+ WVSTART "no sparse support detected -- skipping tests"
+ exit 0
+fi
+
+WVSTART "sparse restore on $(current-filesystem), assuming ${block_size}B blocks"
+
+WVPASS bup init
+WVPASS mkdir src
+
+WVPASS dd if=/dev/zero of=src/foo seek="$data_size" bs=1 count=1
+WVPASS bup index src
+WVPASS bup save -n src src
+
+WVSTART "sparse file restore (all sparse)"
+WVPASS bup restore -C restore "src/latest/$(pwd)/"
+restore_size=$(WVPASS du -k -s restore/src/foo | WVPASS cut -f1) || exit $?
+WVPASS [ "$restore_size" -ge "$((data_size / 1024))" ]
+WVPASS "$top/dev/compare-trees" -c src/ restore/src/
+
+WVSTART "sparse file restore --no-sparse (all sparse)"
+WVPASS rm -r restore
+WVPASS bup restore --no-sparse -C restore "src/latest/$(pwd)/"
+restore_size=$(WVPASS du -k -s restore/src/foo | WVPASS cut -f1) || exit $?
+WVPASS [ "$restore_size" -ge "$((data_size / 1024))" ]
+WVPASS "$top/dev/compare-trees" -c src/ restore/src/
+
+WVSTART "sparse file restore --sparse (all sparse)"
+WVPASS rm -r restore
+WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
+restore_size=$(WVPASS du -k -s restore/src/foo | WVPASS cut -f1) || exit $?
+WVPASS [ "$restore_size" -le "$((3 * (block_size / 1024)))" ]
+WVPASS "$top/dev/compare-trees" -c src/ restore/src/
+
+WVSTART "sparse file restore --sparse (sparse end)"
+WVPASS echo "start" > src/foo
+WVPASS dd if=/dev/zero of=src/foo seek="$data_size" bs=1 count=1 conv=notrunc
+WVPASS bup index src
+WVPASS bup save -n src src
+WVPASS rm -r restore
+WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
+restore_size=$(WVPASS du -k -s restore/src/foo | WVPASS cut -f1) || exit $?
+WVPASS [ "$restore_size" -le "$((3 * (block_size / 1024)))" ]
+WVPASS "$top/dev/compare-trees" -c src/ restore/src/
+
+WVSTART "sparse file restore --sparse (sparse middle)"
+WVPASS echo "end" >> src/foo
+WVPASS bup index src
+WVPASS bup save -n src src
+WVPASS rm -r restore
+WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
+restore_size=$(WVPASS du -k -s restore/src/foo | WVPASS cut -f1) || exit $?
+WVPASS [ "$restore_size" -le "$((5 * (block_size / 1024)))" ]
+WVPASS "$top/dev/compare-trees" -c src/ restore/src/
+
+WVSTART "sparse file restore --sparse (bracketed zero run in buf)"
+WVPASS echo 'x' > src/foo
+WVPASS dd if=/dev/zero bs=1 count=512 >> src/foo
+WVPASS echo 'y' >> src/foo
+WVPASS bup index src
+WVPASS bup save -n src src
+WVPASS rm -r restore
+WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
+WVPASS "$top/dev/compare-trees" -c src/ restore/src/
+
+WVSTART "sparse file restore --sparse (sparse start)"
+WVPASS dd if=/dev/zero of=src/foo seek="$data_size" bs=1 count=1
+WVPASS echo "end" >> src/foo
+WVPASS bup index src
+WVPASS bup save -n src src
+WVPASS rm -r restore
+WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
+restore_size=$(WVPASS du -k -s restore/src/foo | WVPASS cut -f1) || exit $?
+WVPASS [ "$restore_size" -le "$((5 * (block_size / 1024)))" ]
+WVPASS "$top/dev/compare-trees" -c src/ restore/src/
+
+WVSTART "sparse file restore --sparse (sparse start and end)"
+WVPASS dd if=/dev/zero of=src/foo seek="$data_size" bs=1 count=1
+WVPASS echo "middle" >> src/foo
+WVPASS dd if=/dev/zero of=src/foo seek=$((2 * data_size)) bs=1 count=1 conv=notrunc
+WVPASS bup index src
+WVPASS bup save -n src src
+WVPASS rm -r restore
+WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
+restore_size=$(WVPASS du -k -s restore/src/foo | WVPASS cut -f1) || exit $?
+WVPASS [ "$restore_size" -le "$((5 * (block_size / 1024)))" ]
+WVPASS "$top/dev/compare-trees" -c src/ restore/src/
+
+if test "$block_size" -gt $mb; then
+ random_size="$block_size"
+else
+ random_size=1M
+fi
+WVSTART "sparse file restore --sparse (random $random_size)"
+WVPASS bup random --seed "$RANDOM" 1M > src/foo
+WVPASS bup index src
+WVPASS bup save -n src src
+WVPASS rm -r restore
+WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
+WVPASS "$top/dev/compare-trees" -c src/ restore/src/
+
+WVSTART "sparse file restore --sparse (random sparse regions)"
+WVPASS rm -rf "$BUP_DIR" src
+WVPASS bup init
+WVPASS mkdir src
+for sparse_dataset in 0 1 2 3 4 5 6 7 8 9
+do
+ WVPASS "$top/dev/sparse-test-data" "src/foo-$sparse_dataset"
+done
+WVPASS bup index src
+WVPASS bup save -n src src
+WVPASS rm -r restore
+WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
+WVPASS "$top/dev/compare-trees" -c src/ restore/src/
+
+WVSTART "sparse file restore --sparse (short zero runs around boundary)"
+WVPASS bup-cfg-py > src/foo <<EOF
+from sys import stdout
+stdout.write("x" * 65535 + "\0")
+stdout.write("\0" + "x" * 65535)
+stdout.write("\0" + "x" * 65534 + "\0")
+stdout.write("x" * 65536)
+stdout.write("\0")
+EOF
+WVPASS bup index src
+WVPASS bup save -n src src
+WVPASS rm -r restore
+WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
+WVPASS "$top/dev/compare-trees" -c src/ restore/src/
+
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-. dev/lib.sh || exit $?
-
-set -o pipefail
-
-mb=1048576
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-readonly mb top tmpdir
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-
-WVPASS cd "$tmpdir"
-
-# The 3MB guess is semi-arbitrary, but we've been informed that
-# Lustre, for example, uses 1MB, so guess higher than that, at least.
-block_size=$(bup-cfg-py -c \
- "import os; print(getattr(os.stat('.'), 'st_blksize', 0)) or $mb * 3") \
- || exit $?
-data_size=$((block_size * 10))
-readonly block_size data_size
-
-WVPASS dd if=/dev/zero of=test-sparse-probe seek="$data_size" bs=1 count=1
-probe_size=$(WVPASS du -k -s test-sparse-probe | WVPASS cut -f1) || exit $?
-if [ "$probe_size" -ge "$((data_size / 1024))" ]; then
- WVSTART "no sparse support detected -- skipping tests"
- exit 0
-fi
-
-WVSTART "sparse restore on $(current-filesystem), assuming ${block_size}B blocks"
-
-WVPASS bup init
-WVPASS mkdir src
-
-WVPASS dd if=/dev/zero of=src/foo seek="$data_size" bs=1 count=1
-WVPASS bup index src
-WVPASS bup save -n src src
-
-WVSTART "sparse file restore (all sparse)"
-WVPASS bup restore -C restore "src/latest/$(pwd)/"
-restore_size=$(WVPASS du -k -s restore/src/foo | WVPASS cut -f1) || exit $?
-WVPASS [ "$restore_size" -ge "$((data_size / 1024))" ]
-WVPASS "$top/dev/compare-trees" -c src/ restore/src/
-
-WVSTART "sparse file restore --no-sparse (all sparse)"
-WVPASS rm -r restore
-WVPASS bup restore --no-sparse -C restore "src/latest/$(pwd)/"
-restore_size=$(WVPASS du -k -s restore/src/foo | WVPASS cut -f1) || exit $?
-WVPASS [ "$restore_size" -ge "$((data_size / 1024))" ]
-WVPASS "$top/dev/compare-trees" -c src/ restore/src/
-
-WVSTART "sparse file restore --sparse (all sparse)"
-WVPASS rm -r restore
-WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
-restore_size=$(WVPASS du -k -s restore/src/foo | WVPASS cut -f1) || exit $?
-WVPASS [ "$restore_size" -le "$((3 * (block_size / 1024)))" ]
-WVPASS "$top/dev/compare-trees" -c src/ restore/src/
-
-WVSTART "sparse file restore --sparse (sparse end)"
-WVPASS echo "start" > src/foo
-WVPASS dd if=/dev/zero of=src/foo seek="$data_size" bs=1 count=1 conv=notrunc
-WVPASS bup index src
-WVPASS bup save -n src src
-WVPASS rm -r restore
-WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
-restore_size=$(WVPASS du -k -s restore/src/foo | WVPASS cut -f1) || exit $?
-WVPASS [ "$restore_size" -le "$((3 * (block_size / 1024)))" ]
-WVPASS "$top/dev/compare-trees" -c src/ restore/src/
-
-WVSTART "sparse file restore --sparse (sparse middle)"
-WVPASS echo "end" >> src/foo
-WVPASS bup index src
-WVPASS bup save -n src src
-WVPASS rm -r restore
-WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
-restore_size=$(WVPASS du -k -s restore/src/foo | WVPASS cut -f1) || exit $?
-WVPASS [ "$restore_size" -le "$((5 * (block_size / 1024)))" ]
-WVPASS "$top/dev/compare-trees" -c src/ restore/src/
-
-WVSTART "sparse file restore --sparse (bracketed zero run in buf)"
-WVPASS echo 'x' > src/foo
-WVPASS dd if=/dev/zero bs=1 count=512 >> src/foo
-WVPASS echo 'y' >> src/foo
-WVPASS bup index src
-WVPASS bup save -n src src
-WVPASS rm -r restore
-WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
-WVPASS "$top/dev/compare-trees" -c src/ restore/src/
-
-WVSTART "sparse file restore --sparse (sparse start)"
-WVPASS dd if=/dev/zero of=src/foo seek="$data_size" bs=1 count=1
-WVPASS echo "end" >> src/foo
-WVPASS bup index src
-WVPASS bup save -n src src
-WVPASS rm -r restore
-WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
-restore_size=$(WVPASS du -k -s restore/src/foo | WVPASS cut -f1) || exit $?
-WVPASS [ "$restore_size" -le "$((5 * (block_size / 1024)))" ]
-WVPASS "$top/dev/compare-trees" -c src/ restore/src/
-
-WVSTART "sparse file restore --sparse (sparse start and end)"
-WVPASS dd if=/dev/zero of=src/foo seek="$data_size" bs=1 count=1
-WVPASS echo "middle" >> src/foo
-WVPASS dd if=/dev/zero of=src/foo seek=$((2 * data_size)) bs=1 count=1 conv=notrunc
-WVPASS bup index src
-WVPASS bup save -n src src
-WVPASS rm -r restore
-WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
-restore_size=$(WVPASS du -k -s restore/src/foo | WVPASS cut -f1) || exit $?
-WVPASS [ "$restore_size" -le "$((5 * (block_size / 1024)))" ]
-WVPASS "$top/dev/compare-trees" -c src/ restore/src/
-
-if test "$block_size" -gt $mb; then
- random_size="$block_size"
-else
- random_size=1M
-fi
-WVSTART "sparse file restore --sparse (random $random_size)"
-WVPASS bup random --seed "$RANDOM" 1M > src/foo
-WVPASS bup index src
-WVPASS bup save -n src src
-WVPASS rm -r restore
-WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
-WVPASS "$top/dev/compare-trees" -c src/ restore/src/
-
-WVSTART "sparse file restore --sparse (random sparse regions)"
-WVPASS rm -rf "$BUP_DIR" src
-WVPASS bup init
-WVPASS mkdir src
-for sparse_dataset in 0 1 2 3 4 5 6 7 8 9
-do
- WVPASS "$top/dev/sparse-test-data" "src/foo-$sparse_dataset"
-done
-WVPASS bup index src
-WVPASS bup save -n src src
-WVPASS rm -r restore
-WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
-WVPASS "$top/dev/compare-trees" -c src/ restore/src/
-
-WVSTART "sparse file restore --sparse (short zero runs around boundary)"
-WVPASS bup-cfg-py > src/foo <<EOF
-from sys import stdout
-stdout.write("x" * 65535 + "\0")
-stdout.write("\0" + "x" * 65535)
-stdout.write("\0" + "x" * 65534 + "\0")
-stdout.write("x" * 65536)
-stdout.write("\0")
-EOF
-WVPASS bup index src
-WVPASS bup save -n src src
-WVPASS rm -r restore
-WVPASS bup restore --sparse -C restore "src/latest/$(pwd)/"
-WVPASS "$top/dev/compare-trees" -c src/ restore/src/
-
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. wvtest.sh
+. wvtest-bup.sh
+. dev/lib.sh
+
+set -o pipefail
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+export BUP_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+
+WVPASS cd "$tmpdir"
+
+WVPASS bup init
+
+WVSTART "split --noop"
+WVPASS bup split --noop <"$top/test/testfile1" >noop.tmp
+WVPASSEQ '' "$(<noop.tmp)"
+WVPASS bup split --noop -b <"$top/test/testfile1" >tags1n.tmp
+WVPASS bup split --noop -t <"$top/test/testfile2" >tags2tn.tmp
+WVPASSEQ $(find "$BUP_DIR/objects/pack" -name '*.pack' | wc -l) 0
+
+WVSTART "split"
+WVPASS echo a >a.tmp
+WVPASS echo b >b.tmp
+WVPASS bup split -b a.tmp >taga.tmp
+WVPASS bup split -b b.tmp >tagb.tmp
+WVPASS cat a.tmp b.tmp | WVPASS bup split -b >tagab.tmp
+WVPASSEQ $(cat taga.tmp | wc -l) 1
+WVPASSEQ $(cat tagb.tmp | wc -l) 1
+WVPASSEQ $(cat tagab.tmp | wc -l) 1
+WVPASSEQ $(cat tag[ab].tmp | wc -l) 2
+WVPASSEQ "$(bup split -b a.tmp b.tmp)" "$(cat tagab.tmp)"
+WVPASSEQ "$(bup split -b --keep-boundaries a.tmp b.tmp)" "$(cat tag[ab].tmp)"
+WVPASSEQ "$(cat tag[ab].tmp | bup split -b --keep-boundaries --git-ids)" \
+ "$(cat tag[ab].tmp)"
+WVPASSEQ "$(cat tag[ab].tmp | bup split -b --git-ids)" \
+ "$(cat tagab.tmp)"
+WVPASS bup split --bench -b <"$top/test/testfile1" >tags1.tmp
+WVPASS bup split -vvvv -b "$top/test/testfile2" >tags2.tmp
+WVPASS echo -n "" | WVPASS bup split -n split_empty_string.tmp
+WVPASS bup margin
+WVPASS bup midx -f
+WVPASS bup midx --check -a
+WVPASS bup midx -o "$BUP_DIR/objects/pack/test1.midx" \
+ "$BUP_DIR"/objects/pack/*.idx
+WVPASS bup midx --check -a
+WVPASS bup midx -o "$BUP_DIR"/objects/pack/test1.midx \
+ "$BUP_DIR"/objects/pack/*.idx \
+ "$BUP_DIR"/objects/pack/*.idx
+WVPASS bup midx --check -a
+all=$(echo "$BUP_DIR"/objects/pack/*.idx "$BUP_DIR"/objects/pack/*.midx)
+WVPASS bup midx -o "$BUP_DIR"/objects/pack/zzz.midx $all
+WVPASS bup tick
+WVPASS bup midx -o "$BUP_DIR"/objects/pack/yyy.midx $all
+WVPASS bup midx -a
+WVPASSEQ "$(echo "$BUP_DIR"/objects/pack/*.midx)" \
+ ""$BUP_DIR"/objects/pack/yyy.midx"
+WVPASS bup margin
+WVPASS bup split -t "$top/test/testfile2" >tags2t.tmp
+WVPASS bup split -t "$top/test/testfile2" --fanout 3 >tags2tf.tmp
+WVPASS bup split -r "$BUP_DIR" -c "$top/test/testfile2" >tags2c.tmp
+WVPASS bup split -r ":$BUP_DIR" -c "$top/test/testfile2" >tags2c.tmp
+WVPASS ls -lR \
+ | WVPASS bup split -r ":$BUP_DIR" -c --fanout 3 --max-pack-objects 3 -n lslr \
+ || exit $?
+WVPASS bup ls
+WVFAIL bup ls /does-not-exist
+WVPASS bup ls /lslr
+WVPASS bup ls /lslr/latest
+WVPASS bup ls /lslr/latest/
+#WVPASS bup ls /lslr/1971-01-01 # all dates always exist
+WVFAIL diff -u tags1.tmp tags2.tmp
+WVPASS diff -u tags1.tmp tags1n.tmp
+WVPASS diff -u tags2t.tmp tags2tn.tmp
+
+# fanout must be different from non-fanout
+WVFAIL diff tags2t.tmp tags2tf.tmp
+WVPASS wc -c "$top/test/testfile1" "$top/test/testfile2"
+WVPASS wc -l tags1.tmp tags2.tmp
+
+WVSTART "join"
+WVPASS bup join $(cat tags1.tmp) >out1.tmp
+WVPASS bup join <tags2.tmp >out2.tmp
+WVPASS bup join <tags2t.tmp -o out2t.tmp
+WVPASS bup join -r "$BUP_DIR" <tags2c.tmp >out2c.tmp
+WVPASS bup join -r ":$BUP_DIR" <tags2c.tmp >out2c.tmp
+WVPASS diff -u "$top/test/testfile1" out1.tmp
+WVPASS diff -u "$top/test/testfile2" out2.tmp
+WVPASS diff -u "$top/test/testfile2" out2t.tmp
+WVPASS diff -u "$top/test/testfile2" out2c.tmp
+WVPASSEQ "$(bup join split_empty_string.tmp)" ""
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. wvtest.sh
-. wvtest-bup.sh
-. dev/lib.sh
-
-set -o pipefail
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-export BUP_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-
-WVPASS cd "$tmpdir"
-
-WVPASS bup init
-
-WVSTART "split --noop"
-WVPASS bup split --noop <"$top/test/testfile1" >noop.tmp
-WVPASSEQ '' "$(<noop.tmp)"
-WVPASS bup split --noop -b <"$top/test/testfile1" >tags1n.tmp
-WVPASS bup split --noop -t <"$top/test/testfile2" >tags2tn.tmp
-WVPASSEQ $(find "$BUP_DIR/objects/pack" -name '*.pack' | wc -l) 0
-
-WVSTART "split"
-WVPASS echo a >a.tmp
-WVPASS echo b >b.tmp
-WVPASS bup split -b a.tmp >taga.tmp
-WVPASS bup split -b b.tmp >tagb.tmp
-WVPASS cat a.tmp b.tmp | WVPASS bup split -b >tagab.tmp
-WVPASSEQ $(cat taga.tmp | wc -l) 1
-WVPASSEQ $(cat tagb.tmp | wc -l) 1
-WVPASSEQ $(cat tagab.tmp | wc -l) 1
-WVPASSEQ $(cat tag[ab].tmp | wc -l) 2
-WVPASSEQ "$(bup split -b a.tmp b.tmp)" "$(cat tagab.tmp)"
-WVPASSEQ "$(bup split -b --keep-boundaries a.tmp b.tmp)" "$(cat tag[ab].tmp)"
-WVPASSEQ "$(cat tag[ab].tmp | bup split -b --keep-boundaries --git-ids)" \
- "$(cat tag[ab].tmp)"
-WVPASSEQ "$(cat tag[ab].tmp | bup split -b --git-ids)" \
- "$(cat tagab.tmp)"
-WVPASS bup split --bench -b <"$top/test/testfile1" >tags1.tmp
-WVPASS bup split -vvvv -b "$top/test/testfile2" >tags2.tmp
-WVPASS echo -n "" | WVPASS bup split -n split_empty_string.tmp
-WVPASS bup margin
-WVPASS bup midx -f
-WVPASS bup midx --check -a
-WVPASS bup midx -o "$BUP_DIR/objects/pack/test1.midx" \
- "$BUP_DIR"/objects/pack/*.idx
-WVPASS bup midx --check -a
-WVPASS bup midx -o "$BUP_DIR"/objects/pack/test1.midx \
- "$BUP_DIR"/objects/pack/*.idx \
- "$BUP_DIR"/objects/pack/*.idx
-WVPASS bup midx --check -a
-all=$(echo "$BUP_DIR"/objects/pack/*.idx "$BUP_DIR"/objects/pack/*.midx)
-WVPASS bup midx -o "$BUP_DIR"/objects/pack/zzz.midx $all
-WVPASS bup tick
-WVPASS bup midx -o "$BUP_DIR"/objects/pack/yyy.midx $all
-WVPASS bup midx -a
-WVPASSEQ "$(echo "$BUP_DIR"/objects/pack/*.midx)" \
- ""$BUP_DIR"/objects/pack/yyy.midx"
-WVPASS bup margin
-WVPASS bup split -t "$top/test/testfile2" >tags2t.tmp
-WVPASS bup split -t "$top/test/testfile2" --fanout 3 >tags2tf.tmp
-WVPASS bup split -r "$BUP_DIR" -c "$top/test/testfile2" >tags2c.tmp
-WVPASS bup split -r ":$BUP_DIR" -c "$top/test/testfile2" >tags2c.tmp
-WVPASS ls -lR \
- | WVPASS bup split -r ":$BUP_DIR" -c --fanout 3 --max-pack-objects 3 -n lslr \
- || exit $?
-WVPASS bup ls
-WVFAIL bup ls /does-not-exist
-WVPASS bup ls /lslr
-WVPASS bup ls /lslr/latest
-WVPASS bup ls /lslr/latest/
-#WVPASS bup ls /lslr/1971-01-01 # all dates always exist
-WVFAIL diff -u tags1.tmp tags2.tmp
-WVPASS diff -u tags1.tmp tags1n.tmp
-WVPASS diff -u tags2t.tmp tags2tn.tmp
-
-# fanout must be different from non-fanout
-WVFAIL diff tags2t.tmp tags2tf.tmp
-WVPASS wc -c "$top/test/testfile1" "$top/test/testfile2"
-WVPASS wc -l tags1.tmp tags2.tmp
-
-WVSTART "join"
-WVPASS bup join $(cat tags1.tmp) >out1.tmp
-WVPASS bup join <tags2.tmp >out2.tmp
-WVPASS bup join <tags2t.tmp -o out2t.tmp
-WVPASS bup join -r "$BUP_DIR" <tags2c.tmp >out2c.tmp
-WVPASS bup join -r ":$BUP_DIR" <tags2c.tmp >out2c.tmp
-WVPASS diff -u "$top/test/testfile1" out1.tmp
-WVPASS diff -u "$top/test/testfile2" out2.tmp
-WVPASS diff -u "$top/test/testfile2" out2t.tmp
-WVPASS diff -u "$top/test/testfile2" out2c.tmp
-WVPASSEQ "$(bup join split_empty_string.tmp)" ""
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+
+set -o pipefail
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+
+WVSTART "half hour TZ"
+
+export TZ=ACDT-10:30
+
+WVPASS bup init
+WVPASS cd "$tmpdir"
+
+WVPASS mkdir src
+WVPASS bup index src
+WVPASS bup save -n src -d 1420164180 src
+
+WVPASSEQ "$(WVPASS git cat-file commit src | sed -ne 's/^author .*> //p')" \
+"1420164180 +1030"
+
+WVPASSEQ "$(WVPASS bup ls /src)" \
+"2015-01-02-123300
+latest"
+
+WVPASS rm -rf "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-
-set -o pipefail
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-
-WVSTART "half hour TZ"
-
-export TZ=ACDT-10:30
-
-WVPASS bup init
-WVPASS cd "$tmpdir"
-
-WVPASS mkdir src
-WVPASS bup index src
-WVPASS bup save -n src -d 1420164180 src
-
-WVPASSEQ "$(WVPASS git cat-file commit src | sed -ne 's/^author .*> //p')" \
-"1420164180 +1030"
-
-WVPASSEQ "$(WVPASS bup ls /src)" \
-"2015-01-02-123300
-latest"
-
-WVPASS rm -rf "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. wvtest-bup.sh || exit $?
+. dev/lib.sh || exit $?
+
+set -o pipefail
+
+TOP="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+export BUP_DIR="$tmpdir/bup"
+
+bup()
+{
+ "$TOP/bup" "$@"
+}
+
+wait-for-server-start()
+{
+ curl --unix-socket ./socket http://localhost/
+ curl_status=$?
+ while test $curl_status -eq 7; do
+ sleep 0.2
+ curl --unix-socket ./socket http://localhost/
+ curl_status=$?
+ done
+ WVPASSEQ $curl_status 0
+}
+
+WVPASS cd "$tmpdir"
+
+# FIXME: add WVSKIP
+if test -z "$(type -p curl)"; then
+ WVSTART 'curl does not appear to be installed; skipping test'
+ exit 0
+fi
+
+WVPASS bup-cfg-py -c "import socket as s; s.socket(s.AF_UNIX).bind('socket')"
+curl -s --unix-socket ./socket http://localhost/foo
+if test $? -ne 7; then
+ WVSTART 'curl does not appear to support --unix-socket; skipping test'
+ exit 0
+fi
+
+if ! bup-python -c 'import tornado' 2> /dev/null; then
+ WVSTART 'unable to import tornado; skipping test'
+ exit 0
+fi
+
+WVSTART 'web'
+WVPASS bup init
+WVPASS mkdir src
+WVPASS echo '¡excitement!' > src/data
+WVPASS echo -e 'whee \x80\x90\xff' > "$(echo -ne 'src/whee \x80\x90\xff')"
+WVPASS bup index src
+WVPASS bup save -n '¡excitement!' --strip src
+
+"$TOP/bup" web unix://socket &
+web_pid=$!
+wait-for-server-start
+
+WVPASS curl --unix-socket ./socket \
+ 'http://localhost/%C2%A1excitement%21/latest/data' > result
+WVPASS curl --unix-socket ./socket \
+ 'http://localhost/%C2%A1excitement%21/latest/whee%20%80%90%ff' > result2
+WVPASSEQ "$(curl --unix-socket ./socket http://localhost/static/styles.css)" \
+ "$(cat "$TOP/lib/web/static/styles.css")"
+
+WVPASSEQ '¡excitement!' "$(cat result)"
+WVPASS cmp "$(echo -ne 'src/whee \x80\x90\xff')" result2
+WVPASS kill -s TERM "$web_pid"
+WVPASS wait "$web_pid"
+
+WVPASS rm -r "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. wvtest-bup.sh || exit $?
-. dev/lib.sh || exit $?
-
-set -o pipefail
-
-TOP="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-export BUP_DIR="$tmpdir/bup"
-
-bup()
-{
- "$TOP/bup" "$@"
-}
-
-wait-for-server-start()
-{
- curl --unix-socket ./socket http://localhost/
- curl_status=$?
- while test $curl_status -eq 7; do
- sleep 0.2
- curl --unix-socket ./socket http://localhost/
- curl_status=$?
- done
- WVPASSEQ $curl_status 0
-}
-
-WVPASS cd "$tmpdir"
-
-# FIXME: add WVSKIP
-if test -z "$(type -p curl)"; then
- WVSTART 'curl does not appear to be installed; skipping test'
- exit 0
-fi
-
-WVPASS bup-cfg-py -c "import socket as s; s.socket(s.AF_UNIX).bind('socket')"
-curl -s --unix-socket ./socket http://localhost/foo
-if test $? -ne 7; then
- WVSTART 'curl does not appear to support --unix-socket; skipping test'
- exit 0
-fi
-
-if ! bup-python -c 'import tornado' 2> /dev/null; then
- WVSTART 'unable to import tornado; skipping test'
- exit 0
-fi
-
-WVSTART 'web'
-WVPASS bup init
-WVPASS mkdir src
-WVPASS echo '¡excitement!' > src/data
-WVPASS echo -e 'whee \x80\x90\xff' > "$(echo -ne 'src/whee \x80\x90\xff')"
-WVPASS bup index src
-WVPASS bup save -n '¡excitement!' --strip src
-
-"$TOP/bup" web unix://socket &
-web_pid=$!
-wait-for-server-start
-
-WVPASS curl --unix-socket ./socket \
- 'http://localhost/%C2%A1excitement%21/latest/data' > result
-WVPASS curl --unix-socket ./socket \
- 'http://localhost/%C2%A1excitement%21/latest/whee%20%80%90%ff' > result2
-WVPASSEQ "$(curl --unix-socket ./socket http://localhost/static/styles.css)" \
- "$(cat "$TOP/lib/web/static/styles.css")"
-
-WVPASSEQ '¡excitement!' "$(cat result)"
-WVPASS cmp "$(echo -ne 'src/whee \x80\x90\xff')" result2
-WVPASS kill -s TERM "$web_pid"
-WVPASS wait "$web_pid"
-
-WVPASS rm -r "$tmpdir"
--- /dev/null
+#!/usr/bin/env bash
+. ./wvtest-bup.sh || exit $?
+
+set -o pipefail
+
+root_status="$(dev/root-status)" || exit $?
+
+if [ "$root_status" != root ]; then
+ WVSTART 'not root: skipping tests'
+ exit 0 # FIXME: add WVSKIP.
+fi
+
+if ! modprobe loop; then
+ WVSTART 'unable to load loopback module; skipping tests' 1>&2
+ exit 0
+fi
+
+# These tests are only likely to work under Linux for now
+# (patches welcome).
+if ! [[ $(uname) =~ Linux ]]; then
+ WVSTART 'not Linux: skipping tests'
+ exit 0 # FIXME: add WVSKIP.
+fi
+
+top="$(WVPASS pwd)" || exit $?
+tmpdir="$(WVPASS wvmktempdir)" || exit $?
+
+export BUP_DIR="$tmpdir/bup"
+export GIT_DIR="$tmpdir/bup"
+
+bup() { "$top/bup" "$@"; }
+
+WVPASS bup init
+WVPASS pushd "$tmpdir"
+
+WVSTART 'drecurse'
+
+WVPASS dd if=/dev/zero of=testfs-1.img bs=1M count=32
+WVPASS dd if=/dev/zero of=testfs-2.img bs=1M count=32
+WVPASS mkfs -F testfs-1.img # Don't care what type (though must have symlinks)
+WVPASS mkfs -F testfs-2.img # Don't care what type (though must have symlinks)
+WVPASS mkdir -p src/mnt-1/hidden-1 src/mnt-2/hidden-2
+WVPASS mount -o loop testfs-1.img src/mnt-1
+WVPASS mount -o loop testfs-2.img src/mnt-2
+
+WVPASS touch src/1
+
+WVPASS mkdir -p src/mnt-1/x
+WVPASS touch src/mnt-1/2 src/mnt-1/x/3
+
+WVPASS touch src/mnt-2/4
+
+(WVPASS cd src && WVPASS ln -s mnt-2 mnt-link)
+(WVPASS cd src && WVPASS ln -s . top)
+
+WVPASSEQ "$(bup drecurse src | grep -vF lost+found)" "src/top
+src/mnt-link
+src/mnt-2/4
+src/mnt-2/
+src/mnt-1/x/3
+src/mnt-1/x/
+src/mnt-1/2
+src/mnt-1/
+src/1
+src/"
+
+WVPASSEQ "$(bup drecurse -x src)" "src/top
+src/mnt-link
+src/mnt-2/
+src/mnt-1/
+src/1
+src/"
+
+WVSTART 'index/save/restore'
+
+WVPASS bup index src
+WVPASS bup save -n src src
+WVPASS mkdir src-restore
+WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
+WVPASS test -d src-restore/src
+WVPASS "$top/dev/compare-trees" -c src/ src-restore/src/
+
+# Test -x when none of the mount points are explicitly indexed
+WVPASS rm -r "$BUP_DIR" src-restore
+WVPASS bup init
+WVPASS bup index -x src
+WVPASS bup save -n src src
+WVPASS mkdir src-restore
+WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
+WVPASS test -d src-restore/src
+WVPASSEQ "$(cd src-restore/src && find . -not -name lost+found | LC_ALL=C sort)" \
+".
+./1
+./mnt-1
+./mnt-2
+./mnt-link
+./top"
+
+# Test -x when a mount point is explicitly indexed. This should
+# include the mount.
+WVPASS rm -r "$BUP_DIR" src-restore
+WVPASS bup init
+WVPASS bup index -x src src/mnt-2
+WVPASS bup save -n src src
+WVPASS mkdir src-restore
+WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
+WVPASS test -d src-restore/src
+WVPASSEQ "$(cd src-restore/src && find . -not -name lost+found | LC_ALL=C sort)" \
+".
+./1
+./mnt-1
+./mnt-2
+./mnt-2/4
+./mnt-link
+./top"
+
+# Test -x when a direct link to a mount point is explicitly indexed.
+# This should *not* include the mount.
+WVPASS rm -r "$BUP_DIR" src-restore
+WVPASS bup init
+WVPASS bup index -x src src/mnt-link
+WVPASS bup save -n src src
+WVPASS mkdir src-restore
+WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
+WVPASS test -d src-restore/src
+WVPASSEQ "$(cd src-restore/src && find . -not -name lost+found | LC_ALL=C sort)" \
+".
+./1
+./mnt-1
+./mnt-2
+./mnt-link
+./top"
+
+# Test -x when a path that resolves to a mount point is explicitly
+# indexed (i.e. dir symlnks that redirect the leaf to a mount point).
+# This should include the mount.
+WVPASS rm -r "$BUP_DIR" src-restore
+WVPASS bup init
+WVPASS bup index -x src src/top/top/mnt-2
+WVPASS bup save -n src src
+WVPASS mkdir src-restore
+WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
+WVPASS test -d src-restore/src
+WVPASSEQ "$(cd src-restore/src && find . -not -name lost+found | LC_ALL=C sort)" \
+".
+./1
+./mnt-1
+./mnt-2
+./mnt-2/4
+./mnt-link
+./top"
+
+WVPASS cd "$top"
+WVPASS umount "$tmpdir/src/mnt-1"
+WVPASS umount "$tmpdir/src/mnt-2"
+WVPASS rm -r "$tmpdir"
+++ /dev/null
-#!/usr/bin/env bash
-. ./wvtest-bup.sh || exit $?
-
-set -o pipefail
-
-root_status="$(dev/root-status)" || exit $?
-
-if [ "$root_status" != root ]; then
- WVSTART 'not root: skipping tests'
- exit 0 # FIXME: add WVSKIP.
-fi
-
-if ! modprobe loop; then
- WVSTART 'unable to load loopback module; skipping tests' 1>&2
- exit 0
-fi
-
-# These tests are only likely to work under Linux for now
-# (patches welcome).
-if ! [[ $(uname) =~ Linux ]]; then
- WVSTART 'not Linux: skipping tests'
- exit 0 # FIXME: add WVSKIP.
-fi
-
-top="$(WVPASS pwd)" || exit $?
-tmpdir="$(WVPASS wvmktempdir)" || exit $?
-
-export BUP_DIR="$tmpdir/bup"
-export GIT_DIR="$tmpdir/bup"
-
-bup() { "$top/bup" "$@"; }
-
-WVPASS bup init
-WVPASS pushd "$tmpdir"
-
-WVSTART 'drecurse'
-
-WVPASS dd if=/dev/zero of=testfs-1.img bs=1M count=32
-WVPASS dd if=/dev/zero of=testfs-2.img bs=1M count=32
-WVPASS mkfs -F testfs-1.img # Don't care what type (though must have symlinks)
-WVPASS mkfs -F testfs-2.img # Don't care what type (though must have symlinks)
-WVPASS mkdir -p src/mnt-1/hidden-1 src/mnt-2/hidden-2
-WVPASS mount -o loop testfs-1.img src/mnt-1
-WVPASS mount -o loop testfs-2.img src/mnt-2
-
-WVPASS touch src/1
-
-WVPASS mkdir -p src/mnt-1/x
-WVPASS touch src/mnt-1/2 src/mnt-1/x/3
-
-WVPASS touch src/mnt-2/4
-
-(WVPASS cd src && WVPASS ln -s mnt-2 mnt-link)
-(WVPASS cd src && WVPASS ln -s . top)
-
-WVPASSEQ "$(bup drecurse src | grep -vF lost+found)" "src/top
-src/mnt-link
-src/mnt-2/4
-src/mnt-2/
-src/mnt-1/x/3
-src/mnt-1/x/
-src/mnt-1/2
-src/mnt-1/
-src/1
-src/"
-
-WVPASSEQ "$(bup drecurse -x src)" "src/top
-src/mnt-link
-src/mnt-2/
-src/mnt-1/
-src/1
-src/"
-
-WVSTART 'index/save/restore'
-
-WVPASS bup index src
-WVPASS bup save -n src src
-WVPASS mkdir src-restore
-WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
-WVPASS test -d src-restore/src
-WVPASS "$top/dev/compare-trees" -c src/ src-restore/src/
-
-# Test -x when none of the mount points are explicitly indexed
-WVPASS rm -r "$BUP_DIR" src-restore
-WVPASS bup init
-WVPASS bup index -x src
-WVPASS bup save -n src src
-WVPASS mkdir src-restore
-WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
-WVPASS test -d src-restore/src
-WVPASSEQ "$(cd src-restore/src && find . -not -name lost+found | LC_ALL=C sort)" \
-".
-./1
-./mnt-1
-./mnt-2
-./mnt-link
-./top"
-
-# Test -x when a mount point is explicitly indexed. This should
-# include the mount.
-WVPASS rm -r "$BUP_DIR" src-restore
-WVPASS bup init
-WVPASS bup index -x src src/mnt-2
-WVPASS bup save -n src src
-WVPASS mkdir src-restore
-WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
-WVPASS test -d src-restore/src
-WVPASSEQ "$(cd src-restore/src && find . -not -name lost+found | LC_ALL=C sort)" \
-".
-./1
-./mnt-1
-./mnt-2
-./mnt-2/4
-./mnt-link
-./top"
-
-# Test -x when a direct link to a mount point is explicitly indexed.
-# This should *not* include the mount.
-WVPASS rm -r "$BUP_DIR" src-restore
-WVPASS bup init
-WVPASS bup index -x src src/mnt-link
-WVPASS bup save -n src src
-WVPASS mkdir src-restore
-WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
-WVPASS test -d src-restore/src
-WVPASSEQ "$(cd src-restore/src && find . -not -name lost+found | LC_ALL=C sort)" \
-".
-./1
-./mnt-1
-./mnt-2
-./mnt-link
-./top"
-
-# Test -x when a path that resolves to a mount point is explicitly
-# indexed (i.e. dir symlnks that redirect the leaf to a mount point).
-# This should include the mount.
-WVPASS rm -r "$BUP_DIR" src-restore
-WVPASS bup init
-WVPASS bup index -x src src/top/top/mnt-2
-WVPASS bup save -n src src
-WVPASS mkdir src-restore
-WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
-WVPASS test -d src-restore/src
-WVPASSEQ "$(cd src-restore/src && find . -not -name lost+found | LC_ALL=C sort)" \
-".
-./1
-./mnt-1
-./mnt-2
-./mnt-2/4
-./mnt-link
-./top"
-
-WVPASS cd "$top"
-WVPASS umount "$tmpdir/src/mnt-1"
-WVPASS umount "$tmpdir/src/mnt-2"
-WVPASS rm -r "$tmpdir"