Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
141 Kevin 1
#!/usr/bin/python
2
#
3
#Script: stdriver.py
4
#Author: Patrick Boyd
5
#
6
#Purpose: Run point-valued python test scripts and generate a grade sheet
7
#
8
#Description:
9
#Runs a set of python tests as determined by the contents of the input file.
10
#The contents of the .txt file should appear as follows:
11
#   = test group 1
12
#   5 test_worth_5.py
13
#   10 test_worth 10.py
14
#   15 test_worth_15.py
15
#   = test group 2
16
#   20 test_worth 20.py
17
#   25 test_worth 25.py
18
#   ...
19
#
20
#These tests will then be spawned into their own subprocesses and ran,
21
#and their results will be recorded.  If the verbose option is enabled,
22
#error information will be displayed.
23
#
24
#
25
#
26
 
27
import getopt, os, sys, subprocess, re
28
 
29
# add directory in which script is located to python path
30
script_dir = "/".join(__file__.split("/")[:-1])
31
if script_dir == "":
32
    script_dir = "."
33
if script_dir not in sys.path:
34
    sys.path.append(script_dir)
35
 
36
verbose = False
37
output_spec_file = "./eshoutput.py"
38
plugin_directory = ""
39
test_base = "./eshtests/"
40
milestone_test_file = "milestone.tst"
41
basic_test_file = "basic.tst"
42
reduced_test_file = "reduced.tst"
43
advanced_test_file = "advanced.tst"
44
testfilter = None
45
 
46
def usage():
47
    print """
48
Usage: python stdriver.py [options] [tests1.tst tests2.tst] ... 
49
    -m              Run milestone tests 
50
    -p plugin_dir   Run plugins from the supplied directory
51
    -b              Run basic tests
52
    -v              Verbose 
53
    -h              Show help 
54
    -o outputspec   Run using this output spec file
55
    -t testname     Run only tests whose names contains 'testname'
56
    -l              List available tests (not implemented)
57
    -a              Run advanced tests
58
    """
59
 
60
try:
61
    opts, args = getopt.getopt(sys.argv[1:], "ahvmrbo:p:t:", \
62
        ["help", "outputspec=", "test="])
63
except getopt.GetoptError, err:
64
    # print help information and exit:
65
    print str(err) # will print something like "option -a not recognized"
66
    usage()
67
    sys.exit(2)
68
 
69
for o, a in opts:
70
    if o == "-v":
71
        verbose = True
72
    elif o in ("-h", "--help"):
73
        usage()
74
        sys.exit()
75
    elif o in ("-t", "--test"):
76
        testfilter = a
77
    elif o in ("-m"):
78
        args = [test_base + milestone_test_file]
79
    elif o in ("-b"):
80
        args = [test_base + basic_test_file]
81
    elif o in ("-a"):
82
        args = [test_base + advanced_test_file]
83
    elif o in ("-r"):
84
        #args = [test_base + reduced_test_file]
85
        print "-r is no longer allowed"
86
        usage()
87
        sys.exit()
88
    elif o in ("-p"):
89
        plugin_directory = a
90
    elif o in ("-o"):
91
        output_spec_file = a
92
    else:
93
        assert False, "unhandled option"
94
 
95
if plugin_directory != "" and not os.access(plugin_directory, os.R_OK):
96
    print "Directory ", plugin_directory, " is not readable"
97
    print "You must create this plugin directory if you wish to test plugins"
98
    sys.exit(1)
99
else:
100
    plugin_directory = " -p " + plugin_directory
101
 
102
if not os.access(output_spec_file, os.R_OK):
103
    print "File ", output_spec_file, " is not readable"
104
    print "You must create this file and adapt it to match the output of your shell"
105
    sys.exit(1)
106
 
107
full_testlist = []
108
if len(args) == 0:
109
    usage()
110
    sys.exit(1)
111
 
112
for testlist_filename in args:
113
    try:
114
        testlist_file = open(testlist_filename, 'r')
115
        test_dir = os.path.dirname(testlist_filename)
116
        if test_dir == "":
117
            test_dir = './'
118
        else:
119
            test_dir = test_dir + '/'
120
    except:
121
        print 'Error: Tests list file: ''%s'' could not be opened.'% testlist_filename
122
        sys.exit(-1)
123
 
124
    #File input, read in the test filenames
125
    #test information is placed into tuples that are placed onto a 2d list
126
    for line in testlist_file:
127
 
128
        grps = re.match("^= (.+)", line)
129
        if grps:
130
            testset = { 'name' : grps.group(1), 
131
                        'tests' : [ ], 
132
                        'dir' : test_dir }
133
            full_testlist.append(testset)
134
        else:
135
            grps = re.match("(\d+) (.+)", line)
136
            if grps:
137
                points, testname = int(grps.group(1)), grps.group(2)
138
                if not testfilter or testname.find(testfilter) != -1:
139
                    testset['tests'].append((points, testname))
140
 
141
    testlist_file.close()
142
 
143
# print full_testlist
144
 
145
process_list = []
146
 
147
#Run through each test set in the list
148
for testset in full_testlist:
149
    print testset['name']
150
    print '-------------------------'
151
 
152
    #Run through each test in the set
153
    testresults = [ ]
154
    for (points, testname) in testset['tests']:
155
 
156
        print str(points) + '\t' + testname + ':',
157
        sys.stdout.flush()
158
 
159
        # run test
160
        child_process = subprocess.Popen(["python", testset['dir'] + testname, \
161
                             output_spec_file, plugin_directory],\
162
                             stderr=subprocess.PIPE, stdout=subprocess.PIPE)
163
        test_passed = child_process.wait() == 0
164
 
165
        # build result list
166
        testresults.append((points, testname, child_process, test_passed))
167
 
168
        #if: test passed
169
        if test_passed:
170
            print ' PASS'
171
        else:
172
            print ' FAIL'
173
    print ""
174
    testset['tests'] = testresults
175
 
176
 
177
    #Grade sheet printing.  It prints each individual test and the points awarded
178
    #from that test, the points awarded from each set of tests, and the total
179
    #points awarded over the entire test.
180
 
181
    #Run through each set of tests in the list
182
    testset_points = 0
183
    testset_points_earned = 0
184
 
185
    #Run through each test in the set
186
    for (points, testname, child_process, test_passed) in testset['tests']:
187
        testset_points += points
188
        points_earned = points
189
        if not test_passed:
190
            points_earned = 0
191
 
192
        print '\t%s\t%d/%d' % (testname, points_earned, points)
193
        testset_points_earned += points_earned
194
 
195
    print '-------------------------'
196
 
197
    print testset['name'] + '\t' + str(testset_points_earned) + '/' + \
198
                                                        str(testset_points)
199
 
200
 
201
 
202
#Verbose printing.  If the verbose option was enabled, print the error
203
#information from the tests that failed.
204
if verbose:
205
    print '\nError Output'
206
    print '-------------------------'
207
    for testset in full_testlist:
208
        for (points, testname, child_process, test_passed) in testset['tests']:
209
            if not test_passed:
210
                print testname + ':'
211
                (stdout, stderr) = child_process.communicate()
212
                print stdout, stderr
213