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