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