summaryrefslogtreecommitdiff
path: root/automated
diff options
context:
space:
mode:
Diffstat (limited to 'automated')
-rwxr-xr-xautomated/utils/test-runner.py151
1 files changed, 131 insertions, 20 deletions
diff --git a/automated/utils/test-runner.py b/automated/utils/test-runner.py
index c374c26..88d4177 100755
--- a/automated/utils/test-runner.py
+++ b/automated/utils/test-runner.py
@@ -28,10 +28,16 @@ except ImportError as e:
SSH_PARAMS = "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
-def call_ssh(args):
- ssh_cmd = "ssh %s %s" % (SSH_PARAMS, args)
- ssh_output = subprocess.check_output(shlex.split(ssh_cmd)).strip()
- return ssh_output
+def run_command(command, target=None):
+ """ Run a shell command. If target is specified, ssh to the given target first. """
+
+ run = command
+ if target:
+ run = 'ssh {} {} "{}"'.format(SSH_PARAMS, target, command)
+
+ logger = logging.getLogger('RUNNER.run_command')
+ logger.debug(run)
+ return subprocess.check_output(shlex.split(run)).strip().decode('utf-8')
class TestPlan(object):
@@ -293,19 +299,26 @@ class RemoteTestRun(AutomatedTestRun):
def copy_to_target(self):
os.chdir(self.test['test_path'])
tarball_name = "target-test-files.tar"
- tar_cmd = 'tar -caf %s run.sh uuid automated/lib automated/bin automated/utils %s' % (tarball_name, self.test['tc_relative_dir'])
- subprocess.call(shlex.split(tar_cmd))
- create_target_test_path_cmd = '%s "mkdir -p %s"' % (self.args.target, self.test['target_test_path'])
- call_ssh(create_target_test_path_cmd)
- scp_cmd = 'scp %s ./%s %s:%s' % (SSH_PARAMS, tarball_name, self.args.target, self.test['target_test_path'])
- self.logger.info('Pushing test files to target with command: %s' % scp_cmd)
- subprocess.call(shlex.split(scp_cmd))
- uncompress_cmd = '%s "cd %s && tar -xf %s"' % (self.args.target, self.test['target_test_path'], tarball_name)
- self.logger.info('Uncompressing test files on target with command: %s' % uncompress_cmd)
- call_ssh(uncompress_cmd)
- delete_tarball_cmd = "%s rm %s/%s" % (self.args.target, self.test['target_test_path'], tarball_name)
- self.logger.info("Deleting remote tarball: %s" % delete_tarball_cmd)
- call_ssh(delete_tarball_cmd)
+
+ self.logger.info("Archiving test files")
+ run_command(
+ 'tar -caf %s run.sh uuid automated/lib automated/bin automated/utils %s' %
+ (tarball_name, self.test['tc_relative_dir']))
+
+ self.logger.info("Creating test path")
+ run_command("mkdir -p %s" % (self.test['target_test_path']), self.args.target)
+
+ self.logger.info("Copying test archive to target host")
+ run_command('scp %s ./%s %s:%s' % (SSH_PARAMS, tarball_name, self.args.target,
+ self.test['target_test_path']))
+
+ self.logger.info("Unarchiving test files on target")
+ run_command("cd %s && tar -xf %s" % (self.test['target_test_path'],
+ tarball_name), self.args.target)
+
+ self.logger.info("Removing test file archive from target")
+ run_command("rm %s/%s" % (self.test['target_test_path'],
+ tarball_name), self.args.target)
def run(self):
self.copy_to_target()
@@ -432,6 +445,98 @@ class ManualTestRun(TestRun, cmd.Cmd):
pass
+def get_packages(linux_distribution, target=None):
+ """ Return a list of installed packages with versions
+
+ linux_distribution is a string that may be 'debian',
+ 'ubuntu', 'centos', or 'fedora'.
+
+ For example (ubuntu):
+ 'packages': ['acl-2.2.52-2',
+ 'adduser-3.113+nmu3',
+ ...
+ 'zlib1g:amd64-1:1.2.8.dfsg-2+b1',
+ 'zlib1g-dev:amd64-1:1.2.8.dfsg-2+b1']
+
+ (centos):
+ "packages": ["acl-2.2.51-12.el7",
+ "apr-1.4.8-3.el7",
+ ...
+ "zlib-1.2.7-17.el7",
+ "zlib-devel-1.2.7-17.el7"
+ ]
+ """
+
+ logger = logging.getLogger('RUNNER.get_packages')
+ packages = []
+ if linux_distribution in ['debian', 'ubuntu']:
+ # Debian (apt) based system
+ packages = run_command("dpkg-query -W -f '${package}-${version}\n'", target).splitlines()
+
+ elif linux_distribution in ['centos', 'fedora']:
+ # RedHat (rpm) based system
+ packages = run_command("rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}\n'", target).splitlines()
+ else:
+ logger.warning("Unknown linux distribution '{}'; package list not populated.".format(linux_distribution))
+
+ packages.sort()
+ return packages
+
+
+def get_environment(target=None, skip_collection=False):
+ """ Return a dictionary with environmental information
+
+ target: optional ssh host string to gather environment remotely.
+ skip_collection: Skip data collection and return an empty dictionary.
+
+ For example (on a HiSilicon D03):
+ {
+ "bios_version": "Hisilicon D03 UEFI 16.12 Release",
+ "board_name": "D03",
+ "board_vendor": "Huawei",
+ "kernel": "4.9.0-20.gitedc2a1c.linaro.aarch64",
+ "linux_distribution": "centos",
+ "packages": [
+ "GeoIP-1.5.0-11.el7",
+ "NetworkManager-1.4.0-20.el7_3",
+ ...
+ "yum-plugin-fastestmirror-1.1.31-40.el7",
+ "zlib-1.2.7-17.el7"
+ ],
+ "uname": "Linux localhost.localdomain 4.9.0-20.gitedc2a1c.linaro.aarch64 #1 SMP Wed Dec 14 17:50:15 UTC 2016 aarch64 aarch64 aarch64 GNU/Linux"
+ }
+ """
+
+ environment = {}
+ if skip_collection:
+ return environment
+ environment['linux_distribution'] = run_command(
+ "grep ^ID= /etc/os-release", target).split('=')[-1].strip('"').lower()
+ environment['kernel'] = run_command("uname -r", target)
+ environment['uname'] = run_command("uname -a", target)
+
+ try:
+ environment['bios_version'] = run_command(
+ "cat /sys/devices/virtual/dmi/id/bios_version", target)
+ except subprocess.CalledProcessError:
+ environment['bios_version'] = ""
+
+ try:
+ environment['board_vendor'] = run_command(
+ "cat /sys/devices/virtual/dmi/id/board_vendor", target)
+ except subprocess.CalledProcessError:
+ environment['board_vendor'] = ""
+
+ try:
+ environment['board_name'] = run_command(
+ "cat /sys/devices/virtual/dmi/id/board_name", target)
+ except subprocess.CalledProcessError:
+ environment['board_name'] = ""
+
+ environment['packages'] = get_packages(environment['linux_distribution'], target)
+ return environment
+
+
class ResultParser(object):
def __init__(self, test, args):
self.test = test
@@ -440,6 +545,9 @@ class ResultParser(object):
self.results = {}
self.results['test'] = test['test_name']
self.results['id'] = test['test_uuid']
+ self.results['test_plan'] = args.test_plan
+ self.results['environment'] = get_environment(
+ target=self.args.target, skip_collection=self.args.skip_environment)
self.logger = logging.getLogger('RUNNER.ResultParser')
self.results['params'] = {}
self.pattern = None
@@ -615,6 +723,9 @@ def get_args():
parser.add_argument('-s', '--skip_install', dest='skip_install',
default=False, action='store_true',
help='skip install section defined in test definition.')
+ parser.add_argument('-e', '--skip_environment', dest='skip_environment',
+ default=False, action='store_true',
+ help='skip environmental data collection (board name, distro, etc)')
args = parser.parse_args()
return args
@@ -646,7 +757,7 @@ def main():
logger.error('openssh client must be installed on the host.')
sys.exit(1)
try:
- call_ssh("%s exit" % args.target)
+ run_command("exit", args.target)
except subprocess.CalledProcessError as e:
logger.error('ssh login failed.')
print(e)
@@ -674,8 +785,7 @@ def main():
tc_realpath = os.path.realpath(test['path'])
tc_dirname = os.path.dirname(tc_realpath)
test['tc_relative_dir'] = '%s%s' % (args.kind, tc_dirname.split(args.kind)[1])
- target_user_home_cmd = '%s "echo $HOME"' % args.target
- target_user_home = call_ssh(target_user_home_cmd)
+ target_user_home = run_command("echo $HOME", args.target)
test['target_test_path'] = '%s/output/%s' % (target_user_home, test['test_uuid'])
logger.debug('Test parameters: %s' % test)
@@ -702,5 +812,6 @@ def main():
else:
logger.warning("Requested test definition %s doesn't exist" % test['path'])
+
if __name__ == "__main__":
main()