5
7
from commands import getstatusoutput
8
from datetime import datetime
8
from abrek.utils import geturl
11
from abrek.utils import geturl, write_file
10
13
class AbrekTest(object):
14
"""Base class for defining tests.
12
16
This can be used by test definition files to create an object that
13
17
contains the building blocks for installing tests, running them,
14
18
and parsing the results.
19
23
runner - AbrekRunner instance to use
20
24
parser - AbrekParser instance to use
23
26
def __init__(self, testname, version="", installer=None, runner=None,
25
28
self.config = abrek.config.AbrekConfig()
28
31
self.installer = installer
29
32
self.runner = runner
30
33
self.parser = parser
34
self.installdir = os.path.join(self.config.installdir, self.testname)
31
35
self.origdir = os.path.abspath(os.curdir)
35
Install the test suite. This creates an install directory under
36
the user's XDG_DATA_HOME directory to mark that the test is installed.
37
The installer's install() method is then called from this directory
38
to complete any test specific install that may be needed.
41
path = os.path.join(self.config.installdir, self.testname)
42
if os.path.exists(path):
43
raise RuntimeError, "%s is already installed" % self.testname
46
rc = self.installer.install()
49
raise RuntimeError, "An error was detected during", \
50
"installation, cleaning up"
38
"""Install the test suite.
40
This creates an install directory under the user's XDG_DATA_HOME
41
directory to mark that the test is installed. The installer's
42
install() method is then called from this directory to complete any
43
test specific install that may be needed.
45
if not self.installer:
46
raise RuntimeError("no installer defined for '%s'" %
48
if os.path.exists(self.installdir):
49
raise RuntimeError("%s is already installed" % self.testname)
50
os.makedirs(self.installdir)
51
os.chdir(self.installdir)
53
self.installer.install()
54
except Exception as strerror:
56
raise RuntimeError("An error was detected during",
57
"installation, cleaning up: %s" % strerror)
52
59
def uninstall(self):
60
"""Uninstall the test suite.
54
62
Uninstalling just recursively removes the test specific directory
55
63
under the user's XDG_DATA_HOME directory. This will both mark
56
64
the test as removed, and clean up any files that were downloaded
62
70
if os.path.exists(path):
63
71
shutil.rmtree(path)
73
def _savetestdata(self):
75
filename = os.path.join(self.resultsdir, 'testdata.json')
76
testdata['testname'] = self.testname
77
testdata['version'] = self.version
78
testdata['starttime'] = time.mktime(self.runner.starttime.timetuple())
79
testdata['endtime'] = time.mktime(self.runner.endtime.timetuple())
80
write_file(json.dumps(testdata), filename)
67
return self.runner.run()
84
raise RuntimeError("no test runner defined for '%s'" %
86
resultname = (self.testname +
87
str(time.mktime(datetime.utcnow().timetuple())))
88
self.resultsdir = os.path.join(self.config.resultsdir, resultname)
89
os.makedirs(self.resultsdir)
90
os.chdir(self.installdir)
91
self.runner.run(self.resultsdir)
69
94
def parse(self,results):
71
return self.parser.parse(results)
96
raise RuntimeError("no test parser defined for '%s'" %
98
self.parser.parse(results)
73
100
class AbrekTestInstaller(object):
75
Base class for defining an installer object. This class can be used
76
as-is for simple installers, or extended for more advanced funcionality.
101
"""Base class for defining an installer object.
102
This class can be used as-is for simple installers, or extended for more
103
advanced funcionality.
78
105
steps - list of steps to be executed in a shell
79
106
deps - list of dependencies to apt-get install before running the steps
80
107
url - location from which the test suite should be downloaded
81
108
md5 - md5sum to check the integrety of the download
84
110
def __init__(self, steps=[], deps=[], url="", md5="", **kwargs):
85
111
self.steps = steps
93
119
cmd = "sudo apt-get install %s", " ".join(self.deps)
94
rc,output = getstatusoutput(cmd)
120
rc, output = getstatusoutput(cmd)
96
raise RuntimeError, "Dependency installation failed"
122
raise RuntimeError("Dependency installation failed")
98
124
def _download(self):
100
Download the file specified by the url and check the md5.
101
Return the path and filename if successful, otherwise return None
125
"""Download the file specified by the url and check the md5.
127
Returns the path and filename if successful, otherwise return None
112
138
for data in fd.read(0x10000):
113
139
checkmd5.update(data)
114
140
if checkmd5.hexdigest() != self.md5:
115
raise RuntimeError, "Unexpected md5sum downloading %s" % \
141
raise RuntimeError("Unexpected md5sum downloading %s" %
120
146
def _runsteps(self):
121
147
for cmd in self.steps:
122
rc,output = getstatusoutput(cmd)
148
rc, output = getstatusoutput(cmd)
124
150
def install(self):
125
151
self._installdeps()
155
class AbrekTestRunner(object):
156
"""Base class for defining an test runner object.
158
This class can be used as-is for simple execution with the expectation
159
that the run() method will be called from the directory where the test
160
was installed. Steps, if used, should handle changing directories from
161
there to the directory where the test was extracted if necessary.
162
This class can also be extended for more advanced funcionality.
164
steps - list of steps to be executed in a shell
166
def __init__(self, steps=[]):
170
def _runsteps(self, resultsdir):
171
outputlog = os.path.join(resultsdir, 'testoutput.log')
172
with open(outputlog, 'a') as fd:
173
for cmd in self.steps:
174
rc, output = getstatusoutput(cmd)
177
def run(self, resultsdir):
178
self.starttime = datetime.utcnow()
179
self._runsteps(resultsdir)
180
self.endtime = datetime.utcnow()
129
182
def testloader(testname):
131
184
Load the test definition, which can be either an individual