##############################################################################
# Copyright (c) 2015 Ericsson AB and others.
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0

""" Heat template and stack management
"""

import os
import time
import datetime
import getpass
import socket
import logging
import pkg_resources
import json
import heatclient.client
import keystoneclient

from yardstick.common import template_format

log = logging.getLogger(__name__)

class HeatObject(object):
    ''' base class for template and stack'''
    def __init__(self):
        self._keystone_client = None
        self._heat_client = None
        self.uuid = None

    def _get_keystone_client(self):
        '''returns a keystone client instance'''

        if self._keystone_client is None:
            self._keystone_client = keystoneclient.v2_0.client.Client(
                auth_url=os.environ.get('OS_AUTH_URL'),
                username=os.environ.get('OS_USERNAME'),
                password=os.environ.get('OS_PASSWORD'),
                tenant_name=os.environ.get('OS_TENANT_NAME'))

        return self._keystone_client

    def _get_heat_client(self):
        '''returns a heat client instance'''

        if self._heat_client is None:
            keystone = self._get_keystone_client()
            heat_endpoint = keystone.service_catalog.url_for(
                service_type='orchestration')
            self._heat_client = heatclient.client.Client(
                '1', endpoint=heat_endpoint, token=keystone.auth_token)

        return self._heat_client

    def status(self):
        '''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) '''
    stacks = []

    def __init__(self, name):
        super(HeatStack, self).__init__()
        self.name = name
        self.outputs = None
        HeatStack.stacks.append(self)

    @staticmethod
    def stacks_exist():
        '''check if any stack has been deployed'''
        return len(HeatStack.stacks) > 0

    def _delete(self):
        '''deletes a stack from the target cloud using heat'''
        if self.uuid is None:
            return

        log.info("Deleting stack '%s', uuid:%s", self.name, self.uuid)
        template = heat.stacks.get(self.uuid)
        start_time = time.time()
        template.delete()
        status = self.status()

        while status != u'DELETE_COMPLETE':
            log.debug("stack state %s", status)
            if status == u'DELETE_FAILED':
                raise RuntimeError(
                    heat.stacks.get(self.uuid).stack_status_reason)

            time.sleep(2)
            status = self.status()

        end_time = time.time()
        log.info("Deleted stack '%s' in %d secs", self.name,
                 end_time - start_time)

    def delete(self, block=True, retries=3):
        '''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.
        '''
            return

        if not block:
            self._delete()
            return

        i = 0
        while i < retries:
            try:
                self._delete()
                break
            except RuntimeError as err:
                log.warn(err.args)
                time.sleep(2)
            i += 1

        # if still not deleted try once more and let it fail everything
        if self.uuid is not None:

        HeatStack.stacks.remove(self)

    def delete_all():
        for stack in HeatStack.stacks[:]:
            stack.delete()

    def update(self):
        '''update a stack'''
        raise RuntimeError("not implemented")

class HeatTemplate(HeatObject):
    '''Describes a Heat template and a method to deploy template to a stack'''

    def _init_template(self):
        self._template = {}
        self._template['heat_template_version'] = '2013-05-23'

        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.
            All referred generated resources are prefixed with the template
            name (i.e. %s).''' % (getpass.getuser(), socket.gethostname(),
                                  timestamp, self.name)

        # short hand for resources part of template
        self.resources = self._template['resources'] = {}

        self._template['outputs'] = {}

    def __init__(self, name, template_file=None, heat_parameters=None):
        super(HeatTemplate, self).__init__()
        self.state = "NOT_CREATED"
        self.keystone_client = None
        self.heat_client = None
        self.heat_parameters = {}

        # heat_parameters is passed to heat in stack create, empty dict when
        # yardstick creates the template (no get_param in resources part)
        if heat_parameters:
            self.heat_parameters = heat_parameters

        if template_file:
            with open(template_file) as stream:
                print "Parsing external template:", template_file
                template_str = stream.read()
                self._template = template_format.parse(template_str)
            self._parameters = heat_parameters
        else:
            self._init_template()

        # holds results of requested output after deployment
        self.outputs = {}

        log.debug("template object '%s' created", name)

    def add_network(self, name):
        '''add to the template a Neutron Net'''
        log.debug("adding Neutron::Net '%s'", name)
        self.resources[name] = {
            'type': 'OS::Neutron::Net',
            'properties': {'name': name}
        }

    def add_subnet(self, name, network, cidr):
        '''add to the template a Neutron Subnet'''
        log.debug("adding Neutron::Subnet '%s' in network '%s', cidr '%s'",
                  name, network, cidr)
            'type': 'OS::Neutron::Subnet',
            'depends_on': network,
            'properties': {
                'name': name,
                'cidr': cidr,
                'network_id': {'get_resource': network}
            }
        }

        self._template['outputs'][name] = {
            'description': 'subnet %s ID' % name,
            'value': {'get_resource': name}
        }

    def add_router(self, name, ext_gw_net, subnet_name):
        '''add to the template a Neutron Router and interface'''
        log.debug("adding Neutron::Router:'%s', gw-net:'%s'", name, ext_gw_net)

            'type': 'OS::Neutron::Router',
            'depends_on': [subnet_name],
                'external_gateway_info': {
                    'network': ext_gw_net
                }
            }
        }

    def add_router_interface(self, name, router_name, subnet_name):
        '''add to the template a Neutron RouterInterface and interface'''
        log.debug("adding Neutron::RouterInterface '%s' router:'%s', "
                  "subnet:'%s'", name, router_name, subnet_name)

            'type': 'OS::Neutron::RouterInterface',
            'depends_on': [router_name, subnet_name],
                'router_id': {'get_resource': router_name},
                'subnet_id': {'get_resource': subnet_name}
            }
        }

    def add_port(self, name, network_name, subnet_name, sec_group_id=None):
        '''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)
            'type': 'OS::Neutron::Port',
                'fixed_ips': [{'subnet': {'get_resource': subnet_name}}],
                'network_id': {'get_resource': network_name},
                'replacement_policy': 'AUTO',
            }
        }

        if sec_group_id:
            self.resources[name]['depends_on'].append(sec_group_id)
            self.resources[name]['properties']['security_groups'] = \
                [sec_group_id]

            'description': 'Address for interface %s' % name,
            'value': {'get_attr': [name, 'fixed_ips', 0, 'ip_address']}
        }

    def add_floating_ip(self, name, network_name, port_name, router_if_name,
                        secgroup_name=None):
        '''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)

            'type': 'OS::Nova::FloatingIP',
            'depends_on': [port_name, router_if_name],
                'pool': network_name
            }
        }

        if secgroup_name:
            self.resources[name]["depends_on"].append(secgroup_name)

            'description': 'floating ip %s' % name,
            'value': {'get_attr': [name, 'ip']}
        }

    def add_floating_ip_association(self, name, floating_ip_name, server_name):
        '''add to the template a Nova FloatingIP Association resource
        '''
        log.debug("adding Nova::FloatingIPAssociation '%s', server '%s', "
                  "floating_ip '%s'", name, server_name, floating_ip_name)

            'type': 'OS::Nova::FloatingIPAssociation',
            'depends_on': [server_name],
                'floating_ip': {'get_resource': floating_ip_name},
                'server_id': {'get_resource': server_name}
            }
        }

    def add_keypair(self, name):
        '''add to the template a Nova KeyPair'''
        log.debug("adding Nova::KeyPair '%s'", name)
            'type': 'OS::Nova::KeyPair',
                'public_key': pkg_resources.resource_string(
                    'yardstick.resources', 'files/yardstick_key.pub')
            }
        }

    def add_servergroup(self, name, policy):
        '''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)

            'type': 'OS::Nova::ServerGroup',
                'policies': [policy]
            }
        }

            'description': 'ID Server Group %s' % name,
        }

    def add_security_group(self, name):
        '''add to the template a Neutron SecurityGroup'''
        log.debug("adding Neutron::SecurityGroup '%s'", name)
            'type': 'OS::Neutron::SecurityGroup',
                'description': "Group allowing icmp and upd/tcp on all ports",
                'rules': [
                    {'remote_ip_prefix': '0.0.0.0/0',
                     'protocol': 'tcp',
                     'port_range_min': '1',
                     'port_range_max': '65535'},
                     'protocol': 'udp',
                     'protocol': 'icmp'}
                ]
            }
        }

            'description': 'ID of Security Group',
        }

    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'''
        log.debug("adding Nova::Server '%s', image '%s', flavor '%s', "
                  "ports %s", name, image, flavor, ports)

            'type': 'OS::Nova::Server'
        }

        server_properties = {
            'name': name,
            'image': image,
            'flavor': flavor,
            'networks': []  # list of dictionaries
        }

        if user:
            server_properties['admin_user'] = user

        if key_name:
            self.resources[name]['depends_on'] = [key_name]
            server_properties['key_name'] = {'get_resource': key_name}

        if ports:
            self.resources[name]['depends_on'] = ports

            for port in ports:
                server_properties['networks'].append(
                    {'port': {'get_resource': port}}
                )

        if networks:
            for i in range(len(networks)):
                server_properties['networks'].append({'network': networks[i]})

        if scheduler_hints:
            server_properties['scheduler_hints'] = scheduler_hints

        if user_data:
            server_properties['user_data'] = user_data

        if metadata:
            assert type(metadata) is dict
            server_properties['metadata'] = metadata

        if additional_properties:
            assert type(additional_properties) is dict
            for prop in additional_properties:
                server_properties[prop] = additional_properties[prop]

        server_properties['config_drive'] = True

        self.resources[name]['properties'] = server_properties

            'description': 'VM UUID',
        }

    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'''
        log.info("Creating stack '%s'", self.name)

        # create stack early to support cleanup, e.g. ctrl-c while waiting
        stack = HeatStack(self.name)

        json_template = json.dumps(self._template)
        stack.uuid = self.uuid = heat.stacks.create(
            stack_name=self.name, template=json_template,
            parameters=self.heat_parameters)['stack']['id']

        if block:
            while status != u'CREATE_COMPLETE':
                log.debug("stack state %s", status)
                if status == u'CREATE_FAILED':
                    raise RuntimeError(getattr(heat.stacks.get(self.uuid),
                                               'stack_status_reason'))

                status = self.status()

            end_time = time.time()
            outputs = getattr(heat.stacks.get(self.uuid), 'outputs')

        for output in outputs:
            self.outputs[output["output_key"].encode("ascii")] = \
                output["output_value"].encode("ascii")

        log.info("Created stack '%s' in %d secs",
                 self.name, end_time - start_time)

        stack.outputs = self.outputs
        return stack

#

""" Handler for yardstick command 'scenario' """

from yardstick.benchmark.scenarios.base import Scenario
from yardstick.common.utils import cliargs
from yardstick.cmd import print_hbar

class ScenarioCommands(object):
    '''Scenario commands.

       Set of commands to discover and display scenario types.
    '''

    def do_list(self, args):
        '''List existing scenario types'''
        types = Scenario.get_types()
        print_hbar(78)
        print("| %-16s | %-60s" % ("Type", "Description"))
        for stype in types:
            print("| %-16s | %-60s" % (stype.__scenario_type__,
                                       stype.__doc__.split("\n")[0]))

    @cliargs("type", type=str, help="runner type", nargs=1)
    def do_show(self, args):
        '''Show details of a specific scenario type'''
        stype = Scenario.get_cls(args.type[0])
        print stype.__doc__

# Copyright (c) 2015 Intel Research and Development Ireland Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from experimental_framework.benchmarks import benchmark_base_class
from experimental_framework.packet_generators \
    import dpdk_packet_generator as dpdk
import experimental_framework.common as common
from experimental_framework.constants import framework_parameters as fp

PACKET_SIZE = 'packet_size'
VLAN_SENDER = 'vlan_sender'
VLAN_RECEIVER = 'vlan_receiver'

class RFC2544ThroughputBenchmark(benchmark_base_class.BenchmarkBaseClass):
    """
    Calculates the throughput of the VNF under test according to the RFC2544.
    """

    def __init__(self, name, params):
        benchmark_base_class.BenchmarkBaseClass.__init__(self, name, params)
        self.base_dir = common.get_base_dir() + \
            fp.EXPERIMENTAL_FRAMEWORK_DIR + fp.DPDK_PKTGEN_DIR
        self.results_file = self.base_dir + 'experiment.res'
        self.lua_file = self.base_dir + 'rfc2544.lua'

    def init(self):
        """
        Initialize the benchmark
        :return: None
        """
        pass

    def finalize(self):
        """
        """
        pass

    def get_features(self):
        """
        Returns the features associated to the benchmark
        :return:
        """
        features = dict()
        features['description'] = 'RFC 2544 Throughput calculation'
        features['parameters'] = [PACKET_SIZE, VLAN_SENDER, VLAN_RECEIVER]
        features['allowed_values'] = dict()
        features['allowed_values'][PACKET_SIZE] = ['64', '128', '256', '512',
                                                   '1024', '1280', '1514']
        features['allowed_values'][VLAN_SENDER] = map(str, range(-1, 4096))
        features['allowed_values'][VLAN_RECEIVER] = map(str, range(-1, 4096))
        features['default_values'] = dict()
        features['default_values'][PACKET_SIZE] = '1280'
        features['default_values'][VLAN_SENDER] = '1007'
        features['default_values'][VLAN_RECEIVER] = '1006'
        return features

    def run(self):
        """
        Sends and receive traffic according to the RFC methodology in order
        to measure the throughput of the workload
        :return: Results of the testcase (type: dict)
        """
        packet_size = self._extract_packet_size_from_params()

        # Packetgen management
        packetgen = dpdk.DpdkPacketGenerator()
        self._configure_lua_file()
        packetgen.init_dpdk_pktgen(dpdk_interfaces=2,
                                   pcap_file_0='packet_' +
                                               packet_size + '.pcap',
                                   pcap_file_1='igmp.pcap',
                                   lua_script='rfc2544.lua',
                                   vlan_0=self.params[VLAN_SENDER],
                                   vlan_1=self.params[VLAN_RECEIVER])
        common.LOG.debug('Start the packet generator - packet size: ' +
                         str(packet_size))
        packetgen.send_traffic()
        common.LOG.debug('Stop the packet generator')

        return self._get_results()

    def _extract_packet_size_from_params(self):
        """
        Extracts packet sizes from parameters
        :return: packet_sizes (list)
        """
        packet_size = '1280'  # default value
        if PACKET_SIZE in self.params.keys() and \
                isinstance(self.params[PACKET_SIZE], str):
            packet_size = self.params[PACKET_SIZE]
        return packet_size

    def _configure_lua_file(self):
        """
        Configure the packet gen to write the results into the right file
        """
        common.replace_in_file(self.lua_file, 'local out_file = ""',
                               'local out_file = "' +
                               self.results_file + '"')

    def _reset_lua_file(self):
        """
        Sets back the configuration of the local file var to the default
        :return:
        """
        common.replace_in_file(self.lua_file, 'local out_file = "' +
                               self.results_file + '"',
                               'local out_file = ""')

    def _get_results(self):
        """
        Returns the results of the experiment
        """
        throughput = common.get_file_first_line(self.results_file)
        ret_val = dict()
        try:
            ret_val['throughput'] = int(throughput)
        except:
            ret_val['throughput'] = 0
        return ret_val

#############################################################################
#

import os

from yardstick.benchmark.scenarios import base
from experimental_framework import api as api

LOG = logging.getLogger(__name__)

class VtcThroughput(base.Scenario):
    """Execute Instantiation Validation TC on the vTC
    """
    __scenario_type__ = "vtc_throughput"

    def __init__(self, scenario_cfg, context_cfg):
        self.scenario_cfg = scenario_cfg
        self.context_cfg = context_cfg
        self.options = None
        self.setup_done = False

    def setup(self):
        '''scenario setup'''

        self.options = self.scenario_cfg['options']
        self.setup_done = True

    def run(self, result):
        """execute test"""

        if not self.setup_done:
            self.setup()

        heat_template = 'vTC.yaml'
        iterations = 1

        openstack_credentials = {
            'ip_controller': '0.0.0.0',
            'heat_url': '***',
            'auth_uri': os.environ.get('OS_AUTH_URL'),
            'user': os.environ.get('OS_USERNAME'),
            'password': os.environ.get('OS_PASSWORD'),
            'project': os.environ.get('OS_TENANT_NAME')
        }
        heat_template_parameters = {
            'default_net': self.options['default_net_name'],
            'default_subnet': self.options['default_subnet_name'],
            'source_net': self.options['vlan_net_1_name'],
            'source_subnet': self.options['vlan_subnet_1_name'],
            'destination_net': self.options['vlan_net_2_name'],
            'destination_subnet': self.options['vlan_subnet_2_name']
        }
        deployment_configuration = {
            'vnic_type': [self.options['vnic_type']],
            'vtc_flavor': [self.options['vtc_flavor']]
        }

        test_case = dict()
        test_case['name'] = 'rfc2544_throughput_benchmark.' \
                            'RFC2544ThroughputBenchmark'
        test_case['params'] = dict()
        test_case['params']['packet_size'] = str(self.options['packet_size'])
        test_case['params']['vlan_sender'] = str(self.options['vlan_sender'])
        test_case['params']['vlan_receiver'] = \
            str(self.options['vlan_receiver'])

        res = dict()
        try:
            res = api.FrameworkApi.execute_framework(
                [test_case],
                iterations,
                heat_template,
                heat_template_parameters,
                deployment_configuration,
                openstack_credentials)
        except Exception as e:
            LOG.info('Exception: {}'.format(e.message))
        LOG.info('Got output: {}'.format(res))
        result.update(res)

#
#
#

# ------------------------------------------------------
# Configuration File Sections
CFS_PKTGEN = 'PacketGen'
CFS_GENERAL = 'General'
CFS_OPENSTACK = 'OpenStack'
CFS_EXPERIMENT_VNF = 'Experiment-VNF'
CFS_EXPERIMENT_GENERIC = 'Experiment-generic'
CFS_TESTCASE_PARAMETERS = 'Testcase-parameters'
CFS_DEPLOYMENT_PARAMETERS = 'Deployment-parameters'
CFS_INFLUXDB = 'InfluxDB'

def get_sections():
    return [
        CFS_PKTGEN,
        CFS_GENERAL,
        CFS_OPENSTACK,
        CFS_EXPERIMENT_VNF,
        # CFS_EXPERIMENT_GENERIC,
        CFS_TESTCASE_PARAMETERS,
        CFS_DEPLOYMENT_PARAMETERS,
        CFS_INFLUXDB
        # Add here eventually new sections in configuration file ...
    ]

def get_sections_api():
    return [
    ]

# General section parameters
CFSG_ITERATIONS = 'iterations'
CFSG_TEMPLATE_DIR = 'template_dir'
CFSG_TEMPLATE_NAME = 'template_base_name'
CFSG_RESULT_DIRECTORY = 'results_directory'
CFSG_BENCHMARKS = 'benchmarks'
CFSG_DEBUG = 'debug'

# InfluxDB
CFSI_IDB_IP = 'influxdb_ip_address'
CFSI_IDB_PORT = 'influxdb_port'
CFSI_IDB_DB_NAME = 'influxdb_db_name'

# Packet generator section parameters
CFSP_PACKET_GENERATOR = 'packet_generator'
CFSP_DPDK_PKTGEN_DIRECTORY = 'pktgen_directory'
CFSP_DPDK_DPDK_DIRECTORY = 'dpdk_directory'
CFSP_DPDK_PROGRAM_NAME = 'program_name'
CFSP_DPDK_COREMASK = 'coremask'
CFSP_DPDK_MEMORY_CHANNEL = 'memory_channels'
CFSP_DPDK_BUS_SLOT_NIC_1 = 'bus_slot_nic_1'
CFSP_DPDK_BUS_SLOT_NIC_2 = 'bus_slot_nic_2'
CFSP_DPDK_NAME_IF_1 = 'name_if_1'
CFSP_DPDK_NAME_IF_2 = 'name_if_2'

# Supported Packet generators
CFSP_PG_NONE = 'none'
CFSP_PG_DPDK = 'dpdk_pktgen'

# OpenStack section variables
CFSO_IP_CONTROLLER = 'ip_controller'
CFSO_HEAT_URL = 'heat_url'
CFSO_USER = 'user'
CFSO_PASSWORD = 'password'
CFSO_AUTH_URI = 'auth_uri'
CFSO_PROJECT = 'project'

# Copyright (c) 2015 Huawei Technologies Co.,Ltd and others.
#

class Dummy(base.Scenario):
    """Execute Dummy echo
    """
    __scenario_type__ = "Dummy"

        """execute the benchmark"""

        result["hello"] = "yardstick"
        LOG.info("Dummy echo hello yardstick!")

#

import yardstick.ssh as ssh

class Ping6(base.Scenario):  # pragma: no cover
    """Execute ping6 between two hosts

    read link below for more ipv6 info description:
    http://wiki.opnfv.org/ipv6_opnfv_project
    """
    __scenario_type__ = "Ping6"

    TARGET_SCRIPT = 'ping6_benchmark.bash'
    PRE_SETUP_SCRIPT = 'ping6_pre_setup.bash'
    SETUP_SCRIPT = 'ping6_setup.bash'
    FIND_HOST_SCRIPT = 'ping6_find_host.bash'
    TEARDOWN_SCRIPT = 'ping6_teardown.bash'
    METADATA_SCRIPT = 'ping6_metadata.txt'
    POST_TEARDOWN_SCRIPT = 'ping6_post_teardown.bash'

        self.run_done = False

    def _pre_setup(self):
        for node_name in self.host_list:
            self._ssh_host(node_name)
            self.client.run("cat > ~/pre_setup.sh",
                            stdin=open(self.pre_setup_script, "rb"))
            status, stdout, stderr = self.client.execute(
                "sudo bash pre_setup.sh")

    def _ssh_host(self, node_name):
        # ssh host
        print node_name
        nodes = self.context_cfg['nodes']
        node = nodes.get(node_name, None)
        host_user = node.get('user', 'ubuntu')
        host_ip = node.get('ip', None)
        host_pwd = node.get('password', 'root')
        LOG.debug("user:%s, host:%s", host_user, host_ip)
        self.client = ssh.SSH(host_user, host_ip, password=host_pwd)
        self.client.wait(timeout=600)

        self.setup_script = pkg_resources.resource_filename(
            'yardstick.benchmark.scenarios.networking',
            Ping6.SETUP_SCRIPT)

        self.pre_setup_script = pkg_resources.resource_filename(
            Ping6.PRE_SETUP_SCRIPT)

        self.ping6_metadata_script = pkg_resources.resource_filename(
            Ping6.METADATA_SCRIPT)

        options = self.scenario_cfg['options']
        host_str = options.get("host", 'host1')
        self.host_list = host_str.split(',')
        self.host_list.sort()
        pre_setup = options.get("pre_setup", True)
        if pre_setup:
            self._pre_setup()

        # ssh host1
        self._ssh_host(self.host_list[0])
        # run script to setup ipv6
        self.client.run("cat > ~/setup.sh",
                        stdin=open(self.setup_script, "rb"))
        self.client.run("cat > ~/metadata.txt",
                        stdin=open(self.ping6_metadata_script, "rb"))
        cmd = "sudo bash setup.sh"
        status, stdout, stderr = self.client.execute(cmd)

        # ssh vm1
        self.ping6_script = pkg_resources.resource_filename(
            Ping6.TARGET_SCRIPT)

        self.ping6_find_host_script = pkg_resources.resource_filename(
            Ping6.FIND_HOST_SCRIPT)

            options = self.scenario_cfg['options']
            host_str = options.get("host", 'host1')
            self.host_list = host_str.split(',')
            self.host_list.sort()
            self._ssh_host(self.host_list[0])
        self.client.run("cat > ~/find_host.sh",
                        stdin=open(self.ping6_find_host_script, "rb"))
        cmd = "sudo bash find_host.sh"
        LOG.debug("Executing command: %s", cmd)
        host_name = stdout.strip()
        print host_name
        self.client.run("cat ~/vRouterKey",
                        stdout=open("/tmp/vRouterKey", "w"))
        self._ssh_host(host_name)

        self.client.run("cat > ~/vRouterKey",
                        stdin=open("/tmp/vRouterKey", "rb"))

        self.client.run("cat > ~/ping6.sh",
                        stdin=open(self.ping6_script, "rb"))
        cmd = "sudo bash ping6.sh"
        print stdout
        if status:
            raise RuntimeError(stderr)

        if stdout:
            result["rtt"] = float(stdout)

            if "sla" in self.scenario_cfg:
                sla_max_rtt = int(self.scenario_cfg["sla"]["max_rtt"])
                assert result["rtt"] <= sla_max_rtt, \
                    "rtt %f > sla:max_rtt(%f); " % (result["rtt"], sla_max_rtt)
        else:
            LOG.error("ping6 timeout")
        self.run_done = True

    def teardown(self):
        """teardown the benchmark"""

        self.post_teardown_script = pkg_resources.resource_filename(
            Ping6.POST_TEARDOWN_SCRIPT)

        host_str = options.get("host", 'node1')

        if not self.run_done:

        self.teardown_script = pkg_resources.resource_filename(
            Ping6.TEARDOWN_SCRIPT)
        self.client.run("cat > ~/teardown.sh",
                        stdin=open(self.teardown_script, "rb"))
        cmd = "sudo bash teardown.sh"

        post_teardown = options.get("post_teardown", True)
        if post_teardown:
            self._post_teardown()

        if status:

        if stdout:
            pass
        else:
            LOG.error("ping6 teardown failed")

    def _post_teardown(self):
            self.client.run("cat > ~/post_teardown.sh",
                            stdin=open(self.post_teardown_script, "rb"))
                "sudo bash post_teardown.sh")

#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

# yardstick: this file is copied from python-heatclient and slightly modified

import yaml

if hasattr(yaml, 'CSafeLoader'):
    yaml_loader = yaml.CSafeLoader
else:
    yaml_loader = yaml.SafeLoader

if hasattr(yaml, 'CSafeDumper'):
    yaml_dumper = yaml.CSafeDumper
else:
    yaml_dumper = yaml.SafeDumper

def _construct_yaml_str(self, node):
    # Override the default string handling function
    # to always return unicode objects
    return self.construct_scalar(node)
yaml_loader.add_constructor(u'tag:yaml.org,2002:str', _construct_yaml_str)
# Unquoted dates like 2013-05-23 in yaml files get loaded as objects of type
# datetime.data which causes problems in API layer when being processed by
# openstack.common.jsonutils. Therefore, make unicode string out of timestamps
# until jsonutils can handle dates.
yaml_loader.add_constructor(u'tag:yaml.org,2002:timestamp',
                            _construct_yaml_str)

def parse(tmpl_str):
    '''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 = json.loads(tmpl_str)
    else:
        try:
            tpl = yaml.load(tmpl_str, Loader=yaml_loader)
        except yaml.YAMLError as yea:
            raise ValueError(yea)
        else:
            if tpl is None:
                tpl = {}
    # Looking for supported version keys in the loaded template
    if not ('HeatTemplateFormatVersion' in tpl or
            'heat_template_version' in tpl or
            'AWSTemplateFormatVersion' in tpl):
        raise ValueError("Template format version not found.")
    return tpl

#
#
#

'''
The Benchmarking Unit manages the Benchmarking of VNFs orchestrating the
initialization, execution and finalization
'''

import inspect

from experimental_framework.benchmarks import benchmark_base_class as base
from experimental_framework import common
# from experimental_framework import data_manager as data
from experimental_framework import heat_template_generation as heat
from experimental_framework import deployment_unit as deploy

class BenchmarkingUnit:
    """
    Management of the overall Benchmarking process
    """

    def __init__(self, heat_template_name, openstack_credentials,
                 heat_template_parameters, iterations, benchmarks):
        """
        :param heat_template_name: (str) Name of the heat template.

        :param openstack_credentials: (dict) Credentials for openstack.
                        Required fields are: 'ip_controller', 'heat_url',
                        'user', 'password', 'auth_uri', 'project'.

        :param heat_template_parameters: (dict) parameters to be given as
                        input to the heat template. Required keys depend on
                        the specific heat template.

        :param iterations: (int) number of cycles to be executed.

        :param benchmarks: (list[str]) List of the names of the
                        benchmarks/test_cases to be executed in the cycle.

        """
        # Loads vars from configuration file
        self.template_file_extension = common.TEMPLATE_FILE_EXTENSION
        self.template_dir = common.get_template_dir()
        self.results_directory = str(common.RESULT_DIR) + str(time.time())

        # Initializes other internal variable from parameters
        self.template_name = heat_template_name
        self.iterations = iterations
        self.required_benchmarks = benchmarks
        self.template_files = []
        self.benchmarks = list()
        self.benchmark_names = list()
        # self.data_manager = data.DataManager(self.results_directory)
        self.heat_template_parameters = heat_template_parameters
        self.template_files = \
            heat.get_all_heat_templates(self.template_dir,
                                        self.template_file_extension)
        common.DEPLOYMENT_UNIT = deploy.DeploymentUnit(openstack_credentials)

    def initialize(self):
        """
        Initialize the environment in order to run the benchmarking

        """
        for benchmark in self.required_benchmarks:
            benchmark_class = BenchmarkingUnit.get_benchmark_class(
                benchmark['name'])
            # Need to generate a unique name for the benchmark
            # (since there is the possibility to have different
            # instances of the same benchmark)
            self.benchmarks.append(benchmark_class(
                self.get_benchmark_name(benchmark['name']),
                benchmark['params']))

        # for template_file_name in self.template_files:
        #     experiment_name = BenchmarkingUnit.extract_experiment_name(
        #         template_file_name)
            # self.data_manager.create_new_experiment(experiment_name)
            # for benchmark in self.benchmarks:
            #     self.data_manager.add_benchmark(experiment_name,
            #                                    benchmark.get_name())

        """
        Finalizes the Benchmarking Unit
        Destroys all the stacks deployed by the framework and save results on
        csv file.

        """
        # self.data_manager.generate_result_csv_file()
        common.DEPLOYMENT_UNIT.destroy_all_deployed_stacks()

    def run_benchmarks(self):
        """
        Runs all the requested benchmarks and collect the results.

        """
        common.LOG.info('Run Benchmarking Unit')

        experiment = dict()
        result = dict()
        for iteration in range(0, self.iterations):
            common.LOG.info('Iteration ' + str(iteration))
            for template_file_name in self.template_files:
                experiment_name = BenchmarkingUnit.\
                    extract_experiment_name(template_file_name)
                experiment['experiment_name'] = experiment_name
                configuration = self.\
                    get_experiment_configuration(template_file_name)
                # self.data_manager.add_configuration(experiment_name,
                #                                     configuration)
                for key in configuration.keys():
                    experiment[key] = configuration[key]
                # metadata = dict()
                # metadata['experiment_name'] = experiment_name
                # self.data_manager.add_metadata(experiment_name, metadata)

                # For each benchmark in the cycle the workload is deployed
                for benchmark in self.benchmarks:
                    log_msg = 'Benchmark {} started on {}'.format(
                        benchmark.get_name(), template_file_name
                    )
                    common.LOG.info(log_msg)

                    # Initialization of Benchmark
                    benchmark.init()
                    log_msg = 'Template {} deployment START'.\
                        format(experiment_name)

                    # Deployment of the workload
                    deployment_success = \
                        common.DEPLOYMENT_UNIT.deploy_heat_template(
                            self.template_dir + template_file_name,
                            experiment_name,
                            self.heat_template_parameters)

                    if deployment_success:
                        log_msg = 'Template {} deployment COMPLETED'.format(
                            experiment_name)
                        common.LOG.info(log_msg)
                    else:
                        log_msg = 'Template {} deployment FAILED'.format(
                        continue

                    # Running the Benchmark/test case
                    result = benchmark.run()
                    # self.data_manager.add_data_points(experiment_name,
                    #                                   benchmark.get_name(),
                    #                                   result)

                    # Terminate the workload
                    log_msg = 'Destroying deployment for experiment {}'.\
                    common.DEPLOYMENT_UNIT.destroy_heat_template(
                        experiment_name)

                    # Finalize the benchmark
                    benchmark.finalize()
                    log_msg = 'Benchmark {} terminated'.format(
                        benchmark.__class__.__name__)
                    # self.data_manager.generate_result_csv_file()

                    experiment['benchmark'] = benchmark.get_name()
                    for key in benchmark.get_params():
                        experiment[key] = benchmark.get_params()[key]
                common.LOG.info('Benchmark Finished')
                # self.data_manager.generate_result_csv_file()
        common.LOG.info('Benchmarking Unit: Experiments completed!')
        return result

    def get_experiment_configuration(self, template_file_name):
        """
        Reads and returns the configuration for the specific experiment
        (heat template)

        :param template_file_name: (str) Name of the file for the heat
                        template for which it is requested the configuration

        :return: dict() Configuration parameters and values
        """
        file_name = "{}{}.json".format(self.template_dir, template_file_name)
        with open(file_name) as json_file:
            configuration = json.load(json_file)
        return configuration

    def get_benchmark_name(self, name, instance=0):
        """
        Returns the name to be used for the benchmark/test case (TC).
        This is required since each benchmark/TC could be run more than once
        within the same cycle, with different initialization parameters.
        In order to distinguish between them, a unique name is generated.

        :param name: (str) original name of the benchmark/TC

        :param instance: (int) number of instance already in the queue for
                        this type of benchmark/TC.

        :return: (str) name to be assigned to the benchmark/TC
        """
        if name + "_" + str(instance) in self.benchmark_names:
            instance += 1
            return self.get_benchmark_name(name, instance)
        self.benchmark_names.append(name + "_" + str(instance))
        return name + "_" + str(instance)

    def extract_experiment_name(template_file_name):
        """
        Generates a unique experiment name for a given template.

        :param template_file_name: (str) File name of the template used
                        during the experiment string

        :return: (str) Experiment Name
        """
        strings = template_file_name.split('.')
        return ".".join(strings[:(len(strings)-1)])

    def get_benchmark_class(complete_module_name):
        """
        Returns the classes included in a given module.

        :param complete_module_name: (str) Complete name of the module as
                        returned by get_available_test_cases.

        :return: Class related to the benchmark/TC present in the requested
                        module.
        """
        strings = complete_module_name.split('.')
        class_name = 'experimental_framework.benchmarks.{}'.format(strings[0])
        pkg = __import__(class_name, globals(), locals(), [], -1)
        module = getattr(getattr(pkg, 'benchmarks'), strings[0])
        members = inspect.getmembers(module)
        for m in members:
            if inspect.isclass(m[1]):
                class_name = m[1]("", dict()).__class__.__name__
                if isinstance(m[1]("", dict()), base.BenchmarkBaseClass) and \
                        not class_name == 'BenchmarkBaseClass':
                    return m[1]

    def get_required_benchmarks(required_benchmarks):
        """
        Returns instances of required test cases.

        :param required_benchmarks: (list() of strings) Benchmarks to be
                        executed by the experimental framework.

        :return: list() of BenchmarkBaseClass
        """
        benchmarks = list()
        for b in required_benchmarks:
            class_ = BenchmarkingUnit.get_benchmark_class(b)
            instance = class_("", dict())
            benchmarks.append(instance)
        return benchmarks

#

import sys

from yardstick.benchmark.contexts.base import Context

class NodeContext(Context):
    '''Class that handle nodes info'''

    __context_type__ = "Node"

        self.name = None
        self.file_path = None
        self.nodes = []
        self.controllers = []
        self.computes = []
        self.baremetals = []
        super(self.__class__, self).__init__()

    def init(self, attrs):
        '''initializes itself from the supplied arguments'''
        self.name = attrs["name"]
        self.file_path = attrs.get("file", "/etc/yardstick/nodes/pod.yaml")

        LOG.info("Parsing pod file: %s", self.file_path)

        try:
            with open(self.file_path) as stream:
                cfg = yaml.load(stream)
        except IOError as ioerror:
            sys.exit(ioerror)

        self.nodes.extend(cfg["nodes"])
        self.controllers.extend([node for node in cfg["nodes"]
                                if node["role"] == "Controller"])
        self.computes.extend([node for node in cfg["nodes"]
                             if node["role"] == "Compute"])
        self.baremetals.extend([node for node in cfg["nodes"]
                               if node["role"] == "Baremetal"])
        LOG.debug("Nodes: %r", self.nodes)
        LOG.debug("Controllers: %r", self.controllers)
        LOG.debug("Computes: %r", self.computes)
        LOG.debug("BareMetals: %r", self.baremetals)

    def deploy(self):
        '''don't need to deploy'''
        pass

    def undeploy(self):
        '''don't need to undeploy'''
        pass

    def _get_server(self, attr_name):
        '''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

        if self.name != attr_name.split(".")[1]:
        node_name = attr_name.split(".")[0]
        nodes = [n for n in self.nodes
                 if n["name"] == node_name]
        if len(nodes) == 0:
        elif len(nodes) > 1:
            LOG.error("Duplicate nodes!!!")
            LOG.error("Nodes: %r" % nodes)
            sys.exit(-1)

        node = nodes[0]
        node["name"] = attr_name
        return node

# Copyright (c) 2015 Huawei Technologies Co.,Ltd and other.
#
import re
import os

LOG.setLevel(logging.DEBUG)

class Cyclictest(base.Scenario):
    """Execute cyclictest benchmark on guest vm

  Parameters
    affinity - run thread #N on processor #N, if possible
        type:    int
        unit:    na
        default: 1
    interval - base interval of thread
        type:    int
        unit:    us
        default: 1000
    loops - number of loops, 0 for endless
        type:    int
        unit:    na
    priority - priority of highest prio thread
        type:    int
        unit:    na
        default: 99
    threads - number of threads
        type:    int
        unit:    na
        default: 1
    histogram - dump a latency histogram to stdout after the run
                here set the max time to be tracked
        type:    int
        unit:    ms
        default: 90

    Read link below for more fio args description:
        https://rt.wiki.kernel.org/index.php/Cyclictest
    """
    __scenario_type__ = "Cyclictest"

    TARGET_SCRIPT = "cyclictest_benchmark.bash"
    WORKSPACE = "/root/workspace/"
    REBOOT_CMD_PATTERN = r";\s*reboot\b"

    def _put_files(self, client):
        setup_options = self.scenario_cfg["setup_options"]
        rpm_dir = setup_options["rpm_dir"]
        script_dir = setup_options["script_dir"]
        image_dir = setup_options["image_dir"]
        LOG.debug("Send RPMs from %s to workspace %s" %
                  (rpm_dir, self.WORKSPACE))
        client.put(rpm_dir, self.WORKSPACE, recursive=True)
        LOG.debug("Send scripts from %s to workspace %s" %
                  (script_dir, self.WORKSPACE))
        client.put(script_dir, self.WORKSPACE, recursive=True)
        LOG.debug("Send guest image from %s to workspace %s" %
                  (image_dir, self.WORKSPACE))
        client.put(image_dir, self.WORKSPACE, recursive=True)

    def _connect_host(self):
        host = self.context_cfg["host"]
        user = host.get("user", "root")
        ip = host.get("ip", None)
        key_filename = host.get("key_filename", "~/.ssh/id_rsa")

        LOG.debug("user:%s, host:%s", user, ip)
        self.host = ssh.SSH(user, ip, key_filename=key_filename)
        self.host.wait(timeout=600)

    def _connect_guest(self):

        self.guest = ssh.SSH(user, ip, port=5555, key_filename=key_filename)
        self.guest.wait(timeout=600)

    def _run_setup_cmd(self, client, cmd):
        LOG.debug("Run cmd: %s" % cmd)
        status, stdout, stderr = client.execute(cmd)
        if status:
            if re.search(self.REBOOT_CMD_PATTERN, cmd):
                LOG.debug("Error on reboot")
            else:
                raise RuntimeError(stderr)

    def _run_host_setup_scripts(self, scripts):
        script_dir = os.path.basename(setup_options["script_dir"])

        for script in scripts:
            cmd = "cd %s/%s; export PATH=./:$PATH; %s" %\
                  (self.WORKSPACE, script_dir, script)
            self._run_setup_cmd(self.host, cmd)

                time.sleep(3)
                self._connect_host()

    def _run_guest_setup_scripts(self, scripts):

            self._run_setup_cmd(self.guest, cmd)

                self._connect_guest()

        host_setup_seqs = setup_options["host_setup_seqs"]
        guest_setup_seqs = setup_options["guest_setup_seqs"]

        self._connect_host()
        self._put_files(self.host)
        self._run_host_setup_scripts(host_setup_seqs)

        self._connect_guest()
        self._put_files(self.guest)
        self._run_guest_setup_scripts(guest_setup_seqs)

        # copy script to host
        self.target_script = pkg_resources.resource_filename(
            "yardstick.benchmark.scenarios.compute",
            Cyclictest.TARGET_SCRIPT)
        self.guest.run("cat > ~/cyclictest_benchmark.sh",
                       stdin=open(self.target_script, "rb"))

        default_args = "-m -n -q"

        options = self.scenario_cfg["options"]
        affinity = options.get("affinity", 1)
        interval = options.get("interval", 1000)
        priority = options.get("priority", 99)
        loops = options.get("loops", 1000)
        threads = options.get("threads", 1)
        histogram = options.get("histogram", 90)

        cmd_args = "-a %s -i %s -p %s -l %s -t %s -h %s %s" \
                   % (affinity, interval, priority, loops,
                      threads, histogram, default_args)
        cmd = "bash cyclictest_benchmark.sh %s" % (cmd_args)
        status, stdout, stderr = self.guest.execute(cmd)
        if status:

        result.update(json.loads(stdout))

        if "sla" in self.scenario_cfg:
            sla_error = ""
            for t, latency in result.items():
                if 'max_%s_latency' % t not in self.scenario_cfg['sla']:
                    continue

                sla_latency = int(self.scenario_cfg['sla'][
                                  'max_%s_latency' % t])
                latency = int(latency)
                if latency > sla_latency:
                    sla_error += "%s latency %d > sla:max_%s_latency(%d); " % \
                        (t, latency, t, sla_latency)
            assert sla_error == "", sla_error

def _test():    # pragma: no cover
    '''internal test function'''
    key_filename = pkg_resources.resource_filename("yardstick.resources",
                                                   "files/yardstick_key")
    ctx = {
        "host": {
            "ip": "10.229.47.137",
            "user": "root",
            "key_filename": key_filename
        }
    }

    logger = logging.getLogger("yardstick")
    logger.setLevel(logging.DEBUG)

    options = {
        "affinity": 2,
        "interval": 100,
        "priority": 88,
        "loops": 10000,
        "threads": 2,
        "histogram": 80
    }
    sla = {
        "max_min_latency": 100,
        "max_avg_latency": 500,
        "max_max_latency": 1000,
    }
    args = {
        "options": options,
        "sla": sla
    }
    result = {}

    cyclictest = Cyclictest(args, ctx)
    cyclictest.run(result)
    print result

if __name__ == '__main__':    # pragma: no cover
    _test()

#
#
#

import abc

class BasePacketGenerator:

        pass

    @abc.abstractmethod
    def send_traffic(self):
        """
        Starts the traffic generation.
        According to the specific packet generator it requires prior
        initialization
        """
        raise NotImplementedError("Subclass must implement abstract method")

#
#
#

import instantiation_validation_benchmark as base

NUM_OF_NEIGHBORS = 'num_of_neighbours'
AMOUNT_OF_RAM = 'amount_of_ram'
NUMBER_OF_CORES = 'number_of_cores'

class InstantiationValidationNoisyNeighborsBenchmark(
        base.InstantiationValidationBenchmark):

        base.InstantiationValidationBenchmark.__init__(self, name, params)
        self.template_file = common.get_template_dir() + \
            'stress_workload.yaml'
        self.stack_name = 'neighbour'
        self.neighbor_stack_names = list()

        features = super(InstantiationValidationNoisyNeighborsBenchmark,
                         self).get_features()
        features['description'] = 'Instantiation Validation Benchmark ' \
                                  'with noisy neghbors'
        features['parameters'].append(NUM_OF_NEIGHBORS)
        features['parameters'].append(AMOUNT_OF_RAM)
        features['parameters'].append(NUMBER_OF_CORES)
        features['allowed_values'][NUM_OF_NEIGHBORS] = \
            ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
        features['allowed_values'][NUMBER_OF_CORES] = \
            ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
        features['allowed_values'][AMOUNT_OF_RAM] = \
            ['256M', '1G', '2G', '3G', '4G', '5G', '6G', '7G', '8G', '9G',
             '10G']
        features['default_values'][NUM_OF_NEIGHBORS] = '1'
        features['default_values'][NUMBER_OF_CORES] = '1'
        features['default_values'][AMOUNT_OF_RAM] = '256M'

        super(InstantiationValidationNoisyNeighborsBenchmark, self).init()
        heat_param = dict()
        heat_param['cores'] = self.params['number_of_cores']
        heat_param['memory'] = self.params['amount_of_ram']
        for i in range(0, int(self.params['num_of_neighbours'])):
            stack_name = self.stack_name + str(i)
            common.DEPLOYMENT_UNIT.deploy_heat_template(self.template_file,
                                                        stack_name,
                                                        heat_param)
            self.neighbor_stack_names.append(stack_name)

        # destroy neighbor stacks
        for stack_name in self.neighbor_stack_names:
            common.DEPLOYMENT_UNIT.destroy_heat_template(stack_name)

# Copyright (c) 2015 Huawei Technologies Co.,Ltd. and others
#

from baseattacker import BaseAttacker

class ProcessAttacker(BaseAttacker):

    __attacker_type__ = 'kill-process'

        LOG.debug("config:%s context:%s" % (self._config, self._context))
        host = self._context.get(self._config['host'], None)

        self.connection = ssh.SSH(user, ip, key_filename=key_filename)
        self.connection.wait(timeout=600)
        LOG.debug("ssh host success!")

        self.service_name = self._config['process_name']
        self.fault_cfg = BaseAttacker.attacker_cfgs.get('kill-process')

        self.check_script = self.get_script_fullpath(
            self.fault_cfg['check_script'])
        self.inject_script = self.get_script_fullpath(
            self.fault_cfg['inject_script'])
        self.recovery_script = self.get_script_fullpath(
            self.fault_cfg['recovery_script'])

        if self.check():
            self.setup_done = True

    def check(self):
        exit_status, stdout, stderr = self.connection.execute(
            "/bin/sh -s {0}".format(self.service_name),
            stdin=open(self.check_script, "r"))

        if stdout and "running" in stdout:
            LOG.info("check the envrioment success!")
            return True
        else:
            LOG.error(
                "the host envrioment is error, stdout:%s, stderr:%s" %
                (stdout, stderr))
        return False

    def inject_fault(self):
            stdin=open(self.inject_script, "r"))

    def recover(self):
            "/bin/sh -s {0} ".format(self.service_name),
            stdin=open(self.recovery_script, "r"))

#

# ping scenario

class Ping(base.Scenario):
    """Execute ping between two hosts

    packetsize - number of data bytes to send
        type:    int
        unit:    bytes
        default: 56
    """

    __scenario_type__ = "Ping"

    TARGET_SCRIPT = 'ping_benchmark.bash'

            'yardstick.benchmark.scenarios.networking', Ping.TARGET_SCRIPT)
        host = self.context_cfg['host']
        user = host.get('user', 'ubuntu')
        ip = host.get('ip', None)
        key_filename = host.get('key_filename', '~/.ssh/id_rsa')

        LOG.info("user:%s, host:%s", user, ip)

        self.connection.wait()

        if "options" in self.scenario_cfg:
            options = "-s %s" % \
                self.scenario_cfg['options'].get("packetsize", '56')
        else:
            options = ""

        destination = self.context_cfg['target'].get("ipaddr", '127.0.0.1')

        LOG.debug("ping '%s' '%s'", options, destination)

            "/bin/sh -s {0} {1}".format(destination, options),
            stdin=open(self.target_script, "r"))

        if exit_status != 0:

        if stdout:

        else:
            LOG.error("ping '%s' '%s' timeout", options, destination)

def _test():
    ctx = {
        "host": {
        },
        "target": {
            "ipaddr": "10.229.17.105",
        }
    }

    args = {}
    result = {}

    p = Ping(args, ctx)
    p.run(result)

if __name__ == '__main__':
    _test()

#
import subprocess
import traceback
import basemonitor as basemonitor

def _execute_shell_command(command):
    '''execute shell script with error handling'''
    exitcode = 0
    output = []
    try:
        output = subprocess.check_output(command, shell=True)
    except Exception:
        exitcode = -1
        output = traceback.format_exc()
        LOG.error("exec command '%s' error:\n " % command)
        LOG.error(traceback.format_exc())

    return exitcode, output

class MonitorOpenstackCmd(basemonitor.BaseMonitor):
    """docstring for MonitorApi"""

    __monitor_type__ = "openstack-cmd"

        self.connection = None
        node_name = self._config.get("host", None)
        if node_name:
            host = self._context[node_name]
            ip = host.get("ip", None)
            user = host.get("user", "root")
            key_filename = host.get("key_filename", "~/.ssh/id_rsa")

            self.connection = ssh.SSH(user, ip, key_filename=key_filename)
            self.connection.wait(timeout=600)
            LOG.debug("ssh host success!")

            "ha_tools/check_openstack_cmd.bash")

        self.cmd = self._config["command_name"]

    def monitor_func(self):
        exit_status = 0
        if self.connection:
            exit_status, stdout, stderr = self.connection.execute(
                "/bin/bash -s '{0}'".format(self.cmd),
                stdin=open(self.check_script, "r"))

            LOG.debug("the ret stats: %s stdout: %s stderr: %s" %
                      (exit_status, stdout, stderr))
        else:
            exit_status, stdout = _execute_shell_command(self.cmd)
        if exit_status:
            return False
        return True

    def verify_SLA(self):
        outage_time = self._result.get('outage_time', None)
        LOG.debug("the _result:%s" % self._result)
        max_outage_time = self._config["sla"]["max_outage_time"]
        if outage_time > max_outage_time:
            LOG.info("SLA failure: %f > %f" % (outage_time, max_outage_time))
        else:
            LOG.info("the sla is passed")

    host = {
        "ip": "192.168.235.22",
        "user": "root",
        "key_filename": "/root/.ssh/id_rsa"
    }
    context = {"node1": host}
    monitor_configs = []
    config = {
        'monitor_type': 'openstack-cmd',
        'command_name': 'nova image-list',
        'monitor_time': 1,
        'host': 'node1',
        'sla': {'max_outage_time': 5}
    }
    monitor_configs.append(config)

    p = basemonitor.MonitorMgr()
    p.init_monitors(monitor_configs, context)
    p.start_monitors()
    p.wait_monitors()
    p.verify_SLA()

    _test()

#
#
#

import os

from experimental_framework import heat_manager

MAX_RETRY = 3

class DeploymentUnit:
    """
    This unit is in charge to manage the deployment of the workloads under
    test and any other workloads necessary to
    the benchmark
    """

    def __init__(self, openstack_credentials):
        self.heat_manager = heat_manager.HeatManager(openstack_credentials)
        self.deployed_stacks = list()

    def destroy_heat_template(self, stack_name):
        """
        Destroys a stack
        :param stack_name: Stack of the name to be destroyed (sting)
        """
        try:
            if self.heat_manager.check_stack_status(stack_name):
                if stack_name in self.deployed_stacks:
                    self.deployed_stacks.remove(stack_name)
                self.heat_manager.delete_stack(stack_name)

            status = self.heat_manager.check_stack_status(stack_name)
            while status and 'DELETE_IN_PROGRESS' in status:
                common.LOG.info(status)
                time.sleep(5)
                status = self.heat_manager.check_stack_status(stack_name)
        except:

    def destroy_all_deployed_stacks(self):
        """
        Destroys all the stacks currently deployed
        """
        for stack in self.deployed_stacks:
            if self.heat_manager.is_stack_deployed(stack):
                self.destroy_heat_template(stack)

    def deploy_heat_template(self, template_file, stack_name, parameters,
                             attempt=0):
        """
        Deploys a heat template and in case of failure retries 3 times
        :param template_file: full path file name of the heat template
        :param stack_name: name of the stack to deploy
        :param parameters: parameters to be given to the heat template
        :param attempt: number of current attempt
        :return: returns True in case the creation is completed
                 returns False in case the creation is failed
        """
        if not os.path.isfile(template_file):
            raise ValueError('The specified file does not exist ("' +
                             template_file + '")')
        self.heat_manager.validate_heat_template(template_file)
        try:
            self.heat_manager.create_stack(template_file, stack_name,
                                           parameters)
            deployed = True
        except:
            deployed = False

        if not deployed and 'COMPLETE' in \
                self.heat_manager.check_stack_status(stack_name):
            try:
                self.destroy_heat_template(stack_name)
            except:
                pass

        status = self.heat_manager.check_stack_status(stack_name)
        while status and 'CREATE_IN_PROGRESS' in status:
            time.sleep(5)
        if status and ('FAILED' in status or 'NOT_FOUND' in status):
            if attempt < MAX_RETRY:
                attempt += 1
                try:
                    self.destroy_heat_template(stack_name)
                except Exception as e:
                    common.LOG.debug(e.message)
                    pass
                return self.deploy_heat_template(template_file, stack_name,
                                                 parameters, attempt)
            else:
                try:
                finally:
                    return False
        if self.heat_manager.check_stack_status(stack_name) and \
            'COMPLETE' in self.heat_manager.\
                check_stack_status(stack_name):
            self.deployed_stacks.append(stack_name)

#
# yardstick: this file is copied from rally and slightly modified
import re
import jinja2
import jinja2.meta

class TaskTemplate(object):
    @classmethod
    def render(cls, task_template, **kwargs):
        """Render jinja2 task template to Yardstick input task.

        :param task_template: string that contains template
        :param kwargs: Dict with template arguments
        :returns:rendered template str
        """

        from six.moves import builtins

        ast = jinja2.Environment().parse(task_template)
        required_kwargs = jinja2.meta.find_undeclared_variables(ast)

        missing = set(required_kwargs) - set(kwargs) - set(dir(builtins))
        real_missing = [mis for mis in missing
                        if is_really_missing(mis, task_template)]

        if real_missing:
            multi_msg = ("Please specify next template task arguments:%s")
            single_msg = ("Please specify template task argument:%s")
            raise TypeError((len(real_missing) > 1 and multi_msg or single_msg)
                            % ", ".join(real_missing))
        return jinja2.Template(task_template).render(**kwargs)

def is_really_missing(mis, task_template):
    # Removing variables that have default values from
    # missing. Construction that won't be properly
    # check is {% set x = x or 1}
    if re.search(mis.join(["{%\s*set\s+", "\s*=\s*", "[^\w]+"]),
                 task_template):
    # Also check for a default filter which can show up as
    # a missing variable
    if re.search(mis + "\s*\|\s*default\(", task_template):
    return True

#

'''A runner that runs a specific time before it returns
'''

import os
import multiprocessing

from yardstick.benchmark.runners import base

def _worker_process(queue, cls, method_name, scenario_cfg,
                    context_cfg, aborted):

    sequence = 1

    runner_cfg = scenario_cfg['runner']

    interval = runner_cfg.get("interval", 1)
    duration = runner_cfg.get("duration", 60)
    LOG.info("worker START, duration %d sec, class %s", duration, cls)

    runner_cfg['runner_id'] = os.getpid()

    benchmark = cls(scenario_cfg, context_cfg)
    benchmark.setup()
    method = getattr(benchmark, method_name)

    sla_action = None
    if "sla" in scenario_cfg:
        sla_action = scenario_cfg["sla"].get("action", "assert")

    queue.put({'runner_id': runner_cfg['runner_id'],
               'scenario_cfg': scenario_cfg,
               'context_cfg': context_cfg})

    start = time.time()
    while True:

        LOG.debug("runner=%(runner)s seq=%(sequence)s START" %
                  {"runner": runner_cfg["runner_id"], "sequence": sequence})

        data = {}
        errors = ""

        try:
            method(data)
        except AssertionError as assertion:
            # SLA validation failed in scenario, determine what to do now
            if sla_action == "assert":
                raise
            elif sla_action == "monitor":
                LOG.warning("SLA validation failed: %s" % assertion.args)
                errors = assertion.args
            errors = traceback.format_exc()
            LOG.exception(e)

        time.sleep(interval)

        benchmark_output = {
            'timestamp': time.time(),
            'sequence': sequence,
            'data': data,
            'errors': errors
        }

        record = {'runner_id': runner_cfg['runner_id'],
                  'benchmark': benchmark_output}

        queue.put(record)

        LOG.debug("runner=%(runner)s seq=%(sequence)s END" %

        sequence += 1

        if (errors and sla_action is None) or \
                (time.time() - start > duration or aborted.is_set()):
            LOG.info("worker END")
            break

    benchmark.teardown()

class DurationRunner(base.Runner):
    '''Run a scenario for a certain amount of time

If the scenario ends before the time has elapsed, it will be started again.

    duration - amount of time the scenario will be run for
        type:    int
        unit:    seconds
        default: 1 sec
    interval - time to wait between each scenario invocation
        type:    int
    '''
    __execution_type__ = 'Duration'

    def _run_benchmark(self, cls, method, scenario_cfg, context_cfg):
        self.process = multiprocessing.Process(
            target=_worker_process,
            args=(self.result_queue, cls, method, scenario_cfg,
                  context_cfg, self.aborted))
        self.process.start()

#

""" Scenario base class
"""

import yardstick.common.utils as utils

class Scenario(object):

        ''' default impl for scenario setup '''
        pass

    def run(self, args):
        ''' catcher for not implemented run methods in subclasses '''
        raise RuntimeError("run method not implemented")

        ''' default impl for scenario teardown '''
        pass

    def get_types():
        '''return a list of known runner type (class) names'''
        scenarios = []
        for scenario in utils.itersubclasses(Scenario):
            scenarios.append(scenario)
        return scenarios

    def get_cls(scenario_type):
        '''return class of specified type'''
            if scenario_type == scenario.__scenario_type__:
                return scenario

        raise RuntimeError("No such scenario type %s" % scenario_type)

    def get(scenario_type):
        """Returns instance of a scenario runner for execution type.
        """
                return scenario.__module__ + "." + scenario.__name__

#

import importlib

from oslo_config import cfg

from yardstick.benchmark.scenarios import base as base_scenario
from yardstick.dispatcher.base import Base as DispatcherBase

CONF = cfg.CONF

def _output_serializer_main(filename, queue):
    '''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
    dispatcher = DispatcherBase.get(config)

        # blocks until data becomes available
        record = queue.get()
        if record == '_TERMINATE_':
            dispatcher.flush_result_data()
            break
        else:
            dispatcher.record_result_data(record)

    output = []
    try:
        log.error("exec command '%s' error:\n " % command)
        log.error(traceback.format_exc())

def _single_action(seconds, command, queue):
    '''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)
    ret_code, data = _execute_shell_command(command)
    if ret_code < 0:
        log.error("single action error! command:%s" % command)
        queue.put({'single-action-data': data})
        return
    log.debug("single action data: \n%s" % data)
    queue.put({'single-action-data': data})

def _periodic_action(interval, command, queue):
    '''entrypoint for the periodic action process'''
    log.debug("periodic action, fires every: %d seconds", interval)
    time_spent = 0
        time_spent += interval
        log.debug("periodic action, executing command: '%s'", command)
        ret_code, data = _execute_shell_command(command)
        if ret_code < 0:
            log.error("periodic action error! command:%s", command)
            queue.put({'periodic-action-data': data})
            break
        log.debug("periodic action data: \n%s" % data)
        queue.put({'periodic-action-data': data})

class Runner(object):
    queue = None
    dump_process = None
    runners = []

    def get_cls(runner_type):
        for runner in utils.itersubclasses(Runner):
            if runner_type == runner.__execution_type__:
                return runner
        raise RuntimeError("No such runner_type %s" % runner_type)

        types = []
            types.append(runner)
        return types

    def get(config):
        """
        # if there is no runner, start the output serializer subprocess
        if len(Runner.runners) == 0:
            log.debug("Starting dump process file '%s'" %
                      config["output_filename"])
            Runner.queue = multiprocessing.Queue()
            Runner.dump_process = multiprocessing.Process(
                target=_output_serializer_main,
                name="Dumper",
                args=(config["output_filename"], Runner.queue))
            Runner.dump_process.start()

        return Runner.get_cls(config["type"])(config, Runner.queue)

    def release_dump_process():
        '''Release the dumper process'''
        log.debug("Stopping dump process")
        if Runner.dump_process:
            Runner.queue.put('_TERMINATE_')
            Runner.dump_process.join()
            Runner.dump_process = None

    def release(runner):
        '''Release the runner'''
        if runner in Runner.runners:
            Runner.runners.remove(runner)

        # if this was the last runner, stop the output serializer subprocess
            Runner.release_dump_process()

    def terminate(runner):
        '''Terminate the runner'''
        if runner.process and runner.process.is_alive():
            runner.process.terminate()

    def terminate_all():
        '''Terminate all runners (subprocesses)'''
        log.debug("Terminating all runners")

        # release dumper process as some errors before any runner is created
            return

        for runner in Runner.runners:
            log.debug("Terminating runner: %s", runner)
            if runner.process:
                runner.process.terminate()
                runner.process.join()
            if runner.periodic_action_process:
                log.debug("Terminating periodic action process")
                runner.periodic_action_process.terminate()
                runner.periodic_action_process = None
            Runner.release(runner)

    def __init__(self, config, queue):
        self.config = config
        self.periodic_action_process = None
        self.result_queue = queue
        self.process = None
        self.aborted = multiprocessing.Event()
        Runner.runners.append(self)

    def run_post_stop_action(self):
        '''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)
            ret_code, data = _execute_shell_command(command)
            if ret_code < 0:
                log.error("post action error! command:%s", command)
                self.result_queue.put({'post-stop-action-data': data})
                return
            log.debug("post-stop data: \n%s" % data)
            self.result_queue.put({'post-stop-action-data': data})

    def run(self, scenario_cfg, context_cfg):
        scenario_type = scenario_cfg["type"]
        class_name = base_scenario.Scenario.get(scenario_type)
        path_split = class_name.split(".")
        module_path = ".".join(path_split[:-1])
        module = importlib.import_module(module_path)
        cls = getattr(module, path_split[-1])

        self.config['object'] = class_name
        self.aborted.clear()

        # run a potentially configured pre-start action
        if "pre-start-action" in self.config:
            command = self.config["pre-start-action"]["command"]
            log.debug("pre start action: command: '%s'" % command)
                log.error("pre-start action error! command:%s", command)
                self.result_queue.put({'pre-start-action-data': data})
                return
            log.debug("pre-start data: \n%s" % data)
            self.result_queue.put({'pre-start-action-data': data})

        if "single-shot-action" in self.config:
            single_action_process = multiprocessing.Process(
                target=_single_action,
                name="single-shot-action",
                args=(self.config["single-shot-action"]["after"],
                      self.config["single-shot-action"]["command"],
                      self.result_queue))
            single_action_process.start()

        if "periodic-action" in self.config:
            self.periodic_action_process = multiprocessing.Process(
                target=_periodic_action,
                name="periodic-action",
                args=(self.config["periodic-action"]["interval"],
                      self.config["periodic-action"]["command"],
            self.periodic_action_process.start()

        self._run_benchmark(cls, "run", scenario_cfg, context_cfg)

    def abort(self):
        '''Abort the execution of a scenario'''
        self.aborted.set()

    def join(self, timeout=None):
        self.process.join(timeout)
        if self.periodic_action_process:
            self.periodic_action_process.terminate()
            self.periodic_action_process = None

        self.run_post_stop_action()
        return self.process.exitcode

#!/usr/bin/env python

#

""" yardstick - command line tool for managing benchmarks

    Example invocation:
    $ yardstick task start samples/ping.yaml

    Servers are the same as VMs (Nova calls them servers in the API)

    Many tests use a client/server architecture. A test client is configured
    to use a specific test server e.g. using an IP address. This is true for
    example iperf. In some cases the test server is included in the kernel
    (ping, pktgen) and no additional software is needed on the server. In other
    cases (iperf) a server process needs to be installed and started.

    One server is required to host the test client program (such as ping or
    iperf). In the task file this server is called host.

    A server can be the _target_ of a test client (think ping destination
    argument). A target server is optional but needed in most test scenarios.
    In the task file this server is called target. This is probably the same
    as DUT in existing terminology.

    Existing terminology:
    https://www.ietf.org/rfc/rfc1242.txt (throughput/latency)
    https://www.ietf.org/rfc/rfc2285.txt (DUT/SUT)

    New terminology:
    NFV TST

"""
import sys

from yardstick.cmd.cli import YardstickCLI

def main():
    '''yardstick main'''
    YardstickCLI().main(sys.argv[1:])

    main()

#
from yardstick.benchmark.scenarios.availability.monitor import basemonitor
from yardstick.benchmark.scenarios.availability.attacker import baseattacker

class ServiceHA(base.Scenario):
    """TODO: docstring of ServiceHA
    """
    __scenario_type__ = "ServiceHA"

        LOG.debug(
            "scenario_cfg:%s context_cfg:%s" %
            (scenario_cfg, context_cfg))

        nodes = self.context_cfg.get("nodes", None)
        if nodes is None:
            LOG.error("the nodes info is none")
            return

        self.attackers = []
        attacker_cfgs = self.scenario_cfg["options"]["attackers"]
        for attacker_cfg in attacker_cfgs:
            attacker_cls = baseattacker.BaseAttacker.get_attacker_cls(
                attacker_cfg)
            attacker_ins = attacker_cls(attacker_cfg, nodes)
            attacker_ins.setup()
            self.attackers.append(attacker_ins)

        monitor_cfgs = self.scenario_cfg["options"]["monitors"]

        self.monitorMgr = basemonitor.MonitorMgr()
        self.monitorMgr.init_monitors(monitor_cfgs, nodes)

            LOG.error("The setup not finished!")
            return

        self.monitorMgr.start_monitors()
        LOG.info("monitor start!")

        for attacker in self.attackers:
            attacker.inject_fault()

        self.monitorMgr.wait_monitors()
        LOG.info("monitor stop!")

        sla_pass = self.monitorMgr.verify_SLA()
        assert sla_pass is True, "the test cases is not pass the SLA"

        return

        '''scenario teardown'''
            attacker.recover()

    host = {
        "ip": "10.20.0.5",
    }
    ctx = {"nodes": {"node1": host}}
    attacker_cfg = {
        "fault_type": "kill-process",
        "process_name": "nova-api",
        "host": "node1"
    }
    attacker_cfgs = []
    attacker_cfgs.append(attacker_cfg)
    monitor_cfg = {
        "monitor_cmd": "nova image-list"
    }
    monitor_cfgs = []
    monitor_cfgs.append(monitor_cfg)

    options = {
        "attackers": attacker_cfgs,
        "wait_time": 10,
        "monitors": monitor_cfgs
    }
    sla = {"outage_time": 5}
    args = {"options": options, "sla": sla}

    print "create instance"
    terstInstance = ServiceHA(args, ctx)

    terstInstance.setup()
    result = {}
    terstInstance.run(result)

    terstInstance.teardown()

    _test()

#

'''
Command-line interface to yardstick
'''

import os
import sys

from pkg_resources import get_distribution
from argparse import RawDescriptionHelpFormatter

from yardstick.cmd.commands import task
from yardstick.cmd.commands import runner
from yardstick.cmd.commands import scenario

cli_opts = [
    cfg.BoolOpt('debug',
                short='d',
                default=False,
                help='increase output verbosity to debug'),
    cfg.BoolOpt('verbose',
                short='v',
                help='increase output verbosity to info')
]
CONF.register_cli_opts(cli_opts)

CONFIG_SEARCH_PATHS = [sys.prefix + "/etc/yardstick",
                       "~/.yardstick",
                       "/etc/yardstick"]

def find_config_files(path_list):
    for path in path_list:
        abspath = os.path.abspath(os.path.expanduser(path))
        confname = abspath + "/yardstick.conf"
        if os.path.isfile(confname):
            return [confname]

    return None

class YardstickCLI():
    '''Command-line interface to yardstick'''

    # Command categories
    categories = {
        'task': task.TaskCommands,
        'runner': runner.RunnerCommands,
        'scenario': scenario.ScenarioCommands
    }

        self._version = 'yardstick version %s ' % \
            get_distribution('yardstick').version

    def _find_actions(self, subparsers, actions_module):
        '''find action methods'''
        # Find action methods inside actions_module and
        # add them to the command parser.
        # The 'actions_module' argument may be a class
        # or module. Action methods start with 'do_'
        for attr in (a for a in dir(actions_module) if a.startswith('do_')):
            command = attr[3:].replace('_', '-')
            callback = getattr(actions_module, attr)
            desc = callback.__doc__ or ''
            arguments = getattr(callback, 'arguments', [])
            subparser = subparsers.add_parser(
                command,
                description=desc
            )
            for (args, kwargs) in arguments:
                subparser.add_argument(*args, **kwargs)
            subparser.set_defaults(func=callback)

    def _add_command_parsers(self, categories, subparsers):
        '''add commands to command-line parser'''
        for category in categories:
            command_object = categories[category]()
            desc = command_object.__doc__ or ''
                category, description=desc,
                formatter_class=RawDescriptionHelpFormatter
            )
            subparser.set_defaults(command_object=command_object)
            cmd_subparsers = subparser.add_subparsers(title='subcommands')
            self._find_actions(cmd_subparsers, command_object)

    def main(self, argv):
        '''run the command line interface'''

        # register subcommands to parse additional command line arguments
        def parser(subparsers):
            self._add_command_parsers(YardstickCLI.categories, subparsers)

        category_opt = cfg.SubCommandOpt("category",
                                         title="Command categories",
                                         help="Available categories",
                                         handler=parser)
        CONF.register_cli_opt(category_opt)

        # load CLI args and config files
        CONF(argv, project="yardstick", version=self._version,
             default_config_files=find_config_files(CONFIG_SEARCH_PATHS))

        # handle global opts
        logger = logging.getLogger('yardstick')
        logger.setLevel(logging.WARNING)

        if CONF.verbose:
            logger.setLevel(logging.INFO)

        if CONF.debug:
            logger.setLevel(logging.DEBUG)

        # dispatch to category parser
        func = CONF.category.func
        func(CONF.category)

#
import os

monitor_conf_path = pkg_resources.resource_filename(
    "yardstick.benchmark.scenarios.availability",
    "monitor_conf.yaml")

class MonitorMgr(object):
    """docstring for MonitorMgr"""
        self._monitor_list = []

    def init_monitors(self, monitor_cfgs, context):
        LOG.debug("monitorMgr config: %s" % monitor_cfgs)

        for monitor_cfg in monitor_cfgs:
            monitor_type = monitor_cfg["monitor_type"]
            monitor_cls = BaseMonitor.get_monitor_cls(monitor_type)
            monitor_ins = monitor_cls(monitor_cfg, context)

            self._monitor_list.append(monitor_ins)

    def start_monitors(self):
        for _monotor_instace in self._monitor_list:
            _monotor_instace.start_monitor()

    def wait_monitors(self):
        for monitor in self._monitor_list:
            monitor.wait_monitor()

        sla_pass = True
            sla_pass = sla_pass & monitor.verify_SLA()
        return sla_pass

class BaseMonitor(multiprocessing.Process):
    """docstring for BaseMonitor"""

    def __init__(self, config, context):
        multiprocessing.Process.__init__(self)
        self._config = config
        self._context = context
        self._queue = multiprocessing.Queue()
        self._event = multiprocessing.Event()

    def get_monitor_cls(monitor_type):
        '''return monitor class of specified type'''

        for monitor in utils.itersubclasses(BaseMonitor):
            if monitor_type == monitor.__monitor_type__:
                return monitor
        raise RuntimeError("No such monitor_type %s" % monitor_type)

    def get_script_fullpath(self, path):
        base_path = os.path.dirname(monitor_conf_path)
        return os.path.join(base_path, path)

        self.setup()
        monitor_time = self._config.get("monitor_time", 0)

        total_time = 0
        outage_time = 0
        total_count = 0
        outage_count = 0
        first_outage = 0
        last_outage = 0

        begin_time = time.time()
        while True:
            total_count = total_count + 1

            one_check_begin_time = time.time()
            exit_status = self.monitor_func()
            one_check_end_time = time.time()

            if exit_status is False:
                outage_count = outage_count + 1

                outage_time = outage_time + (
                    one_check_end_time - one_check_begin_time)

                if not first_outage:
                    first_outage = one_check_begin_time

                last_outage = one_check_end_time

            if self._event.is_set():
                LOG.debug("the monitor process stop")
                break

            if one_check_end_time - begin_time > monitor_time:
                LOG.debug("the monitor max_time finished and exit!")
                break

        total_time = end_time - begin_time

        self._queue.put({"total_time": total_time,
                         "outage_time": last_outage-first_outage,
                         "total_count": total_count,
                         "outage_count": outage_count})

    def start_monitor(self):
        self.start()

    def wait_monitor(self):
        self.join()
        self._result = self._queue.get()
        LOG.debug("the monitor result:%s" % self._result)

    def setup(self):  # pragma: no cover
        pass

    def monitor_func(self):  # pragma: no cover
        pass

        pass

#
#
#

class TestBenchmark(base.BenchmarkBaseClass):

        pass

        pass

        features['description'] = 'Test Benchmark'
        features['parameters'] = list()

        time.sleep(10)
        return dict()

#

import os

import experimental_framework.api as api

class VtcInstantiationValidation(base.Scenario):
    """
    __scenario_type__ = "vtc_instantiation_validation"

        }
        }
        }

        test_case['name'] = 'instantiation_validation_benchmark.' \
                            'InstantiationValidationBenchmark'
        test_case['params']['throughput'] = '1'

        try:

#
#
#

import os
import base_packet_generator
from experimental_framework.constants import conf_file_sections as conf_file

class DpdkPacketGenerator(base_packet_generator.BasePacketGenerator):

        base_packet_generator.BasePacketGenerator.__init__(self)
        self.command = ''
        self.directory = ''
        self.program_name = ''
        self.command_options = list()
        self.dpdk_interfaces = -1

        '''
        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()
        self._init_physical_nics(self.dpdk_interfaces, dpdk_vars)
        common.run_command(self.command)
        self._finalize_physical_nics(self.dpdk_interfaces, dpdk_vars)
        DpdkPacketGenerator._chdir(current_dir)

    def init_dpdk_pktgen(self,
                         dpdk_interfaces,
                         lua_script='generic_test.lua',
                         pcap_file_0='',
                         pcap_file_1='',
                         vlan_0='',
                         vlan_1=''):
        """
        Initializes internal parameters and configuration of the module.
        Needs to be called before the send_traffic
        :param dpdk_interfaces: Number of interfaces to be used (type: int)
        :param lua_script: Full path of the Lua script to be used (type: str)
        :param pcap_file_0: Full path of the Pcap file to be used for port 0
                            (type: str)
        :param pcap_file_1: Full path of the Pcap file to be used for port 1
        :param vlan_0: VLAN tag to be used for port 0 (type: str)
        :param vlan_1: VLAN tag to be used for port 1 (type: str)
        :return:
        """
        # Input Validation
        if pcap_file_0 and not vlan_0:
            message = 'In order to use NIC_0, the parameter vlan_0 is required'
            raise ValueError(message)
        if dpdk_interfaces > 1 and pcap_file_1 and not vlan_1:
            message = 'in order to use NIC_1, the parameter vlan_1 is required'

        self.dpdk_interfaces = dpdk_interfaces
        vars = common.get_dpdk_pktgen_vars()

        lua_directory = common.get_base_dir()
        lua_directory += fp.EXPERIMENTAL_FRAMEWORK_DIR
        lua_directory += fp.DPDK_PKTGEN_DIR

        pcap_directory = common.get_base_dir()
        pcap_directory += fp.EXPERIMENTAL_FRAMEWORK_DIR
        pcap_directory += fp.PCAP_DIR

        DpdkPacketGenerator._init_input_validation(pcap_file_0,
                                                   pcap_file_1,
                                                   lua_script,
                                                   pcap_directory,
                                                   lua_directory,
                                                   vars)

        self.directory = vars[conf_file.CFSP_DPDK_PKTGEN_DIRECTORY]
        self.program_name = vars[conf_file.CFSP_DPDK_PROGRAM_NAME]

        core_nics = DpdkPacketGenerator.\
            _get_core_nics(dpdk_interfaces, vars[conf_file.CFSP_DPDK_COREMASK])
        self.command_options = ['-c ' + vars[conf_file.CFSP_DPDK_COREMASK],
                                '-n ' + vars[conf_file.
                                             CFSP_DPDK_MEMORY_CHANNEL],
                                '--proc-type auto',
                                '--file-prefix pg',
                                '-- -T',
                                '-P',
                                '-m "' + core_nics + '"',
                                '-f ' + lua_directory + lua_script,
                                '-s 0:' + pcap_directory + pcap_file_0]

        if pcap_file_1:
            self.command_options.append('-s 1:' + pcap_directory + pcap_file_1)

        # Avoid to show the output of the packet generator
        self.command_options.append('> /dev/null')
        # Prepare the command to be invoked
        self.command = 'sudo ' + self.directory + self.program_name
        for opt in self.command_options:
            self.command += (' ' + opt)
        if pcap_file_0 and vlan_0:
            DpdkPacketGenerator._change_vlan(pcap_directory, pcap_file_0,
                                             vlan_0)
        if pcap_file_1 and vlan_1:
            DpdkPacketGenerator._change_vlan(pcap_directory, pcap_file_1,
                                             vlan_1)

    def _get_core_nics(dpdk_interfaces, coremask):
        """
        Retruns the core_nics string to be used in the dpdk pktgen command
        :param dpdk_interfaces: number of interfaces to be used in the pktgen
                                (type: int)
        :param coremask: hexadecimal value representing the cores assigned to
                         the pktgen (type: str)
        :return: Returns the core nics param for pktgen (type: str)
        """
        if dpdk_interfaces == 1:
            return DpdkPacketGenerator._cores_configuration(coremask, 1, 2, 0)
        elif dpdk_interfaces == 2:
            return DpdkPacketGenerator._cores_configuration(coremask, 1, 2, 2)
        raise ValueError("This framework only supports two ports to generate "
                         "traffic")

    def _change_vlan(pcap_directory, pcap_file, vlan):
        common.LOG.info("Changing VLAN Tag on Packet: " + pcap_file +
                        ". New VLAN Tag is " + vlan)
        command = "chmod +x {}{}".format(pcap_directory, 'vlan_tag.sh')
        common.run_command(command)
        command = pcap_directory + 'vlan_tag.sh '
        command += pcap_directory + pcap_file + ' ' + vlan

    def _init_input_validation(pcap_file_0, pcap_file_1, lua_script,
                               pcap_directory, lua_directory, variables):
        """
        Validates the input parameters values and raises an exception if
        there is any non valid param
        :param pcap_file_0: file name of the pcap file for NIC 0
                            (it does not includes the path) (type: str)
        :param pcap_file_1: file name of the pcap file for NIC 1
        :param lua_script: file name of the lua script to be used
        :param pcap_directory: directory where the pcap files are located
                               (type: str)
        :param lua_directory:  directory where the lua scripts are located
        :param variables: variables for the packet gen from configuration file
                          (type: dict)
        """
        if not pcap_directory:
            raise ValueError("pcap_directory not provided correctly")
        if not pcap_file_0:
            raise ValueError("pcap_file_0 not provided correctly")
        if not pcap_file_1:
            raise ValueError("pcap_file_1 not provided correctly")
        if not lua_script:
            raise ValueError("lua_script not provided correctly")
        if not os.path.isfile(pcap_directory + pcap_file_0):
            raise ValueError("The file " + pcap_file_0 + " does not exist")
        if not os.path.isfile(pcap_directory + pcap_file_1):
            raise ValueError("The file " + pcap_file_1 + " does not exist")
        if not os.path.isfile(lua_directory + lua_script):
            raise ValueError("The file " + lua_script + " does not exist")
        for var in [conf_file.CFSP_DPDK_PKTGEN_DIRECTORY,
                    conf_file.CFSP_DPDK_PROGRAM_NAME,
                    conf_file.CFSP_DPDK_COREMASK,
                    conf_file.CFSP_DPDK_MEMORY_CHANNEL]:
            if var not in variables.keys() or (var in variables.keys() and
               variables[var] is ''):
                raise ValueError("The variable " + var + " does not exist")

    def _chdir(directory):
        """
        Changes the current directory
        :param directory: directory where to move (type: str)
        """
        os.chdir(directory)

    def _init_physical_nics(self, dpdk_interfaces, dpdk_vars):
        """
        Initializes the physical interfaces
        :param dpdk_vars: variables from config file related to DPDK pktgen
        """
        if not dpdk_interfaces == 1 and not dpdk_interfaces == 2:
            raise ValueError('The number of NICs can be 1 or 2')
        # Initialize NIC 1
        # bus_address_1 = dpdk_vars[conf_file.CFSP_DPDK_BUS_SLOT_NIC_1]
        interface_1 = dpdk_vars[conf_file.CFSP_DPDK_NAME_IF_1]
        common.run_command('sudo ifconfig ' + interface_1 + ' down')
        common.run_command('sudo ' +
                           dpdk_vars[conf_file.CFSP_DPDK_DPDK_DIRECTORY] +
                           'tools/dpdk_nic_bind.py --unbind ' +
                           dpdk_vars[conf_file.CFSP_DPDK_BUS_SLOT_NIC_1])
                           'tools/dpdk_nic_bind.py --bind=igb_uio ' +
        if dpdk_interfaces == 2:
            # Initialize NIC 2
            # bus_address_2 = dpdk_vars[conf_file.CFSP_DPDK_BUS_SLOT_NIC_2]
            interface_2 = dpdk_vars[conf_file.CFSP_DPDK_NAME_IF_2]
            common.run_command('sudo ifconfig ' + interface_2 + ' down')
            common.run_command('sudo ' +
                               dpdk_vars[conf_file.CFSP_DPDK_DPDK_DIRECTORY] +
                               'tools/dpdk_nic_bind.py --unbind ' +
                               dpdk_vars[conf_file.CFSP_DPDK_BUS_SLOT_NIC_2])
                               'tools/dpdk_nic_bind.py --bind=igb_uio ' +

    def _finalize_physical_nics(self, dpdk_interfaces, dpdk_vars):
        """
        Finalizes the physical interfaces
        """
            raise ValueError('No interfaces have been indicated for packet '
                             'generation usage. Please specify one or two '
                             'NICs')
        time.sleep(5)
                           'tools/dpdk_nic_bind.py --bind=ixgbe ' +
        common.run_command('sudo ifconfig ' +
                           dpdk_vars[conf_file.CFSP_DPDK_NAME_IF_1] +
                           ' up')
                               'tools/dpdk_nic_bind.py --bind=ixgbe ' +
            common.run_command('sudo ifconfig ' +
                               dpdk_vars[conf_file.CFSP_DPDK_NAME_IF_2] +
                               ' up')

    def _cores_configuration(coremask, pktgen_cores=1, nic_1_cores=2,
                             nic_2_cores=2):
        """
        Calculation of the core_nics parameter which is necessary for the
        packet generator to run

        :param coremask: Hexadecimal value indicating the cores to be assigned
                         to the whole dpdk pktgen software (included the
                         ones to receive and send packets from NICs)
                         (type: str)
        :param pktgen_cores: number of cores to be assigned to main thread of
                             the pktgen directly
        :param nic_1_cores: number of cores to be assigned to the first NIC
        :param nic_2_nics: number of cores to be assigned to the second NIC
        :return: returns the core_nics parameter (type: str)
        """
        required_cores = pktgen_cores + nic_1_cores + nic_2_cores
        bin_coremask = bin(int(coremask, 16))[2:]
        index = len(bin_coremask)
        cores = []
        while index >= 0:
            index -= 1
            if bin_coremask[index] == '1':
                core = index
                cores.append(core)
        if len(cores) < required_cores:
            raise ValueError('The provided coremask does not provide'
                             ' enough cores for the DPDK packet generator')
        # ret_pktgen_cores = []
        ret_nic_1_cores = []
        ret_nic_2_cores = []
        current_core = 0

        if nic_2_cores > 0:
            ret_nic_2_cores.append(cores[current_core])
            current_core += 1
        if nic_2_cores > 1:

        if nic_1_cores > 0:
            ret_nic_1_cores.append(cores[current_core])
        if nic_1_cores > 1:

        # for n in range(0, pktgen_cores):
        #     ret_pktgen_cores.append(cores[n])
        # for n in range(0, nic_1_cores):
        #     ret_nic_1_cores.append(cores[pktgen_cores + n])
        # for n in range(0, nic_2_cores):
        #     ret_nic_2_cores.append(cores[pktgen_cores + nic_1_cores + n])

        corenics = ''
            if nic_1_cores < 2:
                corenics += str(ret_nic_1_cores[0]) + '.0'
            if nic_1_cores == 2:
                corenics += '[' + str(ret_nic_1_cores[0])
                corenics += ':' + str(ret_nic_1_cores[1])
                corenics += '].0'
            corenics += ','
            if nic_2_cores < 2:
                corenics += str(ret_nic_2_cores[0]) + '.1'
            if nic_2_cores == 2:
                corenics += '[' + str(ret_nic_2_cores[0])
                corenics += ':' + str(ret_nic_2_cores[1])
                corenics += '].1'
        return corenics

#

class Parser(base.Scenario):
    """running Parser Yang-to-Tosca module as a tool
    validating output against expected outcome

    more info https://wiki.opnfv.org/parser
    """
    __scenario_type__ = "Parser"

    SETUP_SCRIPT = "parser_setup.sh"
    TEARDOWN_SCRIPT = "parser_teardown.sh"
    PARSER_SCRIPT = "parser.sh"

        """scenario setup"""
            "yardstick.benchmark.scenarios.parser",
            Parser.SETUP_SCRIPT)
        cmd = "%s" % (self.setup_script)

        subprocess.call(cmd, shell=True)

        """execute the translation"""
        yangfile = options.get("yangfile", '~/yardstick/samples/yang.yaml')
        toscafile = options.get("toscafile", '~/yardstick/samples/tosca.yaml')

        self.parser_script = pkg_resources.resource_filename(
            Parser.PARSER_SCRIPT)

        cmd1 = "%s %s %s" % (self.parser_script, yangfile, toscafile)
        cmd2 = "chmod 777 %s" % (self.parser_script)
        subprocess.call(cmd2, shell=True)
        output = subprocess.call(cmd1, shell=True, stdout=subprocess.PIPE)
        print "yangtotosca finished"

        result['yangtotosca'] = "success" if output == 0 else "fail"

        ''' for scenario teardown remove parser and pyang '''
            Parser.TEARDOWN_SCRIPT)
        subprocess.call(self.teardown_script, shell=True)
        self.teardown_done = True

    pass

    _test()

#

'''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).
'''

import os
import itertools

    if 'options' in scenario_cfg:
        options = scenario_cfg['options']
    else:  # options must be instatiated if not present in yaml
        options = {}
        scenario_cfg['options'] = options

    LOG.info("worker START, class %s", cls)

    # To both be able to include the stop value and handle backwards stepping
    def margin(start, stop):
        return -1 if start > stop else 1

    param_iters = \
        [xrange(d['start'], d['stop'] + margin(d['start'], d['stop']),
                d['step']) for d in runner_cfg['iterators']]
    param_names = [d['name'] for d in runner_cfg['iterators']]

    iter_type = runner_cfg.get("iter_type", "nested_for_loops")

    if iter_type == 'nested_for_loops':
        # Create a complete combination set of all parameter lists
        loop_iter = itertools.product(*param_iters)
    elif iter_type == 'tuple_loops':
        # Combine each i;th index of respective parameter list
        loop_iter = itertools.izip(*param_iters)
    else:
        LOG.warning("iter_type unrecognized: %s", iter_type)
        raise

    # Populate options and run the requested method for each value combination
    for comb_values in loop_iter:

        if aborted.is_set():
            break

        for i, value in enumerate(comb_values):
            options[param_names[i]] = value

        data = {}
        errors = ""

        try:
                raise

        }

        if (errors and sla_action is None):
            break

    LOG.info("worker END")

class ArithmeticRunner(base.Runner):
    '''Run a scenario arithmetically stepping input value(s)

        type:    int
    iter_type: - Iteration type of input parameter(s): nested_for_loops
                 or tuple_loops
        type:    string
        unit:    na
        default: nested_for_loops
    -
      name - name of scenario option that will be increased for each invocation
          type:    string
          unit:    na
          default: na
      start - value to use in first invocation of scenario
          type:    int
          unit:    na
          default: none
      stop - value indicating end of invocation. Can be set to same
             value as start for one single value.
          type:    int
          unit:    na
      step - value added to start value in next invocation of scenario.
             Must not be set to zero. Can be set negative if start > stop
          type:    int
          unit:    na
    -
      name - and so on......
    '''

    __execution_type__ = 'Arithmetic'

#

'''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.
'''

import os

    arg_name = runner_cfg.get('scenario_option_name')
    sequence_values = runner_cfg.get('sequence')

    if 'options' not in scenario_cfg:
        scenario_cfg['options'] = {}

    options = scenario_cfg['options']

    LOG.info("worker START, sequence_values(%s, %s), class %s",
             arg_name, sequence_values, cls)

    for value in sequence_values:
        options[arg_name] = value

        data = {}
        errors = ""

        try:
                raise

        }

        if (errors and sla_action is None) or aborted.is_set():
            break

class SequenceRunner(base.Runner):
    '''Run a scenario by changing an input value defined in a list

        type:    int
    scenario_option_name - name of the option that is increased each invocation
        unit:    na
        default: none
    sequence - list of values which are executed in their respective scenarios
        type:    [int]
        unit:    na
    '''

    __execution_type__ = 'Sequence'

#

""" Logical model

"""

class Object(object):
    '''Base class for classes in the logical model
    Contains common attributes and methods
    '''
    def __init__(self, name, context):
        # model identities and reference

        # stack identities
        self.stack_name = None
        self.stack_id = None

    @property
    def dn(self):
        '''returns distinguished name for object'''
        return self.name + "." + self._context.name

class PlacementGroup(Object):
    '''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):
        if policy not in ["affinity", "availability"]:
            raise ValueError("placement group '%s', policy '%s' is not valid" %
                             (name, policy))
        self.members = set()
        self.stack_name = context.name + "-" + name
        self.policy = policy
        PlacementGroup.map[name] = self

    def add_member(self, name):
        self.members.add(name)

    def get(name):
        if name in PlacementGroup.map:
            return PlacementGroup.map[name]
        else:

class Router(Object):
    '''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)

        self.stack_name = context.name + "-" + network_name + "-" + self.name
        self.stack_if_name = self.stack_name + "-if0"
        self.external_gateway_info = external_gateway_info

class Network(Object):
    '''Class that represents a network in the logical model'''
    list = []

    def __init__(self, name, context, attrs):
        self.stack_name = context.name + "-" + self.name
        self.subnet_stack_name = self.stack_name + "-subnet"
        self.subnet_cidr = attrs.get('cidr', '10.0.1.0/24')
        self.router = None

        if "external_network" in attrs:
            self.router = Router("router", self.name,
                                 context, attrs["external_network"])

        Network.list.append(self)

    def has_route_to(self, network_name):
        '''determines if this network has a route to the named network'''
        if self.router and self.router.external_gateway_info == network_name:

    def find_by_route_to(external_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

    def find_external_network():
        '''return the name of an external network some network in this
        context has a route to'''
            if network.router:
                return network.router.external_gateway_info
        return None

class Server(Object):
    '''Class that represents a server in the logical model'''
    list = []

        self.stack_name = self.name + "." + context.name
        self.keypair_name = context.keypair_name
        self.secgroup_name = context.secgroup_name
        self.user = context.user
        self.context = context
        self.public_ip = None
        self.private_ip = None

        if attrs is None:
            attrs = {}

        self.placement_groups = []
        placement = attrs.get("placement", [])
        placement = placement if type(placement) is list else [placement]
        for p in placement:
            pg = PlacementGroup.get(p)
            if not pg:
                raise ValueError("server '%s', placement '%s' is invalid" %
                                 (name, p))
            self.placement_groups.append(pg)
            pg.add_member(self.stack_name)

        self.instances = 1
        if "instances" in attrs:
            self.instances = attrs["instances"]

        # dict with key network name, each item is a dict with port name and ip
        self.ports = {}

        self.floating_ip = None
        self.floating_ip_assoc = None
        if "floating_ip" in attrs:
            self.floating_ip = {}
            self.floating_ip_assoc = {}

        if self.floating_ip is not None:
            ext_net = Network.find_external_network()
            assert ext_net is not None
            self.floating_ip["external_network"] = ext_net

        self._image = None
        if "image" in attrs:
            self._image = attrs["image"]

        self._flavor = None
        if "flavor" in attrs:
            self._flavor = attrs["flavor"]

        Server.list.append(self)

    @property
    def image(self):
        '''returns a server's image name'''
        if self._image:
            return self._image
        else:
            return self._context.image

    @property
    def flavor(self):
        '''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'''
        port_name_list = []
        for network in networks:
            port_name = server_name + "-" + network.name + "-port"
            self.ports[network.name] = {"stack_name": port_name}
            template.add_port(port_name, network.stack_name,
                              network.subnet_stack_name,
                              sec_group_id=self.secgroup_name)
            port_name_list.append(port_name)

            if self.floating_ip:
                external_network = self.floating_ip["external_network"]
                if network.has_route_to(external_network):
                    self.floating_ip["stack_name"] = server_name + "-fip"
                    template.add_floating_ip(self.floating_ip["stack_name"],
                                             external_network,
                                             port_name,
                                             network.router.stack_if_name,
                                             self.secgroup_name)
                self.floating_ip_assoc["stack_name"] = \
                    server_name + "-fip-assoc"
                template.add_floating_ip_association(
                    self.floating_ip_assoc["stack_name"],
                    self.floating_ip["stack_name"],
                    server_name)

        template.add_server(server_name, self.image, self.flavor,
                            ports=port_name_list,
                            user=self.user,
                            key_name=self.keypair_name,
                            scheduler_hints=scheduler_hints)

    def add_to_template(self, template, networks, scheduler_hints=None):
        '''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,
                               scheduler_hints=scheduler_hints)
        else:
            # TODO(hafe) fix or remove, no test/sample for this
            for i in range(self.instances):
                server_name = "%s-%d" % (self.stack_name, i)
                self._add_instance(template, server_name, networks,
                                   scheduler_hints=scheduler_hints)

def update_scheduler_hints(scheduler_hints, added_servers, placement_group):
    ''' 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"]
        else:
            host_list = scheduler_hints["same_host"] = []
    else:
        if "different_host" in scheduler_hints:
            host_list = scheduler_hints["different_host"]
        else:
            host_list = scheduler_hints["different_host"] = []

    for name in added_servers:
        if name in placement_group.members:
            host_list.append({'get_resource': name})

#
#
#

from keystoneclient.v2_0 import client as keystoneClient
from heatclient import client as heatClient
from heatclient.common import template_utils

__author__ = 'vmriccox'

class HeatManager:

    def __init__(self, credentials):
        self.ip_controller = credentials['ip_controller']
        self.heat_url = credentials['heat_url']
        self.user = credentials['user']
        self.password = credentials['password']
        self.auth_uri = credentials['auth_uri']
        self.project_id = credentials['project']
        self.heat = None

    def init_heat(self):
        keystone = keystoneClient.Client(username=self.user,
                                         password=self.password,
                                         tenant_name=self.project_id,
                                         auth_url=self.auth_uri)
        auth_token = keystone.auth_token
        self.heat_url = keystone.service_catalog.url_for(
            service_type='orchestration')
        self.heat = heatClient.Client('1', endpoint=self.heat_url,
                                      token=auth_token)

    def print_stacks(self, name=None):
        for stack in self.heat.stacks.list():
            if (name and stack.stack_name == name) or not name:
                common.LOG.info("Stack Name: " + stack.stack_name)
                common.LOG.info("Stack Status: " + stack.stack_status)

    def create_stack(self, template_file, stack_name, parameters):
        self.init_heat()
        # self.print_stacks()
        tpl_files, template = \
            template_utils.get_template_contents(template_file)

        fields = {
            'template': template,
            'files': dict(list(tpl_files.items()))
        }
        self.heat.stacks.create(stack_name=stack_name, files=fields['files'],
                                template=template, parameters=parameters)
        self.print_stacks(stack_name)

    def is_stack_deployed(self, stack_name):
        if stack_name in self.heat.stacks.list():

    def check_stack_status(self, stack_name):
        """
        Returns a string representing the status of a stack from Heat
        perspective
        :param stack_name: Name of the stack to be checked (type: str)
        :return: (type: str)
        """
            if stack.stack_name == stack_name:
                return stack.stack_status
        return 'NOT_FOUND'

    def validate_heat_template(self, heat_template_file):
        if not self.heat.stacks.validate(template=open(heat_template_file,
                                                       'r').read()):
            raise ValueError('The provided heat template "' +
                             heat_template_file +
                             '" is not in the correct format')

    def delete_stack(self, stack_name):
        try:
            for stack in self.heat.stacks.list():
                if stack.stack_name == stack_name:
                    self.heat.stacks.delete(stack.id)
                    return True
        except:
            pass

#

def print_hbar(barlen):
    '''print to stdout a horizontal bar'''
    print("+"),
    print("-" * barlen),
    print("+")

#
#
#

import os
import commands
# import signal
from experimental_framework.constants import conf_file_sections as cfs
from experimental_framework.packet_generators import dpdk_packet_generator \
    as dpdk

THROUGHPUT = 'throughput'
PACKETS_FILE_NAME = 'packets.res'
PACKET_CHECKER_PROGRAM_NAME = 'test_sniff'
MULTICAST_GROUP = '224.192.16.1'

class InstantiationValidationBenchmark(base.BenchmarkBaseClass):

        base.BenchmarkBaseClass.__init__(self, name, params)
        self.base_dir = "{}{}{}".format(
            common.get_base_dir(), fp.EXPERIMENTAL_FRAMEWORK_DIR,
            fp.DPDK_PKTGEN_DIR)
        self.results_file = self.base_dir + PACKETS_FILE_NAME
        self.lua_file = self.base_dir + 'constant_traffic.lua'
        self.res_dir = ''
        self.interface_name = ''

        # Set the packet checker command
        self.pkt_checker_command = common.get_base_dir()
        self.pkt_checker_command += 'experimental_framework/libraries/'
        self.pkt_checker_command += 'packet_checker/'
        self.pkt_checker_command += PACKET_CHECKER_PROGRAM_NAME + ' '

        """
        """
        pass

        """
        Finalizes the benchmark
        """
        pass

        features['description'] = 'Instantiation Validation Benchmark'
        features['parameters'] = [THROUGHPUT, VLAN_SENDER, VLAN_RECEIVER]
        features['allowed_values'][THROUGHPUT] = map(str, range(0, 100))
        features['default_values'][THROUGHPUT] = '1'
        features['default_values'][VLAN_SENDER] = '-1'
        features['default_values'][VLAN_RECEIVER] = '-1'

        # Setup packet generator
        traffic_time = '10'
        packet_size = '512'
        traffic_rate_percentage = self.params[THROUGHPUT]

        dpdk_pktgen_vars = common.get_dpdk_pktgen_vars()
        # bus_address = dpdk_pktgen_vars[cfs.CFSP_DPDK_BUS_SLOT_NIC_2]
        self.interface_name = dpdk_pktgen_vars[cfs.CFSP_DPDK_NAME_IF_2]
        self._configure_lua_file(traffic_rate_percentage, traffic_time)
        packetgen.init_dpdk_pktgen(dpdk_interfaces=1,
                                   pcap_file_0='packet_' + packet_size +
                                               '.pcap',
                                   lua_script='constant_traffic.lua',

        self._init_packet_checker()
        # Send constant traffic at a specified rate
        common.LOG.debug('Start the packet generator')
        self._finalize_packet_checker()
        self._reset_lua_file(traffic_rate_percentage, traffic_time)

    def _configure_lua_file(self, traffic_rate_percentage, traffic_time):
        """
        """
        common.replace_in_file(self.lua_file, 'local traffic_rate = 0',
                               'local traffic_rate = ' +
                               traffic_rate_percentage)
        common.replace_in_file(self.lua_file, 'local traffic_delay = 0',
                               'local traffic_delay = ' + traffic_time)

    def _reset_lua_file(self, traffic_rate_percentage, traffic_time):
        """
        :param traffic_rate_percentage:
        :param traffic_time:
        """

        common.replace_in_file(self.lua_file, 'local traffic_rate = ' +
                               traffic_rate_percentage,
                               'local traffic_rate = 0')
        common.replace_in_file(self.lua_file, 'local traffic_delay = ' +
                               traffic_time, 'local traffic_delay = 0')

        packet_checker_res = 0
        if self.res_dir:
            packet_checker_res = \
                int(common.get_file_first_line(self.res_dir +
                                               'packet_checker.res'))
        pkt_gen_res = int(common.get_file_first_line(self.results_file))
        if pkt_gen_res <= packet_checker_res or \
           (float(pkt_gen_res - packet_checker_res) / pkt_gen_res) <= 0.1:
            ret_val['failure'] = '0'
        else:
            ret_val['failure'] = '1'

    def _init_packet_checker(self):
        """
        Sets up the multicast and starts the packet checker
        :return:
        """
        # Kill any other process running from previous failed execution
        self.res_dir = common.get_result_dir()
        pids = self._get_pids()
        for pid in pids:
            # os.kill(pid, signal.SIGTERM)
            command = 'sudo kill ' + str(pid)
            common.run_command(command)

        # initialization of the VLAN interface
        command = "sudo ip link add link "
        command += self.interface_name
        command += " name "
        command += self.interface_name + '.' + self.params[VLAN_RECEIVER]
        command += " type vlan id " + self.params[VLAN_RECEIVER]

        # set up the new
        command = 'sudo ifconfig ' + self.interface_name + '.' + \
                  self.params[VLAN_RECEIVER]
        # An IP address is required for the interface to receive a multicast
        # flow. The specific address is not important
        command += ' 10.254.254.254 up'

        # configure smcroute
        command = "sudo echo 'mgroup from "
        command += " group "
        command += MULTICAST_GROUP
        command += "' > /etc/smcroute.conf"

        # run smcroute on the interface
        command = 'sudo smcroute -d'

        # Start the packet checker
        dir_list = self.pkt_checker_command.split('/')
        directory = '/'.join(dir_list[0:len(dir_list)-1])
        command = "make"
        os.chdir(current_dir)

        command = "sudo chmod +x {}".format(self.pkt_checker_command)

        command = 'sudo ' + self.pkt_checker_command
        command += ' 128'
        command += ' &'

    def _finalize_packet_checker(self):
        """
        Obtains the PID of the packet checker and sends an alarm to
        terminate it
        """

        # stop smcroute on the interface
        command = 'sudo smcroute -k'

        # finalization of the VLAN interface
        command = "sudo ip link delete "

    def _get_pids(self):
        """
        Returns a list of integers containing the pid or the pids of the
        processes currently running on the host
        :return: type: list of int
        """
        output = commands.getoutput("ps -ef |pgrep " +
                                    PACKET_CHECKER_PROGRAM_NAME)
        if not output:
            pids = []
        else:
            pids = map(int, output.split('\n'))
        return pids

#

class DummyContext(Context):
    '''Class that handle dummy info'''

    __context_type__ = "Dummy"

        pass

        pass

        pass

#

class Pktgen(base.Scenario):
    """Execute pktgen between two hosts

    packetsize - packet size in bytes without the CRC
        type:    int
        default: 60
    number_of_ports - number of UDP ports to test
        type:    int
        unit:    na
        default: 10
    duration - duration of the test
        type:    int
        default: 20
    """
    __scenario_type__ = "Pktgen"

    TARGET_SCRIPT = 'pktgen_benchmark.bash'

            Pktgen.TARGET_SCRIPT)
        host_user = host.get('user', 'ubuntu')
        host_ip = host.get('ip', None)
        host_key_filename = host.get('key_filename', '~/.ssh/id_rsa')
        target = self.context_cfg['target']
        target_user = target.get('user', 'ubuntu')
        target_ip = target.get('ip', None)
        target_key_filename = target.get('key_filename', '~/.ssh/id_rsa')

        LOG.info("user:%s, target:%s", target_user, target_ip)
        self.server = ssh.SSH(target_user, target_ip,
                              key_filename=target_key_filename)
        self.server.wait(timeout=600)

        LOG.info("user:%s, host:%s", host_user, host_ip)
        self.client = ssh.SSH(host_user, host_ip,
                              key_filename=host_key_filename)

        self.client.run("cat > ~/pktgen.sh",
                        stdin=open(self.target_script, "rb"))

    def _iptables_setup(self):
        """Setup iptables on server to monitor for received packets"""
        cmd = "sudo iptables -F; " \
              "sudo iptables -A INPUT -p udp --dport 1000:%s -j DROP" \
              % (1000 + self.number_of_ports)
        status, _, stderr = self.server.execute(cmd)
        if status:

    def _iptables_get_result(self):
        """Get packet statistics from server"""
        cmd = "sudo iptables -L INPUT -vnx |" \
              "awk '/dpts:1000:%s/ {{printf \"%%s\", $1}}'" \
        status, stdout, stderr = self.server.execute(cmd)
        if status:
        return int(stdout)

        ipaddr = self.context_cfg["target"].get("ipaddr", '127.0.0.1')

        packetsize = options.get("packetsize", 60)
        self.number_of_ports = options.get("number_of_ports", 10)
        # if run by a duration runner
        duration_time = self.scenario_cfg["runner"].get("duration", None) \
            if "runner" in self.scenario_cfg else None
        # if run by an arithmetic runner
        arithmetic_time = options.get("duration", None)

        if duration_time:
            duration = duration_time
        elif arithmetic_time:
            duration = arithmetic_time
        else:
            duration = 20

        self._iptables_setup()

        cmd = "sudo bash pktgen.sh %s %s %s %s" \
            % (ipaddr, self.number_of_ports, packetsize, duration)

        if status:

        result['packets_received'] = self._iptables_get_result()

            sent = result['packets_sent']
            received = result['packets_received']
            ppm = 1000000 * (sent - received) / sent
            sla_max_ppm = int(self.scenario_cfg["sla"]["max_ppm"])
            assert ppm <= sla_max_ppm, "ppm %d > sla_max_ppm %d; " \
                % (ppm, sla_max_ppm)

    key_filename = pkg_resources.resource_filename('yardstick.resources',
                                                   'files/yardstick_key')
    ctx = {
        'host': {
            'ip': '10.229.47.137',
            'user': 'root',
            'key_filename': key_filename
        },
        'target': {
            'key_filename': key_filename,
            'ipaddr': '10.229.47.137',
        }
    }

    logger = logging.getLogger('yardstick')

    options = {'packetsize': 120}
    args = {'options': options}
    result = {}

    p = Pktgen(args, ctx)

    _test()

#

def _execute_shell_command(command, stdin=None):
    output = []
    try:
        output = subprocess.check_output(command, stdin=stdin, shell=True)

class BaremetalAttacker(BaseAttacker):

    __attacker_type__ = 'bare-metal-down'

        self.host_ip = ip

        self.ipmi_ip = host.get("ipmi_ip", None)
        self.ipmi_user = host.get("ipmi_user", "root")
        self.ipmi_pwd = host.get("ipmi_pwd", None)

        self.fault_cfg = BaseAttacker.attacker_cfgs.get('bare-metal-down')

            "/bin/sh -s {0} -W 10".format(self.host_ip),

        LOG.debug("check ret: %s out:%s err:%s" %
                  (exit_status, stdout, stderr))
        if not stdout or "running" not in stdout:
            LOG.info("the host (ipmi_ip:%s) is not running!" % self.ipmi_ip)

            "shutdown -h now")
        LOG.debug("inject fault ret: %s out:%s err:%s" %
        if not exit_status:
            LOG.info("inject fault success")

        jump_host_name = self._config.get("jump_host", None)
        self.jump_connection = None
        if jump_host_name is not None:
            host = self._context.get(jump_host_name, None)
            pwd = host.get("pwd", None)

            LOG.debug("jump_host ip:%s user:%s" % (ip, user))
            self.jump_connection = ssh.SSH(user, ip, password=pwd)
            self.jump_connection.wait(timeout=600)
            LOG.debug("ssh jump host success!")

        if self.jump_connection is not None:
            exit_status, stdout, stderr = self.jump_connection.execute(
                "/bin/bash -s {0} {1} {2} {3}".format(
                    self.ipmi_ip, self.ipmi_user, self.ipmi_pwd, "on"),
                stdin=open(self.recovery_script, "r"))
        else:
            exit_status, stdout = _execute_shell_command(

def _test():  # pragma: no cover
    host = {
        "ipmi_ip": "10.20.0.5",
        "ipmi_user": "root",
        "ipmi_pwd": "123456",
    }
        'fault_type': 'bear-metal-down',
    }
    ins = BaremetalAttacker(attacker_cfg, context)
    ins.setup()
    ins.inject_fault()

if __name__ == '__main__':  # pragma: no cover
    _test()

# Copyright (c) 2015 Huawei Technologies Co.,Ltd.
#

class Fio(base.Scenario):
    """Execute fio benchmark in a host

    filename - file name for fio workload
        unit:    na
        default: /home/ubuntu/data.raw
    bs - block size used for the io units
        type:    int
        default: 4k
    iodepth - number of iobuffers to keep in flight
        type:    int
        unit:    na
        default: 1
    rw - type of io pattern [read, write, randwrite, randread, rw, randrw]
        unit:    na
        default: write
    ramp_time - run time before logging any performance
        type:    int

        http://www.bluestop.org/fio/HOWTO.txt
    """
    __scenario_type__ = "Fio"

    TARGET_SCRIPT = "fio_benchmark.bash"

            "yardstick.benchmark.scenarios.storage",
            Fio.TARGET_SCRIPT)

        self.client = ssh.SSH(user, ip, key_filename=key_filename)

        self.client.run("cat > ~/fio.sh",

        default_args = "-ioengine=libaio -direct=1 -group_reporting " \
            "-numjobs=1 -time_based --output-format=json"

        filename = options.get("filename", "/home/ubuntu/data.raw")
        bs = options.get("bs", "4k")
        iodepth = options.get("iodepth", "1")
        rw = options.get("rw", "write")
        ramp_time = options.get("ramp_time", 20)
        name = "yardstick-fio"
            runtime = duration_time
            runtime = arithmetic_time
        else:
            runtime = 30

        cmd_args = "-filename=%s -bs=%s -iodepth=%s -rw=%s -ramp_time=%s " \
                   "-runtime=%s -name=%s %s" \
                   % (filename, bs, iodepth, rw, ramp_time, runtime, name,
                      default_args)
        cmd = "sudo bash fio.sh %s %s" % (filename, cmd_args)
        # Set timeout, so that the cmd execution does not exit incorrectly
        # when the test run time is last long
        timeout = int(ramp_time) + int(runtime) + 600
        status, stdout, stderr = self.client.execute(cmd, timeout=timeout)
        if status:

        raw_data = json.loads(stdout)

        # The bandwidth unit is KB/s, and latency unit is us
        if rw in ["read", "randread", "rw", "randrw"]:
            result["read_bw"] = raw_data["jobs"][0]["read"]["bw"]
            result["read_iops"] = raw_data["jobs"][0]["read"]["iops"]
            result["read_lat"] = raw_data["jobs"][0]["read"]["lat"]["mean"]
        if rw in ["write", "randwrite", "rw", "randrw"]:
            result["write_bw"] = raw_data["jobs"][0]["write"]["bw"]
            result["write_iops"] = raw_data["jobs"][0]["write"]["iops"]
            result["write_lat"] = raw_data["jobs"][0]["write"]["lat"]["mean"]

            for k, v in result.items():
                if k not in self.scenario_cfg['sla']:
                    continue

                if "lat" in k:
                    # For lattency small value is better
                    max_v = float(self.scenario_cfg['sla'][k])
                    if v > max_v:
                        sla_error += "%s %f > sla:%s(%f); " % (k, v, k, max_v)
                else:
                    # For bandwidth and iops big value is better
                    min_v = int(self.scenario_cfg['sla'][k])
                    if v < min_v:
                        sla_error += "%s %d < " \
                            "sla:%s(%d); " % (k, v, k, min_v)

    ctx = {
        "host": {
        }
    }

    options = {
        "filename": "/home/ubuntu/data.raw",
        "bs": "4k",
        "iodepth": "1",
        "rw": "rw",
        "ramp_time": 1,
        "duration": 10
    }
    result = {}
    args = {"options": options}

    fio = Fio(args, ctx)
    fio.run(result)

    _test()

# yardstick comment: this file is a modified copy of
# influxdb-python/influxdb/line_protocol.py

from __future__ import unicode_literals
from copy import copy

from six import binary_type, text_type, integer_types

def _escape_tag(tag):
    tag = _get_unicode(tag, force=True)
    return tag.replace(
        "\\", "\\\\"
    ).replace(
        " ", "\\ "
        ",", "\\,"
        "=", "\\="
    )

def _escape_value(value):
    value = _get_unicode(value)
    if isinstance(value, text_type) and value != '':
        return "\"{}\"".format(
            value.replace(
                "\"", "\\\""
            ).replace(
                "\n", "\\n"
            )
        )
    elif isinstance(value, integer_types) and not isinstance(value, bool):
        return str(value) + 'i'
    else:
        return str(value)

def _get_unicode(data, force=False):
    """
    Try to return a text aka unicode object from the given data.
    """
    if isinstance(data, binary_type):
        return data.decode('utf-8')
    elif data is None:
        return ''
    elif force:
        return str(data)
    else:
        return data

def make_lines(data):
    """
    Extracts the points from the given dict and returns a Unicode string
    matching the line protocol introduced in InfluxDB 0.9.0.

    line protocol format:
        <measurement>[,<tag-key>=<tag-value>...] <field-key>=<field-value>\
            [,<field2-key>=<field2-value>...] [unix-nano-timestamp]

    Ref:
        https://influxdb.com/docs/v0.9/write_protocols/write_syntax.html
        https://influxdb.com/docs/v0.9/write_protocols/line.html
    """
    lines = []
    static_tags = data.get('tags', None)
    for point in data['points']:
        elements = []

        # add measurement name
        measurement = _escape_tag(_get_unicode(
            point.get('measurement', data.get('measurement'))
        ))
        key_values = [measurement]

        # add tags
        if static_tags is None:
            tags = point.get('tags', {})
        else:
            tags = copy(static_tags)
            tags.update(point.get('tags', {}))

        # tags should be sorted client-side to take load off server
        for tag_key in sorted(tags.keys()):
            key = _escape_tag(tag_key)
            value = _escape_tag(tags[tag_key])

            if key != '' and value != '':
                key_values.append("{key}={value}".format(key=key, value=value))
        key_values = ','.join(key_values)
        elements.append(key_values)

        # add fields
        field_values = []
        for field_key in sorted(point['fields'].keys()):
            key = _escape_tag(field_key)
            value = _escape_value(point['fields'][field_key])
                field_values.append("{key}={value}".format(
                    key=key,
                    value=value
                ))
        field_values = ','.join(field_values)
        elements.append(field_values)

        # add timestamp
        if 'time' in point:
            elements.append(point['time'])

        line = ' '.join(elements)
        lines.append(line)
    lines = '\n'.join(lines)
    return lines + '\n'

#

import sys

from yardstick.benchmark.contexts.model import Server
from yardstick.benchmark.contexts.model import PlacementGroup
from yardstick.benchmark.contexts.model import Network
from yardstick.benchmark.contexts.model import update_scheduler_hints
from yardstick.orchestrator.heat import HeatTemplate

class HeatContext(Context):
    '''Class that represents a context in the logical model'''

    __context_type__ = "Heat"

        self.stack = None
        self.networks = []
        self.servers = []
        self.keypair_name = None
        self.secgroup_name = None
        self._server_map = {}
        self._user = None
        self.template_file = None
        self.heat_parameters = None

        if "user" in attrs:
            self._user = attrs["user"]

        if "heat_template" in attrs:
            self.template_file = attrs["heat_template"]
            self.heat_parameters = attrs.get("heat_parameters", None)
            return

        self.keypair_name = self.name + "-key"
        self.secgroup_name = self.name + "-secgroup"

        if "placement_groups" in attrs:
            for name, pgattrs in attrs["placement_groups"].items():
                pg = PlacementGroup(name, self, pgattrs["policy"])
                self.placement_groups.append(pg)

        for name, netattrs in attrs["networks"].items():
            network = Network(name, self, netattrs)
            self.networks.append(network)

        for name, serverattrs in attrs["servers"].items():
            server = Server(name, self, serverattrs)
            self.servers.append(server)
            self._server_map[server.dn] = server

    @property
        '''returns application's default image name'''
        return self._image

    @property
        '''returns application's default flavor name'''
        return self._flavor

    @property
    def user(self):
        '''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'''
        template.add_keypair(self.keypair_name)
        template.add_security_group(self.secgroup_name)

        for network in self.networks:
            template.add_network(network.stack_name)
            template.add_subnet(network.subnet_stack_name, network.stack_name,
                                network.subnet_cidr)

                template.add_router(network.router.stack_name,
                                    network.router.external_gateway_info,
                                    network.subnet_stack_name)
                template.add_router_interface(network.router.stack_if_name,
                                              network.router.stack_name,
                                              network.subnet_stack_name)

        # create a list of servers sorted by increasing no of placement groups
        list_of_servers = sorted(self.servers,
                                 key=lambda s: len(s.placement_groups))

        #
        # add servers with scheduler hints derived from placement groups
        #

        # create list of servers with availability policy
        availability_servers = []
        for server in list_of_servers:
            for pg in server.placement_groups:
                if pg.policy == "availability":
                    availability_servers.append(server)
                    break

        # add servers with availability policy
        added_servers = []
        for server in availability_servers:
            scheduler_hints = {}
                update_scheduler_hints(scheduler_hints, added_servers, pg)
            # workround for openstack nova bug, check JIRA: YARDSTICK-200
            # for details
            if len(availability_servers) == 2:
                if len(scheduler_hints["different_host"]) == 0:
                    scheduler_hints.pop("different_host", None)
                    server.add_to_template(template,
                                           self.networks,
                                           scheduler_hints)
                    added_servers.append(server.stack_name)
                else:
                    scheduler_hints["different_host"] = \
                        scheduler_hints["different_host"][0]
            else:
                server.add_to_template(template,
                                       self.networks,
                                       scheduler_hints)
                added_servers.append(server.stack_name)

        # create list of servers with affinity policy
        affinity_servers = []
                if pg.policy == "affinity":
                    affinity_servers.append(server)
                    break

        # add servers with affinity policy
        for server in affinity_servers:
            if server.stack_name in added_servers:
                continue
            server.add_to_template(template, self.networks, scheduler_hints)
            added_servers.append(server.stack_name)

        # add remaining servers with no placement group configured
            if len(server.placement_groups) == 0:
                server.add_to_template(template, self.networks, {})

        '''deploys template into a stack using cloud'''
        print "Deploying context '%s'" % self.name

        heat_template = HeatTemplate(self.name, self.template_file,
                                     self.heat_parameters)

        if self.template_file is None:
            self._add_resources_to_template(heat_template)

        try:
            self.stack = heat_template.create()
        except KeyboardInterrupt:
            sys.exit("\nStack create interrupted")
        except RuntimeError as err:
            sys.exit("error: failed to deploy stack: '%s'" % err.args)
        except Exception as err:
            sys.exit("error: failed to deploy stack: '%s'" % err)

        # copy some vital stack output into server objects
        for server in self.servers:
            if len(server.ports) > 0:
                # TODO(hafe) can only handle one internal network for now
                port = server.ports.values()[0]
                server.private_ip = self.stack.outputs[port["stack_name"]]

            if server.floating_ip:
                server.public_ip = \
                    self.stack.outputs[server.floating_ip["stack_name"]]

        print "Context '%s' deployed" % self.name

        '''undeploys stack from cloud'''
        if self.stack:
            print "Undeploying context '%s'" % self.name
            self.stack.delete()
            self.stack = None
            print "Context '%s' undeployed" % self.name

        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')

            cname = attr_name["name"].split(".")[1]
            if cname != self.name:
                return None

            public_ip = None
            private_ip = None
            if "public_ip_attr" in attr_name:
                public_ip = self.stack.outputs[attr_name["public_ip_attr"]]
            if "private_ip_attr" in attr_name:
                private_ip = self.stack.outputs[
                    attr_name["private_ip_attr"]]

            # Create a dummy server instance for holding the *_ip attributes
            server = Server(attr_name["name"].split(".")[0], self, {})
            server.public_ip = public_ip
            server.private_ip = private_ip
        else:
            if attr_name not in self._server_map:
            server = self._server_map[attr_name]

        if server is None:

        result = {
            "user": server.context.user,
            "key_filename": key_filename,
            "private_ip": server.private_ip
        }
        # Target server may only have private_ip
        if server.public_ip:
            result["ip"] = server.public_ip

#

'''A runner that runs a configurable number of times before it returns
'''

import os

    iterations = runner_cfg.get("iterations", 1)
    run_step = runner_cfg.get("run_step", "setup,run,teardown")
    LOG.info("worker START, iterations %d times, class %s", iterations, cls)

    if "setup" in run_step:
        benchmark.setup()

    if "run" in run_step:

            LOG.debug("runner=%(runner)s seq=%(sequence)s START" %
                      {"runner": runner_cfg["runner_id"],
                       "sequence": sequence})

            data = {}
            errors = ""

            try:
                method(data)
            except AssertionError as assertion:
                # SLA validation failed in scenario, determine what to do now
                if sla_action == "assert":
                    raise
                elif sla_action == "monitor":
                    LOG.warning("SLA validation failed: %s" % assertion.args)
                    errors = assertion.args
            except Exception as e:
                errors = traceback.format_exc()
                LOG.exception(e)

            time.sleep(interval)

            benchmark_output = {
                'timestamp': time.time(),
                'sequence': sequence,
                'data': data,
                'errors': errors
            }

            record = {'runner_id': runner_cfg['runner_id'],
                      'benchmark': benchmark_output}

            queue.put(record)

            LOG.debug("runner=%(runner)s seq=%(sequence)s END" %

            sequence += 1

            if (errors and sla_action is None) or \
                    (sequence > iterations or aborted.is_set()):
                LOG.info("worker END")
                break
    if "teardown" in run_step:
        benchmark.teardown()

class IterationRunner(base.Runner):
    '''Run a scenario for a configurable number of times

    iterations - amount of times the scenario will be run for
        type:    int
        unit:    na
        default: 1
        type:    int
    '''
    __execution_type__ = 'Iteration'

#

import os

class VtcInstantiationValidationNoisy(base.Scenario):
    """
    __scenario_type__ = "vtc_instantiation_validation_noisy"

        }
        }
        }

        test_case['name'] = 'instantiation_validation_noisy_neighbors_' \
                            'benchmark.' \
                            'InstantiationValidationNoisyNeighborsBenchmark'
        test_case['params']['num_of_neighbours'] = \
            str(self.options['num_of_neighbours'])
        test_case['params']['amount_of_ram'] = \
            str(self.options['amount_of_ram'])
        test_case['params']['number_of_cores'] = \
            str(self.options['number_of_cores'])

        try:

#
import os

attacker_conf_path = pkg_resources.resource_filename(
    "attacker_conf.yaml")

class BaseAttacker(object):

    attacker_cfgs = {}

        if not BaseAttacker.attacker_cfgs:
            with open(attacker_conf_path) as stream:
                BaseAttacker.attacker_cfgs = yaml.load(stream)

    def get_attacker_cls(attacker_cfg):
        '''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__:
                return attacker_cls
        raise RuntimeError("No such runner_type %s" % attacker_type)

        base_path = os.path.dirname(attacker_conf_path)

#

class Lmbench(base.Scenario):
    """Execute lmbench memory read latency or memory bandwidth benchmark in a host

    Parameters
        test_type - specifies whether to measure memory latency or bandwidth
            type:       string
            unit:       na
            default:    "latency"

    Parameters for memory read latency benchmark
        stride - number of locations in memory between starts of array elements
            type:       int
            unit:       bytes
            default:    128
        stop_size - maximum array size to test (minimum value is 0.000512)
            type:       float
            unit:       megabytes
            default:    16.0

        Results are accurate to the ~2-5 nanosecond range.

    Parameters for memory bandwidth benchmark
        size - the amount of memory to test
            type:       int
            unit:       kilobyte
        benchmark - the name of the memory bandwidth benchmark test to execute.
        Valid test names are rd, wr, rdwr, cp, frd, fwr, fcp, bzero, bcopy
            unit:       na
            default:    "rd"
        warmup - the number of repetitons to perform before taking measurements
            type:       int
            unit:       na
            default:    0
    more info http://manpages.ubuntu.com/manpages/trusty/lmbench.8.html
    """
    __scenario_type__ = "Lmbench"

    LATENCY_BENCHMARK_SCRIPT = "lmbench_latency_benchmark.bash"
    BANDWIDTH_BENCHMARK_SCRIPT = "lmbench_bandwidth_benchmark.bash"

        self.bandwidth_target_script = pkg_resources.resource_filename(
            Lmbench.BANDWIDTH_BENCHMARK_SCRIPT)
        self.latency_target_script = pkg_resources.resource_filename(
            Lmbench.LATENCY_BENCHMARK_SCRIPT)
        user = host.get("user", "ubuntu")
        key_filename = host.get('key_filename', "~/.ssh/id_rsa")

        # copy scripts to host
        self.client.run("cat > ~/lmbench_latency.sh",
                        stdin=open(self.latency_target_script, 'rb'))
        self.client.run("cat > ~/lmbench_bandwidth.sh",
                        stdin=open(self.bandwidth_target_script, 'rb'))

        test_type = options.get('test_type', 'latency')

        if test_type == 'latency':
            stride = options.get('stride', 128)
            stop_size = options.get('stop_size', 16.0)
            cmd = "sudo bash lmbench_latency.sh %f %d" % (stop_size, stride)
        elif test_type == 'bandwidth':
            size = options.get('size', 128)
            benchmark = options.get('benchmark', 'rd')
            warmup_repetitions = options.get('warmup', 0)
            cmd = "sudo bash lmbench_bandwidth.sh %d %s %d" % \
                  (size, benchmark, warmup_repetitions)
        else:
            raise RuntimeError("No such test_type: %s for Lmbench scenario",
                               test_type)

        if status:

            result.update({"latencies": json.loads(stdout)})
        else:
            result.update(json.loads(stdout))

            if test_type == 'latency':
                sla_max_latency = int(self.scenario_cfg['sla']['max_latency'])
                for t_latency in result["latencies"]:
                    latency = t_latency['latency']
                    if latency > sla_max_latency:
                        sla_error += "latency %f > sla:max_latency(%f); " \
                            % (latency, sla_max_latency)
            else:
                sla_min_bw = int(self.scenario_cfg['sla']['min_bandwidth'])
                bw = result["bandwidth(MBps)"]
                if bw < sla_min_bw:
                    sla_error += "bandwidth %f < " \
                                 "sla:min_bandwidth(%f)" % (bw, sla_min_bw)

    """internal test function"""
    ctx = {
        'host': {
        }
    }

    options = {
        'test_type': 'latency',
        'stride': 128,
        'stop_size': 16
    }

    sla = {'max_latency': 35, 'action': 'monitor'}
    args = {'options': options, 'sla': sla}
    result = {}

    p = Lmbench(args, ctx)

    _test()

# Copyright 2013: Mirantis Inc.
# All Rights Reserved.
#
#
#

# yardstick comment: this is a modified copy of rally/rally/common/sshutils.py

"""High level ssh library.

Usage examples:

Execute command and get output:

    ssh = sshclient.SSH("root", "example.com", port=33)
    status, stdout, stderr = ssh.execute("ps ax")
    if status:
        raise Exception("Command failed with non-zero status.")
    print stdout.splitlines()

Execute command with huge output:

    class PseudoFile(object):
        def write(chunk):
            if "error" in chunk:
                email_admin(chunk)

    ssh = sshclient.SSH("root", "example.com")
    ssh.run("tail -f /var/log/syslog", stdout=PseudoFile(), timeout=False)

Execute local script on remote side:

    ssh = sshclient.SSH("user", "example.com")
    status, out, err = ssh.execute("/bin/sh -s arg1 arg2",
                                   stdin=open("~/myscript.sh", "r"))

Upload file:

    ssh.run("cat > ~/upload/file.gz", stdin=open("/store/file.gz", "rb"))

Eventlet:

    eventlet.monkey_patch(select=True, time=True)
    or
    eventlet.monkey_patch()
    or
    sshclient = eventlet.import_patched("opentstack.common.sshclient")

"""

import select

import paramiko
from scp import SCPClient
import six

class SSHError(Exception):
    pass

class SSHTimeout(SSHError):
    pass

class SSH(object):
    """Represent ssh connection."""

    def __init__(self, user, host, port=22, pkey=None,
                 key_filename=None, password=None):
        """Initialize SSH client.

        :param user: ssh username
        :param host: hostname or ip address of remote ssh server
        :param port: remote ssh port
        :param pkey: RSA or DSS private key string or file object
        :param key_filename: private key filename
        :param password: password
        """

        self.user = user
        self.host = host
        self.port = port
        self.pkey = self._get_pkey(pkey) if pkey else None
        self.password = password
        self.key_filename = key_filename
        self._client = False

    def _get_pkey(self, key):
        if isinstance(key, six.string_types):
            key = six.moves.StringIO(key)
        errors = []
        for key_class in (paramiko.rsakey.RSAKey, paramiko.dsskey.DSSKey):
            try:
                return key_class.from_private_key(key)
            except paramiko.SSHException as e:
                errors.append(e)
        raise SSHError("Invalid pkey: %s" % (errors))

    def _get_client(self):
        if self._client:
            return self._client
        try:
            self._client = paramiko.SSHClient()
            self._client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            self._client.connect(self.host, username=self.user,
                                 port=self.port, pkey=self.pkey,
                                 key_filename=self.key_filename,
                                 password=self.password, timeout=1)
            message = ("Exception %(exception_type)s was raised "
                       "during connect. Exception value is: %(exception)r")
            self._client = False
            raise SSHError(message % {"exception": e,
                                      "exception_type": type(e)})

    def close(self):
        self._client.close()

    def run(self, cmd, stdin=None, stdout=None, stderr=None,
            raise_on_error=True, timeout=3600):
        """Execute specified command on the server.

        :param cmd:             Command to be executed.
        :param stdin:           Open file or string to pass to stdin.
        :param stdout:          Open file to connect to stdout.
        :param stderr:          Open file to connect to stderr.
        :param raise_on_error:  If False then exit code will be return. If True
                                then exception will be raized if non-zero code.
        :param timeout:         Timeout in seconds for command execution.
                                Default 1 hour. No timeout if set to 0.
        """

        client = self._get_client()

        if isinstance(stdin, six.string_types):
            stdin = six.moves.StringIO(stdin)

        return self._run(client, cmd, stdin=stdin, stdout=stdout,
                         stderr=stderr, raise_on_error=raise_on_error,
                         timeout=timeout)

    def _run(self, client, cmd, stdin=None, stdout=None, stderr=None,
             raise_on_error=True, timeout=3600):

        transport = client.get_transport()
        session = transport.open_session()
        session.exec_command(cmd)

        data_to_send = ""
        stderr_data = None

        # If we have data to be sent to stdin then `select' should also
        # check for stdin availability.
        if stdin and not stdin.closed:
            writes = [session]
        else:
            writes = []

            # Block until data can be read/write.
            r, w, e = select.select([session], writes, [session], 1)

            if session.recv_ready():
                data = session.recv(4096)
                LOG.debug("stdout: %r" % data)
                if stdout is not None:
                    stdout.write(data)
                continue

            if session.recv_stderr_ready():
                stderr_data = session.recv_stderr(4096)
                LOG.debug("stderr: %r" % stderr_data)
                if stderr is not None:
                    stderr.write(stderr_data)
                continue

            if session.send_ready():
                if stdin is not None and not stdin.closed:
                    if not data_to_send:
                        data_to_send = stdin.read(4096)
                        if not data_to_send:
                            stdin.close()
                            session.shutdown_write()
                            writes = []
                            continue
                    sent_bytes = session.send(data_to_send)
                    # LOG.debug("sent: %s" % data_to_send[:sent_bytes])
                    data_to_send = data_to_send[sent_bytes:]

            if session.exit_status_ready():
                break

            if timeout and (time.time() - timeout) > start_time:
                args = {"cmd": cmd, "host": self.host}
                raise SSHTimeout("Timeout executing command "
                                 "'%(cmd)s' on host %(host)s" % args)
            if e:
                raise SSHError("Socket error.")

        exit_status = session.recv_exit_status()
        if 0 != exit_status and raise_on_error:
            fmt = "Command '%(cmd)s' failed with exit_status %(status)d."
            details = fmt % {"cmd": cmd, "status": exit_status}
            if stderr_data:
                details += " Last stderr data: '%s'." % stderr_data
            raise SSHError(details)
        return exit_status

    def execute(self, cmd, stdin=None, timeout=3600):
        """Execute the specified command on the server.

        :param cmd:     Command to be executed.
        :param stdin:   Open file to be sent on process stdin.
        :param timeout: Timeout for execution of the command.

        :returns: tuple (exit_status, stdout, stderr)
        """
        stdout = six.moves.StringIO()
        stderr = six.moves.StringIO()

        exit_status = self.run(cmd, stderr=stderr,
                               stdout=stdout, stdin=stdin,
                               timeout=timeout, raise_on_error=False)
        stdout.seek(0)
        stderr.seek(0)
        return (exit_status, stdout.read(), stderr.read())

    def wait(self, timeout=120, interval=1):
        """Wait for the host will be available via ssh."""
            try:
                return self.execute("uname")
            except (socket.error, SSHError) as e:
                LOG.debug("Ssh is still unavailable: %r" % e)
                time.sleep(interval)
            if time.time() > (start_time + timeout):
                raise SSHTimeout("Timeout waiting for '%s'" % self.host)

    def put(self, files, remote_path=b'.', recursive=False):

        with SCPClient(client.get_transport()) as scp:
            scp.put(files, remote_path, recursive)

#

import os

class VtcThroughputNoisy(base.Scenario):
    """
    __scenario_type__ = "vtc_throughput_noisy"

        }
        }
        }

        test_case['name'] = 'multi_tenancy_throughput_benchmark.' \
                            'MultiTenancyThroughputBenchmark'

        try:

#
#
#

'''
Generation of the heat templates from the base template
'''

import os
import shutil

class TreeNode:
    """
    This class represent the node of the configuration tree.\
    Each node represents a single configuration value for a single
    configuration parameter.
    """

        self.up = None
        self.down = []
        self.variable_name = ''
        self.variable_value = 0

    def add_child(self, node):
        """
        Adds a node as a child for the current node
        :param node: node to be added as a child (type: TreeNode)
        """
        node.up = self
        self.down.append(node)

    def get_parent(self):
        """
        Returns the parent node of the current one
        :return type: TreeNode
        """
        return self.up

    def get_children(self):
        """
        Returns the children of the current node
        :return type: list of TreeNode
        """
        if len(self.down) == 0:
            # return [self]
            return []
        return self.down

    def get_variable_name(self):
        """
        Returns the name of the variable correspondent to the current node
        :return type: str
        """
        return self.variable_name

    def get_variable_value(self):
        """
        Returns the value of the variable correspondent to the current node
        :return type: str or int
        """
        return self.variable_value

    def set_variable_name(self, name):
        """
        Sets the name of the variable for the current node
        :param name: Name of the variable (type: str)
        :return None
        """
        self.variable_name = name

    def set_variable_value(self, value):
        """
        Sets the value of the variable for the current node
        :param value: value of the variable (type: str)
        """
        self.variable_value = value

    def get_path(self):
        """
        Returns all the path from the current node to the root of the tree.
        """
        ret_val = []
        if not self.up:
            ret_val.append(self)
            return ret_val
        for node in self.up.get_path():
            ret_val.append(node)
        ret_val.append(self)

    def __str__(self):
        return str(self.variable_name) + " --> " + str(self.variable_value)

    def __repr__(self):
        return str(self.variable_name) + " = " + str(self.variable_value)

    def _get_leaves(node, leaves):
        """
        Returns all the leaves of a tree.
        It changes the "leaves" list.
        :param node: root of the tree (type: TreeNode)
        :param leaves: partial list of leaves (type: list of TreeNode)
        :return type: None
        """
        children = node.get_children()
        if len(children) == 0:
            leaves.append(node)
            return
        for child in children:
            TreeNode._get_leaves(child, leaves)

    def get_leaves(node):
        """
        :param node: root of the tree (TreeNode)
        :return type: list
        """
        leaves = list()
        TreeNode._get_leaves(node, leaves)
        return leaves

template_name = fp.EXPERIMENT_TEMPLATE_NAME

def generates_templates(base_heat_template, deployment_configuration):
    """
    Generates the heat templates for the experiments
    :return: None
    """
    # Load useful parameters from file
    template_dir = common.get_template_dir()
    template_file_extension = fp.TEMPLATE_FILE_EXTENSION
    template_base_name = base_heat_template

    variables = deployment_configuration

    # Delete the templates eventually generated in previous running of the
    # framework
    common.LOG.info("Removing the heat templates previously generated")
    command = "rm {}{}_*".format(template_dir, template_name)
    os.system(command)

    # Creation of the tree with all the new configurations
    common.LOG.info("Creation of the tree with all the new configurations")
    tree = TreeNode()
    for variable in variables:
        leaves = TreeNode.get_leaves(tree)
        common.LOG.debug("LEAVES: " + str(leaves))
        common.LOG.debug("VALUES: " + str(variables[variable]))

        for value in variables[variable]:
            for leaf in leaves:
                new_node = TreeNode()
                new_node.set_variable_name(variable)
                new_node.set_variable_value(value)
                leaf.add_child(new_node)

    common.LOG.debug("CONFIGURATION TREE: " + str(tree))

    common.LOG.info("Heat Template and metadata file creation")
    leaves = TreeNode.get_leaves(tree)
    counter = 1
    for leaf in leaves:
        heat_template_vars = leaf.get_path()
        if os.path.isabs(template_base_name):
            base_template = template_base_name
        else:
            base_template = template_dir + template_base_name
        new_template = template_dir + template_name
        new_template += "_" + str(counter) + template_file_extension
        shutil.copy(base_template, new_template)

        metadata = dict()
        for var in heat_template_vars:
            if var.get_variable_name():
                common.replace_in_file(new_template, "#" +
                                       var.get_variable_name(),
                                       var.get_variable_value())
                metadata[var.get_variable_name()] = var.get_variable_value()

        # Save the metadata on a JSON file
        with open(new_template + ".json", 'w') as outfile:
            json.dump(metadata, outfile)

        common.LOG.debug("Heat Templates and Metadata file " + str(counter) +
                         " created")
        counter += 1

    # Creation of the template files
    common.LOG.info(str(counter - 1) + " Heat Templates and Metadata files "
                                       "created")

def get_all_heat_templates(template_dir, template_file_extension):
    """
    Loads and returns all the generated heat templates
    :param template_dir: directory to search in (type: str)
    :param template_file_extension: extension of the file for templates
            (type: str)
    :return: type: list
    """
    template_files = list()
    for dirname, dirnames, filenames in os.walk(template_dir):
        for filename in filenames:
            if template_file_extension in filename and \
                    filename.endswith(template_file_extension) and \
                    template_name in filename:
                template_files.append(filename)
    template_files.sort()
    return template_files

#
#
#

# Directories and file locations
EXPERIMENTAL_FRAMEWORK_DIR = 'experimental_framework/'
EXPERIMENT_TEMPLATE_NAME = 'experiment'
TEMPLATE_FILE_EXTENSION = '.yaml'
DPDK_PKTGEN_DIR = 'packet_generators/dpdk_pktgen/'
PCAP_DIR = 'packet_generators/pcap_files/'

def get_supported_packet_generators():
    return [
        cfs.CFSP_PG_NONE,
        cfs.CFSP_PG_DPDK
        # Add here any other supported packet generator
    ]

#

class Perf(base.Scenario):
    """Execute perf benchmark in a host

    events - perf tool software, hardware or tracepoint events
        type:       [str]
        unit:       na
        default:    ['task-clock']
    load - simulate load on the host by doing IO operations
        type:       bool
        unit:       na
        default:    false

    For more info about perf and perf events see https://perf.wiki.kernel.org
    """

    __scenario_type__ = "Perf"

    TARGET_SCRIPT = 'perf_benchmark.bash'

            'yardstick.benchmark.scenarios.compute', Perf.TARGET_SCRIPT)

        self.client.run("cat > ~/perf_benchmark.sh",

        events = options.get('events', ['task-clock'])

        events_string = ""
        for event in events:
            events_string += event + " "

        else:
            duration = 30

        if 'load' in options:
            load = "dd if=/dev/urandom of=/dev/null"
        else:
            load = "sleep %d" % duration

        cmd = "sudo bash perf_benchmark.sh '%s' %d %s" \
            % (load, duration, events_string)

        if status:
            raise RuntimeError(stdout)

            metric = self.scenario_cfg['sla']['metric']
            exp_val = self.scenario_cfg['sla']['expected_value']
            smaller_than_exp = 'smaller_than_expected' \
                               in self.scenario_cfg['sla']

            if metric not in result:
                assert False, "Metric (%s) not found." % metric
            else:
                if smaller_than_exp:
                    assert result[metric] < exp_val, "%s %d >= %d (sla); " \
                        % (metric, result[metric], exp_val)
                else:
                    assert result[metric] >= exp_val, "%s %d < %d (sla); " \

    ctx = {
        'host': {
        }
    }

    options = {'load': True}
    result = {}

    p = Perf(args, ctx)

    _test()

#
#
#

import experimental_framework.benchmarking_unit as b_unit
from experimental_framework import heat_template_generation, common

class FrameworkApi(object):

    def init():
        """
        Initializes the Framework

        """
        common.init(api=True)

    # @staticmethod
    # def get_available_test_cases():
    #     """
    #     Returns a list of available test cases.
    #     This list include eventual modules developed by the user, if any.
    #     Each test case is returned as a string that represents the full name
    #     of the test case and that can be used to get more information
    #     calling get_test_case_features(test_case_name)
    #
    #     :return: list of strings
    #     """
    #     return b_unit.BenchmarkingUnit.get_available_test_cases()

    def get_test_case_features(test_case):
        """
        Returns a list of features (description, requested parameters,
        allowed values, etc.) for a specified test case.

        :param test_case: name of the test case (string)
                          The string represents the test case and can be
                          obtained  calling  "get_available_test_cases()"
                          method.

        :return: dict() containing the features of the test case
        """
        if not isinstance(test_case, str):
            raise ValueError('The provided test_case parameter has to be '
                             'a string')
        benchmark = b_unit.BenchmarkingUnit.get_required_benchmarks(
            [test_case])[0]
        return benchmark.get_features()

    def execute_framework(
            test_cases,
            iterations,
            heat_template,
            heat_template_parameters,
            deployment_configuration,
            openstack_credentials
    ):
        """
        Executes the framework according the inputs

        :param test_cases: Test cases to be ran on the workload
                            (dict() of dict())

                            Example:
                            test_case = dict()
                            test_case['name'] = 'module.Class'
                            test_case['params'] = dict()
                            test_case['params']['throughput'] = '1'
                            test_case['params']['vlan_sender'] = '1007'
                            test_case['params']['vlan_receiver'] = '1006'
                            test_cases = [test_case]

        :param iterations: Number of cycles to be executed (int)

        :param heat_template: (string) File name of the heat template of the
                            workload to be deployed. It contains the
                            parameters to be evaluated in the form of
                            #parameter_name. (See heat_templates/vTC.yaml as
                            example).

        :param heat_template_parameters: (dict) Parameters to be provided
                            as input to the heat template.
                            See http://docs.openstack.org/developer/heat/
                            template_guide/hot_guide.html - section
                            "Template input parameters" for further info.

        :param deployment_configuration: ( dict[string] = list(strings) ) )
                            Dictionary of parameters representing the
                            deployment configuration of the workload
                            The key is a string corresponding to the name of
                            the parameter, the value is a list of strings
                            representing the value to be assumed by a specific
                            param.
                            The parameters are user defined: they have to
                            correspond to the place holders (#parameter_name)
                            specified in the heat template.

        :return: dict() Containing results
        """

        common.InputValidation.validate_os_credentials(openstack_credentials)
        credentials = openstack_credentials

        msg = 'The provided heat_template does not exist'
        template = "{}{}".format(common.get_template_dir(), heat_template)
        common.InputValidation.validate_file_exist(template, msg)

        msg = 'The provided iterations variable must be an integer value'
        common.InputValidation.validate_integer(iterations, msg)

        msg = 'The provided heat_template_parameters variable must be a ' \
              'dictionary'
        common.InputValidation.validate_dictionary(heat_template_parameters,
                                                   msg)
        log_msg = "Generation of all the heat templates " \
                  "required by the experiment"
        common.LOG.info(log_msg)
        heat_template_generation.generates_templates(heat_template,
                                                     deployment_configuration)
        benchmarking_unit = \
            b_unit.BenchmarkingUnit(
                heat_template, credentials, heat_template_parameters,
                iterations, test_cases)
        try:
            common.LOG.info("Benchmarking Unit initialization")
            benchmarking_unit.initialize()
            common.LOG.info("Benchmarking Unit Running")
            results = benchmarking_unit.run_benchmarks()
        finally:
            common.LOG.info("Benchmarking Unit Finalization")
            benchmarking_unit.finalize()
        return results

#
#
#

# yardstick comment: this is a modified copy of rally/rally/common/utils.py

import os
import sys
from oslo_utils import importutils

import yardstick

# Decorator for cli-args
def cliargs(*args, **kwargs):
    def _decorator(func):
        func.__dict__.setdefault('arguments', []).insert(0, (args, kwargs))
        return func
    return _decorator

def itersubclasses(cls, _seen=None):
    """Generator over all subclasses of a given class in depth first order."""

    if not isinstance(cls, type):
        raise TypeError("itersubclasses must be called with "
                        "new-style classes, not %.100r" % cls)
    _seen = _seen or set()
    try:
        subs = cls.__subclasses__()
    except TypeError:   # fails only when cls is type
        subs = cls.__subclasses__(cls)
    for sub in subs:
        if sub not in _seen:
            _seen.add(sub)
            yield sub
            for sub in itersubclasses(sub, _seen):
                yield sub

def try_append_module(name, modules):
    if name not in modules:
        modules[name] = importutils.import_module(name)

def import_modules_from_package(package):
    """Import modules from package and append into sys.modules

    :param: package - Full package name. For example: rally.deploy.engines
    """
    path = [os.path.dirname(yardstick.__file__), ".."] + package.split(".")
    path = os.path.join(*path)
    for root, dirs, files in os.walk(path):
        for filename in files:
            if filename.startswith("__") or not filename.endswith(".py"):
                continue
            new_package = ".".join(root.split(os.sep)).split("....")[1]
            module_name = "%s.%s" % (new_package, filename[:-3])
            try_append_module(module_name, sys.modules)

#
# bulk data test and req/rsp test are supported

class Netperf(base.Scenario):
    """Execute netperf between two hosts

    testname - to specify the test you wish to perform.
    the valid testnames are TCP_STREAM, TCP_RR, UDP_STREAM, UDP_RR
        unit:    na
        default: TCP_STREAM
    send_msg_size - value set the local send size to value bytes.
        type:    int
        default: na
    recv_msg_size - setting the receive size for the remote system.
        type:    int
    req_rsp_size - set the request and/or response sizes based on sizespec.
        unit:    na
        type:    int

    read link below for more netperf args description:
    http://www.netperf.org/netperf/training/Netperf.html
    """
    __scenario_type__ = "Netperf"

    TARGET_SCRIPT = 'netperf_benchmark.bash'

            Netperf.TARGET_SCRIPT)

        # netserver start automatically during the vm boot

        self.client.run("cat > ~/netperf.sh",

        # get global options
        ipaddr = self.context_cfg['target'].get("ipaddr", '127.0.0.1')
        testname = options.get("testname", 'TCP_STREAM')
            testlen = duration_time
            testlen = arithmetic_time
        else:
            testlen = 20

        cmd_args = "-H %s -l %s -t %s" % (ipaddr, testlen, testname)

        # get test specific options
        default_args = "-O 'THROUGHPUT,THROUGHPUT_UNITS,MEAN_LATENCY'"
        cmd_args += " -- %s" % default_args
        option_pair_list = [("send_msg_size", "-m"),
                            ("recv_msg_size", "-M"),
                            ("req_rsp_size", "-r")]
        for option_pair in option_pair_list:
            if option_pair[0] in options:
                cmd_args += " %s %s" % (option_pair[1],
                                        options[option_pair[0]])

        cmd = "sudo bash netperf.sh %s" % (cmd_args)

        if status:

        if result['mean_latency'] == '':

        # sla check
        mean_latency = float(result['mean_latency'])
            sla_max_mean_latency = int(
                self.scenario_cfg["sla"]["mean_latency"])

            assert mean_latency <= sla_max_mean_latency, \
                "mean_latency %f > sla_max_mean_latency(%f); " % \
                (mean_latency, sla_max_mean_latency)

    ctx = {
        "host": {
        },
            "ipaddr": "10.229.47.137"
        }
    }

    options = {
        "testname": 'TCP_STREAM'
    }

    result = {}

    netperf = Netperf(args, ctx)
    netperf.run(result)

    _test()

#

class MonitorProcess(basemonitor.BaseMonitor):

    __monitor_type__ = "process"

        host = self._context[self._config["host"]]

            "ha_tools/check_process_python.bash")
        self.process_name = self._config["process_name"]

            "/bin/sh -s {0}".format(self.process_name),
        if not stdout or int(stdout) <= 0:
            LOG.info("the process (%s) is not running!" % self.process_name)

        max_outage_time = self._config["sla"]["max_recover_time"]
            LOG.error("SLA failure: %f > %f" % (outage_time, max_outage_time))
        else:

    host = {
    }
    config = {
        'monitor_type': 'process',
        'process_name': 'nova-api',
        'host': "node1",
        'sla': {'max_recover_time': 5}
    }

    _test()

#

class Unixbench(base.Scenario):
    """Execute Unixbench cpu benchmark in a host
    The Run script takes a number of options which you can use to customise a
    test, and you can specify the names of the tests to run.  The full usage
    is:

    Run [ -q | -v ] [-i <n> ] [-c <n> [-c <n> ...]] [test ...]

    -i <count>    Run <count> iterations for each test -- slower tests
                use <count> / 3, but at least 1.  Defaults to 10 (3 for
                slow tests).
    -c <n>        Run <n> copies of each test in parallel.

    Parameters for setting unixbench
        run_mode - Run in quiet mode or verbose mode
            unit:       None
            default:    None
        test_type - The available tests are organised into categories;
            unit:       None
        iterations - Run <count> iterations for each test -- slower tests
        use <count> / 3, but at least 1.  Defaults to 10 (3 for slow tests).
            type:       int
            unit:       None
        copies - Run <n> copies of each test in parallel.
            type:       int
            unit:       None

    more info https://github.com/kdlucas/byte-unixbench/blob/master/UnixBench
    """
    __scenario_type__ = "UnixBench"

    TARGET_SCRIPT = "unixbench_benchmark.bash"

            Unixbench.TARGET_SCRIPT)

        self.client.run("cat > ~/unixbench_benchmark.sh",
                        stdin=open(self.target_script, 'rb'))

        run_mode = options.get("run_mode", None)
        LOG.debug("Executing run_mode: %s", run_mode)
        cmd_args = ""
        if run_mode == "quiet":
            cmd_args = "-q"
        elif run_mode == "verbose":
            cmd_args = "-v"

        option_pair_list = [("iterations", "-i"),
                            ("copies", "-c")]
                cmd_args += " %s %s " % (option_pair[1],
                                         options[option_pair[0]])

        test_type = options.get("test_type", None)
        if test_type is not None:
            cmd_args += " %s " % (test_type)

        cmd = "sudo bash unixbench_benchmark.sh %s" % (cmd_args)
        if status:

            for t, score in result.items():
                if t not in self.scenario_cfg['sla']:
                    continue
                sla_score = float(self.scenario_cfg['sla'][t])
                score = float(score)
                if score < sla_score:
                    sla_error += "%s score %f < sla:%s_score(%f); " % \
                        (t, score, t, sla_score)

    ctx = {
        'host': {
        }
    }

    options = {
        'test_type': 'dhrystone',
        'run_mode': 'verbose'
    }

    result = {}

    p = Unixbench(args, ctx)

    _test()

#

# iperf3 scenario
# iperf3 homepage at: http://software.es.net/iperf/

class Iperf(base.Scenario):
    """Execute iperf3 between two hosts

By default TCP is used but UDP can also be configured.
For more info see http://software.es.net/iperf

    bytes - number of bytes to transmit
      only valid with a non duration runner, mutually exclusive with blockcount
        type:    int
    udp - use UDP rather than TCP
        type:    bool
        unit:    na
        default: false
    nodelay - set TCP no delay, disabling Nagle's Algorithm
        type:    bool
        unit:    na
    blockcount - number of blocks (packets) to transmit,
      only valid with a non duration runner, mutually exclusive with bytes
        type:    int
        default: -
    """
    __scenario_type__ = "Iperf3"

        self.target = ssh.SSH(target_user, target_ip,
        self.target.wait(timeout=600)

        self.host = ssh.SSH(host_user, host_ip,
                            key_filename=host_key_filename)

        cmd = "iperf3 -s -D"
        LOG.debug("Starting iperf3 server with command: %s", cmd)
        status, _, stderr = self.target.execute(cmd)
        if status:

        LOG.debug("teardown")
        self.host.close()
        status, stdout, stderr = self.target.execute("pkill iperf3")
        if status:
            LOG.warn(stderr)
        self.target.close()

        # if run by a duration runner, get the duration time and setup as arg
        time = self.scenario_cfg["runner"].get("duration", None) \

        cmd = "iperf3 -c %s --json" % (self.context_cfg['target']['ipaddr'])

        # If there are no options specified
        if not options:

        use_UDP = False
        if "udp" in options:
            cmd += " --udp"
            use_UDP = True
            if "bandwidth" in options:
                cmd += " --bandwidth %s" % options["bandwidth"]
        else:
            # tcp obviously
            if "nodelay" in options:
                cmd += " --nodelay"

        # these options are mutually exclusive in iperf3
        if time:
            cmd += " %d" % time
        elif "bytes" in options:
            # number of bytes to transmit (instead of --time)
            cmd += " --bytes %d" % options["bytes"]
        elif "blockcount" in options:
            cmd += " --blockcount %d" % options["blockcount"]

        status, stdout, stderr = self.host.execute(cmd)
        if status:
            # error cause in json dict on stdout

        # Note: convert all ints to floats in order to avoid
        # schema conflicts in influxdb. We probably should add
        # a format func in the future.
        result.update(json.loads(stdout, parse_int=float))

            sla_iperf = self.scenario_cfg["sla"]
            if not use_UDP:
                sla_bytes_per_second = int(sla_iperf["bytes_per_second"])

                # convert bits per second to bytes per second
                bit_per_second = \
                    int(result["end"]["sum_received"]["bits_per_second"])
                bytes_per_second = bit_per_second / 8
                assert bytes_per_second >= sla_bytes_per_second, \
                    "bytes_per_second %d < sla:bytes_per_second (%d); " % \
                    (bytes_per_second, sla_bytes_per_second)
            else:
                sla_jitter = float(sla_iperf["jitter"])

                jitter_ms = float(result["end"]["sum"]["jitter_ms"])
                assert jitter_ms <= sla_jitter, \
                    "jitter_ms  %f > sla:jitter %f; " % \
                    (jitter_ms, sla_jitter)

    ctx = {
        'host': {
        },
        }
    }

    result = {}

    p = Iperf(args, ctx)

    _test()

class Sfc(base.Scenario):
    ''' SFC scenario class '''

    __scenario_type__ = "sfc"

    PRE_SETUP_SCRIPT = 'sfc_pre_setup.bash'
    TACKER_SCRIPT = 'sfc_tacker.bash'
    SERVER_SCRIPT = 'sfc_server.bash'
    TEARDOWN_SCRIPT = "sfc_teardown.bash"

        self.teardown_done = False

        self.tacker_script = pkg_resources.resource_filename(
            Sfc.TACKER_SCRIPT)

        self.server_script = pkg_resources.resource_filename(
            Sfc.SERVER_SCRIPT)

        ''' calling Tacker to instantiate VNFs and Service Chains '''
        cmd_tacker = "%s" % (self.tacker_script)
        subprocess.call(cmd_tacker, shell=True)

        target_user = target.get('user', 'root')
        target_pwd = target.get('password', 'octopus')

        ''' webserver start automatically during the vm boot '''
        self.server = ssh.SSH(target_user, target_ip, password=target_pwd)
        self.server.run("cat > ~/server.sh",
                        stdin=open(self.server_script, "rb"))
        cmd_server = "sudo bash server.sh"
        LOG.debug("Executing command: %s", cmd_server)
        status, stdout, stderr = self.server.execute(cmd_server)
        LOG.debug("Output server command: %s", status)

        ''' Creating client and server VMs to perform the test'''
        host_user = host.get('user', 'cirros')
        host_pwd = host.get('password', 'cubswin:)')

        cmd_client = "curl %s", target_ip
        LOG.debug("Executing command: %s", cmd_client)
        result = self.client.execute(cmd_client)
        LOG.debug("Output client command: %s", result)

        ''' for scenario teardown remove tacker VNFs, chains and classifiers'''
            "yardstick.benchmark.scenarios.sfc",
            Sfc.TEARDOWN_SCRIPT)

'''def _test():

    internal test function
    logger = logging.getLogger("Sfc Yardstick")

    result = {}

    sfc = Sfc()
    sfc.setup()
    sfc.run(result)
    sfc.teardown()

    _test()'''

#
#
#

import os
import re
import ConfigParser
import fileinput
from experimental_framework.constants import conf_file_sections as cf

# List of common variables

LOG = None
CONF_FILE = None
DEPLOYMENT_UNIT = None
ITERATIONS = None

BASE_DIR = None
RESULT_DIR = None
TEMPLATE_DIR = None
TEMPLATE_NAME = None
TEMPLATE_FILE_EXTENSION = None

PKTGEN = None
PKTGEN_DIR = None
PKTGEN_DPDK_DIRECTORY = None
PKTGEN_PROGRAM = None
PKTGEN_COREMASK = None
PKTGEN_MEMCHANNEL = None
PKTGEN_BUS_SLOT_NIC_1 = None
PKTGEN_BUS_SLOT_NIC_2 = None
PKTGEN_NAME_NIC_1 = None
PKTGEN_NAME_NIC_2 = None

INFLUXDB_IP = None
INFLUXDB_PORT = None
INFLUXDB_DB_NAME = None

# Initialization and Input 'heat_templates/'validation

def init(api=False):
    global BASE_DIR
    # BASE_DIR = os.getcwd()
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    BASE_DIR = BASE_DIR.replace('/experimental_framework', '')
    BASE_DIR = InputValidation.validate_directory_exist_and_format(
        BASE_DIR, "Error 000001")

    init_conf_file(api)
    init_log()
    init_general_vars(api)
    if len(CONF_FILE.get_variable_list(cf.CFS_PKTGEN)) > 0:
        init_pktgen()

def init_conf_file(api=False):
    global CONF_FILE
    if api:
        CONF_FILE = ConfigurationFile(cf.get_sections_api(),
                                      '/tmp/apexlake/apexlake.conf')
    else:
        CONF_FILE = ConfigurationFile(cf.get_sections(),

def init_general_vars(api=False):
    global TEMPLATE_FILE_EXTENSION
    global TEMPLATE_NAME
    global TEMPLATE_DIR
    global RESULT_DIR
    global ITERATIONS

    TEMPLATE_FILE_EXTENSION = '.yaml'

    # Check Section in Configuration File
    InputValidation.\
        validate_configuration_file_section(
            cf.CFS_GENERAL,
            "Section " + cf.CFS_GENERAL +
            "is not present in configuration file")

    TEMPLATE_DIR = '/tmp/apexlake/heat_templates/'
    # if not os.path.exists(TEMPLATE_DIR):
    #     os.makedirs(TEMPLATE_DIR)
    # cmd = "cp /tmp/apexlake/heat_templates/*.yaml {}".format(TEMPLATE_DIR)
    # run_command(cmd)

    if not api:
        # Validate template name
        InputValidation.\
            validate_configuration_file_parameter(
                cf.CFS_GENERAL,
                cf.CFSG_TEMPLATE_NAME,
                "Parameter " + cf.CFSG_TEMPLATE_NAME +
                "is not present in configuration file")
        TEMPLATE_NAME = CONF_FILE.get_variable(cf.CFS_GENERAL,
                                               cf.CFSG_TEMPLATE_NAME)
        InputValidation.validate_file_exist(
            TEMPLATE_DIR + TEMPLATE_NAME,
            "The provided template file does not exist")

    RESULT_DIR = "/tmp/apexlake/results/"
    if not os.path.isdir(RESULT_DIR):
        os.mkdir(RESULT_DIR)

    # Validate and assign Iterations
    if cf.CFSG_ITERATIONS in CONF_FILE.get_variable_list(cf.CFS_GENERAL):
        ITERATIONS = int(CONF_FILE.get_variable(cf.CFS_GENERAL,
                                                cf.CFSG_ITERATIONS))
    else:
        ITERATIONS = 1

def init_log():
    global LOG
    LOG = logging.getLogger()
    LOG.setLevel(level=logging.INFO)
    log_formatter = logging.Formatter("%(asctime)s --- %(message)s")
    file_handler = logging.FileHandler("{0}/{1}.log".format("./", "benchmark"))
    file_handler.setFormatter(log_formatter)
    file_handler.setLevel(logging.DEBUG)
    LOG.addHandler(file_handler)

# InfluxDB conf variables
def init_influxdb():
    global INFLUXDB_IP
    global INFLUXDB_PORT
    global INFLUXDB_DB_NAME

    INFLUXDB_IP = CONF_FILE.get_variable(cf.CFS_INFLUXDB, cf.CFSI_IDB_IP)
    INFLUXDB_PORT = CONF_FILE.get_variable(cf.CFS_INFLUXDB, cf.CFSI_IDB_PORT)
    INFLUXDB_DB_NAME = CONF_FILE.get_variable(cf.CFS_INFLUXDB,
                                              cf.CFSI_IDB_DB_NAME)

# Packet Generator conf variables
def init_pktgen():
    global PKTGEN
    global PKTGEN_DIR
    global PKTGEN_PROGRAM
    global PKTGEN_COREMASK
    global PKTGEN_MEMCHANNEL
    global PKTGEN_BUS_SLOT_NIC_1
    global PKTGEN_BUS_SLOT_NIC_2
    global PKTGEN_DPDK_DIRECTORY
    global PKTGEN_NAME_NIC_1
    global PKTGEN_NAME_NIC_2

    msg = "Section {} is not present in the configuration file".\
        format(cf.CFS_PKTGEN)
    InputValidation.validate_configuration_file_section(cf.CFS_PKTGEN, msg)

    pktgen_var_list = CONF_FILE.get_variable_list(cf.CFS_PKTGEN)
    PKTGEN = 'dpdk_pktgen'  # default value
    if cf.CFSP_PACKET_GENERATOR in pktgen_var_list:
        msg = "Parameter {} is not present in section {}".format(
            cf.CFSP_PACKET_GENERATOR, cf.CFS_PKTGEN)
        InputValidation.validate_configuration_file_parameter(
            cf.CFS_PKTGEN, cf.CFSP_PACKET_GENERATOR, msg)
        PKTGEN = CONF_FILE.get_variable(
            cf.CFS_PKTGEN, cf.CFSP_PACKET_GENERATOR)

    if PKTGEN not in fp.get_supported_packet_generators():
        raise ValueError('The specified packet generator is not supported '
                         'by the framework')

    # Check if the packet gen is dpdk_pktgen
    if PKTGEN == cf.CFSP_PG_DPDK:
        # Validation of DPDK pktgen directory
            cf.CFSP_DPDK_PKTGEN_DIRECTORY, cf.CFS_PKTGEN)
            cf.CFS_PKTGEN, cf.CFSP_DPDK_PKTGEN_DIRECTORY, msg)
        PKTGEN_DIR = CONF_FILE.get_variable(
            cf.CFS_PKTGEN, cf.CFSP_DPDK_PKTGEN_DIRECTORY)
        msg = "The directory {} does not exist.".format(PKTGEN_DIR)
        PKTGEN_DIR = InputValidation.validate_directory_exist_and_format(
            PKTGEN_DIR, msg)

        # Validation of the DPDK program name
            cf.CFSP_DPDK_PROGRAM_NAME, cf.CFS_PKTGEN)
            cf.CFS_PKTGEN, cf.CFSP_DPDK_PROGRAM_NAME, msg)
        PKTGEN_PROGRAM = CONF_FILE.get_variable(
            cf.CFS_PKTGEN, cf.CFSP_DPDK_PROGRAM_NAME)

        # Validation of the DPDK Coremask parameter
            cf.CFSP_DPDK_COREMASK, cf.CFS_PKTGEN)
            cf.CFS_PKTGEN, cf.CFSP_DPDK_COREMASK, msg)
        PKTGEN_COREMASK = CONF_FILE.get_variable(
            cf.CFS_PKTGEN, cf.CFSP_DPDK_COREMASK)

        # Validation of the DPDK Memory Channel parameter
            cf.CFSP_DPDK_MEMORY_CHANNEL, cf.CFS_PKTGEN)
            cf.CFS_PKTGEN, cf.CFSP_DPDK_MEMORY_CHANNEL, msg)
        PKTGEN_MEMCHANNEL = CONF_FILE.get_variable(
            cf.CFS_PKTGEN, cf.CFSP_DPDK_MEMORY_CHANNEL)

        # Validation of the DPDK Bus Slot 1
            cf.CFSP_DPDK_BUS_SLOT_NIC_1, cf.CFS_PKTGEN)
            cf.CFS_PKTGEN, cf.CFSP_DPDK_BUS_SLOT_NIC_1, msg)
        PKTGEN_BUS_SLOT_NIC_1 = CONF_FILE.get_variable(
            cf.CFS_PKTGEN, cf.CFSP_DPDK_BUS_SLOT_NIC_1)

        # Validation of the DPDK Bus Slot 2
            cf.CFSP_DPDK_BUS_SLOT_NIC_2, cf.CFS_PKTGEN)
            cf.CFS_PKTGEN, cf.CFSP_DPDK_BUS_SLOT_NIC_2, msg)
        PKTGEN_BUS_SLOT_NIC_2 = CONF_FILE.get_variable(
            cf.CFS_PKTGEN, cf.CFSP_DPDK_BUS_SLOT_NIC_2)

        # Validation of the DPDK NIC 1
            cf.CFSP_DPDK_NAME_IF_1, cf.CFS_PKTGEN)
            cf.CFS_PKTGEN, cf.CFSP_DPDK_NAME_IF_1, msg)
        PKTGEN_NAME_NIC_1 = CONF_FILE.get_variable(
            cf.CFS_PKTGEN, cf.CFSP_DPDK_NAME_IF_1)

        # Validation of the DPDK NIC 2
            cf.CFSP_DPDK_NAME_IF_2, cf.CFS_PKTGEN)
            cf.CFS_PKTGEN, cf.CFSP_DPDK_NAME_IF_2, msg)
        PKTGEN_NAME_NIC_2 = CONF_FILE.get_variable(
            cf.CFS_PKTGEN, cf.CFSP_DPDK_NAME_IF_2)

        # Validation of DPDK directory parameter
            cf.CFSP_DPDK_DPDK_DIRECTORY, cf.CFS_PKTGEN)
            cf.CFS_PKTGEN, cf.CFSP_DPDK_DPDK_DIRECTORY, msg)
        PKTGEN_DPDK_DIRECTORY = CONF_FILE.get_variable(
            cf.CFS_PKTGEN, cf.CFSP_DPDK_DPDK_DIRECTORY)
        msg = "Directory {} does not exist".format(
            cf.CFSP_DPDK_DPDK_DIRECTORY)
        PKTGEN_DPDK_DIRECTORY = InputValidation.\
            validate_directory_exist_and_format(PKTGEN_DPDK_DIRECTORY, msg)

# Configuration file access

class ConfigurationFile:
    """
    Used to extract data from the configuration file
    """

    def __init__(self, sections, config_file='conf.cfg'):
        """
        Reads configuration file sections

        :param sections: list of strings representing the sections to be
                         loaded
        :param config_file: name of the configuration file (string)
        """
        InputValidation.validate_string(
            config_file, "The configuration file name must be a string")
        # config_file = BASE_DIR + config_file
            config_file, 'The provided configuration file does not exist')
        self.config = ConfigParser.ConfigParser()
        self.config.read(config_file)
        for section in sections:
            setattr(
                self, section, ConfigurationFile.
                _config_section_map(section, self.config))

    def _config_section_map(section, config_file):
        """
        Returns a dictionary with the configuration values for the specific
        section

        :param section: section to be loaded (string)
        :return: dict
        """
        dict1 = dict()
        options = config_file.options(section)
        for option in options:
            dict1[option] = config_file.get(section, option)
        return dict1

    def get_variable(self, section, variable_name):
        """
        Returns the value correspondent to a variable

        :param variable_name: name of the variable (string)
        :return: string
        """
        message = "The variable name must be a string"
        InputValidation.validate_string(variable_name, message)
        if variable_name in self.get_variable_list(section):
            sect = getattr(self, section)
            return sect[variable_name]
        else:
            exc_msg = 'Parameter {} is not in the {} section of the ' \
                      'conf file'.format(variable_name, section)
            raise ValueError(exc_msg)

    def get_variable_list(self, section):
        """
        Returns the list of the available variables in a section
        :return: list
        """
        try:
            return getattr(self, section)
        except:
            msg = 'Section {}  not found in the configuration file'.\
                format(section)
            raise ValueError(msg)

# Get OpenStack Credentials
def get_credentials():
    """
    Returns the credentials for OpenStack access from the configuration file
    :return: dictionary
    """
    credentials = dict()
    credentials[cf.CFSO_IP_CONTROLLER] = CONF_FILE.get_variable(
        cf.CFS_OPENSTACK, cf.CFSO_IP_CONTROLLER)
    credentials[cf.CFSO_HEAT_URL] = CONF_FILE.get_variable(
        cf.CFS_OPENSTACK, cf.CFSO_HEAT_URL)
    credentials[cf.CFSO_USER] = CONF_FILE.get_variable(
        cf.CFS_OPENSTACK, cf.CFSO_USER)
    credentials[cf.CFSO_PASSWORD] = CONF_FILE.get_variable(
        cf.CFS_OPENSTACK, cf.CFSO_PASSWORD)
    credentials[cf.CFSO_AUTH_URI] = CONF_FILE.get_variable(
        cf.CFS_OPENSTACK, cf.CFSO_AUTH_URI)
    credentials[cf.CFSO_PROJECT] = CONF_FILE.get_variable(
        cf.CFS_OPENSTACK, cf.CFSO_PROJECT)
    return credentials

# Manage files

def get_heat_template_params():
    """
    Returns the list of deployment parameters from the configuration file
    for the heat template

    :return: dict
    """
    heat_parameters_list = CONF_FILE.get_variable_list(
        cf.CFS_DEPLOYMENT_PARAMETERS)
    testcase_parameters = dict()
    for param in heat_parameters_list:
        testcase_parameters[param] = CONF_FILE.get_variable(
            cf.CFS_DEPLOYMENT_PARAMETERS, param)
    return testcase_parameters

def get_testcase_params():
    """
    Returns the list of testcase parameters from the configuration file

    """
    parameters = CONF_FILE.get_variable_list(cf.CFS_TESTCASE_PARAMETERS)
    for param in parameters:
            cf.CFS_TESTCASE_PARAMETERS, param)

def get_file_first_line(file_name):
    """
    Returns the first line of a file

    :param file_name: name of the file to be read (str)
    :return: str
    """
    message = "The name of the file must be a string"
    InputValidation.validate_string(file_name, message)
    message = 'The file {} does not exist'.format(file_name)
    InputValidation.validate_file_exist(file_name, message)
    res = open(file_name, 'r')
    return res.readline()

def replace_in_file(file, text_to_search, text_to_replace):
    """
    Replaces a string within a file

    :param file: name of the file (str)
    :param text_to_search: text to be replaced
    :param text_to_replace: new text that will replace the previous
    """
    message = 'The text to be replaced in the file must be a string'
    InputValidation.validate_string(text_to_search, message)
    message = 'The text to replace in the file must be a string'
    InputValidation.validate_string(text_to_replace, message)
    InputValidation.validate_string(file, message)
    message = "The file does not exist"
    InputValidation.validate_file_exist(file, message)
    for line in fileinput.input(file, inplace=True):
        print(line.replace(text_to_search, text_to_replace).rstrip())

# Shell interaction
def run_command(command):
    LOG.info("Running command: {}".format(command))
    return os.system(command)

def push_data_influxdb(data):
    ip = INFLUXDB_IP
    port = INFLUXDB_PORT
    db_name = INFLUXDB_DB_NAME
    command = "curl -i -XPOST 'http://{}:{}/write?db={}' " \
              "--data-binary {}".format(ip, port, db_name, data)
    run_command(command)

# Expose variables to other modules

def get_base_dir():
    return BASE_DIR

def get_template_dir():
    return TEMPLATE_DIR

def get_result_dir():
    return RESULT_DIR

def get_dpdk_pktgen_vars():
    if not (PKTGEN == 'dpdk_pktgen'):
    ret_val = dict()
    ret_val[cf.CFSP_DPDK_PKTGEN_DIRECTORY] = PKTGEN_DIR
    ret_val[cf.CFSP_DPDK_DPDK_DIRECTORY] = PKTGEN_DPDK_DIRECTORY
    ret_val[cf.CFSP_DPDK_PROGRAM_NAME] = PKTGEN_PROGRAM
    ret_val[cf.CFSP_DPDK_COREMASK] = PKTGEN_COREMASK
    ret_val[cf.CFSP_DPDK_MEMORY_CHANNEL] = PKTGEN_MEMCHANNEL
    ret_val[cf.CFSP_DPDK_BUS_SLOT_NIC_1] = PKTGEN_BUS_SLOT_NIC_1
    ret_val[cf.CFSP_DPDK_BUS_SLOT_NIC_2] = PKTGEN_BUS_SLOT_NIC_2
    ret_val[cf.CFSP_DPDK_NAME_IF_1] = PKTGEN_NAME_NIC_1
    ret_val[cf.CFSP_DPDK_NAME_IF_2] = PKTGEN_NAME_NIC_2
    return ret_val

# Configuration Variables from Config File
def get_deployment_configuration_variables_from_conf_file():
    variables = dict()
    types = dict()
    all_variables = CONF_FILE.get_variable_list(cf.CFS_EXPERIMENT_VNF)
    for var in all_variables:
        v = CONF_FILE.get_variable(cf.CFS_EXPERIMENT_VNF, var)
        type = re.findall(r'@\w*', v)
        values = re.findall(r'\"(.+?)\"', v)
        variables[var] = values
        try:
            types[var] = type[0][1:]
        except IndexError:
            LOG.debug("No type has been specified for variable " + var)
    return variables

# benchmarks from Config File
def get_benchmarks_from_conf_file():
    requested_benchmarks = list()
    benchmarks = \
        CONF_FILE.get_variable(cf.CFS_GENERAL, cf.CFSG_BENCHMARKS).split(', ')
    for benchmark in benchmarks:
        requested_benchmarks.append(benchmark)
    return requested_benchmarks

class InputValidation(object):

    def validate_string(param, message):
        if not isinstance(param, str):

    def validate_integer(param, message):
        if not isinstance(param, int):

    def validate_dictionary(param, message):
        if not isinstance(param, dict):

    def validate_file_exist(file_name, message):
        if not os.path.isfile(file_name):
            raise ValueError(message + ' ' + file_name)

    def validate_directory_exist_and_format(directory, message):
        if not os.path.isdir(directory):
        if not directory.endswith('/'):
            return directory + '/'
        return directory

    def validate_configuration_file_parameter(section, parameter, message):
        params = CONF_FILE.get_variable_list(section)
        if parameter not in params:

    def validate_configuration_file_section(section, message):
        if section not in cf.get_sections():

    def validate_boolean(boolean, message):
        if isinstance(boolean, bool):
            return boolean
        if isinstance(boolean, str):
            if boolean == 'True':
                return True
            if boolean == 'False':
                return False
        raise ValueError(message)

    def validate_os_credentials(credentials):
        if not isinstance(credentials, dict):
            raise ValueError(
                'The provided openstack_credentials '
                'variable must be in dictionary format')

        credential_keys = ['ip_controller', 'heat_url', 'user', 'password',
                           'auth_uri', 'project']
        missing = [
            credential_key
            for credential_key in credential_keys
            if credential_key not in credentials.keys()
        ]
        if len(missing) == 0:
        msg = 'OpenStack Credentials Error! ' \
              'The following parameters are missing: {}'.\
            format(", ".join(missing))
        raise ValueError(msg)

#

""" Handler for yardstick command 'task' """

import sys
import os
import atexit
import ipaddress
import uuid
from itertools import ifilter

from yardstick.benchmark.runners import base as base_runner
from yardstick.common.task_template import TaskTemplate

output_file_default = "/tmp/yardstick.out"
test_cases_dir_default = "tests/opnfv/test_cases/"

class TaskCommands(object):
    '''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",
             help="Input task args (dict in json). These args are used"
             "to render input task that is jinja2 template.")
    @cliargs("--task-args-file", dest="task_args_file",
             help="Path to the file with input task args (dict in "
             "json/yaml). These args are used to render input"
             "task that is jinja2 template.")
    @cliargs("--keep-deploy", help="keep context deployed in cloud",
             action="store_true")
    @cliargs("--parse-only", help="parse the config file and exit",
    @cliargs("--output-file", help="file where output is stored, default %s" %
             output_file_default, default=output_file_default)
    @cliargs("--suite", help="process test suite file instead of a task file",
    def do_start(self, args):
        '''Start a benchmark scenario.'''

        atexit.register(atexit_handler)

        total_start_time = time.time()
        parser = TaskParser(args.inputfile[0])

        suite_params = {}
        if args.suite:
            suite_params = parser.parse_suite()
            test_cases_dir = suite_params["test_cases_dir"]
            if test_cases_dir[-1] != os.sep:
                test_cases_dir += os.sep
            task_files = [test_cases_dir + task
                          for task in suite_params["task_fnames"]]
        else:
            task_files = [parser.path]

        task_args = suite_params.get("task_args", [args.task_args])
        task_args_fnames = suite_params.get("task_args_fnames",
                                            [args.task_args_file])

        if args.parse_only:
            sys.exit(0)

        if os.path.isfile(args.output_file):
            os.remove(args.output_file)

        for i in range(0, len(task_files)):
            one_task_start_time = time.time()
            parser.path = task_files[i]
            task_name = os.path.splitext(os.path.basename(task_files[i]))[0]
            scenarios, run_in_parallel, meet_precondition = parser.parse_task(
                task_name, task_args[i], task_args_fnames[i])

            if not meet_precondition:
                LOG.info("meet_precondition is %s, please check envrionment",
                         meet_precondition)
                continue

            self._run(scenarios, run_in_parallel, args.output_file)

            if args.keep_deploy:
                # keep deployment, forget about stack
                # (hide it for exit handler)
                Context.list = []
            else:
                for context in Context.list:
                    context.undeploy()
            one_task_end_time = time.time()
            LOG.info("task %s finished in %d secs", task_files[i],
                     one_task_end_time - one_task_start_time)

        total_end_time = time.time()
        LOG.info("total finished in %d secs",
                 total_end_time - total_start_time)

        print "Done, exiting"

    def _run(self, scenarios, run_in_parallel, output_file):
        '''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):
            scenario["runner"] = dict(type="Duration", duration=1000000000)
            runner = run_one_scenario(scenario, output_file)
            background_runners.append(runner)

        runners = []
        if run_in_parallel:
            for scenario in scenarios:
                if not _is_background_scenario(scenario):
                    runner = run_one_scenario(scenario, output_file)
                    runners.append(runner)

            # Wait for runners to finish
            for runner in runners:
                runner_join(runner)
                print "Runner ended, output in", output_file
        else:
            # run serially
                    runner_join(runner)
                    print "Runner ended, output in", output_file

        # Abort background runners
        for runner in background_runners:
            runner.abort()

        # Wait for background runners to finish
            if runner.join(timeout=60) is None:
                # Nuke if it did not stop nicely
                base_runner.Runner.terminate(runner)
            else:
                base_runner.Runner.release(runner)
            print "Background task ended"

# TODO: Move stuff below into TaskCommands class !?

class TaskParser(object):
    '''Parser for task config files in yaml format'''
    def __init__(self, path):
        self.path = path

    def parse_suite(self):
        '''parse the suite file and return a list of task config file paths
           and lists of optional parameters if present'''
        print "Parsing suite file:", self.path

        try:
            with open(self.path) as stream:

        self._check_schema(cfg["schema"], "suite")
        print "Starting suite:", cfg["name"]

        test_cases_dir = cfg.get("test_cases_dir", test_cases_dir_default)
        task_fnames = []
        task_args = []
        task_args_fnames = []

        for task in cfg["test_cases"]:
            task_fnames.append(task["file_name"])
            if "task_args" in task:
                task_args.append(task["task_args"])
            else:
                task_args.append(None)

            if "task_args_file" in task:
                task_args_fnames.append(task["task_args_file"])
            else:
                task_args_fnames.append(None)

        suite_params = {
            "test_cases_dir": test_cases_dir,
            "task_fnames": task_fnames,
            "task_args": task_args,
            "task_args_fnames": task_args_fnames
        }

        return suite_params

    def parse_task(self, task_name, task_args=None, task_args_file=None):
        '''parses the task file and return an context and scenario instances'''
        print "Parsing task config:", self.path

        try:
            kw = {}
            if task_args_file:
                with open(task_args_file) as f:
                    kw.update(parse_task_args("task_args_file", f.read()))
            kw.update(parse_task_args("task_args", task_args))
        except TypeError:
            raise TypeError()

        try:
            with open(self.path) as f:
                try:
                    input_task = f.read()
                    rendered_task = TaskTemplate.render(input_task, **kw)
                    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)

                cfg = yaml.load(rendered_task)

        self._check_schema(cfg["schema"], "task")
        meet_precondition = self._check_precondition(cfg)

        # TODO: support one or many contexts? Many would simpler and precise
        # TODO: support hybrid context type
        if "context" in cfg:
            context_cfgs = [cfg["context"]]
        elif "contexts" in cfg:
            context_cfgs = cfg["contexts"]
        else:
            context_cfgs = [{"type": "Dummy"}]

        for cfg_attrs in context_cfgs:
            context_type = cfg_attrs.get("type", "Heat")
            if "Heat" == context_type and "networks" in cfg_attrs:
                # config external_network based on env var
                for _, attrs in cfg_attrs["networks"].items():
                    attrs["external_network"] = os.environ.get(
                        'EXTERNAL_NETWORK', 'net04_ext')
            context = Context.get(context_type)
            context.init(cfg_attrs)

        run_in_parallel = cfg.get("run_in_parallel", False)

        # add tc and task id for influxdb extended tags
        task_id = str(uuid.uuid4())
        for scenario in cfg["scenarios"]:
            scenario["tc"] = task_name
            scenario["task_id"] = task_id

        # 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'''

        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'''

        if "precondition" in cfg:
            precondition = cfg["precondition"]
            installer_type = precondition.get("installer_type", None)
            deploy_scenarios = precondition.get("deploy_scenarios", None)
            installer_type_env = os.environ.get('INSTALL_TYPE', None)
            deploy_scenario_env = os.environ.get('DEPLOY_SCENARIO', None)
            if installer_type and installer_type_env:
                if installer_type_env not in installer_type:
            if deploy_scenarios and deploy_scenario_env:
                deploy_scenarios_list = deploy_scenarios.split(',')
                for deploy_scenario in deploy_scenarios_list:
                    if deploy_scenario_env.startswith(deploy_scenario):
                        return True

def atexit_handler():
    '''handler for process termination'''
    base_runner.Runner.terminate_all()

    if len(Context.list) > 0:
        print "Undeploying all contexts"
            context.undeploy()

def is_ip_addr(addr):
    '''check if string addr is an IP address'''
    try:
        ipaddress.ip_address(unicode(addr))
    except ValueError:

def _is_same_heat_context(host_attr, target_attr):
    '''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
    '''
    host = None
    target = None
    for context in Context.list:
        if context.__context_type__ != "Heat":
            continue

        host = context._get_server(host_attr)
        if host is None:
            continue

        target = context._get_server(target_attr)
        if target is None:

        # Both host and target is not None, then they are in the
        # same heat context.

    return False

def _is_background_scenario(scenario):
    if "run_in_background" in scenario:
        return scenario["run_in_background"]
    else:

def run_one_scenario(scenario_cfg, output_file):
    '''run one scenario using context'''
    runner_cfg = scenario_cfg["runner"]
    runner_cfg['output_filename'] = output_file

    # TODO support get multi hosts/vms info
    context_cfg = {}
    if "host" in scenario_cfg:
        context_cfg['host'] = Context.get_server(scenario_cfg["host"])

    if "target" in scenario_cfg:
        if is_ip_addr(scenario_cfg["target"]):
            context_cfg['target'] = {}
            context_cfg['target']["ipaddr"] = scenario_cfg["target"]
        else:
            context_cfg['target'] = Context.get_server(scenario_cfg["target"])
            if _is_same_heat_context(scenario_cfg["host"],
                                     scenario_cfg["target"]):
                context_cfg["target"]["ipaddr"] = \
                    context_cfg["target"]["private_ip"]
            else:
                    context_cfg["target"]["ip"]

    if "nodes" in scenario_cfg:
        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"]
    runner.run(scenario_cfg, context_cfg)

    return runner

def parse_nodes_with_context(scenario_cfg):
    '''paras the 'nodes' fields in scenario '''
    nodes = scenario_cfg["nodes"]

    nodes_cfg = {}
    for nodename in nodes:
        nodes_cfg[nodename] = Context.get_server(nodes[nodename])

    return nodes_cfg

def runner_join(runner):
    '''join (wait for) a runner, exit process at runner failure'''
    status = runner.join()
    base_runner.Runner.release(runner)
    if status != 0:
        sys.exit("Runner failed")

def print_invalid_header(source_name, args):
    print(("Invalid %(source)s passed:\n\n %(args)s\n")
          % {"source": source_name, "args": args})

def parse_task_args(src_name, args):
    try:
        kw = args and yaml.safe_load(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")
              % {"source": src_name, "err": e})
        raise TypeError()

    if not isinstance(kw, dict):
        print(("%(src)s had to be dict, actually %(src_type)s\n")
              % {"src": src_name, "src_type": type(kw)})
    return kw

#

import os
import requests

from yardstick.dispatcher.base import Base as DispatchBase

http_dispatcher_opts = [
    cfg.StrOpt('target',
               default='http://127.0.0.1:8000/results',
               help='The target where the http request will be sent. '
                    'If this is not set, no data will be posted. For '
                    'example: target = http://hostname:1234/path'),
    cfg.IntOpt('timeout',
               default=5,
               help='The max time in seconds to wait for a request to '
                    'timeout.'),
]

CONF.register_opts(http_dispatcher_opts, group="dispatcher_http")

class HttpDispatcher(DispatchBase):
    """Dispatcher class for posting data into a http target.
    """

    __dispatcher_type__ = "Http"

    def __init__(self, conf):
        super(HttpDispatcher, self).__init__(conf)
        self.headers = {'Content-type': 'application/json'}
        self.timeout = CONF.dispatcher_http.timeout
        self.target = CONF.dispatcher_http.target
        self.raw_result = []
        self.result = {
            "project_name": "yardstick",
            "description": "yardstick test cases result",
            "pod_name": os.environ.get('NODE_NAME', 'unknown'),
            "installer": os.environ.get('INSTALLER_TYPE', 'unknown'),
            "version": os.environ.get('YARDSTICK_VERSION', 'unknown')
        }

    def record_result_data(self, data):
        self.raw_result.append(data)

    def flush_result_data(self):
        if self.target == '':
            # if the target was not set, do not do anything
            LOG.error('Dispatcher target was not set, no data will'
                      'be posted.')
            return

        self.result["details"] = self.raw_result

        case_name = ""
        for v in self.raw_result:
            if isinstance(v, dict) and "scenario_cfg" in v:
                case_name = v["scenario_cfg"]["tc"]
                break
        if case_name == "":
            LOG.error('Test result : %s' % json.dumps(self.result))
            LOG.error('The case_name cannot be found, no data will be posted.')
            return

        self.result["case_name"] = case_name

        try:
            LOG.debug('Test result : %s' % json.dumps(self.result))
            res = requests.post(self.target,
                                data=json.dumps(self.result),
                                headers=self.headers,
                                timeout=self.timeout)
            LOG.debug('Test result posting finished with status code'
                      ' %d.' % res.status_code)
            LOG.exception('Failed to record result data: %s',
                          err)

#
import abc
import six

@six.add_metaclass(abc.ABCMeta)
class Context(object):
    list = []

        Context.list.append(self)

        "Initiate context."

    def get_cls(context_type):
        '''Return class of specified type.'''
        for context in utils.itersubclasses(Context):
            if context_type == context.__context_type__:
                return context
        raise RuntimeError("No such context_type %s" % context_type)

    def get(context_type):
        """Returns instance of a context for context type.
        """
        return Context.get_cls(context_type)()

        '''Deploy context.'''

        '''Undeploy context.'''

        '''get server info by name from context
        '''

    def get_server(attr_name):
        '''
        server = None
            server = context._get_server(attr_name)
            if server is not None:
                break

            raise ValueError("context not found for server '%r'" %
                             attr_name)

        return server

#
#
#

from experimental_framework.benchmarks import rfc2544_throughput_benchmark \
    as base

class MultiTenancyThroughputBenchmark(base.RFC2544ThroughputBenchmark):

        base.RFC2544ThroughputBenchmark.__init__(self, name, params)
        self.template_file = "{}{}".format(common.get_template_dir(),
                                           'stress_workload.yaml')

        features = super(MultiTenancyThroughputBenchmark, self).get_features()
        features['description'] = \
            'RFC 2544 Throughput calculation with ' \
            'memory-bound noisy neighbors'
        features['parameters'].append('num_of_neighbours')
        features['parameters'].append('amount_of_ram')
        features['parameters'].append('number_of_cores')
        features['allowed_values']['num_of_neighbours'] = \
        features['allowed_values']['number_of_cores'] = \
        features['allowed_values']['amount_of_ram'] = \
             '10G']
        features['default_values']['num_of_neighbours'] = '1'
        features['default_values']['number_of_cores'] = '1'
        features['default_values']['amount_of_ram'] = '256M'

        """
        return: None
        """

        """
        """

#

import abc
import six

class Base(object):

        self.conf = conf

    def get_cls(dispatcher_type):
        for dispatcher in utils.itersubclasses(Base):
            if dispatcher_type == dispatcher.__dispatcher_type__:
                return dispatcher
        raise RuntimeError("No such dispatcher_type %s" % dispatcher_type)

        """Returns instance of a dispatcher for dispatcher type.
        """
        return Base.get_cls(config["type"])(config)

        """Recording result data interface."""

        """Flush result data into permanent storage media interface."""

#

"""Processor statistics and system load."""

import re

class CPULoad(base.Scenario):

    """Collect processor statistics and system load.

    This scenario reads system load averages and
    CPU usage statistics on a Linux host.

    CPU usage statistics are read using the utility 'mpstat'.

    If 'mpstat' is not installed on the host usage statistics
    are instead read directly from '/proc/stat'.

    Load averages are read from the file '/proc/loadavg'
    on the Linux host.

          interval - Time interval to measure CPU usage. A value of 0
                     indicates that processors statistics are to be
                     reported for the time since system startup (boot)

          type:       [int]
          unit:       seconds
          default:    0

    """

    __scenario_type__ = "CPUload"

    MPSTAT_FIELD_SIZE = 10

        """Scenario construction."""
        self.has_mpstat = False

        """Scenario setup."""

        # Check if mpstat prog is installed
        status, _, _ = self.client.execute("mpstat -V >/dev/null 2>&1")
        if status != 0:
            LOG.info("MPSTAT is NOT installed")
            self.has_mpstat = False
        else:
            LOG.info("MPSTAT is installed")
            self.has_mpstat = True

        if 'options' in self.scenario_cfg:
            self.interval = self.scenario_cfg['options'].get("interval", 0)
        else:
            self.interval = 0

    def _execute_command(self, cmd):
        """Execute a command on server."""
        LOG.info("Executing: %s" % cmd)
            raise RuntimeError("Failed executing command: ",
                               cmd, stderr)
        return stdout

    def _get_loadavg(self):
        """Get system load."""
        return {'loadavg': self._execute_command("cat /proc/loadavg").split()}

    def _get_cpu_usage_mpstat(self):
        """Get processor usage using mpstat."""
        if self.interval > 0:
            cmd = "mpstat -P ON %s 1" % self.interval
        else:
            cmd = "mpstat -P ON"

        result = self._execute_command(cmd)

        fields = []
        mpstat = {}

        time_marker = re.compile("^([0-9]+):([0-9]+):([0-9]+)$")
        ampm_marker = re.compile("(AM|PM)$")

        # Parse CPU stats
        for row in result.split('\n'):
            line = row.split()

            if line and re.match(time_marker, line[0]):

                if re.match(ampm_marker, line[1]):
                    del line[:2]
                else:
                    del line[:1]

                if line[0] == 'CPU':
                    # header fields
                    fields = line[1:]
                    if len(fields) != CPULoad.MPSTAT_FIELD_SIZE:
                        raise RuntimeError("mpstat: unexpected field size",
                                           fields)
                else:
                    # value fields
                    cpu = 'cpu' if line[0] == 'all' else 'cpu' + line[0]
                    values = line[1:]
                    if values and len(values) == len(fields):
                        mpstat[cpu] = dict(zip(fields, values))
                    else:
                        raise RuntimeError("mpstat: parse error", fields, line)

        return {'mpstat': mpstat}

    def _get_cpu_usage(self):
        """Get processor usage from /proc/stat."""
        fields = ['%usr', '%nice', '%sys', '%idle', '%iowait',
                  '%irq', '%soft', '%steal', '%guest', '%gnice']

        cmd = "grep '^cpu[0-9 ].' /proc/stat"

            previous = self._execute_command(cmd).splitlines()
            time.sleep(self.interval)
            current = self._execute_command(cmd).splitlines()
        else:
            previous = current

        mpstat = {}

        for (prev, cur) in zip(previous, current):

            # Split string to list tokens
            cur_list = cur.split()
            prev_list = prev.split()

            cpu = cur_list[0]

            cur_stats = map(int, cur_list[1:])
            if self.interval > 0:
                prev_stats = map(int, prev_list[1:])
            else:
                prev_stats = [0] * len(cur_stats)

            # NB: Don't add 'guest' and 'gnice' as they
            # are already included in 'usr' and 'nice'.
            uptime_prev = sum(prev_stats[0:8])
            uptime_cur = sum(cur_stats[0:8])

            # Remove 'guest' and 'gnice' from 'usr' and 'nice'
            prev_stats[0] -= prev_stats[8]
            prev_stats[1] -= prev_stats[9]
            cur_stats[0] -= cur_stats[8]
            cur_stats[1] -= cur_stats[9]

            # number of samples (jiffies) in the interval
            samples = (uptime_cur - uptime_prev) or 1

            def _percent(x, y):
                if x < y:
                    return 0.0
                else:
                    return "%.2f" % (100.0 * (x - y) / samples)

            load = map(_percent, cur_stats, prev_stats)

            mpstat[cpu] = dict(zip(fields, load))

        """Read processor statistics."""

        result.update(self._get_loadavg())

        if self.has_mpstat:
            result.update(self._get_cpu_usage_mpstat())
        else:
            result.update(self._get_cpu_usage())

        # Note: No SLA as this scenario is only collecting statistics

# def _test():
#     """internal test function."""
#     import pkg_resources
#     key_filename = pkg_resources.resource_filename('yardstick.resources',
#                                                    'files/yardstick_key')
#     ctx = {
#         'host': {
#             'ip': '172.16.0.175',
#             'user': 'ubuntu',
#             'key_filename': key_filename
#         }
#     }

#     logger = logging.getLogger('yardstick')
#     logger.setLevel(logging.DEBUG)

#     args = {}
#     result = {}

#     p = CPULoad(args, ctx)
#     p.run(result)
#     import json
#     print json.dumps(result)

# if __name__ == '__main__':
#     _test()

#

import os

from yardstick.dispatcher.influxdb_line_protocol import make_lines

influx_dispatcher_opts = [
               default='http://127.0.0.1:8086',
    cfg.StrOpt('db_name',
               default='yardstick',
               help='The database name to store test results.'),
    cfg.StrOpt('username',
               default='root',
               help='The user name to access database.'),
    cfg.StrOpt('password',
               help='The user password to access database.'),
]

CONF.register_opts(influx_dispatcher_opts, group="dispatcher_influxdb")

class InfluxdbDispatcher(DispatchBase):
    """Dispatcher class for posting data into an influxdb target.
    """

    __dispatcher_type__ = "Influxdb"

        super(InfluxdbDispatcher, self).__init__(conf)
        self.timeout = CONF.dispatcher_influxdb.timeout
        self.target = CONF.dispatcher_influxdb.target
        self.db_name = CONF.dispatcher_influxdb.db_name
        self.username = CONF.dispatcher_influxdb.username
        self.password = CONF.dispatcher_influxdb.password
        self.influxdb_url = "%s/write?db=%s" % (self.target, self.db_name)
        self.case_name = ""
        self.tc = ""
        self.task_id = -1
        self.runners_info = {}
        self.static_tags = {
            "deploy_scenario": os.environ.get('DEPLOY_SCENARIO', 'unknown'),
        }

    def _dict_key_flatten(self, data):
        next_data = {}

        if not [v for v in data.values()
                if type(v) == dict or type(v) == list]:
            return data

        for k, v in data.iteritems():
            if type(v) == dict:
                for n_k, n_v in v.iteritems():
                    next_data["%s.%s" % (k, n_k)] = n_v
            elif type(v) == list:
                for index, item in enumerate(v):
                    next_data["%s%d" % (k, index)] = item
            else:
                next_data[k] = v

        return self._dict_key_flatten(next_data)

    def _get_nano_timestamp(self, results):
        try:
            timestamp = results["benchmark"]["timestamp"]
        except Exception:
            timestamp = time.time()

        return str(int(float(timestamp) * 1000000000))

    def _get_extended_tags(self, data):
        runner_info = self.runners_info[data["runner_id"]]
        tags = {
            "runner_id": data["runner_id"],
            "task_id": self.task_id,
            "scenarios": runner_info["scenarios"]
        }
        if "host" in runner_info:
            tags["host"] = runner_info["host"]
        if "target" in runner_info:
            tags["target"] = runner_info["target"]

        return tags

    def _data_to_line_protocol(self, data):
        msg = {}
        point = {}
        point["measurement"] = self.tc
        point["fields"] = self._dict_key_flatten(data["benchmark"]["data"])
        point["time"] = self._get_nano_timestamp(data)
        point["tags"] = self._get_extended_tags(data)
        msg["points"] = [point]
        msg["tags"] = self.static_tags

        return make_lines(msg).encode('utf-8')

        LOG.debug('Test result : %s' % json.dumps(data))
            return -1

        if isinstance(data, dict) and "scenario_cfg" in data:
            self.tc = data["scenario_cfg"]["tc"]
            self.task_id = data["scenario_cfg"]["task_id"]
            scenario_cfg = data["scenario_cfg"]
            runner_id = data["runner_id"]
            self.runners_info[runner_id] = {"scenarios": scenario_cfg["type"]}
            if "host" in scenario_cfg:
                self.runners_info[runner_id]["host"] = scenario_cfg["host"]
            if "target" in scenario_cfg:
                self.runners_info[runner_id]["target"] = scenario_cfg["target"]
            return 0

        if self.tc == "":
            LOG.error('Test result : %s' % json.dumps(data))
            return -1

        try:
            line = self._data_to_line_protocol(data)
            LOG.debug('Test result line format : %s' % line)
            res = requests.post(self.influxdb_url,
                                data=line,
                                auth=(self.username, self.password),
            if res.status_code != 204:
                LOG.error('Test result posting finished with status code'
                          ' %d.' % res.status_code)
                LOG.error(res.text)

                          err)
            return -1
        return 0

        LOG.debug('Test result all : %s' % json.dumps(self.raw_result))
        return 0

#
#
#

import abc

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
    '''

        if not params:
            params = dict()
        if not isinstance(params, dict):
            raise ValueError("Parameters need to be provided in a dict")

        for param in self.get_features()['parameters']:
            if param not in params.keys():
                params[param] = self.get_features()['default_values'][param]

            if params[param] not in \
                    (self.get_features())['allowed_values'][param]:
                raise ValueError('Value of parameter "' + param +
                                 '" is not allowed')
        self.params = params

    def get_name(self):
        return self.name

    def get_params(self):
        return self.params

        features['description'] = 'Please implement the method ' \
                                  '"get_features" for your benchmark'

        """
        Initializes the benchmark
        :return:
        """

        """
        :return:
        """

        """
        This method executes the specific benchmark on the VNF already
        instantiated
        :return: list of dictionaries (every dictionary contains the results
        of a data point
        """

#

OPTS = [
    cfg.StrOpt('file_path',
               default='/tmp/yardstick.out',
               help='Name and the location of the file to record '
                    'data.'),
    cfg.IntOpt('max_bytes',
               default=0,
               help='The max size of the file.'),
    cfg.IntOpt('backup_count',
               help='The max number of the files to keep.'),
]
CONF.register_opts(OPTS, group="dispatcher_file")

class FileDispatcher(DispatchBase):
    """Dispatcher class for recording data to a file.
    """

    __dispatcher_type__ = "File"

        super(FileDispatcher, self).__init__(conf)
        self.log = None

        # if the directory and path are configured, then log to the file
        if CONF.dispatcher_file.file_path:
            dispatcher_logger = logging.Logger('dispatcher.file')
            dispatcher_logger.setLevel(logging.INFO)
            # create rotating file handler which logs result
            rfh = logging.handlers.RotatingFileHandler(
                self.conf.get('file_path', CONF.dispatcher_file.file_path),
                maxBytes=CONF.dispatcher_file.max_bytes,
                backupCount=CONF.dispatcher_file.backup_count,
                encoding='utf8')

            rfh.setLevel(logging.INFO)
            # Only wanted the data to be saved in the file, not the
            # project root logger.
            dispatcher_logger.propagate = False
            dispatcher_logger.addHandler(rfh)
            self.log = dispatcher_logger

        if self.log:
            self.log.info(json.dumps(data))

        pass

#

""" Handler for yardstick command 'runner' """

from yardstick.benchmark.runners.base import Runner

class RunnerCommands(object):
    '''Runner commands.

       Set of commands to discover and display runner types.
    '''

        '''List existing runner types'''
        types = Runner.get_types()
        for rtype in types:
            print "| %-16s | %-60s" % (rtype.__execution_type__,
                                       rtype.__doc__.split("\n")[0])

        '''Show details of a specific runner type'''
        rtype = Runner.get_cls(args.type[0])
        print rtype.__doc__

TARGET_SCRIPT (yardstick.benchmark.scenarios.storage.fio.Fio attribute)

delete_all() (yardstick.orchestrator.heat.HeatStack static method)

stacks_exist() (yardstick.orchestrator.heat.HeatStack static method)

add_floating_ip() (yardstick.orchestrator.heat.HeatTemplate method)

add_floating_ip_association() (yardstick.orchestrator.heat.HeatTemplate method)

add_router_interface() (yardstick.orchestrator.heat.HeatTemplate method)

add_security_group() (yardstick.orchestrator.heat.HeatTemplate method)

add_servergroup() (yardstick.orchestrator.heat.HeatTemplate method)

PARSER_SCRIPT (yardstick.benchmark.scenarios.parser.parser.Parser attribute)

SETUP_SCRIPT (yardstick.benchmark.scenarios.parser.parser.Parser attribute)

TEARDOWN_SCRIPT (yardstick.benchmark.scenarios.parser.parser.Parser attribute)

run() (yardstick.benchmark.scenarios.parser.parser.Parser method)

setup() (yardstick.benchmark.scenarios.parser.parser.Parser method)

teardown() (yardstick.benchmark.scenarios.parser.parser.Parser method)

render() (yardstick.common.task_template.TaskTemplate class method)

import_modules_from_package() (in module yardstick.common.utils)

ServiceHA (class in yardstick.benchmark.scenarios.availability.serviceha)

run() (yardstick.benchmark.scenarios.availability.serviceha.ServiceHA method)

setup() (yardstick.benchmark.scenarios.availability.serviceha.ServiceHA method)

get_cls() (yardstick.benchmark.contexts.base.Context static method)

get_server() (yardstick.benchmark.contexts.base.Context static method)

deploy() (yardstick.benchmark.contexts.dummy.DummyContext method)

undeploy() (yardstick.benchmark.contexts.dummy.DummyContext method)

flavor (yardstick.benchmark.contexts.heat.HeatContext attribute)

undeploy() (yardstick.benchmark.contexts.heat.HeatContext method)

find_by_route_to() (yardstick.benchmark.contexts.model.Network static method)

find_external_network() (yardstick.benchmark.contexts.model.Network static method)

has_route_to() (yardstick.benchmark.contexts.model.Network method)

add_member() (yardstick.benchmark.contexts.model.PlacementGroup method)

get() (yardstick.benchmark.contexts.model.PlacementGroup static method)

map (yardstick.benchmark.contexts.model.PlacementGroup attribute)

add_to_template() (yardstick.benchmark.contexts.model.Server method)

update_scheduler_hints() (in module yardstick.benchmark.contexts.model)

undeploy() (yardstick.benchmark.contexts.node.NodeContext method)

FrameworkApi (class in yardstick.vTC.apexlake.experimental_framework.api)

execute_framework() (yardstick.vTC.apexlake.experimental_framework.api.FrameworkApi static method)

get_test_case_features() (yardstick.vTC.apexlake.experimental_framework.api.FrameworkApi static method)

init() (yardstick.vTC.apexlake.experimental_framework.api.FrameworkApi static method)

BenchmarkingUnit (class in yardstick.vTC.apexlake.experimental_framework.benchmarking_unit)

get_benchmark_class() (yardstick.vTC.apexlake.experimental_framework.benchmarking_unit.BenchmarkingUnit static method)

ConfigurationFile (class in yardstick.vTC.apexlake.experimental_framework.common)

InputValidation (class in yardstick.vTC.apexlake.experimental_framework.common)

validate_boolean() (yardstick.vTC.apexlake.experimental_framework.common.InputValidation static method)

validate_dictionary() (yardstick.vTC.apexlake.experimental_framework.common.InputValidation static method)

validate_file_exist() (yardstick.vTC.apexlake.experimental_framework.common.InputValidation static method)

validate_integer() (yardstick.vTC.apexlake.experimental_framework.common.InputValidation static method)

validate_os_credentials() (yardstick.vTC.apexlake.experimental_framework.common.InputValidation static method)

validate_string() (yardstick.vTC.apexlake.experimental_framework.common.InputValidation static method)

get_base_dir() (in module yardstick.vTC.apexlake.experimental_framework.common)

get_benchmarks_from_conf_file() (in module yardstick.vTC.apexlake.experimental_framework.common)

get_credentials() (in module yardstick.vTC.apexlake.experimental_framework.common)

get_deployment_configuration_variables_from_conf_file() (in module yardstick.vTC.apexlake.experimental_framework.common)

get_dpdk_pktgen_vars() (in module yardstick.vTC.apexlake.experimental_framework.common)

get_file_first_line() (in module yardstick.vTC.apexlake.experimental_framework.common)

get_heat_template_params() (in module yardstick.vTC.apexlake.experimental_framework.common)

get_result_dir() (in module yardstick.vTC.apexlake.experimental_framework.common)

get_template_dir() (in module yardstick.vTC.apexlake.experimental_framework.common)

get_testcase_params() (in module yardstick.vTC.apexlake.experimental_framework.common)

init() (in module yardstick.vTC.apexlake.experimental_framework.common)

init_conf_file() (in module yardstick.vTC.apexlake.experimental_framework.common)

init_general_vars() (in module yardstick.vTC.apexlake.experimental_framework.common)

init_influxdb() (in module yardstick.vTC.apexlake.experimental_framework.common)

init_log() (in module yardstick.vTC.apexlake.experimental_framework.common)

init_pktgen() (in module yardstick.vTC.apexlake.experimental_framework.common)

push_data_influxdb() (in module yardstick.vTC.apexlake.experimental_framework.common)

replace_in_file() (in module yardstick.vTC.apexlake.experimental_framework.common)

run_command() (in module yardstick.vTC.apexlake.experimental_framework.common)

DeploymentUnit (class in yardstick.vTC.apexlake.experimental_framework.deployment_unit)

HeatManager (class in yardstick.vTC.apexlake.experimental_framework.heat_manager)

TreeNode (class in yardstick.vTC.apexlake.experimental_framework.heat_template_generation)

get_leaves() (yardstick.vTC.apexlake.experimental_framework.heat_template_generation.TreeNode static method)

generates_templates() (in module yardstick.vTC.apexlake.experimental_framework.heat_template_generation)

get_all_heat_templates() (in module yardstick.vTC.apexlake.experimental_framework.heat_template_generation)

get_sections() (in module yardstick.vTC.apexlake.experimental_framework.constants.conf_file_sections)

get_sections_api() (in module yardstick.vTC.apexlake.experimental_framework.constants.conf_file_sections)

BaseMonitor (class in yardstick.benchmark.scenarios.availability.monitor.basemonitor)

get_monitor_cls() (yardstick.benchmark.scenarios.availability.monitor.basemonitor.BaseMonitor static method)

MonitorMgr (class in yardstick.benchmark.scenarios.availability.monitor.basemonitor)

MonitorOpenstackCmd (class in yardstick.benchmark.scenarios.availability.monitor.monitor_command)

MonitorProcess (class in yardstick.benchmark.scenarios.availability.monitor.monitor_process)

get() (yardstick.benchmark.scenarios.base.Scenario static method)

get_cls() (yardstick.benchmark.scenarios.base.Scenario static method)

get_types() (yardstick.benchmark.scenarios.base.Scenario static method)

BasePacketGenerator (class in yardstick.vTC.apexlake.experimental_framework.packet_generators.base_packet_generator)

DpdkPacketGenerator (class in yardstick.vTC.apexlake.experimental_framework.packet_generators.dpdk_packet_generator)

flush_result_data() (yardstick.dispatcher.file.FileDispatcher method)

record_result_data() (yardstick.dispatcher.file.FileDispatcher method)

flush_result_data() (yardstick.dispatcher.http.HttpDispatcher method)

record_result_data() (yardstick.dispatcher.http.HttpDispatcher method)

flush_result_data() (yardstick.dispatcher.influxdb.InfluxdbDispatcher method)

record_result_data() (yardstick.dispatcher.influxdb.InfluxdbDispatcher method)

make_lines() (in module yardstick.dispatcher.influxdb_line_protocol)

setup() (yardstick.benchmark.scenarios.dummy.dummy.Dummy method)

ArithmeticRunner (class in yardstick.benchmark.runners.arithmetic)

dump_process (yardstick.benchmark.runners.base.Runner attribute)

get_cls() (yardstick.benchmark.runners.base.Runner static method)

get_types() (yardstick.benchmark.runners.base.Runner static method)

release() (yardstick.benchmark.runners.base.Runner static method)

release_dump_process() (yardstick.benchmark.runners.base.Runner static method)

run_post_stop_action() (yardstick.benchmark.runners.base.Runner method)

terminate() (yardstick.benchmark.runners.base.Runner static method)

terminate_all() (yardstick.benchmark.runners.base.Runner static method)

IterationRunner (class in yardstick.benchmark.runners.iteration)

CPULoad (class in yardstick.benchmark.scenarios.compute.cpuload)

run() (yardstick.benchmark.scenarios.compute.cpuload.CPULoad method)

setup() (yardstick.benchmark.scenarios.compute.cpuload.CPULoad method)

Cyclictest (class in yardstick.benchmark.scenarios.compute.cyclictest)

run() (yardstick.benchmark.scenarios.compute.cyclictest.Cyclictest method)

setup() (yardstick.benchmark.scenarios.compute.cyclictest.Cyclictest method)

Lmbench (class in yardstick.benchmark.scenarios.compute.lmbench)

run() (yardstick.benchmark.scenarios.compute.lmbench.Lmbench method)

setup() (yardstick.benchmark.scenarios.compute.lmbench.Lmbench method)

TARGET_SCRIPT (yardstick.benchmark.scenarios.compute.perf.Perf attribute)

setup() (yardstick.benchmark.scenarios.compute.perf.Perf method)

Unixbench (class in yardstick.benchmark.scenarios.compute.unixbench)

run() (yardstick.benchmark.scenarios.compute.unixbench.Unixbench method)

setup() (yardstick.benchmark.scenarios.compute.unixbench.Unixbench method)

Iperf (class in yardstick.benchmark.scenarios.networking.iperf3)

run() (yardstick.benchmark.scenarios.networking.iperf3.Iperf method)

setup() (yardstick.benchmark.scenarios.networking.iperf3.Iperf method)

teardown() (yardstick.benchmark.scenarios.networking.iperf3.Iperf method)

Netperf (class in yardstick.benchmark.scenarios.networking.netperf)

run() (yardstick.benchmark.scenarios.networking.netperf.Netperf method)

setup() (yardstick.benchmark.scenarios.networking.netperf.Netperf method)

TARGET_SCRIPT (yardstick.benchmark.scenarios.networking.ping.Ping attribute)

run() (yardstick.benchmark.scenarios.networking.ping.Ping method)

METADATA_SCRIPT (yardstick.benchmark.scenarios.networking.ping6.Ping6 attribute)

SETUP_SCRIPT (yardstick.benchmark.scenarios.networking.ping6.Ping6 attribute)

TARGET_SCRIPT (yardstick.benchmark.scenarios.networking.ping6.Ping6 attribute)

TEARDOWN_SCRIPT (yardstick.benchmark.scenarios.networking.ping6.Ping6 attribute)

run() (yardstick.benchmark.scenarios.networking.ping6.Ping6 method)

setup() (yardstick.benchmark.scenarios.networking.ping6.Ping6 method)

teardown() (yardstick.benchmark.scenarios.networking.ping6.Ping6 method)

Pktgen (class in yardstick.benchmark.scenarios.networking.pktgen)

TARGET_SCRIPT (yardstick.benchmark.scenarios.networking.pktgen.Pktgen attribute)

run() (yardstick.benchmark.scenarios.networking.pktgen.Pktgen method)

setup() (yardstick.benchmark.scenarios.networking.pktgen.Pktgen method)

PRE_SETUP_SCRIPT (yardstick.benchmark.scenarios.networking.sfc.Sfc attribute)

SERVER_SCRIPT (yardstick.benchmark.scenarios.networking.sfc.Sfc attribute)

TACKER_SCRIPT (yardstick.benchmark.scenarios.networking.sfc.Sfc attribute)

TEARDOWN_SCRIPT (yardstick.benchmark.scenarios.networking.sfc.Sfc attribute)

setup() (yardstick.benchmark.scenarios.networking.sfc.Sfc method)

teardown() (yardstick.benchmark.scenarios.networking.sfc.Sfc method)

VtcInstantiationValidation (class in yardstick.benchmark.scenarios.networking.vtc_instantiation_validation)

VtcInstantiationValidationNoisy (class in yardstick.benchmark.scenarios.networking.vtc_instantiation_validation_noisy)

VtcThroughput (class in yardstick.benchmark.scenarios.networking.vtc_throughput)

VtcThroughputNoisy (class in yardstick.benchmark.scenarios.networking.vtc_throughput_noisy)

BaremetalAttacker (class in yardstick.benchmark.scenarios.availability.attacker.attacker_baremetal)

ProcessAttacker (class in yardstick.benchmark.scenarios.availability.attacker.attacker_process)

BaseAttacker (class in yardstick.benchmark.scenarios.availability.attacker.baseattacker)

get_attacker_cls() (yardstick.benchmark.scenarios.availability.attacker.baseattacker.BaseAttacker static method)

do_list() (yardstick.cmd.commands.scenario.ScenarioCommands method)

do_show() (yardstick.cmd.commands.scenario.ScenarioCommands method)

parse_nodes_with_context() (in module yardstick.cmd.commands.task)

BenchmarkBaseClass (class in yardstick.vTC.apexlake.experimental_framework.benchmarks.benchmark_base_class)

TestBenchmark (class in yardstick.vTC.apexlake.experimental_framework.benchmarks.test_benchmark)