""" Handler for yardstick command 'task' """
+from __future__ import absolute_import
+from __future__ import print_function
import sys
import os
import yaml
import logging
import uuid
import errno
-from itertools import ifilter
+from six.moves import filter
from yardstick.benchmark.contexts.base import Context
from yardstick.benchmark.runners import base as base_runner
class Task(object): # pragma: no cover
- '''Task commands.
+ """Task commands.
Set of commands to manage benchmark tasks.
- '''
+ """
def start(self, args, **kwargs):
- '''Start a benchmark scenario.'''
+ """Start a benchmark scenario."""
atexit.register(atexit_handler)
one_task_start_time = time.time()
parser.path = task_files[i]
scenarios, run_in_parallel, meet_precondition = parser.parse_task(
- self.task_id, task_args[i], task_args_fnames[i])
+ self.task_id, task_args[i], task_args_fnames[i])
if not meet_precondition:
LOG.info("meet_precondition is %s, please check envrionment",
LOG.info("total finished in %d secs",
total_end_time - total_start_time)
- print "Done, exiting"
+ print("Done, exiting")
def _run(self, scenarios, run_in_parallel, output_file):
- '''Deploys context and calls runners'''
+ """Deploys context and calls runners"""
for context in Context.list:
context.deploy()
background_runners = []
# Start all background scenarios
- for scenario in ifilter(_is_background_scenario, scenarios):
+ for scenario in filter(_is_background_scenario, scenarios):
scenario["runner"] = dict(type="Duration", duration=1000000000)
runner = run_one_scenario(scenario, output_file)
background_runners.append(runner)
# Wait for runners to finish
for runner in runners:
runner_join(runner)
- print "Runner ended, output in", output_file
+ print("Runner ended, output in", output_file)
else:
# run serially
for scenario in scenarios:
if not _is_background_scenario(scenario):
runner = run_one_scenario(scenario, output_file)
runner_join(runner)
- print "Runner ended, output in", output_file
+ print("Runner ended, output in", output_file)
# Abort background runners
for runner in background_runners:
runner_join(runner)
else:
base_runner.Runner.release(runner)
- print "Background task ended"
+ print("Background task ended")
# TODO: Move stuff below into TaskCommands class !?
class TaskParser(object): # pragma: no cover
- '''Parser for task config files in yaml format'''
+ """Parser for task config files in yaml format"""
+
def __init__(self, path):
self.path = path
return task_args, task_args_fnames
def parse_suite(self):
- '''parse the suite file and return a list of task config file paths
- and lists of optional parameters if present'''
+ """parse the suite file and return a list of task config file paths
+ and lists of optional parameters if present"""
LOG.info("\nParsing suite file:%s", self.path)
try:
return valid_task_files, valid_task_args, valid_task_args_fnames
def parse_task(self, task_id, task_args=None, task_args_file=None):
- '''parses the task file and return an context and scenario instances'''
- print "Parsing task config:", self.path
+ """parses the task file and return an context and scenario instances"""
+ print("Parsing task config:", self.path)
try:
kw = {}
input_task = f.read()
rendered_task = TaskTemplate.render(input_task, **kw)
except Exception as e:
- print(("Failed to render template:\n%(task)s\n%(err)s\n")
+ print("Failed to render template:\n%(task)s\n%(err)s\n"
% {"task": input_task, "err": e})
raise e
- print(("Input task is:\n%s\n") % rendered_task)
+ print("Input task is:\n%s\n" % rendered_task)
cfg = yaml.load(rendered_task)
except IOError as ioerror:
else:
context_cfgs = [{"type": "Dummy"}]
+ name_suffix = '-{}'.format(task_id[:8])
for cfg_attrs in context_cfgs:
+ cfg_attrs['name'] = '{}{}'.format(cfg_attrs['name'], name_suffix)
context_type = cfg_attrs.get("type", "Heat")
if "Heat" == context_type and "networks" in cfg_attrs:
# bugfix: if there are more than one network,
# the name of netwrok should follow this rule:
# test, test2, test3 ...
# sort network with the length of network's name
- sorted_networks = sorted(cfg_attrs["networks"].keys())
+ sorted_networks = sorted(cfg_attrs["networks"])
# config external_network based on env var
cfg_attrs["networks"][sorted_networks[0]]["external_network"] \
= os.environ.get("EXTERNAL_NETWORK", "net04_ext")
scenario["tc"] = task_name
scenario["task_id"] = task_id
+ change_server_name(scenario, name_suffix)
+
+ try:
+ for node in scenario['nodes']:
+ scenario['nodes'][node] += name_suffix
+ except KeyError:
+ pass
+
# TODO we need something better here, a class that represent the file
return cfg["scenarios"], run_in_parallel, meet_precondition
def _check_schema(self, cfg_schema, schema_type):
- '''Check if config file is using the correct schema type'''
+ """Check if config file is using the correct schema type"""
if cfg_schema != "yardstick:" + schema_type + ":0.1":
sys.exit("error: file %s has unknown schema %s" % (self.path,
cfg_schema))
def _check_precondition(self, cfg):
- '''Check if the envrionment meet the preconditon'''
+ """Check if the envrionment meet the preconditon"""
if "precondition" in cfg:
precondition = cfg["precondition"]
def atexit_handler():
- '''handler for process termination'''
+ """handler for process termination"""
base_runner.Runner.terminate_all()
if len(Context.list) > 0:
- print "Undeploying all contexts"
+ print("Undeploying all contexts")
for context in Context.list:
context.undeploy()
def is_ip_addr(addr):
- '''check if string addr is an IP address'''
+ """check if string addr is an IP address"""
try:
- ipaddress.ip_address(unicode(addr))
+ ipaddress.ip_address(addr.encode('utf-8'))
return True
except ValueError:
return False
def _is_same_heat_context(host_attr, target_attr):
- '''check if two servers are in the same heat context
+ """check if two servers are in the same heat context
host_attr: either a name for a server created by yardstick or a dict
with attribute name mapping when using external heat templates
target_attr: either a name for a server created by yardstick or a dict
with attribute name mapping when using external heat templates
- '''
+ """
host = None
target = None
for context in Context.list:
def run_one_scenario(scenario_cfg, output_file):
- '''run one scenario using context'''
+ """run one scenario using context"""
runner_cfg = scenario_cfg["runner"]
runner_cfg['output_filename'] = output_file
context_cfg["nodes"] = parse_nodes_with_context(scenario_cfg)
runner = base_runner.Runner.get(runner_cfg)
- print "Starting runner of type '%s'" % runner_cfg["type"]
+ print("Starting runner of type '%s'" % runner_cfg["type"])
runner.run(scenario_cfg, context_cfg)
return runner
def parse_nodes_with_context(scenario_cfg):
- '''paras the 'nodes' fields in scenario '''
+ """paras the 'nodes' fields in scenario """
nodes = scenario_cfg["nodes"]
nodes_cfg = {}
def runner_join(runner):
- '''join (wait for) a runner, exit process at runner failure'''
+ """join (wait for) a runner, exit process at runner failure"""
status = runner.join()
base_runner.Runner.release(runner)
if status != 0:
def print_invalid_header(source_name, args):
- print(("Invalid %(source)s passed:\n\n %(args)s\n")
+ print("Invalid %(source)s passed:\n\n %(args)s\n"
% {"source": source_name, "args": args})
kw = {} if kw is None else kw
except yaml.parser.ParserError as e:
print_invalid_header(src_name, args)
- print(("%(source)s has to be YAML. Details:\n\n%(err)s\n")
+ print("%(source)s has to be YAML. Details:\n\n%(err)s\n"
% {"source": src_name, "err": e})
raise TypeError()
if not isinstance(kw, dict):
print_invalid_header(src_name, args)
- print(("%(src)s had to be dict, actually %(src_type)s\n")
+ print("%(src)s had to be dict, actually %(src_type)s\n"
% {"src": src_name, "src_type": type(kw)})
raise TypeError()
return kw
if e.errno != errno.EEXIST:
raise
LOG.debug('OPENRC file not found')
+
+
+def change_server_name(scenario, suffix):
+ try:
+ scenario['host'] += suffix
+ except KeyError:
+ pass
+
+ try:
+ scenario['target'] += suffix
+ except KeyError:
+ pass
+
+ try:
+ key = 'targets'
+ scenario[key] = ['{}{}'.format(a, suffix) for a in scenario[key]]
+ except KeyError:
+ pass