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