19190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake# Copyright 2016 The Chromium OS Authors. All rights reserved. 29190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake# Use of this source code is governed by a BSD-style license that can be 39190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake# found in the LICENSE file. 49190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 59190a1326eab9dd70406d0fff3988466f4c888b2Benny Peakeimport json 69190a1326eab9dd70406d0fff3988466f4c888b2Benny Peakeimport logging 79190a1326eab9dd70406d0fff3988466f4c888b2Benny Peakeimport os 89190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 99190a1326eab9dd70406d0fff3988466f4c888b2Benny Peakefrom autotest_lib.client.common_lib import error 109190a1326eab9dd70406d0fff3988466f4c888b2Benny Peakefrom autotest_lib.client.common_lib import global_config 119190a1326eab9dd70406d0fff3988466f4c888b2Benny Peakefrom autotest_lib.client.common_lib.cros import dev_server 129190a1326eab9dd70406d0fff3988466f4c888b2Benny Peakefrom autotest_lib.server import adb_utils 139190a1326eab9dd70406d0fff3988466f4c888b2Benny Peakefrom autotest_lib.server import constants 149190a1326eab9dd70406d0fff3988466f4c888b2Benny Peakefrom autotest_lib.server.cros import dnsname_mangler 159190a1326eab9dd70406d0fff3988466f4c888b2Benny Peakefrom autotest_lib.server.hosts import adb_host 169190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 179190a1326eab9dd70406d0fff3988466f4c888b2Benny PeakeDEFAULT_ACTS_INTERNAL_DIRECTORY = 'tools/test/connectivity/acts' 189190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 199190a1326eab9dd70406d0fff3988466f4c888b2Benny PeakeCONFIG_FOLDER_LOCATION = global_config.global_config.get_config_value( 20a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan 'ACTS', 'acts_config_folder', default='') 219190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 229190a1326eab9dd70406d0fff3988466f4c888b2Benny PeakeTEST_DIR_NAME = 'tests' 239190a1326eab9dd70406d0fff3988466f4c888b2Benny PeakeFRAMEWORK_DIR_NAME = 'framework' 249190a1326eab9dd70406d0fff3988466f4c888b2Benny PeakeSETUP_FILE_NAME = 'setup.py' 259190a1326eab9dd70406d0fff3988466f4c888b2Benny PeakeCONFIG_DIR_NAME = 'autotest_config' 269190a1326eab9dd70406d0fff3988466f4c888b2Benny PeakeCAMPAIGN_DIR_NAME = 'autotest_campaign' 279190a1326eab9dd70406d0fff3988466f4c888b2Benny PeakeLOG_DIR_NAME = 'logs' 289190a1326eab9dd70406d0fff3988466f4c888b2Benny PeakeACTS_EXECUTABLE_IN_FRAMEWORK = 'acts/bin/act.py' 299190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 309190a1326eab9dd70406d0fff3988466f4c888b2Benny PeakeACTS_TESTPATHS_ENV_KEY = 'ACTS_TESTPATHS' 319190a1326eab9dd70406d0fff3988466f4c888b2Benny PeakeACTS_LOGPATH_ENV_KEY = 'ACTS_LOGPATH' 329190a1326eab9dd70406d0fff3988466f4c888b2Benny PeakeACTS_PYTHONPATH_ENV_KEY = 'PYTHONPATH' 339190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 349190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 359190a1326eab9dd70406d0fff3988466f4c888b2Benny Peakedef create_acts_package_from_current_artifact(test_station, job_repo_url, 369190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake target_zip_file): 379190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """Creates an acts package from the build branch being used. 389190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 399190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake Creates an acts artifact from the build branch being used. This is 409190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake determined by the job_repo_url passed in. 419190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 429190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param test_station: The teststation that should be creating the package. 439190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param job_repo_url: The job_repo_url to get the build info from. 449190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param target_zip_file: The zip file to create form the artifact on the 459190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake test_station. 469190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 479190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @returns An ActsPackage containing all the information about the zipped 489190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake artifact. 499190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 509190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake build_info = adb_host.ADBHost.get_build_info_from_build_url(job_repo_url) 519190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 529190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake return create_acts_package_from_artifact( 53a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan test_station, build_info['branch'], build_info['target'], 54a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan build_info['build_id'], job_repo_url, target_zip_file) 559190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 569190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 579190a1326eab9dd70406d0fff3988466f4c888b2Benny Peakedef create_acts_package_from_artifact(test_station, branch, target, build_id, 589190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake job_repo_url, target_zip_file): 599190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """Creates an acts package from a specified branch. 609190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 619190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake Grabs the packaged acts artifact from the branch and places it on the 629190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake test_station. 639190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 649190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param test_station: The teststation that should be creating the package. 659190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param branch: The name of the branch where the artifact is to be pulled. 669190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param target: The name of the target where the artifact is to be pulled. 679190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param build_id: The build id to pull the artifact from. 689190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param job_repo_url: The job repo url for where to pull build from. 699190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param target_zip_file: The zip file to create on the teststation. 709190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 719190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @returns An ActsPackage containing all the information about the zipped 729190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake artifact. 739190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 749190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake devserver_url = dev_server.AndroidBuildServer.get_server_url(job_repo_url) 759190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake devserver = dev_server.AndroidBuildServer(devserver_url) 76a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan devserver.trigger_download( 77a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan target, build_id, branch, files='acts.zip', synchronous=True) 789190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 79d6ac897f46fa85e88f727c73490273556a4ad798Benny Peake pull_base_url = devserver.get_pull_url(target, build_id, branch) 80d6ac897f46fa85e88f727c73490273556a4ad798Benny Peake download_ulr = os.path.join(pull_base_url, 'acts.zip') 819190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 829190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake test_station.download_file(download_ulr, target_zip_file) 839190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 849190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake return ActsPackage(test_station, target_zip_file) 859190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 869190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 879190a1326eab9dd70406d0fff3988466f4c888b2Benny Peakedef create_acts_package_from_zip(test_station, zip_location, target_zip_file): 889190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """Creates an acts package from an existing zip. 899190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 909190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake Creates an acts package from a zip file that already sits on the drone. 919190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 929190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param test_station: The teststation to create the package on. 939190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param zip_location: The location of the zip on the drone. 949190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param target_zip_file: The zip file to create on the teststaiton. 959190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 969190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @returns An ActsPackage containing all the information about the zipped 979190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake artifact. 989190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 999190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake if not os.path.isabs(zip_location): 1009190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake zip_location = os.path.join(CONFIG_FOLDER_LOCATION, 'acts_artifacts', 1019190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake zip_location) 1029190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 10333fb5ffd979a9d00c42a74b88e73697feaeba8a7Benny Peake test_station.send_file(zip_location, target_zip_file) 1049190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 10533fb5ffd979a9d00c42a74b88e73697feaeba8a7Benny Peake return ActsPackage(test_station, target_zip_file) 1069190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 1079190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 1089190a1326eab9dd70406d0fff3988466f4c888b2Benny Peakeclass ActsPackage(object): 1099190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """A packaged version of acts on a teststation.""" 110a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan 1119190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake def __init__(self, test_station, zip_file_path): 1129190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 1139190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param test_station: The teststation this package is on. 1149190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param zip_file_path: The path to the zip file on the test station that 1159190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake holds the package on the teststation. 1169190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 1179190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.test_station = test_station 1189190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.zip_file = zip_file_path 1199190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 1209190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake def create_container(self, 1219190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake container_directory, 1229190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake internal_acts_directory=None): 1239190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """Unpacks this package into a container. 1249190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 1259519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake Unpacks this acts package into a container to interact with acts. 1269190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 1279190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param container_directory: The directory on the teststation to hold 1289190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake the container. 1299190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param internal_acts_directory: The directory inside of the package 1309190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake that holds acts. 1319190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 1329190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @returns: An ActsContainer with info on the unpacked acts container. 1339190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 1349519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake self.test_station.run('unzip "%s" -x -d "%s"' % 1359519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake (self.zip_file, container_directory)) 1369519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake 137a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan return ActsContainer( 138a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan self.test_station, 139a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan container_directory, 140a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan acts_directory=internal_acts_directory) 1419519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake 1429519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake def create_enviroment(self, 1439519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake container_directory, 1449519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake testbed, 1459519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake testbed_name=None, 1469519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake internal_acts_directory=None): 1479519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake """Unpacks this package into an acts testing enviroment. 1489519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake 1499519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake Unpacks this acts package into a test enviroment to test with acts. 1509519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake 1519519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake @param container_directory: The directory on the teststation to hold 1529519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake the test enviroment. 1539519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake @param testbed: The testbed that the test enviroment 1549519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake will be testing on. 1559519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake @param testbed_name: An overriding name for the testbed. 1569519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake @param internal_acts_directory: The directory inside of the package 1579519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake that holds acts. 1589519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake 1599519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake @returns: An ActsTestingEnviroment with info on the unpacked 1609519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake acts testing enviroment. 1619519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake """ 162591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake if testbed.teststation != self.test_station: 163591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake raise error.TestError('Creating a contianer for a testbed on a ' 164a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan 'different teststation is not allowed.') 165591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake 1669190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.test_station.run('unzip "%s" -x -d "%s"' % 1679190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake (self.zip_file, container_directory)) 1689190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 169a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan return ActsTestingEnviroment( 170a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan testbed=testbed, 171a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan container_directory=container_directory, 172a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan testbed_name=testbed_name, 173a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan acts_directory=internal_acts_directory) 1749190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 1759190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 176591cff492c1d31debfb7d44723a5d382e22b132bBenny Peakeclass AndroidTestingEnviroment(object): 177591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake """A container for testing android devices on a test station.""" 178a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan 1799519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake def __init__(self, testbed, testbed_name=None): 180591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake """Creates a new android testing enviroment. 181591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake 182591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake @param testbed: The testbed to test on. 183591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake @param testbed_name: An overriding name for the testbed. 184591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake """ 185591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake self.testbed = testbed 186591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake 187591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake if not testbed_name: 188591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake # If no override is given get the name from the hostname. 189591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake hostname = testbed.hostname 190591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake if dnsname_mangler.is_ip_address(hostname): 191591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake testbed_name = hostname 192591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake else: 193591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake testbed_name = hostname.split('.')[0] 194591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake 195591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake self.testbed_name = testbed_name 196591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake 197ccac2d18550a9c5d2c43545da73f4f6f6b398d60Benny Peake def install_sl4a_apk(self, force_reinstall=True): 198ccac2d18550a9c5d2c43545da73f4f6f6b398d60Benny Peake """Install sl4a to a test bed. 199ccac2d18550a9c5d2c43545da73f4f6f6b398d60Benny Peake 200ccac2d18550a9c5d2c43545da73f4f6f6b398d60Benny Peake @param force_reinstall: If true the apk will be force to reinstall. 201ccac2d18550a9c5d2c43545da73f4f6f6b398d60Benny Peake """ 202591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake for serial, adb_host in self.testbed.get_adb_devices().iteritems(): 203591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake adb_utils.install_apk_from_build( 204a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan adb_host, 205a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan constants.SL4A_APK, 206a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan constants.SL4A_ARTIFACT, 207ccac2d18550a9c5d2c43545da73f4f6f6b398d60Benny Peake package_name=constants.SL4A_PACKAGE, 208ccac2d18550a9c5d2c43545da73f4f6f6b398d60Benny Peake force_reinstall=force_reinstall) 209591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake 210ccac2d18550a9c5d2c43545da73f4f6f6b398d60Benny Peake def install_apk(self, apk_info, force_reinstall=True): 211591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake """Installs an additional apk on all adb devices. 2122573fae61e5f6a4d2809ac21630da7c625711088Benny Peake 2132573fae61e5f6a4d2809ac21630da7c625711088Benny Peake @param apk_info: A dictionary contianing the apk info. This dictionary 2142573fae61e5f6a4d2809ac21630da7c625711088Benny Peake should contain the keys: 2152573fae61e5f6a4d2809ac21630da7c625711088Benny Peake apk="Name of the apk", 2162573fae61e5f6a4d2809ac21630da7c625711088Benny Peake package="Name of the package". 2172573fae61e5f6a4d2809ac21630da7c625711088Benny Peake artifact="Name of the artifact", if missing 2182573fae61e5f6a4d2809ac21630da7c625711088Benny Peake the package name is used." 219ccac2d18550a9c5d2c43545da73f4f6f6b398d60Benny Peake @param force_reinstall: If true the apk will be forced to reinstall. 220591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake """ 221591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake for serial, adb_host in self.testbed.get_adb_devices().iteritems(): 222591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake adb_utils.install_apk_from_build( 223a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan adb_host, 224a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan apk_info['apk'], 225a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan apk_info.get('artifact') or constants.SL4A_ARTIFACT, 226ccac2d18550a9c5d2c43545da73f4f6f6b398d60Benny Peake package_name=apk_info['package'], 227ccac2d18550a9c5d2c43545da73f4f6f6b398d60Benny Peake force_reinstall=force_reinstall) 228591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake 229591cff492c1d31debfb7d44723a5d382e22b132bBenny Peake 2309519ea8471db998eefa54c38508e85d4fa8c1508Benny Peakeclass ActsContainer(object): 2319519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake """A container for working with acts.""" 232a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan 233a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan def __init__(self, test_station, container_directory, acts_directory=None): 2349190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 2359519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake @param test_station: The test station that the container is on. 2369190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param container_directory: The directory on the teststation this 2379190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake container operates out of. 2389190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param acts_directory: The directory within the container that holds 2399190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake acts. If none then it defaults to 2409190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake DEFAULT_ACTS_INTERNAL_DIRECTORY. 2419190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 2429519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake self.test_station = test_station 2439519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake self.container_directory = container_directory 2449190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 2459190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake if not acts_directory: 2469190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake acts_directory = DEFAULT_ACTS_INTERNAL_DIRECTORY 2479190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 2489190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake if not os.path.isabs(acts_directory): 2499190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.acts_directory = os.path.join(container_directory, 2509190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake acts_directory) 2519190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake else: 2529190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.acts_directory = acts_directory 2539190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 2549190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.tests_directory = os.path.join(self.acts_directory, TEST_DIR_NAME) 2559190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.framework_directory = os.path.join(self.acts_directory, 2569190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake FRAMEWORK_DIR_NAME) 2579190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 2589190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.acts_file = os.path.join(self.framework_directory, 2599190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake ACTS_EXECUTABLE_IN_FRAMEWORK) 2609190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 2619190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.setup_file = os.path.join(self.framework_directory, 2629190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake SETUP_FILE_NAME) 2639190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 2649190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake def get_test_paths(self): 2659190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """Get all test paths within this container. 2669190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 2679190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake Gets all paths that hold tests within the container. 2689190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 2699190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @returns: A list of paths on the teststation that hold tests. 2709190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 2719190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake get_test_paths_result = self.test_station.run('find %s -type d' % 2729190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.tests_directory) 2739190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake test_search_dirs = get_test_paths_result.stdout.splitlines() 2749190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake return test_search_dirs 2759190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 2769190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake def get_python_path(self): 2779190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """Get the python path being used. 2789190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 2799190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake Gets the python path that will be set in the enviroment for this 2809190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake container. 2819190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 2829190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @returns: A string of the PYTHONPATH enviroment variable to be used. 2839190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 2849190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake return '%s:$PYTHONPATH' % self.framework_directory 2859190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 2869190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake def get_enviroment(self): 2879190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """Gets the enviroment variables to be used for this container. 2889190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 2899190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @returns: A dictionary of enviroment variables to be used by this 2909190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake container. 2919190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 292a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan env = { 293a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan ACTS_TESTPATHS_ENV_KEY: ':'.join(self.get_test_paths()), 294a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan ACTS_LOGPATH_ENV_KEY: self.log_directory, 295a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan ACTS_PYTHONPATH_ENV_KEY: self.get_python_path() 296a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan } 2979190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 2989190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake return env 2999190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 3009190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake def upload_file(self, src, dst): 3019190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """Uploads a file to be used by the container. 3029190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 3039190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake Uploads a file from the drone to the test staiton to be used by the 3049190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake test container. 3059190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 3069190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param src: The source file on the drone. If a relative path is given 3079190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake it is assumed to exist in CONFIG_FOLDER_LOCATION. 3089190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param dst: The destination on the teststation. If a relative path is 3099190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake given it is assumed that it is within the container. 3109190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 3119190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @returns: The full path on the teststation. 3129190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 3139190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake if not os.path.isabs(src): 3149190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake src = os.path.join(CONFIG_FOLDER_LOCATION, src) 3159190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 3169190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake if not os.path.isabs(dst): 3179190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake dst = os.path.join(self.container_directory, dst) 3189190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 319f1b9f3932748bbdb20f07cb90cfade4338098ad2Benny Peake path = os.path.dirname(dst) 320a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan result = self.test_station.run('mkdir "%s"' % path, ignore_status=True) 321f1b9f3932748bbdb20f07cb90cfade4338098ad2Benny Peake 322f1b9f3932748bbdb20f07cb90cfade4338098ad2Benny Peake original_dst = dst 323f1b9f3932748bbdb20f07cb90cfade4338098ad2Benny Peake if os.path.basename(src) == os.path.basename(dst): 324f1b9f3932748bbdb20f07cb90cfade4338098ad2Benny Peake dst = os.path.dirname(dst) 3259190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 3269190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.test_station.send_file(src, dst) 3279190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 328f1b9f3932748bbdb20f07cb90cfade4338098ad2Benny Peake return original_dst 3299190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 3309519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake def setup_enviroment(self, python_bin='python'): 3319519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake """Sets up the teststation system enviroment so the container can run. 3329519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake 3339519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake Prepares the remote system so that the container can run. This involves 3349519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake uninstalling all versions of acts for the version of python being 3359519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake used and installing all needed dependencies. 3369519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake 3379519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake @param python_bin: The python binary to use. 3389519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake """ 3399519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake uninstall_command = '%s %s uninstall' % (python_bin, self.setup_file) 3409519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake install_deps_command = '%s %s install_deps' % (python_bin, 3419519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake self.setup_file) 3429519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake 3439519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake self.test_station.run(uninstall_command) 3449519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake self.test_station.run(install_deps_command) 3459519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake 3469519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake 3479519ea8471db998eefa54c38508e85d4fa8c1508Benny Peakeclass ActsTestingEnviroment(ActsContainer, AndroidTestingEnviroment): 3489519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake """A container for running acts tests with a contained version of acts.""" 349a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan 3509519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake def __init__(self, 3519519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake container_directory, 3529519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake testbed, 3539519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake testbed_name=None, 3549519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake acts_directory=None): 3559519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake """ 3569519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake @param testbed: The testbed to test on. 3579519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake @param container_directory: The directory on the teststation this 3589519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake container operates out of. 3599519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake @param testbed_name: An overriding name for the testbed. 3609519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake @param acts_directory: The directory within the container that holds 3619519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake acts. If none then it defaults to 3629519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake DEFAULT_ACTS_INTERNAL_DIRECTORY. 3639519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake """ 364a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan AndroidTestingEnviroment.__init__( 365a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan self, testbed, testbed_name=testbed_name) 3669519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake 367a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan ActsContainer.__init__( 368a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan self, 369a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan testbed.teststation, 370a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan container_directory=container_directory, 371a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan acts_directory=acts_directory) 3729519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake 3739519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake self.config_location = os.path.join(self.container_directory, 3749519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake CONFIG_DIR_NAME) 3759519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake 3769519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake self.log_directory = os.path.join(self.container_directory, 3779519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake LOG_DIR_NAME) 3789519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake 3799519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake self.acts_file = os.path.join(self.framework_directory, 3809519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake ACTS_EXECUTABLE_IN_FRAMEWORK) 3819519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake 3829519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake self.working_directory = os.path.join(container_directory, 3839519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake CONFIG_DIR_NAME) 3849519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake self.test_station.run('mkdir %s' % self.working_directory, 385a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan ignore_status=True) 3869519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake 3879519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake self.configs = {} 3889519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake self.campaigns = {} 3899519ea8471db998eefa54c38508e85d4fa8c1508Benny Peake 3909190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake def upload_config(self, config_file): 3919190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """Uploads a config file to the container. 3929190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 3939190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake Uploads a config file to the config folder in the container. 3949190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 3959190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param config_file: The config file to upload. This must be a file 3969190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake within the autotest_config directory under the 3979190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake CONFIG_FOLDER_LOCATION. 3989190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 3999190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @returns: The full path of the config on the test staiton. 4009190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 4019190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake full_name = os.path.join(CONFIG_DIR_NAME, config_file) 4029190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4039190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake full_path = self.upload_file(full_name, full_name) 4049190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.configs[config_file] = full_path 4059190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4069190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake return full_path 4079190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4089190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake def upload_campaign(self, campaign_file): 4099190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """Uploads a campaign file to the container. 4109190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4119190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake Uploads a campaign file to the campaign folder in the container. 4129190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4139190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param campaign_file: The campaign file to upload. This must be a file 4149190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake within the autotest_campaign directory under the 4159190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake CONFIG_FOLDER_LOCATION. 4169190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4179190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @returns: The full path of the campaign on the test staiton. 4189190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 4199190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake full_name = os.path.join(CAMPAIGN_DIR_NAME, campaign_file) 4209190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4219190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake full_path = self.upload_file(full_name, full_name) 4229190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.campaigns[campaign_file] = full_path 4239190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4249190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake return full_path 4259190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4269190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake def run_test(self, 4279190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake config, 4289190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake campaign=None, 4299190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake test_case=None, 4309190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake extra_env={}, 4319190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake python_bin='python', 432a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan timeout=7200, 433a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan additional_cmd_line_params=None): 4349190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """Runs a test within the container. 4359190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4369190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake Runs a test within a container using the given settings. 4379190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4389190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param config: The name of the config file to use as the main config. 4399190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake This should have already been uploaded with 4409190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake upload_config. The string passed into upload_config 4419190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake should be used here. 4429190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param campaign: The campaign file to use for this test. If none then 4439190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake test_case is assumed. This file should have already 4449190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake been uploaded with upload_campaign. The string passed 4459190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake into upload_campaign should be used here. 4469190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param test_case: The test case to run the test with. If none then the 447913791f8d6e79e8f5f0f645b3e3793f51b71185fBenny Peake campaign will be used. If multiple are given, 448913791f8d6e79e8f5f0f645b3e3793f51b71185fBenny Peake multiple will be run. 4499190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param extra_env: Extra enviroment variables to run the test with. 4509190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param python_bin: The python binary to execute the test with. 4519190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param timeout: How many seconds to wait before timing out. 452a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan @param additional_cmd_line_params: Adds the ability to add any string 453a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan to the end of the acts.py command 454a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan line string. This is intended to 455a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan add acts command line flags however 456a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan this is unbounded so it could cause 457a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan errors if incorrectly set. 4589190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4599190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @returns: The results of the test run. 4609190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 4619190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake if not config in self.configs: 4629190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake # Check if the config has been uploaded and upload if it hasn't 4639190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.upload_config(config) 4649190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4659190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake full_config = self.configs[config] 4669190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4679190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake if campaign: 4689190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake # When given a campaign check if it's upload. 4699190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake if not campaign in self.campaigns: 4709190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.upload_campaign(campaign) 4719190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4729190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake full_campaign = self.campaigns[campaign] 4739190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake else: 4749190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake full_campaign = None 4759190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4769190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake full_env = self.get_enviroment() 4779190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4789190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake # Setup enviroment variables. 4799190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake if extra_env: 4809190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake for k, v in extra_env.items(): 4819190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake full_env[k] = extra_env 4829190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4839190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake logging.info('Using env: %s', full_env) 4849190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake exports = ('export %s=%s' % (k, v) for k, v in full_env.items()) 4859190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake env_command = ';'.join(exports) 4869190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4879190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake # Make sure to execute in the working directory. 4889190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake command_setup = 'cd %s' % self.working_directory 4899190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 490a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan if additional_cmd_line_params: 491a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan act_base_cmd = '%s %s -c %s -tb %s %s ' % ( 492a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan python_bin, self.acts_file, full_config, self.testbed_name, 493a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan additional_cmd_line_params) 494a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan else: 495a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan act_base_cmd = '%s %s -c %s -tb %s ' % ( 496a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan python_bin, self.acts_file, full_config, self.testbed_name) 4979190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 4989190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake # Format the acts command based on what type of test is being run. 4999190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake if test_case and campaign: 5009190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake raise error.TestError( 501a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan 'campaign and test_file cannot both have a value.') 5029190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake elif test_case: 503913791f8d6e79e8f5f0f645b3e3793f51b71185fBenny Peake if isinstance(test_case, str): 504913791f8d6e79e8f5f0f645b3e3793f51b71185fBenny Peake test_case = [test_case] 505913791f8d6e79e8f5f0f645b3e3793f51b71185fBenny Peake if len(test_case) < 1: 506913791f8d6e79e8f5f0f645b3e3793f51b71185fBenny Peake raise error.TestError('At least one test case must be given.') 507913791f8d6e79e8f5f0f645b3e3793f51b71185fBenny Peake 508913791f8d6e79e8f5f0f645b3e3793f51b71185fBenny Peake tc_str = '' 509913791f8d6e79e8f5f0f645b3e3793f51b71185fBenny Peake for tc in test_case: 510913791f8d6e79e8f5f0f645b3e3793f51b71185fBenny Peake tc_str = '%s %s' % (tc_str, tc) 511913791f8d6e79e8f5f0f645b3e3793f51b71185fBenny Peake tc_str = tc_str.strip() 512913791f8d6e79e8f5f0f645b3e3793f51b71185fBenny Peake 513913791f8d6e79e8f5f0f645b3e3793f51b71185fBenny Peake act_cmd = '%s -tc %s' % (act_base_cmd, tc_str) 5149190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake elif campaign: 5159190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake act_cmd = '%s -tf %s' % (act_base_cmd, full_campaign) 5169190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake else: 5179190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake raise error.TestFail('No tests was specified!') 5189190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 5199190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake # Format all commands into a single command. 5209190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake command_list = [command_setup, env_command, act_cmd] 5219190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake full_command = '; '.join(command_list) 5229190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 5239190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake try: 5249190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake # Run acts on the remote machine. 5259190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake act_result = self.test_station.run(full_command, timeout=timeout) 5269190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake excep = None 5279190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake except Exception as e: 5289190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake # Catch any error to store in the results. 5299190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake act_result = None 5309190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake excep = e 5319190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 532a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan return ActsTestResults( 533a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan str(test_case) or campaign, 534a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan self.testbed, 535a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan testbed_name=self.testbed_name, 536a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan run_result=act_result, 537a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan log_directory=self.log_directory, 538a0db27cea336604e330ce02e1011a00c760f8157Joe Brennan exception=excep) 5399190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 5409190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 5419190a1326eab9dd70406d0fff3988466f4c888b2Benny Peakeclass ActsTestResults(object): 5429190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """The packaged results of a test run.""" 5439190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake acts_result_to_autotest = { 5449190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 'PASS': 'GOOD', 5459190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 'FAIL': 'FAIL', 5469190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 'UNKNOWN': 'WARN', 5479190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 'SKIP': 'ABORT' 5489190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake } 5499190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 5509190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake def __init__(self, 5519190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake name, 5529190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake testbed, 5539190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake testbed_name=None, 5549190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake run_result=None, 55551c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake log_directory=None, 5569190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake exception=None): 5579190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 5589190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param name: A name to identify the test run. 5599190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param testbed: The testbed that ran the test. 5609190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param testbed_name: The name the testbed was run with, if none the 5619190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake default name of the testbed is used. 5629190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param run_result: The raw i/o result of the test run. 56351c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake @param log_directory: The directory that acts logged to. 5649190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param exception: An exception that was thrown while running the test. 5659190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 5669190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.name = name 5679190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.run_result = run_result 5689190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.exception = exception 56951c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake self.log_directory = log_directory 57051c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake self.test_station = testbed.teststation 5719190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 5729190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.testbed = testbed 5739190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake if not testbed_name: 5749190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake # If no override is given get the name from the hostname. 5759190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake hostname = testbed.hostname 5769190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake if dnsname_mangler.is_ip_address(hostname): 5779190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.testbed_name = hostname 5789190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake else: 5799190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.testbed_name = hostname.split('.')[0] 5809190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake else: 5819190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.testbed_name = testbed_name 5829190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 5839190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.reported_to = set() 5849190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 58551c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake self.json_results = {} 58651c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake self.results_dir = None 58751c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake if self.log_directory: 58851c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake self.results_dir = os.path.join(self.log_directory, 58951c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake self.testbed_name, 'latest') 59051c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake results_file = os.path.join(self.results_dir, 59151c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake 'test_run_summary.json') 59251c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake cat_log_result = self.test_station.run('cat %s' % results_file, 59351c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake ignore_status=True) 59451c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake if not cat_log_result.exit_status: 59551c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake self.json_results = json.loads(cat_log_result.stdout) 59651c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake 5979190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake def log_output(self): 5989190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """Logs the output of the test.""" 5999190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake if self.run_result: 6009190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake logging.debug('ACTS Output:\n%s', self.run_result.stdout) 6019190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 60283904b1ded3752220ee088feecba1571e1e8ad63Benny Peake def save_test_info(self, test): 60383904b1ded3752220ee088feecba1571e1e8ad63Benny Peake """Save info about the test. 60483904b1ded3752220ee088feecba1571e1e8ad63Benny Peake 60583904b1ded3752220ee088feecba1571e1e8ad63Benny Peake @param test: The test to save. 60683904b1ded3752220ee088feecba1571e1e8ad63Benny Peake """ 60783904b1ded3752220ee088feecba1571e1e8ad63Benny Peake if self.testbed and self: 60883904b1ded3752220ee088feecba1571e1e8ad63Benny Peake self.testbed.save_info(test.resultsdir) 60983904b1ded3752220ee088feecba1571e1e8ad63Benny Peake 6109190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake def rethrow_exception(self): 6119190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """Re-throws the exception thrown during the test.""" 6129190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake if self.exception: 6139190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake raise self.exception 6149190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 61551c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake def upload_to_local(self, local_dir): 61651c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake """Saves all acts results to a local directory. 6179190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 61851c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake @param local_dir: The directory on the local machine to save all results 61951c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake to. 6209190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 62151c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake if self.results_dir: 62251c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake self.test_station.get_file(self.results_dir, local_dir) 6239190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 6249190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake def report_to_autotest(self, test): 6259190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """Reports the results to an autotest test object. 6269190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 62751c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake Reports the results to the test and saves all acts results under the 62851c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake tests results directory. 62951c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake 6309190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake @param test: The autotest test object to report to. If this test object 6319190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake has already recived our report then this call will be 6329190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake ignored. 6339190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake """ 6349190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake if test in self.reported_to: 6359190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake return 6369190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 63751c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake if self.results_dir: 63851c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake self.upload_to_local(test.resultsdir) 63951c675ba15212e58b19fcffb9ff4bfb4031aea46Benny Peake 6409190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake if not 'Results' in self.json_results: 6419190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake return 6429190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 6439190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake results = self.json_results['Results'] 6449190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake for result in results: 6459190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake verdict = self.acts_result_to_autotest[result['Result']] 6469190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake details = result['Details'] 6479190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake test.job.record(verdict, None, self.name, status=(details or '')) 6489190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake 6499190a1326eab9dd70406d0fff3988466f4c888b2Benny Peake self.reported_to.add(test) 650