Undoes mod: xfs-cmds:slinx:120772a
[xfstests-dev.git] / dmapi / src / suite2 / bindir / run_test
1 #!/bin/ksh
2
3 #
4 # Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
5
6 # This program is free software; you can redistribute it and/or modify it
7 # under the terms of version 2 of the GNU General Public License as
8 # published by the Free Software Foundation.
9
10 # This program is distributed in the hope that it would be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
14 # Further, this software is distributed without any warranty that it is
15 # free of the rightful claim of any third person regarding infringement
16 # or the like.  Any license provided herein, whether implied or
17 # otherwise, applies only to this software file.  Patent licenses, if
18 # any, provided herein do not apply to combinations of this program with
19 # other software, or any other product whatsoever.
20
21 # You should have received a copy of the GNU General Public License along
22 # with this program; if not, write the Free Software Foundation, Inc., 59
23 # Temple Place - Suite 330, Boston MA 02111-1307, USA.
24
25 # Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
26 # Mountain View, CA  94043, or:
27
28 # http://www.sgi.com 
29
30 # For further information regarding this notice, see: 
31
32 # http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
33
34 #-----------------------------------------------------------------#
35 # run_test:  a ksh script for testing the DMAPI.
36 #
37 # USAGE: run_test [-p] [-x] [-u user] 
38 #        [-F fs_type -M fs_mtpt -R "real" directory] 
39 #        [-f datafile] [-s sleeptime]
40 #        bindir testdir fsdir
41 #
42 # p:  Causes pausing after every test (not just ones with errors).
43 #
44 # x:  Prints an execution trace as the script runs.
45 #
46 # user:  Most tests don't need root access, so they will be run
47 #        under this username. 
48 #
49 # (NOTE: the following three must be used together)
50 #
51 #     fs_type: For NFS tests; the type of filesystem (ie nfs2, nfs3).
52 #
53 #     fs_mtpt: For NFS tests, the path to the mount of your 
54 #              "real" filesystem.
55 #              (ie, "mount -t nfs2 localhost:/dmitest $fs_mtpt")
56 #
57 #     "real" directory:  For NFS tests, the path to the "real" test directory.
58 #
59 # datafile:  The name of the file which contains the tests to run.
60 #   
61 # sleeptime: time, in seconds, for the daemon to sleep after  
62 #            responding to an event. (Useful for testing small
63 #            outstanding-events queues.)
64 #
65 # bindir:  The path to the directory that holds dm_test_daemon, send_msg,
66 #          the datafile, and any other files required by the datafile.
67 #    
68 # testdir:  The path to the test directory.  All DMAPI testing
69 #           occurs here -- this is where the tests will actually
70 #           be run.  (For NFS tests, this will be an NFS mount 
71 #           of the "real" directory.)
72 #          
73 # fsdir:  The path name of the test filesystem.  The daemon will start
74 #         using this path, and the mount and unmount of the DMAPI
75 #         filesystem will be done here.  (Even for NFS tests, this 
76 #         should still be the same test filesystem.)
77 #
78 #-----------------------------------------------------------------#
79
80 # For most reads, we'll want spaces to be the field separators.
81 IFS=" "
82
83 typeset -i fail_flag
84 typeset -i pause_flag
85 typeset -i sleeptime
86
87 # To run tests that don't require root access, we'll change to
88 # a user specified by lname.
89 lname=$LOGNAME
90
91 # Set the default external files to use.
92 datafile=main.dat
93 sleeptime=0
94
95 unset fs_type fs_mtpt
96 real_dir=set_me_later
97
98 # Parse the command-line options
99 while getopts :pxu:F:M:R:f:b:s: option
100 do  case $option in
101     p) pause_flag=1;;
102     x) set -x;;
103     u) lname=$OPTARG;;
104     F) fs_type=$OPTARG;;
105     M) fs_mtpt=$OPTARG;;
106     R) real_dir=$OPTARG;;
107     f) datafile=$OPTARG;;
108     b) bindir=$OPTARG;;
109     s) sleeptime=$OPTARG;;
110     :) print -u2 "${0##*/}: $OPTARG requires a value"
111        exit 2;;
112    \?) print -nu2 "USAGE: ${0##*/} [-p] [-x] [-u user] "
113        print -nu2 "[-F fs type -M mountpoint directory -R \"real\" directory] "
114        print -u2 "[-s sleeptime] [-f datafile] bindir testdir fsdir"
115        exit 2;;
116     esac
117 done
118
119 # Shift out the examined options, then check that we have
120 # exactly three arguments left: (the paths to the "bindir", 
121 # the test directory, and the filesystem).
122 shift OPTIND-1
123 if [[ $# != 3 ]]
124 then  print -nu2 "USAGE: ${0##*/} [-p] [-x] [-u user] "
125       print -nu2 "[-F fs type -M mountpoint directory -R \"real\" directory] "
126       print -u2 "[-s sleeptime] [-f datafile] bindir testdir fsdir"
127       exit 2
128 fi
129
130 # For NFS tests, $2 will be an NFS mount of the test directory;
131 # real_dir should be the test directory's actual path.
132 # Otherwise, real_dir should just be $2.
133 if [[ $real_dir = set_me_later ]]
134 then real_dir=$2
135 fi
136
137 # Check bindir for the existence of our three critical external files.
138 error_count=0
139 for i in dm_test_daemon send_msg $datafile 
140 do
141     if [[ ! ( -r "$1/$i" ) ]]
142     then if ((error_count==0)) 
143          then print "Aborting: the directory $1/ is missing critical files:"
144          fi
145          print "$1/$i"
146          (( error_count = error_count + 1 ))
147     fi
148 done
149 if (( error_count > 0 )) 
150 then exit 1
151 fi
152
153 # Open the datafile on file descriptor 3
154 exec 3< $1/$datafile
155
156 # Read datafile and determine what files it needs from bindir;
157 # then, check for the existence of these files.
158 error_count=0
159 while read -u3 file_list
160 do case $file_list in
161    ---*) break;;
162     //*) continue;;
163       *) for i in $file_list
164          do if [[ ! ( -r "$1/$i" ) ]]
165             then if ((error_count==0)) 
166                  then print "The directory $1/ is missing these files:"
167                  fi
168                  print "$1/$i"
169                  (( error_count = error_count + 1 ))
170             fi
171          done;;
172    esac
173 done
174 if (( error_count > 0 )) 
175  then exit 1
176 fi
177
178 # Run initialization stuff without daemon.
179 while read -u3 cmd
180 do    case $cmd in
181        //*) continue;;
182       ---*) break;;
183          *) eval "$cmd";;
184       esac
185 done
186
187 # If we're testing over nfs, remount the filesystem to clear the cache.
188 case $fs_type in
189    nfs2) print "Clearing nfs2 cache by remounting filesystem..."
190          eval "umount $fs_mtpt"
191          eval "mount -t nfs2 localhost:$3 $fs_mtpt";;
192    nfs3) print "Clearing nfs3 cache by remounting filesystem..."
193          eval "umount $fs_mtpt"
194          eval "mount -t nfs3 localhost:$3 $fs_mtpt";;
195       *) if [[ $fs_type != "" ]] 
196          then print "ERROR: $fs_type not a known or testable filesystem type"
197          fi;;
198 esac
199     
200
201 # Check with the user before starting up daemon
202 print "\n** Using testfile ${datafile##*/} **"
203 print "** Using userid $lname for tests not requiring root access **"
204 print "Press enter to begin, or enter q or n to abort..."
205 read go
206 case "$go" in
207     n|N|q|Q) exit 1;;
208     *);;
209 esac
210
211 # Now, the user will need ownership of the test directory 
212 # ($2, not $real_dir, since real_dir is accessed only as root).
213 eval "chown $lname $2"
214
215 # Now it's time to begin running the daemon as a coprocess.
216 # The daemon will use a : as its internal field separator.
217 IFS=":"
218 if (($sleeptime > 0)) then 
219     $1/dm_test_daemon -s $sleeptime $3 |&
220 else
221     $1/dm_test_daemon $3 |&
222 fi
223
224 #Keep track of the coprocess id... "$!" may change.
225 coproc=$!
226
227 # Initialize the count of errors
228 error_count=0;
229
230 # dm_test_daemon starts with a spurious line feed.
231 read -p junk
232
233 # Finally, we've reached the actual loop to read in the testfile.
234 while true
235 do    
236       clear
237       while read -u3 cmd
238       do
239             case $cmd in
240             run_without_test)
241                 while read -u3 cmd
242                 do  case $cmd in
243                     ---*) clear; continue 2;;
244                      //*) continue;;
245                      @@*) cmd=${cmd#@@*}
246                           print "!!  ${cmd# *}"
247                           continue;;
248                        *) eval $cmd;;
249                     esac
250                 done;;
251             run_as_root)
252                 read -u3 cmd
253                 root_flag=1
254                 break;;
255             //*)  continue;;
256             @@*) cmd=${cmd#@@*}
257                  print "!!  ${cmd# *}"
258                  continue;;
259               *) root_flag=0
260                  break;;
261             esac
262       done
263       if (( $root_flag == 1 ))
264       then print "Command to execute (as root):\n\n   $cmd\n"
265            eval "$cmd"
266       else print "Command to execute:\n\n   $cmd\n"
267            eval "su $lname -c \"$cmd\""
268       fi
269
270       # Note failure of the command.  Also, send a message
271       # that the command is done.  We will know we're done
272       # reading from the daemon when we see this message. 
273       fail_flag=$?
274       $1/send_msg over
275       print
276
277       # Reset variables for reading this command.
278       event_count=0
279       unset contents event fs_handle handle length offset
280       unset media_designator mode mountpoint_handle
281       unset mountpoint_path msg_str name new_name new_parent
282       unset parent_handle ret_code root_handle sequence token  
283       unset tries_left unmount_mode
284
285       # Read events, report them, and store their data.
286       while true 
287       do 
288          read -p event[event_count]
289          case "${event[event_count]}" in
290          mount) 
291             print "Report: found mount event."
292             read -p junk token[event_count]
293             read -p junk sequence[event_count]
294             read -p junk fs_handle[event_count]
295             read -p junk mountpoint_handle[event_count]
296             read -p junk mountpoint_path[event_count]
297             read -p junk media_designator[event_count]
298             read -p junk root_handle[event_count]
299             read -p junk mode[event_count]
300             read -p junk;;
301          preunmount) 
302             print "Report: found preunmount event."
303             read -p junk token[event_count]
304             read -p junk sequence[event_count]
305             read -p junk fs_handle[event_count]
306             read -p junk root_handle[event_count]
307             read -p junk unmount_mode[event_count]
308             read -p junk;;
309          unmount) 
310             print "Report: found unmount event."
311             read -p junk token[event_count]
312             read -p junk sequence[event_count]
313             read -p junk fs_handle[event_count]
314             read -p junk unmount_mode[event_count]
315             read -p junk ret_code[event_count]
316             read -p junk;;
317          nospace) 
318             print "Report: found nospace event."
319             read -p junk token[event_count]
320             read -p junk sequence[event_count]
321             read -p junk fs_handle[event_count]
322             read -p junk;;
323          create|remove) 
324             print "Report: found ${event[event_count]} event."
325             read -p junk token[event_count]
326             read -p junk sequence[event_count]
327             read -p junk parent_handle[event_count]
328             read -p junk name[event_count]
329             read -p junk mode[event_count]
330             read -p junk;;
331          postcreate) 
332             print "Report: found postcreate event."
333             read -p junk token[event_count]
334             read -p junk sequence[event_count]
335             read -p junk parent_handle[event_count]
336             read -p junk handle[event_count]
337             read -p junk name[event_count]
338             read -p junk mode[event_count]
339             read -p junk ret_code[event_count]
340             read -p junk;;
341          postremove) 
342             print "Report: found postremove event."
343             read -p junk token[event_count]
344             read -p junk sequence[event_count]
345             read -p junk parent_handle[event_count]
346             read -p junk name[event_count]
347             read -p junk mode[event_count]
348             read -p junk ret_code[event_count]
349             read -p junk;;
350          rename) 
351             print "Report: found rename event."
352             read -p junk token[event_count]
353             read -p junk sequence[event_count]
354             read -p junk parent_handle[event_count]
355             read -p junk new_parent[event_count]
356             read -p junk name[event_count]
357             read -p junk new_name[event_count]
358             read -p junk;;
359          postrename) 
360             print "Report: found postrename event."
361             read -p junk token[event_count]
362             read -p junk sequence[event_count]
363             read -p junk parent_handle[event_count]
364             read -p junk new_parent[event_count]
365             read -p junk name[event_count]
366             read -p junk new_name[event_count]
367             read -p junk ret_code[event_count]
368             read -p junk;;
369          symlink) 
370             print "Report: found symlink event."
371             read -p junk token[event_count]
372             read -p junk sequence[event_count]
373             read -p junk parent_handle[event_count]
374             read -p junk name[event_count]
375             read -p junk contents[event_count]
376             read -p junk;;
377          postsymlink) 
378             print "Report: found postsymlink event."
379             read -p junk token[event_count]
380             read -p junk sequence[event_count]
381             read -p junk parent_handle[event_count]
382             read -p junk handle[event_count]
383             read -p junk name[event_count]
384             read -p junk contents[event_count]
385             read -p junk ret_code[event_count]
386             read -p junk;;
387          link) 
388             print "Report: found link event."
389             read -p junk token[event_count]
390             read -p junk sequence[event_count]
391             read -p junk parent_handle[event_count]
392             read -p junk handle[event_count]
393             read -p junk name[event_count]
394             read -p junk;;
395          postlink) 
396             print "Report: found postlink event."
397             read -p junk token[event_count]
398             read -p junk sequence[event_count]
399             read -p junk parent_handle[event_count]
400             read -p junk handle[event_count]
401             read -p junk name[event_count]
402             read -p junk ret_code[event_count]
403             read -p junk;;
404          read|write|truncate) 
405             print "Report: found ${event[event_count]} event."
406             read -p junk token[event_count]
407             read -p junk sequence[event_count]
408             read -p junk handle[event_count]
409             read -p junk offset[event_count]
410             read -p junk length[event_count]
411             read -p junk;;
412          attribute) 
413             print "Report: found attribute event."
414             read -p junk token[event_count]
415             read -p junk sequence[event_count]
416             read -p junk handle[event_count]
417             read -p junk;;
418          destroy) 
419             print "Report: found destroy event."
420             read -p junk token[event_count]
421             read -p junk sequence[event_count]
422             read -p junk handle[event_count]
423             read -p junk name[event_count]
424             read -p junk contents[event_count]
425             read -p junk;;
426          user) 
427             read -p junk token[event_count]
428             read -p junk sequence[event_count]
429             read -p junk msg_str[event_count]
430             case "${msg_str[event_count]}" in
431                 "over") read -p junk 
432                         event[event_count]=end_of_tests
433                         print "Report: found \"end of test\" user event. "
434                         break;;
435                 *) print "Report: found user event. "
436                    read -p junk;; 
437             esac;;
438          pending)
439             read -p junk tries_left[event_count]
440             print -n "Report: process pending. "
441             print "Tries left: ${tries_left[event_count]}"
442             read -p junk;;
443          *) 
444             print -n "Report: found ${event[event_count]} event. "
445             print    "(unknown to this version)"
446             while read -p msg_str[event_count]
447             do case "${msg_str[event_count]}" in
448                     "end_of_message") break;;
449                     *);;
450                esac
451             done;;
452          esac
453          ((event_count=event_count+1))
454       done
455       ((old_error_count=error_count));
456
457       IFS=" "
458
459       while read -u3 val_one val_two val_tre
460       do case $val_one in
461          ---*)  if [[ $fail_flag != -1 ]]
462                 then if [[ $fail_flag != 0 ]]
463                      then print -n "ERROR: command failed; it was "
464                           print "expected to succeed."
465                           ((error_count=error_count+1))
466                      fi
467                 fi
468                 if (( error_count>old_error_count || pause_flag==1 )) 
469                 then print "\nEnter q to quit, or press enter to continue..."
470                      read go
471                      case "$go" in
472                      q|Q) break;;
473                      *);;
474                      esac
475                 fi
476                 IFS=":"
477                 continue 2;;
478          failure)
479            if [[ $fail_flag = 0 ]] 
480            then print "ERROR: command succeeded; it was expected to fail."
481            ((error_count=error_count+1))
482            else print "Note: command is expected to fail."
483            fi
484            fail_flag=-1;;
485          *) case $val_two in
486             matches)  
487                if [[ $(eval "print $"{$val_one}) = $(eval "print $"{$val_tre}) ]] 
488                then print "Report: $val_one and $val_tre match; both are "
489                     if [[ $(eval "print $"{$val_one}) = "" ]]
490                     then print "unset"
491                     else print "$(eval "print $"{$val_one})"
492                     fi
493                else print -n "ERROR: $val_one was "
494                     if [[ $(eval "print $"{$val_one}) = "" ]]
495                     then print -n "unset "
496                     else print -n "equal to $(eval "print $"{$val_one})"
497                     fi
498                     print -n ", while $val_tre was "
499                     if [[ $(eval "print $"{$val_tre}) = "" ]]
500                     then print "unset."
501                     else print "equal to $(eval "print $"{$val_tre})."
502                     fi
503                     ((error_count=error_count+1))
504                fi;;
505             store_in) 
506                eval ${val_tre}=$(eval "print $"{$val_one})
507                print -n "Report: value of ${val_one} copied into "
508                print "${val_tre}.";;
509             *) 
510                if [[ $(eval "print $"{$val_one}) = $val_two ]] 
511                then :
512                else if [[ "$val_one" = event_count ]]
513                     then print -n "ERROR: expected $val_two event(s), "
514                          print "but found $event_count."
515                          else print -n "ERROR: $val_one was "
516                          if [[ $(eval "print $"{$val_one}) = "" ]]
517                          then print -n "unset "
518                          else print -n "equal to $(eval "print $"{$val_one}) "
519                          fi
520                          print "rather than $val_two as expected."
521                     fi 
522                        ((error_count=error_count+1))
523                fi;;
524             esac;;
525          esac
526       done
527       if [[ $fail_flag != -1 ]] 
528       then if [[ $fail_flag != 0 ]]
529            then print -n "ERROR: command failed; it was "
530                 print "expected to succeed."
531                 ((error_count=error_count+1))
532            fi
533       fi
534       if (( error_count>old_error_count || pause_flag==1 )) 
535       then print "\nTests complete.  Press enter to quit..."
536            read go
537       fi
538       break
539 done
540
541 # Close the datafile
542 exec 3<&-
543
544 # End the daemon
545 kill $coproc
546 wait $coproc
547
548 clear
549 if ((error_count==1)) 
550 then print "Test result: 1 error found."
551 else print "Test result: $error_count errors found."
552 fi