bbc88b74d1472fc6a46203d813d968b2cb3e3bd6
[wimlib] / tests / test-imagex-ntfs
1 #!/bin/bash
2
3 # This script does some sanity testing of the 'imagex' program, specifically
4 # checking the NTFS capture and apply features.
5 #
6 # This test will fail if wimlib was compiled with --without-ntfs-3g.
7
8 # Assume an in-tree build.
9 set -e
10 cd tests
11
12 imagex() {
13         #echo "imagex $@"
14         ../imagex $@ #> /dev/null
15 }
16
17 do_unmount() {
18         if mountpoint $1 &> /dev/null; then
19                 if !  fusermount -u $1; then
20                         error "Failed to unmount \"$1\""
21                 fi
22         fi
23 }
24
25 do_mount() {
26         do_unmount $2
27         options="$3"
28         if ! ntfs-3g ${options:+-o $options} $1 $2; then
29                 error "Could not mount NTFS volume \"$1\" on \"$2\".  Make sure ntfs-3g is installed."
30         fi
31 }
32
33 do_mkntfs() {
34         if ! mkntfs --force --fast $1 &> /dev/null; then
35                 error "Could not create NTFS volume on \"$1\".  Make sure ntfs-3g / ntfsprogs are installed"
36         fi
37 }
38
39 init() {
40         echo "Creating NTFS volumes and empty directories to use as mountpoints"
41         dd if=/dev/zero of=in.ntfs bs=4096 count=1000 &> /dev/null
42         dd if=/dev/zero of=out.ntfs bs=4096 count=1000 &> /dev/null
43         mkdir in.mnt out.mnt
44         do_mkntfs in.ntfs
45         do_mkntfs out.ntfs
46 }
47
48 cleanup() {
49         do_unmount in.mnt
50         do_unmount out.mnt
51         rm -rf in.ntfs out.ntfs in.mnt out.mnt in.xattr out.xattr
52 }
53 #trap cleanup exit
54
55
56 error() {
57         echo "****************************************************************"
58         echo "                         Test failure                           "
59         echo $*
60         echo "****************************************************************"
61         exit 1
62 }
63
64 do_capture() {
65         do_unmount in.mnt
66         if ! imagex capture in.ntfs ntfs.wim; then
67                 error "Failed to capture NTFS volume into a WIM"
68         fi
69 }
70
71 do_apply() {
72         do_unmount out.mnt
73         do_mkntfs out.ntfs
74         if ! imagex apply ntfs.wim 1 out.ntfs; then
75                 error "Failed to apply WIM to NTFS volume"
76         fi
77 }
78
79 cmp_xattrs() {
80         infile=$1
81         outfile=$2
82         xattr=$3
83         #echo "Comparing xattr $xattr of $infile and $outfile"
84         if test "$xattr" = "system.ntfs_times"; then
85                 headnum=24
86         else
87                 headnum=1000000000
88         fi
89         if eval getfattr --only-values -h -d -n $xattr $infile 2>/dev/null\
90                                         | head -c $headnum > in.xattr; then
91                 if eval getfattr --only-values -h -d -n $xattr $outfile 2>/dev/null\
92                                         | head -c $headnum > out.xattr; then
93                         if ! cmp in.xattr out.xattr; then
94                                 error "Extended attribute $xattr of $infile and $outfile differs"
95                         fi
96                 else
97                         error "$infile has extended attribute $xattr, but $outfile doesn't"
98                 fi
99         else
100                 if eval getfattr --only-values -h -d -n $xattr $outfile 2>/dev/null\
101                                         | head -c $headnum > out.xattr; then
102                         error "$outfile has extended attribute $xattr, but $infile doesn't"
103                 fi
104         fi
105 }
106
107 # Captures in.ntfs, applies it to out.ntfs, and diffs the result including
108 # extended attributes
109 do_capture_and_apply() {
110         do_capture
111         do_apply
112         do_mount in.ntfs in.mnt ro
113         do_mount out.ntfs out.mnt ro
114         #if ! diff -r in.mnt out.mnt; then
115                 #error "Recursive diff of original NTFS volume with applied NTFS volume failed"
116         #fi
117         for infile in `find in.mnt`; do
118                 outfile=out.mnt${infile##in.mnt}
119                 #echo "Comparing xattrs of $infile and $outfile"
120                 if [ ! -L $infile -a ! -d $infile ]; then
121                         if ! cmp $infile $outfile; then
122                                 error "Contents of $infile and $outfile differed"
123                         fi
124                 fi
125                 cmp_xattrs $infile $outfile system.ntfs_attrib
126                 cmp_xattrs $infile $outfile system.ntfs_reparse_data
127                 cmp_xattrs $infile $outfile system.ntfs_acl
128                 cmp_xattrs $infile $outfile system.ntfs_dos_name
129                 cmp_xattrs $infile $outfile system.ntfs_times
130         done
131 }
132
133 build_ntfs() {
134         do_unmount in.mnt
135         do_mkntfs in.ntfs
136         do_mount in.ntfs in.mnt
137         ( cd in.mnt; eval "$1" )
138 }
139
140 do_test() {
141         build_ntfs "$1"
142         do_capture_and_apply
143 }
144 msg() {
145         echo "Testing image capture and application of $1"
146 }
147
148 cleanup
149 init
150
151 msg "Empty NTFS volume"
152 do_capture_and_apply
153
154 msg "NTFS volume containing a single file"
155 do_test "echo 1 > file"
156
157 msg "NTFS volume containing a single directory"
158 do_test "mkdir dir"
159
160 msg "NTFS volume containing subdirectory with file"
161 do_test "mkdir dir; echo 1 > dir/file"
162
163 msg "NTFS volume containing empty file"
164 do_test "echo -n > empty_file"
165
166 msg "NTFS volume containing two empty files"
167 do_test "echo -n > empty_file_1; echo -n > empty_file_2"
168
169 msg "NTFS volume containing hard link in same directory"
170 do_test "echo 1 > file; ln file link"
171
172 msg "NTFS volume containing hard link between empty files"
173 do_test "echo -n > empty_file; ln empty_file link"
174
175 msg "NTFS volume containing relative symbolic link"
176 do_test "echo 1 > file; ln -s file symlink"
177
178 msg "NTFS volume containing absolute symbolic link"
179 do_test "echo 1 > file; ln -s /some/absolute/target symlink"
180
181 msg "NTFS volume containing large file"
182 do_test "dd if=/dev/zero of=file bs=4096 count=10 &> /dev/null"
183
184 msg "NTFS volume containing file with DOS name"
185 do_test "echo 1 > file; setfattr -v file -n system.ntfs_dos_name file"
186
187 msg "NTFS volume containing file with DOS name with alphabetically smaller hardlink in same directory"
188 do_test "echo 1 > file; setfattr -v file -n system.ntfs_dos_name file; ln file aaa_link"
189
190 msg "NTFS volume containing file with DOS name with alphabetically larger hardlink in same directory"
191 do_test "echo 1 > file; setfattr -v file -n system.ntfs_dos_name file; ln file zzz_link"
192
193 msg "NTFS volume containing file with long name and with DOS name with alphabetically smaller hardlink in same directory"
194 do_test 'echo 1 > file_with_a_long_name;
195          setfattr -v "file~1" -n system.ntfs_dos_name file_with_a_long_name;
196          ln file_with_a_long_name aaa_link'
197
198 msg "NTFS volume containing many nested directories"
199 do_test 'mkdir dir; mkdir dir/subdir; mkdir dir/subdir/subdir2; mkdir dir/subdir/subdir3'
200
201 msg "NTFS volume containing identical files and symlinks in subdirectory"
202 do_test 'mkdir dir;
203          echo 888 > dir/file;
204          echo 888 > dir/idfile2;
205          ln -s dir dir/circle; ln -s file dir/filelink'
206
207 msg "NTFS volume containing hard link group and identical files not hard linked"
208 do_test 'echo 888 > file;
209          echo 888 > file2;
210          ln file link;
211          ln file link2;
212          echo 888 > file3'
213