122 lines
4.6 KiB
Python
122 lines
4.6 KiB
Python
import os, logging, six.moves.configparser
|
|
from autotest_lib.client.common_lib import autotemp, packages, error
|
|
from autotest_lib.client.common_lib import global_config
|
|
from autotest_lib.client.bin import harness
|
|
|
|
|
|
class harness_autoserv(harness.harness):
|
|
"""
|
|
The server harness for running from autoserv
|
|
|
|
Properties:
|
|
job
|
|
The job object for this job
|
|
"""
|
|
|
|
def __init__(self, job, harness_args):
|
|
"""
|
|
job
|
|
The job object for this job
|
|
"""
|
|
super(harness_autoserv, self).__init__(job)
|
|
# 2 for buffer size. Can't use the kwarg 'buffering' on fdopen in py2.
|
|
self.status = os.fdopen(3, 'w', 2)
|
|
|
|
# If a bug on the client run code prevents global_config.ini
|
|
# from being copied to the client machine, the client will run
|
|
# without a global config, relying only on the defaults of the
|
|
# config items. To avoid that happening silently, the check below
|
|
# was written.
|
|
try:
|
|
cfg = global_config.global_config.get_section_values("CLIENT")
|
|
except six.moves.configparser.NoSectionError:
|
|
logging.error("Empty CLIENT configuration session. "
|
|
"global_config.ini missing. This probably means "
|
|
"a bug on the server code. Please verify.")
|
|
|
|
|
|
def run_start(self):
|
|
# set up the package fetcher for direct-from-autoserv fetches
|
|
fetcher = AutoservFetcher(self.job.pkgmgr, self)
|
|
self.job.pkgmgr.add_repository(fetcher)
|
|
|
|
|
|
def _send_and_wait(self, title, *args):
|
|
"""Send a message to the autoserv and wait for it to signal
|
|
completion.
|
|
|
|
@param title: An alphanumeric string to title the message.
|
|
@param *args: Additional arbitrary alphanumeric arguments to pass
|
|
to the server.
|
|
"""
|
|
# create a named pipe for us to recieve a signal on
|
|
fifo_dir = autotemp.tempdir(suffix='-fifo', unique_id='harness',
|
|
dir=self.job.tmpdir)
|
|
try:
|
|
fifo_path = os.path.join(fifo_dir.name, 'autoserv.fifo')
|
|
os.mkfifo(fifo_path)
|
|
|
|
# send signal to the server as title[:args]:path
|
|
msg = ':'.join([title] + list(args) + [fifo_path]) + '\n'
|
|
self.status.write(msg)
|
|
self.status.flush()
|
|
# wait for the server to signal back to us
|
|
fifo = open(fifo_path)
|
|
fifo.read(1)
|
|
fifo.close()
|
|
finally:
|
|
fifo_dir.clean()
|
|
|
|
|
|
def run_test_complete(self):
|
|
"""A test run by this job is complete, signal it to autoserv and
|
|
wait for it to signal to continue"""
|
|
self._send_and_wait('AUTOTEST_TEST_COMPLETE')
|
|
|
|
|
|
def test_status(self, status, tag):
|
|
"""A test within this job is completing"""
|
|
for line in status.split('\n'):
|
|
# sent status messages with AUTOTEST_STATUS:tag:message
|
|
msg = ('AUTOTEST_STATUS:%s:%s\n' % (tag, line))
|
|
self.status.write(msg)
|
|
|
|
|
|
def fetch_package(self, pkg_name, dest_path):
|
|
"""Request a package from the remote autoserv.
|
|
|
|
@param pkg_name: The name of the package, as generally used by the
|
|
client.common_lib.packages infrastructure.
|
|
@param dest_path: The path the package should be copied to.
|
|
"""
|
|
self._send_and_wait('AUTOTEST_FETCH_PACKAGE', pkg_name, dest_path)
|
|
|
|
|
|
class AutoservFetcher(packages.RepositoryFetcher):
|
|
def __init__(self, package_manager, job_harness):
|
|
self.url = "autoserv://"
|
|
self.job_harness = job_harness
|
|
|
|
|
|
def fetch_pkg_file(self, filename, dest_path):
|
|
if os.path.exists(dest_path):
|
|
os.remove(dest_path)
|
|
|
|
if not global_config.global_config.get_config_value(
|
|
'CLIENT', 'fetch_from_autoserv', type=bool, default=True):
|
|
# In order to preserve autotest semantics, we treat this as a
|
|
# PackageFetchError rather than a success or not including the
|
|
# fetcher: see crosbug.com/35080.
|
|
logging.error('Not fetching %s from autoserv.', filename)
|
|
raise error.PackageFetchError(
|
|
'%s not fetched from autoserv as fetching from autoserv is '
|
|
'disabled.' % filename)
|
|
|
|
logging.info('Fetching %s from autoserv to %s.', filename, dest_path)
|
|
self.job_harness.fetch_package(filename, dest_path)
|
|
if os.path.exists(dest_path):
|
|
logging.debug('Successfully fetched %s from autoserv.', filename)
|
|
else:
|
|
raise error.PackageFetchError('%s not fetched from autoserv.'
|
|
% filename)
|