vfs_shadow_copy2: add tests for snapsharepath
[obnox/samba/samba-obnox.git] / source3 / script / tests / test_shadow_copy.sh
1 #!/bin/bash
2 #
3 # Blackbox test for shadow_copy2 VFS.
4 #
5
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;
11 fi
12
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="$*"
23
24 incdir=`dirname $0`/../../../testprogs/blackbox
25 . $incdir/subunit.sh
26
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'
37
38 # build a hierarchy of files, symlinks, and directories
39 build_files()
40 {
41     local rootdir
42     local prefix
43     local version
44     local destdir
45     rootdir=$1
46     prefix=$2
47     version=$3
48     if [ -n "$prefix" ] ; then
49         destdir=$rootdir/$prefix
50     else
51         destdir=$rootdir
52     fi
53
54     mkdir -p $destdir
55     if [ "$version" = "latest" ] ; then
56         #non-snapshot files
57         # for non-snapshot version, create legit files
58         # so that wide-link checks focus on snapshot files
59         touch $destdir/foo
60         mkdir -p $destdir/bar
61         touch $destdir/bar/baz
62         touch $destdir/bar/lfoo
63         touch $destdir/bar/letcpasswd
64         touch $destdir/bar/loutside
65     elif [ "$version" = "fullsnap" ] ; then
66         #snapshot files
67         touch $destdir/foo
68         mkdir -p $destdir/bar
69         touch $destdir/bar/baz
70         ln -fs ../foo $destdir/bar/lfoo
71         ln -fs /etc/passwd $destdir/bar/letcpasswd
72         ln -fs ../../outside $destdir/bar/loutside
73         touch `dirname $destdir`/outside
74     else #subshare snapshot - at bar
75         touch $destdir/baz
76         ln -fs ../foo $destdir/lfoo
77         ln -fs /etc/passwd $destdir/letcpasswd
78         ln -fs ../../outside $destdir/loutside
79         touch `dirname $destdir`/../outside
80     fi
81
82 }
83
84 # build a snapshots directory
85 build_snapshots()
86 {
87     local where     #where to build snapshots
88     local prefix    #prefix from snapshot dir to share root
89     local start     #timestamp index of first snapshot
90     local end       #timestamp index of last snapshot
91     local sub       #creat a snapshot of subtree of share
92     local snapdir
93     local snapname
94     local i
95     local version
96
97     where=$1
98     prefix=$2
99     start=$3
100     end=$4
101     sub=$5
102
103     snapdir=$where/.snapshots
104     mkdir -p $snapdir
105
106     version="fullsnap"
107     if [ "$sub" = "1" ] ; then
108         version="subsnap"
109         prefix=""
110
111         # a valid link target for an inner symlink -
112         # the link is not broken yet should be blocked
113         # by wide link checks
114         touch $snapdir/foo
115     fi
116
117     for i in `seq $start $end` ; do
118         snapname=${SNAPSHOTS[$i]}
119         mkdir $snapdir/$snapname
120         build_files $snapdir/$snapname "$prefix" $version
121     done
122 }
123
124 # Test listing previous versions of a file
125 test_count_versions()
126 {
127     local share
128     local path
129     local expected_count
130     local versions
131
132     share=$1
133     path=$2
134     expected_count=$3
135     versions=`$SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP -c "allinfo $path" | grep "^create_time:" | wc -l`
136     if [ "$versions" = "$expected_count" ] ; then
137         true
138     else
139         echo "expected $expected_count versions of $path, got $versions"
140         false
141     fi
142 }
143
144 # Test fetching a previous version of a file
145 test_fetch_snap_file()
146 {
147     local share
148     local path
149     local snapidx
150
151     share=$1
152     path=$2
153     snapidx=$3
154     $SMBCLIENT -U$USERNAME%$PASSWORD "//$SERVER/$share" -I $SERVER_IP \
155         -c "get ${SNAPSHOTS[$snapidx]}/$path $WORKDIR/foo"
156 }
157
158 test_shadow_copy_fixed()
159 {
160     local share     #share to contact
161     local where     #where to place snapshots
162     local prefix    #prefix to files inside snapshot
163     local msg
164     local allow_wl
165     local ncopies_allowd
166     local ncopies_blocked
167
168     share=$1
169     where=$2
170     prefix=$3
171     msg=$4
172     allow_wl=$5
173
174     ncopies_allowed=4
175     ncopies_blocked=1
176     if [ -n "$allow_wl" ] ; then
177         ncopies_blocked=4
178     fi
179
180     #delete snapshots from previous tests
181     find $WORKDIR -name ".snapshots" -exec rm -rf {} \; 1>/dev/null 2>&1
182     build_snapshots $WORKDIR/$where "$prefix" 0 2
183
184     testit "$msg - regular file" \
185         test_count_versions $share foo $ncopies_allowed || \
186         failed=`expr $failed + 1`
187
188     testit "$msg - regular file in subdir" \
189         test_count_versions $share bar/baz $ncopies_allowed || \
190         failed=`expr $failed + 1`
191
192     testit "$msg - local symlink" \
193         test_count_versions $share bar/lfoo $ncopies_allowed || \
194         failed=`expr $failed + 1`
195
196     testit "$msg - abs symlink outside" \
197         test_count_versions $share bar/letcpasswd $ncopies_blocked || \
198         failed=`expr $failed + 1`
199
200     testit "$msg - rel symlink outside" \
201         test_count_versions $share bar/loutside $ncopies_blocked || \
202         failed=`expr $failed + 1`
203 }
204
205 test_shadow_copy_everywhere()
206 {
207     local share     #share to contact
208
209     share=$1
210
211     #delete snapshots from previous tests
212     find $WORKDIR -name ".snapshots" -exec rm -rf {} \; 1>/dev/null 2>&1
213     build_snapshots "$WORKDIR/mount" "base/share" 0 0
214     build_snapshots "$WORKDIR/mount/base" "share" 1 2
215     build_snapshots "$WORKDIR/mount/base/share" "" 3 5
216     build_snapshots "$WORKDIR/mount/base/share/bar" "" 6 9 1
217
218     testit "snapshots in each dir - regular file" \
219         test_count_versions $share foo 4 || \
220         failed=`expr $failed + 1`
221
222     testit "snapshots in each dir - regular file in subdir" \
223         test_count_versions $share bar/baz 5 || \
224         failed=`expr $failed + 1`
225
226     testit "snapshots in each dir - local symlink (but outside snapshot)" \
227         test_count_versions $share bar/lfoo 1 || \
228         failed=`expr $failed + 1`
229
230     testit "snapshots in each dir - abs symlink outside" \
231         test_count_versions $share bar/letcpasswd 1 || \
232         failed=`expr $failed + 1`
233
234     testit "snapshots in each dir - rel symlink outside" \
235         test_count_versions $share bar/loutside 1 || \
236         failed=`expr $failed + 1`
237
238     #the previous versions of the file bar/lfoo points to are outside its
239     #snapshot, and are not reachable. However, but previous versions
240     #taken at different, non-overlapping times higher up the
241     #hierarchy are still reachable.
242     testit "fetch a previous version of a regular file" \
243         test_fetch_snap_file $share "bar/baz" 6 || \
244         failed=`expr $failed + 1`
245
246     testit_expect_failure "fetch a (non-existent) previous version of a symlink" \
247         test_fetch_snap_file $share "bar/lfoo" 6 || \
248         failed=`expr $failed + 1`
249
250     testit "fetch a previous version of a symlink via browsing (1)" \
251         test_fetch_snap_file $share "bar/lfoo" 0 || \
252         failed=`expr $failed + 1`
253
254     testit "fetch a previous version of a symlink via browsing (2)" \
255         test_fetch_snap_file $share "bar/lfoo" 1 || \
256         failed=`expr $failed + 1`
257
258     testit "fetch a previous version of a symlink via browsing (3)" \
259         test_fetch_snap_file $share "bar/lfoo" 3 || \
260         failed=`expr $failed + 1`
261
262 }
263
264 #build "latest" files
265 build_files $WORKDIR/mount base/share "latest"
266
267 failed=0
268
269 # a test with wide links allowed - also to verify that what's later
270 # being blocked is a result of server security measures and not
271 # a testing artifact.
272 test_shadow_copy_fixed shadow_wl mount base/share "shadow copies with wide links allowed" 1
273
274 # tests for a fixed snapshot location
275 test_shadow_copy_fixed shadow1 mount base/share "full volume snapshots mounted under volume"
276 test_shadow_copy_fixed shadow2 . base/share "full volume snapshots mounted outside volume"
277 test_shadow_copy_fixed shadow3 mount/base share "sub volume snapshots mounted under snapshot point"
278 test_shadow_copy_fixed shadow4 . share "sub volume snapshots mounted outside"
279 test_shadow_copy_fixed shadow5 mount/base/share "" "full volume snapshots and share mounted under volume"
280 test_shadow_copy_fixed shadow6 . "" "full volume snapshots and share mounted outside"
281 test_shadow_copy_fixed shadow8 . share "logical snapshot layout"
282
283 # tests for snapshot everywhere - one snapshot location
284 test_shadow_copy_fixed shadow7 mount base/share "'everywhere' full volume snapshots"
285 test_shadow_copy_fixed shadow7 mount/base share "'everywhere' sub volume snapshots"
286 test_shadow_copy_fixed shadow7 mount/base/share "" "'everywhere' share snapshots"
287
288 # a test for snapshots everywhere - multiple snapshot locations
289 test_shadow_copy_everywhere shadow7
290
291 exit $failed