]> arthur.barton.de Git - bup.git/blob - t/test-meta.sh
Fix path ownership restoration problems on Cygwin.
[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
156 # Test that we pull the index (not filesystem) metadata for any
157 # unchanged files whenever we're saving other files in a given
158 # directory.
159 WVSTART 'metadata save/restore (using index metadata)'
160 (
161     setup-test-tree
162     cd "$TOP/bupmeta.tmp"
163
164     # ...for now -- might be a problem with hardlink restores that was
165     # causing noise wrt this test.
166     rm -rf src/hardlink*
167
168     # Pause here to keep the filesystem changes far enough away from
169     # the first index run that bup won't cap their index timestamps
170     # (see "bup help index" for more information).  Without this
171     # sleep, the compare-trees test below "Bup should *not* pick up
172     # these metadata..." may fail.
173     sleep 1
174
175     set -x
176     rm -rf src.bup
177     mkdir src.bup
178     export BUP_DIR=$(pwd)/src.bup
179     WVPASS bup init
180     WVPASS bup index src
181     WVPASS bup save -t -n src src
182
183     force-delete src-restore-1
184     mkdir src-restore-1
185     WVPASS bup restore -C src-restore-1 "/src/latest$(pwd)/"
186     WVPASS test -d src-restore-1/src
187     WVPASS "$TOP/t/compare-trees" -c src/ src-restore-1/src/
188
189     echo "blarg" > src/volatile/1
190     cp -a src/volatile/1 src-restore-1/src/volatile/
191     WVPASS bup index src
192
193     # Bup should *not* pick up these metadata changes.
194     touch src/volatile/2
195
196     WVPASS bup save -t -n src src
197
198     force-delete src-restore-2
199     mkdir src-restore-2
200     WVPASS bup restore -C src-restore-2 "/src/latest$(pwd)/"
201     WVPASS test -d src-restore-2/src
202     WVPASS "$TOP/t/compare-trees" -c src-restore-1/src/ src-restore-2/src/
203
204     rm -rf src.bup
205     set +x
206 )
207
208 setup-hardlink-test()
209 {
210     (
211         cd "$TOP/bupmeta.tmp"
212         rm -rf src src.bup
213         mkdir src src.bup
214         WVPASS bup init
215     )
216 }
217
218 hardlink-test-run-restore()
219 {
220     force-delete src-restore
221     mkdir src-restore
222     WVPASS bup restore -C src-restore "/src/latest$(pwd)/"
223     WVPASS test -d src-restore/src
224 }
225
226 # Test hardlinks more carefully.
227 WVSTART 'metadata save/restore (hardlinks)'
228 (
229     set -e
230     set -x
231     export BUP_DIR="$TOP/bupmeta.tmp/src.bup"
232     force-delete "$TOP/bupmeta.tmp"
233     mkdir -p "$TOP/bupmeta.tmp"
234
235     cd "$TOP/bupmeta.tmp"
236
237     # Test trivial case - single hardlink.
238     setup-hardlink-test
239     (
240         cd "$TOP/bupmeta.tmp"/src
241         touch hardlink-target
242         ln hardlink-target hardlink-1
243     )
244     WVPASS bup index src
245     WVPASS bup save -t -n src src
246     hardlink-test-run-restore
247     WVPASS "$TOP/t/compare-trees" -c src/ src-restore/src/
248
249     # Test the case where the hardlink hasn't changed, but the tree
250     # needs to be saved again. i.e. the save-cmd.py "if hashvalid:"
251     # case.
252     (
253         cd "$TOP/bupmeta.tmp"/src
254         echo whatever > something-new
255     )
256     WVPASS bup index src
257     WVPASS bup save -t -n src src
258     hardlink-test-run-restore
259     WVPASS "$TOP/t/compare-trees" -c src/ src-restore/src/
260
261     # Test hardlink changes between index runs.
262     #
263     setup-hardlink-test
264     cd "$TOP/bupmeta.tmp"/src
265     touch hardlink-target-a
266     touch hardlink-target-b
267     ln hardlink-target-a hardlink-b-1
268     ln hardlink-target-a hardlink-a-1
269     cd ..
270     WVPASS bup index -vv src
271     rm src/hardlink-b-1
272     ln src/hardlink-target-b src/hardlink-b-1
273     WVPASS bup index -vv src
274     WVPASS bup save -t -n src src
275     hardlink-test-run-restore
276     echo ./src/hardlink-a-1 > hardlink-sets.expected
277     echo ./src/hardlink-target-a >> hardlink-sets.expected
278     echo >> hardlink-sets.expected
279     echo ./src/hardlink-b-1 >> hardlink-sets.expected
280     echo ./src/hardlink-target-b >> hardlink-sets.expected
281     (cd src-restore && hardlink-sets .) > hardlink-sets.restored
282     WVPASS diff -u hardlink-sets.expected hardlink-sets.restored
283
284     # Test hardlink changes between index and save -- hardlink set [a
285     # b c d] changes to [a b] [c d].  At least right now bup should
286     # notice and recreate the latter.
287     setup-hardlink-test
288     cd "$TOP/bupmeta.tmp"/src
289     touch a
290     ln a b
291     ln a c
292     ln a d
293     cd ..
294     WVPASS bup index -vv src
295     rm src/c src/d
296     touch src/c
297     ln src/c src/d
298     WVPASS bup save -t -n src src
299     hardlink-test-run-restore
300     echo ./src/a > hardlink-sets.expected
301     echo ./src/b >> hardlink-sets.expected
302     echo >> hardlink-sets.expected
303     echo ./src/c >> hardlink-sets.expected
304     echo ./src/d >> hardlink-sets.expected
305     (cd src-restore && hardlink-sets .) > hardlink-sets.restored
306     WVPASS diff -u hardlink-sets.expected hardlink-sets.restored
307
308     # Test that we don't link outside restore tree.
309     setup-hardlink-test
310     cd "$TOP/bupmeta.tmp"
311     mkdir src/a src/b
312     touch src/a/1
313     ln src/a/1 src/b/1
314     WVPASS bup index -vv src
315     WVPASS bup save -t -n src src
316     force-delete src-restore
317     mkdir src-restore
318     WVPASS bup restore -C src-restore "/src/latest$(pwd)/src/a/"
319     WVPASS test -e src-restore/1
320     echo -n > hardlink-sets.expected
321     (cd src-restore && hardlink-sets .) > hardlink-sets.restored
322     WVPASS diff -u hardlink-sets.expected hardlink-sets.restored
323
324     # Test that we do link within separate sub-trees.
325     setup-hardlink-test
326     cd "$TOP/bupmeta.tmp"
327     mkdir src/a src/b
328     touch src/a/1
329     ln src/a/1 src/b/1
330     WVPASS bup index -vv src/a src/b
331     WVPASS bup save -t -n src src/a src/b
332     hardlink-test-run-restore
333     echo ./src/a/1 > hardlink-sets.expected
334     echo ./src/b/1 >> hardlink-sets.expected
335     (cd src-restore && hardlink-sets .) > hardlink-sets.restored
336     WVPASS diff -u hardlink-sets.expected hardlink-sets.restored
337 )
338
339 WVSTART 'meta --edit'
340 (
341     force-delete "$TOP/bupmeta.tmp"
342     mkdir "$TOP/bupmeta.tmp"
343     cd "$TOP/bupmeta.tmp"
344     mkdir src
345     WVPASS bup meta -cf src.meta src
346
347     WVPASS bup meta --edit --set-uid 0 src.meta | WVPASS bup meta -tvvf - \
348         | WVPASS grep -qE '^uid: 0'
349     WVPASS bup meta --edit --set-uid 1000 src.meta | WVPASS bup meta -tvvf - \
350         | WVPASS grep -qE '^uid: 1000'
351
352     WVPASS bup meta --edit --set-gid 0 src.meta | WVPASS bup meta -tvvf - \
353         | WVPASS grep -qE '^gid: 0'
354     WVPASS bup meta --edit --set-gid 1000 src.meta | WVPASS bup meta -tvvf - \
355         | WVPASS grep -qE '^gid: 1000'
356
357     WVPASS bup meta --edit --set-user foo src.meta | WVPASS bup meta -tvvf - \
358         | WVPASS grep -qE '^user: foo'
359     WVPASS bup meta --edit --set-user bar src.meta | WVPASS bup meta -tvvf - \
360         | WVPASS grep -qE '^user: bar'
361     WVPASS bup meta --edit --unset-user src.meta | WVPASS bup meta -tvvf - \
362         | WVPASS grep -qE '^user:'
363     WVPASS bup meta --edit --set-user bar --unset-user src.meta \
364         | WVPASS bup meta -tvvf - | WVPASS grep -qE '^user:'
365     WVPASS bup meta --edit --unset-user --set-user bar src.meta \
366         | WVPASS bup meta -tvvf - | WVPASS grep -qE '^user: bar'
367
368     WVPASS bup meta --edit --set-group foo src.meta | WVPASS bup meta -tvvf - \
369         | WVPASS grep -qE '^group: foo'
370     WVPASS bup meta --edit --set-group bar src.meta | WVPASS bup meta -tvvf - \
371         | WVPASS grep -qE '^group: bar'
372     WVPASS bup meta --edit --unset-group src.meta | WVPASS bup meta -tvvf - \
373         | WVPASS grep -qE '^group:'
374     WVPASS bup meta --edit --set-group bar --unset-group src.meta \
375         | WVPASS bup meta -tvvf - | WVPASS grep -qE '^group:'
376     WVPASS bup meta --edit --unset-group --set-group bar src.meta \
377         | WVPASS bup meta -tvvf - | grep -qE '^group: bar'
378 )
379
380 # Test ownership restoration (when not root or fakeroot).
381 (
382     if [ $(t/root-status) != none ]; then
383         exit 0
384     fi
385
386     WVSTART 'metadata (restoration of ownership)'
387     force-delete "$TOP/bupmeta.tmp"
388     mkdir "$TOP/bupmeta.tmp"
389     cd "$TOP/bupmeta.tmp"
390     touch src
391     WVPASS bup meta -cf src.meta src
392
393     mkdir dest
394     cd dest
395     # Make sure we don't change (or try to change) the user when not root.
396     WVPASS bup meta --edit --set-user root ../src.meta | WVPASS bup meta -x
397     WVPASS bup xstat src | WVPASS grep -qvE '^user: root'
398     rm -rf src
399     WVPASS bup meta --edit --unset-user --set-uid 0 ../src.meta \
400         | WVPASS bup meta -x
401     WVPASS bup xstat src | grep -qvE '^user: root'
402
403     # Make sure we can restore one of the user's groups.
404     last_group="$(python -c 'import os,grp; \
405       print grp.getgrgid(os.getgroups()[0])[0]')"
406     rm -rf src
407     WVPASS bup meta --edit --set-group "$last_group" ../src.meta \
408         | WVPASS bup meta -x
409     WVPASS bup xstat src | WVPASS grep -qE "^group: $last_group"
410
411     # Make sure we can restore one of the user's gids.
412     user_gids="$(id -G)"
413     last_gid="$(echo ${user_gids/* /})"
414     rm -rf src
415     WVPASS bup meta --edit --unset-group --set-gid "$last_gid" ../src.meta \
416         | WVPASS bup meta -x
417     WVPASS bup xstat src | WVPASS grep -qE "^gid: $last_gid"
418
419     # Test --numeric-ids (gid).
420     rm -rf src
421     current_gidx=$(bup meta -tvvf ../src.meta | grep -e '^gid:')
422     WVPASS bup meta --edit --set-group "$last_group" ../src.meta \
423         | WVPASS bup meta -x --numeric-ids
424     new_gidx=$(bup xstat src | grep -e '^gid:')
425     WVPASSEQ "$current_gidx" "$new_gidx"
426
427     # Test that restoring an unknown user works.
428     unknown_user=$("$TOP"/t/unknown-owner --user)
429     rm -rf src
430     current_uidx=$(bup meta -tvvf ../src.meta | grep -e '^uid:')
431     WVPASS bup meta --edit --set-user "$unknown_user" ../src.meta \
432         | WVPASS bup meta -x
433     new_uidx=$(bup xstat src | grep -e '^uid:')
434     WVPASSEQ "$current_uidx" "$new_uidx"
435
436     # Test that restoring an unknown group works.
437     unknown_group=$("$TOP"/t/unknown-owner --group)
438     rm -rf src
439     current_gidx=$(bup meta -tvvf ../src.meta | grep -e '^gid:')
440     WVPASS bup meta --edit --set-group "$unknown_group" ../src.meta \
441         | WVPASS bup meta -x
442     new_gidx=$(bup xstat src | grep -e '^gid:')
443     WVPASSEQ "$current_gidx" "$new_gidx"
444 )
445
446 # Test ownership restoration (when root or fakeroot).
447 (
448     if [ $(t/root-status) == none ]; then
449         exit 0
450     fi
451
452     WVSTART 'metadata (restoration of ownership as root)'
453     force-delete "$TOP/bupmeta.tmp"
454     mkdir "$TOP/bupmeta.tmp"
455     cd "$TOP/bupmeta.tmp"
456     touch src
457     chown 0:0 src # In case the parent dir is sgid, etc.
458     WVPASS bup meta -cf src.meta src
459
460     mkdir dest
461     chmod 700 dest # so we can't accidentally do something insecure
462     cd dest
463
464     other_uinfo="$(id-other-than --user "$(id -un)")"
465     other_user="${other_uinfo%%:*}"
466     other_uid="${other_uinfo##*:}"
467
468     other_ginfo="$(id-other-than --group "$(id -gn)")"
469     other_group="${other_ginfo%%:*}"
470     other_gid="${other_ginfo##*:}"
471
472     # Make sure we can restore a uid (must be in /etc/passwd b/c cygwin).
473     WVPASS bup meta --edit --unset-user --set-uid "$other_uid" ../src.meta \
474         | WVPASS bup meta -x
475     WVPASS bup xstat src | WVPASS grep -qE "^uid: $other_uid"
476
477     # Make sure we can restore a gid (must be in /etc/group b/c cygwin).
478     WVPASS bup meta --edit --unset-group --set-gid "$other_gid" ../src.meta \
479         | WVPASS bup meta -x
480     WVPASS bup xstat src | WVPASS grep -qE "^gid: $other_gid"
481
482     other_uinfo2="$(id-other-than --user "$(id -un)" "$other_user")"
483     other_user2="${other_uinfo2%%:*}"
484     other_uid2="${other_uinfo2##*:}"
485
486     other_ginfo2="$(id-other-than --group "$(id -gn)" "$other_group")"
487     other_group2="${other_ginfo2%%:*}"
488     other_gid2="${other_ginfo2##*:}"
489
490     # Try to restore a user (and see that user trumps uid when uid is not 0).
491     WVPASS bup meta --edit \
492         --set-uid "$other_uid2" --set-user "$some_user" ../src.meta \
493         | WVPASS bup meta -x
494     WVPASS bup xstat src | WVPASS grep -qE "^user: $some_user"
495
496     # Try to restore a group (and see that group trumps gid when gid is not 0).
497     WVPASS bup meta --edit \
498         --set-gid "$other_gid2" --set-group "$some_group" ../src.meta \
499         | WVPASS bup meta -x
500     WVPASS bup xstat src | WVPASS grep -qE "^group: $some_user"
501
502     # Test --numeric-ids (uid).  Note the name 'root' is not handled
503     # specially, so we use that here as the test user name.  We assume
504     # that the root user's uid is never 42.
505     rm -rf src
506     WVPASS bup meta --edit --set-user root --set-uid "$other_uid" ../src.meta \
507         | WVPASS bup meta -x --numeric-ids
508     new_uidx=$(bup xstat src | grep -e '^uid:')
509     WVPASSEQ "$new_uidx" "uid: $other_uid"
510
511     # Test --numeric-ids (gid).  Note the name 'root' is not handled
512     # specially, so we use that here as the test group name.  We
513     # assume that the root group's gid is never 42.
514     rm -rf src
515     WVPASS bup meta --edit --set-group root --set-gid "$other_gid" ../src.meta \
516         | WVPASS bup meta -x --numeric-ids
517     new_gidx=$(bup xstat src | grep -e '^gid:')
518     WVPASSEQ "$new_gidx" "gid: $other_gid"
519
520     # Test that restoring an unknown user works.
521     unknown_user=$("$TOP"/t/unknown-owners --user)
522     rm -rf src
523     WVPASS bup meta --edit \
524         --set-uid "$other_uid" --set-user "$unknown_user" ../src.meta \
525         | WVPASS bup meta -x
526     new_uidx=$(bup xstat src | grep -e '^uid:')
527     WVPASSEQ "$new_uidx" "uid: $other_uid"
528
529     # Test that restoring an unknown group works.
530     unknown_group=$("$TOP"/t/unknown-owners --group)
531     rm -rf src
532     WVPASS bup meta --edit \
533         --set-gid "$other_gid" --set-group "$unknown_group" ../src.meta \
534         | WVPASS bup meta -x
535     new_gidx=$(bup xstat src | grep -e '^gid:')
536     WVPASSEQ "$new_gidx" "gid: $other_gid"
537
538     if ! [[ $(uname) =~ CYGWIN ]]; then
539         # For now, skip these on Cygwin because it doesn't allow
540         # restoring an unknown uid/gid.
541
542         # Make sure a uid of 0 trumps a non-root user.
543         WVPASS bup meta --edit --set-user "$some_user" ../src.meta \
544             | WVPASS bup meta -x
545         WVPASS bup xstat src | WVPASS grep -qvE "^user: $some_user"
546         WVPASS bup xstat src | WVPASS grep -qE "^uid: 0"
547
548         # Make sure a gid of 0 trumps a non-root group.
549         WVPASS bup meta --edit --set-group "$some_user" ../src.meta \
550             | WVPASS bup meta -x
551         WVPASS bup xstat src | WVPASS grep -qvE "^group: $some_group"
552         WVPASS bup xstat src | WVPASS grep -qE "^gid: 0"
553     fi
554 )
555
556 # Root-only tests that require an FS with all the trimmings: ACLs,
557 # Linux attr, Linux xattr, etc.
558 if [ $(t/root-status) == root ]; then
559     (
560         set -e
561         # Some cleanup handled in universal-cleanup() above.
562         # These tests are only likely to work under Linux for now
563         # (patches welcome).
564         [[ $(uname) =~ Linux ]] || exit 0
565
566         WVSTART 'meta - general (as root)'
567         setup-test-tree
568         cd "$TOP/bupmeta.tmp"
569
570         umount testfs || true
571         dd if=/dev/zero of=testfs.img bs=1M count=32
572         mke2fs -F -j -m 0 testfs.img
573         mkdir testfs
574         mount -o loop,acl,user_xattr testfs.img testfs
575         # Hide, so that tests can't create risks.
576         chown root:root testfs
577         chmod 0700 testfs
578
579         umount testfs-limited || true
580         dd if=/dev/zero of=testfs-limited.img bs=1M count=32
581         mkfs -t vfat testfs-limited.img
582         mkdir testfs-limited
583         mount -o loop,uid=root,gid=root,umask=0077 \
584             testfs-limited.img testfs-limited
585
586         #cp -a src testfs/src
587         cp -pPR src testfs/src
588         (cd testfs && test-src-create-extract)
589
590         WVSTART 'meta - atime (as root)'
591         force-delete testfs/src
592         mkdir testfs/src
593         (
594             mkdir testfs/src/foo
595             touch testfs/src/bar
596             PYTHONPATH="$TOP/lib" \
597                 python -c "from bup import xstat; \
598                 x = xstat.timespec_to_nsecs((42, 0));\
599                    xstat.utime('testfs/src/foo', (x, x));\
600                    xstat.utime('testfs/src/bar', (x, x));"
601             cd testfs
602             WVPASS bup meta -v --create --recurse --file src.meta src
603             bup meta -tvf src.meta
604             # Test extract.
605             force-delete src-restore
606             mkdir src-restore
607             cd src-restore
608             WVPASS bup meta --extract --file ../src.meta
609             WVPASSEQ "$(bup xstat --include-fields=atime src/foo)" "atime: 42"
610             WVPASSEQ "$(bup xstat --include-fields=atime src/bar)" "atime: 42"
611             # Test start/finish extract.
612             force-delete src
613             WVPASS bup meta --start-extract --file ../src.meta
614             WVPASS test -d src
615             WVPASS bup meta --finish-extract --file ../src.meta
616             WVPASSEQ "$(bup xstat --include-fields=atime src/foo)" "atime: 42"
617             WVPASSEQ "$(bup xstat --include-fields=atime src/bar)" "atime: 42"
618         )
619
620         WVSTART 'meta - Linux attr (as root)'
621         force-delete testfs/src
622         mkdir testfs/src
623         (
624             touch testfs/src/foo
625             mkdir testfs/src/bar
626             chattr +acdeijstuADST testfs/src/foo
627             chattr +acdeijstuADST testfs/src/bar
628             (cd testfs && test-src-create-extract)
629             # Test restoration to a limited filesystem (vfat).
630             (
631                 WVPASS bup meta --create --recurse --file testfs/src.meta \
632                     testfs/src
633                 force-delete testfs-limited/src-restore
634                 mkdir testfs-limited/src-restore
635                 cd testfs-limited/src-restore
636                 WVFAIL bup meta --extract --file ../../testfs/src.meta 2>&1 \
637                     | WVPASS grep -e '^Linux chattr:' \
638                     | WVPASS python -c \
639                       'import sys; exit(not len(sys.stdin.readlines()) == 2)'
640             )
641         )
642
643         WVSTART 'meta - Linux xattr (as root)'
644         force-delete testfs/src
645         mkdir testfs/src
646         (
647             touch testfs/src/foo
648             mkdir testfs/src/bar
649             attr -s foo -V bar testfs/src/foo
650             attr -s foo -V bar testfs/src/bar
651             (cd testfs && test-src-create-extract)
652
653             # Test restoration to a limited filesystem (vfat).
654             (
655                 WVPASS bup meta --create --recurse --file testfs/src.meta \
656                     testfs/src
657                 force-delete testfs-limited/src-restore
658                 mkdir testfs-limited/src-restore
659                 cd testfs-limited/src-restore
660                 WVFAIL bup meta --extract --file ../../testfs/src.meta 2>&1 \
661                     | WVPASS grep -e '^xattr\.set:' \
662                     | WVPASS python -c \
663                       'import sys; exit(not len(sys.stdin.readlines()) == 2)'
664             )
665         )
666
667         WVSTART 'meta - POSIX.1e ACLs (as root)'
668         force-delete testfs/src
669         mkdir testfs/src
670         (
671             touch testfs/src/foo
672             mkdir testfs/src/bar
673             setfacl -m u:root:r testfs/src/foo
674             setfacl -m u:root:r testfs/src/bar
675             (cd testfs && test-src-create-extract)
676
677             # Test restoration to a limited filesystem (vfat).
678             (
679                 WVPASS bup meta --create --recurse --file testfs/src.meta \
680                     testfs/src
681                 force-delete testfs-limited/src-restore
682                 mkdir testfs-limited/src-restore
683                 cd testfs-limited/src-restore
684                 WVFAIL bup meta --extract --file ../../testfs/src.meta 2>&1 \
685                     | WVPASS grep -e '^POSIX1e ACL applyto:' \
686                     | WVPASS python -c \
687                       'import sys; exit(not len(sys.stdin.readlines()) == 2)'
688             )
689         )
690     )
691 fi
692
693 exit 0