be more flexible with a lack of -ldb on a system (just skip test 010).
[xfstests-dev.git] / 001
1 #! /bin/sh
2 #
3 # XFS QA Test No. 001
4 # $Id: 1.1 $
5 #
6 # Random file copier to produce chains of identical files so the head
7 # and the tail cna be diff'd at then end of each iteration.
8 #
9 # Exercises creat, write and unlink for a variety of directory sizes, and
10 # checks for data corruption.
11 #
12 # run [config]
13 #
14 # config has one line per file with filename and byte size, else use
15 # the default one below.
16 #
17 #-----------------------------------------------------------------------
18 # Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
19
20 # This program is free software; you can redistribute it and/or modify it
21 # under the terms of version 2 of the GNU General Public License as
22 # published by the Free Software Foundation.
23
24 # This program is distributed in the hope that it would be useful, but
25 # WITHOUT ANY WARRANTY; without even the implied warranty of
26 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
27
28 # Further, this software is distributed without any warranty that it is
29 # free of the rightful claim of any third person regarding infringement
30 # or the like.  Any license provided herein, whether implied or
31 # otherwise, applies only to this software file.  Patent licenses, if
32 # any, provided herein do not apply to combinations of this program with
33 # other software, or any other product whatsoever.
34
35 # You should have received a copy of the GNU General Public License along
36 # with this program; if not, write the Free Software Foundation, Inc., 59
37 # Temple Place - Suite 330, Boston MA 02111-1307, USA.
38
39 # Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
40 # Mountain View, CA  94043, or:
41
42 # http://www.sgi.com 
43
44 # For further information regarding this notice, see: 
45
46 # http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
47 #-----------------------------------------------------------------------
48 #
49 # creator
50 owner=kenmcd@bruce.melbourne.sgi.com
51
52 seq=`basename $0`
53 echo "QA output created by $seq"
54
55 # get standard environment, filters and checks
56 . ./common.rc
57 . ./common.filter
58
59 tmp=/tmp/$$
60 here=`pwd`
61 status=1
62 done_cleanup=false
63 trap "_cleanup; rm -f $tmp.*; exit \$status" 0 1 2 3 15
64
65 # real QA test starts here
66
67 verbose=true
68
69 if [ $# -eq 0 ]
70 then
71     # use the default config
72     #
73     cat <<End-of-File >$tmp.config
74 # pathname      size in bytes
75 #
76 small           10
77 big             102400
78 sub/small       10
79 sub/big         102400
80 #
81 sub/a           1
82 sub/b           2
83 sub/c           4
84 sub/d           8
85 sub/e           16
86 sub/f           32
87 sub/g           64
88 sub/h           128
89 sub/i           256
90 sub/j           512
91 sub/k           1024
92 sub/l           2048
93 sub/m           4096
94 sub/n           8192
95 #
96 sub/a00         100
97 sub/b00         200
98 sub/c00         400
99 sub/d00         800
100 sub/e00         1600
101 sub/f00         3200
102 sub/g00         6400
103 sub/h00         12800
104 sub/i00         25600
105 sub/j00         51200
106 sub/k00         102400
107 sub/l00         204800
108 sub/m00         409600
109 sub/n00         819200
110 #
111 sub/a000        1000
112 sub/e000        16000
113 sub/h000        128000
114 sub/k000        1024000
115 End-of-File
116 elif [ $# -eq 1 ]
117 then
118     if [ -f $1 ]
119     then
120         cp $1 $tmp.config
121     else
122         echo "Error: cannot open config \"$1\""
123         exit 1
124     fi
125 else
126     echo "Usage: run [config]"
127     exit 1
128 fi
129
130 ncopy=200               # number of file copies in the chain step
131
132 _setup()
133 {
134     if mkdir -p $TEST_DIR/$$
135     then
136         :
137     else
138         echo "Error: cannot mkdir \"$TEST_DIR/$$\""
139         exit 1
140     fi
141     cd $TEST_DIR/$$
142
143     $verbose && echo -n "setup "
144     sed -e '/^#/d' $tmp.config \
145     | while read file nbytes
146     do
147         dir=`dirname $file`
148         if [ "$dir" != "." ]
149         then
150             if [ ! -d $dir ]
151             then
152                 if mkdir $dir
153                 then
154                     :
155                 else
156                     $verbose && echo
157                     echo "Error: cannot mkdir \"$dir\""
158                     exit 1
159                 fi
160             fi
161         fi
162         rm -f $file
163         if $here/src/fill $file $file $nbytes
164         then
165             :
166         else
167             $verbose && echo
168             echo "Error: cannot create \"$file\""
169             exit 1
170         fi
171         $verbose && echo -n "."
172     done
173     $verbose && echo
174 }
175
176 _mark_iteration()
177 {
178     $verbose && echo -n "mark_iteration "
179     sed -e '/^#/d' $tmp.config \
180     | while read file nbytes
181     do
182         if [ ! -f $file ]
183         then
184             $verbose && echo
185             echo "Error: $file vanished!"
186             touch $tmp.bad
187             continue
188         fi
189         sed -e "s/ [0-9][0-9]* / $1 /" <$file >$file.tmp
190         mv $file.tmp $file
191         $verbose && echo -n "."
192     done
193     $verbose && echo
194 }
195
196 # for each file, make a number of copies forming a chain like foo.0,
197 # foo.1, foo.2, ... foo.N
198 #
199 # files are chosen at random, so the lengths of the chains are different
200 #
201 # then rename foo.N to foo.last and remove all of the other files in
202 # the chain
203 #
204 _chain()
205 {
206     $AWK_PROG <$tmp.config '
207 BEGIN   { nfile = 0 }
208 /^\#/   { next }
209         { file[nfile] = $1
210           link[nfile] = 0
211           nfile++
212         }
213 END     { srand('$iter')
214           for (i=0; i < '$ncopy'; i++) {
215             # choose a file at random, and add one copy to that chain
216             j = -1
217             while (j < 0 || j >= nfile)
218                 j = int(rand() * nfile)
219             if (link[j] == 0) {
220                 printf "if [ ! -f %s ]; then echo \"%s missing!\"; exit; fi\n",file[j],file[j]
221                 printf "if [ -f %s.0 ]; then echo \"%s.0 already present!\"; exit; fi\n",file[j],file[j]
222                 printf "cp %s %s.0\n",file[j],file[j]
223             }
224             else {
225                 printf "if [ ! -f %s.%d ]; then echo \"%s.%d missing!\"; exit; fi\n",file[j],link[j]-1,file[j],link[j]-1
226                 printf "if [ -f %s.%d ]; then echo \"%s.%d already present!\"; exit; fi\n",file[j],link[j],file[j],link[j]
227                 printf "cp %s.%d %s.%d\n",file[j],link[j]-1,file[j],link[j]
228             }
229             link[j]++
230           }
231           # close all the chains, and remove all of the files except
232           # the head of the chain
233           for (j=0; j<nfile; j++) {
234             if (link[j] > 0)
235                 printf "mv %s.%d %s.last\n",file[j],link[j]-1,file[j]
236             for (i=0; i<link[j]-1; i++) {
237                 printf "rm -f %s.%d\n",file[j],i
238             }
239           }
240         }' \
241         | sh
242 }
243
244 _check()
245 {
246     rm -f $tmp.bad
247     $verbose && echo -n "check "
248     sed -e '/^#/d' $tmp.config \
249     | while read file nbytes
250     do
251         if [ ! -f $file ]
252         then
253             $verbose && echo
254             echo "Error: $file vanished!"
255             touch $tmp.bad
256             continue
257         fi
258         if [ -f $file.last ]
259         then
260             if cmp $file $file.last >/dev/null 2>&1
261             then
262                 $verbose && echo -n "."
263             else
264                 $verbose && echo
265                 echo "Error: corruption for $file ..."
266                 diff -c $file $file.last
267                 touch $tmp.bad
268             fi
269         else
270             $verbose && echo -n "."
271         fi
272     done
273     $verbose && echo
274 }
275
276 _cleanup()
277 {
278     # cleanup
279     #
280     if $done_cleanup
281     then
282         :
283     elif [ $status -eq 0 ]
284     then
285         $verbose && echo "cleanup"
286         cd /
287         rm -rf $TEST_DIR/$$
288         done_cleanup=true
289     fi
290 }
291
292 status=0
293 _cleanup
294 status=1
295 done_cleanup=false
296
297 _setup
298
299 # do the test
300 #
301 for iter in 1 2 3 4 5
302 do
303     echo -n "iter $iter chain ... "
304     _chain
305     _check
306     if [ -f $tmp.bad ]
307     then
308         echo "Fatal error: test abandoned without changes"
309         exit 1
310     fi
311 done
312
313 status=0
314 exit