selftest: check file readability in shadow_copy2 test
[Samba.git] / source3 / script / tests / test_shadow_copy.sh
blob99b405f94bd0b6f2d5f56c942691b6057bf71767
1 #!/bin/bash
3 # Blackbox test for shadow_copy2 VFS.
6 if [ $# -lt 7 ]; then
7 cat <<EOF
8 Usage: test_shadow_copy SERVER SERVER_IP DOMAIN USERNAME PASSWORD WORKDIR SMBCLIENT
9 EOF
10 exit 1;
13 SERVER=${1}
14 SERVER_IP=${2}
15 DOMAIN=${3}
16 USERNAME=${4}
17 PASSWORD=${5}
18 WORKDIR=${6}
19 SMBCLIENT=${7}
20 shift 7
21 SMBCLIENT="$VALGRIND ${SMBCLIENT}"
22 ADDARGS="$*"
24 incdir=`dirname $0`/../../../testprogs/blackbox
25 . $incdir/subunit.sh
27 SNAPSHOTS[0]='@GMT-2015.10.31-19.40.30'
28 SNAPSHOTS[1]='@GMT-2016.10.31-19.40.30'
29 SNAPSHOTS[2]='@GMT-2017.10.31-19.40.30'
30 SNAPSHOTS[3]='@GMT-2018.10.31-19.40.30'
31 SNAPSHOTS[4]='@GMT-2019.10.31-19.40.30'
32 SNAPSHOTS[5]='@GMT-2020.10.31-19.40.30'
33 SNAPSHOTS[6]='@GMT-2021.10.31-19.40.30'
34 SNAPSHOTS[7]='@GMT-2022.10.31-19.40.30'
35 SNAPSHOTS[8]='@GMT-2023.10.31-19.40.30'
36 SNAPSHOTS[9]='@GMT-2024.10.31-19.40.30'
38 # build a hierarchy of files, symlinks, and directories
39 build_files()
41 local rootdir
42 local prefix
43 local version
44 local destdir
45 local content
46 rootdir=$1
47 prefix=$2
48 version=$3
49 content=$4
50 if [ -n "$prefix" ] ; then
51 destdir=$rootdir/$prefix
52 else
53 destdir=$rootdir
56 mkdir -p $destdir
57 if [ "$version" = "latest" ] ; then
58 #non-snapshot files
59 # for non-snapshot version, create legit files
60 # so that wide-link checks focus on snapshot files
61 echo "$content" > $destdir/foo
62 mkdir -p $destdir/bar
63 echo "$content" > $destdir/bar/baz
64 echo "$content" > $destdir/bar/lfoo
65 echo "$content" > $destdir/bar/letcpasswd
66 echo "$content" > $destdir/bar/loutside
67 elif [ "$version" = "fullsnap" ] ; then
68 #snapshot files
69 echo "$content" > $destdir/foo
70 mkdir -p $destdir/bar
71 echo "$content" > $destdir/bar/baz
72 ln -fs ../foo $destdir/bar/lfoo
73 ln -fs /etc/passwd $destdir/bar/letcpasswd
74 ln -fs ../../outside $destdir/bar/loutside
75 echo "$content" > `dirname $destdir`/outside
76 else #subshare snapshot - at bar
77 echo "$content" > $destdir/baz
78 ln -fs ../foo $destdir/lfoo
79 ln -fs /etc/passwd $destdir/letcpasswd
80 ln -fs ../../outside $destdir/loutside
81 echo "$content" > `dirname $destdir`/../outside
86 # build a snapshots directory
87 build_snapshots()
89 local where #where to build snapshots
90 local prefix #prefix from snapshot dir to share root
91 local start #timestamp index of first snapshot
92 local end #timestamp index of last snapshot
93 local sub #creat a snapshot of subtree of share
94 local snapdir
95 local snapname
96 local i
97 local version
99 where=$1
100 prefix=$2
101 start=$3
102 end=$4
103 sub=$5
105 snapdir=$where/.snapshots
106 mkdir -p $snapdir
108 version="fullsnap"
109 if [ "$sub" = "1" ] ; then
110 version="subsnap"
111 prefix=""
113 # a valid link target for an inner symlink -
114 # the link is not broken yet should be blocked
115 # by wide link checks
116 touch $snapdir/foo
119 for i in `seq $start $end` ; do
120 snapname=${SNAPSHOTS[$i]}
121 mkdir $snapdir/$snapname
122 build_files $snapdir/$snapname "$prefix" $version "$snapname"
123 done
126 # Test listing previous versions of a file
127 test_count_versions()
129 local share
130 local path
131 local expected_count
132 local skip_content
133 local versions
134 local tstamps
135 local tstamp
136 local content
138 share=$1
139 path=$2
140 expected_count=$3
141 skip_content=$4
142 versions=`$SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "allinfo $path" | grep "^create_time:" | wc -l`
143 if [ "$versions" != "$expected_count" ] ; then
144 echo "expected $expected_count versions of $path, got $versions"
145 return 1
148 #readable snapshots
149 tstamps=`$SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "allinfo $path" | awk '/^@GMT-/ {snapshot=$1} /^create_time:/ {printf "%s\n", snapshot}'`
150 for tstamp in $tstamps ; do
151 if ! $SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "get $tstamp\\$path $WORKDIR/foo" ; then
152 echo "Failed getting \\\\$SERVER\\$share\\$tstamp\\$path"
153 return 1
155 #also check the content, but not for wide links
156 if [ "x$skip_content" != "x1" ] ; then
157 content=`cat $WORKDIR/foo`
158 if [ "$content" != "$tstamp" ] ; then
159 echo "incorrect content of \\\\$SERVER\\$share\\$tstamp\\$path expected [$tstamp] got [$content]"
160 return 1
163 done
165 #non-readable snapshots
166 tstamps=`$SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "allinfo $path" | \
167 awk '/^@GMT-/ {if (snapshot!=""){printf "%s\n", snapshot} ; snapshot=$1} /^create_time:/ {snapshot=""} END {if (snapshot!=""){printf "%s\n", snapshot}}'`
168 for tstamp in $tstamps ; do
169 if $SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "get $tstamp\\$path $WORKDIR/foo" ; then
170 echo "Unexpected success getting \\\\$SERVER\\$share\\$tstamp\\$path"
171 return 1
173 done
176 # Test fetching a previous version of a file
177 test_fetch_snap_file()
179 local share
180 local path
181 local snapidx
183 share=$1
184 path=$2
185 snapidx=$3
186 $SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP \
187 -c "get ${SNAPSHOTS[$snapidx]}/$path $WORKDIR/foo"
190 test_shadow_copy_fixed()
192 local share #share to contact
193 local where #where to place snapshots
194 local prefix #prefix to files inside snapshot
195 local msg
196 local allow_wl
197 local ncopies_allowd
198 local ncopies_blocked
200 share=$1
201 where=$2
202 prefix=$3
203 msg=$4
204 allow_wl=$5
206 ncopies_allowed=4
207 ncopies_blocked=1
208 if [ -n "$allow_wl" ] ; then
209 ncopies_blocked=4
212 #delete snapshots from previous tests
213 find $WORKDIR -name ".snapshots" -exec rm -rf {} \; 1>/dev/null 2>&1
214 build_snapshots $WORKDIR/$where "$prefix" 0 2
216 testit "$msg - regular file" \
217 test_count_versions $share foo $ncopies_allowed || \
218 failed=`expr $failed + 1`
220 testit "$msg - regular file in subdir" \
221 test_count_versions $share bar/baz $ncopies_allowed || \
222 failed=`expr $failed + 1`
224 testit "$msg - local symlink" \
225 test_count_versions $share bar/lfoo $ncopies_allowed || \
226 failed=`expr $failed + 1`
228 testit "$msg - abs symlink outside" \
229 test_count_versions $share bar/letcpasswd $ncopies_blocked 1 || \
230 failed=`expr $failed + 1`
232 testit "$msg - rel symlink outside" \
233 test_count_versions $share bar/loutside $ncopies_blocked 1 || \
234 failed=`expr $failed + 1`
237 test_shadow_copy_everywhere()
239 local share #share to contact
241 share=$1
243 #delete snapshots from previous tests
244 find $WORKDIR -name ".snapshots" -exec rm -rf {} \; 1>/dev/null 2>&1
245 build_snapshots "$WORKDIR/mount" "base/share" 0 0
246 build_snapshots "$WORKDIR/mount/base" "share" 1 2
247 build_snapshots "$WORKDIR/mount/base/share" "" 3 5
248 build_snapshots "$WORKDIR/mount/base/share/bar" "" 6 9 1
250 testit "snapshots in each dir - regular file" \
251 test_count_versions $share foo 4 || \
252 failed=`expr $failed + 1`
254 testit "snapshots in each dir - regular file in subdir" \
255 test_count_versions $share bar/baz 5 || \
256 failed=`expr $failed + 1`
258 testit "snapshots in each dir - local symlink (but outside snapshot)" \
259 test_count_versions $share bar/lfoo 1 || \
260 failed=`expr $failed + 1`
262 testit "snapshots in each dir - abs symlink outside" \
263 test_count_versions $share bar/letcpasswd 1 || \
264 failed=`expr $failed + 1`
266 testit "snapshots in each dir - rel symlink outside" \
267 test_count_versions $share bar/loutside 1 || \
268 failed=`expr $failed + 1`
270 #the previous versions of the file bar/lfoo points to are outside its
271 #snapshot, and are not reachable. However, but previous versions
272 #taken at different, non-overlapping times higher up the
273 #hierarchy are still reachable.
274 testit "fetch a previous version of a regular file" \
275 test_fetch_snap_file $share "bar/baz" 6 || \
276 failed=`expr $failed + 1`
278 testit_expect_failure "fetch a (non-existent) previous version of a symlink" \
279 test_fetch_snap_file $share "bar/lfoo" 6 || \
280 failed=`expr $failed + 1`
282 testit "fetch a previous version of a symlink via browsing (1)" \
283 test_fetch_snap_file $share "bar/lfoo" 0 || \
284 failed=`expr $failed + 1`
286 testit "fetch a previous version of a symlink via browsing (2)" \
287 test_fetch_snap_file $share "bar/lfoo" 1 || \
288 failed=`expr $failed + 1`
290 testit "fetch a previous version of a symlink via browsing (3)" \
291 test_fetch_snap_file $share "bar/lfoo" 3 || \
292 failed=`expr $failed + 1`
296 #build "latest" files
297 build_files $WORKDIR/mount base/share "latest" "latest"
299 failed=0
301 # a test with wide links allowed - also to verify that what's later
302 # being blocked is a result of server security measures and not
303 # a testing artifact.
304 test_shadow_copy_fixed shadow_wl mount base/share "shadow copies with wide links allowed" 1
306 # tests for a fixed snapshot location
307 test_shadow_copy_fixed shadow1 mount base/share "full volume snapshots mounted under volume"
308 test_shadow_copy_fixed shadow2 . base/share "full volume snapshots mounted outside volume"
309 test_shadow_copy_fixed shadow3 mount/base share "sub volume snapshots mounted under snapshot point"
310 test_shadow_copy_fixed shadow4 . share "sub volume snapshots mounted outside"
311 test_shadow_copy_fixed shadow5 mount/base/share "" "full volume snapshots and share mounted under volume"
312 test_shadow_copy_fixed shadow6 . "" "full volume snapshots and share mounted outside"
313 test_shadow_copy_fixed shadow8 . share "logical snapshot layout"
315 # tests for snapshot everywhere - one snapshot location
316 test_shadow_copy_fixed shadow7 mount base/share "'everywhere' full volume snapshots"
317 test_shadow_copy_fixed shadow7 mount/base share "'everywhere' sub volume snapshots"
318 test_shadow_copy_fixed shadow7 mount/base/share "" "'everywhere' share snapshots"
320 # a test for snapshots everywhere - multiple snapshot locations
321 test_shadow_copy_everywhere shadow7
323 exit $failed