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