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