[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[LTP] Quick Hack

In an effort to get a working automated execution framework for the
tests, decided to learn python and hack something togther.

The base configuration is a 'command list' file.  It contains something
like this:
test_alarm01 alarm01
test_alarm02 alarm02

Each line describes a particular test.  The first token is a unique id
for each test.  The rest of the tokens on the line is the test command.

Here's an example run:

$ ./runtests.py cmdlist
test_alarm01: running cmdline 'alarm01'
test_alarm01: stdout:
alarm01     1  PASS  :  alarm(1) returned 0
test_alarm01: result: PASS
test_alarm02: running cmdline 'alarm02'
test_alarm02: stdout:
alarm02     1  PASS  :  alarm(4294967295) returned 0 as expected for
value -1.
alarm02     2  PASS  :  alarm(4294967295) returned 0 as expected for
value ULONG_MAX.
alarm02     3  PASS  :  alarm(0) returned 0 as expected for value
test_alarm02: result: PASS

It runs the command, gathering the output and exit status. Then it
prints the output and issues a simple PASS or FAIL for the particular
test based on exit status.  Simple? Yes.  Complete? No.

 - The CLI ops need to be improved to allow specification of a
particular test id to be run. Example: runtests.py -t test_alarm01
cmdlist quickhit.list
 - PATH needs to be set to include the location of all the tests before
running the harness.
 - No multi-process support
 - needs some randomization
 - no configuration analysis capability

There are currently three python files, runtest, runtests, and testobj. 
runtests is the base command, the others are modules that runtests
utilizes.  The synopsis is: runtests.py [cmdfile [cmdfile ...]]



Aaron Laffin
Silicon Graphics, Inc. OS Test Development
Email: alaffin@sgi.com Voice: 651-683-5756
access01 access01
access03 access03
alarm01 alarm01
alarm02 alarm02
alarm03 alarm03
asyncio02 asyncio02
chdir02 chdir02
chmod02 chmod02
chown01 chown01
close08 close08
creat09 creat09
dup01 dup01
dup02 dup02
dup03 dup03
dup04 dup04
dup05 dup05
execl01 execl01
execle01 execle01
execlp01 execlp01
execv01 execv01
execve01 execve01
execvp01 execvp01
fchmod01 fchmod01
fchown01 fchown01
fcntl02 fcntl02
fcntl03 fcntl03
fcntl04 fcntl04
fcntl05 fcntl05
fcntl07 fcntl07
fcntl07B fcntl07B
fcntl08 fcntl08
fcntl09 fcntl09
fcntl10 fcntl10
fork01 fork01
fork04 fork04
fpathconf01 fpathconf01
fstat01 fstat01
fsync01 fsync01
getegid01 getegid01
geteuid01 geteuid01
getgid01 getgid01
getgroups01 getgroups01
getgroups02 getgroups02
gethostid01 gethostid01
gethostname01 gethostname01
getpgrp01 getpgrp01
getpid01 getpid01
getppid01 getppid01
getuid01 getuid01
kill09 kill09
link02 link02
link03 link03
link04 link04
link05 link05
lseek01 lseek01
lseek02 lseek02
lseek04 lseek04
lseek05 lseek05
lstat02 lstat02
mkdir01 mkdir01
mkdir08 mkdir08
mknod01 mknod01
nice05 nice05
open03 open03
pathconf01 pathconf01
pause01 pause01
readlink02 readlink02
rename02 rename02
rmdir04 rmdir04
sbrk01 sbrk01
select01 select01
setgid01 setgid01
setgroups01 setgroups01
setpgid01 setpgid01
setregid01 setregid01
setreuid01 setreuid01
setuid01 setuid01
setuid02 setuid02
stat05 stat05
sync01 sync01
time01 time01
times01 times01
ulimit01 ulimit01
umask01 umask01
uname01 uname01
unlink05 unlink05
unlink06 unlink06
unlink07 unlink07
wait02 wait02
write01 write01
symlink01 symlink01
symlink02 symlink02
readlink01 symlink01 -T readlink01
stat04 symlink01 -T stat04
lstat01 symlink01 -T lstat01
mkdir05 symlink01 -T mkdir05
rmdir03 symlink01 -T rmdir03
chdir01 symlink01 -T chdir01
link01 symlink01 -T link01
unlink01 symlink01 -T unlink01
chmod01 symlink01 -T chmod01
utime01 symlink01 -T utime01
rename01 symlink01 -T rename01
open01 symlink01 -T open01

gf01 growfiles -b -e 1 -u -i 0 -L 20 -w -C 1 -l -I r -T 10 glseek20 glseek20.2
gf02 growfiles -b -e 1 -L 10 -i 100 -I p -S 2 -u -f gf03_
gf03 growfiles -b -e 1 -g 1 -i 1 -S 150 -u -f gf05_
gf04 growfiles -b -e 1 -g 4090 -i 500 -t 39000 -u -f gf06_
gf05 growfiles -b -e 1 -g 5000 -i 500 -t 49900 -T10 -c9 -I p -u -f gf07_
gf06 growfiles -b -e 1 -u -r 1-5000 -R 0--1 -i 0 -L 30 -C 1 g_rand10 g_rand10.2
gf07 growfiles -b -e 1 -u -r 1-5000 -R 0--2 -i 0 -L 30 -C 1 -I p g_rand13 g_rand13.2
gf08 growfiles -b -e 1 -u -r 1-5000 -R 0--2 -i 0 -L 30 -C 1 g_rand11 g_rand11.2
gf09 growfiles -b -e 1 -u -r 1-5000 -R 0--1 -i 0 -L 30 -C 1 -I p g_rand12 g_rand12.2
gf10 growfiles -b -e 1 -u -r 1-5000 -i 0 -L 30 -C 1 -I l g_lio14 g_lio14.2
gf11 growfiles -b -e 1 -u -r 1-5000 -i 0 -L 30 -C 1 -I L g_lio15 g_lio15.2
gf12 mkfifo gffifo17; growfiles -b -e 1 -u -i 0 -L 30 gffifo17
gf13 mkfifo gffifo18; growfiles -b -e 1 -u -i 0 -L 30 -I r -r 1-4096 gffifo18
gf14 growfiles -b -e 1 -u -i 0 -L 20 -w -l -C 1 -T 10 glseek19 glseek19.2
gf15 growfiles -b -e 1 -u -r 1-49600 -I r -u -i 0 -L 120 Lgfile1
gf16 growfiles -b -e 1 -i 0 -L 120 -u -g 4090 -T 100 -t 408990 -l -C 10 -c 1000 -S 10 -f Lgf02_
gf17 growfiles -b -e 1 -i 0 -L 120 -u -g 5000 -T 100 -t 499990 -l -C 10 -c 1000 -S 10 -f Lgf03_
gf18 growfiles -b -e 1 -i 0 -L 120 -w -u -r 10-5000 -I r -T 10 -l -S 2 -f Lgf04_
gf19 growfiles -b -e 1 -g 5000 -i 500 -t 49900 -T10 -c9 -I p -o O_RDWR,O_CREAT,O_TRUNC -u -f gf08i_
gf20 growfiles -D 0 -b -i 0 -L 60 -u -B 1000b -e 1 -r 1-256000:512 -R 512-256000 -T 4 gfbigio-$$
gf21 growfiles -D 0 -b -i 0 -L 60 -u -B 1000b -e 1 -g 20480 -T 10 -t 20480 gf-bld-$$
gf22 growfiles -D 0 -b -i 0 -L 60 -u -B 1000b -e 1 -g 20480 -T 10 -t 20480 gf-bldf-$$
gf23 growfiles -D 0 -b -i 0 -L 60 -u -B 1000b -e 1 -r 512-64000:1024 -R 1-384000 -T 4 gf-inf-$$
gf24 growfiles -D 0 -b -i 0 -L 60 -u -B 1000b -e 1 -g 20480 gf-jbld-$$
gf25 growfiles -D 0 -b -i 0 -L 60 -u -B 1000b -e 1 -r 1024000-2048000:2048 -R 4095-2048000 -T 1 gf-large-gs-$$
gf26 growfiles -D 0 -b -i 0 -L 60 -u -B 1000b -e 1 -r 128-32768:128 -R 512-64000 -T 4 gfsmallio-$$
gf27 growfiles -b -D 0 -w -g 8b -C 1 -b -i 1000 -u gfsparse-1-$$
gf28 growfiles -b -D 0 -w -g 16b -C 1 -b -i 1000 -u gfsparse-2-$$
gf29 growfiles -b -D 0 -r 1-4096 -R 0-33554432 -i 0 -L 60 -C 1 -u gfsparse-3-$$
gf30 growfiles -D 0 -b -i 0 -L 60 -u -B 1000b -e 1 -o O_RDWR,O_CREAT,O_SYNC -g 20480 -T 10 -t 20480 gf-sync-$$
rwtest01 rwtest -c -q -i 60s  -f sync 10%25000:rw-sync-$$
rwtest02 rwtest -c -q -i 60s  -f buffered 10%25000:rw-buffered-$$
rwtest03 rwtest -c -q -i 60s -n 2  -f buffered -s mmread,mmwrite -m random -Dv 10%25000:mm-buff-$$
rwtest04 rwtest -c -q -i 60s -n 2  -f sync -s mmread,mmwrite -m random -Dv 10%25000:mm-sync-$$
rwtest05 rwtest -q -c -i 50 -T 64b 500b:/tmp/rwtest01%f

#must be run as root
iogen01 iogen -i 120s -s read,write 500b:doio.f1.$$ 1000b:doio.f2.$$ | doio -akv -n 2

import os
import sys
import string
import popen2

def execute(id,cmd):
    print "%s: running cmdline '%s'"%(id,cmd)
    subproc = popen2.Popen3(cmd,1)
    exit_status = subproc.wait()>>8
    stdout_lines = subproc.fromchild.readlines()
    stderr_lines = subproc.childerr.readlines()
    if len(stdout_lines) > 0:
      print "%s: stdout:" % (id)
      for line in stdout_lines:
        line = string.strip(line)
        print line
    if len(stderr_lines) > 0:
      print "%s: stderr:" % (id)
      for line in stderr_lines:
        line = string.strip(line)
        print line

    if exit_status != 0:
      print '%s: exit: %d' %(id,exit_status)
      result = "FAIL"
      result = "PASS"

    print "%s: result: %s" % (id,result)
    return exit_report

import string
import testobj
import sys
import os


# read from multiple files all the lines in the files

for file in fargs:
    testfile = open(file,'r')
  except IOError, otherdata:
    print 'IOError:', otherdata 

tlist = testobj.test_list()

# for each line, try to build a test object.  Add each test
# object to the test list.

for line in lineset:
    new_test_obj = testobj.test(line)
  except testobj.test.TestNoObjectError:
  except testobj.test.TestBadObjectError:
    print "bad test record '%s'" % (string.strip(line))
  except testobj.test_list.TestNameExistsError, tname:
    print "Test name '%s' already exists, ignoring" % (tname)

# run all the tests in the test list
import string
import runtest

# Test object contains a test identifier and an associated command
# line.  The constructor is passed a string which contains an id
# token followed by the tokens of the command line of the test.
# TestNoObjectError is raised when the line is blank or contains only
# comments.
# TestBadObjectError is raised when there are not two tokens in the
# line: id & cmd

class test:
  TestNoObjectError = 'Failed attempt to create test object with no information'
  TestBadObjectError = 'Failed attempt to create test object with incomplete information'
  def __init__(self, t_line):
    l_line = string.strip(t_line)

    # look for comments
    if cmt_start != -1:
      l_line = l_line[:cmt_start]
      l_line = string.strip(l_line)
    if l_line == '':
      raise test.TestNoObjectError 

    self.d_name = string.split(l_line)[0]
    self.d_cmd = string.join(string.split(l_line)[1:])

    if self.d_name == '' or self.d_cmd == '':
      raise test.TestBadObjectError 

  def name(self):
    return self.d_name
  def command(self):
    return self.d_cmd

  def __cmp__(self,other):
    if type(other) == type(self.d_name):
      return cmp(self.d_name,other)
      return cmp(self.d_name,other.d_name)

# test_list is a class which is intended to contain a list of the test objects.
# The test object ids must be unique, otherwise a TestNameExistsError exception
# is thrown.

class test_list:
  TestNameExistsError = 'Attempt to add test object with duplicate id'

  def __init__(self):
    self.d_testlist = []

  def add(self, a_tobj):
    for obj in self.d_testlist:
      if obj == a_tobj:
        raise test_list.TestNameExistsError, a_tobj.name()

  def echo(self):
    for obj in self.d_testlist:
      print "%s %s" % \

  def run(self):
    for obj in self.d_testlist:
      exit_report = exit_report | runtest.execute(obj.name(),obj.command())
    return exit_report