[autotest] Delete code for creating Android testbeds.
This deletes all factory code creating testbed.TestBed instances,
along with some related external references to the TestBed class.
BUG=chromium:834335
TEST=TBD
Change-Id: Ie400c0c6a1d13aa01130dd38b71b45b0809a2476
Reviewed-on: https://chromium-review.googlesource.com/1029353
Commit-Ready: Richard Barnette <jrbarnette@chromium.org>
Tested-by: Richard Barnette <jrbarnette@chromium.org>
Reviewed-by: Aviv Keshet <akeshet@chromium.org>
diff --git a/cli/host.py b/cli/host.py
index 3d8e161..05b152f 100644
--- a/cli/host.py
+++ b/cli/host.py
@@ -666,13 +666,9 @@
try:
if bin_utils.ping(host, tries=1, deadline=1) == 0:
serials = self.attributes.get('serials', '').split(',')
- if serials and len(serials) > 1:
- host_dut = hosts.create_testbed(machine,
- adb_serials=serials)
- else:
- adb_serial = self.attributes.get('serials')
- host_dut = hosts.create_host(machine,
- adb_serial=adb_serial)
+ adb_serial = self.attributes.get('serials')
+ host_dut = hosts.create_host(machine,
+ adb_serial=adb_serial)
info = HostInfo(host, host_dut.get_platform(),
host_dut.get_labels())
diff --git a/global_config.ini b/global_config.ini
index 4bca337..19808f3 100644
--- a/global_config.ini
+++ b/global_config.ini
@@ -462,10 +462,6 @@
# running inside the container can use the same user to make RPC.
user:
-[ACTS]
-# Section for ACTS configuration.
-acts_config_folder:
-
[ANDROID]
image_url_pattern: %s/static/%s
stable_version_dragonboard: git_mnc-brillo-dev/dragonboard-userdebug/2512766
diff --git a/server/control_segments/crashinfo b/server/control_segments/crashinfo
index 82f075f..4f45ee4 100644
--- a/server/control_segments/crashinfo
+++ b/server/control_segments/crashinfo
@@ -3,10 +3,6 @@
def crashinfo(machine):
- if utils.machine_is_testbed(machine):
- logging.info('testbed does not need to get crash info.')
- return
-
host = hosts.create_host(machine)
if has_failed_tests:
crashcollect.get_crashinfo(host, test_start_time)
diff --git a/server/control_segments/provision b/server/control_segments/provision
index 2840688..33e22aa 100644
--- a/server/control_segments/provision
+++ b/server/control_segments/provision
@@ -68,10 +68,7 @@
duration = (end_time - start_time).total_seconds()
fields = {'success': label_update_success,
- # TODO(kevcheng): Need a better way of classifying testbeds.
- 'board': (host.get_board()
- if not utils.machine_is_testbed(machine)
- else host.get_platform())}
+ 'board': host.get_board()}
_LABEL_UPDATE_DURATION_METRIC.add(duration, fields=fields)
except Exception:
logging.exception('Provision failed due to Exception.')
diff --git a/server/control_segments/verify_job_repo_url b/server/control_segments/verify_job_repo_url
index 6f908ce..4f25039 100644
--- a/server/control_segments/verify_job_repo_url
+++ b/server/control_segments/verify_job_repo_url
@@ -2,10 +2,6 @@
def install(machine):
- if utils.machine_is_testbed(machine):
- logging.info('testbed does not need to verify job repo url.')
- return
-
logging.info('Verifying job repo url for machine %s', machine)
host = hosts.create_host(machine)
host.verify_job_repo_url(job.tag)
diff --git a/server/hosts/__init__.py b/server/hosts/__init__.py
index ad3babb..b2f7f0a 100644
--- a/server/hosts/__init__.py
+++ b/server/hosts/__init__.py
@@ -19,11 +19,9 @@
from cros_host import CrosHost
from chameleon_host import ChameleonHost
from servo_host import ServoHost
-from testbed import TestBed
# factory function
from factory import create_host
-from factory import create_testbed
from factory import create_target_machine
# Many host creation sites only import the package, so also provide useful
diff --git a/server/hosts/factory.py b/server/hosts/factory.py
index a541953..9b7dafc 100644
--- a/server/hosts/factory.py
+++ b/server/hosts/factory.py
@@ -21,7 +21,6 @@
from autotest_lib.server.hosts import gce_host
from autotest_lib.server.hosts import sonic_host
from autotest_lib.server.hosts import ssh_host
-from autotest_lib.server.hosts import testbed
CONFIG = global_config.global_config
@@ -208,29 +207,8 @@
return host_instance
-def create_testbed(machine, **kwargs):
- """Create the testbed object.
-
- @param machine: A dict representing the test bed under test or a String
- representing the testbed hostname (for legacy caller
- support).
- If it is a machine dict, the 'hostname' key is required.
- Optional 'afe_host' key will pipe in afe_host from
- the afe_host object from the autoserv runtime or the AFE.
- @param kwargs: Keyword args to pass to the testbed initialization.
-
- @returns: The testbed object with all associated host objects instantiated.
- """
- detected_args = _get_host_arguments(machine)
- hostname = detected_args.pop('hostname')
- kwargs.update(detected_args)
- host = testbed.TestBed(hostname, **kwargs)
- base_classes.send_creation_metric(host, context='factory')
- return host
-
-
def create_target_machine(machine, **kwargs):
- """Create the target machine which could be a testbed or a *Host.
+ """Create the target machine, accounting for containers.
@param machine: A dict representing the test bed under test or a String
representing the testbed hostname (for legacy caller
@@ -259,9 +237,4 @@
machine = hostname
logging.debug('Hostname of machine is converted to %s for the test to '
'run inside a container.', hostname)
-
- # TODO(kevcheng): We'll want to have a smarter way of figuring out which
- # host to create (checking host labels).
- if server_utils.machine_is_testbed(machine):
- return create_testbed(machine, **kwargs)
return create_host(machine, **kwargs)
diff --git a/server/hosts/factory_unittest.py b/server/hosts/factory_unittest.py
index f876e4d..8e1d68c 100755
--- a/server/hosts/factory_unittest.py
+++ b/server/hosts/factory_unittest.py
@@ -3,7 +3,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import mock
import unittest
import common
@@ -229,73 +228,6 @@
self.assertEqual(host_obj._init_args['ssh_options'], 'options')
-class CreateTestbedUnittests(unittest.TestCase):
- """Tests for create_testbed function."""
-
- def setUp(self):
- """Mock out TestBed class to eliminate side effects.
- """
- self._orig_testbed = factory.testbed.TestBed
- factory.testbed.TestBed = _gen_mock_host('testbed')
-
-
- def tearDown(self):
- """Clean up mock.
- """
- factory.testbed.TestBed = self._orig_testbed
-
-
- def test_argument_passthrough(self):
- """Confirm that detected and specified arguments are passed through to
- the testbed object.
- """
- machine = _gen_machine_dict(hostname='localhost')
- testbed_obj = factory.create_testbed(machine, foo='bar')
- self.assertEqual(testbed_obj._init_args['hostname'], 'localhost')
- self.assertTrue('afe_host' in testbed_obj._init_args)
- self.assertTrue('host_info_store' in testbed_obj._init_args)
- self.assertEqual(testbed_obj._init_args['foo'], 'bar')
-
-
- def test_global_ssh_params(self):
- """Confirm passing of ssh parameters set as globals.
- """
- factory.ssh_user = 'foo'
- factory.ssh_pass = 'bar'
- factory.ssh_port = 1
- factory.ssh_verbosity_flag = 'baz'
- factory.ssh_options = 'zip'
- machine = _gen_machine_dict()
- try:
- testbed_obj = factory.create_testbed(machine)
- self.assertEqual(testbed_obj._init_args['user'], 'foo')
- self.assertEqual(testbed_obj._init_args['password'], 'bar')
- self.assertEqual(testbed_obj._init_args['port'], 1)
- self.assertEqual(testbed_obj._init_args['ssh_verbosity_flag'],
- 'baz')
- self.assertEqual(testbed_obj._init_args['ssh_options'], 'zip')
- finally:
- del factory.ssh_user
- del factory.ssh_pass
- del factory.ssh_port
- del factory.ssh_verbosity_flag
- del factory.ssh_options
-
-
- def test_host_attribute_ssh_params(self):
- """Confirm passing of ssh parameters from host attributes.
- """
- machine = _gen_machine_dict(attributes={'ssh_user': 'somebody',
- 'ssh_port': 100,
- 'ssh_verbosity_flag': 'verb',
- 'ssh_options': 'options'})
- testbed_obj = factory.create_testbed(machine)
- self.assertEqual(testbed_obj._init_args['user'], 'somebody')
- self.assertEqual(testbed_obj._init_args['port'], 100)
- self.assertEqual(testbed_obj._init_args['ssh_verbosity_flag'], 'verb')
- self.assertEqual(testbed_obj._init_args['ssh_options'], 'options')
-
-
if __name__ == '__main__':
unittest.main()
diff --git a/server/server_job.py b/server/server_job.py
index 9f3ec55..e9774b4 100644
--- a/server/server_job.py
+++ b/server/server_job.py
@@ -1287,7 +1287,6 @@
namespace['autotest'].Autotest.job = self
# server.hosts.base_classes.Host uses .job.
namespace['hosts'].Host.job = self
- namespace['hosts'].TestBed.job = self
namespace['hosts'].factory.ssh_user = self._ssh_user
namespace['hosts'].factory.ssh_port = self._ssh_port
namespace['hosts'].factory.ssh_pass = self._ssh_pass
diff --git a/server/site_tests/android_EasySetup/android_EasySetup.py b/server/site_tests/android_EasySetup/android_EasySetup.py
deleted file mode 100644
index 0ba44bb..0000000
--- a/server/site_tests/android_EasySetup/android_EasySetup.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright 2016 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import logging
-
-import common
-from autotest_lib.server import test
-from autotest_lib.site_utils import acts_lib
-from autotest_lib.server.cros import dnsname_mangler
-from autotest_lib.server.hosts import host_info
-
-
-class android_EasySetup(test.test):
- """A test that does nothing except setup a phone.
-
- This test will only setup a phone how a user wants and will perform no
- tests.
- """
- version = 1
-
- def run_once(self,
- testbed=None,
- install_sl4a=True,
- additional_apks=[]):
- """When run the testbed will be setup.
-
- @param testbed: The testbed to setup.
- @param install_sl4a: When true sl4a will be installed.
- @param additional_apks: An array of apk info dictionaries.
- apk = Name of the apk (eg. sl4a.apk)
- package = Name of the package (eg. test.tools)
- artifact = Name of the artifact, if not given
- package is used.
- """
- hostname = testbed.hostname
- if dnsname_mangler.is_ip_address(hostname):
- testbed_name = hostname
- else:
- testbed_name = hostname.split('.')[0]
-
- valid_hosts = []
- for v in testbed.get_adb_devices().values():
- try:
- info = v.host_info_store.get()
- except host_info.StoreError:
- pass
- else:
- if v.job_repo_url_attribute in info.attributes:
- valid_hosts.append(v)
-
- if not valid_hosts:
- logging.error('No valid devices.')
- return
-
- testbed_env = acts_lib.AndroidTestingEnvironment(
- devices=valid_hosts,
- testbed_name=testbed_name)
-
- if install_sl4a:
- testbed_env.install_sl4a_apk()
-
- for apk in additional_apks:
- testbed_env.install_apk(apk)
diff --git a/server/site_tests/android_EasySetup/control b/server/site_tests/android_EasySetup/control
deleted file mode 100644
index 8a88cf4..0000000
--- a/server/site_tests/android_EasySetup/control
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright 2016 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-AUTHOR = 'bpeake'
-NAME = 'android_EasySetup'
-TIME = 'SHORT'
-TEST_TYPE = 'Server'
-
-DOC = """
-Sets up a phone how the user wants.
-
-"""
-
-import common
-from autotest_lib.server import utils
-
-def run(machine):
- job.run_test('android_EasySetup',
- testbed=hosts.create_testbed(machine))
-
-
-parallel_simple(run, machines)
diff --git a/server/site_utils.py b/server/site_utils.py
index 51cede7..95579d5 100644
--- a/server/site_utils.py
+++ b/server/site_utils.py
@@ -764,20 +764,6 @@
return os.path.join(creds_dir, creds_file)
-def machine_is_testbed(machine):
- """Checks if the machine is a testbed.
-
- The signal we use to determine if the machine is a testbed
- is if the host attributes contain more than 1 serial.
-
- @param machine: is a list of dicts
-
- @return: True if the machine is a testbed, False otherwise.
- """
- _, afe_host = get_host_info_from_machine(machine)
- return len(afe_host.attributes.get('serials', '').split(',')) > 1
-
-
def SetupTsMonGlobalState(*args, **kwargs):
"""Import-safe wrap around chromite.lib.ts_mon_config's setup function.
@@ -990,4 +976,4 @@
_report_result_size_metrics(result_size_info)
- return result_size_info
\ No newline at end of file
+ return result_size_info
diff --git a/site_utils/acts_lib.py b/site_utils/acts_lib.py
deleted file mode 100644
index e8642c9..0000000
--- a/site_utils/acts_lib.py
+++ /dev/null
@@ -1,610 +0,0 @@
-# Copyright 2016 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import logging
-import os
-
-from autotest_lib.client.common_lib import error
-from autotest_lib.client.common_lib import global_config
-from autotest_lib.server import adb_utils
-from autotest_lib.server import constants
-from autotest_lib.server.hosts import adb_host
-
-DEFAULT_ACTS_INTERNAL_DIRECTORY = 'tools/test/connectivity/acts'
-
-CONFIG_FOLDER_LOCATION = global_config.global_config.get_config_value(
- 'ACTS', 'acts_config_folder', default='')
-
-TEST_DIR_NAME = 'tests'
-FRAMEWORK_DIR_NAME = 'framework'
-SETUP_FILE_NAME = 'setup.py'
-CONFIG_DIR_NAME = 'autotest_config'
-CAMPAIGN_DIR_NAME = 'autotest_campaign'
-LOG_DIR_NAME = 'logs'
-ACTS_EXECUTABLE_IN_FRAMEWORK = 'acts/bin/act.py'
-
-ACTS_TESTPATHS_ENV_KEY = 'ACTS_TESTPATHS'
-ACTS_LOGPATH_ENV_KEY = 'ACTS_LOGPATH'
-ACTS_PYTHONPATH_ENV_KEY = 'PYTHONPATH'
-
-
-def create_acts_package_from_current_artifact(test_station, job_repo_url,
- target_zip_file):
- """Creates an acts package from the build branch being used.
-
- Creates an acts artifact from the build branch being used. This is
- determined by the job_repo_url passed in.
-
- @param test_station: The teststation that should be creating the package.
- @param job_repo_url: The job_repo_url to get the build info from.
- @param target_zip_file: The zip file to create form the artifact on the
- test_station.
-
- @returns An ActsPackage containing all the information about the zipped
- artifact.
- """
- build_info = adb_host.ADBHost.get_build_info_from_build_url(job_repo_url)
-
- return create_acts_package_from_artifact(
- test_station, build_info['branch'], build_info['target'],
- build_info['build_id'], job_repo_url, target_zip_file)
-
-
-def create_acts_package_from_artifact(test_station, branch, target, build_id,
- devserver, target_zip_file):
- """Creates an acts package from a specified branch.
-
- Grabs the packaged acts artifact from the branch and places it on the
- test_station.
-
- @param test_station: The teststation that should be creating the package.
- @param branch: The name of the branch where the artifact is to be pulled.
- @param target: The name of the target where the artifact is to be pulled.
- @param build_id: The build id to pull the artifact from.
- @param devserver: The devserver to use.
- @param target_zip_file: The zip file to create on the teststation.
-
- @returns An ActsPackage containing all the information about the zipped
- artifact.
- """
- devserver.trigger_download(
- target, build_id, branch, files='acts.zip', synchronous=True)
-
- pull_base_url = devserver.get_pull_url(target, build_id, branch)
- download_ulr = os.path.join(pull_base_url, 'acts.zip')
-
- test_station.download_file(download_ulr, target_zip_file)
-
- return ActsPackage(test_station, target_zip_file)
-
-
-def create_acts_package_from_zip(test_station, zip_location, target_zip_file):
- """Creates an acts package from an existing zip.
-
- Creates an acts package from a zip file that already sits on the drone.
-
- @param test_station: The teststation to create the package on.
- @param zip_location: The location of the zip on the drone.
- @param target_zip_file: The zip file to create on the teststaiton.
-
- @returns An ActsPackage containing all the information about the zipped
- artifact.
- """
- if not os.path.isabs(zip_location):
- zip_location = os.path.join(CONFIG_FOLDER_LOCATION, 'acts_artifacts',
- zip_location)
-
- test_station.send_file(zip_location, target_zip_file)
-
- return ActsPackage(test_station, target_zip_file)
-
-
-class ActsPackage(object):
- """A packaged version of acts on a teststation."""
-
- def __init__(self, test_station, zip_file_path):
- """
- @param test_station: The teststation this package is on.
- @param zip_file_path: The path to the zip file on the test station that
- holds the package on the teststation.
- """
- self.test_station = test_station
- self.zip_file = zip_file_path
-
- def create_container(self,
- container_directory,
- internal_acts_directory=None):
- """Unpacks this package into a container.
-
- Unpacks this acts package into a container to interact with acts.
-
- @param container_directory: The directory on the teststation to hold
- the container.
- @param internal_acts_directory: The directory inside of the package
- that holds acts.
-
- @returns: An ActsContainer with info on the unpacked acts container.
- """
- self.test_station.run('unzip "%s" -x -d "%s"' %
- (self.zip_file, container_directory))
-
- return ActsContainer(
- self.test_station,
- container_directory,
- acts_directory=internal_acts_directory)
-
- def create_environment(self,
- container_directory,
- devices,
- testbed_name,
- internal_acts_directory=None):
- """Unpacks this package into an acts testing enviroment.
-
- Unpacks this acts package into a test enviroment to test with acts.
-
- @param container_directory: The directory on the teststation to hold
- the test enviroment.
- @param devices: The list of devices in the environment.
- @param testbed_name: The name of the testbed.
- @param internal_acts_directory: The directory inside of the package
- that holds acts.
-
- @returns: An ActsTestingEnvironment with info on the unpacked
- acts testing environment.
- """
- container = self.create_container(container_directory,
- internal_acts_directory)
-
- return ActsTestingEnviroment(
- devices=devices,
- container=container,
- testbed_name=testbed_name)
-
-
-class AndroidTestingEnvironment(object):
- """A container for testing android devices on a test station."""
-
- def __init__(self, devices, testbed_name):
- """Creates a new android testing environment.
-
- @param devices: The devices on the testbed to use.
- @param testbed_name: The name for the testbed.
- """
- self.devices = devices
- self.testbed_name = testbed_name
-
- def install_sl4a_apk(self, force_reinstall=True):
- """Install sl4a to all provided devices..
-
- @param force_reinstall: If true the apk will be force to reinstall.
- """
- for device in self.devices:
- adb_utils.install_apk_from_build(
- device,
- constants.SL4A_APK,
- constants.SL4A_ARTIFACT,
- package_name=constants.SL4A_PACKAGE,
- force_reinstall=force_reinstall)
-
- def install_apk(self, apk_info, force_reinstall=True):
- """Installs an additional apk on all adb devices.
-
- @param apk_info: A dictionary containing the apk info. This dictionary
- should contain the keys:
- apk="Name of the apk",
- package="Name of the package".
- artifact="Name of the artifact", if missing
- the package name is used."
- @param force_reinstall: If true the apk will be forced to reinstall.
- """
- for device in self.devices:
- adb_utils.install_apk_from_build(
- device,
- apk_info['apk'],
- apk_info.get('artifact') or constants.SL4A_ARTIFACT,
- package_name=apk_info['package'],
- force_reinstall=force_reinstall)
-
-
-class ActsContainer(object):
- """A container for working with acts."""
-
- def __init__(self, test_station, container_directory, acts_directory=None):
- """
- @param test_station: The test station that the container is on.
- @param container_directory: The directory on the teststation this
- container operates out of.
- @param acts_directory: The directory within the container that holds
- acts. If none then it defaults to
- DEFAULT_ACTS_INTERNAL_DIRECTORY.
- """
- self.test_station = test_station
- self.container_directory = container_directory
-
- if not acts_directory:
- acts_directory = DEFAULT_ACTS_INTERNAL_DIRECTORY
-
- if not os.path.isabs(acts_directory):
- self.acts_directory = os.path.join(container_directory,
- acts_directory)
- else:
- self.acts_directory = acts_directory
-
- self.tests_directory = os.path.join(self.acts_directory, TEST_DIR_NAME)
- self.framework_directory = os.path.join(self.acts_directory,
- FRAMEWORK_DIR_NAME)
-
- self.acts_file = os.path.join(self.framework_directory,
- ACTS_EXECUTABLE_IN_FRAMEWORK)
-
- self.setup_file = os.path.join(self.framework_directory,
- SETUP_FILE_NAME)
-
- self.log_directory = os.path.join(container_directory,
- LOG_DIR_NAME)
-
- self.config_location = os.path.join(container_directory,
- CONFIG_DIR_NAME)
-
- self.acts_file = os.path.join(self.framework_directory,
- ACTS_EXECUTABLE_IN_FRAMEWORK)
-
- self.working_directory = os.path.join(container_directory,
- CONFIG_DIR_NAME)
- test_station.run('mkdir %s' % self.working_directory,
- ignore_status=True)
-
- def get_test_paths(self):
- """Get all test paths within this container.
-
- Gets all paths that hold tests within the container.
-
- @returns: A list of paths on the teststation that hold tests.
- """
- get_test_paths_result = self.test_station.run('find %s -type d' %
- self.tests_directory)
- test_search_dirs = get_test_paths_result.stdout.splitlines()
- return test_search_dirs
-
- def get_python_path(self):
- """Get the python path being used.
-
- Gets the python path that will be set in the enviroment for this
- container.
-
- @returns: A string of the PYTHONPATH enviroment variable to be used.
- """
- return '%s:$PYTHONPATH' % self.framework_directory
-
- def get_enviroment(self):
- """Gets the enviroment variables to be used for this container.
-
- @returns: A dictionary of enviroment variables to be used by this
- container.
- """
- env = {
- ACTS_TESTPATHS_ENV_KEY: ':'.join(self.get_test_paths()),
- ACTS_LOGPATH_ENV_KEY: self.log_directory,
- ACTS_PYTHONPATH_ENV_KEY: self.get_python_path()
- }
-
- return env
-
- def upload_file(self, src, dst):
- """Uploads a file to be used by the container.
-
- Uploads a file from the drone to the test staiton to be used by the
- test container.
-
- @param src: The source file on the drone. If a relative path is given
- it is assumed to exist in CONFIG_FOLDER_LOCATION.
- @param dst: The destination on the teststation. If a relative path is
- given it is assumed that it is within the container.
-
- @returns: The full path on the teststation.
- """
- if not os.path.isabs(src):
- src = os.path.join(CONFIG_FOLDER_LOCATION, src)
-
- if not os.path.isabs(dst):
- dst = os.path.join(self.container_directory, dst)
-
- path = os.path.dirname(dst)
- self.test_station.run('mkdir "%s"' % path, ignore_status=True)
-
- original_dst = dst
- if os.path.basename(src) == os.path.basename(dst):
- dst = os.path.dirname(dst)
-
- self.test_station.send_file(src, dst)
-
- return original_dst
-
-
-class ActsTestingEnviroment(AndroidTestingEnvironment):
- """A container for running acts tests with a contained version of acts."""
-
- def __init__(self, container, devices, testbed_name):
- """
- @param container: The acts container to use.
- @param devices: The list of devices to use.
- @testbed_name: The name of the testbed being used.
- """
- super(ActsTestingEnviroment, self).__init__(devices=devices,
- testbed_name=testbed_name)
-
- self.container = container
-
- self.configs = {}
- self.campaigns = {}
-
- def upload_config(self, config_file):
- """Uploads a config file to the container.
-
- Uploads a config file to the config folder in the container.
-
- @param config_file: The config file to upload. This must be a file
- within the autotest_config directory under the
- CONFIG_FOLDER_LOCATION.
-
- @returns: The full path of the config on the test staiton.
- """
- full_name = os.path.join(CONFIG_DIR_NAME, config_file)
-
- full_path = self.container.upload_file(full_name, full_name)
- self.configs[config_file] = full_path
-
- return full_path
-
- def upload_campaign(self, campaign_file):
- """Uploads a campaign file to the container.
-
- Uploads a campaign file to the campaign folder in the container.
-
- @param campaign_file: The campaign file to upload. This must be a file
- within the autotest_campaign directory under the
- CONFIG_FOLDER_LOCATION.
-
- @returns: The full path of the campaign on the test staiton.
- """
- full_name = os.path.join(CAMPAIGN_DIR_NAME, campaign_file)
-
- full_path = self.container.upload_file(full_name, full_name)
- self.campaigns[campaign_file] = full_path
-
- return full_path
-
- def setup_enviroment(self, python_bin='python'):
- """Sets up the teststation system enviroment so the container can run.
-
- Prepares the remote system so that the container can run. This involves
- uninstalling all versions of acts for the version of python being
- used and installing all needed dependencies.
-
- @param python_bin: The python binary to use.
- """
- uninstall_command = '%s %s uninstall' % (
- python_bin, self.container.setup_file)
- install_deps_command = '%s %s install_deps' % (
- python_bin, self.container.setup_file)
-
- self.container.test_station.run(uninstall_command)
- self.container.test_station.run(install_deps_command)
-
- def run_test(self,
- config,
- campaign=None,
- test_case=None,
- extra_env={},
- python_bin='python',
- timeout=7200,
- additional_cmd_line_params=None):
- """Runs a test within the container.
-
- Runs a test within a container using the given settings.
-
- @param config: The name of the config file to use as the main config.
- This should have already been uploaded with
- upload_config. The string passed into upload_config
- should be used here.
- @param campaign: The campaign file to use for this test. If none then
- test_case is assumed. This file should have already
- been uploaded with upload_campaign. The string passed
- into upload_campaign should be used here.
- @param test_case: The test case to run the test with. If none then the
- campaign will be used. If multiple are given,
- multiple will be run.
- @param extra_env: Extra enviroment variables to run the test with.
- @param python_bin: The python binary to execute the test with.
- @param timeout: How many seconds to wait before timing out.
- @param additional_cmd_line_params: Adds the ability to add any string
- to the end of the acts.py command
- line string. This is intended to
- add acts command line flags however
- this is unbounded so it could cause
- errors if incorrectly set.
-
- @returns: The results of the test run.
- """
- if not config in self.configs:
- # Check if the config has been uploaded and upload if it hasn't
- self.upload_config(config)
-
- full_config = self.configs[config]
-
- if campaign:
- # When given a campaign check if it's upload.
- if not campaign in self.campaigns:
- self.upload_campaign(campaign)
-
- full_campaign = self.campaigns[campaign]
- else:
- full_campaign = None
-
- full_env = self.container.get_enviroment()
-
- # Setup environment variables.
- if extra_env:
- for k, v in extra_env.items():
- full_env[k] = extra_env
-
- logging.info('Using env: %s', full_env)
- exports = ('export %s=%s' % (k, v) for k, v in full_env.items())
- env_command = ';'.join(exports)
-
- # Make sure to execute in the working directory.
- command_setup = 'cd %s' % self.container.working_directory
-
- if additional_cmd_line_params:
- act_base_cmd = '%s %s -c %s -tb %s %s ' % (
- python_bin, self.container.acts_file, full_config,
- self.testbed_name, additional_cmd_line_params)
- else:
- act_base_cmd = '%s %s -c %s -tb %s ' % (
- python_bin, self.container.acts_file, full_config,
- self.testbed_name)
-
- # Format the acts command based on what type of test is being run.
- if test_case and campaign:
- raise error.TestError(
- 'campaign and test_file cannot both have a value.')
- elif test_case:
- if isinstance(test_case, str):
- test_case = [test_case]
- if len(test_case) < 1:
- raise error.TestError('At least one test case must be given.')
-
- tc_str = ''
- for tc in test_case:
- tc_str = '%s %s' % (tc_str, tc)
- tc_str = tc_str.strip()
-
- act_cmd = '%s -tc %s' % (act_base_cmd, tc_str)
- elif campaign:
- act_cmd = '%s -tf %s' % (act_base_cmd, full_campaign)
- else:
- raise error.TestFail('No tests was specified!')
-
- # Format all commands into a single command.
- command_list = [command_setup, env_command, act_cmd]
- full_command = '; '.join(command_list)
-
- try:
- # Run acts on the remote machine.
- act_result = self.container.test_station.run(full_command,
- timeout=timeout)
- excep = None
- except Exception as e:
- # Catch any error to store in the results.
- act_result = None
- excep = e
-
- return ActsTestResults(str(test_case) or campaign,
- container=self.container,
- devices=self.devices,
- testbed_name=self.testbed_name,
- run_result=act_result,
- exception=excep)
-
-
-class ActsTestResults(object):
- """The packaged results of a test run."""
- acts_result_to_autotest = {
- 'PASS': 'GOOD',
- 'FAIL': 'FAIL',
- 'UNKNOWN': 'WARN',
- 'SKIP': 'ABORT'
- }
-
- def __init__(self,
- name,
- container,
- devices,
- testbed_name,
- run_result=None,
- exception=None):
- """
- @param name: A name to identify the test run.
- @param testbed_name: The name the testbed was run with, if none the
- default name of the testbed is used.
- @param run_result: The raw i/o result of the test run.
- @param log_directory: The directory that acts logged to.
- @param exception: An exception that was thrown while running the test.
- """
- self.name = name
- self.run_result = run_result
- self.exception = exception
- self.log_directory = container.log_directory
- self.test_station = container.test_station
- self.testbed_name = testbed_name
- self.devices = devices
-
- self.reported_to = set()
-
- self.json_results = {}
- self.results_dir = None
- if self.log_directory:
- self.results_dir = os.path.join(self.log_directory,
- self.testbed_name, 'latest')
- results_file = os.path.join(self.results_dir,
- 'test_run_summary.json')
- cat_log_result = self.test_station.run('cat %s' % results_file,
- ignore_status=True)
- if not cat_log_result.exit_status:
- self.json_results = json.loads(cat_log_result.stdout)
-
- def log_output(self):
- """Logs the output of the test."""
- if self.run_result:
- logging.debug('ACTS Output:\n%s', self.run_result.stdout)
-
- def save_test_info(self, test):
- """Save info about the test.
-
- @param test: The test to save.
- """
- for device in self.devices:
- device.save_info(test.resultsdir)
-
- def rethrow_exception(self):
- """Re-throws the exception thrown during the test."""
- if self.exception:
- raise self.exception
-
- def upload_to_local(self, local_dir):
- """Saves all acts results to a local directory.
-
- @param local_dir: The directory on the local machine to save all results
- to.
- """
- if self.results_dir:
- self.test_station.get_file(self.results_dir, local_dir)
-
- def report_to_autotest(self, test):
- """Reports the results to an autotest test object.
-
- Reports the results to the test and saves all acts results under the
- tests results directory.
-
- @param test: The autotest test object to report to. If this test object
- has already recived our report then this call will be
- ignored.
- """
- if test in self.reported_to:
- return
-
- if self.results_dir:
- self.upload_to_local(test.resultsdir)
-
- if not 'Results' in self.json_results:
- return
-
- results = self.json_results['Results']
- for result in results:
- verdict = self.acts_result_to_autotest[result['Result']]
- details = result['Details']
- test.job.record(verdict, None, self.name, status=(details or ''))
-
- self.reported_to.add(test)