]> wimlib.net Git - wimlib/blob - tests/test-imagex-capture_and_apply
v1.14.4
[wimlib] / tests / test-imagex-capture_and_apply
1 #!/usr/bin/env bash
2
3 # Test capturing and applying a WIM image in the normal (non-NTFS) capture mode
4 #
5 # Add in some tests with WIM splitting, joining, and exporting as well.
6 #
7 # Test all three compression modes (None, XPRESS, and LZX).
8 #
9 # Also, test if the capture configuration file works correctly.
10
11 set -e
12 cd tests
13 srcdir="${srcdir:-.}/.."
14 srcdir="$(cd $srcdir; pwd)"
15 . "$srcdir/tests/test_utils.sh"
16
17 TEST_SUBDIR=tmpdir_test-imagex-capture_and_apply
18
19 do_tree_cmp() {
20         if ! ../tree-cmp in.dir out.dir; then
21                 if [ -x /usr/bin/tree ]; then
22                         echo "Dumping tree of applied image"
23                         echo "(Note: compression type was $ctype)"
24                         tree out.dir --inodes -F -s --noreport
25                         error 'Information was lost or corrupted while capturing
26                                 and then applying a directory tree'
27                 fi
28         fi
29 }
30
31 image_name=0
32 do_test() {
33         for ctype in None XPRESS LZX; do
34
35                 # Can we capture the WIM, apply it, and get the same result?
36                 cd in.dir
37                 eval "$1"
38                 cd ..
39                 if [ -x /usr/bin/tree -a "$ctype" = "None" ]; then
40                         tree in.dir --inodes -F -s --noreport
41                 fi
42                 if ! wimcapture in.dir test.wim --compress=$ctype --norpfix; then
43                         error "Failed to capture directory tree into a WIM"
44                 fi
45                 if ! wimapply test.wim 1 out.dir; then
46                         error "Failed to apply WIM to directory"
47                 fi
48                 if [ `wim_ctype test.wim` != $ctype ]; then
49                         error "'wiminfo' didn't report the compression type on the captured WIM correctly"
50                 fi
51                 do_tree_cmp
52                 rm -rf out.dir/*
53
54                 # Can we split the WIM, apply the split WIM, join the split WIM,
55                 # and apply the joined WIM, and get the same results every time?
56                 #
57                 # LC_ALL=C avoids locale-dependent floating point number
58                 # parsing.
59                 if ! LC_ALL=C wimsplit test.wim test.swm 0.01; then
60                         error "Failed to split WIM"
61                 fi
62                 if ! wimapply test.swm 1 out.dir --ref "test*.swm" ; then
63                         error "Failed to apply split WIM"
64                 fi
65                 do_tree_cmp
66                 rm -rf out.dir/* test.wim
67                 if ! wimjoin test.wim test*.swm; then
68                         error "Failed to join split WIM"
69                 fi
70                 if ! wimapply test.wim out.dir; then
71                         error "Failed to apply joined WIM"
72                 fi
73                 do_tree_cmp
74                 rm -rf out.dir/*
75
76                 # Can we export the image to another WIM, apply it, and get the
77                 # same results?
78                 (( image_name++ )) || true
79                 if ! wimexport test.wim 1 test2.wim "$image_name"; then
80                         error "Failed to export WIM image"
81                 fi
82
83                 if ! wimapply test2.wim "$image_name" out.dir; then
84                         error "Failed to apply exported WIM image"
85                 fi
86                 do_tree_cmp
87                 rm -rf out.dir/*
88
89                 # Try pipable WIM (don't bother testing all compression types
90                 # though, it shouldn't make a difference).
91                 if [ "$ctype" = "None" ]; then
92                         # Capture pipable WIM (not writing to pipe)
93                         if ! wimcapture in.dir test.wim \
94                                         --compress=$ctype --norpfix --pipable; then
95                                 error "Failed to capture directory tree into a pipable WIM"
96                         fi
97
98                         # Apply pipable WIM (reading from pipe)
99                         if ! cat test.wim | wimapply - 1 out.dir; then
100                                 error "Failed to apply pipable WIM to directory (from pipe)"
101                         fi
102                         do_tree_cmp
103                         rm -rf out.dir/*
104
105                         # Apply pipable WIM (not reading from pipe)
106                         if ! wimapply test.wim 1 out.dir; then
107                                 error "Failed to apply pipable WIM to directory (not from pipe)"
108                         fi
109                         do_tree_cmp
110                         rm -rf out.dir/*
111
112                         # Capture pipable WIM (writing to pipe) and read pipable
113                         # WIM (reading from pipe)
114                         if ! wimlib_imagex capture --pipable --compress=$ctype \
115                                                 --norpfix --pipable         \
116                                             in.dir - | wimapply - 1 out.dir; then
117                                 error "Failed to capture directory tree into a pipable WIM"
118                         fi
119                         do_tree_cmp
120                         rm -rf out.dir/*
121                 fi
122
123                 rm -rf out.dir/* in.dir/* test.wim test*.swm
124
125         done
126 }
127
128 __msg() {
129         echo "--------------------------------------------------------------------"
130         echo $1
131         echo "--------------------------------------------------------------------"
132 }
133
134 msg() {
135         __msg "Testing image capture and application of directory containing $1"
136 }
137
138 default_cleanup
139 mkdir $TEST_SUBDIR
140 cd $TEST_SUBDIR
141 mkdir in.dir out.dir
142
143 . $srcdir/tests/common_tests.sh
144
145 # Test the data recovery mode
146 __msg "Testing data recovery mode"
147 for file in corrupted_file_1.wim corrupted_file_2.wim; do
148         rm -rf out.dir
149         wimapply $srcdir/tests/wims/$file 1 out.dir 2>/dev/null && \
150                 error "Applying $file in default mode unexpectedly succeeded"
151         rm -rf out.dir
152         wimapply --recover-data $srcdir/tests/wims/$file 1 out.dir || \
153                 error "Applying $file in data recovery mode unexpectedly failed"
154         if [ ! -e out.dir/file ]; then
155                 error "Recovered file not found"
156         fi
157 done
158
159 # Make sure exclusion list works
160 __msg "Testing default capture configuration file"
161 touch in.dir/hiberfil.sys
162 mkdir -p "in.dir/System Volume Information/subdir"
163 wimcapture in.dir test.wim
164 wimapply test.wim out.dir
165 if [ -e out.dir/hiberfil.sys -o -e "out.dir/System Volume Information" ]; then
166         error "Files were not excluded from capture as expected"
167 fi
168
169 #
170 # Execute one of the exclusion list test cases in tests/exclusionlists/.
171 # The file is divided into two sections, separated by a line containing "@@@".
172 # The first is the capture configuration file.  The second is a list of files
173 # and directories, where the ones that should be excluded are marked with "- ".
174 #
175 exclusionlist_test() {
176         local t_file="$1"
177         local in_paths_section=false
178         local path
179         local include
180
181         __msg "Testing exclusion list: ${t_file##*/}"
182
183         echo "/" > expected_out
184         sed -n -e '/^@@@/q;p' "$t_file" > config.txt
185         rm -rf in.dir
186         mkdir in.dir
187         cd in.dir
188         while read -r path; do
189                 path="$(echo "$path" | sed -e 's/[[:space:]]*$//')"
190                 if ! $in_paths_section; then
191                         if [ "$path" = "# case insensitive" ]; then
192                                 export WIMLIB_IMAGEX_IGNORE_CASE=1
193                         elif [ "$path" = "@@@" ]; then
194                                 in_paths_section=true
195                         fi
196                         continue
197                 fi
198                 if [ -z "$path" ]; then
199                         continue
200                 fi
201                 include=true
202                 if [ "${path:0:2}" = "- " ]; then
203                         include=false
204                         path="${path:2}"
205                 fi
206                 if [ "${path: -1}" = "/" ]; then
207                         path="${path:0:$(( ${#path} - 1))}"
208                         mkdir "$path"
209                 else
210                         touch "$path"
211                 fi
212                 if $include; then
213                         echo "/$path" >> ../expected_out
214                 fi
215         done < "$t_file"
216         cd ..
217         $in_paths_section || error "malformed test file: $t_file (never found separator)"
218         wimcapture in.dir test.wim --compress=none --config=config.txt
219         unset WIMLIB_IMAGEX_IGNORE_CASE
220         wimdir test.wim 1 > actual_out
221         diff expected_out actual_out
222 }
223
224 macOS=false
225 if [ "$(uname)" = Darwin ]; then
226         macOS=true
227 fi
228 for t_file in "$srcdir/tests/exclusionlists"/*; do
229         if $macOS && [[ $t_file == */case_*sensitive ]]; then
230                 # Exclude test cases that fail on case-insensitive filesystem
231                 continue
232         fi
233         exclusionlist_test "$t_file"
234 done
235
236 # Make sure reparse point fixups are working as expected
237 __msg "Testing --rpfix"
238 rm -r in.dir out.dir
239 mkdir in.dir
240 ln -s $PWD/in.dir          in.dir/absrootlink
241 ln -s $PWD/in.dir////      in.dir/absrootlinkslashes
242 ln -s /___NONEXISTENT___   in.dir/absnonexistent
243 ln -s /usr/bin/env         in.dir/absoutoftree
244 ln -s file                 in.dir/relalink
245 ln -s $PWD/in.dir/file     in.dir/abslink
246 ln -s $PWD/in.dir/file///  in.dir/abslinkslashes
247 wimcapture --rpfix in.dir test.wim
248 wimapply --norpfix test.wim out.dir
249 if [[ `readlink out.dir/absrootlink` != "/" ]] ||
250    [[ `readlink out.dir/absrootlinkslashes` != "////" ]]; then
251         error "wimcapture --rpfix failed to fix absolute link to capture root"
252 fi
253
254 if [[ ! -L out.dir/absnonexistent ]] ||
255    [[ ! -L out.dir/absoutoftree ]]; then
256         error "wimcapture --rpfix failed to also capture out of tree absolute links"
257 fi
258 if [[ `readlink out.dir/relalink` != "file" ]]; then
259         error "wimcapture --rpfix failed to capture relative symlink"
260 fi
261 if [[ `readlink out.dir/abslink` != "/file" ]] ||
262    [[ `readlink out.dir/abslinkslashes` != "/file///" ]]; then
263         error "wimcapture --rpfix did fix absolute link properly"
264 fi
265 rm -rf out.dir
266
267 wimapply test.wim out.dir
268 if [[ $(get_inode_number $(readlink out.dir/absrootlink)) != \
269         $(get_inode_number out.dir) ]];
270 then
271         error "wimapply failed to apply fixed absolute symlinks"
272 fi
273
274 # Make sure source list mode is working as expected
275 __msg "Testing source list capture mode"
276 rm -rf in.dir out.dir
277 mkdir in.dir
278 echo 1 > in.dir/1
279 ln in.dir/1 in.dir/1link
280 echo 5 > 5
281 mkdir otherdir
282 cp $srcdir/src/add_image.c otherdir
283 cat > srclist << EOF
284 in.dir /
285 5      /5
286 otherdir /otherdir
287 EOF
288 wimcapture srclist --source-list test.wim
289 wimapply test.wim out.dir
290 if [[ ! -f out.dir/5 || ! -f out.dir/1 || ! -f out.dir/1link || \
291       ! -d out.dir/otherdir ]]; then
292         error "source list capture failed to work as expected"
293 fi
294
295 # Still testing source list capture: add quoted name, and try overlay
296 rm -rf out.dir
297 cat > srclist << EOF
298 in.dir /
299 5      /5
300 otherdir /otherdir
301  "overlay dir 1"                'otherdir'      
302  "overlay dir 2"                'otherdir'  
303 EOF
304 mkdir "overlay dir 1"
305 mkdir "overlay dir 2"
306 echo A > "overlay dir 1"/A
307 echo B > "overlay dir 2"/B
308 wimcapture srclist --source-list test.wim
309 wimapply test.wim out.dir
310 if [[ ! -f out.dir/5 || ! -f out.dir/1 || ! -f out.dir/1link || \
311       ! -f out.dir/otherdir/A || ! -f out.dir/otherdir/B ]]; then
312         error "source list capture (with quoted names and basic overlay) failed to work as expected"
313 fi
314
315 # Try deep overlay
316 rm -rf in.dir out.dir "overlay dir 1" "overlay dir 2"
317 mkdir -p in.dir.1/subdir/subdir2 in.dir.2/subdir/subdir2
318 cat > srclist << EOF
319 in.dir.1        /
320 in.dir.2        /
321 EOF
322 echo 1 > in.dir.1/subdir/1
323 echo 2 > in.dir.2/subdir/2
324 echo 3 > in.dir.1/subdir/subdir2/3
325 echo 4 > in.dir.2/subdir/subdir2/4
326 wimcapture srclist --source-list test.wim
327 wimapply test.wim out.dir
328 if [[ ! -f out.dir/subdir/1 || ! -f out.dir/subdir/2 || \
329         ! -f out.dir/subdir/subdir2/3 || ! -f out.dir/subdir/subdir2/4 ]]; then
330         error "source list capture (with deep overlay) failed to work as expected"
331 fi
332
333 # Try bad overlay
334 __msg "Testing bad overlay (errors expected)"
335 rm -rf out.dir
336 echo 5 > 5
337 cat > srclist << EOF
338 in.dir.1        /
339 in.dir.2        /
340 5               /subdir
341 EOF
342 if wimcapture srclist --source-list test.wim; then
343         error "unexpected success in bad overlay with --source-list!"
344 fi
345
346 echo "**********************************************************"
347 echo "          wimcapture/apply tests passed               "
348 echo "**********************************************************"
349
350 cd ..
351 default_cleanup