|
Packit Service |
a04d08 |
# This file is part of cloud-init. See LICENSE file for license information.
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
"""Used to collect data from platforms during tests."""
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
from functools import partial
|
|
Packit Service |
a04d08 |
import os
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
from cloudinit import util as c_util
|
|
Packit Service |
a04d08 |
from tests.cloud_tests import (config, LOG, setup_image, util)
|
|
Packit Service |
a04d08 |
from tests.cloud_tests.stage import (PlatformComponent, run_stage, run_single)
|
|
Packit Service |
a04d08 |
from tests.cloud_tests import platforms
|
|
Packit Service |
a04d08 |
from tests.cloud_tests.testcases import base, get_test_class
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def collect_script(instance, base_dir, script, script_name):
|
|
Packit Service |
a04d08 |
"""Collect script data.
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
@param instance: instance to run script on
|
|
Packit Service |
a04d08 |
@param base_dir: base directory for output data
|
|
Packit Service |
a04d08 |
@param script: script contents
|
|
Packit Service |
a04d08 |
@param script_name: name of script to run
|
|
Packit Service |
a04d08 |
@return_value: None, may raise errors
|
|
Packit Service |
a04d08 |
"""
|
|
Packit Service |
a04d08 |
LOG.debug('running collect script: %s', script_name)
|
|
Packit Service |
a04d08 |
(out, err, exit) = instance.run_script(
|
|
Packit Service |
a04d08 |
script.encode(), rcs=False,
|
|
Packit Service |
a04d08 |
description='collect: {}'.format(script_name))
|
|
Packit Service |
a04d08 |
if err:
|
|
Packit Service |
a04d08 |
LOG.debug("collect script %s exited '%s' and had stderr: %s",
|
|
Packit Service |
a04d08 |
script_name, err, exit)
|
|
Packit Service |
a04d08 |
if not isinstance(out, bytes):
|
|
Packit Service |
a04d08 |
raise util.PlatformError(
|
|
Packit Service |
a04d08 |
"Collection of '%s' returned type %s, expected bytes: %s" %
|
|
Packit Service |
a04d08 |
(script_name, type(out), out))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
c_util.write_file(os.path.join(base_dir, script_name), out)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def collect_console(instance, base_dir):
|
|
Packit Service |
a04d08 |
"""Collect instance console log.
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
@param instance: instance to get console log for
|
|
Packit Service |
a04d08 |
@param base_dir: directory to write console log to
|
|
Packit Service |
a04d08 |
"""
|
|
Packit Service |
a04d08 |
logfile = os.path.join(base_dir, 'console.log')
|
|
Packit Service |
a04d08 |
LOG.debug('getting console log for %s to %s', instance.name, logfile)
|
|
Packit Service |
a04d08 |
try:
|
|
Packit Service |
a04d08 |
data = instance.console_log()
|
|
Packit Service |
a04d08 |
except NotImplementedError as e:
|
|
Packit Service |
a04d08 |
# args[0] is hacky, but thats all I see to get at the message.
|
|
Packit Service |
a04d08 |
data = b'NotImplementedError:' + e.args[0].encode()
|
|
Packit Service |
a04d08 |
with open(logfile, "wb") as fp:
|
|
Packit Service |
a04d08 |
fp.write(data)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def collect_test_data(args, snapshot, os_name, test_name):
|
|
Packit Service |
a04d08 |
"""Collect data for test case.
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
@param args: cmdline arguments
|
|
Packit Service |
a04d08 |
@param snapshot: instantiated snapshot
|
|
Packit Service |
a04d08 |
@param test_name: name or path of test to run
|
|
Packit Service |
a04d08 |
@return_value: tuple of results and fail count
|
|
Packit Service |
a04d08 |
"""
|
|
Packit Service |
a04d08 |
res = ({}, 1)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
# load test config
|
|
Packit Service |
a04d08 |
test_name_in = test_name
|
|
Packit Service |
a04d08 |
test_name = config.path_to_name(test_name)
|
|
Packit Service |
a04d08 |
test_config = config.load_test_config(test_name)
|
|
Packit Service |
a04d08 |
user_data = test_config['cloud_config']
|
|
Packit Service |
a04d08 |
test_scripts = test_config['collect_scripts']
|
|
Packit Service |
a04d08 |
test_output_dir = os.sep.join(
|
|
Packit Service |
a04d08 |
(args.data_dir, snapshot.platform_name, os_name, test_name))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
# if test is not enabled, skip and return 0 failures
|
|
Packit Service |
a04d08 |
if not test_config.get('enabled', False):
|
|
Packit Service |
a04d08 |
LOG.warning('test config %s is not enabled, skipping', test_name)
|
|
Packit Service |
a04d08 |
return ({}, 0)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
test_class = get_test_class(
|
|
Packit Service |
a04d08 |
config.name_to_module(test_name_in),
|
|
Packit Service |
a04d08 |
test_data={'platform': snapshot.platform_name, 'os_name': os_name},
|
|
Packit Service |
a04d08 |
test_conf=test_config['cloud_config'])
|
|
Packit Service |
a04d08 |
try:
|
|
Packit Service |
a04d08 |
test_class.maybeSkipTest()
|
|
Packit Service |
a04d08 |
except base.SkipTest as s:
|
|
Packit Service |
a04d08 |
LOG.warning('skipping test config %s: %s', test_name, s)
|
|
Packit Service |
a04d08 |
return ({}, 0)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
# if testcase requires a feature flag that the image does not support,
|
|
Packit Service |
a04d08 |
# skip the testcase with a warning
|
|
Packit Service |
a04d08 |
req_features = test_config.get('required_features', [])
|
|
Packit Service |
a04d08 |
if any(feature not in snapshot.features for feature in req_features):
|
|
Packit Service |
a04d08 |
LOG.warning('test config %s requires features not supported by image, '
|
|
Packit Service |
a04d08 |
'skipping.\nrequired features: %s\nsupported features: %s',
|
|
Packit Service |
a04d08 |
test_name, req_features, snapshot.features)
|
|
Packit Service |
a04d08 |
return ({}, 0)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
# if there are user data overrides required for this test case, apply them
|
|
Packit Service |
a04d08 |
overrides = snapshot.config.get('user_data_overrides', {})
|
|
Packit Service |
a04d08 |
if overrides:
|
|
Packit Service |
a04d08 |
LOG.debug('updating user data for collect with: %s', overrides)
|
|
Packit Service |
a04d08 |
user_data = util.update_user_data(user_data, overrides)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
# create test instance
|
|
Packit Service |
a04d08 |
component = PlatformComponent(
|
|
Packit Service |
a04d08 |
partial(platforms.get_instance, snapshot, user_data,
|
|
Packit Service |
a04d08 |
block=True, start=False, use_desc=test_name),
|
|
Packit Service |
a04d08 |
preserve_instance=args.preserve_instance)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
LOG.info('collecting test data for test: %s', test_name)
|
|
Packit Service |
a04d08 |
with component as instance:
|
|
Packit Service |
a04d08 |
start_call = partial(run_single, 'boot instance', partial(
|
|
Packit Service |
a04d08 |
instance.start, wait=True, wait_for_cloud_init=True))
|
|
Packit Service |
a04d08 |
collect_calls = [partial(run_single, 'script {}'.format(script_name),
|
|
Packit Service |
a04d08 |
partial(collect_script, instance,
|
|
Packit Service |
a04d08 |
test_output_dir, script, script_name))
|
|
Packit Service |
a04d08 |
for script_name, script in test_scripts.items()]
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
res = run_stage('collect for test: {}'.format(test_name),
|
|
Packit Service |
a04d08 |
[start_call] + collect_calls)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
instance.shutdown()
|
|
Packit Service |
a04d08 |
collect_console(instance, test_output_dir)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
return res
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def collect_snapshot(args, image, os_name):
|
|
Packit Service |
a04d08 |
"""Collect data for snapshot of image.
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
@param args: cmdline arguments
|
|
Packit Service |
a04d08 |
@param image: instantiated image with set up complete
|
|
Packit Service |
a04d08 |
@return_value tuple of results and fail count
|
|
Packit Service |
a04d08 |
"""
|
|
Packit Service |
a04d08 |
res = ({}, 1)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
component = PlatformComponent(partial(platforms.get_snapshot, image))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
LOG.debug('creating snapshot for %s', os_name)
|
|
Packit Service |
a04d08 |
with component as snapshot:
|
|
Packit Service |
a04d08 |
LOG.info('collecting test data for os: %s', os_name)
|
|
Packit Service |
a04d08 |
res = run_stage(
|
|
Packit Service |
a04d08 |
'collect test data for {}'.format(os_name),
|
|
Packit Service |
a04d08 |
[partial(collect_test_data, args, snapshot, os_name, test_name)
|
|
Packit Service |
a04d08 |
for test_name in args.test_config])
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
return res
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def collect_image(args, platform, os_name):
|
|
Packit Service |
a04d08 |
"""Collect data for image.
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
@param args: cmdline arguments
|
|
Packit Service |
a04d08 |
@param platform: instantiated platform
|
|
Packit Service |
a04d08 |
@param os_name: name of distro to collect for
|
|
Packit Service |
a04d08 |
@return_value: tuple of results and fail count
|
|
Packit Service |
a04d08 |
"""
|
|
Packit Service |
a04d08 |
res = ({}, 1)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
os_config = config.load_os_config(
|
|
Packit Service |
a04d08 |
platform.platform_name, os_name, require_enabled=True,
|
|
Packit Service |
a04d08 |
feature_overrides=args.feature_override)
|
|
Packit Service |
a04d08 |
LOG.debug('os config: %s', os_config)
|
|
Packit Service |
a04d08 |
component = PlatformComponent(
|
|
Packit Service |
a04d08 |
partial(platforms.get_image, platform, os_config))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
LOG.info('acquiring image for os: %s', os_name)
|
|
Packit Service |
a04d08 |
with component as image:
|
|
Packit Service |
a04d08 |
res = run_stage('set up and collect data for os: {}'.format(os_name),
|
|
Packit Service |
a04d08 |
[partial(setup_image.setup_image, args, image)] +
|
|
Packit Service |
a04d08 |
[partial(collect_snapshot, args, image, os_name)],
|
|
Packit Service |
a04d08 |
continue_after_error=False)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
return res
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def collect_platform(args, platform_name):
|
|
Packit Service |
a04d08 |
"""Collect data for platform.
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
@param args: cmdline arguments
|
|
Packit Service |
a04d08 |
@param platform_name: platform to collect for
|
|
Packit Service |
a04d08 |
@return_value: tuple of results and fail count
|
|
Packit Service |
a04d08 |
"""
|
|
Packit Service |
a04d08 |
res = ({}, 1)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
platform_config = config.load_platform_config(
|
|
Packit Service |
a04d08 |
platform_name, require_enabled=True)
|
|
Packit Service |
a04d08 |
platform_config['data_dir'] = args.data_dir
|
|
Packit Service |
a04d08 |
LOG.debug('platform config: %s', platform_config)
|
|
Packit Service |
a04d08 |
component = PlatformComponent(
|
|
Packit Service |
a04d08 |
partial(platforms.get_platform, platform_name, platform_config))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
LOG.info('setting up platform: %s', platform_name)
|
|
Packit Service |
a04d08 |
with component as platform:
|
|
Packit Service |
a04d08 |
res = run_stage('collect for platform: {}'.format(platform_name),
|
|
Packit Service |
a04d08 |
[partial(collect_image, args, platform, os_name)
|
|
Packit Service |
a04d08 |
for os_name in args.os_name])
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
return res
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def collect(args):
|
|
Packit Service |
a04d08 |
"""Entry point for collection.
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
@param args: cmdline arguments
|
|
Packit Service |
a04d08 |
@return_value: fail count
|
|
Packit Service |
a04d08 |
"""
|
|
Packit Service |
a04d08 |
(res, failed) = run_stage(
|
|
Packit Service |
a04d08 |
'collect data', [partial(collect_platform, args, platform_name)
|
|
Packit Service |
a04d08 |
for platform_name in args.platform])
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
LOG.debug('collect stages: %s', res)
|
|
Packit Service |
a04d08 |
if args.result:
|
|
Packit Service |
a04d08 |
util.merge_results({'collect_stages': res}, args.result)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
return failed
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
# vi: ts=4 expandtab
|