Integrate existing dmapi qa tests into xfs qa infrastructure
[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 #
19 # creator
20 owner=kenmcd@sgi.com
21
22 seq=`basename $0`
23 echo "QA output created by $seq"
24
25 # get standard environment, filters and checks
26 . ./common.rc
27 . ./common.filter
28
29 tmp=/tmp/$$
30 here=`pwd`
31 status=1
32 done_cleanup=false
33 trap "_cleanup; rm -f $tmp.*; exit \$status" 0 1 2 3 15
34
35 # real QA test starts here
36 _supported_fs xfs udf nfs
37 _supported_os IRIX Linux
38
39 verbose=true
40 verify=$here/verify_fill
41
42 if [ $# -eq 0 ]
43 then
44     # use the default config
45     #
46     cat <<End-of-File >$tmp.config
47 # pathname      size in bytes
48 #
49 small           10
50 big             102400
51 sub/small       10
52 sub/big         102400
53 #
54 sub/a           1
55 sub/b           2
56 sub/c           4
57 sub/d           8
58 sub/e           16
59 sub/f           32
60 sub/g           64
61 sub/h           128
62 sub/i           256
63 sub/j           512
64 sub/k           1024
65 sub/l           2048
66 sub/m           4096
67 sub/n           8192
68 #
69 sub/a00         100
70 sub/b00         200
71 sub/c00         400
72 sub/d00         800
73 sub/e00         1600
74 sub/f00         3200
75 sub/g00         6400
76 sub/h00         12800
77 sub/i00         25600
78 sub/j00         51200
79 sub/k00         102400
80 sub/l00         204800
81 sub/m00         409600
82 sub/n00         819200
83 #
84 sub/a000        1000
85 sub/e000        16000
86 sub/h000        128000
87 sub/k000        1024000
88 End-of-File
89 elif [ $# -eq 1 ]
90 then
91     if [ -f $1 ]
92     then
93         cp $1 $tmp.config
94     else
95         echo "Error: cannot open config \"$1\""
96         exit 1
97     fi
98 else
99     echo "Usage: run [config]"
100     exit 1
101 fi
102
103 ncopy=200               # number of file copies in the chain step
104 udf_fsize=20240         # number of sectors for UDF
105
106 _setup()
107 {
108     if mkdir -p $testdir/$$
109     then
110         :
111     else
112         echo "Error: cannot mkdir \"$testdir/$$\""
113         exit 1
114     fi
115     cd $testdir/$$
116
117     $verbose && echo -n "setup "
118     sed -e '/^#/d' $tmp.config \
119     | while read file nbytes
120     do
121         dir=`dirname $file`
122         if [ "$dir" != "." ]
123         then
124             if [ ! -d $dir ]
125             then
126                 if mkdir $dir
127                 then
128                     :
129                 else
130                     $verbose && echo
131                     echo "Error: cannot mkdir \"$dir\""
132                     exit 1
133                 fi
134             fi
135         fi
136         rm -f $file
137         if $here/src/fill $file $file $nbytes
138         then
139             :
140         else
141             $verbose && echo
142             echo "Error: cannot create \"$file\""
143             exit 1
144         fi
145         $verbose && echo -n "."
146     done
147     $verbose && echo
148 }
149
150 _mark_iteration()
151 {
152     $verbose && echo -n "mark_iteration "
153     sed -e '/^#/d' $tmp.config \
154     | while read file nbytes
155     do
156         if [ ! -f $file ]
157         then
158             $verbose && echo
159             echo "Error: $file vanished!"
160             touch $tmp.bad
161             continue
162         fi
163         sed -e "s/ [0-9][0-9]* / $1 /" <$file >$file.tmp
164         mv $file.tmp $file
165         $verbose && echo -n "."
166     done
167     $verbose && echo
168 }
169
170 # for each file, make a number of copies forming a chain like foo.0,
171 # foo.1, foo.2, ... foo.N
172 #
173 # files are chosen at random, so the lengths of the chains are different
174 #
175 # then rename foo.N to foo.last and remove all of the other files in
176 # the chain
177 #
178 _chain()
179 {
180     $AWK_PROG -v full_file=$here/$seq.full -v verify=$verify <$tmp.config '
181 BEGIN   { nfile = 0 }
182 /^\#/   { next }
183         { file[nfile] = $1
184           size[nfile] = $2
185           link[nfile] = 0
186           nfile++
187           total_size += $2
188         }
189 END     { srand('$iter')
190           for (i=0; i < '$ncopy'; i++) {
191             # choose a file at random, and add one copy to that chain
192             j = -1
193             while (j < 0 || j >= nfile)
194                 j = int(rand() * nfile)
195             if (link[j] == 0) {
196                 # previous should already exist and next one should not exist
197                 printf "if [ ! -f %s ]; then echo \"%s missing!\"; exit; fi\n",file[j],file[j]
198                 printf "if [ -f %s.0 ]; then echo \"%s.0 already present!\"; exit; fi\n",file[j],file[j]
199                 printf "cp %s %s.0 || exit 1\n",file[j],file[j]
200                 printf "ls -i %s.0\n", file[j] >full_file;
201                 total_size += size[j]
202                 printf "# total size = %d\n", total_size 
203             }
204             else {
205                 # previous should already exist and next one should not exist
206                 printf "if [ ! -f %s.%d ]; then echo \"%s.%d missing!\"; exit; fi\n",file[j],link[j]-1,file[j],link[j]-1
207                 printf "if [ -f %s.%d ]; then echo \"%s.%d already present!\"; exit; fi\n",file[j],link[j],file[j],link[j]
208                 printf "cp %s.%d %s.%d || exit 1\n",file[j],link[j]-1,file[j],link[j]
209                 printf "ls -i %s.%d\n", file[j], link[j] >full_file;
210                 total_size += size[j]
211                 printf "# total size = %d\n", total_size 
212             }
213             link[j]++
214           }
215           # close all the chains, 
216           # if have at least one copy then move the last copy to "file[j].last"
217           # and remove all of the other files except the head of the chain
218           for (j=0; j<nfile; j++) {
219             if (link[j] > 0) {
220                 printf "mv %s.%d %s.last\n",file[j],link[j]-1,file[j]
221                 printf "ls -i %s.last\n", file[j] >full_file;
222             }
223             for (i=0; i<link[j]-1; i++) {
224                 printf "rm -f %s.%d\n",file[j],i
225             }
226           }
227         }' \
228         | tee -a $here/$seq.full | sh
229 }
230
231 _check()
232 {
233     rm -f $tmp.bad
234     $verbose && echo -n "check "
235     sed -e '/^#/d' $tmp.config \
236     | while read file nbytes
237     do
238         # the file is never removed so it should exist
239         if [ ! -f $file ]
240         then
241             $verbose && echo
242             echo "Error: $file vanished!"
243             touch $tmp.bad
244             continue
245         fi
246         # checks that the file and its last copy are the same
247         if [ -f $file.last ]
248         then
249             if cmp $file $file.last >/dev/null 2>&1
250             then
251                 $verbose && echo -n "."
252             else
253                 $verbose && echo
254                 echo "Error: corruption for $file ..."
255                 diff -c $file $file.last
256                 touch $tmp.bad
257             fi
258         else
259             $verbose && echo -n "."
260         fi
261     done
262     $verbose && echo
263 }
264
265 _cleanup()
266 {
267     # cleanup
268     #
269     if $done_cleanup
270     then
271         :
272     elif [ $status -eq 0 ]
273     then
274         $verbose && echo "cleanup"
275         cd /
276         rm -rf $testdir/$$
277         _cleanup_testdir
278         done_cleanup=true
279     fi
280 }
281
282 rm -f $here/$seq.full
283 status=0
284 _cleanup
285 status=1
286 done_cleanup=false
287
288 _setup_testdir
289 _setup
290
291 # do the test
292 #
293 for iter in 1 2 3 4 5
294 do
295     echo -n "iter $iter chain ... "
296     echo "iter $iter" >> $here/$seq.full
297     _chain
298     _check
299     if [ -f $tmp.bad ]
300     then
301         echo "Fatal error: test abandoned without changes"
302         exit 1
303     fi
304 done
305
306 status=0
307 exit