blob: 984492bd4cc11c4a3fd059c451c03c3b53180cd9 [file] [log] [blame]
mblighdcd57a82007-07-11 23:06:47 +00001#!/usr/bin/python
2#
3# Copyright 2007 Google Inc. Released under the GPL v2
4
mblighdc735a22007-08-02 16:54:37 +00005"""
6This module defines the Autotest class
mblighdcd57a82007-07-11 23:06:47 +00007
jadmanski0afbb632008-06-06 21:10:57 +00008 Autotest: software to run tests automatically
mblighdcd57a82007-07-11 23:06:47 +00009"""
10
mblighdc735a22007-08-02 16:54:37 +000011__author__ = """
12mbligh@google.com (Martin J. Bligh),
mblighdcd57a82007-07-11 23:06:47 +000013poirier@google.com (Benjamin Poirier),
mblighdc735a22007-08-02 16:54:37 +000014stutsman@google.com (Ryan Stutsman)
15"""
mblighdcd57a82007-07-11 23:06:47 +000016
mbligh02ff2d52008-06-03 15:00:21 +000017import re, os, sys, traceback, subprocess, tempfile, shutil, time
mblighdcd57a82007-07-11 23:06:47 +000018
mblighccb9e182008-04-17 15:42:10 +000019from autotest_lib.server import installable_object, utils, server_job
20from autotest_lib.client.common_lib import logging
mblighc5ddfd12008-08-04 17:15:00 +000021from autotest_lib.client.common_lib import error, global_config, packages
mblighdcd57a82007-07-11 23:06:47 +000022
23
mbligh3c7a1502008-07-24 18:08:47 +000024
mblighdcd57a82007-07-11 23:06:47 +000025AUTOTEST_SVN = 'svn://test.kernel.org/autotest/trunk/client'
26AUTOTEST_HTTP = 'http://test.kernel.org/svn/autotest/trunk/client'
27
28# Timeouts for powering down and up respectively
29HALT_TIME = 300
mbligh07c1eac2007-11-05 18:39:29 +000030BOOT_TIME = 1800
jadmanskiec859142008-05-29 21:33:39 +000031CRASH_RECOVERY_TIME = 9000
mbligh0e4613b2007-10-29 16:55:07 +000032
mblighdcd57a82007-07-11 23:06:47 +000033
mblighd8b39252008-03-20 21:15:03 +000034class BaseAutotest(installable_object.InstallableObject):
jadmanski0afbb632008-06-06 21:10:57 +000035 """
36 This class represents the Autotest program.
mblighdcd57a82007-07-11 23:06:47 +000037
jadmanski0afbb632008-06-06 21:10:57 +000038 Autotest is used to run tests automatically and collect the results.
39 It also supports profilers.
mblighdcd57a82007-07-11 23:06:47 +000040
jadmanski0afbb632008-06-06 21:10:57 +000041 Implementation details:
42 This is a leaf class in an abstract class hierarchy, it must
43 implement the unimplemented methods in parent classes.
44 """
mbligh119c12a2007-11-12 22:13:44 +000045
jadmanski0afbb632008-06-06 21:10:57 +000046 def __init__(self, host = None):
47 self.host = host
48 self.got = False
49 self.installed = False
50 self.serverdir = utils.get_server_dir()
51 super(BaseAutotest, self).__init__()
mblighc8949b82007-07-23 16:33:58 +000052
mblighdc735a22007-08-02 16:54:37 +000053
jadmanski0afbb632008-06-06 21:10:57 +000054 @logging.record
55 def install(self, host = None):
56 """
57 Install autotest. If get() was not called previously, an
58 attempt will be made to install from the autotest svn
59 repository.
mbligh9a3f5e52008-05-28 21:21:43 +000060
jadmanski0afbb632008-06-06 21:10:57 +000061 Args:
62 host: a Host instance on which autotest will be
63 installed
mbligh9a3f5e52008-05-28 21:21:43 +000064
jadmanski0afbb632008-06-06 21:10:57 +000065 Raises:
66 AutoservError: if a tarball was not specified and
67 the target host does not have svn installed in its path
mbligh9a3f5e52008-05-28 21:21:43 +000068
jadmanski0afbb632008-06-06 21:10:57 +000069 TODO(poirier): check dependencies
70 autotest needs:
71 bzcat
72 liboptdev (oprofile)
73 binutils-dev (oprofile)
74 make
75 psutils (netperf)
76 """
77 if not host:
78 host = self.host
79 if not self.got:
80 self.get()
81 host.wait_up(timeout=30)
82 host.setup()
83 print "Installing autotest on %s" % host.hostname
mbligh40f122a2007-11-03 23:08:46 +000084
jadmanski0afbb632008-06-06 21:10:57 +000085 # Let's try to figure out where autotest is installed. If we can't,
86 # (autotest not installed) just assume '/usr/local/autotest' and
87 # proceed.
88 try:
89 autodir = _get_autodir(host)
90 except error.AutotestRunError:
91 autodir = '/usr/local/autotest'
mbligh29742302008-05-09 16:06:37 +000092
mbligh0562e652008-08-20 20:11:45 +000093 # Make the host object know as to where autotest is installed
94 host.set_autodir(autodir)
95
jadmanski0afbb632008-06-06 21:10:57 +000096 host.run('mkdir -p "%s"' % utils.sh_escape(autodir))
mbligh40f122a2007-11-03 23:08:46 +000097
mblighc5ddfd12008-08-04 17:15:00 +000098 # Fetch the autotest client from the nearest repository
99 try:
100 c = global_config.global_config
101 repos = c.get_config_value("PACKAGES", 'fetch_location', type=list)
102 pkgmgr = packages.PackageManager(
103 autodir, repo_urls=repos, do_locking=False,
104 run_function=host.run,
105 run_function_dargs=dict(timeout=600))
106 # The packages dir is used to store all the packages that
107 # are fetched on that client. (for the tests,deps etc.
108 # too apart from the client)
109 pkg_dir = os.path.join(autodir, 'packages')
110 # clean up the autodir except for the packages directory
111 host.run('cd %s && ls | grep -v "^packages$"'
112 ' | xargs rm -rf && rm -rf .[^.]*' % autodir)
113 pkgmgr.install_pkg('autotest', 'client', pkg_dir, autodir,
114 preserve_install_dir=True)
115 self.installed = True
116 return
117 except global_config.ConfigError, e:
118 print ("Could not install autotest using the"
119 " packaging system %s" % e)
120 except (packages.PackageInstallError, error.AutoservRunError), e:
121 print "Could not install autotest from %s : %s " % (repos, e)
122
mbligh40f122a2007-11-03 23:08:46 +0000123
jadmanski0afbb632008-06-06 21:10:57 +0000124 # try to install from file or directory
125 if self.source_material:
126 if os.path.isdir(self.source_material):
127 # Copy autotest recursively
128 host.send_file(self.source_material, autodir)
129 else:
130 # Copy autotest via tarball
131 e_msg = 'Installation method not yet implemented!'
132 raise NotImplementedError(e_msg)
133 print "Installation of autotest completed"
134 self.installed = True
135 return
mbligh91334902007-09-28 01:47:59 +0000136
jadmanski0afbb632008-06-06 21:10:57 +0000137 # if that fails try to install using svn
138 if utils.run('which svn').exit_status:
mbligh78bf5352008-07-11 20:27:36 +0000139 raise error.AutoservError('svn not found on target machine: %s'
140 % host.name)
jadmanski0afbb632008-06-06 21:10:57 +0000141 try:
mbligh78bf5352008-07-11 20:27:36 +0000142 host.run('svn checkout %s %s' % (AUTOTEST_SVN, autodir))
jadmanski0afbb632008-06-06 21:10:57 +0000143 except error.AutoservRunError, e:
mbligh78bf5352008-07-11 20:27:36 +0000144 host.run('svn checkout %s %s' % (AUTOTEST_HTTP, autodir))
jadmanski0afbb632008-06-06 21:10:57 +0000145 print "Installation of autotest completed"
146 self.installed = True
mbligh91334902007-09-28 01:47:59 +0000147
148
jadmanski0afbb632008-06-06 21:10:57 +0000149 def get(self, location = None):
150 if not location:
151 location = os.path.join(self.serverdir, '../client')
152 location = os.path.abspath(location)
153 # If there's stuff run on our client directory already, it
154 # can cause problems. Try giving it a quick clean first.
155 cwd = os.getcwd()
156 os.chdir(location)
157 os.system('tools/make_clean')
158 os.chdir(cwd)
159 super(BaseAutotest, self).get(location)
160 self.got = True
mblighdcd57a82007-07-11 23:06:47 +0000161
162
jadmanski0afbb632008-06-06 21:10:57 +0000163 def run(self, control_file, results_dir = '.', host = None,
164 timeout=None, tag=None, parallel_flag=False):
165 """
166 Run an autotest job on the remote machine.
mbligh9a3f5e52008-05-28 21:21:43 +0000167
jadmanski0afbb632008-06-06 21:10:57 +0000168 Args:
169 control_file: an open file-like-obj of the control file
170 results_dir: a str path where the results should be stored
171 on the local filesystem
172 host: a Host instance on which the control file should
173 be run
174 tag: tag name for the client side instance of autotest
175 parallel_flag: flag set when multiple jobs are run at the
176 same time
177 Raises:
178 AutotestRunError: if there is a problem executing
179 the control file
180 """
181 host = self._get_host_and_setup(host)
182 results_dir = os.path.abspath(results_dir)
mblighc1cbc992008-05-27 20:01:45 +0000183
jadmanski0afbb632008-06-06 21:10:57 +0000184 if tag:
185 results_dir = os.path.join(results_dir, tag)
mblighc1cbc992008-05-27 20:01:45 +0000186
jadmanski0afbb632008-06-06 21:10:57 +0000187 atrun = _Run(host, results_dir, tag, parallel_flag)
188 self._do_run(control_file, results_dir, host, atrun, timeout)
mblighd8b39252008-03-20 21:15:03 +0000189
190
jadmanski0afbb632008-06-06 21:10:57 +0000191 def _get_host_and_setup(self, host):
192 if not host:
193 host = self.host
194 if not self.installed:
195 self.install(host)
mbligh91334902007-09-28 01:47:59 +0000196
jadmanski0afbb632008-06-06 21:10:57 +0000197 host.wait_up(timeout=30)
198 return host
mblighd8b39252008-03-20 21:15:03 +0000199
200
jadmanski0afbb632008-06-06 21:10:57 +0000201 def prepare_for_copying_logs(self, src, dest, host):
202 keyval_path = ''
203 if not os.path.exists(os.path.join(dest, 'keyval')):
204 # Client-side keyval file can be copied directly
205 return keyval_path
206 # Copy client-side keyval to temporary location
207 try:
208 try:
209 # Create temp file
mbligh78bf5352008-07-11 20:27:36 +0000210 fd, keyval_path = tempfile.mkstemp('.keyval_%s' % host.hostname)
211 host.get_file(os.path.join(src, 'keyval'), keyval_path)
jadmanski0afbb632008-06-06 21:10:57 +0000212 finally:
213 # We will squirrel away the client side keyval
214 # away and move it back when we are done
215 self.temp_keyval_path = tempfile.mktemp()
216 host.run('mv %s %s' %
mbligh78bf5352008-07-11 20:27:36 +0000217 (os.path.join(src, 'keyval'), self.temp_keyval_path))
jadmanski0afbb632008-06-06 21:10:57 +0000218 except (error.AutoservRunError, error.AutoservSSHTimeout):
219 print "Prepare for copying logs failed"
220 return keyval_path
mblighcaa62c22008-04-07 21:51:17 +0000221
222
jadmanski0afbb632008-06-06 21:10:57 +0000223 def process_copied_logs(self, dest, host, keyval_path):
224 if not os.path.exists(os.path.join(dest, 'keyval')):
225 # Client-side keyval file was copied directly
226 return
227 # Append contents of keyval_<host> file to keyval file
228 try:
229 # Read in new and old keyval files
230 new_keyval = utils.read_keyval(keyval_path)
231 old_keyval = utils.read_keyval(dest)
232 # 'Delete' from new keyval entries that are in both
233 tmp_keyval = {}
234 for key, val in new_keyval.iteritems():
235 if key not in old_keyval:
236 tmp_keyval[key] = val
237 # Append new info to keyval file
238 utils.write_keyval(dest, tmp_keyval)
239 # Delete keyval_<host> file
240 os.remove(keyval_path)
241 except IOError:
242 print "Process copied logs failed"
mblighcaa62c22008-04-07 21:51:17 +0000243
244
jadmanski0afbb632008-06-06 21:10:57 +0000245 def postprocess_copied_logs(self, src, host):
246 # we can now put our keyval file back
247 try:
248 host.run('mv %s %s' % (self.temp_keyval_path,
249 os.path.join(src, 'keyval')))
250 except:
251 pass
mbligh9a3f5e52008-05-28 21:21:43 +0000252
253
jadmanski0afbb632008-06-06 21:10:57 +0000254 def _do_run(self, control_file, results_dir, host, atrun, timeout):
255 try:
256 atrun.verify_machine()
257 except:
mbligh78bf5352008-07-11 20:27:36 +0000258 print "Verify machine failed on %s. Reinstalling" % host.hostname
jadmanski0afbb632008-06-06 21:10:57 +0000259 self.install(host)
260 atrun.verify_machine()
261 debug = os.path.join(results_dir, 'debug')
262 try:
263 os.makedirs(debug)
264 except:
265 pass
mbligh9a3f5e52008-05-28 21:21:43 +0000266
jadmanski0afbb632008-06-06 21:10:57 +0000267 # Ready .... Aim ....
268 for control in [atrun.remote_control_file,
269 atrun.remote_control_file + '.state',
270 atrun.manual_control_file,
271 atrun.manual_control_file + '.state']:
272 host.run('rm -f ' + control)
mbligh9a3f5e52008-05-28 21:21:43 +0000273
jadmanski0afbb632008-06-06 21:10:57 +0000274 tmppath = utils.get(control_file)
mblighc5ddfd12008-08-04 17:15:00 +0000275
276 # Insert the job.add_repository() lines in the control file
277 # if there are any repos defined in global_config.ini
278 try:
279 cfile = open(tmppath, 'r')
280 cfile_orig = cfile.read()
281 cfile.close()
282 c = global_config.global_config
283 repos = c.get_config_value("PACKAGES", 'fetch_location', type=list)
284 control_file_new = []
285 control_file_new.append('job.add_repository(%s)\n' % repos)
286 control_file_new.append(cfile_orig)
287
288 # Overwrite the control file with the new one
289 cfile = open(tmppath, 'w')
290 cfile.write('\n'.join(control_file_new))
291 cfile.close()
292 except global_config.ConfigError, e:
293 pass
294
295
296 # Copy control_file to remote_control_file on the host
jadmanski0afbb632008-06-06 21:10:57 +0000297 host.send_file(tmppath, atrun.remote_control_file)
298 if os.path.abspath(tmppath) != os.path.abspath(control_file):
299 os.remove(tmppath)
mbligh0e4613b2007-10-29 16:55:07 +0000300
jadmanskib6eb2f12008-09-12 16:39:36 +0000301 collect_func = lambda: self._collect_results(atrun, host, results_dir)
302 host.job.collect_client_job_results = collect_func
jadmanski0afbb632008-06-06 21:10:57 +0000303 try:
304 atrun.execute_control(timeout=timeout)
305 finally:
jadmanskib6eb2f12008-09-12 16:39:36 +0000306 del host.job.collect_client_job_results
307 collect_func()
mbligh1f194902007-12-20 01:31:43 +0000308
mblighc1cbc992008-05-27 20:01:45 +0000309
jadmanskib6eb2f12008-09-12 16:39:36 +0000310 def _collect_results(self, atrun, host, results_dir):
311 # make an effort to wait for the machine to come up
312 try:
313 host.wait_up(timeout=30)
314 except error.AutoservError:
315 # don't worry about any errors, we'll try and
316 # get the results anyway
317 pass
318
319 # get the results
320 if not atrun.tag:
321 results = os.path.join(atrun.autodir, 'results', 'default')
322 else:
323 results = os.path.join(atrun.autodir, 'results', atrun.tag)
324
325 # Copy all dirs in default to results_dir
326 keyval_path = self.prepare_for_copying_logs(results, results_dir,
327 host)
328 host.get_file(results + '/', results_dir)
329 self.process_copied_logs(results_dir, host, keyval_path)
330 self.postprocess_copied_logs(results, host)
mblighdcd57a82007-07-11 23:06:47 +0000331
mbligh0e4613b2007-10-29 16:55:07 +0000332
jadmanski0afbb632008-06-06 21:10:57 +0000333 def run_timed_test(self, test_name, results_dir='.', host=None,
334 timeout=None, tag=None, *args, **dargs):
335 """
336 Assemble a tiny little control file to just run one test,
337 and run it as an autotest client-side test
338 """
339 if not host:
340 host = self.host
341 if not self.installed:
342 self.install(host)
343 opts = ["%s=%s" % (o[0], repr(o[1])) for o in dargs.items()]
344 cmd = ", ".join([repr(test_name)] + map(repr, args) + opts)
345 control = "job.run_test(%s)\n" % cmd
346 self.run(control, results_dir, host, timeout=timeout, tag=tag)
mbligh0e4613b2007-10-29 16:55:07 +0000347
348
jadmanski169ecad2008-09-12 15:49:44 +0000349 def run_test(self, test_name, results_dir='.', host=None, tag=None,
350 *args, **dargs):
jadmanski0afbb632008-06-06 21:10:57 +0000351 self.run_timed_test(test_name, results_dir, host, timeout=None,
352 tag=tag, *args, **dargs)
mblighd54832b2007-07-25 16:46:56 +0000353
354
mblighdcd57a82007-07-11 23:06:47 +0000355class _Run(object):
jadmanski0afbb632008-06-06 21:10:57 +0000356 """
357 Represents a run of autotest control file. This class maintains
358 all the state necessary as an autotest control file is executed.
mblighdcd57a82007-07-11 23:06:47 +0000359
jadmanski0afbb632008-06-06 21:10:57 +0000360 It is not intended to be used directly, rather control files
361 should be run using the run method in Autotest.
362 """
363 def __init__(self, host, results_dir, tag, parallel_flag):
364 self.host = host
365 self.results_dir = results_dir
366 self.env = host.env
367 self.tag = tag
368 self.parallel_flag = parallel_flag
369 self.autodir = _get_autodir(self.host)
mbligh78bf5352008-07-11 20:27:36 +0000370 control = os.path.join(self.autodir, 'control')
jadmanski0afbb632008-06-06 21:10:57 +0000371 if tag:
mbligh78bf5352008-07-11 20:27:36 +0000372 control += '.' + tag
373 self.manual_control_file = control
374 self.remote_control_file = control + '.autoserv'
mblighdc735a22007-08-02 16:54:37 +0000375
376
jadmanski0afbb632008-06-06 21:10:57 +0000377 def verify_machine(self):
378 binary = os.path.join(self.autodir, 'bin/autotest')
379 try:
380 self.host.run('ls %s > /dev/null 2>&1' % binary)
381 except:
382 raise "Autotest does not appear to be installed"
mblighdc735a22007-08-02 16:54:37 +0000383
jadmanski0afbb632008-06-06 21:10:57 +0000384 if not self.parallel_flag:
385 tmpdir = os.path.join(self.autodir, 'tmp')
386 download = os.path.join(self.autodir, 'tests/download')
387 self.host.run('umount %s' % tmpdir, ignore_status=True)
388 self.host.run('umount %s' % download, ignore_status=True)
mblighdc735a22007-08-02 16:54:37 +0000389
jadmanski0afbb632008-06-06 21:10:57 +0000390 def get_full_cmd(self, section):
391 # build up the full command we want to run over the host
jadmanskib6eb2f12008-09-12 16:39:36 +0000392 cmd = [os.path.join(self.autodir, 'bin/autotest_client'),
393 '-H autoserv']
jadmanski0afbb632008-06-06 21:10:57 +0000394 if section > 0:
395 cmd.append('-c')
396 if self.tag:
397 cmd.append('-t %s' % self.tag)
398 if self.host.job.use_external_logging():
399 cmd.append('-l')
400 cmd.append(self.remote_control_file)
401 return ' '.join(cmd)
mblighadf2aab2007-11-29 18:16:43 +0000402
mblighd8b39252008-03-20 21:15:03 +0000403
jadmanski0afbb632008-06-06 21:10:57 +0000404 def get_client_log(self, section):
405 # open up the files we need for our logging
406 client_log_file = os.path.join(self.results_dir, 'debug',
407 'client.log.%d' % section)
408 return open(client_log_file, 'w', 0)
mblighd8b39252008-03-20 21:15:03 +0000409
410
jadmanski0afbb632008-06-06 21:10:57 +0000411 def execute_section(self, section, timeout):
mbligh4e4961c2008-07-11 21:08:10 +0000412 print "Executing %s/bin/autotest %s/control phase %d" % \
413 (self.autodir, self.autodir, section)
mblighd8b39252008-03-20 21:15:03 +0000414
jadmanski0afbb632008-06-06 21:10:57 +0000415 full_cmd = self.get_full_cmd(section)
416 client_log = self.get_client_log(section)
jadmanskib6eb2f12008-09-12 16:39:36 +0000417 redirector = server_job.client_logger(self.host)
mblighd528d302007-12-19 16:19:05 +0000418
jadmanski0afbb632008-06-06 21:10:57 +0000419 try:
420 old_resultdir = self.host.job.resultdir
421 self.host.job.resultdir = self.results_dir
422 result = self.host.run(full_cmd, ignore_status=True,
423 timeout=timeout,
424 stdout_tee=client_log,
425 stderr_tee=redirector)
426 finally:
427 redirector.close()
428 self.host.job.resultdir = old_resultdir
mbligh2bf2db62007-11-27 00:53:18 +0000429
jadmanski0afbb632008-06-06 21:10:57 +0000430 if result.exit_status == 1:
431 self.host.job.aborted = True
jadmanski89476062008-07-01 23:57:21 +0000432 raise error.AutotestRunError("client job was aborted")
jadmanski0afbb632008-06-06 21:10:57 +0000433 if not result.stderr:
434 raise error.AutotestRunError(
435 "execute_section: %s failed to return anything\n"
436 "stdout:%s\n" % (full_cmd, result.stdout))
mbligh0e4613b2007-10-29 16:55:07 +0000437
jadmanski0afbb632008-06-06 21:10:57 +0000438 return redirector.last_line
mblighdc735a22007-08-02 16:54:37 +0000439
440
jadmanski0afbb632008-06-06 21:10:57 +0000441 def execute_control(self, timeout=None):
442 section = 0
443 time_left = None
444 if timeout:
445 end_time = time.time() + timeout
446 time_left = end_time - time.time()
447 while not timeout or time_left > 0:
448 last = self.execute_section(section, time_left)
449 if timeout:
450 time_left = end_time - time.time()
451 if time_left <= 0:
452 break
453 section += 1
454 if re.match(r'^END .*\t----\t----\t.*$', last):
455 print "Client complete"
456 return
457 elif re.match('^\t*GOOD\t----\treboot\.start.*$', last):
458 print "Client is rebooting"
459 print "Waiting for client to halt"
460 if not self.host.wait_down(HALT_TIME):
jadmanski169ecad2008-09-12 15:49:44 +0000461 err = "%s failed to shutdown after %d"
462 err %= (self.host.hostname, HALT_TIME)
mbligh78bf5352008-07-11 20:27:36 +0000463 raise error.AutotestRunError(err)
jadmanski0afbb632008-06-06 21:10:57 +0000464 print "Client down, waiting for restart"
465 if not self.host.wait_up(BOOT_TIME):
466 # since reboot failed
467 # hardreset the machine once if possible
468 # before failing this control file
mbligh78bf5352008-07-11 20:27:36 +0000469 print "Hardresetting %s" % self.host.hostname
jadmanski0afbb632008-06-06 21:10:57 +0000470 try:
471 self.host.hardreset(wait=False)
472 except error.AutoservUnsupportedError:
mbligh78bf5352008-07-11 20:27:36 +0000473 print "Hardreset unsupported on %s" % self.host.hostname
474 raise error.AutotestRunError("%s failed to boot after %ds" %
475 (self.host.hostname, BOOT_TIME))
jadmanski0afbb632008-06-06 21:10:57 +0000476 self.host.reboot_followup()
477 continue
jadmanskic66e93c2008-07-29 21:25:22 +0000478 self.host.job.record("END ABORT", None, None,
mbligh78bf5352008-07-11 20:27:36 +0000479 "Autotest client terminated unexpectedly")
jadmanski0afbb632008-06-06 21:10:57 +0000480 # give the client machine a chance to recover from
481 # possible crash
482 self.host.wait_up(CRASH_RECOVERY_TIME)
mbligh78bf5352008-07-11 20:27:36 +0000483 raise error.AutotestRunError("Aborting - unexpected final status "
484 "message from client: %s\n" % last)
mblighdcd57a82007-07-11 23:06:47 +0000485
jadmanski0afbb632008-06-06 21:10:57 +0000486 # should only get here if we timed out
487 assert timeout
488 raise error.AutotestTimeoutError()
mbligh0e4613b2007-10-29 16:55:07 +0000489
mblighdcd57a82007-07-11 23:06:47 +0000490
491def _get_autodir(host):
mbligh3c7a1502008-07-24 18:08:47 +0000492 autodir = host.get_autodir()
493 if autodir:
494 return autodir
jadmanski0afbb632008-06-06 21:10:57 +0000495 try:
496 # There's no clean way to do this. readlink may not exist
497 cmd = "python -c 'import os,sys; print os.readlink(sys.argv[1])' /etc/autotest.conf 2> /dev/null"
mbligh3c7a1502008-07-24 18:08:47 +0000498 autodir = os.path.dirname(host.run(cmd).stdout)
499 if autodir:
500 return autodir
jadmanski0afbb632008-06-06 21:10:57 +0000501 except error.AutoservRunError:
502 pass
503 for path in ['/usr/local/autotest', '/home/autotest']:
504 try:
jadmanski169ecad2008-09-12 15:49:44 +0000505 host.run('ls %s > /dev/null 2>&1' %
506 os.path.join(path, 'bin/autotest'))
jadmanski0afbb632008-06-06 21:10:57 +0000507 return path
508 except error.AutoservRunError:
509 pass
510 raise error.AutotestRunError("Cannot figure out autotest directory")
mblighd8b39252008-03-20 21:15:03 +0000511
512
513# site_autotest.py may be non-existant or empty, make sure that an appropriate
514# SiteAutotest class is created nevertheless
515try:
jadmanski0afbb632008-06-06 21:10:57 +0000516 from site_autotest import SiteAutotest
mblighd8b39252008-03-20 21:15:03 +0000517except ImportError:
jadmanski0afbb632008-06-06 21:10:57 +0000518 class SiteAutotest(BaseAutotest):
519 pass
mblighd8b39252008-03-20 21:15:03 +0000520
521
522class Autotest(SiteAutotest):
jadmanski0afbb632008-06-06 21:10:57 +0000523 pass