blob: 159aba7664f705b781000440877904ce9d7a8b5b [file] [log] [blame]
mbligh05269362007-10-16 16:58:11 +00001# Copyright Martin J. Bligh, Andy Whitcroft, 2007
2#
3# Shell class for a test, inherited by all individual tests
4#
5# Methods:
6# __init__ initialise
7# initialize run once for each job
8# setup run once for each new version of the test installed
9# run run the test (wrapped by job.run_test())
10#
11# Data:
12# job backreference to the job this test instance is part of
13# outputdir eg. results/<job>/<testname.tag>
14# resultsdir eg. results/<job>/<testname.tag>/results
15# profdir eg. results/<job>/<testname.tag>/profiling
16# debugdir eg. results/<job>/<testname.tag>/debug
17# bindir eg. tests/<test>
18# src eg. tests/<test>/src
19# tmpdir eg. tmp/<test>
20
21import os, pickle, tempfile, re
22from subcommand import *
mblighf31b0c02007-11-29 18:19:22 +000023from common.error import *
mbligh05269362007-10-16 16:58:11 +000024from utils import *
25
26class test:
27 preserve_srcdir = False
28
29 def __init__(self, job, bindir, outputdir):
30 testname = self.__class__.__name__
31
32 self.job = job
mblighecf55f42008-01-14 16:54:51 +000033
mbligh05269362007-10-16 16:58:11 +000034 self.outputdir = outputdir
mblighecf55f42008-01-14 16:54:51 +000035 tagged_testname = os.path.basename(self.outputdir)
36 # check if the outputdir already exists, because if it does
37 # then this test has already been run with the same tag earlier
38 # in this job
39 if os.path.exists(self.outputdir):
40 testname, tag = (tagged_testname + '.').split('.', 1)
41 msg = ("%s already exists, test <%s> may have already "
42 + "run with tag <%s>") % (tagged_testname,
43 testname, tag)
44 raise TestError(msg)
45 else:
46 os.mkdir(self.outputdir)
47
mbligh05269362007-10-16 16:58:11 +000048 self.resultsdir = self.outputdir + "/results"
49 os.mkdir(self.resultsdir)
50 self.profdir = self.outputdir + "/profiling"
51 os.mkdir(self.profdir)
52 self.debugdir = self.outputdir + "/debug"
53 os.mkdir(self.debugdir)
54
55 self.bindir = bindir
56 self.srcdir = bindir + '/src'
57
58 self.tmpdir = job.tmpdir + '/' + testname
59 if os.path.exists(self.tmpdir):
60 system('rm -rf ' + self.tmpdir)
61 os.mkdir(self.tmpdir)
62
63 self.initialize()
64 # compile and install the test, if needed.
65 update_version(self.srcdir, self.preserve_srcdir, self.version, self.setup)
66
67
mblighdccabe32008-02-01 17:39:32 +000068 def assert_(self, expr, msg='Assertion failed.'):
69 if not expr:
70 raise TestError(msg)
71
72
mbligh05269362007-10-16 16:58:11 +000073 def initialize(self):
74 pass
75
76
77 def setup(self):
78 pass
79
80
mbligh29d65032007-10-25 15:51:06 +000081 def cleanup(self):
82 pass
83
84
mbligh05269362007-10-16 16:58:11 +000085 def run(self, args, dargs):
86 try:
87 # self.job.stdout.tee_redirect(
88 # os.path.join(self.debugdir, 'stdout'))
89 # self.job.stderr.tee_redirect(
90 # os.path.join(self.debugdir, 'stderr'))
91
mbligh29d65032007-10-25 15:51:06 +000092 try:
93 os.chdir(self.outputdir)
94 write_keyval(self.outputdir, { 'version':self.version })
95 self.execute(*args, **dargs)
96 finally:
97 self.cleanup()
mbligh05269362007-10-16 16:58:11 +000098 # self.job.stderr.restore()
99 # self.job.stdout.restore()
100 except AutotestError:
101 raise
102 except:
103 raise UnhandledError('running test ' + \
104 self.__class__.__name__ + "\n")
105
106
107def testname(url):
108 # Extract the testname from the test url.
109 match = re.match('[^:]+://(.*)/([^/]*)$', url)
110 if not match:
111 return ('', url)
112 (group, filename) = match.groups()
113
114 # Generate the group prefix.
115 gfix = re.compile('\W')
116 group = gfix.sub('_', group)
117
118 # Drop the extension to get the raw test name.
119 tfix = re.compile('\.tgz')
120 testname = tfix.sub('', filename)
121
122 return (group, testname)
123
124
125def __installtest(job, url):
126 (group, name) = testname(url)
127
128 ##print "group=%s name=%s" % (group, name)
129
130 # Bail if the test is already installed
131 group_dir = os.path.join(job.testdir, "download", group)
132 if os.path.exists(os.path.join(group_dir, name)):
133 return (group, name)
134
135 # If the group directory is missing create it and add
136 # an empty __init__.py so that sub-directories are
137 # considered for import.
138 if not os.path.exists(group_dir):
139 os.mkdir(group_dir)
140 f = file(os.path.join(group_dir, '__init__.py'), 'w+')
141 f.close()
142
143 print name + ": installing test url=" + url
144 system("wget %s -O %s" % (url, os.path.join(group_dir, 'test.tgz')))
145 system("cd %s; tar zxf %s" % (group_dir, 'test.tgz'))
146 os.unlink(os.path.join(group_dir, 'test.tgz'))
147
148 # For this 'sub-object' to be importable via the name
149 # 'group.name' we need to provide an __init__.py,
150 # so link the main entry point to this.
151 os.symlink(name + '.py', os.path.join(group_dir, name,
152 '__init__.py'))
153
154 # The test is now installed.
155 return (group, name)
156
157
158# runtest: main interface for importing and instantiating new tests.
159def __runtest(job, url, tag, args, dargs):
160 (group, testname) = ('', url)
161 bindir = os.path.join(job.testdir, group, testname)
162
163 outputdir = os.path.join(job.resultdir, testname)
164 if (tag):
165 outputdir += '.' + tag
166 if os.path.exists(outputdir):
167 system('rm -rf ' + outputdir)
168
169 if not os.path.exists(bindir):
170 raise TestError(testname + ": test does not exist")
171
172 try:
173 if group:
174 sys.path.insert(0, os.path.join(job.testdir,
175 "download"))
176 group += '.'
177 else:
178 sys.path.insert(0, os.path.join(job.testdir, testname))
179
180 exec "import %s%s" % (group, testname)
181 exec "mytest = %s%s.%s(job, bindir, outputdir)" % \
182 (group, testname, testname)
183 finally:
184 sys.path.pop(0)
185
186 pwd = os.getcwd()
187 os.chdir(outputdir)
188 mytest.run(args, dargs)
189 os.chdir(pwd)
190
191
192def runtest(job, url, tag, args, dargs):
193 t = subcommand(__runtest, [job, url, tag, args, dargs])
194 t.fork_start()
195 t.fork_waitfor()