@six.add_metaclass(abc.ABCMeta)
class Context(object):
- '''Class that represents a context in the logical model'''
+ """Class that represents a context in the logical model"""
list = []
def __init__(self):
@staticmethod
def get_cls(context_type):
- '''Return class of specified type.'''
+ """Return class of specified type."""
for context in utils.itersubclasses(Context):
if context_type == context.__context_type__:
return context
@abc.abstractmethod
def deploy(self):
- '''Deploy context.'''
+ """Deploy context."""
@abc.abstractmethod
def undeploy(self):
- '''Undeploy context.'''
+ """Undeploy context."""
@abc.abstractmethod
def _get_server(self, attr_name):
- '''get server info by name from context
- '''
+ """get server info by name from context
+ """
@staticmethod
def get_server(attr_name):
- '''lookup server info by name from context
+ """lookup server info by name from context
attr_name: either a name for a server created by yardstick or a dict
with attribute name mapping when using external heat templates
- '''
+ """
server = None
for context in Context.list:
server = context._get_server(attr_name)
class DummyContext(Context):
- '''Class that handle dummy info'''
+ """Class that handle dummy info"""
__context_type__ = "Dummy"
pass
def deploy(self):
- '''don't need to deploy'''
+ """don't need to deploy"""
pass
def undeploy(self):
- '''don't need to undeploy'''
+ """don't need to undeploy"""
pass
def _get_server(self, attr_name):
class HeatContext(Context):
- '''Class that represents a context in the logical model'''
+ """Class that represents a context in the logical model"""
__context_type__ = "Heat"
super(self.__class__, self).__init__()
def init(self, attrs):
- '''initializes itself from the supplied arguments'''
+ """initializes itself from the supplied arguments"""
self.name = attrs["name"]
if "user" in attrs:
@property
def image(self):
- '''returns application's default image name'''
+ """returns application's default image name"""
return self._image
@property
def flavor(self):
- '''returns application's default flavor name'''
+ """returns application's default flavor name"""
return self._flavor
@property
def user(self):
- '''return login user name corresponding to image'''
+ """return login user name corresponding to image"""
return self._user
def _add_resources_to_template(self, template):
- '''add to the template the resources represented by this context'''
+ """add to the template the resources represented by this context"""
template.add_keypair(self.keypair_name, self.key_uuid)
template.add_security_group(self.secgroup_name)
server.add_to_template(template, self.networks, {})
def deploy(self):
- '''deploys template into a stack using cloud'''
+ """deploys template into a stack using cloud"""
print("Deploying context '%s'" % self.name)
heat_template = HeatTemplate(self.name, self.template_file,
print("Context '%s' deployed" % self.name)
def undeploy(self):
- '''undeploys stack from cloud'''
+ """undeploys stack from cloud"""
if self.stack:
print("Undeploying context '%s'" % self.name)
self.stack.delete()
LOG.exception("Key filename %s", self.key_filename)
def _get_server(self, attr_name):
- '''lookup server info by name from context
+ """lookup server info by name from context
attr_name: either a name for a server created by yardstick or a dict
with attribute name mapping when using external heat templates
- '''
+ """
key_filename = pkg_resources.resource_filename(
'yardstick.resources',
'files/yardstick_key-' + get_short_key_uuid(self.key_uuid))
class Object(object):
- '''Base class for classes in the logical model
+ """Base class for classes in the logical model
Contains common attributes and methods
- '''
+ """
def __init__(self, name, context):
# model identities and reference
@property
def dn(self):
- '''returns distinguished name for object'''
+ """returns distinguished name for object"""
return self.name + "." + self._context.name
class PlacementGroup(Object):
- '''Class that represents a placement group in the logical model
+ """Class that represents a placement group in the logical model
Concept comes from the OVF specification. Policy should be one of
"availability" or "affinity (there are more but they are not supported)"
- '''
+ """
map = {}
def __init__(self, name, context, policy):
class Router(Object):
- '''Class that represents a router in the logical model'''
+ """Class that represents a router in the logical model"""
def __init__(self, name, network_name, context, external_gateway_info):
super(self.__class__, self).__init__(name, context)
class Network(Object):
- '''Class that represents a network in the logical model'''
+ """Class that represents a network in the logical model"""
list = []
def __init__(self, name, context, attrs):
Network.list.append(self)
def has_route_to(self, network_name):
- '''determines if this network has a route to the named network'''
+ """determines if this network has a route to the named network"""
if self.router and self.router.external_gateway_info == network_name:
return True
return False
@staticmethod
def find_by_route_to(external_network):
- '''finds a network that has a route to the specified network'''
+ """finds a network that has a route to the specified network"""
for network in Network.list:
if network.has_route_to(external_network):
return network
@staticmethod
def find_external_network():
- '''return the name of an external network some network in this
- context has a route to'''
+ """return the name of an external network some network in this
+ context has a route to"""
for network in Network.list:
if network.router:
return network.router.external_gateway_info
class Server(Object):
- '''Class that represents a server in the logical model'''
+ """Class that represents a server in the logical model"""
list = []
def __init__(self, name, context, attrs):
@property
def image(self):
- '''returns a server's image name'''
+ """returns a server's image name"""
if self._image:
return self._image
else:
@property
def flavor(self):
- '''returns a server's flavor name'''
+ """returns a server's flavor name"""
if self._flavor:
return self._flavor
else:
return self._context.flavor
def _add_instance(self, template, server_name, networks, scheduler_hints):
- '''adds to the template one server and corresponding resources'''
+ """adds to the template one server and corresponding resources"""
port_name_list = []
for network in networks:
port_name = server_name + "-" + network.name + "-port"
scheduler_hints=scheduler_hints)
def add_to_template(self, template, networks, scheduler_hints=None):
- '''adds to the template one or more servers (instances)'''
+ """adds to the template one or more servers (instances)"""
if self.instances == 1:
server_name = self.stack_name
self._add_instance(template, server_name, networks,
def update_scheduler_hints(scheduler_hints, added_servers, placement_group):
- ''' update scheduler hints from server's placement configuration
+ """ update scheduler hints from server's placement configuration
TODO: this code is openstack specific and should move somewhere else
- '''
+ """
if placement_group.policy == "affinity":
if "same_host" in scheduler_hints:
host_list = scheduler_hints["same_host"]
class NodeContext(Context):
- '''Class that handle nodes info'''
+ """Class that handle nodes info"""
__context_type__ = "Node"
super(self.__class__, self).__init__()
def init(self, attrs):
- '''initializes itself from the supplied arguments'''
+ """initializes itself from the supplied arguments"""
self.name = attrs["name"]
self.file_path = attrs.get("file", "pod.yaml")
if not os.path.exists(self.file_path):
LOG.debug("BareMetals: %r", self.baremetals)
def deploy(self):
- '''don't need to deploy'''
+ """don't need to deploy"""
pass
def undeploy(self):
- '''don't need to undeploy'''
+ """don't need to undeploy"""
pass
def _get_server(self, attr_name):
- '''lookup server info by name from context
+ """lookup server info by name from context
attr_name: a name for a server listed in nodes config file
- '''
+ """
if type(attr_name) is dict:
return None
def print_hbar(barlen):
- '''print to stdout a horizontal bar'''
+ """print to stdout a horizontal bar"""
print("+"),
print("-" * barlen),
print("+")
class Runners(object):
- '''Runner commands.
+ """Runner commands.
Set of commands to discover and display runner types.
- '''
+ """
def list_all(self, args):
- '''List existing runner types'''
+ """List existing runner types"""
types = Runner.get_types()
print_hbar(78)
print("| %-16s | %-60s" % ("Type", "Description"))
print_hbar(78)
def show(self, args):
- '''Show details of a specific runner type'''
+ """Show details of a specific runner type"""
rtype = Runner.get_cls(args.type[0])
print(rtype.__doc__)
class Scenarios(object):
- '''Scenario commands.
+ """Scenario commands.
Set of commands to discover and display scenario types.
- '''
+ """
def list_all(self, args):
- '''List existing scenario types'''
+ """List existing scenario types"""
types = Scenario.get_types()
print_hbar(78)
print("| %-16s | %-60s" % ("Type", "Description"))
print_hbar(78)
def show(self, args):
- '''Show details of a specific scenario type'''
+ """Show details of a specific scenario type"""
stype = Scenario.get_cls(args.type[0])
print(stype.__doc__)
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)
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()
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'''
+ """parses the task file and return an context and scenario instances"""
print("Parsing task config:", self.path)
try:
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:
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(addr.encode('utf-8'))
return True
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
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:
class Testcase(object):
- '''Testcase commands.
+ """Testcase commands.
Set of commands to discover and display test cases.
- '''
+ """
def __init__(self):
self.test_case_path = YARDSTICK_ROOT_PATH + 'tests/opnfv/test_cases/'
self.testcase_list = []
def list_all(self, args):
- '''List existing test cases'''
+ """List existing test cases"""
try:
testcase_files = os.listdir(self.test_case_path)
return True
def show(self, args):
- '''Show details of a specific test case'''
+ """Show details of a specific test case"""
testcase_name = args.casename[0]
testcase_path = self.test_case_path + testcase_name + ".yaml"
try:
return description, installer_type, deploy_scenarios
def _format_print(self, testcase_list):
- '''format output'''
+ """format output"""
print_hbar(88)
print("| %-21s | %-60s" % ("Testcase Name", "Description"))
# yardstick comment: this is a modified copy of
# rally/rally/benchmark/runners/constant.py
-'''A runner that every run arithmetically steps specified input value(s) to
+"""A runner that every run arithmetically steps specified input value(s) to
the scenario. This just means step value(s) is added to the previous value(s).
It is possible to combine several named input values and run with those either
as nested for loops or combine each i:th index of each "input value list"
until the end of the shortest list is reached (optimally all lists should be
defined with the same number of values when using such iter_type).
-'''
+"""
from __future__ import absolute_import
class ArithmeticRunner(base.Runner):
- '''Run a scenario arithmetically stepping input value(s)
+ """Run a scenario arithmetically stepping input value(s)
Parameters
interval - time to wait between each scenario invocation
default: none
-
name - and so on......
- '''
+ """
__execution_type__ = 'Arithmetic'
def _output_serializer_main(filename, queue):
- '''entrypoint for the singleton subprocess writing to outfile
+ """entrypoint for the singleton subprocess writing to outfile
Use of this process enables multiple instances of a scenario without
messing up the output file.
- '''
+ """
config = {}
config["type"] = CONF.dispatcher.capitalize()
config["file_path"] = filename
def _execute_shell_command(command):
- '''execute shell script with error handling'''
+ """execute shell script with error handling"""
exitcode = 0
output = []
try:
def _single_action(seconds, command, queue):
- '''entrypoint for the single action process'''
+ """entrypoint for the single action process"""
log.debug("single action, fires after %d seconds (from now)", seconds)
time.sleep(seconds)
log.debug("single action: executing command: '%s'", command)
def _periodic_action(interval, command, queue):
- '''entrypoint for the periodic action process'''
+ """entrypoint for the periodic action process"""
log.debug("periodic action, fires every: %d seconds", interval)
time_spent = 0
while True:
@staticmethod
def get_cls(runner_type):
- '''return class of specified type'''
+ """return class of specified type"""
for runner in utils.itersubclasses(Runner):
if runner_type == runner.__execution_type__:
return runner
@staticmethod
def get_types():
- '''return a list of known runner type (class) names'''
+ """return a list of known runner type (class) names"""
types = []
for runner in utils.itersubclasses(Runner):
types.append(runner)
@staticmethod
def release_dump_process():
- '''Release the dumper process'''
+ """Release the dumper process"""
log.debug("Stopping dump process")
if Runner.dump_process:
Runner.queue.put('_TERMINATE_')
@staticmethod
def release(runner):
- '''Release the runner'''
+ """Release the runner"""
if runner in Runner.runners:
Runner.runners.remove(runner)
@staticmethod
def terminate(runner):
- '''Terminate the runner'''
+ """Terminate the runner"""
if runner.process and runner.process.is_alive():
runner.process.terminate()
@staticmethod
def terminate_all():
- '''Terminate all runners (subprocesses)'''
+ """Terminate all runners (subprocesses)"""
log.debug("Terminating all runners")
# release dumper process as some errors before any runner is created
Runner.runners.append(self)
def run_post_stop_action(self):
- '''run a potentially configured post-stop action'''
+ """run a potentially configured post-stop action"""
if "post-stop-action" in self.config:
command = self.config["post-stop-action"]["command"]
log.debug("post stop action: command: '%s'", command)
self._run_benchmark(cls, "run", scenario_cfg, context_cfg)
def abort(self):
- '''Abort the execution of a scenario'''
+ """Abort the execution of a scenario"""
self.aborted.set()
def join(self, timeout=None):
# yardstick comment: this is a modified copy of
# rally/rally/benchmark/runners/constant.py
-'''A runner that runs a specific time before it returns
-'''
+"""A runner that runs a specific time before it returns
+"""
from __future__ import absolute_import
import os
class DurationRunner(base.Runner):
- '''Run a scenario for a certain amount of time
+ """Run a scenario for a certain amount of time
If the scenario ends before the time has elapsed, it will be started again.
type: int
unit: seconds
default: 1 sec
- '''
+ """
__execution_type__ = 'Duration'
def _run_benchmark(self, cls, method, scenario_cfg, context_cfg):
# yardstick comment: this is a modified copy of
# rally/rally/benchmark/runners/constant.py
-'''A runner that runs a configurable number of times before it returns
-'''
+"""A runner that runs a configurable number of times before it returns
+"""
from __future__ import absolute_import
import os
class IterationRunner(base.Runner):
- '''Run a scenario for a configurable number of times
+ """Run a scenario for a configurable number of times
If the scenario ends before the time has elapsed, it will be started again.
type: int
unit: seconds
default: 1 sec
- '''
+ """
__execution_type__ = 'Iteration'
def _run_benchmark(self, cls, method, scenario_cfg, context_cfg):
# yardstick comment: this is a modified copy of
# rally/rally/benchmark/runners/constant.py
-'''A runner that every run changes a specified input value to the scenario.
+"""A runner that every run changes a specified input value to the scenario.
The input value in the sequence is specified in a list in the input file.
-'''
+"""
from __future__ import absolute_import
import os
class SequenceRunner(base.Runner):
- '''Run a scenario by changing an input value defined in a list
+ """Run a scenario by changing an input value defined in a list
Parameters
interval - time to wait between each scenario invocation
type: [int]
unit: na
default: none
- '''
+ """
__execution_type__ = 'Sequence'
def _execute_shell_command(command, stdin=None):
- '''execute shell script with error handling'''
+ """execute shell script with error handling"""
exitcode = 0
output = []
try:
@staticmethod
def get_attacker_cls(attacker_cfg):
- '''return attacker instance of specified type'''
+ """return attacker instance of specified type"""
attacker_type = attacker_cfg['fault_type']
for attacker_cls in utils.itersubclasses(BaseAttacker):
if attacker_type == attacker_cls.__attacker_type__:
@staticmethod
def get_monitor_cls(monitor_type):
- '''return monitor class of specified type'''
+ """return monitor class of specified type"""
for monitor in utils.itersubclasses(BaseMonitor):
if monitor_type == monitor.__monitor_type__:
def _execute_shell_command(command):
- '''execute shell script with error handling'''
+ """execute shell script with error handling"""
exitcode = 0
output = []
try:
@staticmethod
def get_operation_cls(type):
- '''return operation instance of specified type'''
+ """return operation instance of specified type"""
operation_type = type
for operation_cls in utils.itersubclasses(BaseOperation):
if operation_type == operation_cls.__operation__type__:
@staticmethod
def get_resultchecker_cls(type):
- '''return resultchecker instance of specified type'''
+ """return resultchecker instance of specified type"""
resultchecker_type = type
for checker_cls in utils.itersubclasses(BaseResultChecker):
if resultchecker_type == checker_cls.__result_checker__type__:
self.setup_done = False
def setup(self):
- '''scenario setup'''
+ """scenario setup"""
nodes = self.context_cfg.get("nodes", None)
if nodes is None:
LOG.error("the nodes info is none")
return
def teardown(self):
- '''scenario teardown'''
+ """scenario teardown"""
for attacker in self.attackers:
attacker.recover()
def _test(): # pragma: no cover
- '''internal test function'''
+ """internal test function"""
host = {
"ip": "10.20.0.5",
"user": "root",
class Scenario(object):
def setup(self):
- ''' default impl for scenario setup '''
+ """ default impl for scenario setup """
pass
def run(self, args):
- ''' catcher for not implemented run methods in subclasses '''
+ """ catcher for not implemented run methods in subclasses """
raise RuntimeError("run method not implemented")
def teardown(self):
- ''' default impl for scenario teardown '''
+ """ default impl for scenario teardown """
pass
@staticmethod
def get_types():
- '''return a list of known runner type (class) names'''
+ """return a list of known runner type (class) names"""
scenarios = []
for scenario in utils.itersubclasses(Scenario):
scenarios.append(scenario)
@staticmethod
def get_cls(scenario_type):
- '''return class of specified type'''
+ """return class of specified type"""
for scenario in utils.itersubclasses(Scenario):
if scenario_type == scenario.__scenario_type__:
return scenario
class CACHEstat(base.Scenario):
- '''Collect cache statistics.
+ """Collect cache statistics.
This scenario reads system cache hit/miss ratio and other statistics on
a Linux host.
some error margin depending on unusual workload types.
REQUIREMENTS: CONFIG_FUNCTION_PROFILER, awk.
- '''
+ """
__scenario_type__ = "CACHEstat"
TARGET_SCRIPT = "cache_stat.bash"
self._connect_guest()
def setup(self):
- '''scenario setup'''
+ """scenario setup"""
setup_options = self.scenario_cfg["setup_options"]
host_setup_seqs = setup_options["host_setup_seqs"]
guest_setup_seqs = setup_options["guest_setup_seqs"]
def _test(): # pragma: no cover
- '''internal test function'''
+ """internal test function"""
key_filename = pkg_resources.resource_filename("yardstick.resources",
"files/yardstick_key")
ctx = {
self.setup_done = False
def setup(self):
- '''scenario setup'''
+ """scenario setup"""
self.setup_done = True
def run(self, result):
def _test():
- '''internal test function'''
+ """internal test function"""
key_filename = pkg_resources.resource_filename('yardstick.resources',
'files/yardstick_key')
ctx = {
self.setup_done = False
def setup(self):
- '''scenario setup'''
+ """scenario setup"""
self.target_script = pkg_resources.resource_filename(
'yardstick.benchmark.scenarios.networking',
Netperf.TARGET_SCRIPT)
def _test():
- '''internal test function'''
+ """internal test function"""
key_filename = pkg_resources.resource_filename("yardstick.resources",
"files/yardstick_key")
ctx = {
self.setup_done = False
def setup(self):
- '''scenario setup'''
+ """scenario setup"""
self.target_script = pkg_resources.resource_filename(
'yardstick.benchmark.scenarios.networking',
NetperfNode.TARGET_SCRIPT)
(mean_latency, sla_max_mean_latency)
def teardown(self):
- '''remove netperf from nodes after test'''
+ """remove netperf from nodes after test"""
self.server.execute("sudo bash netperf_remove.sh")
self.client.execute("sudo bash netperf_remove.sh")
def _test(): # pragma: no cover
- '''internal test function'''
+ """internal test function"""
ctx = {
"host": {
"ip": "192.168.10.10",
def _test(): # pragma: no cover
- '''internal test function'''
+ """internal test function"""
key_filename = pkg_resources.resource_filename("yardstick.resources",
"files/yardstick_key")
ctx = {
return None
def setup(self):
- '''scenario setup'''
+ """scenario setup"""
self.setup_script = pkg_resources.resource_filename(
'yardstick.benchmark.scenarios.networking',
Ping6.SETUP_SCRIPT)
self.setup_done = False
def setup(self):
- '''scenario setup'''
+ """scenario setup"""
self.target_script = pkg_resources.resource_filename(
'yardstick.benchmark.scenarios.networking',
Pktgen.TARGET_SCRIPT)
def _test():
- '''internal test function'''
+ """internal test function"""
key_filename = pkg_resources.resource_filename('yardstick.resources',
'files/yardstick_key')
ctx = {
self.setup_done = False
def setup(self):
- '''scenario setup'''
+ """scenario setup"""
self.pktgen_dpdk_script = pkg_resources.resource_filename(
'yardstick.benchmark.scenarios.networking',
PktgenDPDKLatency.PKTGEN_DPDK_SCRIPT)
class Sfc(base.Scenario): # pragma: no cover
- ''' SFC scenario class '''
+ """ SFC scenario class """
__scenario_type__ = "sfc"
self.teardown_done = False
def setup(self):
- '''scenario setup'''
+ """scenario setup"""
self.tacker_script = pkg_resources.resource_filename(
'yardstick.benchmark.scenarios.networking',
Sfc.TACKER_SCRIPT)
'yardstick.benchmark.scenarios.networking',
Sfc.SERVER_SCRIPT)
- ''' calling Tacker to instantiate VNFs and Service Chains '''
+ """ calling Tacker to instantiate VNFs and Service Chains """
cmd_tacker = "%s" % (self.tacker_script)
subprocess.call(cmd_tacker, shell=True)
target_pwd = target.get('password', 'opnfv')
target_ip = target.get('ip', None)
- ''' webserver start automatically during the vm boot '''
+ """ webserver start automatically during the vm boot """
LOG.info("user:%s, target:%s", target_user, target_ip)
self.server = ssh.SSH(target_user, target_ip, password=target_pwd,
port=target_ssh_port)
self.setup_done = True
def run(self, result):
- ''' Creating client and server VMs to perform the test'''
+ """ Creating client and server VMs to perform the test"""
host = self.context_cfg['host']
host_user = host.get('user', 'root')
ssh_port = host.get("ssh_port", ssh.DEFAULT_PORT)
'yardstick.benchmark.scenarios.networking',
Sfc.TACKER_CHANGECLASSI)
- ''' calling Tacker to change the classifier '''
+ """ calling Tacker to change the classifier """
cmd_tacker = "%s" % (self.tacker_classi)
subprocess.call(cmd_tacker, shell=True)
" :) \n" + '\033[0m')
def teardown(self):
- ''' for scenario teardown remove tacker VNFs, chains and classifiers'''
+ """ for scenario teardown remove tacker VNFs, chains and classifiers"""
self.teardown_script = pkg_resources.resource_filename(
"yardstick.benchmark.scenarios.networking",
Sfc.TEARDOWN_SCRIPT)
self.teardown_done = True
-'''def _test(): # pragma: no cover
+"""def _test(): # pragma: no cover
internal test function
logger = logging.getLogger("Sfc Yardstick")
sfc.teardown()
if __name__ == '__main__': # pragma: no cover
- _test()'''
+ _test()"""
None)
def setup(self):
- '''scenario setup'''
+ """scenario setup"""
vsperf = self.context_cfg['host']
vsperf_user = vsperf.get('user', 'ubuntu')
vsperf_ssh_port = vsperf.get('ssh_port', ssh.DEFAULT_PORT)
self.setup_done = False
def setup(self):
- '''scenario setup'''
+ """scenario setup"""
self.options = self.scenario_cfg['options']
self.setup_done = True
self.setup_done = False
def setup(self):
- '''scenario setup'''
+ """scenario setup"""
self.options = self.scenario_cfg['options']
self.setup_done = True
self.setup_done = False
def setup(self):
- '''scenario setup'''
+ """scenario setup"""
self.options = self.scenario_cfg['options']
self.setup_done = True
self.setup_done = False
def setup(self):
- '''scenario setup'''
+ """scenario setup"""
self.options = self.scenario_cfg['options']
self.setup_done = True
result['yangtotosca'] = "success" if p.returncode == 0 else "fail"
def teardown(self):
- ''' for scenario teardown remove parser and pyang '''
+ """ for scenario teardown remove parser and pyang """
self.teardown_script = pkg_resources.resource_filename(
"yardstick.benchmark.scenarios.parser",
Parser.TEARDOWN_SCRIPT)
def _test():
- '''internal test function'''
+ """internal test function"""
pass
self.setup_done = False
def setup(self):
- '''scenario setup'''
+ """scenario setup"""
self.target_script = pkg_resources.resource_filename(
"yardstick.benchmark.scenarios.storage",
Fio.TARGET_SCRIPT)
def _test():
- '''internal test function'''
+ """internal test function"""
key_filename = pkg_resources.resource_filename("yardstick.resources",
"files/yardstick_key")
ctx = {
def print_hbar(barlen):
- '''print to stdout a horizontal bar'''
+ """print to stdout a horizontal bar"""
print(("+"), end=' ')
print(("-" * barlen), end=' ')
print("+")
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-'''
+"""
Command-line interface to yardstick
-'''
+"""
from __future__ import absolute_import
import logging
class YardstickCLI():
- '''Command-line interface to yardstick'''
+ """Command-line interface to yardstick"""
# Command categories
categories = {
get_distribution('yardstick').version
def _find_actions(self, subparsers, actions_module):
- '''find action methods'''
+ """find action methods"""
# Find action methods inside actions_module and
# add them to the command parser.
# The 'actions_module' argument may be a class
subparser.set_defaults(func=callback)
def _add_command_parsers(self, categories, subparsers):
- '''add commands to command-line parser'''
+ """add commands to command-line parser"""
for category in categories:
command_object = categories[category]()
desc = command_object.__doc__ or ''
CONF.unregister_opts(self.opts)
def main(self, argv): # pragma: no cover
- '''run the command line interface'''
+ """run the command line interface"""
try:
self._register_cli_opt()
self._clear_config_opts()
def api(self, argv, task_id): # pragma: no cover
- '''run the api interface'''
+ """run the api interface"""
try:
self._register_cli_opt()
class EnvCommand(object):
- '''
+ """
Set of commands to prepare environment
- '''
+ """
def do_influxdb(self, args):
data = {'action': 'createInfluxDBContainer'}
class PluginCommands(object):
- '''Plugin commands.
+ """Plugin commands.
Set of commands to manage plugins.
- '''
+ """
@cliargs("input_file", type=str, help="path to plugin configuration file",
nargs=1)
def do_install(self, args):
- '''Install a plugin.'''
+ """Install a plugin."""
param = change_osloobj_to_paras(args)
Plugin().install(param)
@cliargs("input_file", type=str, help="path to plugin configuration file",
nargs=1)
def do_remove(self, args):
- '''Remove a plugin.'''
+ """Remove a plugin."""
param = change_osloobj_to_paras(args)
Plugin().remove(param)
class RunnerCommands(object):
- '''Runner commands.
+ """Runner commands.
Set of commands to discover and display runner types.
- '''
+ """
def do_list(self, args):
- '''List existing runner types'''
+ """List existing runner types"""
param = change_osloobj_to_paras(args)
Runners().list_all(param)
@cliargs("type", type=str, help="runner type", nargs=1)
def do_show(self, args):
- '''Show details of a specific runner type'''
+ """Show details of a specific runner type"""
param = change_osloobj_to_paras(args)
Runners().show(param)
class ScenarioCommands(object):
- '''Scenario commands.
+ """Scenario commands.
Set of commands to discover and display scenario types.
- '''
+ """
def do_list(self, args):
- '''List existing scenario types'''
+ """List existing scenario types"""
param = change_osloobj_to_paras(args)
Scenarios().list_all(param)
@cliargs("type", type=str, help="runner type", nargs=1)
def do_show(self, args):
- '''Show details of a specific scenario type'''
+ """Show details of a specific scenario type"""
param = change_osloobj_to_paras(args)
Scenarios().show(param)
class TaskCommands(object):
- '''Task commands.
+ """Task commands.
Set of commands to manage benchmark tasks.
- '''
+ """
@cliargs("inputfile", type=str, help="path to task or suite file", nargs=1)
@cliargs("--task-args", dest="task_args",
class TestcaseCommands(object):
- '''Testcase commands.
+ """Testcase commands.
Set of commands to discover and display test cases.
- '''
+ """
def do_list(self, args):
- '''List existing test cases'''
+ """List existing test cases"""
param = change_osloobj_to_paras(args)
Testcase().list_all(param)
@cliargs("casename", type=str, help="test case name", nargs=1)
def do_show(self, args):
- '''Show details of a specific test case'''
+ """Show details of a specific test case"""
param = change_osloobj_to_paras(args)
Testcase().show(param)
def parse(tmpl_str):
- '''Takes a string and returns a dict containing the parsed structure.
+ """Takes a string and returns a dict containing the parsed structure.
This includes determination of whether the string is using the
JSON or YAML format.
- '''
+ """
if tmpl_str.startswith('{'):
tpl = jsonutils.loads(tmpl_str)
else:
@staticmethod
def get_cls(dispatcher_type):
- '''Return class of specified type.'''
+ """Return class of specified type."""
for dispatcher in utils.itersubclasses(Base):
if dispatcher_type == dispatcher.__dispatcher_type__:
return dispatcher
def main():
- '''yardstick main'''
+ """yardstick main"""
YardstickCLI().main(sys.argv[1:])
if __name__ == '__main__':
class HeatObject(object):
- ''' base class for template and stack'''
+ """ base class for template and stack"""
def __init__(self):
self._heat_client = None
self.uuid = None
def _get_heat_client(self):
- '''returns a heat client instance'''
+ """returns a heat client instance"""
if self._heat_client is None:
sess = op_utils.get_session()
return self._heat_client
def status(self):
- '''returns stack state as a string'''
+ """returns stack state as a string"""
heat = self._get_heat_client()
stack = heat.stacks.get(self.uuid)
return getattr(stack, 'stack_status')
class HeatStack(HeatObject):
- ''' Represents a Heat stack (deployed template) '''
+ """ Represents a Heat stack (deployed template) """
stacks = []
def __init__(self, name):
@staticmethod
def stacks_exist():
- '''check if any stack has been deployed'''
+ """check if any stack has been deployed"""
return len(HeatStack.stacks) > 0
def _delete(self):
- '''deletes a stack from the target cloud using heat'''
+ """deletes a stack from the target cloud using heat"""
if self.uuid is None:
return
self.uuid = None
def delete(self, block=True, retries=3):
- '''deletes a stack in the target cloud using heat (with retry)
+ """deletes a stack in the target cloud using heat (with retry)
Sometimes delete fail with "InternalServerError" and the next attempt
succeeds. So it is worthwhile to test a couple of times.
- '''
+ """
if self.uuid is None:
return
stack.delete()
def update(self):
- '''update a stack'''
+ """update a stack"""
raise RuntimeError("not implemented")
class HeatTemplate(HeatObject):
- '''Describes a Heat template and a method to deploy template to a stack'''
+ """Describes a Heat template and a method to deploy template to a stack"""
def _init_template(self):
self._template = {}
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
self._template['description'] = \
- '''Stack built by the yardstick framework for %s on host %s %s.
+ """Stack built by the yardstick framework for %s on host %s %s.
All referred generated resources are prefixed with the template
- name (i.e. %s).''' % (getpass.getuser(), socket.gethostname(),
+ name (i.e. %s).""" % (getpass.getuser(), socket.gethostname(),
timestamp, self.name)
# short hand for resources part of template
log.debug("template object '%s' created", name)
def add_network(self, name):
- '''add to the template a Neutron Net'''
+ """add to the template a Neutron Net"""
log.debug("adding Neutron::Net '%s'", name)
self.resources[name] = {
'type': 'OS::Neutron::Net',
}
def add_subnet(self, name, network, cidr):
- '''add to the template a Neutron Subnet'''
+ """add to the template a Neutron Subnet"""
log.debug("adding Neutron::Subnet '%s' in network '%s', cidr '%s'",
name, network, cidr)
self.resources[name] = {
}
def add_router(self, name, ext_gw_net, subnet_name):
- '''add to the template a Neutron Router and interface'''
+ """add to the template a Neutron Router and interface"""
log.debug("adding Neutron::Router:'%s', gw-net:'%s'", name, ext_gw_net)
self.resources[name] = {
}
def add_router_interface(self, name, router_name, subnet_name):
- '''add to the template a Neutron RouterInterface and interface'''
+ """add to the template a Neutron RouterInterface and interface"""
log.debug("adding Neutron::RouterInterface '%s' router:'%s', "
"subnet:'%s'", name, router_name, subnet_name)
}
def add_port(self, name, network_name, subnet_name, sec_group_id=None):
- '''add to the template a named Neutron Port'''
+ """add to the template a named Neutron Port"""
log.debug("adding Neutron::Port '%s', network:'%s', subnet:'%s', "
"secgroup:%s", name, network_name, subnet_name, sec_group_id)
self.resources[name] = {
def add_floating_ip(self, name, network_name, port_name, router_if_name,
secgroup_name=None):
- '''add to the template a Nova FloatingIP resource
+ """add to the template a Nova FloatingIP resource
see: https://bugs.launchpad.net/heat/+bug/1299259
- '''
+ """
log.debug("adding Nova::FloatingIP '%s', network '%s', port '%s', "
"rif '%s'", name, network_name, port_name, router_if_name)
}
def add_floating_ip_association(self, name, floating_ip_name, port_name):
- '''add to the template a Nova FloatingIP Association resource
- '''
+ """add to the template a Nova FloatingIP Association resource
+ """
log.debug("adding Nova::FloatingIPAssociation '%s', server '%s', "
"floating_ip '%s'", name, port_name, floating_ip_name)
}
def add_keypair(self, name, key_uuid):
- '''add to the template a Nova KeyPair'''
+ """add to the template a Nova KeyPair"""
log.debug("adding Nova::KeyPair '%s'", name)
self.resources[name] = {
'type': 'OS::Nova::KeyPair',
}
def add_servergroup(self, name, policy):
- '''add to the template a Nova ServerGroup'''
+ """add to the template a Nova ServerGroup"""
log.debug("adding Nova::ServerGroup '%s', policy '%s'", name, policy)
if policy not in ["anti-affinity", "affinity"]:
raise ValueError(policy)
}
def add_security_group(self, name):
- '''add to the template a Neutron SecurityGroup'''
+ """add to the template a Neutron SecurityGroup"""
log.debug("adding Neutron::SecurityGroup '%s'", name)
self.resources[name] = {
'type': 'OS::Neutron::SecurityGroup',
def add_server(self, name, image, flavor, ports=None, networks=None,
scheduler_hints=None, user=None, key_name=None,
user_data=None, metadata=None, additional_properties=None):
- '''add to the template a Nova Server'''
+ """add to the template a Nova Server"""
log.debug("adding Nova::Server '%s', image '%s', flavor '%s', "
"ports %s", name, image, flavor, ports)
}
def create(self, block=True):
- '''creates a template in the target cloud using heat
- returns a dict with the requested output values from the template'''
+ """creates a template in the target cloud using heat
+ returns a dict with the requested output values from the template"""
log.info("Creating stack '%s'", self.name)
# create stack early to support cleanup, e.g. ctrl-c while waiting
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
-''' yardstick-plot - a command line tool for visualizing results from the
+""" yardstick-plot - a command line tool for visualizing results from the
output file of yardstick framework.
Example invocation:
$ yardstick-plot -i /tmp/yardstick.out -o /tmp/plots/
-'''
+"""
from __future__ import absolute_import
from __future__ import print_function
class Parser(object):
- ''' Command-line argument and input file parser for yardstick-plot tool'''
+ """ Command-line argument and input file parser for yardstick-plot tool"""
def __init__(self):
self.data = {
self.scenarios = {}
def _get_parser(self):
- '''get a command-line parser'''
+ """get a command-line parser"""
parser = argparse.ArgumentParser(
prog='yardstick-plot',
description="A tool for visualizing results from yardstick. "
return parser
def _add_record(self, record):
- '''add record to the relevant scenario'''
+ """add record to the relevant scenario"""
if "runner_id" in record and "benchmark" not in record:
obj_name = record["scenario_cfg"]["runner"]["object"]
self.scenarios[record["runner_id"]] = obj_name
self.data[test_type].append(record)
def parse_args(self):
- '''parse command-line arguments'''
+ """parse command-line arguments"""
parser = self._get_parser()
self.args = parser.parse_args()
return self.args
def parse_input_file(self):
- '''parse the input test results file'''
+ """parse the input test results file"""
if self.args.input:
input_file = self.args.input
else:
class Plotter(object):
- '''Graph plotter for scenario-specific results from yardstick framework'''
+ """Graph plotter for scenario-specific results from yardstick framework"""
def __init__(self, data, output_folder):
self.data = data
self.colors = ['g', 'b', 'c', 'm', 'y']
def plot(self):
- '''plot the graph(s)'''
+ """plot the graph(s)"""
for test_type in self.data.keys():
if self.data[test_type]:
plt.figure(self.fig_counter)
self._save_plot(test_type)
def _save_plot(self, test_type):
- '''save the graph to output folder'''
+ """save the graph to output folder"""
timestr = time.strftime("%Y%m%d-%H%M%S")
file_name = test_type + "_" + timestr + ".png"
if not self.output_folder:
print(("Saved graph to " + new_file))
def _plot_ping(self, records):
- '''ping test result interpretation and visualization on the graph'''
+ """ping test result interpretation and visualization on the graph"""
rtts = [r['benchmark']['data']['rtt'] for r in records]
seqs = [r['benchmark']['sequence'] for r in records]
plt.ylabel("round trip time in milliseconds (rtt)")
def _plot_pktgen(self, records):
- '''pktgen test result interpretation and visualization on the graph'''
+ """pktgen test result interpretation and visualization on the graph"""
flows = [r['benchmark']['data']['flows'] for r in records]
sent = [r['benchmark']['data']['packets_sent'] for r in records]
received = [int(r['benchmark']['data']['packets_received'])
plt.ylabel("lost packets per million packets (ppm)")
def _plot_iperf3(self, records):
- '''iperf3 test result interpretation and visualization on the graph'''
+ """iperf3 test result interpretation and visualization on the graph"""
intervals = []
for r in records:
# If did not fail the SLA
plt.ylabel("bandwidth in Kb/s")
def _plot_fio(self, records):
- '''fio test result interpretation and visualization on the graph'''
+ """fio test result interpretation and visualization on the graph"""
rw_types = [r['sargs']['options']['rw'] for r in records]
seqs = [x for x in range(1, len(records) + 1)]
data = {}
plt.xticks(seqs, seqs)
def _plot_fio_helper(self, data, seqs, key, bar_color, axl):
- '''check if measurements exist for a key and then plot the
- data to a given subplot'''
+ """check if measurements exist for a key and then plot the
+ data to a given subplot"""
if key in data:
if len(data[key]) == 1:
axl.bar(0.1, data[key], 0.35, color=bar_color)
axl.plot(seqs, data[key], line_style)
def _construct_legend(self, legend_texts, obj=plt):
- '''construct legend for the plot or subplot'''
+ """construct legend for the plot or subplot"""
ci = 0
lines = []
# See the License for the specific language governing permissions and
# limitations under the License.
-'''
+"""
The Benchmarking Unit manages the Benchmarking of VNFs orchestrating the
initialization, execution and finalization
-'''
+"""
from __future__ import absolute_import
class BenchmarkBaseClass(object):
- '''
+ """
This class represents a Benchmark that we want to run on the platform.
One of them will be the calculation of the throughput changing the
configuration parameters
- '''
+ """
def __init__(self, name, params):
if not params:
# limitations under the License.
-'''
+"""
Generation of the heat templates from the base template
-'''
+"""
from __future__ import absolute_import
import json
# See the License for the specific language governing permissions and
# limitations under the License.
-'''
+"""
Libraries to be used by the framework.
-'''
+"""
__author__ = 'vmriccox'
# See the License for the specific language governing permissions and
# limitations under the License.
-'''
+"""
Packet generators
-'''
+"""
__author__ = 'vmriccox'
self.dpdk_interfaces = -1
def send_traffic(self):
- '''
+ """
Calls the packet generator and starts to send traffic
Blocking call
- '''
+ """
current_dir = os.path.dirname(os.path.realpath(__file__))
DpdkPacketGenerator._chdir(self.directory)
dpdk_vars = common.get_dpdk_pktgen_vars()
mock_dir_name,
mock_os_path,
mock_os_system):
- '''
+ """
Calls the packet generator and starts to send traffic
Blocking call
- '''
+ """
mock_get_core_nics.return_value = "{corenics}"
mock_os_path.realpath.return_value = 'pktgen_dir_test'
mock_os_path.dirname.return_value = 'current_directory'