--hardlink fix
[wimlib] / tests / test-imagex
1 #!/bin/sh
2
3 # This script does some sanity testing of the 'imagex' program.  It by no means
4 # tests every aspect of wimlib comprehensively.
5
6 # Assume an in-tree build.
7 set -e
8 cd tests
9
10 imagex() {
11         echo "imagex $@"
12         ../imagex $@
13 }
14 #diff() {
15         #echo "diff $@"
16         #/usr/bin/env diff $@
17 #}
18
19 #dd() {
20         #echo "dd $@"
21         #/usr/bin/env dd $@
22 #}
23 #stat() {
24         #echo "stat $@" 1>&2
25         #/usr/bin/env stat $@
26 #}
27 #cmp() {
28         #echo "cmp $@"
29         #/usr/bin/env cmp $@
30 #}
31
32 cleanup() {
33         if [ -d tmp ] && mountpoint tmp > /dev/null; then
34                 fusermount -u tmp > /dev/null;
35         fi
36         rm -rf dir* tmp* *.wim *.swm
37 }
38 trap cleanup exit
39
40 # Make test directory
41 mkdir dir
42 cp ../src/*.c ../src/*.h dir
43 mkdir dir/subdir
44 echo 'hello' > dir/subdir/hello
45 echo 'hello' > dir/subdir/hello2
46 ln dir/subdir/hello dir/subdir/hellolink
47 echo -n > dir/subdir/empty_file
48 ln -s hello dir/subdir/rel_symlink
49
50 mkdir dir2
51 echo 'testing' > dir2/file
52 dd if=/dev/zero of=dir2/zeroes bs=4096 count=5
53
54 error() {
55         echo "**********************************************"
56         echo "                  Test failure                "
57         echo $*
58         echo "**********************************************"
59         exit 1
60 }
61
62 # Capturing and applying WIM with None, LZX, and XPRESS compression
63
64 for comp_type in None LZX XPRESS; do
65         echo "Testing capture and application of $comp_type-compressed WIM"
66         if ! imagex capture dir dir.wim --compress=$comp_type; then
67                 error "'imagex capture' failed"
68         fi
69         if ! imagex apply dir.wim tmp; then
70                 error "'imagex apply' failed"
71         fi
72         if ! test "`imagex info dir.wim | grep Compression | awk '{print $2}'`" = "$comp_type"; then
73                 error "'imagex info' didn't report the compression type correctly"
74         fi
75         if ! diff -q -r dir tmp; then
76                 error "Recursive diff of extracted directory with original failed"
77         fi
78         if ! test `stat -c %h tmp/subdir/hello` = 2; then
79                 error "Incorrect number of hard links in extracted file"
80         fi
81         if ! test `stat -c %i tmp/subdir/hello` != `stat -c %i tmp/subdir/hello2`; then
82                 error "Expected different inode numbers in files not hard-linked"
83         fi
84         if ! test "`stat -c %i tmp/subdir/hello`" = "`stat -c %i tmp/subdir/hellolink`"; then
85                 error "Expected same inode numbers in hard-linked files"
86         fi
87         if ! test -L tmp/subdir/rel_symlink; then
88                 error "Symlink not extracted correctly"
89         fi
90         if ! test "`readlink tmp/subdir/rel_symlink`" = "hello"; then
91                 error "Symlink target not correct"
92         fi
93         
94         rm -rf dir.wim tmp
95 done
96
97 # Capturing and modifying name, description, and bootable flag
98
99 echo "Testing capture of WIM with default name and description"
100 imagex capture dir dir.wim
101 if ! test "`imagex info dir.wim | grep Name | awk '{print $2}'`" = "dir"; then
102         error "WIM name not set correctly"
103 fi
104 if ! test "`imagex info dir.wim | grep Description | awk '{print $2}'`" = ""; then
105         error "WIM description not set correctly"
106 fi
107
108 echo "Testing capture of WIM with default boot flag"
109 imagex capture dir dir.wim
110 if ! test "`imagex info dir.wim | grep Boot | awk '{print $3}'`" = "0"; then
111         error "WIM boot flag not set correctly"
112 fi
113
114 echo "Testing changing image bootable flag"
115 if ! imagex info dir.wim 1 --boot; then
116         error "Failed to change bootable image"
117 fi
118 if ! test "`imagex info dir.wim | grep Boot | awk '{print $3}'`" = "1"; then
119         error "Bootable image not changed correctly"
120 fi
121 echo "Testing changing image bootable flag"
122 if ! imagex info dir.wim 0 --boot; then
123         error "Failed to reset bootable image"
124 fi
125 if ! test "`imagex info dir.wim | grep Boot | awk '{print $3}'`" = "0"; then
126         error "Bootable image not reset correctly"
127 fi
128 echo "Testing changing image bootable flag to invalid image (this should generate errors)"
129 if imagex info dir.wim 2 --boot; then
130         error "Succeeded in changing bootable image to invalid number"
131 fi
132 if ! test "`imagex info dir.wim | grep Boot | awk '{print $3}'`" = "0"; then
133         error "Boot flag was changed even though the change command was supposed to fail"
134 fi
135 rm -rf dir.wim tmp
136
137 echo "Testing capture of WIM with name and description"
138 if ! imagex capture dir dir.wim "myname" "mydesc"; then
139         error "Failed to capture WIM with specified name and description"
140 fi
141 if ! test "`imagex info dir.wim | grep Name | awk '{print $2}'`" = "myname"; then
142         error "WIM name not set correctly"
143 fi
144 if ! test "`imagex info dir.wim | grep Description | awk '{print $2}'`" = "mydesc"; then
145         error "WIM name not set correctly"
146 fi
147 echo "Testing printing WIM lookup table"
148 if ! imagex info --lookup-table dir.wim > /dev/null; then
149         error "Failed to print WIM lookup table"
150 fi
151 echo "Testing printing WIM header"
152 if ! imagex info --header dir.wim > /dev/null; then
153         error "Failed to print WIM header"
154 fi
155 echo "Testing printing WIM XML info"
156 if ! imagex info --xml dir.wim > /dev/null; then
157         error "Failed to print WIM XML data"
158 fi
159 echo "Testing extracting WIM XML info"
160 if ! imagex info --extract-xml=dir.xml dir.wim; then
161         error "Failed to extract WIM XML data"
162 fi
163 echo "Testing printing WIM metadata"
164 if ! imagex info --metadata dir.wim > /dev/null; then
165         error "Failed to print WIM metadata"
166 fi
167 rm -rf dir.wim tmp dir.xml
168
169 echo "Testing capture of bootable WIM"
170 if ! imagex capture dir dir.wim --boot; then
171         error "Failed to capture bootable WIM"
172 fi
173 if ! test "`imagex info dir.wim | grep Boot | awk '{print $3}'`" = "1"; then
174         error "Boot flag on bootable WIM not set correctly"
175 fi
176 rm -rf dir.wim tmp
177
178 # Integrity table
179
180 echo "Testing capture of WIM with integrity table"
181 if ! imagex capture dir dir.wim --check; then
182         error "Failed to capture WIM with integrity table"
183 fi
184 if ! test "`imagex info dir.wim | grep Integrity | awk '{print $3}'`" = "yes"; then
185         error "Integrity table on WIM not made"
186 fi
187 if ! imagex apply --check dir.wim tmp; then
188         error "Integrity table on WIM not made correctly"
189 fi
190 if ! diff -q -r dir tmp; then
191         error "Recursive diff of applied WIM with original directory failed"
192 fi
193 rm -rf dir.wim tmp
194
195 # Appending and deleting images
196
197 echo "Testing appending WIM image"
198 imagex capture dir dir.wim
199 if ! imagex append dir2 dir.wim; then
200         error "Appending WIM image failed"
201 fi
202 if ! test "`imagex info dir.wim | grep 'Image Count' | awk '{print $3}'`" = 2; then
203         error "WIM image count not correct"
204 fi
205
206 echo "Testing appending WIM image with existing name (this should generate errors)"
207 if imagex append dir2 dir.wim; then
208         error "Adding duplicate image name didn't fail"
209 fi
210 echo "Testing appending WIM image with new name"
211 if ! imagex append dir2 dir.wim "newname"; then
212         error "Appending WIM image failed"
213 fi
214 echo "Testing appending WIM image with integrity check"
215 if ! imagex append dir2 dir.wim "newname2" --check; then
216         error "Appending WIM image failed"
217 fi
218 if ! test "`imagex info dir.wim | grep Integrity | awk '{print $3}'`" = "yes"; then
219         error "Integrity table not set correctly on image append"
220 fi
221 echo "Testing appending WIM image with no integrity check"
222 if ! imagex append dir2 dir.wim "newname3"; then
223         error "Appending WIM image failed"
224 fi
225 if ! test "`imagex info dir.wim | grep Integrity | awk '{print $3}'`" = "no"; then
226         error "WIM integrity table not removed"
227 fi
228 # 5 images at this point
229 if ! test "`imagex info dir.wim | grep 'Image Count' | awk '{print $3}'`" = 5; then
230         error "WIM does not contain the expected 5 images"
231 fi
232 echo "Testing deleting first WIM image"
233 if ! imagex delete dir.wim 1; then
234         error "Failed to delete WIM image"
235 fi
236 if ! test "`imagex info dir.wim | grep 'Image Count' | awk '{print $3}'`" = 4; then
237         error "WIM image not deleted correctly"
238 fi
239 echo "Testing deleting last WIM image"
240 if ! imagex delete dir.wim 4; then
241         error "Failed to delete WIM image"
242 fi
243 if ! test "`imagex info dir.wim | grep 'Image Count' | awk '{print $3}'`" = 3; then
244         error "WIM image not deleted correctly"
245 fi
246 echo "Testing deleting invalid WIM image (this should generate errors)"
247 if imagex delete dir.wim 4; then
248         error "Expected to fail to delete non-existent WIM image"
249 fi
250 if ! test "`imagex info dir.wim | grep 'Image Count' | awk '{print $3}'`" = 3; then
251         error "Image count changed even though we intentionally failed to delete an image"
252 fi
253 echo "Testing deleting all WIM images"
254 if ! imagex delete dir.wim all; then
255         error "Failed to delete all images from WIM"
256 fi
257 if ! test "`imagex info dir.wim | grep 'Image Count' | awk '{print $3}'`" = 0; then
258         error "Couldn't delete all WIM images correctly"
259 fi
260 echo "Testing appending directory to empty WIM and making it bootable"
261 if ! imagex append dir dir.wim "myname" "mydesc" --check --boot; then
262         error "Couldn't append named, described, bootable image to empty WIM with integrity check"
263 fi
264 if ! test "`imagex info dir.wim | grep Integrity | awk '{print $3}'`" = "yes"; then
265         error "Integrity check not found"
266 fi
267 if ! test "`imagex info dir.wim | grep Boot | awk '{print $3}'`" = "1"; then
268         error "Bootable image not set correctly"
269 fi
270 echo "Testing appending non-directory (should generate errors)"
271 if imagex append dir.wim dir.wim; then
272         error "Incorrectly succeeded to append non-directory to WIM"
273 fi
274 echo "Testing appending non-existent file (should generate errors)"
275 if imagex append SOME_NONEXISTENT_FILE dir.wim; then
276         error "Incorrectly succeeded to append non-existent file to WIM"
277 fi
278 echo "Testing appending directory containing unreadable file (should generate errors)"
279 mkdir -p dir3
280 touch dir3/file
281 chmod -r dir3/file
282 if imagex append dir3 dir.wim; then
283         error "Incorrectly succeeded in capturing directory with unreadable file"
284 fi
285 rm -rf dir3 dir.wim
286
287 # Applying multiple images, applying with hardlinks/symlinks
288
289 echo "Testing application of multiple images"
290 if ! imagex capture dir dir.wim; then
291         error "Failed to prepare test WIM"
292 fi
293 if ! imagex append dir dir.wim "myname"; then
294         error "Failed to append image to test WIM"
295 fi
296 if ! imagex apply dir.wim all tmp; then
297         error "Applying multiple images failed"
298 fi
299 if ! diff -q -r tmp/dir tmp/myname || ! diff -q -r dir tmp/dir; then
300         error "Recursive diff of applied WIM with original directory failed"
301 fi
302 if test "`stat -c %h tmp/dir/lz.c`" != 1; then
303         error "Incorrect link count on extracted file"
304 fi
305 if test "`stat -c %h tmp/myname/lz.c`" != 1; then
306         error "Incorrect link count on extracted file"
307 fi
308 if test "`stat -c %i tmp/myname/lz.c`" = "`stat -c %i tmp/dir/lz.c`"; then
309         error "Incorrect inode number"
310 fi
311 rm -rf tmp
312 echo "Testing application of multiple images with hardlinks"
313 if ! imagex apply dir.wim all tmp --hardlink; then
314         error "Failed to apply multiple images with cross-image hardlinks"
315 fi
316 if ! diff -q -r tmp/dir tmp/myname || ! diff -q -r dir tmp/dir; then
317         error "Recursive diff of applied WIM with original directory failed"
318 fi
319 if test "`stat -c %h tmp/dir/lz.c`" != 2; then
320         error "Incorrect link count on extracted file"
321 fi
322 if test "`stat -c %h tmp/myname/lz.c`" != 2; then
323         error "Incorrect link count on extracted file"
324 fi
325 if test "`stat -c %i tmp/myname/lz.c`" != "`stat -c %i tmp/dir/lz.c`"; then
326         error "Incorrect inode number"
327 fi
328 rm -rf tmp
329
330 echo "Testing application of single image containing identical files"
331 if ! imagex apply dir.wim 1 tmp; then
332         error "Failed to apply WIM"
333 fi
334 if test "`stat -c %h tmp/subdir/hello`" != 2; then
335         error "Incorrect link count on extracted file"
336 fi
337 if test "`stat -c %h tmp/subdir/hello2`" != 1; then
338         error "Incorrect link count on extracted file"
339 fi
340 if test "`stat -c %i tmp/subdir/hello`" = "`stat -c %i tmp/subdir/hello2`"; then
341         error "Inode numbers on non-hard-linked files are the same"
342 fi
343 if test "`stat -c %i tmp/subdir/hello`" != "`stat -c %i tmp/subdir/hellolink`"; then
344         error "Inode numbers on hard-linked files are different"
345 fi
346 rm -rf tmp
347
348 echo "Testing application of single image containing identical files with hardlinks"
349 if ! imagex apply dir.wim 1 tmp --hardlink; then
350         error "Failed to apply WIM"
351 fi
352 if test "`stat -c %h tmp/subdir/hello`" != 3; then
353         error "Incorrect link count on extracted file"
354 fi
355 if test "`stat -c %h tmp/subdir/hello2`" != 3; then
356         error "Incorrect link count on extracted file"
357 fi
358 if test "`stat -c %i tmp/subdir/hello`" != "`stat -c %i tmp/subdir/hello2`"; then
359         error "Hard link set does not share inode number"
360 fi
361 if test "`stat -c %i tmp/subdir/hello`" != "`stat -c %i tmp/subdir/hellolink`"; then
362         error "Hard link set does not share inode number"
363 fi
364 rm -rf tmp
365
366 echo "Testing application of single image containing identical files with symlinks"
367 if ! imagex apply dir.wim 1 tmp --symlink; then
368         error "Failed to apply WIM"
369 fi
370 if test "`stat -c %h tmp/subdir/hello`" != 1; then
371         error "Incorrect link count on extracted file"
372 fi
373 if test "`stat -c %h tmp/subdir/hello2`" != 1; then
374         error "Incorrect link count on extracted file"
375 fi
376 if test "`stat -c %i tmp/subdir/hello`" = "`stat -c %i tmp/subdir/hello2`"; then
377         error "Incorrect inode number"
378 fi
379 if ! test -L tmp/subdir/hello || ! test -L tmp/subdir/hello2; then
380         error "Expected symlinks, but found non-symlinks"
381 fi
382 rm -rf dir.wim tmp
383
384 # imagex mount
385
386 for flag in "--compress=none" "--compress=maximum" "--compress=fast"; do
387         echo "Using flag $flag"
388         echo "Testing mounting WIM read-only"
389         if ! imagex capture dir dir.wim $flag; then
390                 error "Failed to capture WIM"
391         fi
392         mkdir tmp
393         if ! imagex mount dir.wim dir tmp; then
394                 error "Failde to mount test WIM read-only"
395         fi
396         echo "Testing extracting file from mounted read-only WIM"
397         if ! cp tmp/lz.c lz.c; then
398                 error "Failed to extract file from read-only mounted WIM"
399         fi
400         if ! diff -q dir/lz.c lz.c; then
401                 error "Extracted file does not match copy in mounted WIM"
402         fi
403         if ! diff -q tmp/lz.c dir/lz.c; then
404                 error "Extractef file does not match original"
405         fi
406         rm -f lz.c
407         echo "Testing modifying mounted read-only WIM (should fail)"
408         if rm tmp/lz.c; then
409                 error "Removing file from read-only mounted WIM didn't fail"
410         fi
411         if touch tmp/newfile; then
412                 error "Creating file on read-only mounted WIM didn't fail"
413         fi
414         if echo 3 > tmp/lz.c; then
415                 error "Writing to file on read-only mounted WIM didn't fail"
416         fi
417         echo "Testing diff of mounted read-only WIM with original directory"
418         if ! diff -q -r tmp dir; then
419                 error "Recursive diff of read-only mounted WIM with original directory failed"
420         fi
421         echo "Testing unmount of read-only filesystem"
422         if ! imagex unmount tmp; then
423                 error "Unmounting read-only WIM failed"
424         fi
425         echo "Testing unmount of read-only filesystem with --commit given"
426         if ! imagex mount dir.wim dir tmp; then
427                 error "Failed to re-mount WIM read-only"
428         fi
429         if ! imagex unmount tmp --commit; then
430                 error "Failed to unmount read-only WIM with --commit flag (should be ignored)"
431         fi
432         rm -rf tmp dir.wim
433 done
434
435 # imagex mountrw
436 echo "Testing mounting WIM read-write"
437 if ! imagex capture dir dir.wim; then
438         error "Failed to capture WIM"
439 fi
440 mkdir tmp
441 if ! imagex mountrw dir.wim dir tmp; then
442         error "Failed to mount test WIM read-write"
443 fi
444 echo "Testing unmounting WIM unmodified"
445 if ! imagex unmount tmp; then
446         error "Failed to unmount test WIM unmodified"
447 fi
448 echo "Testing unmounting WIM unmodified with --commit and --check"
449 if ! imagex mountrw dir.wim dir tmp; then
450         error "Failed to re-mount test WIM read-write"
451 fi
452 if ! imagex unmount tmp --commit --check; then
453         error "Failed to unmount read-write mounted WIM with changes commited (no changes made)"
454 fi
455 echo "Testing removing file from mounted WIM"
456 if ! imagex mountrw dir.wim dir tmp; then
457         error "Failed to re-mount test WIM read-write"
458 fi
459 if ! rm tmp/lz.c; then
460         error "Failed to remove file from read-write mounted WIM"
461 fi
462 if test -f tmp/lz.c; then
463         error "Removing file from read-write mounted WIM failed"
464 fi
465 echo "Testing making directory in mounted WIM"
466 if ! mkdir tmp/newdir; then
467         error "Failed to make directory in read-write mounted WIM"
468 fi
469 if ! test -d tmp/newdir; then
470         error "Making directory in read-write mounted WIM failed"
471 fi
472 echo "Testing making new empty file in mounted WIM"
473 if ! touch tmp/newdir/empty_file; then
474         error "Could not create new empty file in read-write mounted WIM"
475 fi
476 if ! test -f tmp/newdir/empty_file; then
477         error "New empty file not created correctly in read-write mounted WIM"
478 fi
479 if ! test "`stat -c %s tmp/newdir/empty_file`" = 0; then
480         error "New empty file in read-write mounted WIM is not empty"
481 fi
482 echo "Testing making new non-empty file in mounted WIM"
483 if ! dd if=/dev/zero of=tmp/newdir/zeroes1 bs=1 count=4096; then
484         error "Failed to make new non-empty file in mounted WIM"
485 fi
486 if ! dd if=/dev/zero of=tmp/newdir/zeroes2 bs=4096 count=1; then
487         error "Failed to make new non-empty file in mounted WIM"
488 fi
489 if ! diff -q tmp/newdir/zeroes1 tmp/newdir/zeroes2; then
490         error "New files in mounted WIM not made correctly"
491 fi
492 echo "Unmounting WIM with changes committed and --check"
493 if ! imagex unmount tmp --commit --check; then
494         error "Failed to unmount read-write mounted WIM"
495 fi
496 if test "`imagex info dir.wim | grep Integrity | awk '{print $3}'`" != "yes"; then
497         error "Integrity information was not included"
498 fi
499 rm -rf tmp
500 if ! imagex apply dir.wim tmp; then
501         error "Failed to apply WIM we had previously mounted read-write"
502 fi
503 if ! diff -q tmp/newdir/zeroes1 tmp/newdir/zeroes2; then
504         error "The new non-empty files we made in the read-write mounted WIM were not extracted correctly"
505 fi
506 if test `stat -c %s tmp/newdir/empty_file` != 0; then
507         error "The new empty file we made in the read-write mounted WIM was not extracted correctly"
508 fi
509 if test `stat -c %s tmp/newdir/zeroes1` != 4096; then
510         error "The new non-empty files we made in the read-write mounted WIM were not extracted correctly"
511 fi
512 rm -rf tmp dir.wim
513
514 # imagex split, imagex join
515
516 echo "Creating random files to test WIM splitting on"
517 mkdir tmp
518 for i in `seq 1 100`; do
519         dd if=/dev/urandom of=tmp/file$i bs=4096 count=10 &> /dev/null
520 done
521 for flag in "--compress=none" "--compress=maximum" "--compress=fast"; do
522         echo "Using flag $flag"
523         if ! imagex capture tmp tmp.wim $flag; then
524                 error "Failed to capture test WIM"
525         fi
526         echo "Splitting WIM into 1 MiB chunks"
527         if ! imagex split tmp.wim tmp.swm 1; then
528                 error "Failed to split WIM"
529         fi
530         echo "Verifying the split WIMs (some errors expected)"
531         if test "`imagex info tmp.swm | grep 'Part Number' | awk '{print $3}'`" != "1/4"; then
532                 error "Part number of split WIM not correct"
533         fi
534         if ! imagex dir tmp.swm > /dev/null; then
535                 error "Failed to list files in split WIM"
536         fi
537         if ! test -e tmp2.swm; then
538                 error "Could not find split-WIM part 2"
539         fi
540         if imagex dir tmp2.swm > /dev/null; then
541                 error "Listed files in part 2 of split WIM (this should have failed)"
542         fi
543
544         # Unsupported, should fail
545         if imagex info tmp.swm --boot 0; then
546                 error "Should not have been able to change boot index of split WIM"
547         fi
548         echo "Joining the split WIMs and applying the result"
549         if ! imagex join tmp2.wim tmp*.wim; then
550                 error "Failed to join split WIMs"
551         fi
552         if ! imagex apply tmp2.wim tmp2; then
553                 error "Failed to apply joined split WIM"
554         fi
555         if ! imagex apply tmp.wim tmp3; then
556                 error "Failed to apply test WIM"
557         fi
558         if ! diff -q -r tmp tmp2 || ! diff -q -r tmp tmp3; then
559                 error "Recursive diff of applied joined split WIM with original directory failed"
560         fi
561         rm -f *.wim *.swm
562         rm -rf tmp2 tmp3
563 done
564 rm -rf tmp
565
566 # imagex export
567 echo "Testing export of single image to new WIM"
568 imagex capture dir dir.wim
569 imagex append dir2 dir.wim
570 imagex export dir.wim dir new.wim
571 test "`imagex info new.wim | grep 'Image Count' | awk '{print $3}'`" = 1;
572 echo "Testing export of single image to existing WIM"
573 imagex export dir.wim dir2 new.wim
574 test "`imagex info new.wim | grep 'Image Count' | awk '{print $3}'`" = 2;
575 echo "Testing export of single image to existing WIM using wrong compression type"
576 ! imagex export dir.wim dir2 new.wim newname --compress=maximum
577 rm -f new.wim
578 echo "Testing export of multiple images to new WIM"
579 imagex export dir.wim all new.wim
580 test "`imagex info new.wim | grep 'Image Count' | awk '{print $3}'`" = 2;
581 imagex capture dir2 new.wim newname
582 echo "Testing export of multiple images to existing WIM"
583 imagex export dir.wim all new.wim
584 echo "Testing export of multiple images to existing WIM with --boot"
585 imagex capture dir2 new.wim newname
586 imagex info dir.wim --boot 1
587 imagex export dir.wim all new.wim --boot
588 echo "Testing export of multiple images to existing WIM with --boot, but no bootable image (errors expected)"
589 imagex capture dir2 new.wim newname
590 imagex info dir.wim --boot 0
591 ! imagex export dir.wim all new.wim --boot