]> arthur.barton.de Git - bup.git/blob - t/test-meta.sh
Fix top-level non-dir metadata restoration with /foo/latest/target/ syntax.
[bup.git] / t / test-meta.sh
1 #!/usr/bin/env bash
2 . wvtest.sh
3 . t/lib.sh
4
5 TOP="$(pwd)"
6 export BUP_DIR="$TOP/buptest.tmp"
7
8 bup()
9 {
10     "$TOP/bup" "$@"
11 }
12
13 hardlink-sets()
14 {
15     "$TOP/t/hardlink-sets" "$@"
16 }
17
18 id-other-than()
19 {
20     "$TOP/t/id-other-than" "$@"
21 }
22
23 # Very simple metadata tests -- create a test tree then check that bup
24 # meta can reproduce the metadata correctly (according to bup xstat)
25 # via create, extract, start-extract, and finish-extract.  The current
26 # tests are crude, and this does not fully test devices, varying
27 # users/groups, acls, attrs, etc.
28
29 genstat()
30 {
31     (
32         export PATH="$TOP:$PATH" # pick up bup
33         # Skip atime (test elsewhere) to avoid the observer effect.
34         find . | sort | xargs bup xstat --exclude-fields ctime,atime,size
35     )
36 }
37
38 test-src-create-extract()
39 {
40     # Test bup meta create/extract for ./src -> ./src-restore.
41     # Also writes to ./src-stat and ./src-restore-stat.
42     (
43         (cd src && WVPASS genstat) > src-stat
44         WVPASS bup meta --create --recurse --file src.meta src
45         # Test extract.
46         force-delete src-restore
47         mkdir src-restore
48         cd src-restore
49         WVPASS bup meta --extract --file ../src.meta
50         WVPASS test -d src
51         (cd src && genstat >../../src-restore-stat) || WVFAIL
52         WVPASS diff -U5 ../src-stat ../src-restore-stat
53         # Test start/finish extract.
54         force-delete src
55         WVPASS bup meta --start-extract --file ../src.meta
56         WVPASS test -d src
57         WVPASS bup meta --finish-extract --file ../src.meta
58         (cd src && genstat >../../src-restore-stat) || WVFAIL
59         WVPASS diff -U5 ../src-stat ../src-restore-stat
60     )
61 }
62
63 test-src-save-restore()
64 {
65     # Test bup save/restore metadata for ./src -> ./src-restore.  Also
66     # writes to ./src.bup.  Note that for now this just tests the
67     # restore below src/, in order to avoid having to worry about
68     # operations that require root (like chown /home).
69     (
70         set -x
71         rm -rf src.bup
72         mkdir src.bup
73         export BUP_DIR=$(pwd)/src.bup
74         WVPASS bup init
75         WVPASS bup index src
76         WVPASS bup save -t -n src src
77         # Test extract.
78         force-delete src-restore
79         mkdir src-restore
80         WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
81         WVPASS test -d src-restore/src
82         WVPASS "$TOP/t/compare-trees" -c src/ src-restore/src/
83         rm -rf src.bup
84         set +x
85     )
86 }
87
88 universal-cleanup()
89 {
90     if [ $(t/root-status) != root ]; then return 0; fi
91     cd "$TOP"
92     umount "$TOP/bupmeta.tmp/testfs" || true
93     umount "$TOP/bupmeta.tmp/testfs-limited" || true
94 }
95
96 universal-cleanup
97 trap universal-cleanup EXIT
98
99 setup-test-tree()
100 (
101     set -e
102     force-delete "$BUP_DIR"
103     force-delete "$TOP/bupmeta.tmp"
104     mkdir -p "$TOP/bupmeta.tmp/src"
105     cp -pPR Documentation cmd lib t "$TOP/bupmeta.tmp"/src
106
107     # Add some hard links for the general tests.
108     (
109         cd "$TOP/bupmeta.tmp"/src
110         touch hardlink-target
111         ln hardlink-target hardlink-1
112         ln hardlink-target hardlink-2
113         ln hardlink-target hardlink-3
114     )
115
116     # Add some trivial files for the index, modify, save tests.
117     (
118         cd "$TOP/bupmeta.tmp"/src
119         mkdir volatile
120         touch volatile/{1,2,3}
121     )
122
123     # Regression test for metadata sort order.  Previously, these two
124     # entries would sort in the wrong order because the metadata
125     # entries were being sorted by mangled name, but the index isn't.
126     dd if=/dev/zero of="$TOP/bupmeta.tmp"/src/foo bs=1k count=33
127     touch -t 201111111111 "$TOP/bupmeta.tmp"/src/foo
128     touch -t 201112121111 "$TOP/bupmeta.tmp"/src/foo-bar
129
130     t/mksock "$TOP/bupmeta.tmp/src/test-socket" || true
131 ) || WVFAIL
132
133 # Use the test tree to check bup meta.
134 WVSTART 'meta --create/--extract'
135 (
136     setup-test-tree
137     cd "$TOP/bupmeta.tmp"
138     test-src-create-extract
139
140     # Test a top-level file (not dir).
141     touch src-file
142     WVPASS bup meta -cf src-file.meta src-file
143     mkdir dest
144     cd dest
145     WVPASS bup meta -xf ../src-file.meta
146 )
147
148 # Use the test tree to check bup save/restore metadata.
149 WVSTART 'metadata save/restore (general)'
150 (
151     setup-test-tree
152     cd "$TOP/bupmeta.tmp"
153     test-src-save-restore
154
155     # Test a deeper subdir/ to make sure top-level non-dir metadata is
156     # restored correctly.  We need at least one dir and one non-dir at
157     # the "top-level".
158     WVPASS test -f src/lib/__init__.py
159     WVPASS test -d src/lib/bup
160     rm -rf src.bup
161     mkdir src.bup
162     export BUP_DIR=$(pwd)/src.bup
163     WVPASS bup init
164     touch -t 201111111111 src-restore # Make sure the top won't match.
165     WVPASS bup index src
166     WVPASS bup save -t -n src src
167     force-delete src-restore
168     WVPASS bup restore -C src-restore "/src/latest$(pwd)/src/lib/"
169     touch -t 201211111111 src-restore # Make sure the top won't match.
170     # Check that the only difference is the top dir.
171     $TOP/t/compare-trees -c src/lib/ src-restore/ > tmp-compare-trees
172     WVPASSEQ $(cat tmp-compare-trees | wc -l) 2
173     tail -n +2 tmp-compare-trees | WVPASS grep -qE '^\.d[^ ]+ \./$'
174 ) || WVFAIL
175
176 # Test that we pull the index (not filesystem) metadata for any
177 # unchanged files whenever we're saving other files in a given
178 # directory.
179 WVSTART 'metadata save/restore (using index metadata)'
180 (
181     setup-test-tree
182     cd "$TOP/bupmeta.tmp"
183
184     # ...for now -- might be a problem with hardlink restores that was
185     # causing noise wrt this test.
186     rm -rf src/hardlink*
187
188     # Pause here to keep the filesystem changes far enough away from
189     # the first index run that bup won't cap their index timestamps
190     # (see "bup help index" for more information).  Without this
191     # sleep, the compare-trees test below "Bup should *not* pick up
192     # these metadata..." may fail.
193     sleep 1
194
195     set -x
196     rm -rf src.bup
197     mkdir src.bup
198     export BUP_DIR=$(pwd)/src.bup
199     WVPASS bup init
200     WVPASS bup index src
201     WVPASS bup save -t -n src src
202
203     force-delete src-restore-1
204     mkdir src-restore-1
205     WVPASS bup restore -C src-restore-1 "/src/latest$(pwd)/"
206     WVPASS test -d src-restore-1/src
207     WVPASS "$TOP/t/compare-trees" -c src/ src-restore-1/src/
208
209     echo "blarg" > src/volatile/1
210     cp -a src/volatile/1 src-restore-1/src/volatile/
211     WVPASS bup index src
212
213     # Bup should *not* pick up these metadata changes.
214     touch src/volatile/2
215
216     WVPASS bup save -t -n src src
217
218     force-delete src-restore-2
219     mkdir src-restore-2
220     WVPASS bup restore -C src-restore-2 "/src/latest$(pwd)/"
221     WVPASS test -d src-restore-2/src
222     WVPASS "$TOP/t/compare-trees" -c src-restore-1/src/ src-restore-2/src/
223
224     rm -rf src.bup
225     set +x
226 )
227
228 setup-hardlink-test()
229 {
230     (
231         cd "$TOP/bupmeta.tmp"
232         rm -rf src src.bup
233         mkdir src src.bup
234         WVPASS bup init
235     )
236 }
237
238 hardlink-test-run-restore()
239 {
240     force-delete src-restore
241     mkdir src-restore
242     WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
243     WVPASS test -d src-restore/src
244 }
245
246 # Test hardlinks more carefully.
247 WVSTART 'metadata save/restore (hardlinks)'
248 (
249     set -e
250     set -x
251     export BUP_DIR="$TOP/bupmeta.tmp/src.bup"
252     force-delete "$TOP/bupmeta.tmp"
253     mkdir -p "$TOP/bupmeta.tmp"
254
255     cd "$TOP/bupmeta.tmp"
256
257     # Test trivial case - single hardlink.
258     setup-hardlink-test
259     (
260         cd "$TOP/bupmeta.tmp"/src
261         touch hardlink-target
262         ln hardlink-target hardlink-1
263     )
264     WVPASS bup index src
265     WVPASS bup save -t -n src src
266     hardlink-test-run-restore
267     WVPASS "$TOP/t/compare-trees" -c src/ src-restore/src/
268
269     # Test the case where the hardlink hasn't changed, but the tree
270     # needs to be saved again. i.e. the save-cmd.py "if hashvalid:"
271     # case.
272     (
273         cd "$TOP/bupmeta.tmp"/src
274         echo whatever > something-new
275     )
276     WVPASS bup index src
277     WVPASS bup save -t -n src src
278     hardlink-test-run-restore
279     WVPASS "$TOP/t/compare-trees" -c src/ src-restore/src/
280
281     # Test hardlink changes between index runs.
282     #
283     setup-hardlink-test
284     cd "$TOP/bupmeta.tmp"/src
285     touch hardlink-target-a
286     touch hardlink-target-b
287     ln hardlink-target-a hardlink-b-1
288     ln hardlink-target-a hardlink-a-1
289     cd ..
290     WVPASS bup index -vv src
291     rm src/hardlink-b-1
292     ln src/hardlink-target-b src/hardlink-b-1
293     WVPASS bup index -vv src
294     WVPASS bup save -t -n src src
295     hardlink-test-run-restore
296     echo ./src/hardlink-a-1 > hardlink-sets.expected
297     echo ./src/hardlink-target-a >> hardlink-sets.expected
298     echo >> hardlink-sets.expected
299     echo ./src/hardlink-b-1 >> hardlink-sets.expected
300     echo ./src/hardlink-target-b >> hardlink-sets.expected
301     (cd src-restore && hardlink-sets .) > hardlink-sets.restored
302     WVPASS diff -u hardlink-sets.expected hardlink-sets.restored
303
304     # Test hardlink changes between index and save -- hardlink set [a
305     # b c d] changes to [a b] [c d].  At least right now bup should
306     # notice and recreate the latter.
307     setup-hardlink-test
308     cd "$TOP/bupmeta.tmp"/src
309     touch a
310     ln a b
311     ln a c
312     ln a d
313     cd ..
314     WVPASS bup index -vv src
315     rm src/c src/d
316     touch src/c
317     ln src/c src/d
318     WVPASS bup save -t -n src src
319     hardlink-test-run-restore
320     echo ./src/a > hardlink-sets.expected
321     echo ./src/b >> hardlink-sets.expected
322     echo >> hardlink-sets.expected
323     echo ./src/c >> hardlink-sets.expected
324     echo ./src/d >> hardlink-sets.expected
325     (cd src-restore && hardlink-sets .) > hardlink-sets.restored
326     WVPASS diff -u hardlink-sets.expected hardlink-sets.restored
327
328     # Test that we don't link outside restore tree.
329     setup-hardlink-test
330     cd "$TOP/bupmeta.tmp"
331     mkdir src/a src/b
332     touch src/a/1
333     ln src/a/1 src/b/1
334     WVPASS bup index -vv src
335     WVPASS bup save -t -n src src
336     force-delete src-restore
337     mkdir src-restore
338     WVPASS bup restore -C src-restore "/src/latest$(pwd)/src/a/"
339     WVPASS test -e src-restore/1
340     echo -n > hardlink-sets.expected
341     (cd src-restore && hardlink-sets .) > hardlink-sets.restored
342     WVPASS diff -u hardlink-sets.expected hardlink-sets.restored
343
344     # Test that we do link within separate sub-trees.
345     setup-hardlink-test
346     cd "$TOP/bupmeta.tmp"
347     mkdir src/a src/b
348     touch src/a/1
349     ln src/a/1 src/b/1
350     WVPASS bup index -vv src/a src/b
351     WVPASS bup save -t -n src src/a src/b
352     hardlink-test-run-restore
353     echo ./src/a/1 > hardlink-sets.expected
354     echo ./src/b/1 >> hardlink-sets.expected
355     (cd src-restore && hardlink-sets .) > hardlink-sets.restored
356     WVPASS diff -u hardlink-sets.expected hardlink-sets.restored
357 )
358
359 WVSTART 'meta --edit'
360 (
361     force-delete "$TOP/bupmeta.tmp"
362     mkdir "$TOP/bupmeta.tmp"
363     cd "$TOP/bupmeta.tmp"
364     mkdir src
365     WVPASS bup meta -cf src.meta src
366
367     WVPASS bup meta --edit --set-uid 0 src.meta | WVPASS bup meta -tvvf - \
368         | WVPASS grep -qE '^uid: 0'
369     WVPASS bup meta --edit --set-uid 1000 src.meta | WVPASS bup meta -tvvf - \
370         | WVPASS grep -qE '^uid: 1000'
371
372     WVPASS bup meta --edit --set-gid 0 src.meta | WVPASS bup meta -tvvf - \
373         | WVPASS grep -qE '^gid: 0'
374     WVPASS bup meta --edit --set-gid 1000 src.meta | WVPASS bup meta -tvvf - \
375         | WVPASS grep -qE '^gid: 1000'
376
377     WVPASS bup meta --edit --set-user foo src.meta | WVPASS bup meta -tvvf - \
378         | WVPASS grep -qE '^user: foo'
379     WVPASS bup meta --edit --set-user bar src.meta | WVPASS bup meta -tvvf - \
380         | WVPASS grep -qE '^user: bar'
381     WVPASS bup meta --edit --unset-user src.meta | WVPASS bup meta -tvvf - \
382         | WVPASS grep -qE '^user:'
383     WVPASS bup meta --edit --set-user bar --unset-user src.meta \
384         | WVPASS bup meta -tvvf - | WVPASS grep -qE '^user:'
385     WVPASS bup meta --edit --unset-user --set-user bar src.meta \
386         | WVPASS bup meta -tvvf - | WVPASS grep -qE '^user: bar'
387
388     WVPASS bup meta --edit --set-group foo src.meta | WVPASS bup meta -tvvf - \
389         | WVPASS grep -qE '^group: foo'
390     WVPASS bup meta --edit --set-group bar src.meta | WVPASS bup meta -tvvf - \
391         | WVPASS grep -qE '^group: bar'
392     WVPASS bup meta --edit --unset-group src.meta | WVPASS bup meta -tvvf - \
393         | WVPASS grep -qE '^group:'
394     WVPASS bup meta --edit --set-group bar --unset-group src.meta \
395         | WVPASS bup meta -tvvf - | WVPASS grep -qE '^group:'
396     WVPASS bup meta --edit --unset-group --set-group bar src.meta \
397         | WVPASS bup meta -tvvf - | grep -qE '^group: bar'
398 )
399
400 # Test ownership restoration (when not root or fakeroot).
401 (
402     if [ $(t/root-status) != none ]; then
403         exit 0
404     fi
405
406     WVSTART 'metadata (restoration of ownership)'
407     force-delete "$TOP/bupmeta.tmp"
408     mkdir "$TOP/bupmeta.tmp"
409     cd "$TOP/bupmeta.tmp"
410     touch src
411     WVPASS bup meta -cf src.meta src
412
413     mkdir dest
414     cd dest
415     # Make sure we don't change (or try to change) the user when not root.
416     WVPASS bup meta --edit --set-user root ../src.meta | WVPASS bup meta -x
417     WVPASS bup xstat src | WVPASS grep -qvE '^user: root'
418     rm -rf src
419     WVPASS bup meta --edit --unset-user --set-uid 0 ../src.meta \
420         | WVPASS bup meta -x
421     WVPASS bup xstat src | grep -qvE '^user: root'
422
423     # Make sure we can restore one of the user's groups.
424     last_group="$(python -c 'import os,grp; \
425       print grp.getgrgid(os.getgroups()[0])[0]')"
426     rm -rf src
427     WVPASS bup meta --edit --set-group "$last_group" ../src.meta \
428         | WVPASS bup meta -x
429     WVPASS bup xstat src | WVPASS grep -qE "^group: $last_group"
430
431     # Make sure we can restore one of the user's gids.
432     user_gids="$(id -G)"
433     last_gid="$(echo ${user_gids/* /})"
434     rm -rf src
435     WVPASS bup meta --edit --unset-group --set-gid "$last_gid" ../src.meta \
436         | WVPASS bup meta -x
437     WVPASS bup xstat src | WVPASS grep -qE "^gid: $last_gid"
438
439     # Test --numeric-ids (gid).
440     rm -rf src
441     current_gidx=$(bup meta -tvvf ../src.meta | grep -e '^gid:')
442     WVPASS bup meta --edit --set-group "$last_group" ../src.meta \
443         | WVPASS bup meta -x --numeric-ids
444     new_gidx=$(bup xstat src | grep -e '^gid:')
445     WVPASSEQ "$current_gidx" "$new_gidx"
446
447     # Test that restoring an unknown user works.
448     unknown_user=$("$TOP"/t/unknown-owner --user)
449     rm -rf src
450     current_uidx=$(bup meta -tvvf ../src.meta | grep -e '^uid:')
451     WVPASS bup meta --edit --set-user "$unknown_user" ../src.meta \
452         | WVPASS bup meta -x
453     new_uidx=$(bup xstat src | grep -e '^uid:')
454     WVPASSEQ "$current_uidx" "$new_uidx"
455
456     # Test that restoring an unknown group works.
457     unknown_group=$("$TOP"/t/unknown-owner --group)
458     rm -rf src
459     current_gidx=$(bup meta -tvvf ../src.meta | grep -e '^gid:')
460     WVPASS bup meta --edit --set-group "$unknown_group" ../src.meta \
461         | WVPASS bup meta -x
462     new_gidx=$(bup xstat src | grep -e '^gid:')
463     WVPASSEQ "$current_gidx" "$new_gidx"
464 )
465
466 # Test ownership restoration (when root or fakeroot).
467 (
468     if [ $(t/root-status) == none ]; then
469         exit 0
470     fi
471
472     WVSTART 'metadata (restoration of ownership as root)'
473     force-delete "$TOP/bupmeta.tmp"
474     mkdir "$TOP/bupmeta.tmp"
475     cd "$TOP/bupmeta.tmp"
476     touch src
477     chown 0:0 src # In case the parent dir is sgid, etc.
478     WVPASS bup meta -cf src.meta src
479
480     mkdir dest
481     chmod 700 dest # so we can't accidentally do something insecure
482     cd dest
483
484     other_uinfo="$(id-other-than --user "$(id -un)")"
485     other_user="${other_uinfo%%:*}"
486     other_uid="${other_uinfo##*:}"
487
488     other_ginfo="$(id-other-than --group "$(id -gn)")"
489     other_group="${other_ginfo%%:*}"
490     other_gid="${other_ginfo##*:}"
491
492     # Make sure we can restore a uid (must be in /etc/passwd b/c cygwin).
493     WVPASS bup meta --edit --unset-user --set-uid "$other_uid" ../src.meta \
494         | WVPASS bup meta -x
495     WVPASS bup xstat src | WVPASS grep -qE "^uid: $other_uid"
496
497     # Make sure we can restore a gid (must be in /etc/group b/c cygwin).
498     WVPASS bup meta --edit --unset-group --set-gid "$other_gid" ../src.meta \
499         | WVPASS bup meta -x
500     WVPASS bup xstat src | WVPASS grep -qE "^gid: $other_gid"
501
502     other_uinfo2="$(id-other-than --user "$(id -un)" "$other_user")"
503     other_user2="${other_uinfo2%%:*}"
504     other_uid2="${other_uinfo2##*:}"
505
506     other_ginfo2="$(id-other-than --group "$(id -gn)" "$other_group")"
507     other_group2="${other_ginfo2%%:*}"
508     other_gid2="${other_ginfo2##*:}"
509
510     # Try to restore a user (and see that user trumps uid when uid is not 0).
511     WVPASS bup meta --edit \
512         --set-uid "$other_uid2" --set-user "$some_user" ../src.meta \
513         | WVPASS bup meta -x
514     WVPASS bup xstat src | WVPASS grep -qE "^user: $some_user"
515
516     # Try to restore a group (and see that group trumps gid when gid is not 0).
517     WVPASS bup meta --edit \
518         --set-gid "$other_gid2" --set-group "$some_group" ../src.meta \
519         | WVPASS bup meta -x
520     WVPASS bup xstat src | WVPASS grep -qE "^group: $some_user"
521
522     # Test --numeric-ids (uid).  Note the name 'root' is not handled
523     # specially, so we use that here as the test user name.  We assume
524     # that the root user's uid is never 42.
525     rm -rf src
526     WVPASS bup meta --edit --set-user root --set-uid "$other_uid" ../src.meta \
527         | WVPASS bup meta -x --numeric-ids
528     new_uidx=$(bup xstat src | grep -e '^uid:')
529     WVPASSEQ "$new_uidx" "uid: $other_uid"
530
531     # Test --numeric-ids (gid).  Note the name 'root' is not handled
532     # specially, so we use that here as the test group name.  We
533     # assume that the root group's gid is never 42.
534     rm -rf src
535     WVPASS bup meta --edit --set-group root --set-gid "$other_gid" ../src.meta \
536         | WVPASS bup meta -x --numeric-ids
537     new_gidx=$(bup xstat src | grep -e '^gid:')
538     WVPASSEQ "$new_gidx" "gid: $other_gid"
539
540     # Test that restoring an unknown user works.
541     unknown_user=$("$TOP"/t/unknown-owners --user)
542     rm -rf src
543     WVPASS bup meta --edit \
544         --set-uid "$other_uid" --set-user "$unknown_user" ../src.meta \
545         | WVPASS bup meta -x
546     new_uidx=$(bup xstat src | grep -e '^uid:')
547     WVPASSEQ "$new_uidx" "uid: $other_uid"
548
549     # Test that restoring an unknown group works.
550     unknown_group=$("$TOP"/t/unknown-owners --group)
551     rm -rf src
552     WVPASS bup meta --edit \
553         --set-gid "$other_gid" --set-group "$unknown_group" ../src.meta \
554         | WVPASS bup meta -x
555     new_gidx=$(bup xstat src | grep -e '^gid:')
556     WVPASSEQ "$new_gidx" "gid: $other_gid"
557
558     if ! [[ $(uname) =~ CYGWIN ]]; then
559         # For now, skip these on Cygwin because it doesn't allow
560         # restoring an unknown uid/gid.
561
562         # Make sure a uid of 0 trumps a non-root user.
563         WVPASS bup meta --edit --set-user "$some_user" ../src.meta \
564             | WVPASS bup meta -x
565         WVPASS bup xstat src | WVPASS grep -qvE "^user: $some_user"
566         WVPASS bup xstat src | WVPASS grep -qE "^uid: 0"
567
568         # Make sure a gid of 0 trumps a non-root group.
569         WVPASS bup meta --edit --set-group "$some_user" ../src.meta \
570             | WVPASS bup meta -x
571         WVPASS bup xstat src | WVPASS grep -qvE "^group: $some_group"
572         WVPASS bup xstat src | WVPASS grep -qE "^gid: 0"
573     fi
574 )
575
576 # Root-only tests that require an FS with all the trimmings: ACLs,
577 # Linux attr, Linux xattr, etc.
578 if [ $(t/root-status) == root ]; then
579     (
580         set -e
581         # Some cleanup handled in universal-cleanup() above.
582         # These tests are only likely to work under Linux for now
583         # (patches welcome).
584         [[ $(uname) =~ Linux ]] || exit 0
585
586         WVSTART 'meta - general (as root)'
587         setup-test-tree
588         cd "$TOP/bupmeta.tmp"
589
590         umount testfs || true
591         dd if=/dev/zero of=testfs.img bs=1M count=32
592         mke2fs -F -j -m 0 testfs.img
593         mkdir testfs
594         mount -o loop,acl,user_xattr testfs.img testfs
595         # Hide, so that tests can't create risks.
596         chown root:root testfs
597         chmod 0700 testfs
598
599         umount testfs-limited || true
600         dd if=/dev/zero of=testfs-limited.img bs=1M count=32
601         mkfs -t vfat testfs-limited.img
602         mkdir testfs-limited
603         mount -o loop,uid=root,gid=root,umask=0077 \
604             testfs-limited.img testfs-limited
605
606         #cp -a src testfs/src
607         cp -pPR src testfs/src
608         (cd testfs && test-src-create-extract)
609
610         WVSTART 'meta - atime (as root)'
611         force-delete testfs/src
612         mkdir testfs/src
613         (
614             mkdir testfs/src/foo
615             touch testfs/src/bar
616             PYTHONPATH="$TOP/lib" \
617                 python -c "from bup import xstat; \
618                 x = xstat.timespec_to_nsecs((42, 0));\
619                    xstat.utime('testfs/src/foo', (x, x));\
620                    xstat.utime('testfs/src/bar', (x, x));"
621             cd testfs
622             WVPASS bup meta -v --create --recurse --file src.meta src
623             bup meta -tvf src.meta
624             # Test extract.
625             force-delete src-restore
626             mkdir src-restore
627             cd src-restore
628             WVPASS bup meta --extract --file ../src.meta
629             WVPASSEQ "$(bup xstat --include-fields=atime src/foo)" "atime: 42"
630             WVPASSEQ "$(bup xstat --include-fields=atime src/bar)" "atime: 42"
631             # Test start/finish extract.
632             force-delete src
633             WVPASS bup meta --start-extract --file ../src.meta
634             WVPASS test -d src
635             WVPASS bup meta --finish-extract --file ../src.meta
636             WVPASSEQ "$(bup xstat --include-fields=atime src/foo)" "atime: 42"
637             WVPASSEQ "$(bup xstat --include-fields=atime src/bar)" "atime: 42"
638         )
639
640         WVSTART 'meta - Linux attr (as root)'
641         force-delete testfs/src
642         mkdir testfs/src
643         (
644             touch testfs/src/foo
645             mkdir testfs/src/bar
646             chattr +acdeijstuADST testfs/src/foo
647             chattr +acdeijstuADST testfs/src/bar
648             (cd testfs && test-src-create-extract)
649             # Test restoration to a limited filesystem (vfat).
650             (
651                 WVPASS bup meta --create --recurse --file testfs/src.meta \
652                     testfs/src
653                 force-delete testfs-limited/src-restore
654                 mkdir testfs-limited/src-restore
655                 cd testfs-limited/src-restore
656                 WVFAIL bup meta --extract --file ../../testfs/src.meta 2>&1 \
657                     | WVPASS grep -e '^Linux chattr:' \
658                     | WVPASS python -c \
659                       'import sys; exit(not len(sys.stdin.readlines()) == 2)'
660             )
661         )
662
663         WVSTART 'meta - Linux xattr (as root)'
664         force-delete testfs/src
665         mkdir testfs/src
666         (
667             touch testfs/src/foo
668             mkdir testfs/src/bar
669             attr -s foo -V bar testfs/src/foo
670             attr -s foo -V bar testfs/src/bar
671             (cd testfs && test-src-create-extract)
672
673             # Test restoration to a limited filesystem (vfat).
674             (
675                 WVPASS bup meta --create --recurse --file testfs/src.meta \
676                     testfs/src
677                 force-delete testfs-limited/src-restore
678                 mkdir testfs-limited/src-restore
679                 cd testfs-limited/src-restore
680                 WVFAIL bup meta --extract --file ../../testfs/src.meta 2>&1 \
681                     | WVPASS grep -e '^xattr\.set:' \
682                     | WVPASS python -c \
683                       'import sys; exit(not len(sys.stdin.readlines()) == 2)'
684             )
685         )
686
687         WVSTART 'meta - POSIX.1e ACLs (as root)'
688         force-delete testfs/src
689         mkdir testfs/src
690         (
691             touch testfs/src/foo
692             mkdir testfs/src/bar
693             setfacl -m u:root:r testfs/src/foo
694             setfacl -m u:root:r testfs/src/bar
695             (cd testfs && test-src-create-extract)
696
697             # Test restoration to a limited filesystem (vfat).
698             (
699                 WVPASS bup meta --create --recurse --file testfs/src.meta \
700                     testfs/src
701                 force-delete testfs-limited/src-restore
702                 mkdir testfs-limited/src-restore
703                 cd testfs-limited/src-restore
704                 WVFAIL bup meta --extract --file ../../testfs/src.meta 2>&1 \
705                     | WVPASS grep -e '^POSIX1e ACL applyto:' \
706                     | WVPASS python -c \
707                       'import sys; exit(not len(sys.stdin.readlines()) == 2)'
708             )
709         )
710     )
711 fi
712
713 exit 0