diff options
Diffstat (limited to 'yardstick/vTC/apexlake')
59 files changed, 5167 insertions, 60 deletions
diff --git a/yardstick/vTC/apexlake/.gitignore b/yardstick/vTC/apexlake/.gitignore new file mode 100644 index 000000000..ddcd58683 --- /dev/null +++ b/yardstick/vTC/apexlake/.gitignore @@ -0,0 +1,2 @@ +benchmark.log + diff --git a/yardstick/vTC/apexlake/MANIFEST.in b/yardstick/vTC/apexlake/MANIFEST.in new file mode 100644 index 000000000..57649e597 --- /dev/null +++ b/yardstick/vTC/apexlake/MANIFEST.in @@ -0,0 +1,7 @@ +recursive-include bin *.py +recursive-include benchmarks *.py +recursive-include heat_templates * +recursive-include packet_generators * +recursive-include etc *.cfg *.json +include *.py +include README.md diff --git a/yardstick/vTC/apexlake/README.md b/yardstick/vTC/apexlake/README.md new file mode 100644 index 000000000..ca4f4ded6 --- /dev/null +++ b/yardstick/vTC/apexlake/README.md @@ -0,0 +1,116 @@ +Welcome to ApexLake's documentation! +==================================== +ApexLake is a framework that provides automatic execution of experiment and related data collection to help +the user validating the infrastructure from a Virtual Network Function perspective. + +Install framework and dependencies +---------------------------------- +Before to start the framework, a set of dependencies are required. +In the following a set of instructions to be executed on the Linux shell to install dependencies and configure the environment. + +1. Install dependencies + - # apt-get install python-dev + - # apt-get install python-pip + - # apt-get install python-mock + - # apt-get install tcpreplay + - # apt-get install libpcap-dev + +2. Install the framework on the system + - # python setup.py install + +3. Source OpenStack openrc file + - $ source openrc + +4. Create 2 Networks (and subnets) based on VLANs (provider:network_type = vlan) in Neutron + - $ neutron net-create apexlake_inbound_network --provider:network_type vlan --provider:physical_network physnet1 + - $ neutron subnet-create apexlake_inbound_network 192.168.0.0/24 --name apexlake_inbound_subnet + - $ neutron net-create apexlake_outbound_network --provider:network_type vlan --provider:physical_network physnet1 + - $ neutron subnet-create apexlake_outbound_network 192.168.1.0/24 --name apexlake_outbound_subnet + +5. Insert VLAN tags related to the networks have to ApexLake, either: + - into the "conf.cfg" configuration file, or + - through the Python API. + + +Install and configure DPDK Pktgen ++++++++++++++++++++++++++++++++++ +The execution of the framework is based on DPDK Pktgen. +If DPDK Pktgen has not been installed on the system by the user, it is necessary to download, compile and configure it. +The user can create a directory and download the dpdk packet generator source code: + - $ cd experimental_framework/libraries + - $ mkdir dpdk_pktgen + - $ git clone https://github.com/pktgen/Pktgen-DPDK.git + +For the installation and configuration of DPDK and DPDK Pktgen please follow the official DPDK Pktgen README file. +Once the installation is completed, it is necessary to load the DPDK kernel driver, as follow: + - # insmod uio + - # insmod DPDK_DIR/x86_64-native-linuxapp-gcc/kmod/igb_uio.ko + +It is required to properly set the configuration file according to the system on Pktgen runs on. +An example is provided in the following: + + - [PacketGen] + - packet_generator = dpdk_pktgen + - pktgen_directory = /home/user/apexlake/experimental_framework/libraries/dpdk_pktgen/dpdk/examples/pktgen/ + -- This is the directory where the packet generator is installed (if the user previously installed dpdk-pktgen, it is required to provide the director where it is installed). + - dpdk_directory = /home/user/apexlake/experimental_framework/libraries/Pktgen-DPDK/dpdk/ + -- This is the directory where DPDK is installed + - program_name = app/app/x86_64-native-linuxapp-gcc/pktgen + -- This is the name of the dpdk-pktgen program that starts the packet generator + - coremask = 1f + -- DPDK coremask (see DPDK-Pktgen readme) + - memory_channels = 3 + -- DPDK memory channels (see DPDK-Pktgen readme) + - name_if_1 = p1p1 + -- Name of the interface of the pktgen to be used to send traffic + - name_if_2 = p1p2 + -- Name of the interface of the pktgen to be used to receive traffic + - bus_slot_nic_1 = 01:00.0 + -- PCI bus address correspondent to the if_1 + - bus_slot_nic_2 = 01:00.1 + -- PCI bus address correspondent to the if_2 + + +To find the parameters related to names of the NICs and addresses of the PCI buses the user may find useful to run the DPDK tool nic_bind as follows: + + - $ DPDK_DIR/tools/dpdk_nic_bind.py --status + +which lists the NICs available on the system, show the available drivers and bus addresses for each interface. +Please make sure to select NICs which are DPDK compatible. + +Installation and configuration of smcroute +++++++++++++++++++++++++++++++++++++++++++ +The user is required to install smcroute which is used by the framework to support multicast communications. +In the following a list of commands to be ran to download and install smroute is provided. + + - $ cd ~ + - $ git clone https://github.com/troglobit/smcroute.git + - $ cd smcroute + - $ sed -i 's/aclocal-1.11/aclocal/g' ./autogen.sh + - $ sed -i 's/automake-1.11/automake/g' ./autogen.sh + - $ ./autogen.sh + - $ ./configure + - $ make + - $ sudo make install + - $ cd .. + +It is also required to create a configuration file using the following command: + + - $ SMCROUTE_NIC=(name of the nic) + +where name of the nic is the name used previously for the variable "name_if_2". +In the example it would be: + + - $ SMCROUTE_NIC=p1p2 + +Then create the smcroute configuration file /etc/smcroute.conf + + - $echo mgroup from $SMCROUTE_NIC group 224.192.16.1 > /etc/smcroute.conf + + +Experiment using SR-IOV configuration on the compute node ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +In order to enable SR-IOV interfaces on the physical NIC of the compute node, a compatible NIC is required. +NIC configuration depends on model and vendor. After proper configuration to support SR-IOV, a proper configuration of openstack is required. +For further information, please look at the following link: +https://wiki.openstack.org/wiki/SR-IOV-Passthrough-For-Networking diff --git a/yardstick/vTC/apexlake/__init__.py b/yardstick/vTC/apexlake/__init__.py new file mode 100644 index 000000000..8898092d0 --- /dev/null +++ b/yardstick/vTC/apexlake/__init__.py @@ -0,0 +1,17 @@ +# 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. + +""" +Benchmarking Framework +""" diff --git a/yardstick/vTC/apexlake/apexlake.conf b/yardstick/vTC/apexlake/apexlake.conf new file mode 100644 index 000000000..56937d2ef --- /dev/null +++ b/yardstick/vTC/apexlake/apexlake.conf @@ -0,0 +1,69 @@ +[General] +## template_base is the name of the base template from which generate all the others +#template_base_name = vTC.yaml +## Benchmarks to be executed on the VNF under test (uncomment one of the following) +#benchmarks = instantiation_validation_benchmark.InstantiationValidationBenchmark +#benchmarks = instantiation_validation_noisy_neighbors_benchmark.InstantiationValidationNoisyNeighborsBenchmark +#benchmarks = rfc2544_throughput_benchmark.RFC2544ThroughputBenchmark +#benchmarks = multi_tenancy_throughput_benchmark.MultiTenancyThroughputBenchmark +## Number of iterations +#iterations = 1 +#debug = true + + +[OpenStack] +## ip_controller is the IP address of the OpenStack Controller +#ip_controller = 10.2.1.1 +## Heat URL is the URL for the Heat endpoint +#heat_url = http://IP_ADDRESS_CONTROLLER:8004/v1/TENANT_ID +## user is the OpenStack user name +#user = admin +## password is the OpenStack password +#password = password +## auth_uri is the authentication URI provided by keystone +#auth_uri = http://IP_ADDRESS_CONTROLLER:5000/v2.0 +## project is the name of the project on which create the VNF instances +#project = demo + + +[Experiment-VNF] +## List of all the variables and the values that will be tested by the framework +#VNIC_TYPE = @string "direct", "normal" +#VTC_FLAVOR = @string "m1.small" "m1.medium" "m1.large" + + +[InfluxDB] +influxdb_ip_address = 192.168.1.1 +influxdb_port = 8086 +influxdb_db_name = database + + +[PacketGen] +packet_generator = dpdk_pktgen +pktgen_directory = /root/programs/Pktgen-DPDK/dpdk/examples/pktgen/ +dpdk_directory = /root/programs/Pktgen-DPDK/dpdk/ +program_name = app/app/x86_64-native-linuxapp-gcc/pktgen +coremask = 1f +memory_channels = 3 +bus_slot_nic_1 = 01:00.0 +bus_slot_nic_2 = 01:00.1 +name_if_1 = p2p1 +name_if_2 = p2p2 + + +[Deployment-parameters] +#default_net = monitoring +#default_subnet = monitoring_subnet +#source_net = inbound_traffic_network +#source_subnet = inbound_traffic_subnet +#destination_net = destination_B_network +#destination_subnet = destination_B_subnet +#destination_subnet = destination_B_subnet +#key_name = destination_B_subnet + + +[Testcase-parameters] +#packet_size = 1280 +#throughput = 1 +#vlan_sender = 1000 +#vlan_receiver = 1001
\ No newline at end of file diff --git a/yardstick/vTC/apexlake/bin/run_tests.sh b/yardstick/vTC/apexlake/bin/run_tests.sh index 01592ddc7..6707ad75e 100755 --- a/yardstick/vTC/apexlake/bin/run_tests.sh +++ b/yardstick/vTC/apexlake/bin/run_tests.sh @@ -1 +1,2 @@ +export PYTHONPATH=`pwd` nosetests --with-coverage --cover-erase --cover-package experimental_framework diff --git a/yardstick/vTC/apexlake/docs/source/api.rst b/yardstick/vTC/apexlake/docs/source/api.rst new file mode 100644 index 000000000..38085900b --- /dev/null +++ b/yardstick/vTC/apexlake/docs/source/api.rst @@ -0,0 +1,5 @@ +.. automodule:: experimental_framework.api + :members: + :undoc-members: + :inherited-members: + :show-inheritance: diff --git a/yardstick/vTC/apexlake/experimental_framework/__init__.py b/yardstick/vTC/apexlake/experimental_framework/__init__.py new file mode 100644 index 000000000..d4ab29e9d --- /dev/null +++ b/yardstick/vTC/apexlake/experimental_framework/__init__.py @@ -0,0 +1,17 @@ +# 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. + +''' +Experimental Framework +''' diff --git a/yardstick/vTC/apexlake/experimental_framework/api.py b/yardstick/vTC/apexlake/experimental_framework/api.py new file mode 100644 index 000000000..1851f1b09 --- /dev/null +++ b/yardstick/vTC/apexlake/experimental_framework/api.py @@ -0,0 +1,148 @@ +# 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. + +import experimental_framework.benchmarking_unit as b_unit +from experimental_framework import heat_template_generation, common + + +class FrameworkApi(object): + + @staticmethod + def init(): + """ + Initializes the Framework + + :return: None + """ + 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() + + @staticmethod + 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() + + @staticmethod + 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.init(api=True) + + # Input Validation + 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 diff --git a/yardstick/vTC/apexlake/experimental_framework/benchmarking_unit.py b/yardstick/vTC/apexlake/experimental_framework/benchmarking_unit.py new file mode 100644 index 000000000..1963696f8 --- /dev/null +++ b/yardstick/vTC/apexlake/experimental_framework/benchmarking_unit.py @@ -0,0 +1,281 @@ +# 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. + +''' +The Benchmarking Unit manages the Benchmarking of VNFs orchestrating the +initialization, execution and finalization +''' + + +import json +import time +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. + + :return: None + """ + # 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 + + :return: None + """ + 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()) + + def finalize(self): + """ + Finalizes the Benchmarking Unit + Destroys all the stacks deployed by the framework and save results on + csv file. + + :return: None + """ + # 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. + + :return: None + """ + 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) + common.LOG.info(log_msg) + + # 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( + experiment_name) + common.LOG.info(log_msg) + 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 {}'.\ + format(experiment_name) + common.LOG.info(log_msg) + common.DEPLOYMENT_UNIT.destroy_heat_template( + experiment_name) + + # Finalize the benchmark + benchmark.finalize() + log_msg = 'Benchmark {} terminated'.format( + benchmark.__class__.__name__) + common.LOG.info(log_msg) + # 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) + + @staticmethod + 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)]) + + @staticmethod + 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] + + @staticmethod + 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 diff --git a/yardstick/vTC/apexlake/experimental_framework/benchmarks/__init__.py b/yardstick/vTC/apexlake/experimental_framework/benchmarks/__init__.py new file mode 100644 index 000000000..99635a45a --- /dev/null +++ b/yardstick/vTC/apexlake/experimental_framework/benchmarks/__init__.py @@ -0,0 +1,17 @@ +# 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. + +""" +Benchmarks to be executed within the framework +""" diff --git a/yardstick/vTC/apexlake/experimental_framework/benchmarks/benchmark_base_class.py b/yardstick/vTC/apexlake/experimental_framework/benchmarks/benchmark_base_class.py index 756962714..41235635c 100644 --- a/yardstick/vTC/apexlake/experimental_framework/benchmarks/benchmark_base_class.py +++ b/yardstick/vTC/apexlake/experimental_framework/benchmarks/benchmark_base_class.py @@ -44,6 +44,9 @@ class BenchmarkBaseClass(object): def get_name(self): return self.name + def get_params(self): + return self.params + def get_features(self): features = dict() features['description'] = 'Please implement the method ' \ diff --git a/yardstick/vTC/apexlake/experimental_framework/benchmarks/instantiation_validation_benchmark.py b/yardstick/vTC/apexlake/experimental_framework/benchmarks/instantiation_validation_benchmark.py index 29a87f2ee..049912305 100644 --- a/yardstick/vTC/apexlake/experimental_framework/benchmarks/instantiation_validation_benchmark.py +++ b/yardstick/vTC/apexlake/experimental_framework/benchmarks/instantiation_validation_benchmark.py @@ -36,8 +36,9 @@ class InstantiationValidationBenchmark(base.BenchmarkBaseClass): def __init__(self, name, params): base.BenchmarkBaseClass.__init__(self, name, params) - self.base_dir = common.get_base_dir() + \ - fp.EXPERIMENTAL_FRAMEWORK_DIR + fp.DPDK_PKTGEN_DIR + 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 = '' @@ -143,7 +144,7 @@ class InstantiationValidationBenchmark(base.BenchmarkBaseClass): if self.res_dir: packet_checker_res = \ int(common.get_file_first_line(self.res_dir + - '/packet_checker.res')) + '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: @@ -158,7 +159,7 @@ class InstantiationValidationBenchmark(base.BenchmarkBaseClass): :return: """ # Kill any other process running from previous failed execution - self.res_dir = os.getcwd() + self.res_dir = common.get_result_dir() pids = self._get_pids() for pid in pids: os.kill(pid, signal.SIGTERM) @@ -192,6 +193,9 @@ class InstantiationValidationBenchmark(base.BenchmarkBaseClass): common.run_command(command) # Start the packet checker + # TODO: Compile "make" the packet sniffer + command = "chmod +x {}".format(self.pkt_checker_command) + common.run_command(command) command = self.pkt_checker_command command += self.interface_name + '.' + self.params[VLAN_RECEIVER] command += ' 128' diff --git a/yardstick/vTC/apexlake/experimental_framework/benchmarks/instantiation_validation_noisy_neighbors_benchmark.py b/yardstick/vTC/apexlake/experimental_framework/benchmarks/instantiation_validation_noisy_neighbors_benchmark.py index 4e3b640d8..9610bc165 100644 --- a/yardstick/vTC/apexlake/experimental_framework/benchmarks/instantiation_validation_noisy_neighbors_benchmark.py +++ b/yardstick/vTC/apexlake/experimental_framework/benchmarks/instantiation_validation_noisy_neighbors_benchmark.py @@ -45,11 +45,11 @@ class InstantiationValidationNoisyNeighborsBenchmark( features['allowed_values'][NUMBER_OF_CORES] = \ ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'] features['allowed_values'][AMOUNT_OF_RAM] = \ - ['250M', '1G', '2G', '3G', '4G', '5G', '6G', '7G', '8G', '9G', + ['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] = '250M' + features['default_values'][AMOUNT_OF_RAM] = '256M' return features def init(self): diff --git a/yardstick/vTC/apexlake/experimental_framework/benchmarks/multi_tenancy_throughput_benchmark.py b/yardstick/vTC/apexlake/experimental_framework/benchmarks/multi_tenancy_throughput_benchmark.py index ba1e0cc81..3182837c5 100644 --- a/yardstick/vTC/apexlake/experimental_framework/benchmarks/multi_tenancy_throughput_benchmark.py +++ b/yardstick/vTC/apexlake/experimental_framework/benchmarks/multi_tenancy_throughput_benchmark.py @@ -40,11 +40,11 @@ class MultiTenancyThroughputBenchmark(base.RFC2544ThroughputBenchmark): features['allowed_values']['number_of_cores'] = \ ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'] features['allowed_values']['amount_of_ram'] = \ - ['250M', '1G', '2G', '3G', '4G', '5G', '6G', '7G', '8G', '9G', + ['256M', '1G', '2G', '3G', '4G', '5G', '6G', '7G', '8G', '9G', '10G'] features['default_values']['num_of_neighbours'] = '1' features['default_values']['number_of_cores'] = '1' - features['default_values']['amount_of_ram'] = '250M' + features['default_values']['amount_of_ram'] = '256M' return features def init(self): diff --git a/yardstick/vTC/apexlake/experimental_framework/benchmarks/rfc2544_throughput_benchmark.py b/yardstick/vTC/apexlake/experimental_framework/benchmarks/rfc2544_throughput_benchmark.py index 2ac3ea9c4..e026fa377 100644 --- a/yardstick/vTC/apexlake/experimental_framework/benchmarks/rfc2544_throughput_benchmark.py +++ b/yardstick/vTC/apexlake/experimental_framework/benchmarks/rfc2544_throughput_benchmark.py @@ -1,3 +1,4 @@ + # Copyright (c) 2015 Intel Research and Development Ireland Ltd. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -74,9 +75,7 @@ class RFC2544ThroughputBenchmark(benchmark_base_class.BenchmarkBaseClass): to measure the throughput of the workload :return: Results of the testcase (type: dict) """ - ret_val = dict() packet_size = self._extract_packet_size_from_params() - ret_val[PACKET_SIZE] = packet_size # Packetgen management packetgen = dpdk.DpdkPacketGenerator() @@ -93,12 +92,7 @@ class RFC2544ThroughputBenchmark(benchmark_base_class.BenchmarkBaseClass): packetgen.send_traffic() common.LOG.debug('Stop the packet generator') - # Result Collection - results = self._get_results() - for metric_name in results.keys(): - ret_val[metric_name] = results[metric_name] - self._reset_lua_file() - return ret_val + return self._get_results() def _extract_packet_size_from_params(self): """ diff --git a/yardstick/vTC/apexlake/experimental_framework/benchmarks/test_benchmark.py b/yardstick/vTC/apexlake/experimental_framework/benchmarks/test_benchmark.py index d530168da..cbb930d21 100644 --- a/yardstick/vTC/apexlake/experimental_framework/benchmarks/test_benchmark.py +++ b/yardstick/vTC/apexlake/experimental_framework/benchmarks/test_benchmark.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import time from experimental_framework.benchmarks import benchmark_base_class as base @@ -33,4 +34,5 @@ class TestBenchmark(base.BenchmarkBaseClass): return features def run(self): + time.sleep(10) return dict() diff --git a/yardstick/vTC/apexlake/experimental_framework/common.py b/yardstick/vTC/apexlake/experimental_framework/common.py new file mode 100644 index 000000000..afe70241a --- /dev/null +++ b/yardstick/vTC/apexlake/experimental_framework/common.py @@ -0,0 +1,600 @@ +# 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. + +import os +import re +import ConfigParser +import logging +import fileinput +from experimental_framework.constants import conf_file_sections as cf +from experimental_framework.constants import framework_parameters as fp + + +# ------------------------------------------------------ +# 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 + +# TODO: remove Influx +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(), + '/tmp/apexlake/apexlake.conf') + + +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/" + + # 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 + msg = "Parameter {} is not present in section {}".format( + cf.CFSP_DPDK_PKTGEN_DIRECTORY, cf.CFS_PKTGEN) + InputValidation.validate_configuration_file_parameter( + 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 + msg = "Parameter {} is not present in section {}".format( + cf.CFSP_DPDK_PROGRAM_NAME, cf.CFS_PKTGEN) + InputValidation.validate_configuration_file_parameter( + 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 + msg = "Parameter {} is not present in section {}".format( + cf.CFSP_DPDK_COREMASK, cf.CFS_PKTGEN) + InputValidation.validate_configuration_file_parameter( + 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 + msg = "Parameter {} is not present in section {}".format( + cf.CFSP_DPDK_MEMORY_CHANNEL, cf.CFS_PKTGEN) + InputValidation.validate_configuration_file_parameter( + 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 + msg = "Parameter {} is not present in section {}".format( + cf.CFSP_DPDK_BUS_SLOT_NIC_1, cf.CFS_PKTGEN) + InputValidation.validate_configuration_file_parameter( + 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 + msg = "Parameter {} is not present in section {}".format( + cf.CFSP_DPDK_BUS_SLOT_NIC_2, cf.CFS_PKTGEN) + InputValidation.validate_configuration_file_parameter( + 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 + msg = "Parameter {} is not present in section {}".format( + cf.CFSP_DPDK_NAME_IF_1, cf.CFS_PKTGEN) + InputValidation.validate_configuration_file_parameter( + 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 + msg = "Parameter {} is not present in section {}".format( + cf.CFSP_DPDK_NAME_IF_2, cf.CFS_PKTGEN) + InputValidation.validate_configuration_file_parameter( + 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 + msg = "Parameter {} is not present in section {}".format( + cf.CFSP_DPDK_DPDK_DIRECTORY, cf.CFS_PKTGEN) + InputValidation.validate_configuration_file_parameter( + 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) + :return: None + """ + InputValidation.validate_string( + config_file, "The configuration file name must be a string") + # config_file = BASE_DIR + config_file + InputValidation.validate_file_exist( + 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)) + + @staticmethod + 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) + :param config_file: name of the configuration file (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 section: section to be loaded (string) + :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 + :param section: section to be loaded (string) + :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 + + :return: dict + """ + testcase_parameters = dict() + parameters = CONF_FILE.get_variable_list(cf.CFS_TESTCASE_PARAMETERS) + for param in parameters: + testcase_parameters[param] = CONF_FILE.get_variable( + cf.CFS_TESTCASE_PARAMETERS, param) + return testcase_parameters + + +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 + :return: None + """ + 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) + message = "The name of the file must be a string" + 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'): + return dict() + 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): + + @staticmethod + def validate_string(param, message): + if not isinstance(param, str): + raise ValueError(message) + return True + + @staticmethod + def validate_integer(param, message): + if not isinstance(param, int): + raise ValueError(message) + return True + + @staticmethod + def validate_dictionary(param, message): + if not isinstance(param, dict): + raise ValueError(message) + return True + + @staticmethod + def validate_file_exist(file_name, message): + if not os.path.isfile(file_name): + raise ValueError(message + ' ' + file_name) + return True + + @staticmethod + def validate_directory_exist_and_format(directory, message): + if not os.path.isdir(directory): + raise ValueError(message) + if not directory.endswith('/'): + return directory + '/' + return directory + + @staticmethod + def validate_configuration_file_parameter(section, parameter, message): + params = CONF_FILE.get_variable_list(section) + if parameter not in params: + raise ValueError(message) + return True + + @staticmethod + def validate_configuration_file_section(section, message): + if section not in cf.get_sections(): + raise ValueError(message) + return True + + @staticmethod + 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) + + @staticmethod + 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: + return True + msg = 'OpenStack Credentials Error! ' \ + 'The following parameters are missing: {}'.\ + format(", ".join(missing)) + raise ValueError(msg) diff --git a/yardstick/vTC/apexlake/experimental_framework/constants/conf_file_sections.py b/yardstick/vTC/apexlake/experimental_framework/constants/conf_file_sections.py index eed00bce0..f397984e9 100644 --- a/yardstick/vTC/apexlake/experimental_framework/constants/conf_file_sections.py +++ b/yardstick/vTC/apexlake/experimental_framework/constants/conf_file_sections.py @@ -23,6 +23,7 @@ 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(): @@ -31,9 +32,10 @@ def get_sections(): CFS_GENERAL, CFS_OPENSTACK, CFS_EXPERIMENT_VNF, - CFS_EXPERIMENT_GENERIC, + # CFS_EXPERIMENT_GENERIC, CFS_TESTCASE_PARAMETERS, - CFS_DEPLOYMENT_PARAMETERS + CFS_DEPLOYMENT_PARAMETERS, + CFS_INFLUXDB # Add here eventually new sections in configuration file ... ] @@ -42,8 +44,7 @@ def get_sections_api(): return [ CFS_PKTGEN, CFS_GENERAL, - # TODO: TO BE REMOVED AFTER TESTING THE API - CFS_OPENSTACK + CFS_INFLUXDB # Add here eventually new sections in configuration file ... ] @@ -55,17 +56,30 @@ 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_DIRECTORY = 'directory' +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_CORE_NICS = 'core_nics' +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' # ------------------------------------------------------ diff --git a/yardstick/vTC/apexlake/experimental_framework/deployment_unit.py b/yardstick/vTC/apexlake/experimental_framework/deployment_unit.py new file mode 100644 index 000000000..186258f7d --- /dev/null +++ b/yardstick/vTC/apexlake/experimental_framework/deployment_unit.py @@ -0,0 +1,119 @@ +# 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. + +import os +import time + +from experimental_framework import heat_manager +from experimental_framework import common + +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) + :return: None + """ + 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) + return True + except: + return False + + def destroy_all_deployed_stacks(self): + """ + Destroys all the stacks currently deployed + :return: None + """ + 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) + status = self.heat_manager.check_stack_status(stack_name) + 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: + self.destroy_heat_template(stack_name) + except Exception as e: + common.LOG.debug(e.message) + 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) + return True diff --git a/yardstick/vTC/apexlake/experimental_framework/heat_manager.py b/yardstick/vTC/apexlake/experimental_framework/heat_manager.py index 41fc585f7..607fa77f3 100644 --- a/yardstick/vTC/apexlake/experimental_framework/heat_manager.py +++ b/yardstick/vTC/apexlake/experimental_framework/heat_manager.py @@ -19,7 +19,7 @@ from keystoneclient.v2_0 import client as keystoneClient from heatclient import client as heatClient from heatclient.common import template_utils -from experimental_framework import common +import experimental_framework.common as common class HeatManager: @@ -33,15 +33,14 @@ class HeatManager: self.project_id = credentials['project'] self.heat = None - # TODO: verify that init_heat is useless in the constructor - # self.init_heat() - 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) diff --git a/yardstick/vTC/apexlake/experimental_framework/heat_template_generation.py b/yardstick/vTC/apexlake/experimental_framework/heat_template_generation.py index 15c4eff36..e0c1a667f 100644 --- a/yardstick/vTC/apexlake/experimental_framework/heat_template_generation.py +++ b/yardstick/vTC/apexlake/experimental_framework/heat_template_generation.py @@ -14,8 +14,7 @@ ''' -This file contains the code to Generate the heat templates from the base -template +Generation of the heat templates from the base template ''' import json @@ -160,7 +159,8 @@ def generates_templates(base_heat_template, deployment_configuration): # Delete the templates eventually generated in previous running of the # framework common.LOG.info("Removing the heat templates previously generated") - os.system("rm " + template_dir + template_name + "_*") + 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") @@ -188,10 +188,7 @@ def generates_templates(base_heat_template, deployment_configuration): base_template = template_base_name else: base_template = template_dir + template_base_name - if os.path.isabs(template_name): - new_template = template_name - else: - new_template = template_dir + template_name + new_template = template_dir + template_name new_template += "_" + str(counter) + template_file_extension shutil.copy(base_template, new_template) diff --git a/yardstick/vTC/apexlake/experimental_framework/libraries/packet_checker/test_sniff.c b/yardstick/vTC/apexlake/experimental_framework/libraries/packet_checker/test_sniff.c index f85acfa11..a4eda3cff 100644 --- a/yardstick/vTC/apexlake/experimental_framework/libraries/packet_checker/test_sniff.c +++ b/yardstick/vTC/apexlake/experimental_framework/libraries/packet_checker/test_sniff.c @@ -135,7 +135,7 @@ int main(int argc,char **argv) int write_file() { - FILE *f = fopen("packet_checker.res", "w"); + FILE *f = fopen("/tmp/apexlake/results/packet_checker.res", "w"); if (f == NULL) { printf("Error opening file!\n"); diff --git a/yardstick/vTC/apexlake/experimental_framework/packet_generators/dpdk_packet_generator.py b/yardstick/vTC/apexlake/experimental_framework/packet_generators/dpdk_packet_generator.py index ae54502e9..347d51af3 100644 --- a/yardstick/vTC/apexlake/experimental_framework/packet_generators/dpdk_packet_generator.py +++ b/yardstick/vTC/apexlake/experimental_framework/packet_generators/dpdk_packet_generator.py @@ -15,6 +15,7 @@ import os import base_packet_generator import experimental_framework.common as common +import time from experimental_framework.constants import conf_file_sections as conf_file from experimental_framework.constants import framework_parameters as fp @@ -141,6 +142,8 @@ class DpdkPacketGenerator(base_packet_generator.BasePacketGenerator): 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 common.run_command(command) @@ -244,6 +247,7 @@ class DpdkPacketGenerator(base_packet_generator.BasePacketGenerator): common.run_command(dpdk_vars[conf_file.CFSP_DPDK_DPDK_DIRECTORY] + 'tools/dpdk_nic_bind.py --unbind ' + dpdk_vars[conf_file.CFSP_DPDK_BUS_SLOT_NIC_1]) + time.sleep(5) common.run_command(dpdk_vars[conf_file.CFSP_DPDK_DPDK_DIRECTORY] + 'tools/dpdk_nic_bind.py --bind=ixgbe ' + dpdk_vars[conf_file.CFSP_DPDK_BUS_SLOT_NIC_1]) @@ -255,6 +259,7 @@ class DpdkPacketGenerator(base_packet_generator.BasePacketGenerator): common.run_command(dpdk_vars[conf_file.CFSP_DPDK_DPDK_DIRECTORY] + 'tools/dpdk_nic_bind.py --unbind ' + dpdk_vars[conf_file.CFSP_DPDK_BUS_SLOT_NIC_2]) + time.sleep(5) common.run_command(dpdk_vars[conf_file.CFSP_DPDK_DPDK_DIRECTORY] + 'tools/dpdk_nic_bind.py --bind=ixgbe ' + dpdk_vars[conf_file.CFSP_DPDK_BUS_SLOT_NIC_2]) diff --git a/yardstick/vTC/apexlake/heat_templates/stress_workload.yaml b/yardstick/vTC/apexlake/heat_templates/stress_workload.yaml new file mode 100644 index 000000000..1a2f7dbb3 --- /dev/null +++ b/yardstick/vTC/apexlake/heat_templates/stress_workload.yaml @@ -0,0 +1,112 @@ +heat_template_version: 2014-10-16 +description: HOT template to create a DPI + +parameters: + nic_type: + type: string + default: normal + name: + type: string + default: cpu_stress + cores: + type: string + memory: + type: string + +resources: + internal_net: + type: OS::Neutron::Net + properties: + name: traffic_network + internal_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: internal_net } + cidr: 10.100.0.0/24 + + router: + properties: + admin_state_up: true + name: router + type: OS::Neutron::Router + + router_gateway: + properties: + network: external + router_id: { get_resource: router } + type: OS::Neutron::RouterGateway + + router_interface_0: + properties: + router_id: { get_resource: router } + subnet_id: { get_resource: internal_subnet } + type: OS::Neutron::RouterInterface + + vm1_port_1: + type: OS::Neutron::Port + properties: + network: { get_resource: internal_net } + binding:vnic_type: { get_param: nic_type } + fixed_ips: + - subnet: { get_resource: internal_subnet } + + flavor_1: + type: OS::Nova::Flavor + properties: + disk: 20 + ram: 4096 + vcpus: 4 + + vm1: + type: OS::Nova::Server + properties: + name: traffic_vm1 + key_name: test + image: ubuntu1404 + user_data: + str_replace: + template: | + #!/bin/sh + echo "Creating custom user..." + useradd clouduser -g admin -s /bin/bash -m + echo clouduser:secrete | chpasswd + echo "Enabling ssh password login..." + sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config + service ssh restart + sleep 1 + + ifconfig eth1 up + dhclient eth1 + + sed -i 's/localhost/localhost traffic_vm1/g' /etc/hosts + touch /etc/resolfconf/resolv.conf.d/tail + echo 'nameserver 8.8.8.8' > /etc/resolvconf/resolv.conf.d/tail + resolvconf -u + + # Installation of stress + apt-get install -y stress + + cd /home/clouduser + # Setup merlin + rm -rf merlin + mkdir merlin + cd merlin + wget http://10.2.1.65/~iolie/merlin/MerlinAgent-12-06-2015-TNovaVM-001.zip + apt-get install -y zip + unzip MerlinAgent-12-06-2015-TNovaVM-001.zip + ./updateConfiguration.py ./instrumentation.cfg tags source=tnova_vm + ./updateConfiguration.py ./instrumentation.cfg tags role=cpu_stress + nohup ./Agent.py ./instrumentation.cfg >log.out 2>&1 & + cd .. + + # workload setup + nohup stress -c #CORES --vm-bytes #MEMORY + + params: + $NAME: { get_param: name } + $CORES: { get_param: cores } + $MEMORY: { get_param: memory } + + flavor: { get_resource: flavor_1 } + networks: + - port: { get_resource: vm1_port_1 } diff --git a/yardstick/vTC/apexlake/heat_templates/vTC.yaml b/yardstick/vTC/apexlake/heat_templates/vTC.yaml new file mode 100644 index 000000000..e0163e872 --- /dev/null +++ b/yardstick/vTC/apexlake/heat_templates/vTC.yaml @@ -0,0 +1,167 @@ +heat_template_version: 2014-10-16 +description: HOT template to deploy a vitual Traffic Classifier + +parameters: + default_net: + type: string + default_subnet: + type: string + source_net: + type: string + source_subnet: + type: string + destination_net: + type: string + destination_subnet: + type: string + timeout: + type: number + description: Timeout for WaitCondition, depends on your image and environment + default: 2000 + +resources: + wait_condition: + type: OS::Heat::WaitCondition + properties: + handle: {get_resource: wait_handle} + count: 1 + timeout: {get_param: timeout} + + wait_handle: + type: OS::Heat::WaitConditionHandle + + ### DEFAULT NETWORK FOR MNGM + port_1: + type: OS::Neutron::Port + properties: + network: { get_param: default_net } + binding:vnic_type: normal + fixed_ips: + - subnet: { get_param: default_subnet } + + ### NETWORK FOR RECEIVING TRAFFIC + port_2: + type: OS::Neutron::Port + properties: + network: { get_param: source_net } + binding:vnic_type: #vnic_type + fixed_ips: + - subnet: { get_param: source_subnet } + + ### NETWORK FOR SENDING TRAFFIC + port_3: + type: OS::Neutron::Port + properties: + network: { get_param: destination_net } + binding:vnic_type: #vnic_type + fixed_ips: + - subnet: { get_param: destination_subnet } + + server: + type: OS::Nova::Server + properties: + name: vTC + #key_name: { get_param: key_name } + image: ubuntu1404 + user_data: + str_replace: + template: | + #!/bin/sh + # Creation of a user + echo "Creating custom user..." + useradd clouduser -g admin -s /bin/bash -m + echo clouduser:secrete | chpasswd + echo "Enabling ssh password login..." + sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config + service ssh restart + sleep 1 + + # wake up interfaces + ifconfig eth1 up + ifconfig eth2 up + dhclient eth1 + dhclient eth2 + + # Install vTC Dependencies + apt-get update + apt-get install -y git build-essential gcc libnuma-dev bison flex byacc libjson0-dev libcurl4-gnutls-dev jq dh-autoreconf libpcap-dev libpulse-dev libtool pkg-config + apt-get install -y byacc libtool libcurl4-openssl-dev + + sed -i 's/localhost/localhost vtc/g' /etc/hosts + cd /home/clouduser + + # Setup multicast + echo mgroup from eth1 group 224.192.16.1 > /etc/smcroute.conf + git clone https://github.com/troglobit/smcroute.git + cd smcroute + sed -i 's/aclocal-1.11/aclocal/g' ./autogen.sh + sed -i 's/automake-1.11/automake/g' ./autogen.sh + ./autogen.sh + ./configure + make + make install + cd .. + touch multicast.sh + echo "#!/bin/bash" > multicast.sh + echo "while [ true ]" >> multicast.sh + echo "do" >> multicast.sh + echo " smcroute -k" >> multicast.sh + echo " smcroute -d" >> multicast.sh + echo " sleep 50" >> multicast.sh + echo "done" >> multicast.sh + chmod +x multicast.sh + ./multicast.sh & + + rm resp.json + curl -X POST -u "mPkgwvJPsTFS8hYmHk:SDczcrK4cvnkMRWSEchB3ANcWbqFXqPx" https://bitbucket.org/site/oauth2/access_token -d grant_type=refresh_token -d refresh_token=38uFQuhEdPvCTbhc7k >> resp.json + access_token=`jq -r '.access_token' resp.json` + git clone https://x-token-auth:${access_token}@bitbucket.org/akiskourtis/vtc.git + cd vtc + git checkout -b stable + #Build nDPI library + cd nDPI + NDPI_DIR=$(pwd) + echo $NDPI_DIR + NDPI_INCLUDE=$(pwd)/src/include + echo $NDPI_INCLUDE + ./autogen.sh + ./configure + make + make install + + #Build PF_RING library + cd .. + cd PF_RING + make + #Build PF_RING examples, including the modified pfbridge, with nDPI integrated. + cd userland/examples/ + sed -i 's#EXTRA_LIBS =#EXTRA_LIBS='"${NDPI_DIR}"'/src/lib/.libs/libndpi.a -ljson-c#' ./Makefile + sed -i 's# -Ithird-party# -Ithird-party/ -I'"$NDPI_INCLUDE"' -I'"$NDPI_DIR"'#' ./Makefile + echo $NDPI_DIR + make + cd ../.. + cd .. + cd .. + + # To use PF_RING driver use the following + #sudo rmmod pf_ring + #insmod ./vtc/PF_RING/kernel/pf_ring.ko min_num_slots=16384 enable_debug=1 quick_mode=1 enable_tx_capture=0 + #./vtc/PF_RING/userland/examples/pfbridge -a eth1 -b eth2 & + sleep 5 + + # To use the Linux kernel driver use the following + cd /home/clouduser/ + sudo nohup ./vtc/nDPI/example/ndpiReader -i eth1 -a eth2 & + sleep 5 + + curl --data-ascii "{\"classification_rules\":[{\"RuleId\":\"1\",\"ToS\":\"16\"}]}" http://localhost:9999/classifier/classification_rules/224.192.16.1 & + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + wc_notify: { get_attr: ['wait_handle', 'curl_cli'] } + #$IP_FAMILY: { get_param: ip_family } + flavor: #vtc_flavor + networks: + - port: { get_resource: port_1 } + - port: { get_resource: port_2 } + - port: { get_resource: port_3 } +outputs: diff --git a/yardstick/vTC/apexlake/setup.py b/yardstick/vTC/apexlake/setup.py new file mode 100644 index 000000000..8ab3f4845 --- /dev/null +++ b/yardstick/vTC/apexlake/setup.py @@ -0,0 +1,38 @@ +""" +Experimental Framework +""" + +from distutils.core import setup + + +# TODO: Add instruction to compile the test_sniff + +setup(name='apexlake', + version='1.0', + description='Framework to automatically run experiments/benchmarks ' + 'with VMs within OpenStack environments', + author='Intel Research and Development Ireland Ltd', + author_email='vincenzo.m.riccobene@intel.com', + license='Apache 2.0', + url='www.intel.com', + packages=['experimental_framework', + 'experimental_framework.benchmarks', + 'experimental_framework.packet_generators', + 'experimental_framework.libraries', + 'experimental_framework.constants'], + include_package_data=True, + package_data={ + 'experimental_framework': [ + 'packet_generators/dpdk_pktgen/*.lua', + 'packet_generators/pcap_files/*.pcap', + 'packet_generators/pcap_files/*.sh', + 'libraries/packet_checker/*' + ] + }, + data_files=[ + ('/tmp/apexlake/', ['apexlake.conf']), + ('/tmp/apexlake/heat_templates/', + ['heat_templates/vTC.yaml']), + ('/tmp/apexlake/heat_templates/', + ['heat_templates/stress_workload.yaml']) + ]) diff --git a/yardstick/vTC/apexlake/tests/api_test.py b/yardstick/vTC/apexlake/tests/api_test.py new file mode 100644 index 000000000..4b70b9bd6 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/api_test.py @@ -0,0 +1,143 @@ +# 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. + + +import unittest +import mock +import os +import experimental_framework.common as common +from experimental_framework.api import FrameworkApi +from experimental_framework.benchmarking_unit import BenchmarkingUnit +import experimental_framework.benchmarks.\ + instantiation_validation_benchmark as iv + + +class DummyBenchmarkingUnit(BenchmarkingUnit): + + def __init__(self): + BenchmarkingUnit.__init__(self) + + @staticmethod + def get_available_test_cases(): + return ['BenchA', 'BenchB'] + + @staticmethod + def get_required_benchmarks(required_benchmarks): + common.BASE_DIR = "base_dir/" + return [iv.InstantiationValidationBenchmark('benchmark', dict())] + + +class DummyBenchmarkingUnit2(BenchmarkingUnit): + + counter_init = 0 + counter_finalize = 0 + counter_run = 0 + + def __init__(self, base_heat_template, credentials, + heat_template_parameters, iterations, test_cases): + DummyBenchmarkingUnit.counter_init = 0 + DummyBenchmarkingUnit.counter_finalize = 0 + DummyBenchmarkingUnit.counter_run = 0 + + def initialize(self): + DummyBenchmarkingUnit2.counter_init += 1 + + def run_benchmarks(self): + DummyBenchmarkingUnit2.counter_run += 1 + + def finalize(self): + DummyBenchmarkingUnit2.counter_finalize += 1 + + +class TestGeneratesTemplate(unittest.TestCase): + def setUp(self): + pass + + def tearDown(self): + pass + + @mock.patch('experimental_framework.common.init') + def test_init_for_success(self, mock_init): + FrameworkApi.init() + mock_init.assert_called_once_with(api=True) + + # @mock.patch('experimental_framework.benchmarking_unit.BenchmarkingUnit.' + # 'get_available_test_cases', + # side_effect=DummyBenchmarkingUnit.get_available_test_cases) + # def test_get_available_test_cases_for_success(self, mock_bench): + # expected = ['BenchA', 'BenchB'] + # output = FrameworkApi.get_available_test_cases() + # self.assertEqual(expected, output) + + @mock.patch('experimental_framework.benchmarking_unit.BenchmarkingUnit.' + 'get_required_benchmarks', + side_effect=DummyBenchmarkingUnit.get_required_benchmarks) + def test_get_test_case_features_for_success(self, mock_get_req_bench): + expected = dict() + expected['description'] = 'Instantiation Validation Benchmark' + expected['parameters'] = [ + iv.THROUGHPUT, + iv.VLAN_SENDER, + iv.VLAN_RECEIVER] + expected['allowed_values'] = dict() + expected['allowed_values'][iv.THROUGHPUT] = \ + map(str, range(0, 100)) + expected['allowed_values'][iv.VLAN_SENDER] = \ + map(str, range(-1, 4096)) + expected['allowed_values'][iv.VLAN_RECEIVER] = \ + map(str, range(-1, 4096)) + expected['default_values'] = dict() + expected['default_values'][iv.THROUGHPUT] = '1' + expected['default_values'][iv.VLAN_SENDER] = '-1' + expected['default_values'][iv.VLAN_RECEIVER] = '-1' + + test_case = 'instantiation_validation_benchmark.' \ + 'InstantiationValidationBenchmark' + output = FrameworkApi.get_test_case_features(test_case) + self.assertEqual(expected, output) + + def test__get_test_case_features__for_failure(self): + self.assertRaises( + ValueError, FrameworkApi.get_test_case_features, 111) + + @mock.patch('experimental_framework.common.init') + @mock.patch('experimental_framework.common.LOG') + @mock.patch('experimental_framework.common.get_credentials') + @mock.patch('experimental_framework.heat_template_generation.' + 'generates_templates') + @mock.patch('experimental_framework.benchmarking_unit.BenchmarkingUnit', + side_effect=DummyBenchmarkingUnit2) + def test_execute_framework_for_success(self, mock_b_unit, mock_heat, + mock_credentials, mock_log, + mock_common_init): + common.TEMPLATE_DIR = "{}/{}/".format( + os.getcwd(), 'tests/data/generated_templates' + ) + + test_cases = dict() + iterations = 1 + heat_template = 'VTC_base_single_vm_wait.tmp' + heat_template_parameters = dict() + deployment_configuration = '' + openstack_credentials = dict() + openstack_credentials['ip_controller'] = '' + openstack_credentials['heat_url'] = '' + openstack_credentials['user'] = '' + openstack_credentials['password'] = '' + openstack_credentials['auth_uri'] = '' + openstack_credentials['project'] = '' + FrameworkApi.execute_framework( + test_cases, iterations, heat_template, + heat_template_parameters, deployment_configuration, + openstack_credentials) diff --git a/yardstick/vTC/apexlake/tests/benchmarking_unit_test.py b/yardstick/vTC/apexlake/tests/benchmarking_unit_test.py new file mode 100644 index 000000000..ccf64066a --- /dev/null +++ b/yardstick/vTC/apexlake/tests/benchmarking_unit_test.py @@ -0,0 +1,477 @@ +# 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. + +__author__ = 'vmriccox' + + +import unittest +import mock +from experimental_framework.benchmarking_unit import BenchmarkingUnit +# from experimental_framework.data_manager import DataManager +from experimental_framework.deployment_unit import DeploymentUnit +import experimental_framework.common as common +from experimental_framework.benchmarks.rfc2544_throughput_benchmark import \ + RFC2544ThroughputBenchmark + + +# class DummyDataManager(DataManager): +# +# def __init__(self, experiment_directory): +# self.experiment_directory = experiment_directory +# self.experiments = dict() +# self.new_exp_counter = 0 +# self.add_bench_counter = 0 +# self.close_experiment_1_counter = 0 +# self.close_experiment_2_counter = 0 +# self.generate_csv_counter = 0 +# +# def create_new_experiment(self, experiment_name, get_counter=None): +# if not get_counter: +# self.new_exp_counter += 1 +# else: +# return self.new_exp_counter +# +# def add_benchmark(self, experiment_name, benchmark_name, get_counter=None): +# if not get_counter: +# self.add_bench_counter += 1 +# else: +# return self.add_bench_counter +# +# def close_experiment(self, experiment, get_counter=None): +# if get_counter: +# return [self.close_experiment_1_counter, +# self.close_experiment_2_counter] +# if experiment == 'VTC_base_single_vm_wait_1': +# self.close_experiment_1_counter += 1 +# if experiment == 'VTC_base_single_vm_wait_2': +# self.close_experiment_2_counter += 1 +# +# def generate_result_csv_file(self, get_counter=None): +# if get_counter: +# return self.generate_csv_counter +# else: +# self.generate_csv_counter += 1 +# +# def add_metadata(self, experiment_name, metadata): +# pass +# +# def add_configuration(self, experiment_name, configuration): +# pass +# +# def add_data_points(self, experiment_name, benchmark_name, result): +# pass + + +class Dummy_2544(RFC2544ThroughputBenchmark): + + def __init__(self, name, params): + self.name = name + self.init_counter = 0 + self.finalize_counter = 0 + self.run_counter = 0 + self.params = params + + def init(self, get_counter=None): + if get_counter: + return self.init_counter + else: + self.init_counter += 1 + + def finalize(self, get_counter=None): + if get_counter: + return self.finalize_counter + else: + self.finalize_counter += 1 + + def run(self, get_counter=None): + if get_counter: + return self.run_counter + else: + self.run_counter += 1 + return {'throughput': 10} + + +class DummyDeploymentUnit(DeploymentUnit): + + def __init__(self, openstack_credentials): + pass + + def deploy_heat_template(self, template_file, stack_name, parameters, + attempt=0): + return False + + +class TestBenchmarkingUnit(unittest.TestCase): + + def setUp(self): + pass + + def tearDown(self): + pass + + @mock.patch('time.time') + @mock.patch('experimental_framework.common.get_template_dir') + # @mock.patch('experimental_framework.data_manager.DataManager', + # side_effect=DummyDataManager) + @mock.patch('experimental_framework.deployment_unit.DeploymentUnit') + @mock.patch('experimental_framework.benchmarking_unit.heat.' + 'get_all_heat_templates') + def test___init__(self, mock_heat, mock_dep_unit, + # mock_data_manager, + mock_temp_dir, mock_time): + mock_heat.return_value = list() + mock_time.return_value = '12345' + mock_temp_dir.return_value = 'tests/data/results/' + common.TEMPLATE_FILE_EXTENSION = '.ext' + common.RESULT_DIR = 'tests/data/results/' + heat_template_name = 'name' + openstack_credentials = { + 'name': 'aaa', + 'surname': 'bbb' + } + heat_template_parameters = { + 'param_1': 'name_1', + 'param_2': 'name_2' + } + iterations = 1 + benchmarks = ['bench_1', 'bench_2'] + bu = BenchmarkingUnit(heat_template_name, + openstack_credentials, + heat_template_parameters, + iterations, + benchmarks) + self.assertEqual(bu.required_benchmarks, benchmarks) + bu.heat_template_parameters = heat_template_parameters + # mock_data_manager.assert_called_once_with('tests/data/results/12345') + mock_dep_unit.assert_called_once_with(openstack_credentials) + mock_heat.assert_called_once_with('tests/data/results/', '.ext') + + @mock.patch('experimental_framework.benchmarks.' + 'rfc2544_throughput_benchmark', side_effect=Dummy_2544) + @mock.patch('time.time') + @mock.patch('experimental_framework.common.get_template_dir') + # @mock.patch('experimental_framework.data_manager.DataManager', + # side_effect=DummyDataManager) + @mock.patch('experimental_framework.deployment_unit.DeploymentUnit') + @mock.patch('experimental_framework.benchmarking_unit.' + 'heat.get_all_heat_templates') + def test_initialize_for_success(self, mock_heat, mock_dep_unit, + # mock_data_manager, + mock_temp_dir, + mock_time, mock_rfc2544): + mock_heat.return_value = list() + mock_time.return_value = '12345' + mock_temp_dir.return_value = 'tests/data/test_templates/' + common.TEMPLATE_FILE_EXTENSION = '.yaml' + common.RESULT_DIR = 'tests/data/results/' + + heat_template_name = 'VTC_base_single_vm_wait_' + openstack_credentials = { + 'name': 'aaa', + 'surname': 'bbb' + } + heat_template_parameters = { + 'param_1': 'name_1', + 'param_2': 'name_2' + } + iterations = 1 + benchmarks = [ + { + 'name': + 'rfc2544_throughput_benchmark.RFC2544ThroughputBenchmark', + 'params': dict() + } + ] + bu = BenchmarkingUnit(heat_template_name, + openstack_credentials, + heat_template_parameters, + iterations, + benchmarks) + self.assertEqual(bu.required_benchmarks, benchmarks) + bu.heat_template_parameters = heat_template_parameters + bu.template_files = ['VTC_base_single_vm_wait_1.yaml', + 'VTC_base_single_vm_wait_2.yaml'] + bu.initialize() + self.assertTrue(len(bu.benchmarks) == 1) + self.assertEqual(bu.benchmarks[0].__class__, + Dummy_2544) + # self.assertEqual(bu.data_manager.create_new_experiment('', True), 2) + # self.assertEqual(bu.data_manager.add_benchmark('', '', True), 2) + + @mock.patch('experimental_framework.benchmarks.' + 'rfc2544_throughput_benchmark', side_effect=Dummy_2544) + @mock.patch('time.time') + @mock.patch('experimental_framework.common.get_template_dir') + # @mock.patch('experimental_framework.data_manager.DataManager', + # side_effect=DummyDataManager) + @mock.patch('experimental_framework.deployment_unit.DeploymentUnit') + @mock.patch('experimental_framework.benchmarking_unit.' + 'heat.get_all_heat_templates') + def test_finalize_for_success( + self, mock_heat, mock_dep_unit, + # mock_data_manager, + mock_temp_dir, mock_time, mock_rfc2544): + mock_heat.return_value = list() + mock_time.return_value = '12345' + mock_temp_dir.return_value = 'tests/data/test_templates/' + common.TEMPLATE_FILE_EXTENSION = '.yaml' + common.RESULT_DIR = 'tests/data/results/' + + heat_template_name = 'VTC_base_single_vm_wait_' + openstack_credentials = { + 'name': 'aaa', + 'surname': 'bbb' + } + heat_template_parameters = { + 'param_1': 'name_1', + 'param_2': 'name_2' + } + iterations = 1 + benchmarks = [ + { + 'name': + 'rfc2544_throughput_benchmark.RFC2544ThroughputBenchmark', + 'params': dict() + } + ] + bu = BenchmarkingUnit(heat_template_name, + openstack_credentials, + heat_template_parameters, + iterations, + benchmarks) + bu.heat_template_parameters = heat_template_parameters + bu.template_files = ['VTC_base_single_vm_wait_1.yaml', + 'VTC_base_single_vm_wait_2.yaml'] + bu.finalize() + # self.assertEqual(bu.data_manager.close_experiment('', True), [1, 1]) + # self.assertEqual(bu.data_manager.generate_result_csv_file(True), 1) + + @mock.patch('experimental_framework.common.push_data_influxdb') + @mock.patch('experimental_framework.common.LOG') + @mock.patch('experimental_framework.benchmarks.' + 'rfc2544_throughput_benchmark', side_effect=Dummy_2544) + @mock.patch('time.time') + @mock.patch('experimental_framework.common.get_template_dir') + # @mock.patch('experimental_framework.data_manager.DataManager', + # side_effect=DummyDataManager) + @mock.patch('experimental_framework.common.DEPLOYMENT_UNIT') + @mock.patch('experimental_framework.deployment_unit.DeploymentUnit') + @mock.patch('experimental_framework.benchmarking_unit.' + 'heat.get_all_heat_templates') + def test_run_benchmarks_for_success(self, mock_heat, mock_common_dep_unit, + mock_dep_unit, + # mock_data_manager, + mock_temp_dir, mock_time, + mock_rfc2544, mock_log, mock_influx): + mock_heat.return_value = list() + mock_time.return_value = '12345' + mock_temp_dir.return_value = 'tests/data/test_templates/' + common.TEMPLATE_FILE_EXTENSION = '.yaml' + common.RESULT_DIR = 'tests/data/results/' + common.INFLUXDB_IP = 'InfluxIP' + common.INFLUXDB_PORT = '8086' + common.INFLUXDB_DB_NAME = 'test_db' + + heat_template_name = 'VTC_base_single_vm_wait_' + openstack_credentials = { + 'name': 'aaa', + 'surname': 'bbb' + } + heat_template_parameters = { + 'param_1': 'name_1', + 'param_2': 'name_2' + } + iterations = 1 + benchmarks = [ + { + 'name': + 'rfc2544_throughput_benchmark.RFC2544ThroughputBenchmark', + 'params': dict() + } + ] + bu = BenchmarkingUnit(heat_template_name, + openstack_credentials, + heat_template_parameters, + iterations, + benchmarks) + # bu.data_manager = DummyDataManager('tests/data/results/12345') + bu.template_files = ['VTC_base_single_vm_wait_1.yaml', + 'VTC_base_single_vm_wait_2.yaml'] + bu.benchmarks = [Dummy_2544('dummy', {'param1': 'val1'})] + bu.run_benchmarks() + self.assertEqual(bu.benchmarks[0].init(True), 2) + self.assertEqual(bu.benchmarks[0].finalize(True), 2) + self.assertEqual(bu.benchmarks[0].run(True), 2) + # expected_metric = \ + # 'throughput,vnic_type=direct,ram=1024,benchmark=dummy,' \ + # 'vcpus=2,experiment_name=VTC_base_single_vm_wait_2,' \ + # 'param1=val1 value=10 12345000000000' + # mock_influx.assert_called_with(expected_metric) + + @mock.patch('experimental_framework.common.LOG') + @mock.patch('experimental_framework.benchmarks.' + 'rfc2544_throughput_benchmark', side_effect=Dummy_2544) + @mock.patch('time.time') + @mock.patch('experimental_framework.common.get_template_dir') + # @mock.patch('experimental_framework.data_manager.DataManager', + # side_effect=DummyDataManager) + @mock.patch('experimental_framework.common.DEPLOYMENT_UNIT') + @mock.patch('experimental_framework.deployment_unit.DeploymentUnit') + @mock.patch('experimental_framework.benchmarking_unit.' + 'heat.get_all_heat_templates') + def test_run_benchmarks_2_for_success( + self, mock_heat, mock_common_dep_unit, mock_dep_unit, + # mock_data_manager, + mock_temp_dir, mock_time, mock_rfc2544, + mock_log): + mock_heat.return_value = list() + mock_time.return_value = '12345' + mock_temp_dir.return_value = 'tests/data/test_templates/' + common.TEMPLATE_FILE_EXTENSION = '.yaml' + common.RESULT_DIR = 'tests/data/results/' + + heat_template_name = 'VTC_base_single_vm_wait_' + openstack_credentials = { + 'name': 'aaa', + 'surname': 'bbb' + } + heat_template_parameters = { + 'param_1': 'name_1', + 'param_2': 'name_2' + } + iterations = 1 + benchmarks = [ + { + 'name': + 'rfc2544_throughput_benchmark.RFC2544ThroughputBenchmark', + 'params': dict() + } + ] + bu = BenchmarkingUnit(heat_template_name, + openstack_credentials, + heat_template_parameters, + iterations, + benchmarks) + # bu.data_manager = DummyDataManager('tests/data/results/12345') + bu.template_files = ['VTC_base_single_vm_wait_1.yaml', + 'VTC_base_single_vm_wait_2.yaml'] + bu.benchmarks = [Dummy_2544('dummy', dict())] + common.DEPLOYMENT_UNIT = DummyDeploymentUnit(dict()) + bu.run_benchmarks() + self.assertEqual(bu.benchmarks[0].init(True), 2) + self.assertEqual(bu.benchmarks[0].finalize(True), 0) + self.assertEqual(bu.benchmarks[0].run(True), 0) + + @mock.patch('experimental_framework.common.LOG') + @mock.patch('experimental_framework.benchmarks.' + 'rfc2544_throughput_benchmark', side_effect=Dummy_2544) + @mock.patch('time.time') + @mock.patch('experimental_framework.common.get_template_dir') + # @mock.patch('experimental_framework.data_manager.DataManager', + # side_effect=DummyDataManager) + @mock.patch('experimental_framework.common.DEPLOYMENT_UNIT') + @mock.patch('experimental_framework.deployment_unit.DeploymentUnit') + @mock.patch('experimental_framework.benchmarking_unit.' + 'heat.get_all_heat_templates') + def test_get_benchmark_name_for_success( + self, mock_heat, mock_common_dep_unit, mock_dep_unit, + # mock_data_manager, + mock_temp_dir, mock_time, mock_rfc2544, + mock_log): + mock_heat.return_value = list() + mock_time.return_value = '12345' + mock_temp_dir.return_value = 'tests/data/test_templates/' + common.TEMPLATE_FILE_EXTENSION = '.yaml' + common.RESULT_DIR = 'tests/data/results/' + + heat_template_name = 'VTC_base_single_vm_wait_' + openstack_credentials = { + 'name': 'aaa', + 'surname': 'bbb' + } + heat_template_parameters = { + 'param_1': 'name_1', + 'param_2': 'name_2' + } + iterations = 1 + benchmarks = [ + { + 'name': + 'rfc2544_throughput_benchmark.RFC2544ThroughputBenchmark', + 'params': dict() + } + ] + bu = BenchmarkingUnit(heat_template_name, + openstack_credentials, + heat_template_parameters, + iterations, + benchmarks) + + expected = 'rfc2544_throughput_benchmark.RFC2544ThroughputBenchmark_0' + output = bu.get_benchmark_name( + 'rfc2544_throughput_benchmark.RFC2544ThroughputBenchmark') + self.assertEqual(expected, output) + + expected = 'rfc2544_throughput_benchmark.RFC2544ThroughputBenchmark_1' + output = bu.get_benchmark_name( + 'rfc2544_throughput_benchmark.RFC2544ThroughputBenchmark') + self.assertEqual(expected, output) + + @mock.patch('experimental_framework.common.LOG') + @mock.patch('experimental_framework.benchmarks.' + 'rfc2544_throughput_benchmark', side_effect=Dummy_2544) + @mock.patch('time.time') + @mock.patch('experimental_framework.common.get_template_dir') + # @mock.patch('experimental_framework.data_manager.DataManager', + # side_effect=DummyDataManager) + @mock.patch('experimental_framework.common.DEPLOYMENT_UNIT') + @mock.patch('experimental_framework.deployment_unit.DeploymentUnit') + @mock.patch('experimental_framework.benchmarking_unit.' + 'heat.get_all_heat_templates') + def test_get_required_benchmarks_for_success( + self, mock_heat, mock_common_dep_unit, mock_dep_unit, + # mock_data_manager, + mock_temp_dir, mock_time, mock_rfc2544, + mock_log): + mock_heat.return_value = list() + mock_time.return_value = '12345' + mock_temp_dir.return_value = 'tests/data/test_templates/' + common.TEMPLATE_FILE_EXTENSION = '.yaml' + common.RESULT_DIR = 'tests/data/results/' + openstack_credentials = { + 'name': 'aaa', + 'surname': 'bbb' + } + heat_template_parameters = { + 'param_1': 'name_1', + 'param_2': 'name_2' + } + iterations = 1 + benchmarks = [ + { + 'name': + 'rfc2544_throughput_benchmark.RFC2544ThroughputBenchmark', + 'params': dict() + } + ] + bu = BenchmarkingUnit('', + openstack_credentials, + heat_template_parameters, + iterations, + benchmarks) + req_benchs = \ + ['rfc2544_throughput_benchmark.RFC2544ThroughputBenchmark'] + output = bu.get_required_benchmarks(req_benchs) + self.assertEqual(len(req_benchs), 1) + self.assertEqual(output[0].__class__, Dummy_2544) diff --git a/yardstick/vTC/apexlake/tests/common_test.py b/yardstick/vTC/apexlake/tests/common_test.py new file mode 100644 index 000000000..293754b16 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/common_test.py @@ -0,0 +1,648 @@ +__author__ = 'vmricco' + +import unittest +import mock +import os +import logging +import ConfigParser +import experimental_framework.common as common +import experimental_framework.constants.conf_file_sections as cf + + +def reset_common(): + common.LOG = None + common.CONF_FILE = None + common.DEPLOYMENT_UNIT = None + common.ITERATIONS = None + common.BASE_DIR = None + common.RESULT_DIR = None + common.TEMPLATE_DIR = None + common.TEMPLATE_NAME = None + common.TEMPLATE_FILE_EXTENSION = None + common.PKTGEN = None + common.PKTGEN_DIR = None + common.PKTGEN_DPDK_DIRECTORY = None + common.PKTGEN_PROGRAM = None + common.PKTGEN_COREMASK = None + common.PKTGEN_MEMCHANNEL = None + common.PKTGEN_BUS_SLOT_NIC_1 = None + common.PKTGEN_BUS_SLOT_NIC_2 = None + common.INFLUXDB_IP = None + common.INFLUXDB_PORT = None + common.INFLUXDB_DB_NAME = None + + +class DummyConfigurationFile(common.ConfigurationFile): + def __init__(self, sections, conf_file=''): + pass + + def get_variable(self, section, variable_name): + return 'vTC.yaml' + + def get_variable_list(self, section): + return ['template_base_name'] + + +class DummyConfigurationFile2(common.ConfigurationFile): + def __init__(self, sections): + self.pktgen_counter = 0 + + def get_variable(self, section, variable_name): + if variable_name == cf.CFSG_TEMPLATE_NAME: + return 'vTC.yaml' + if variable_name == cf.CFSG_ITERATIONS: + return '2' + if variable_name == cf.CFSG_DEBUG: + return 'True' + if variable_name == cf.CFSP_PACKET_GENERATOR: + if self.pktgen_counter == 1: + return 'non_supported' + self.pktgen_counter += 1 + return 'dpdk_pktgen' + if variable_name == cf.CFSP_DPDK_PKTGEN_DIRECTORY: + return os.getcwd() + if variable_name == cf.CFSP_DPDK_PROGRAM_NAME: + return 'program' + if variable_name == cf.CFSP_DPDK_COREMASK: + return 'coremask' + if variable_name == cf.CFSP_DPDK_MEMORY_CHANNEL: + return 'memchannel' + if variable_name == cf.CFSP_DPDK_BUS_SLOT_NIC_1: + return 'bus_slot_nic_1' + if variable_name == cf.CFSP_DPDK_BUS_SLOT_NIC_2: + return 'bus_slot_nic_2' + if variable_name == cf.CFSP_DPDK_DPDK_DIRECTORY: + return os.getcwd() + + def get_variable_list(self, section): + if section == cf.CFS_PKTGEN: + return [ + cf.CFSP_DPDK_NAME_IF_2, + cf.CFSP_DPDK_NAME_IF_1, + cf.CFSP_DPDK_BUS_SLOT_NIC_1, + cf.CFSP_DPDK_BUS_SLOT_NIC_2, + cf.CFSP_DPDK_COREMASK, + cf.CFSP_DPDK_DPDK_DIRECTORY, + cf.CFSP_DPDK_PKTGEN_DIRECTORY, + cf.CFSP_DPDK_MEMORY_CHANNEL, + cf.CFSP_DPDK_PROGRAM_NAME, + cf.CFSP_PACKET_GENERATOR + ] + else: + return [ + 'template_base_name', + 'iterations', + cf.CFSG_DEBUG + ] + + +class TestCommonInit(unittest.TestCase): + + def setUp(self): + common.CONF_FILE = DummyConfigurationFile('') + self.dir = '{}/{}'.format(os.getcwd(), + 'experimental_framework/') + + def tearDown(self): + reset_common() + # common.CONF_FILE = None + + @mock.patch('os.getcwd') + @mock.patch('experimental_framework.common.init_conf_file') + @mock.patch('experimental_framework.common.init_general_vars') + @mock.patch('experimental_framework.common.init_log') + @mock.patch('experimental_framework.common.init_pktgen') + @mock.patch('experimental_framework.common.CONF_FILE') + def test_init_for_success(self, mock_conf_file, init_pkgen, init_log, + init_general_vars, init_conf_file, mock_getcwd): + mock_getcwd.return_value = self.dir + common.init(True) + init_pkgen.assert_called_once() + init_conf_file.assert_called_once() + init_general_vars.assert_called_once() + init_log.assert_called_once() + expected = self.dir.split('experimental_framework/')[0] + self.assertEqual(common.BASE_DIR, expected) + + @mock.patch('os.path.exists') + @mock.patch('os.makedirs') + @mock.patch('experimental_framework.common.LOG') + def test_init_general_vars_for_success(self, mock_log, mock_makedirs, + mock_path_exists): + common.BASE_DIR = "{}/".format(os.getcwd()) + mock_path_exists.return_value = False + common.init_general_vars() + self.assertEqual(common.TEMPLATE_FILE_EXTENSION, '.yaml') + self.assertEqual(common.TEMPLATE_DIR, '/tmp/apexlake/heat_templates/') + self.assertEqual(common.TEMPLATE_NAME, 'vTC.yaml') + self.assertEqual(common.RESULT_DIR, '/tmp/apexlake/results/') + self.assertEqual(common.ITERATIONS, 1) + # mock_makedirs.assert_called_once_with('/tmp/apexlake/heat_templates/') + + +class TestCommonInit2(unittest.TestCase): + + def setUp(self): + common.CONF_FILE = DummyConfigurationFile2('') + self.dir = '{}/{}'.format(os.getcwd(), 'experimental_framework/') + + def tearDown(self): + reset_common() + common.CONF_FILE = None + + @mock.patch('experimental_framework.common.LOG') + def test_init_general_vars_2_for_success(self, mock_log): + common.BASE_DIR = "{}/".format(os.getcwd()) + common.init_general_vars() + self.assertEqual(common.TEMPLATE_FILE_EXTENSION, '.yaml') + self.assertEqual(common.TEMPLATE_DIR, '/tmp/apexlake/heat_templates/') + self.assertEqual(common.TEMPLATE_NAME, 'vTC.yaml') + self.assertEqual(common.RESULT_DIR, '/tmp/apexlake/results/') + self.assertEqual(common.ITERATIONS, 2) + + def test_init_log_2_for_success(self): + common.init_log() + self.assertIsInstance(common.LOG, logging.RootLogger) + + def test_init_pktgen_for_success(self): + common.init_pktgen() + self.assertEqual(common.PKTGEN, 'dpdk_pktgen') + directory = self.dir.split('experimental_framework/')[0] + self.assertEqual(common.PKTGEN_DIR, directory) + self.assertEqual(common.PKTGEN_PROGRAM, 'program') + self.assertEqual(common.PKTGEN_COREMASK, 'coremask') + self.assertEqual(common.PKTGEN_MEMCHANNEL, 'memchannel') + self.assertEqual(common.PKTGEN_BUS_SLOT_NIC_1, 'bus_slot_nic_1') + self.assertEqual(common.PKTGEN_BUS_SLOT_NIC_2, 'bus_slot_nic_2') + expected_dir = "{}/".format(os.getcwd()) + self.assertEqual(common.PKTGEN_DPDK_DIRECTORY, expected_dir) + + def test_init_pktgen_for_failure(self): + common.CONF_FILE.get_variable('', cf.CFSP_PACKET_GENERATOR) + self.assertRaises(ValueError, common.init_pktgen) + + +class TestConfFileInitialization(unittest.TestCase): + + def setUp(self): + pass + + def tearDown(self): + reset_common() + + @mock.patch('experimental_framework.common.ConfigurationFile', + side_effect=DummyConfigurationFile) + def test_init_conf_file_for_success(self, conf_file): + common.CONF_FILE = None + common.init_conf_file(False) + self.assertIsInstance(common.CONF_FILE, + DummyConfigurationFile) + + common.CONF_FILE = None + common.init_conf_file(True) + self.assertIsInstance(common.CONF_FILE, + DummyConfigurationFile) + + @mock.patch('experimental_framework.common.CONF_FILE') + def test_init_log_for_success(self, mock_conf_file): + mock_conf_file.get_variable_list.return_value = 'value' + common.init_log() + self.assertIsInstance(common.LOG, logging.RootLogger) + + @mock.patch('experimental_framework.common.CONF_FILE') + def test_init_influxdb_for_success(self, mock_conf_file): + mock_conf_file.get_variable.return_value = 'value' + common.init_influxdb() + self.assertEqual(common.INFLUXDB_IP, 'value') + self.assertEqual(common.INFLUXDB_PORT, 'value') + self.assertEqual(common.INFLUXDB_DB_NAME, 'value') + + +class DummyConfigurationFile3(common.ConfigurationFile): + counter = 0 + + def __init__(self, sections, config_file='conf.cfg'): + common.ConfigurationFile.__init__(self, sections, config_file) + + @staticmethod + def _config_section_map(section, config_file, get_counter=None): + if get_counter: + return DummyConfigurationFile3.counter + else: + DummyConfigurationFile3.counter += 1 + return dict() + + +class TestConfigFileClass(unittest.TestCase): + + def setUp(self): + self.sections = [ + 'General', + 'OpenStack', + 'Experiment-VNF', + 'PacketGen', + 'Deployment-parameters', + 'Testcase-parameters' + ] + c_file = './tests/data/common/conf.cfg' + common.BASE_DIR = os.getcwd() + self.conf_file = common.ConfigurationFile(self.sections, c_file) + + def tearDown(self): + reset_common() + common.BASE_DIR = None + + @mock.patch('experimental_framework.common.ConfigurationFile.' + '_config_section_map', + side_effect=DummyConfigurationFile3._config_section_map) + def test___init___for_success(self, mock_conf_map): + sections = ['General', 'OpenStack', 'Experiment-VNF', 'PacketGen', + 'Deployment-parameters', 'Testcase-parameters'] + c = DummyConfigurationFile3( + sections, config_file='./tests/data/common/conf.cfg') + self.assertEqual( + DummyConfigurationFile3._config_section_map('', '', True), + 6) + for section in sections: + self.assertEqual(getattr(c, section), dict()) + + def test__config_section_map_for_success(self): + general_section = 'General' + # openstack_section = 'OpenStack' + config_file = 'tests/data/common/conf.cfg' + config = ConfigParser.ConfigParser() + config.read(config_file) + + expected = { + 'benchmarks': 'b_marks', + 'iterations': '1', + 'template_base_name': 't_name' + } + output = common.\ + ConfigurationFile._config_section_map(general_section, config) + self.assertEqual(expected, output) + + @mock.patch('experimental_framework.common.' + 'ConfigurationFile.get_variable_list') + def test_get_variable_for_success(self, mock_get_var_list): + section = self.sections[0] + variable_name = 'template_base_name' + expected = 't_name' + mock_get_var_list.return_value = [variable_name] + output = self.conf_file.get_variable(section, variable_name) + self.assertEqual(expected, output) + + @mock.patch('experimental_framework.common.' + 'ConfigurationFile.get_variable_list') + def test_get_variable_for_failure(self, mock_get_var_list): + section = self.sections[0] + variable_name = 'something_else' + self.assertRaises( + ValueError, + self.conf_file.get_variable, + section, variable_name + ) + + def test_get_variable_list_for_success(self): + section = self.sections[0] + expected = { + 'benchmarks': 'b_marks', + 'iterations': '1', + 'template_base_name': 't_name' + } + output = self.conf_file.get_variable_list(section) + self.assertEqual(expected, output) + + def test_get_variable_list_for_failure(self): + section = 'something_else' + self.assertRaises( + ValueError, + self.conf_file.get_variable_list, + section) + + +class DummyConfigurationFile4(common.ConfigurationFile): + + def get_variable(self, section, variable_name): + if variable_name == 'vnic2_type': + return '"value"' + elif variable_name == cf.CFSG_BENCHMARKS: + return "BenchmarkClass1, BenchmarkClass2" + return '@string "value"' + + # def get_variable_list(self, section): + # return list() + + +class TestCommonMethods(unittest.TestCase): + + def setUp(self): + self.sections = [ + 'General', + 'OpenStack', + 'Experiment-VNF', + 'PacketGen', + 'Deployment-parameters', + 'Testcase-parameters' + ] + config_file = './tests/data/common/conf.cfg' + common.BASE_DIR = os.getcwd() + common.CONF_FILE = DummyConfigurationFile4(self.sections, config_file) + + def tearDown(self): + reset_common() + common.CONF_FILE = None + + def test_get_credentials_for_success(self): + expected = { + 'ip_controller': '@string "value"', + 'project': '@string "value"', + 'auth_uri': '@string "value"', + 'user': '@string "value"', + 'heat_url': '@string "value"', + 'password': '@string "value"' + } + output = common.get_credentials() + self.assertEqual(expected, output) + + def test_get_heat_template_params_for_success(self): + expected = { + 'param_1': '@string "value"', + 'param_2': '@string "value"', + 'param_3': '@string "value"', + 'param_4': '@string "value"' + } + output = common.get_heat_template_params() + self.assertEqual(expected, output) + + def test_get_testcase_params_for_success(self): + expected = {'test_case_param': '@string "value"'} + output = common.get_testcase_params() + self.assertEqual(expected, output) + + def test_get_file_first_line_for_success(self): + file = 'tests/data/common/conf.cfg' + expected = '[General]\n' + output = common.get_file_first_line(file) + self.assertEqual(expected, output) + + def test_replace_in_file_for_success(self): + filename = 'tests/data/common/file_replacement.txt' + text_to_search = 'replacement of' + text_to_replace = '***' + common.replace_in_file(filename, text_to_search, text_to_replace) + after = open(filename, 'r').readline() + self.assertEqual(after, 'Test for the *** strings into a file\n') + text_to_search = '***' + text_to_replace = 'replacement of' + common.replace_in_file(filename, text_to_search, text_to_replace) + + @mock.patch('os.system') + @mock.patch('experimental_framework.common.LOG') + def test_run_command_for_success(self, mock_log, mock_os_system): + command = 'command to be run' + common.run_command(command) + mock_os_system.assert_called_once_with(command) + + @mock.patch('experimental_framework.common.run_command') + def test_push_data_influxdb_for_success(self, mock_run_cmd): + data = 'string that describes the data' + expected = "curl -i -XPOST 'http://None:None/write?db=None' " \ + "--data-binary string that describes the data" + common.push_data_influxdb(data) + mock_run_cmd.assert_called_once_with(expected) + + def test_get_base_dir_for_success(self): + base_dir = common.BASE_DIR + common.BASE_DIR = 'base_dir' + expected = 'base_dir' + output = common.get_base_dir() + self.assertEqual(expected, output) + common.BASE_DIR = base_dir + + def test_get_template_dir_for_success(self): + template_dir = common.TEMPLATE_DIR + common.TEMPLATE_DIR = 'base_dir' + expected = 'base_dir' + output = common.get_template_dir() + self.assertEqual(expected, output) + common.TEMPLATE_DIR = template_dir + + def test_get_dpdk_pktgen_vars_test(self): + # Test 1 + common.PKTGEN = 'dpdk_pktgen' + common.PKTGEN_DIR = 'var' + common.PKTGEN_PROGRAM = 'var' + common.PKTGEN_COREMASK = 'var' + common.PKTGEN_MEMCHANNEL = 'var' + common.PKTGEN_BUS_SLOT_NIC_1 = 'var' + common.PKTGEN_BUS_SLOT_NIC_2 = 'var' + common.PKTGEN_NAME_NIC_1 = 'var' + common.PKTGEN_NAME_NIC_2 = 'var' + common.PKTGEN_DPDK_DIRECTORY = 'var' + expected = { + 'bus_slot_nic_1': 'var', + 'bus_slot_nic_2': 'var', + 'name_if_1': 'var', + 'name_if_2': 'var', + 'coremask': 'var', + 'dpdk_directory': 'var', + 'memory_channels': 'var', + 'pktgen_directory': 'var', + 'program_name': 'var' + } + output = common.get_dpdk_pktgen_vars() + self.assertEqual(expected, output) + + # Test 2 + common.PKTGEN = 'something_else' + common.PKTGEN_DIR = 'var' + common.PKTGEN_PROGRAM = 'var' + common.PKTGEN_COREMASK = 'var' + common.PKTGEN_MEMCHANNEL = 'var' + common.PKTGEN_BUS_SLOT_NIC_1 = 'var' + common.PKTGEN_BUS_SLOT_NIC_2 = 'var' + common.PKTGEN_DPDK_DIRECTORY = 'var' + expected = {} + output = common.get_dpdk_pktgen_vars() + self.assertEqual(expected, output) + + @mock.patch('experimental_framework.common.LOG') + def test_get_deployment_configuration_variables_for_success(self, + mock_log): + expected = { + 'vcpu': ['value'], + 'vnic1_type': ['value'], + 'ram': ['value'], + 'vnic2_type': ['value'] + } + output = common.get_deployment_configuration_variables_from_conf_file() + self.assertEqual(expected, output) + + def test_get_benchmarks_from_conf_file_for_success(self): + expected = ['BenchmarkClass1', 'BenchmarkClass2'] + output = common.get_benchmarks_from_conf_file() + self.assertEqual(expected, output) + + +class TestinputValidation(unittest.TestCase): + + def setUp(self): + pass + + def tearDown(self): + reset_common() + + def test_validate_string_for_success(self): + output = common.InputValidation.validate_string('string', '') + self.assertTrue(output) + + def test_validate_string_for_failure(self): + self.assertRaises( + ValueError, + common.InputValidation.validate_string, + list(), '' + ) + + def test_validate_int_for_success(self): + output = common.InputValidation.validate_integer(1111, '') + self.assertTrue(output) + + def test_validate_int_for_failure(self): + self.assertRaises( + ValueError, + common.InputValidation.validate_integer, + list(), '' + ) + + def test_validate_dict_for_success(self): + output = common.InputValidation.validate_dictionary(dict(), '') + self.assertTrue(output) + + def test_validate_dict_for_failure(self): + self.assertRaises( + ValueError, + common.InputValidation.validate_dictionary, + list(), '' + ) + + def test_validate_file_exist_for_success(self): + filename = 'tests/data/common/file_replacement.txt' + output = common.InputValidation.validate_file_exist(filename, '') + self.assertTrue(output) + + def test_validate_file_exist_for_failure(self): + filename = 'tests/data/common/file_replacement' + self.assertRaises( + ValueError, + common.InputValidation.validate_file_exist, + filename, '' + ) + + def test_validate_directory_exist_and_format_for_success(self): + directory = 'tests/data/common/' + output = common.InputValidation.\ + validate_directory_exist_and_format(directory, '') + self.assertTrue(output) + + def test_validate_directory_exist_and_format_for_failure(self): + directory = 'tests/data/com/' + self.assertRaises( + ValueError, + common.InputValidation.validate_directory_exist_and_format, + directory, '' + ) + + @mock.patch('experimental_framework.common.CONF_FILE') + def test_validate_configuration_file_parameter_for_success(self, + mock_conf): + mock_conf.get_variable_list.return_value = ['param'] + section = '' + parameter = 'param' + message = '' + output = common.InputValidation.\ + validate_configuration_file_parameter(section, parameter, message) + self.assertTrue(output) + + @mock.patch('experimental_framework.common.CONF_FILE') + def test_validate_configuration_file_parameter_for_failure( + self, mock_conf_file): + section = '' + parameter = 'something_else' + message = '' + mock_conf_file.get_variable_list.return_value(['parameter']) + self.assertRaises( + ValueError, + common.InputValidation. + validate_configuration_file_parameter, + section, parameter, message + ) + + def test_validate_configuration_file_section_for_success(self): + section = 'General' + message = '' + output = common.InputValidation.\ + validate_configuration_file_section(section, message) + self.assertTrue(output) + + def test_validate_configuration_file_section_for_failure(self): + section = 'Something-Else' + message = '' + self.assertRaises( + ValueError, + common.InputValidation.validate_configuration_file_section, + section, message + ) + + def test_validate_boolean_for_success(self): + message = '' + boolean = True + output = common.InputValidation.validate_boolean(boolean, message) + self.assertTrue(output) + + boolean = 'True' + output = common.InputValidation.validate_boolean(boolean, message) + self.assertTrue(output) + + boolean = 'False' + output = common.InputValidation.validate_boolean(boolean, message) + self.assertFalse(output) + + def test_validate_boolean_for_failure(self): + message = '' + boolean = 'string' + self.assertRaises( + ValueError, + common.InputValidation.validate_boolean, + boolean, message + ) + + def test_validate_os_credentials_for_failure(self): + # Test 1 + credentials = list() + self.assertRaises(ValueError, + common.InputValidation.validate_os_credentials, + credentials) + + # Test 2 + credentials = dict() + credentials['ip_controller'] = '' + credentials['heat_url'] = '' + credentials['user'] = '' + credentials['password'] = '' + credentials['auth_uri'] = '' + # credentials['project'] = '' + self.assertRaises(ValueError, + common.InputValidation.validate_os_credentials, + credentials) + + def test_validate_os_credentials_for_success(self): + credentials = dict() + credentials['ip_controller'] = '' + credentials['heat_url'] = '' + credentials['user'] = '' + credentials['password'] = '' + credentials['auth_uri'] = '' + credentials['project'] = '' + self.assertTrue( + common.InputValidation.validate_os_credentials(credentials)) diff --git a/yardstick/vTC/apexlake/tests/conf_file_sections_test.py b/yardstick/vTC/apexlake/tests/conf_file_sections_test.py new file mode 100644 index 000000000..d2157fcce --- /dev/null +++ b/yardstick/vTC/apexlake/tests/conf_file_sections_test.py @@ -0,0 +1,30 @@ +# 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. + +__author__ = 'vmriccox' + + +import unittest +from experimental_framework.constants import conf_file_sections as cfs + + +class TestConfFileSection(unittest.TestCase): + + def setUp(self): + pass + + def test_get_sections_api_for_success(self): + expected = ['PacketGen', 'General', 'InfluxDB'] + output = cfs.get_sections_api() + self.assertEqual(expected, output) diff --git a/yardstick/vTC/apexlake/tests/data/common/conf.cfg b/yardstick/vTC/apexlake/tests/data/common/conf.cfg new file mode 100644 index 000000000..9266647e8 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/common/conf.cfg @@ -0,0 +1,43 @@ +[General] +template_base_name = t_name +benchmarks = b_marks +iterations = 1 + +[OpenStack] +ip_controller = +heat_url = +user = +password = +auth_uri = +project = + + +[Experiment-VNF] +VNIC1_TYPE = @string "normal" "direct" @costs '0', '1' +VNIC2_TYPE = @string "normal", "direct" @costs '0', '1' +VCPU = @numeric "4" +RAM = @numeric "4096" + + +[PacketGen] +packet_generator = dpdk_pktgen +pktgen_directory = pktgen_dir +dpdk_directory = dpdk_dir +program_name = app/app/x86_64-native-linuxapp-gcc/pktgen +coremask = 1f +memory_channels = 3 +bus_slot_nic_1 = 01:00.0 +name_if_1 = enp1s0f0 +bus_slot_nic_2 = 01:00.1 +name_if_2 = enp1s0f2 + + +[Deployment-parameters] +param_1 = val_1 +param_2 = val_2 +param_3 = val_3 +param_4 = val_4 + + +[Testcase-parameters] +test_case_param = 1280 diff --git a/yardstick/vTC/apexlake/tests/data/common/file_replacement.txt b/yardstick/vTC/apexlake/tests/data/common/file_replacement.txt new file mode 100644 index 000000000..8122d9a91 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/common/file_replacement.txt @@ -0,0 +1 @@ +Test for the replacement of strings into a file diff --git a/yardstick/vTC/apexlake/tests/data/generated_templates/VTC_base_single_vm_wait.tmp b/yardstick/vTC/apexlake/tests/data/generated_templates/VTC_base_single_vm_wait.tmp new file mode 100644 index 000000000..aa3959fc1 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/generated_templates/VTC_base_single_vm_wait.tmp @@ -0,0 +1,199 @@ +heat_template_version: 2014-10-16 +description: HOT template to create a DPI + +parameters: + default_net: + type: string + default_subnet: + type: string + source_net: + type: string + source_subnet: + type: string + destination_net: + type: string + destination_subnet: + type: string + internal_net: + type: string + internal_subnet: + type: string + node: + type: string + default: compB + name: + type: string + default: vtc + ip_family: + type: string + timeout: + type: number + description: Timeout for WaitCondition, depends on your image and environment + default: 1000 + +resources: + wait_condition: + type: OS::Heat::WaitCondition + properties: + handle: {get_resource: wait_handle} + count: 1 + timeout: {get_param: timeout} + + wait_handle: + type: OS::Heat::WaitConditionHandle + + + ### DEFAULT NETWORK FOR MERLIN DATA + port_1: + type: OS::Neutron::Port + properties: + network: { get_param: default_net } + binding:vnic_type: normal + fixed_ips: + - subnet: { get_param: default_subnet } + + ### NETWORK FOR RECEIVING TRAFFIC + port_2: + type: OS::Neutron::Port + properties: + network: { get_param: source_net } + binding:vnic_type: #vnic_type + fixed_ips: + - subnet: { get_param: source_subnet } + + ### NETWORK FOR SENDING TRAFFIC + port_3: + type: OS::Neutron::Port + properties: + network: { get_param: destination_net } + binding:vnic_type: #vnic_type + fixed_ips: + - subnet: { get_param: destination_subnet } + + flavor: + type: OS::Nova::Flavor + properties: + disk: 20 + ram: #ram + vcpus: #vcpus + #extra_specs: { node: { get_param: node }, "hw:cpu_policy": "#core_pinning_enabled", "hw:cpu_threads_policy": "#core_pinning_mode", "hw:mem_page_size": "#hugepages" } + extra_specs: { node: { get_param: node } } + + server: + type: OS::Nova::Server + properties: + name: vTC + key_name: test + image: ubuntu1404 + user_data: + str_replace: + template: | + #!/bin/sh + + # Creation of a user + NAME=$name + echo "Creating custom user..." + useradd clouduser -g admin -s /bin/bash -m + echo clouduser:secrete | chpasswd + echo "Enabling ssh password login..." + sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config + service ssh restart + sleep 1 + + # wake up interfaces + ifconfig eth1 up + ifconfig eth2 up + dhclient eth1 + dhclient eth2 + + sed -i 's/localhost/localhost vtc/g' /etc/hosts + ip route del 0/0 + route add default gw 192.168.200.1 + + AA=$(netstat -ie | grep -B1 $IP_FAMILY | awk '{ print $1 }') + BB=$(echo $AA | awk '{ print $1 }') + + # Setup Instrumentation Agent + rm -rf cimmaron + mkdir cimmaron + cd cimmaron + apt-get install -y zip + wget http://10.2.1.65/~iolie/merlin/MerlinAgent-12-06-2015-TNovaVM-001.zip + unzip MerlinAgent-12-06-2015-TNovaVM-001.zip + ./updateConfiguration.py ./instrumentation.cfg tags source=tnova_vm + ./updateConfiguration.py ./instrumentation.cfg tags role="$NAME" + nohup ./Agent.py ./instrumentation.cfg >log.out 2>&1 & + cd .. + + # Setup for PF_RING and bridge between interfaces + apt-get update + apt-get install -y git build-essential gcc libnuma-dev flex byacc libjson0-dev dh-autoreconf libpcap-dev libpulse-dev libtool pkg-config + + # Setup multicast + echo smcroute -d mgroup from $BB group 224.192.16.1 > /etc/smcroute.conf + cd /home/clouduser/ + git clone https://github.com/troglobit/smcroute.git + cd smcroute + sed -i 's/aclocal-1.11/aclocal/g' ./autogen.sh + sed -i 's/automake-1.11/automake/g' ./autogen.sh + ./autogen.sh + ./configure + make + make install + cd .. + touch multicast.sh + echo "#!/bin/bash" > multicast.sh + echo "while [ true ]" >> multicast.sh + echo "do" >> multicast.sh + echo " smcroute -k" >> multicast.sh + echo " smcroute -d" >> multicast.sh + echo " sleep 50" >> multicast.sh + echo "done" >> multicast.sh + chmod +x multicast.sh + ./multicast.sh & + + # Setup for PF_RING and bridge between interfaces + # Akis Repository + #git clone https://akiskourtis:ptindpi@bitbucket.org/akiskourtis/vtc.git + #cd vtc + #git checkout stable + + # Intel Repository + git clone http://vincenzox.m.riccobene%40intel.com:vincenzo@134.191.243.6:8081/t-nova/vtc_master.git + cd vtc_master + + cd nDPI + NDPI_DIR=$(pwd) + echo $NDPI_DIR + NDPI_INCLUDE=$(pwd)/src/include + echo $NDPI_INCLUDE + ./autogen.sh + ./configure + make + make install + cd .. + cd PF_RING + make + cd userland/examples/ + sed -i 's/EXTRA_LIBS =/EXTRA_LIBS = '"${NDPI_DIR}"'/src/lib/.libs/libndpi.a -ljson-c/g' ./Makefile + sed -i 's/ -Ithird-party/ -Ithird-party -I'"$NDPI_INCLUDE"' -I'"$NDPI_DIR"'/g' ./Makefile + make + cd ../.. + cd .. + cd .. + #insmod ./vtc/PF_RING/kernel/pf_ring.ko min_num_slots=8192 enable_debug=1 quick_mode=1 enable_tx_capture=0 + #./vtc/PF_RING/userland/examples/pfbridge -a eth1 -b eth2 & + insmod ./vtc_master/PF_RING/kernel/pf_ring.ko min_num_slots=8192 enable_debug=1 quick_mode=1 enable_tx_capture=0 + ./vtc_master/PF_RING/userland/examples/pfbridge -a eth1 -b eth2 & + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + wc_notify: { get_attr: ['wait_handle', 'curl_cli'] } + $name: { get_param: name } + $IP_FAMILY: { get_param: ip_family } + + flavor: { get_resource: flavor } + networks: + - port: { get_resource: port_1 } + - port: { get_resource: port_2 } + - port: { get_resource: port_3 } +outputs:
\ No newline at end of file diff --git a/yardstick/vTC/apexlake/tests/data/generated_templates/VTC_base_single_vm_wait_1.yaml b/yardstick/vTC/apexlake/tests/data/generated_templates/VTC_base_single_vm_wait_1.yaml new file mode 100644 index 000000000..5788980b0 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/generated_templates/VTC_base_single_vm_wait_1.yaml @@ -0,0 +1,199 @@ +heat_template_version: 2014-10-16 +description: HOT template to create a DPI + +parameters: + default_net: + type: string + default_subnet: + type: string + source_net: + type: string + source_subnet: + type: string + destination_net: + type: string + destination_subnet: + type: string + internal_net: + type: string + internal_subnet: + type: string + node: + type: string + default: compB + name: + type: string + default: vtc + ip_family: + type: string + timeout: + type: number + description: Timeout for WaitCondition, depends on your image and environment + default: 1000 + +resources: + wait_condition: + type: OS::Heat::WaitCondition + properties: + handle: {get_resource: wait_handle} + count: 1 + timeout: {get_param: timeout} + + wait_handle: + type: OS::Heat::WaitConditionHandle + + + ### DEFAULT NETWORK FOR MERLIN DATA + port_1: + type: OS::Neutron::Port + properties: + network: { get_param: default_net } + binding:vnic_type: normal + fixed_ips: + - subnet: { get_param: default_subnet } + + ### NETWORK FOR RECEIVING TRAFFIC + port_2: + type: OS::Neutron::Port + properties: + network: { get_param: source_net } + binding:vnic_type: normal + fixed_ips: + - subnet: { get_param: source_subnet } + + ### NETWORK FOR SENDING TRAFFIC + port_3: + type: OS::Neutron::Port + properties: + network: { get_param: destination_net } + binding:vnic_type: normal + fixed_ips: + - subnet: { get_param: destination_subnet } + + flavor: + type: OS::Nova::Flavor + properties: + disk: 20 + ram: 1024 + vcpus: 2 + #extra_specs: { node: { get_param: node }, "hw:cpu_policy": "#core_pinning_enabled", "hw:cpu_threads_policy": "#core_pinning_mode", "hw:mem_page_size": "#hugepages" } + extra_specs: { node: { get_param: node } } + + server: + type: OS::Nova::Server + properties: + name: vTC + key_name: test + image: ubuntu1404 + user_data: + str_replace: + template: | + #!/bin/sh + + # Creation of a user + NAME=$name + echo "Creating custom user..." + useradd clouduser -g admin -s /bin/bash -m + echo clouduser:secrete | chpasswd + echo "Enabling ssh password login..." + sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config + service ssh restart + sleep 1 + + # wake up interfaces + ifconfig eth1 up + ifconfig eth2 up + dhclient eth1 + dhclient eth2 + + sed -i 's/localhost/localhost vtc/g' /etc/hosts + ip route del 0/0 + route add default gw 192.168.200.1 + + AA=$(netstat -ie | grep -B1 $IP_FAMILY | awk '{ print $1 }') + BB=$(echo $AA | awk '{ print $1 }') + + # Setup Instrumentation Agent + rm -rf cimmaron + mkdir cimmaron + cd cimmaron + apt-get install -y zip + wget http://10.2.1.65/~iolie/merlin/MerlinAgent-12-06-2015-TNovaVM-001.zip + unzip MerlinAgent-12-06-2015-TNovaVM-001.zip + ./updateConfiguration.py ./instrumentation.cfg tags source=tnova_vm + ./updateConfiguration.py ./instrumentation.cfg tags role="$NAME" + nohup ./Agent.py ./instrumentation.cfg >log.out 2>&1 & + cd .. + + # Setup for PF_RING and bridge between interfaces + apt-get update + apt-get install -y git build-essential gcc libnuma-dev flex byacc libjson0-dev dh-autoreconf libpcap-dev libpulse-dev libtool pkg-config + + # Setup multicast + echo smcroute -d mgroup from $BB group 224.192.16.1 > /etc/smcroute.conf + cd /home/clouduser/ + git clone https://github.com/troglobit/smcroute.git + cd smcroute + sed -i 's/aclocal-1.11/aclocal/g' ./autogen.sh + sed -i 's/automake-1.11/automake/g' ./autogen.sh + ./autogen.sh + ./configure + make + make install + cd .. + touch multicast.sh + echo "#!/bin/bash" > multicast.sh + echo "while [ true ]" >> multicast.sh + echo "do" >> multicast.sh + echo " smcroute -k" >> multicast.sh + echo " smcroute -d" >> multicast.sh + echo " sleep 50" >> multicast.sh + echo "done" >> multicast.sh + chmod +x multicast.sh + ./multicast.sh & + + # Setup for PF_RING and bridge between interfaces + # Akis Repository + #git clone https://akiskourtis:ptindpi@bitbucket.org/akiskourtis/vtc.git + #cd vtc + #git checkout stable + + # Intel Repository + git clone http://vincenzox.m.riccobene%40intel.com:vincenzo@134.191.243.6:8081/t-nova/vtc_master.git + cd vtc_master + + cd nDPI + NDPI_DIR=$(pwd) + echo $NDPI_DIR + NDPI_INCLUDE=$(pwd)/src/include + echo $NDPI_INCLUDE + ./autogen.sh + ./configure + make + make install + cd .. + cd PF_RING + make + cd userland/examples/ + sed -i 's/EXTRA_LIBS =/EXTRA_LIBS = '"${NDPI_DIR}"'/src/lib/.libs/libndpi.a -ljson-c/g' ./Makefile + sed -i 's/ -Ithird-party/ -Ithird-party -I'"$NDPI_INCLUDE"' -I'"$NDPI_DIR"'/g' ./Makefile + make + cd ../.. + cd .. + cd .. + #insmod ./vtc/PF_RING/kernel/pf_ring.ko min_num_slots=8192 enable_debug=1 quick_mode=1 enable_tx_capture=0 + #./vtc/PF_RING/userland/examples/pfbridge -a eth1 -b eth2 & + insmod ./vtc_master/PF_RING/kernel/pf_ring.ko min_num_slots=8192 enable_debug=1 quick_mode=1 enable_tx_capture=0 + ./vtc_master/PF_RING/userland/examples/pfbridge -a eth1 -b eth2 & + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + wc_notify: { get_attr: ['wait_handle', 'curl_cli'] } + $name: { get_param: name } + $IP_FAMILY: { get_param: ip_family } + + flavor: { get_resource: flavor } + networks: + - port: { get_resource: port_1 } + - port: { get_resource: port_2 } + - port: { get_resource: port_3 } +outputs: diff --git a/yardstick/vTC/apexlake/tests/data/generated_templates/VTC_base_single_vm_wait_1.yaml.json b/yardstick/vTC/apexlake/tests/data/generated_templates/VTC_base_single_vm_wait_1.yaml.json new file mode 100644 index 000000000..3af9a1cc7 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/generated_templates/VTC_base_single_vm_wait_1.yaml.json @@ -0,0 +1 @@ +{"vnic_type": "normal", "ram": "1024", "vcpus": "2"}
\ No newline at end of file diff --git a/yardstick/vTC/apexlake/tests/data/generated_templates/VTC_base_single_vm_wait_2.yaml b/yardstick/vTC/apexlake/tests/data/generated_templates/VTC_base_single_vm_wait_2.yaml new file mode 100644 index 000000000..44a81d081 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/generated_templates/VTC_base_single_vm_wait_2.yaml @@ -0,0 +1,199 @@ +heat_template_version: 2014-10-16 +description: HOT template to create a DPI + +parameters: + default_net: + type: string + default_subnet: + type: string + source_net: + type: string + source_subnet: + type: string + destination_net: + type: string + destination_subnet: + type: string + internal_net: + type: string + internal_subnet: + type: string + node: + type: string + default: compB + name: + type: string + default: vtc + ip_family: + type: string + timeout: + type: number + description: Timeout for WaitCondition, depends on your image and environment + default: 1000 + +resources: + wait_condition: + type: OS::Heat::WaitCondition + properties: + handle: {get_resource: wait_handle} + count: 1 + timeout: {get_param: timeout} + + wait_handle: + type: OS::Heat::WaitConditionHandle + + + ### DEFAULT NETWORK FOR MERLIN DATA + port_1: + type: OS::Neutron::Port + properties: + network: { get_param: default_net } + binding:vnic_type: normal + fixed_ips: + - subnet: { get_param: default_subnet } + + ### NETWORK FOR RECEIVING TRAFFIC + port_2: + type: OS::Neutron::Port + properties: + network: { get_param: source_net } + binding:vnic_type: direct + fixed_ips: + - subnet: { get_param: source_subnet } + + ### NETWORK FOR SENDING TRAFFIC + port_3: + type: OS::Neutron::Port + properties: + network: { get_param: destination_net } + binding:vnic_type: direct + fixed_ips: + - subnet: { get_param: destination_subnet } + + flavor: + type: OS::Nova::Flavor + properties: + disk: 20 + ram: 1024 + vcpus: 2 + #extra_specs: { node: { get_param: node }, "hw:cpu_policy": "#core_pinning_enabled", "hw:cpu_threads_policy": "#core_pinning_mode", "hw:mem_page_size": "#hugepages" } + extra_specs: { node: { get_param: node } } + + server: + type: OS::Nova::Server + properties: + name: vTC + key_name: test + image: ubuntu1404 + user_data: + str_replace: + template: | + #!/bin/sh + + # Creation of a user + NAME=$name + echo "Creating custom user..." + useradd clouduser -g admin -s /bin/bash -m + echo clouduser:secrete | chpasswd + echo "Enabling ssh password login..." + sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config + service ssh restart + sleep 1 + + # wake up interfaces + ifconfig eth1 up + ifconfig eth2 up + dhclient eth1 + dhclient eth2 + + sed -i 's/localhost/localhost vtc/g' /etc/hosts + ip route del 0/0 + route add default gw 192.168.200.1 + + AA=$(netstat -ie | grep -B1 $IP_FAMILY | awk '{ print $1 }') + BB=$(echo $AA | awk '{ print $1 }') + + # Setup Instrumentation Agent + rm -rf cimmaron + mkdir cimmaron + cd cimmaron + apt-get install -y zip + wget http://10.2.1.65/~iolie/merlin/MerlinAgent-12-06-2015-TNovaVM-001.zip + unzip MerlinAgent-12-06-2015-TNovaVM-001.zip + ./updateConfiguration.py ./instrumentation.cfg tags source=tnova_vm + ./updateConfiguration.py ./instrumentation.cfg tags role="$NAME" + nohup ./Agent.py ./instrumentation.cfg >log.out 2>&1 & + cd .. + + # Setup for PF_RING and bridge between interfaces + apt-get update + apt-get install -y git build-essential gcc libnuma-dev flex byacc libjson0-dev dh-autoreconf libpcap-dev libpulse-dev libtool pkg-config + + # Setup multicast + echo smcroute -d mgroup from $BB group 224.192.16.1 > /etc/smcroute.conf + cd /home/clouduser/ + git clone https://github.com/troglobit/smcroute.git + cd smcroute + sed -i 's/aclocal-1.11/aclocal/g' ./autogen.sh + sed -i 's/automake-1.11/automake/g' ./autogen.sh + ./autogen.sh + ./configure + make + make install + cd .. + touch multicast.sh + echo "#!/bin/bash" > multicast.sh + echo "while [ true ]" >> multicast.sh + echo "do" >> multicast.sh + echo " smcroute -k" >> multicast.sh + echo " smcroute -d" >> multicast.sh + echo " sleep 50" >> multicast.sh + echo "done" >> multicast.sh + chmod +x multicast.sh + ./multicast.sh & + + # Setup for PF_RING and bridge between interfaces + # Akis Repository + #git clone https://akiskourtis:ptindpi@bitbucket.org/akiskourtis/vtc.git + #cd vtc + #git checkout stable + + # Intel Repository + git clone http://vincenzox.m.riccobene%40intel.com:vincenzo@134.191.243.6:8081/t-nova/vtc_master.git + cd vtc_master + + cd nDPI + NDPI_DIR=$(pwd) + echo $NDPI_DIR + NDPI_INCLUDE=$(pwd)/src/include + echo $NDPI_INCLUDE + ./autogen.sh + ./configure + make + make install + cd .. + cd PF_RING + make + cd userland/examples/ + sed -i 's/EXTRA_LIBS =/EXTRA_LIBS = '"${NDPI_DIR}"'/src/lib/.libs/libndpi.a -ljson-c/g' ./Makefile + sed -i 's/ -Ithird-party/ -Ithird-party -I'"$NDPI_INCLUDE"' -I'"$NDPI_DIR"'/g' ./Makefile + make + cd ../.. + cd .. + cd .. + #insmod ./vtc/PF_RING/kernel/pf_ring.ko min_num_slots=8192 enable_debug=1 quick_mode=1 enable_tx_capture=0 + #./vtc/PF_RING/userland/examples/pfbridge -a eth1 -b eth2 & + insmod ./vtc_master/PF_RING/kernel/pf_ring.ko min_num_slots=8192 enable_debug=1 quick_mode=1 enable_tx_capture=0 + ./vtc_master/PF_RING/userland/examples/pfbridge -a eth1 -b eth2 & + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + wc_notify: { get_attr: ['wait_handle', 'curl_cli'] } + $name: { get_param: name } + $IP_FAMILY: { get_param: ip_family } + + flavor: { get_resource: flavor } + networks: + - port: { get_resource: port_1 } + - port: { get_resource: port_2 } + - port: { get_resource: port_3 } +outputs: diff --git a/yardstick/vTC/apexlake/tests/data/generated_templates/VTC_base_single_vm_wait_2.yaml.json b/yardstick/vTC/apexlake/tests/data/generated_templates/VTC_base_single_vm_wait_2.yaml.json new file mode 100644 index 000000000..9f246891d --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/generated_templates/VTC_base_single_vm_wait_2.yaml.json @@ -0,0 +1 @@ +{"vnic_type": "direct", "ram": "1024", "vcpus": "2"}
\ No newline at end of file diff --git a/yardstick/vTC/apexlake/tests/data/generated_templates/experiment_1.yaml b/yardstick/vTC/apexlake/tests/data/generated_templates/experiment_1.yaml new file mode 100644 index 000000000..5788980b0 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/generated_templates/experiment_1.yaml @@ -0,0 +1,199 @@ +heat_template_version: 2014-10-16 +description: HOT template to create a DPI + +parameters: + default_net: + type: string + default_subnet: + type: string + source_net: + type: string + source_subnet: + type: string + destination_net: + type: string + destination_subnet: + type: string + internal_net: + type: string + internal_subnet: + type: string + node: + type: string + default: compB + name: + type: string + default: vtc + ip_family: + type: string + timeout: + type: number + description: Timeout for WaitCondition, depends on your image and environment + default: 1000 + +resources: + wait_condition: + type: OS::Heat::WaitCondition + properties: + handle: {get_resource: wait_handle} + count: 1 + timeout: {get_param: timeout} + + wait_handle: + type: OS::Heat::WaitConditionHandle + + + ### DEFAULT NETWORK FOR MERLIN DATA + port_1: + type: OS::Neutron::Port + properties: + network: { get_param: default_net } + binding:vnic_type: normal + fixed_ips: + - subnet: { get_param: default_subnet } + + ### NETWORK FOR RECEIVING TRAFFIC + port_2: + type: OS::Neutron::Port + properties: + network: { get_param: source_net } + binding:vnic_type: normal + fixed_ips: + - subnet: { get_param: source_subnet } + + ### NETWORK FOR SENDING TRAFFIC + port_3: + type: OS::Neutron::Port + properties: + network: { get_param: destination_net } + binding:vnic_type: normal + fixed_ips: + - subnet: { get_param: destination_subnet } + + flavor: + type: OS::Nova::Flavor + properties: + disk: 20 + ram: 1024 + vcpus: 2 + #extra_specs: { node: { get_param: node }, "hw:cpu_policy": "#core_pinning_enabled", "hw:cpu_threads_policy": "#core_pinning_mode", "hw:mem_page_size": "#hugepages" } + extra_specs: { node: { get_param: node } } + + server: + type: OS::Nova::Server + properties: + name: vTC + key_name: test + image: ubuntu1404 + user_data: + str_replace: + template: | + #!/bin/sh + + # Creation of a user + NAME=$name + echo "Creating custom user..." + useradd clouduser -g admin -s /bin/bash -m + echo clouduser:secrete | chpasswd + echo "Enabling ssh password login..." + sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config + service ssh restart + sleep 1 + + # wake up interfaces + ifconfig eth1 up + ifconfig eth2 up + dhclient eth1 + dhclient eth2 + + sed -i 's/localhost/localhost vtc/g' /etc/hosts + ip route del 0/0 + route add default gw 192.168.200.1 + + AA=$(netstat -ie | grep -B1 $IP_FAMILY | awk '{ print $1 }') + BB=$(echo $AA | awk '{ print $1 }') + + # Setup Instrumentation Agent + rm -rf cimmaron + mkdir cimmaron + cd cimmaron + apt-get install -y zip + wget http://10.2.1.65/~iolie/merlin/MerlinAgent-12-06-2015-TNovaVM-001.zip + unzip MerlinAgent-12-06-2015-TNovaVM-001.zip + ./updateConfiguration.py ./instrumentation.cfg tags source=tnova_vm + ./updateConfiguration.py ./instrumentation.cfg tags role="$NAME" + nohup ./Agent.py ./instrumentation.cfg >log.out 2>&1 & + cd .. + + # Setup for PF_RING and bridge between interfaces + apt-get update + apt-get install -y git build-essential gcc libnuma-dev flex byacc libjson0-dev dh-autoreconf libpcap-dev libpulse-dev libtool pkg-config + + # Setup multicast + echo smcroute -d mgroup from $BB group 224.192.16.1 > /etc/smcroute.conf + cd /home/clouduser/ + git clone https://github.com/troglobit/smcroute.git + cd smcroute + sed -i 's/aclocal-1.11/aclocal/g' ./autogen.sh + sed -i 's/automake-1.11/automake/g' ./autogen.sh + ./autogen.sh + ./configure + make + make install + cd .. + touch multicast.sh + echo "#!/bin/bash" > multicast.sh + echo "while [ true ]" >> multicast.sh + echo "do" >> multicast.sh + echo " smcroute -k" >> multicast.sh + echo " smcroute -d" >> multicast.sh + echo " sleep 50" >> multicast.sh + echo "done" >> multicast.sh + chmod +x multicast.sh + ./multicast.sh & + + # Setup for PF_RING and bridge between interfaces + # Akis Repository + #git clone https://akiskourtis:ptindpi@bitbucket.org/akiskourtis/vtc.git + #cd vtc + #git checkout stable + + # Intel Repository + git clone http://vincenzox.m.riccobene%40intel.com:vincenzo@134.191.243.6:8081/t-nova/vtc_master.git + cd vtc_master + + cd nDPI + NDPI_DIR=$(pwd) + echo $NDPI_DIR + NDPI_INCLUDE=$(pwd)/src/include + echo $NDPI_INCLUDE + ./autogen.sh + ./configure + make + make install + cd .. + cd PF_RING + make + cd userland/examples/ + sed -i 's/EXTRA_LIBS =/EXTRA_LIBS = '"${NDPI_DIR}"'/src/lib/.libs/libndpi.a -ljson-c/g' ./Makefile + sed -i 's/ -Ithird-party/ -Ithird-party -I'"$NDPI_INCLUDE"' -I'"$NDPI_DIR"'/g' ./Makefile + make + cd ../.. + cd .. + cd .. + #insmod ./vtc/PF_RING/kernel/pf_ring.ko min_num_slots=8192 enable_debug=1 quick_mode=1 enable_tx_capture=0 + #./vtc/PF_RING/userland/examples/pfbridge -a eth1 -b eth2 & + insmod ./vtc_master/PF_RING/kernel/pf_ring.ko min_num_slots=8192 enable_debug=1 quick_mode=1 enable_tx_capture=0 + ./vtc_master/PF_RING/userland/examples/pfbridge -a eth1 -b eth2 & + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + wc_notify: { get_attr: ['wait_handle', 'curl_cli'] } + $name: { get_param: name } + $IP_FAMILY: { get_param: ip_family } + + flavor: { get_resource: flavor } + networks: + - port: { get_resource: port_1 } + - port: { get_resource: port_2 } + - port: { get_resource: port_3 } +outputs: diff --git a/yardstick/vTC/apexlake/tests/data/generated_templates/experiment_1.yaml.json b/yardstick/vTC/apexlake/tests/data/generated_templates/experiment_1.yaml.json new file mode 100644 index 000000000..3af9a1cc7 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/generated_templates/experiment_1.yaml.json @@ -0,0 +1 @@ +{"vnic_type": "normal", "ram": "1024", "vcpus": "2"}
\ No newline at end of file diff --git a/yardstick/vTC/apexlake/tests/data/generated_templates/experiment_2.yaml b/yardstick/vTC/apexlake/tests/data/generated_templates/experiment_2.yaml new file mode 100644 index 000000000..44a81d081 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/generated_templates/experiment_2.yaml @@ -0,0 +1,199 @@ +heat_template_version: 2014-10-16 +description: HOT template to create a DPI + +parameters: + default_net: + type: string + default_subnet: + type: string + source_net: + type: string + source_subnet: + type: string + destination_net: + type: string + destination_subnet: + type: string + internal_net: + type: string + internal_subnet: + type: string + node: + type: string + default: compB + name: + type: string + default: vtc + ip_family: + type: string + timeout: + type: number + description: Timeout for WaitCondition, depends on your image and environment + default: 1000 + +resources: + wait_condition: + type: OS::Heat::WaitCondition + properties: + handle: {get_resource: wait_handle} + count: 1 + timeout: {get_param: timeout} + + wait_handle: + type: OS::Heat::WaitConditionHandle + + + ### DEFAULT NETWORK FOR MERLIN DATA + port_1: + type: OS::Neutron::Port + properties: + network: { get_param: default_net } + binding:vnic_type: normal + fixed_ips: + - subnet: { get_param: default_subnet } + + ### NETWORK FOR RECEIVING TRAFFIC + port_2: + type: OS::Neutron::Port + properties: + network: { get_param: source_net } + binding:vnic_type: direct + fixed_ips: + - subnet: { get_param: source_subnet } + + ### NETWORK FOR SENDING TRAFFIC + port_3: + type: OS::Neutron::Port + properties: + network: { get_param: destination_net } + binding:vnic_type: direct + fixed_ips: + - subnet: { get_param: destination_subnet } + + flavor: + type: OS::Nova::Flavor + properties: + disk: 20 + ram: 1024 + vcpus: 2 + #extra_specs: { node: { get_param: node }, "hw:cpu_policy": "#core_pinning_enabled", "hw:cpu_threads_policy": "#core_pinning_mode", "hw:mem_page_size": "#hugepages" } + extra_specs: { node: { get_param: node } } + + server: + type: OS::Nova::Server + properties: + name: vTC + key_name: test + image: ubuntu1404 + user_data: + str_replace: + template: | + #!/bin/sh + + # Creation of a user + NAME=$name + echo "Creating custom user..." + useradd clouduser -g admin -s /bin/bash -m + echo clouduser:secrete | chpasswd + echo "Enabling ssh password login..." + sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config + service ssh restart + sleep 1 + + # wake up interfaces + ifconfig eth1 up + ifconfig eth2 up + dhclient eth1 + dhclient eth2 + + sed -i 's/localhost/localhost vtc/g' /etc/hosts + ip route del 0/0 + route add default gw 192.168.200.1 + + AA=$(netstat -ie | grep -B1 $IP_FAMILY | awk '{ print $1 }') + BB=$(echo $AA | awk '{ print $1 }') + + # Setup Instrumentation Agent + rm -rf cimmaron + mkdir cimmaron + cd cimmaron + apt-get install -y zip + wget http://10.2.1.65/~iolie/merlin/MerlinAgent-12-06-2015-TNovaVM-001.zip + unzip MerlinAgent-12-06-2015-TNovaVM-001.zip + ./updateConfiguration.py ./instrumentation.cfg tags source=tnova_vm + ./updateConfiguration.py ./instrumentation.cfg tags role="$NAME" + nohup ./Agent.py ./instrumentation.cfg >log.out 2>&1 & + cd .. + + # Setup for PF_RING and bridge between interfaces + apt-get update + apt-get install -y git build-essential gcc libnuma-dev flex byacc libjson0-dev dh-autoreconf libpcap-dev libpulse-dev libtool pkg-config + + # Setup multicast + echo smcroute -d mgroup from $BB group 224.192.16.1 > /etc/smcroute.conf + cd /home/clouduser/ + git clone https://github.com/troglobit/smcroute.git + cd smcroute + sed -i 's/aclocal-1.11/aclocal/g' ./autogen.sh + sed -i 's/automake-1.11/automake/g' ./autogen.sh + ./autogen.sh + ./configure + make + make install + cd .. + touch multicast.sh + echo "#!/bin/bash" > multicast.sh + echo "while [ true ]" >> multicast.sh + echo "do" >> multicast.sh + echo " smcroute -k" >> multicast.sh + echo " smcroute -d" >> multicast.sh + echo " sleep 50" >> multicast.sh + echo "done" >> multicast.sh + chmod +x multicast.sh + ./multicast.sh & + + # Setup for PF_RING and bridge between interfaces + # Akis Repository + #git clone https://akiskourtis:ptindpi@bitbucket.org/akiskourtis/vtc.git + #cd vtc + #git checkout stable + + # Intel Repository + git clone http://vincenzox.m.riccobene%40intel.com:vincenzo@134.191.243.6:8081/t-nova/vtc_master.git + cd vtc_master + + cd nDPI + NDPI_DIR=$(pwd) + echo $NDPI_DIR + NDPI_INCLUDE=$(pwd)/src/include + echo $NDPI_INCLUDE + ./autogen.sh + ./configure + make + make install + cd .. + cd PF_RING + make + cd userland/examples/ + sed -i 's/EXTRA_LIBS =/EXTRA_LIBS = '"${NDPI_DIR}"'/src/lib/.libs/libndpi.a -ljson-c/g' ./Makefile + sed -i 's/ -Ithird-party/ -Ithird-party -I'"$NDPI_INCLUDE"' -I'"$NDPI_DIR"'/g' ./Makefile + make + cd ../.. + cd .. + cd .. + #insmod ./vtc/PF_RING/kernel/pf_ring.ko min_num_slots=8192 enable_debug=1 quick_mode=1 enable_tx_capture=0 + #./vtc/PF_RING/userland/examples/pfbridge -a eth1 -b eth2 & + insmod ./vtc_master/PF_RING/kernel/pf_ring.ko min_num_slots=8192 enable_debug=1 quick_mode=1 enable_tx_capture=0 + ./vtc_master/PF_RING/userland/examples/pfbridge -a eth1 -b eth2 & + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + wc_notify: { get_attr: ['wait_handle', 'curl_cli'] } + $name: { get_param: name } + $IP_FAMILY: { get_param: ip_family } + + flavor: { get_resource: flavor } + networks: + - port: { get_resource: port_1 } + - port: { get_resource: port_2 } + - port: { get_resource: port_3 } +outputs: diff --git a/yardstick/vTC/apexlake/tests/data/generated_templates/experiment_2.yaml.json b/yardstick/vTC/apexlake/tests/data/generated_templates/experiment_2.yaml.json new file mode 100644 index 000000000..9f246891d --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/generated_templates/experiment_2.yaml.json @@ -0,0 +1 @@ +{"vnic_type": "direct", "ram": "1024", "vcpus": "2"}
\ No newline at end of file diff --git a/yardstick/vTC/apexlake/tests/data/test_experiments/experiment_1/benchmark_1.csv b/yardstick/vTC/apexlake/tests/data/test_experiments/experiment_1/benchmark_1.csv new file mode 100644 index 000000000..f5f2932d0 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/test_experiments/experiment_1/benchmark_1.csv @@ -0,0 +1,3 @@ +conf_1;conf_3;conf_2;point_4;point_5;point_6;point_1;point_2;point_3
+conf_value_1;conf_value_3;conf_value_2;?;?;?;value_1;value_2;value_3
+conf_value_1;conf_value_3;conf_value_2;value_4;value_5;value_6;?;?;?
diff --git a/yardstick/vTC/apexlake/tests/data/test_experiments/experiment_1/metadata.json b/yardstick/vTC/apexlake/tests/data/test_experiments/experiment_1/metadata.json new file mode 100644 index 000000000..ff4cebf41 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/test_experiments/experiment_1/metadata.json @@ -0,0 +1 @@ +{"location": "tests/data/experiments/experiment_1/metadata.json", "item_2": "value_2", "item_3": "value_3", "item_1": "value_1"}
\ No newline at end of file diff --git a/yardstick/vTC/apexlake/tests/data/test_experiments/results_benchmark_1.csv b/yardstick/vTC/apexlake/tests/data/test_experiments/results_benchmark_1.csv new file mode 100644 index 000000000..4662dd2be --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/test_experiments/results_benchmark_1.csv @@ -0,0 +1,5 @@ +conf_5;conf_4;conf_6;conf_1;conf_3;conf_2;point_12;point_10;point_11;point_4;point_5;point_6;point_8;point_9;point_7;point_1;point_2;point_3
+?;?;?;conf_value_1;conf_value_3;conf_value_2;?;?;?;?;?;?;?;?;?;value_1;value_2;value_3
+?;?;?;conf_value_1;conf_value_3;conf_value_2;?;?;?;value_4;value_5;value_6;?;?;?;?;?;?
+conf_value_5;conf_value_4;conf_value_6;?;?;?;?;?;?;?;?;?;value_8;value_9;value_7;?;?;?
+conf_value_5;conf_value_4;conf_value_6;?;?;?;value_12;value_10;value_11;?;?;?;?;?;?;?;?;?
diff --git a/yardstick/vTC/apexlake/tests/data/test_templates/VTC_base_single_vm_wait.tmp b/yardstick/vTC/apexlake/tests/data/test_templates/VTC_base_single_vm_wait.tmp new file mode 100644 index 000000000..aa3959fc1 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/test_templates/VTC_base_single_vm_wait.tmp @@ -0,0 +1,199 @@ +heat_template_version: 2014-10-16 +description: HOT template to create a DPI + +parameters: + default_net: + type: string + default_subnet: + type: string + source_net: + type: string + source_subnet: + type: string + destination_net: + type: string + destination_subnet: + type: string + internal_net: + type: string + internal_subnet: + type: string + node: + type: string + default: compB + name: + type: string + default: vtc + ip_family: + type: string + timeout: + type: number + description: Timeout for WaitCondition, depends on your image and environment + default: 1000 + +resources: + wait_condition: + type: OS::Heat::WaitCondition + properties: + handle: {get_resource: wait_handle} + count: 1 + timeout: {get_param: timeout} + + wait_handle: + type: OS::Heat::WaitConditionHandle + + + ### DEFAULT NETWORK FOR MERLIN DATA + port_1: + type: OS::Neutron::Port + properties: + network: { get_param: default_net } + binding:vnic_type: normal + fixed_ips: + - subnet: { get_param: default_subnet } + + ### NETWORK FOR RECEIVING TRAFFIC + port_2: + type: OS::Neutron::Port + properties: + network: { get_param: source_net } + binding:vnic_type: #vnic_type + fixed_ips: + - subnet: { get_param: source_subnet } + + ### NETWORK FOR SENDING TRAFFIC + port_3: + type: OS::Neutron::Port + properties: + network: { get_param: destination_net } + binding:vnic_type: #vnic_type + fixed_ips: + - subnet: { get_param: destination_subnet } + + flavor: + type: OS::Nova::Flavor + properties: + disk: 20 + ram: #ram + vcpus: #vcpus + #extra_specs: { node: { get_param: node }, "hw:cpu_policy": "#core_pinning_enabled", "hw:cpu_threads_policy": "#core_pinning_mode", "hw:mem_page_size": "#hugepages" } + extra_specs: { node: { get_param: node } } + + server: + type: OS::Nova::Server + properties: + name: vTC + key_name: test + image: ubuntu1404 + user_data: + str_replace: + template: | + #!/bin/sh + + # Creation of a user + NAME=$name + echo "Creating custom user..." + useradd clouduser -g admin -s /bin/bash -m + echo clouduser:secrete | chpasswd + echo "Enabling ssh password login..." + sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config + service ssh restart + sleep 1 + + # wake up interfaces + ifconfig eth1 up + ifconfig eth2 up + dhclient eth1 + dhclient eth2 + + sed -i 's/localhost/localhost vtc/g' /etc/hosts + ip route del 0/0 + route add default gw 192.168.200.1 + + AA=$(netstat -ie | grep -B1 $IP_FAMILY | awk '{ print $1 }') + BB=$(echo $AA | awk '{ print $1 }') + + # Setup Instrumentation Agent + rm -rf cimmaron + mkdir cimmaron + cd cimmaron + apt-get install -y zip + wget http://10.2.1.65/~iolie/merlin/MerlinAgent-12-06-2015-TNovaVM-001.zip + unzip MerlinAgent-12-06-2015-TNovaVM-001.zip + ./updateConfiguration.py ./instrumentation.cfg tags source=tnova_vm + ./updateConfiguration.py ./instrumentation.cfg tags role="$NAME" + nohup ./Agent.py ./instrumentation.cfg >log.out 2>&1 & + cd .. + + # Setup for PF_RING and bridge between interfaces + apt-get update + apt-get install -y git build-essential gcc libnuma-dev flex byacc libjson0-dev dh-autoreconf libpcap-dev libpulse-dev libtool pkg-config + + # Setup multicast + echo smcroute -d mgroup from $BB group 224.192.16.1 > /etc/smcroute.conf + cd /home/clouduser/ + git clone https://github.com/troglobit/smcroute.git + cd smcroute + sed -i 's/aclocal-1.11/aclocal/g' ./autogen.sh + sed -i 's/automake-1.11/automake/g' ./autogen.sh + ./autogen.sh + ./configure + make + make install + cd .. + touch multicast.sh + echo "#!/bin/bash" > multicast.sh + echo "while [ true ]" >> multicast.sh + echo "do" >> multicast.sh + echo " smcroute -k" >> multicast.sh + echo " smcroute -d" >> multicast.sh + echo " sleep 50" >> multicast.sh + echo "done" >> multicast.sh + chmod +x multicast.sh + ./multicast.sh & + + # Setup for PF_RING and bridge between interfaces + # Akis Repository + #git clone https://akiskourtis:ptindpi@bitbucket.org/akiskourtis/vtc.git + #cd vtc + #git checkout stable + + # Intel Repository + git clone http://vincenzox.m.riccobene%40intel.com:vincenzo@134.191.243.6:8081/t-nova/vtc_master.git + cd vtc_master + + cd nDPI + NDPI_DIR=$(pwd) + echo $NDPI_DIR + NDPI_INCLUDE=$(pwd)/src/include + echo $NDPI_INCLUDE + ./autogen.sh + ./configure + make + make install + cd .. + cd PF_RING + make + cd userland/examples/ + sed -i 's/EXTRA_LIBS =/EXTRA_LIBS = '"${NDPI_DIR}"'/src/lib/.libs/libndpi.a -ljson-c/g' ./Makefile + sed -i 's/ -Ithird-party/ -Ithird-party -I'"$NDPI_INCLUDE"' -I'"$NDPI_DIR"'/g' ./Makefile + make + cd ../.. + cd .. + cd .. + #insmod ./vtc/PF_RING/kernel/pf_ring.ko min_num_slots=8192 enable_debug=1 quick_mode=1 enable_tx_capture=0 + #./vtc/PF_RING/userland/examples/pfbridge -a eth1 -b eth2 & + insmod ./vtc_master/PF_RING/kernel/pf_ring.ko min_num_slots=8192 enable_debug=1 quick_mode=1 enable_tx_capture=0 + ./vtc_master/PF_RING/userland/examples/pfbridge -a eth1 -b eth2 & + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + wc_notify: { get_attr: ['wait_handle', 'curl_cli'] } + $name: { get_param: name } + $IP_FAMILY: { get_param: ip_family } + + flavor: { get_resource: flavor } + networks: + - port: { get_resource: port_1 } + - port: { get_resource: port_2 } + - port: { get_resource: port_3 } +outputs:
\ No newline at end of file diff --git a/yardstick/vTC/apexlake/tests/data/test_templates/VTC_base_single_vm_wait_1.yaml b/yardstick/vTC/apexlake/tests/data/test_templates/VTC_base_single_vm_wait_1.yaml new file mode 100644 index 000000000..5788980b0 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/test_templates/VTC_base_single_vm_wait_1.yaml @@ -0,0 +1,199 @@ +heat_template_version: 2014-10-16 +description: HOT template to create a DPI + +parameters: + default_net: + type: string + default_subnet: + type: string + source_net: + type: string + source_subnet: + type: string + destination_net: + type: string + destination_subnet: + type: string + internal_net: + type: string + internal_subnet: + type: string + node: + type: string + default: compB + name: + type: string + default: vtc + ip_family: + type: string + timeout: + type: number + description: Timeout for WaitCondition, depends on your image and environment + default: 1000 + +resources: + wait_condition: + type: OS::Heat::WaitCondition + properties: + handle: {get_resource: wait_handle} + count: 1 + timeout: {get_param: timeout} + + wait_handle: + type: OS::Heat::WaitConditionHandle + + + ### DEFAULT NETWORK FOR MERLIN DATA + port_1: + type: OS::Neutron::Port + properties: + network: { get_param: default_net } + binding:vnic_type: normal + fixed_ips: + - subnet: { get_param: default_subnet } + + ### NETWORK FOR RECEIVING TRAFFIC + port_2: + type: OS::Neutron::Port + properties: + network: { get_param: source_net } + binding:vnic_type: normal + fixed_ips: + - subnet: { get_param: source_subnet } + + ### NETWORK FOR SENDING TRAFFIC + port_3: + type: OS::Neutron::Port + properties: + network: { get_param: destination_net } + binding:vnic_type: normal + fixed_ips: + - subnet: { get_param: destination_subnet } + + flavor: + type: OS::Nova::Flavor + properties: + disk: 20 + ram: 1024 + vcpus: 2 + #extra_specs: { node: { get_param: node }, "hw:cpu_policy": "#core_pinning_enabled", "hw:cpu_threads_policy": "#core_pinning_mode", "hw:mem_page_size": "#hugepages" } + extra_specs: { node: { get_param: node } } + + server: + type: OS::Nova::Server + properties: + name: vTC + key_name: test + image: ubuntu1404 + user_data: + str_replace: + template: | + #!/bin/sh + + # Creation of a user + NAME=$name + echo "Creating custom user..." + useradd clouduser -g admin -s /bin/bash -m + echo clouduser:secrete | chpasswd + echo "Enabling ssh password login..." + sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config + service ssh restart + sleep 1 + + # wake up interfaces + ifconfig eth1 up + ifconfig eth2 up + dhclient eth1 + dhclient eth2 + + sed -i 's/localhost/localhost vtc/g' /etc/hosts + ip route del 0/0 + route add default gw 192.168.200.1 + + AA=$(netstat -ie | grep -B1 $IP_FAMILY | awk '{ print $1 }') + BB=$(echo $AA | awk '{ print $1 }') + + # Setup Instrumentation Agent + rm -rf cimmaron + mkdir cimmaron + cd cimmaron + apt-get install -y zip + wget http://10.2.1.65/~iolie/merlin/MerlinAgent-12-06-2015-TNovaVM-001.zip + unzip MerlinAgent-12-06-2015-TNovaVM-001.zip + ./updateConfiguration.py ./instrumentation.cfg tags source=tnova_vm + ./updateConfiguration.py ./instrumentation.cfg tags role="$NAME" + nohup ./Agent.py ./instrumentation.cfg >log.out 2>&1 & + cd .. + + # Setup for PF_RING and bridge between interfaces + apt-get update + apt-get install -y git build-essential gcc libnuma-dev flex byacc libjson0-dev dh-autoreconf libpcap-dev libpulse-dev libtool pkg-config + + # Setup multicast + echo smcroute -d mgroup from $BB group 224.192.16.1 > /etc/smcroute.conf + cd /home/clouduser/ + git clone https://github.com/troglobit/smcroute.git + cd smcroute + sed -i 's/aclocal-1.11/aclocal/g' ./autogen.sh + sed -i 's/automake-1.11/automake/g' ./autogen.sh + ./autogen.sh + ./configure + make + make install + cd .. + touch multicast.sh + echo "#!/bin/bash" > multicast.sh + echo "while [ true ]" >> multicast.sh + echo "do" >> multicast.sh + echo " smcroute -k" >> multicast.sh + echo " smcroute -d" >> multicast.sh + echo " sleep 50" >> multicast.sh + echo "done" >> multicast.sh + chmod +x multicast.sh + ./multicast.sh & + + # Setup for PF_RING and bridge between interfaces + # Akis Repository + #git clone https://akiskourtis:ptindpi@bitbucket.org/akiskourtis/vtc.git + #cd vtc + #git checkout stable + + # Intel Repository + git clone http://vincenzox.m.riccobene%40intel.com:vincenzo@134.191.243.6:8081/t-nova/vtc_master.git + cd vtc_master + + cd nDPI + NDPI_DIR=$(pwd) + echo $NDPI_DIR + NDPI_INCLUDE=$(pwd)/src/include + echo $NDPI_INCLUDE + ./autogen.sh + ./configure + make + make install + cd .. + cd PF_RING + make + cd userland/examples/ + sed -i 's/EXTRA_LIBS =/EXTRA_LIBS = '"${NDPI_DIR}"'/src/lib/.libs/libndpi.a -ljson-c/g' ./Makefile + sed -i 's/ -Ithird-party/ -Ithird-party -I'"$NDPI_INCLUDE"' -I'"$NDPI_DIR"'/g' ./Makefile + make + cd ../.. + cd .. + cd .. + #insmod ./vtc/PF_RING/kernel/pf_ring.ko min_num_slots=8192 enable_debug=1 quick_mode=1 enable_tx_capture=0 + #./vtc/PF_RING/userland/examples/pfbridge -a eth1 -b eth2 & + insmod ./vtc_master/PF_RING/kernel/pf_ring.ko min_num_slots=8192 enable_debug=1 quick_mode=1 enable_tx_capture=0 + ./vtc_master/PF_RING/userland/examples/pfbridge -a eth1 -b eth2 & + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + wc_notify: { get_attr: ['wait_handle', 'curl_cli'] } + $name: { get_param: name } + $IP_FAMILY: { get_param: ip_family } + + flavor: { get_resource: flavor } + networks: + - port: { get_resource: port_1 } + - port: { get_resource: port_2 } + - port: { get_resource: port_3 } +outputs: diff --git a/yardstick/vTC/apexlake/tests/data/test_templates/VTC_base_single_vm_wait_1.yaml.json b/yardstick/vTC/apexlake/tests/data/test_templates/VTC_base_single_vm_wait_1.yaml.json new file mode 100644 index 000000000..3af9a1cc7 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/test_templates/VTC_base_single_vm_wait_1.yaml.json @@ -0,0 +1 @@ +{"vnic_type": "normal", "ram": "1024", "vcpus": "2"}
\ No newline at end of file diff --git a/yardstick/vTC/apexlake/tests/data/test_templates/VTC_base_single_vm_wait_2.yaml b/yardstick/vTC/apexlake/tests/data/test_templates/VTC_base_single_vm_wait_2.yaml new file mode 100644 index 000000000..44a81d081 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/test_templates/VTC_base_single_vm_wait_2.yaml @@ -0,0 +1,199 @@ +heat_template_version: 2014-10-16 +description: HOT template to create a DPI + +parameters: + default_net: + type: string + default_subnet: + type: string + source_net: + type: string + source_subnet: + type: string + destination_net: + type: string + destination_subnet: + type: string + internal_net: + type: string + internal_subnet: + type: string + node: + type: string + default: compB + name: + type: string + default: vtc + ip_family: + type: string + timeout: + type: number + description: Timeout for WaitCondition, depends on your image and environment + default: 1000 + +resources: + wait_condition: + type: OS::Heat::WaitCondition + properties: + handle: {get_resource: wait_handle} + count: 1 + timeout: {get_param: timeout} + + wait_handle: + type: OS::Heat::WaitConditionHandle + + + ### DEFAULT NETWORK FOR MERLIN DATA + port_1: + type: OS::Neutron::Port + properties: + network: { get_param: default_net } + binding:vnic_type: normal + fixed_ips: + - subnet: { get_param: default_subnet } + + ### NETWORK FOR RECEIVING TRAFFIC + port_2: + type: OS::Neutron::Port + properties: + network: { get_param: source_net } + binding:vnic_type: direct + fixed_ips: + - subnet: { get_param: source_subnet } + + ### NETWORK FOR SENDING TRAFFIC + port_3: + type: OS::Neutron::Port + properties: + network: { get_param: destination_net } + binding:vnic_type: direct + fixed_ips: + - subnet: { get_param: destination_subnet } + + flavor: + type: OS::Nova::Flavor + properties: + disk: 20 + ram: 1024 + vcpus: 2 + #extra_specs: { node: { get_param: node }, "hw:cpu_policy": "#core_pinning_enabled", "hw:cpu_threads_policy": "#core_pinning_mode", "hw:mem_page_size": "#hugepages" } + extra_specs: { node: { get_param: node } } + + server: + type: OS::Nova::Server + properties: + name: vTC + key_name: test + image: ubuntu1404 + user_data: + str_replace: + template: | + #!/bin/sh + + # Creation of a user + NAME=$name + echo "Creating custom user..." + useradd clouduser -g admin -s /bin/bash -m + echo clouduser:secrete | chpasswd + echo "Enabling ssh password login..." + sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config + service ssh restart + sleep 1 + + # wake up interfaces + ifconfig eth1 up + ifconfig eth2 up + dhclient eth1 + dhclient eth2 + + sed -i 's/localhost/localhost vtc/g' /etc/hosts + ip route del 0/0 + route add default gw 192.168.200.1 + + AA=$(netstat -ie | grep -B1 $IP_FAMILY | awk '{ print $1 }') + BB=$(echo $AA | awk '{ print $1 }') + + # Setup Instrumentation Agent + rm -rf cimmaron + mkdir cimmaron + cd cimmaron + apt-get install -y zip + wget http://10.2.1.65/~iolie/merlin/MerlinAgent-12-06-2015-TNovaVM-001.zip + unzip MerlinAgent-12-06-2015-TNovaVM-001.zip + ./updateConfiguration.py ./instrumentation.cfg tags source=tnova_vm + ./updateConfiguration.py ./instrumentation.cfg tags role="$NAME" + nohup ./Agent.py ./instrumentation.cfg >log.out 2>&1 & + cd .. + + # Setup for PF_RING and bridge between interfaces + apt-get update + apt-get install -y git build-essential gcc libnuma-dev flex byacc libjson0-dev dh-autoreconf libpcap-dev libpulse-dev libtool pkg-config + + # Setup multicast + echo smcroute -d mgroup from $BB group 224.192.16.1 > /etc/smcroute.conf + cd /home/clouduser/ + git clone https://github.com/troglobit/smcroute.git + cd smcroute + sed -i 's/aclocal-1.11/aclocal/g' ./autogen.sh + sed -i 's/automake-1.11/automake/g' ./autogen.sh + ./autogen.sh + ./configure + make + make install + cd .. + touch multicast.sh + echo "#!/bin/bash" > multicast.sh + echo "while [ true ]" >> multicast.sh + echo "do" >> multicast.sh + echo " smcroute -k" >> multicast.sh + echo " smcroute -d" >> multicast.sh + echo " sleep 50" >> multicast.sh + echo "done" >> multicast.sh + chmod +x multicast.sh + ./multicast.sh & + + # Setup for PF_RING and bridge between interfaces + # Akis Repository + #git clone https://akiskourtis:ptindpi@bitbucket.org/akiskourtis/vtc.git + #cd vtc + #git checkout stable + + # Intel Repository + git clone http://vincenzox.m.riccobene%40intel.com:vincenzo@134.191.243.6:8081/t-nova/vtc_master.git + cd vtc_master + + cd nDPI + NDPI_DIR=$(pwd) + echo $NDPI_DIR + NDPI_INCLUDE=$(pwd)/src/include + echo $NDPI_INCLUDE + ./autogen.sh + ./configure + make + make install + cd .. + cd PF_RING + make + cd userland/examples/ + sed -i 's/EXTRA_LIBS =/EXTRA_LIBS = '"${NDPI_DIR}"'/src/lib/.libs/libndpi.a -ljson-c/g' ./Makefile + sed -i 's/ -Ithird-party/ -Ithird-party -I'"$NDPI_INCLUDE"' -I'"$NDPI_DIR"'/g' ./Makefile + make + cd ../.. + cd .. + cd .. + #insmod ./vtc/PF_RING/kernel/pf_ring.ko min_num_slots=8192 enable_debug=1 quick_mode=1 enable_tx_capture=0 + #./vtc/PF_RING/userland/examples/pfbridge -a eth1 -b eth2 & + insmod ./vtc_master/PF_RING/kernel/pf_ring.ko min_num_slots=8192 enable_debug=1 quick_mode=1 enable_tx_capture=0 + ./vtc_master/PF_RING/userland/examples/pfbridge -a eth1 -b eth2 & + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + wc_notify: { get_attr: ['wait_handle', 'curl_cli'] } + $name: { get_param: name } + $IP_FAMILY: { get_param: ip_family } + + flavor: { get_resource: flavor } + networks: + - port: { get_resource: port_1 } + - port: { get_resource: port_2 } + - port: { get_resource: port_3 } +outputs: diff --git a/yardstick/vTC/apexlake/tests/data/test_templates/VTC_base_single_vm_wait_2.yaml.json b/yardstick/vTC/apexlake/tests/data/test_templates/VTC_base_single_vm_wait_2.yaml.json new file mode 100644 index 000000000..9f246891d --- /dev/null +++ b/yardstick/vTC/apexlake/tests/data/test_templates/VTC_base_single_vm_wait_2.yaml.json @@ -0,0 +1 @@ +{"vnic_type": "direct", "ram": "1024", "vcpus": "2"}
\ No newline at end of file diff --git a/yardstick/vTC/apexlake/tests/deployment_unit_test.py b/yardstick/vTC/apexlake/tests/deployment_unit_test.py new file mode 100644 index 000000000..46b32837b --- /dev/null +++ b/yardstick/vTC/apexlake/tests/deployment_unit_test.py @@ -0,0 +1,273 @@ +# 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. + +__author__ = 'vmriccox' + + +import unittest +import mock +import experimental_framework.deployment_unit as mut + + +class DummyHeatManager: + + def __init__(self, param): + self.counts = 0 + pass + + def validate_heat_template(self, template_file): + return True + + def check_stack_status(self, stack_name): + # return 'CREATE_COMPLETE' + self.counts += 1 + if self.counts >= 3: + return 'CREATE_COMPLETE' + else: + return 'CREATE_IN_PROGRESS' + + def delete_stack(self, stack_name): + pass + + +class DummyHeatManagerFailed(DummyHeatManager): + + def check_stack_status(self, stack_name): + return 'CREATE_FAILED' + + def create_stack(self, template_file, stack_name, parameters): + pass + + +class DummyHeatManagerComplete(DummyHeatManager): + + def check_stack_status(self, stack_name): + return 'CREATE_COMPLETE' + + def create_stack(self, template_file, stack_name, parameters): + raise Exception() + + +class DummyHeatManagerFailedException(DummyHeatManagerFailed): + + def create_stack(self, template_file, stack_name, parameters): + raise Exception + + def check_stack_status(self, stack_name): + return '' + + +class DummyHeatManagerDestroy: + + def __init__(self, credentials): + self.delete_stack_counter = 0 + self.check_stack_status_counter = 0 + + def check_stack_status(self, stack_name): + if self.check_stack_status_counter < 2: + self.check_stack_status_counter += 1 + return 'DELETE_IN_PROGRESS' + else: + return 'DELETE_COMPLETE' + + def create_stack(self, template_file, stack_name, parameters): + pass + + def delete_stack(self, stack_name=None): + if stack_name == 'stack': + self.delete_stack_counter += 1 + else: + return self.delete_stack_counter + + def is_stack_deployed(self, stack_name): + return True + + +class DummyHeatManagerDestroyException(DummyHeatManagerDestroy): + + def delete_stack(self, stack_name=None): + raise Exception + + +class DummyHeatManagerReiteration: + + def __init__(self, param): + self.counts = 0 + + def validate_heat_template(self, template_file): + return True + + def check_stack_status(self, stack_name): + return 'CREATE_FAILED' + + def delete_stack(self, stack_name): + pass + + def create_stack(self, template_file=None, stack_name=None, + parameters=None): + if template_file == 'template_reiteration' and \ + stack_name == 'stack_reiteration' and \ + parameters == 'parameters_reiteration': + self.counts += 1 + + +class DummyDeploymentUnit(mut.DeploymentUnit): + + def destroy_heat_template(self, stack_name): + raise Exception + + +class TestDeploymentUnit(unittest.TestCase): + + def setUp(self): + pass + + def tearDown(self): + pass + + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManager) + def test_constructor_for_sanity(self, mock_heat_manager): + du = mut.DeploymentUnit(dict()) + self.assertTrue(isinstance(du.heat_manager, DummyHeatManager)) + mock_heat_manager.assert_called_once_with(dict()) + self.assertEqual(du.deployed_stacks, list()) + + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManager) + @mock.patch('os.path.isfile') + def test_deploy_heat_template_for_failure(self, mock_os_is_file, + mock_heat_manager): + mock_os_is_file.return_value = False + du = mut.DeploymentUnit(dict()) + template_file = '' + stack_name = '' + parameters = '' + self.assertRaises(ValueError, du.deploy_heat_template, template_file, + stack_name, parameters, 0) + + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManager) + @mock.patch('os.path.isfile') + def test_deploy_heat_template_for_success(self, mock_os_is_file, + mock_heat_manager): + mock_os_is_file.return_value = True + du = mut.DeploymentUnit(dict()) + template_file = '' + stack_name = '' + parameters = '' + output = du.deploy_heat_template(template_file, stack_name, + parameters, 0) + self.assertEqual(output, True) + + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManagerComplete) + @mock.patch('os.path.isfile') + def test_deploy_heat_template_2_for_success(self, mock_os_is_file, + mock_heat_manager): + mock_os_is_file.return_value = True + du = mut.DeploymentUnit(dict()) + template_file = '' + stack_name = '' + parameters = '' + output = du.deploy_heat_template(template_file, stack_name, + parameters, 0) + self.assertEqual(output, True) + + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManagerComplete) + @mock.patch('os.path.isfile') + @mock.patch('experimental_framework.deployment_unit.DeploymentUnit', + side_effect=DummyDeploymentUnit) + def test_deploy_heat_template_3_for_success(self, mock_dep_unit, + mock_os_is_file, + mock_heat_manager): + mock_os_is_file.return_value = True + du = mut.DeploymentUnit(dict()) + template_file = '' + stack_name = '' + parameters = '' + output = du.deploy_heat_template(template_file, stack_name, + parameters, 0) + self.assertEqual(output, True) + + @mock.patch('experimental_framework.common.LOG') + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManagerFailed) + @mock.patch('os.path.isfile') + def test_deploy_heat_template_for_success_2(self, mock_os_is_file, + mock_heat_manager, mock_log): + mock_os_is_file.return_value = True + du = DummyDeploymentUnit(dict()) + template_file = '' + stack_name = '' + parameters = '' + output = du.deploy_heat_template(template_file, stack_name, + parameters, 0) + self.assertEqual(output, False) + + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManagerDestroy) + @mock.patch('experimental_framework.common.LOG') + def test_destroy_heat_template_for_success(self, mock_log, + mock_heat_manager): + openstack_credentials = dict() + du = mut.DeploymentUnit(openstack_credentials) + du.deployed_stacks = ['stack'] + stack_name = 'stack' + self.assertTrue(du.destroy_heat_template(stack_name)) + self.assertEqual(du.heat_manager.delete_stack(None), 1) + + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManagerDestroyException) + @mock.patch('experimental_framework.common.LOG') + def test_destroy_heat_template_for_success_2(self, mock_log, + mock_heat_manager): + openstack_credentials = dict() + du = mut.DeploymentUnit(openstack_credentials) + du.deployed_stacks = ['stack'] + stack_name = 'stack' + self.assertFalse(du.destroy_heat_template(stack_name)) + + def test_destroy_all_deployed_stacks_for_success(self): + du = DeploymentUnitDestroy() + du.destroy_all_deployed_stacks() + self.assertTrue(du.destroy_heat_template()) + + @mock.patch('experimental_framework.heat_manager.HeatManager', + side_effect=DummyHeatManagerReiteration) + @mock.patch('os.path.isfile') + def test_deploy_heat_template_for_success_3(self, mock_os_is_file, + mock_heat_manager): + mock_os_is_file.return_value = True + du = mut.DeploymentUnit(dict()) + template = 'template_reiteration' + stack = 'stack_reiteration' + parameters = 'parameters_reiteration' + output = du.deploy_heat_template(template, stack, parameters, 0) + self.assertFalse(output) + self.assertEqual(du.heat_manager.counts, 4) + + +class DeploymentUnitDestroy(mut.DeploymentUnit): + + def __init__(self): + self.deployed_stacks = ['stack'] + self.heat_manager = DummyHeatManagerDestroy(dict()) + self.destroy_all_deployed_stacks_called_correctly = False + + def destroy_heat_template(self, template_name=None): + if template_name == 'stack': + self.destroy_all_deployed_stacks_called_correctly = True + return self.destroy_all_deployed_stacks_called_correctly diff --git a/yardstick/vTC/apexlake/tests/dpdk_packet_generator_test.py b/yardstick/vTC/apexlake/tests/dpdk_packet_generator_test.py index ad1cdcd2b..29b3e369f 100644 --- a/yardstick/vTC/apexlake/tests/dpdk_packet_generator_test.py +++ b/yardstick/vTC/apexlake/tests/dpdk_packet_generator_test.py @@ -702,4 +702,4 @@ class TestDpdkPacketGenOthers(unittest.TestCase): def test__change_vlan_for_success(self, mock_run_command, mock_log): mut.DpdkPacketGenerator._change_vlan('/directory/', 'pcap_file', '10') expected_param = '/directory/vlan_tag.sh /directory/pcap_file 10' - mock_run_command.assert_called_once_with(expected_param) + mock_run_command.assert_called_with(expected_param) diff --git a/yardstick/vTC/apexlake/tests/generates_template_test.py b/yardstick/vTC/apexlake/tests/generates_template_test.py index 85435db6a..f4525a23d 100644 --- a/yardstick/vTC/apexlake/tests/generates_template_test.py +++ b/yardstick/vTC/apexlake/tests/generates_template_test.py @@ -12,6 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +__author__ = 'gpetralx' + + import unittest import experimental_framework.heat_template_generation as heat_gen import mock @@ -19,6 +22,29 @@ import os import experimental_framework.common as common +def reset_common(): + common.LOG = None + common.CONF_FILE = None + common.DEPLOYMENT_UNIT = None + common.ITERATIONS = None + common.BASE_DIR = None + common.RESULT_DIR = None + common.TEMPLATE_DIR = None + common.TEMPLATE_NAME = None + common.TEMPLATE_FILE_EXTENSION = None + common.PKTGEN = None + common.PKTGEN_DIR = None + common.PKTGEN_DPDK_DIRECTORY = None + common.PKTGEN_PROGRAM = None + common.PKTGEN_COREMASK = None + common.PKTGEN_MEMCHANNEL = None + common.PKTGEN_BUS_SLOT_NIC_1 = None + common.PKTGEN_BUS_SLOT_NIC_2 = None + common.INFLUXDB_IP = None + common.INFLUXDB_PORT = None + common.INFLUXDB_DB_NAME = None + + class TestGeneratesTemplate(unittest.TestCase): def setUp(self): self.deployment_configuration = { @@ -27,16 +53,15 @@ class TestGeneratesTemplate(unittest.TestCase): 'vcpus': ['2'] } self.template_name = 'VTC_base_single_vm_wait.tmp' - common.init() - - def test_dummy(self): - self.assertTrue(True) + # common.init() def tearDown(self): - pass + reset_common() + @mock.patch('experimental_framework.common.LOG') @mock.patch('experimental_framework.common.get_template_dir') - def test_generates_template_for_success(self, mock_template_dir): + def test_generates_template_for_success(self, mock_template_dir, + mock_log): generated_templates_dir = 'tests/data/generated_templates/' mock_template_dir.return_value = generated_templates_dir test_templates = 'tests/data/test_templates/' @@ -50,7 +75,7 @@ class TestGeneratesTemplate(unittest.TestCase): generated.readlines()) t_name = '/tests/data/generated_templates/VTC_base_single_vm_wait.tmp' - self.template_name = os.getcwd() + t_name + self.template_name = "{}{}".format(os.getcwd(), t_name) heat_gen.generates_templates(self.template_name, self.deployment_configuration) for dirname, dirnames, filenames in os.walk(test_templates): diff --git a/yardstick/vTC/apexlake/tests/heat_manager_test.py b/yardstick/vTC/apexlake/tests/heat_manager_test.py index f89835cc7..a2798a737 100644 --- a/yardstick/vTC/apexlake/tests/heat_manager_test.py +++ b/yardstick/vTC/apexlake/tests/heat_manager_test.py @@ -144,11 +144,13 @@ class TestHeatManager(unittest.TestCase): def test_delete_stack_for_success_2(self): self.assertTrue(self.heat_manager.delete_stack('stack_1')) + @mock.patch('experimental_framework.common.LOG') @mock.patch('heatclient.common.template_utils.get_template_contents') @mock.patch('heatclient.client.Client') # @mock.patch('heatclient.client.Client', side_effect=DummyHeatClient) def test_create_stack_for_success(self, mock_stack_create, - mock_get_template_contents): + mock_get_template_contents, + mock_log): return_value = ({'template': 'template'}, 'template') mock_get_template_contents.return_value = return_value self.heat_manager.create_stack('template', 'stack_n', 'parameters') @@ -174,11 +176,18 @@ class TestHeatManager_2(unittest.TestCase): self.assertFalse(self.heat_manager.delete_stack('stack_1')) +class ServiceCatalog(): + def url_for(self, service_type): + return 'http://heat_url' + + class KeystoneMock(object): @property def auth_token(self): return 'token' + service_catalog = ServiceCatalog() + class TestHeatInit(unittest.TestCase): def setUp(self): diff --git a/yardstick/vTC/apexlake/tests/instantiation_validation_bench_test.py b/yardstick/vTC/apexlake/tests/instantiation_validation_bench_test.py index 569d24c5a..c44df6d9f 100644 --- a/yardstick/vTC/apexlake/tests/instantiation_validation_bench_test.py +++ b/yardstick/vTC/apexlake/tests/instantiation_validation_bench_test.py @@ -14,7 +14,9 @@ import unittest import mock +import os import experimental_framework.constants.conf_file_sections as cfs +import experimental_framework.common as common import experimental_framework.benchmarks.\ instantiation_validation_benchmark as iv_module from experimental_framework.benchmarks.\ @@ -70,7 +72,6 @@ def dummy_run_command_2(command, get_counters=None): elif command == "test_sniff interface.100 128 &": command_counter[4] += 1 return - raise Exception(command) def dummy_replace_in_file(file, str_from, str_to, get_couters=None): @@ -152,11 +153,12 @@ class DummyInstantiaionValidationBenchmark(InstantiationValidationBenchmark): class InstantiationValidationInitTest(unittest.TestCase): def setUp(self): + common.BASE_DIR = os.getcwd() self.iv = InstantiationValidationBenchmark('InstantiationValidation', dict()) def tearDown(self): - pass + common.BASE_DIR = None @mock.patch('experimental_framework.common.get_base_dir') def test___init___for_success(self, mock_base_dir): @@ -301,11 +303,13 @@ class InstantiationValidationInitTest(unittest.TestCase): self.assertEqual(dummy_replace_in_file('', '', '', True), [0, 0, 0, 1, 1, 1]) + @mock.patch('experimental_framework.common.LOG') @mock.patch('experimental_framework.packet_generators.' 'dpdk_packet_generator.DpdkPacketGenerator', side_effect=DummyDpdkPacketGenerator) @mock.patch('experimental_framework.common.get_dpdk_pktgen_vars') - def test_run_for_success(self, mock_common_get_vars, mock_pktgen): + def test_run_for_success(self, mock_common_get_vars, mock_pktgen, + mock_log): rval = dict() rval[cfs.CFSP_DPDK_BUS_SLOT_NIC_2] = 'bus_2' rval[cfs.CFSP_DPDK_NAME_IF_2] = 'if_2' diff --git a/yardstick/vTC/apexlake/tests/instantiation_validation_noisy_bench_test.py b/yardstick/vTC/apexlake/tests/instantiation_validation_noisy_bench_test.py index bbdf73947..463035743 100644 --- a/yardstick/vTC/apexlake/tests/instantiation_validation_noisy_bench_test.py +++ b/yardstick/vTC/apexlake/tests/instantiation_validation_noisy_bench_test.py @@ -14,8 +14,9 @@ import unittest import mock - - +import os +import experimental_framework.common as common +import experimental_framework.deployment_unit as deploy import experimental_framework.benchmarks.\ instantiation_validation_noisy_neighbors_benchmark as mut @@ -25,11 +26,22 @@ class InstantiationValidationInitTest(unittest.TestCase): def setUp(self): name = 'instantiation_validation_noisy' params = {'param': 'value'} + openstack_credentials = dict() + openstack_credentials['ip_controller'] = '' + openstack_credentials['project'] = '' + openstack_credentials['auth_uri'] = '' + openstack_credentials['user'] = '' + openstack_credentials['heat_url'] = '' + openstack_credentials['password'] = '' + common.DEPLOYMENT_UNIT = deploy.DeploymentUnit(openstack_credentials) + common.BASE_DIR = os.getcwd() + common.TEMPLATE_DIR = 'tests/data/generated_templates' self.iv = mut.\ InstantiationValidationNoisyNeighborsBenchmark(name, params) def tearDown(self): - pass + common.BASE_DIR = None + common.TEMPLATE_DIR = None @mock.patch('experimental_framework.benchmarks.' 'instantiation_validation_benchmark.' @@ -66,14 +78,14 @@ class InstantiationValidationInitTest(unittest.TestCase): expected['allowed_values'][mut.NUMBER_OF_CORES] = \ ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'] expected['allowed_values'][mut.AMOUNT_OF_RAM] = \ - ['250M', '1G', '2G', '3G', '4G', '5G', '6G', '7G', '8G', '9G', + ['256M', '1G', '2G', '3G', '4G', '5G', '6G', '7G', '8G', '9G', '10G'] expected['default_values']['throughput'] = '1' expected['default_values']['vlan_sender'] = '-1' expected['default_values']['vlan_receiver'] = '-1' expected['default_values'][mut.NUM_OF_NEIGHBORS] = '1' expected['default_values'][mut.NUMBER_OF_CORES] = '1' - expected['default_values'][mut.AMOUNT_OF_RAM] = '250M' + expected['default_values'][mut.AMOUNT_OF_RAM] = '256M' output = self.iv.get_features() self.assertEqual(expected['description'], output['description']) diff --git a/yardstick/vTC/apexlake/tests/multi_tenancy_throughput_benchmark_test.py b/yardstick/vTC/apexlake/tests/multi_tenancy_throughput_benchmark_test.py index 78aff35ba..babf04ab1 100644 --- a/yardstick/vTC/apexlake/tests/multi_tenancy_throughput_benchmark_test.py +++ b/yardstick/vTC/apexlake/tests/multi_tenancy_throughput_benchmark_test.py @@ -17,6 +17,8 @@ __author__ = 'gpetralx' import unittest import mock +import os +import experimental_framework.common as common from experimental_framework.benchmarks \ import multi_tenancy_throughput_benchmark as bench @@ -37,6 +39,7 @@ class TestMultiTenancyThroughputBenchmark(unittest.TestCase): def setUp(self): name = 'benchmark' params = dict() + common.BASE_DIR = os.getcwd() self.benchmark = bench.MultiTenancyThroughputBenchmark(name, params) def tearDown(self): diff --git a/yardstick/vTC/apexlake/tests/rfc2544_throughput_benchmark_test.py b/yardstick/vTC/apexlake/tests/rfc2544_throughput_benchmark_test.py index bef9b7f30..ef3b0dabb 100644 --- a/yardstick/vTC/apexlake/tests/rfc2544_throughput_benchmark_test.py +++ b/yardstick/vTC/apexlake/tests/rfc2544_throughput_benchmark_test.py @@ -12,11 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -__author__ = 'vmriccox' - import unittest import mock +import os from experimental_framework.benchmarks import rfc2544_throughput_benchmark \ as mut import experimental_framework.common as common @@ -29,11 +28,11 @@ class RFC2544ThroughputBenchmarkRunTest(unittest.TestCase): params = dict() params[mut.VLAN_SENDER] = '1' params[mut.VLAN_RECEIVER] = '2' + common.BASE_DIR = os.getcwd() self.benchmark = mut.RFC2544ThroughputBenchmark(name, params) - common.init_log() def tearDown(self): - pass + common.BASE_DIR = None def test_get_features_for_sanity(self): output = self.benchmark.get_features() @@ -51,6 +50,7 @@ class RFC2544ThroughputBenchmarkRunTest(unittest.TestCase): def test_finalize(self): self.assertEqual(self.benchmark.finalize(), None) + @mock.patch('experimental_framework.common.LOG') @mock.patch('experimental_framework.benchmarks.' 'rfc2544_throughput_benchmark.RFC2544ThroughputBenchmark.' '_reset_lua_file') @@ -67,8 +67,8 @@ class RFC2544ThroughputBenchmarkRunTest(unittest.TestCase): 'rfc2544_throughput_benchmark.dpdk.DpdkPacketGenerator') def test_run_for_success(self, mock_dpdk, mock_get_results, mock_extract_size, conf_lua_file_mock, - reset_lua_file_mock): - expected = {'results': 0, 'packet_size': '1'} + reset_lua_file_mock, mock_common_log): + expected = {'results': 0} mock_extract_size.return_value = '1' mock_get_results.return_value = {'results': 0} output = self.benchmark.run() @@ -88,10 +88,11 @@ class RFC2544ThroughputBenchmarkOthers(unittest.TestCase): def setUp(self): name = 'benchmark' params = {'packet_size': '128'} + common.BASE_DIR = os.getcwd() self.benchmark = mut.RFC2544ThroughputBenchmark(name, params) def tearDown(self): - pass + common.BASE_DIR = None def test__extract_packet_size_from_params_for_success(self): expected = '128' @@ -121,10 +122,10 @@ class RFC2544ThroughputBenchmarkOthers(unittest.TestCase): class RFC2544ThroughputBenchmarkGetResultsTest(unittest.TestCase): def setUp(self): - pass + common.BASE_DIR = os.getcwd() def tearDown(self): - pass + common.BASE_DIR = None @mock.patch('experimental_framework.common.get_file_first_line') def test__get_results_for_success(self, mock_common_file_line): diff --git a/yardstick/vTC/apexlake/tests/tree_node_test.py b/yardstick/vTC/apexlake/tests/tree_node_test.py new file mode 100644 index 000000000..8b302c912 --- /dev/null +++ b/yardstick/vTC/apexlake/tests/tree_node_test.py @@ -0,0 +1,97 @@ +# 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. + +__author__ = 'gpetralx' + + +import unittest +import experimental_framework.heat_template_generation as heat_gen + + +class TestTreeNode(unittest.TestCase): + def setUp(self): + self.tree = heat_gen.TreeNode() + + def tearDown(self): + pass + + def test_add_child_for_success(self): + child = heat_gen.TreeNode() + self.tree.add_child(child) + self.assertIn(child, self.tree.down) + + def test_get_parent_for_success(self): + self.assertIsNone(self.tree.get_parent()) + child = heat_gen.TreeNode() + self.tree.add_child(child) + self.assertEqual(self.tree, child.get_parent()) + + def test_get_children_for_success(self): + self.assertListEqual(list(), self.tree.get_children()) + child = heat_gen.TreeNode() + self.tree.add_child(child) + children = [child] + self.assertListEqual(children, self.tree.get_children()) + + def test_variable_name_for_success(self): + self.assertEqual('', self.tree.get_variable_name()) + variable_name = 'test' + self.tree.set_variable_name(variable_name) + self.assertEqual(variable_name, self.tree.get_variable_name()) + + def test_variable_value_for_success(self): + self.assertEqual(0, self.tree.get_variable_value()) + variable_value = 1 + self.tree.set_variable_value(variable_value) + self.assertEqual(variable_value, self.tree.get_variable_value()) + + def test_get_path_for_success(self): + child_1 = heat_gen.TreeNode() + self.tree.add_child(child_1) + child_2 = heat_gen.TreeNode() + child_1.add_child(child_2) + child_3 = heat_gen.TreeNode() + child_2.add_child(child_3) + + path = [self.tree, child_1, child_2, child_3] + + self.assertListEqual(path, child_3.get_path()) + + def test_str_for_success(self): + name = 'name' + value = 0 + self.tree.set_variable_name(name) + self.tree.set_variable_value(value) + self.assertEqual(name + " --> " + str(value), str(self.tree)) + + def test_repr_for_success(self): + name = 'name' + value = 0 + self.tree.set_variable_name(name) + self.tree.set_variable_value(value) + self.assertEqual(name + " = " + str(value), repr(self.tree)) + + def test_get_leaves_for_success(self): + child_1 = heat_gen.TreeNode() + self.tree.add_child(child_1) + child_2 = heat_gen.TreeNode() + child_1.add_child(child_2) + child_3 = heat_gen.TreeNode() + child_2.add_child(child_3) + child_4 = heat_gen.TreeNode() + child_2.add_child(child_4) + child_5 = heat_gen.TreeNode() + child_2.add_child(child_5) + leaves = [child_3, child_4, child_5] + self.assertListEqual(leaves, heat_gen.TreeNode.get_leaves(self.tree)) |