5 export BUP_DIR="$TOP/buptest.tmp"
12 # Very simple metadata tests -- create a test tree then check that bup
13 # meta can reproduce the metadata correctly (according to bup xstat)
14 # via create, extract, start-extract, and finish-extract. The current
15 # tests are crude, and this does not fully test devices, varying
16 # users/groups, acls, attrs, etc.
21 export PATH="$TOP:$PATH" # pick up bup
22 # Skip atime (test elsewhere) to avoid the observer effect.
23 find . | sort | xargs bup xstat --exclude-fields ctime,atime,size
29 test "$(whoami)" == root -a -z "$FAKEROOTKEY"
34 if ! actually-root; then
37 # Go to greater lengths to deal with any test detritus.
39 test -e "$@" || continue
40 chattr -fR = "$@" || true
53 trap "rm -rf '${tmpfile}'" EXIT
54 rsync -ni -aHAX "$1" "$2" > "${tmpfile}"
55 if test $(wc -l < "${tmpfile}") != 0; then
56 echo "ERROR: detected differences between $1 and $2"
63 test-src-create-extract()
65 # Test bup meta create/extract for ./src -> ./src-restore.
66 # Also writes to ./src-stat and ./src-restore-stat.
68 (cd src && WVPASS genstat) > src-stat
69 WVPASS bup meta --create --recurse --file src.meta src
71 force-delete src-restore
74 WVPASS bup meta --extract --file ../src.meta
76 (cd src && genstat >../../src-restore-stat) || WVFAIL
77 WVPASS diff -U5 ../src-stat ../src-restore-stat
78 # Test start/finish extract.
80 WVPASS bup meta --start-extract --file ../src.meta
82 WVPASS bup meta --finish-extract --file ../src.meta
83 (cd src && genstat >../../src-restore-stat) || WVFAIL
84 WVPASS diff -U5 ../src-stat ../src-restore-stat
88 test-src-save-restore()
90 # Test bup save/restore metadata for ./src -> ./src-restore. Also
91 # writes to ./src.bup. Note that for now this just tests the
92 # restore below src/, in order to avoid having to worry about
93 # operations that require root (like chown /home).
98 export BUP_DIR=$(pwd)/src.bup
101 WVPASS bup save -t -n src src
103 force-delete src-restore
105 WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
106 WVPASS test -d src-restore/src
107 WVPASS compare-trees src/ src-restore/src/
115 if ! actually-root; then return 0; fi
117 umount "$TOP/bupmeta.tmp/testfs" || true
118 umount "$TOP/bupmeta.tmp/testfs-limited" || true
122 trap universal-cleanup EXIT
127 force-delete "$BUP_DIR"
128 force-delete "$TOP/bupmeta.tmp"
129 mkdir -p "$TOP/bupmeta.tmp/src"
130 cp -pPR Documentation cmd lib t "$TOP/bupmeta.tmp"/src
132 # Regression test for metadata sort order. Previously, these two
133 # entries would sort in the wrong order because the metadata
134 # entries were being sorted by mangled name, but the index isn't.
135 dd if=/dev/zero of="$TOP/bupmeta.tmp"/src/foo bs=1k count=33
136 touch -d 2011-11-11 "$TOP/bupmeta.tmp"/src/foo
137 touch -d 2011-12-12 "$TOP/bupmeta.tmp"/src/foo-bar
139 t/mksock "$TOP/bupmeta.tmp/src/test-socket" || true
142 # Use the test tree to check bup meta.
143 WVSTART 'meta --create/--extract'
146 cd "$TOP/bupmeta.tmp"
147 test-src-create-extract
149 # Test a top-level file (not dir).
151 WVPASS bup meta -cf src-file.meta src-file
154 WVPASS bup meta -xf ../src-file.meta
157 # Use the test tree to check bup save/restore metadata.
158 WVSTART 'metadata save/restore (general)'
161 cd "$TOP/bupmeta.tmp"
162 test-src-save-restore
165 WVSTART 'meta --edit'
167 force-delete "$TOP/bupmeta.tmp"
168 mkdir "$TOP/bupmeta.tmp"
169 cd "$TOP/bupmeta.tmp"
171 WVPASS bup meta -cf src.meta src
173 WVPASS bup meta --edit --set-uid 0 src.meta | WVPASS bup meta -tvvf - \
174 | WVPASS grep -qE '^uid: 0'
175 WVPASS bup meta --edit --set-uid 1000 src.meta | WVPASS bup meta -tvvf - \
176 | WVPASS grep -qE '^uid: 1000'
178 WVPASS bup meta --edit --set-gid 0 src.meta | WVPASS bup meta -tvvf - \
179 | WVPASS grep -qE '^gid: 0'
180 WVPASS bup meta --edit --set-gid 1000 src.meta | WVPASS bup meta -tvvf - \
181 | WVPASS grep -qE '^gid: 1000'
183 WVPASS bup meta --edit --set-user foo src.meta | WVPASS bup meta -tvvf - \
184 | WVPASS grep -qE '^user: foo'
185 WVPASS bup meta --edit --set-user bar src.meta | WVPASS bup meta -tvvf - \
186 | WVPASS grep -qE '^user: bar'
187 WVPASS bup meta --edit --unset-user src.meta | WVPASS bup meta -tvvf - \
188 | WVPASS grep -qE '^user:'
189 WVPASS bup meta --edit --set-user bar --unset-user src.meta \
190 | WVPASS bup meta -tvvf - | WVPASS grep -qE '^user:'
191 WVPASS bup meta --edit --unset-user --set-user bar src.meta \
192 | WVPASS bup meta -tvvf - | WVPASS grep -qE '^user: bar'
194 WVPASS bup meta --edit --set-group foo src.meta | WVPASS bup meta -tvvf - \
195 | WVPASS grep -qE '^group: foo'
196 WVPASS bup meta --edit --set-group bar src.meta | WVPASS bup meta -tvvf - \
197 | WVPASS grep -qE '^group: bar'
198 WVPASS bup meta --edit --unset-group src.meta | WVPASS bup meta -tvvf - \
199 | WVPASS grep -qE '^group:'
200 WVPASS bup meta --edit --set-group bar --unset-group src.meta \
201 | WVPASS bup meta -tvvf - | WVPASS grep -qE '^group:'
202 WVPASS bup meta --edit --unset-group --set-group bar src.meta \
203 | WVPASS bup meta -tvvf - | grep -qE '^group: bar'
206 # Test ownership restoration (when not root or fakeroot).
208 if test "$(whoami)" == root; then
212 WVSTART 'metadata (restoration of ownership)'
213 force-delete "$TOP/bupmeta.tmp"
214 mkdir "$TOP/bupmeta.tmp"
215 cd "$TOP/bupmeta.tmp"
217 WVPASS bup meta -cf src.meta src
221 # Make sure we don't change (or try to change) the user when not root.
222 WVPASS bup meta --edit --set-user root ../src.meta | WVPASS bup meta -x
223 WVPASS bup xstat src | WVPASS grep -qvE '^user: root'
225 WVPASS bup meta --edit --unset-user --set-uid 0 ../src.meta \
227 WVPASS bup xstat src | grep -qvE '^user: root'
229 # Make sure we can restore one of the user's groups.
230 last_group="$(python -c 'import os,grp; \
231 print grp.getgrgid(os.getgroups()[0])[0]')"
233 WVPASS bup meta --edit --set-group "$last_group" ../src.meta \
235 WVPASS bup xstat src | WVPASS grep -qE "^group: $last_group"
237 # Make sure we can restore one of the user's gids.
239 last_gid="$(echo ${user_gids/* /})"
241 WVPASS bup meta --edit --unset-group --set-gid "$last_gid" ../src.meta \
243 WVPASS bup xstat src | WVPASS grep -qE "^gid: $last_gid"
245 # Test --numeric-ids (gid).
247 current_gidx=$(bup meta -tvvf ../src.meta | grep -e '^gid:')
248 WVPASS bup meta --edit --set-group "$last_group" ../src.meta \
249 | WVPASS bup meta -x --numeric-ids
250 new_gidx=$(bup xstat src | grep -e '^gid:')
251 WVPASSEQ "$current_gidx" "$new_gidx"
253 # Test that restoring an unknown user works.
254 unknown_user=$("$TOP"/t/unknown-owner --user)
256 current_uidx=$(bup meta -tvvf ../src.meta | grep -e '^uid:')
257 WVPASS bup meta --edit --set-user "$unknown_user" ../src.meta \
259 new_uidx=$(bup xstat src | grep -e '^uid:')
260 WVPASSEQ "$current_uidx" "$new_uidx"
262 # Test that restoring an unknown group works.
263 unknown_group=$("$TOP"/t/unknown-owner --group)
265 current_gidx=$(bup meta -tvvf ../src.meta | grep -e '^gid:')
266 WVPASS bup meta --edit --set-group "$unknown_group" ../src.meta \
268 new_gidx=$(bup xstat src | grep -e '^gid:')
269 WVPASSEQ "$current_gidx" "$new_gidx"
272 # Test ownership restoration (when root or fakeroot).
274 if test "$(whoami)" != root; then
278 WVSTART 'metadata (restoration of ownership as root)'
279 force-delete "$TOP/bupmeta.tmp"
280 mkdir "$TOP/bupmeta.tmp"
281 cd "$TOP/bupmeta.tmp"
283 chown 0:0 src # In case the parent dir is sgid, etc.
284 WVPASS bup meta -cf src.meta src
287 chmod 700 dest # so we can't accidentally do something insecure
290 # Make sure we can restore a uid.
291 WVPASS bup meta --edit --unset-user --set-uid 42 ../src.meta \
293 WVPASS bup xstat src | WVPASS grep -qE '^uid: 42'
295 # Make sure we can restore a gid.
296 WVPASS bup meta --edit --unset-group --set-gid 42 ../src.meta \
298 WVPASS bup xstat src | WVPASS grep -qE '^gid: 42'
300 some_user=$("$TOP"/t/some-owner --user)
301 some_group=$("$TOP"/t/some-owner --group)
303 # Try to restore a user (and see that user trumps uid when uid is not 0).
304 WVPASS bup meta --edit --set-uid 42 --set-user "$some_user" ../src.meta \
306 WVPASS bup xstat src | WVPASS grep -qE "^user: $some_user"
308 # Try to restore a group (and see that group trumps gid when gid is not 0).
309 WVPASS bup meta --edit --set-gid 42 --set-group "$some_group" ../src.meta \
311 WVPASS bup xstat src | WVPASS grep -qE "^group: $some_user"
313 # Make sure a uid of 0 trumps a non-root user.
314 WVPASS bup meta --edit --set-user "$some_user" ../src.meta \
316 WVPASS bup xstat src | WVPASS grep -qvE "^user: $some_user"
317 WVPASS bup xstat src | WVPASS grep -qE "^uid: 0"
319 # Make sure a gid of 0 trumps a non-root group.
320 WVPASS bup meta --edit --set-group "$some_user" ../src.meta \
322 WVPASS bup xstat src | WVPASS grep -qvE "^group: $some_group"
323 WVPASS bup xstat src | WVPASS grep -qE "^gid: 0"
325 # Test --numeric-ids (gid). Note the name 'root' is not handled
326 # specially, so we use that here as the test group name. We
327 # assume that the root group's gid is never 42.
329 WVPASS bup meta --edit --set-group root --set-gid 42 ../src.meta \
330 | WVPASS bup meta -x --numeric-ids
331 new_gidx=$(bup xstat src | grep -e '^gid:')
332 WVPASSEQ "$new_gidx" 'gid: 42'
334 # Test --numeric-ids (uid). Note the name 'root' is not handled
335 # specially, so we use that here as the test user name. We assume
336 # that the root user's uid is never 42.
338 WVPASS bup meta --edit --set-user root --set-uid 42 ../src.meta \
339 | WVPASS bup meta -x --numeric-ids
340 new_uidx=$(bup xstat src | grep -e '^uid:')
341 WVPASSEQ "$new_uidx" 'uid: 42'
343 # Test that restoring an unknown user works.
344 unknown_user=$("$TOP"/t/unknown-owners --user)
346 WVPASS bup meta --edit --set-uid 42 --set-user "$unknown_user" ../src.meta \
348 new_uidx=$(bup xstat src | grep -e '^uid:')
349 WVPASSEQ "$new_uidx" 'uid: 42'
351 # Test that restoring an unknown group works.
352 unknown_group=$("$TOP"/t/unknown-owners --group)
354 WVPASS bup meta --edit \
355 --set-gid 42 --set-group "$unknown_group" ../src.meta \
357 new_gidx=$(bup xstat src | grep -e '^gid:')
358 WVPASSEQ "$new_gidx" 'gid: 42'
361 # Root-only tests that require an FS with all the trimmings: ACLs,
362 # Linux attr, Linux xattr, etc.
363 if actually-root; then
366 # Some cleanup handled in universal-cleanup() above.
367 # These tests are only likely to work under Linux for now
369 [[ $(uname) =~ Linux ]] || exit 0
371 WVSTART 'meta - general (as root)'
373 cd "$TOP/bupmeta.tmp"
375 umount testfs || true
376 dd if=/dev/zero of=testfs.img bs=1M count=32
377 mke2fs -F -j -m 0 testfs.img
379 mount -o loop,acl,user_xattr testfs.img testfs
380 # Hide, so that tests can't create risks.
381 chown root:root testfs
384 umount testfs-limited || true
385 dd if=/dev/zero of=testfs-limited.img bs=1M count=32
386 mkfs -t vfat testfs-limited.img
388 mount -o loop,uid=root,gid=root,umask=0077 \
389 testfs-limited.img testfs-limited
391 #cp -a src testfs/src
392 cp -pPR src testfs/src
393 (cd testfs && test-src-create-extract)
395 WVSTART 'meta - atime (as root)'
396 force-delete testfs/src
401 PYTHONPATH="$TOP/lib" \
402 python -c "from bup import xstat; \
403 x = xstat.timespec_to_nsecs((42, 0));\
404 xstat.utime('testfs/src/foo', (x, x));\
405 xstat.utime('testfs/src/bar', (x, x));"
407 WVPASS bup meta -v --create --recurse --file src.meta src
408 bup meta -tvf src.meta
410 force-delete src-restore
413 WVPASS bup meta --extract --file ../src.meta
414 WVPASSEQ "$(bup xstat --include-fields=atime src/foo)" "atime: 42"
415 WVPASSEQ "$(bup xstat --include-fields=atime src/bar)" "atime: 42"
416 # Test start/finish extract.
418 WVPASS bup meta --start-extract --file ../src.meta
420 WVPASS bup meta --finish-extract --file ../src.meta
421 WVPASSEQ "$(bup xstat --include-fields=atime src/foo)" "atime: 42"
422 WVPASSEQ "$(bup xstat --include-fields=atime src/bar)" "atime: 42"
425 WVSTART 'meta - Linux attr (as root)'
426 force-delete testfs/src
431 chattr +acdeijstuADST testfs/src/foo
432 chattr +acdeijstuADST testfs/src/bar
433 (cd testfs && test-src-create-extract)
434 # Test restoration to a limited filesystem (vfat).
436 WVPASS bup meta --create --recurse --file testfs/src.meta \
438 force-delete testfs-limited/src-restore
439 mkdir testfs-limited/src-restore
440 cd testfs-limited/src-restore
441 WVFAIL bup meta --extract --file ../../testfs/src.meta 2>&1 \
442 | WVPASS grep -e '^Linux chattr:' \
444 'import sys; exit(not len(sys.stdin.readlines()) == 2)'
448 WVSTART 'meta - Linux xattr (as root)'
449 force-delete testfs/src
454 attr -s foo -V bar testfs/src/foo
455 attr -s foo -V bar testfs/src/bar
456 (cd testfs && test-src-create-extract)
458 # Test restoration to a limited filesystem (vfat).
460 WVPASS bup meta --create --recurse --file testfs/src.meta \
462 force-delete testfs-limited/src-restore
463 mkdir testfs-limited/src-restore
464 cd testfs-limited/src-restore
465 WVFAIL bup meta --extract --file ../../testfs/src.meta 2>&1 \
466 | WVPASS grep -e '^xattr\.set:' \
468 'import sys; exit(not len(sys.stdin.readlines()) == 2)'
472 WVSTART 'meta - POSIX.1e ACLs (as root)'
473 force-delete testfs/src
478 setfacl -m u:root:r testfs/src/foo
479 setfacl -m u:root:r testfs/src/bar
480 (cd testfs && test-src-create-extract)
482 # Test restoration to a limited filesystem (vfat).
484 WVPASS bup meta --create --recurse --file testfs/src.meta \
486 force-delete testfs-limited/src-restore
487 mkdir testfs-limited/src-restore
488 cd testfs-limited/src-restore
489 WVFAIL bup meta --extract --file ../../testfs/src.meta 2>&1 \
490 | WVPASS grep -e '^POSIX1e ACL applyto:' \
492 'import sys; exit(not len(sys.stdin.readlines()) == 2)'