summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xtools/ubuntu-server-cloudimg-modify.sh5
-rw-r--r--yardstick/vTC/apexlake/experimental_framework/constants/__init__.py17
-rw-r--r--yardstick/vTC/apexlake/experimental_framework/constants/conf_file_sections.py86
-rw-r--r--yardstick/vTC/apexlake/experimental_framework/constants/framework_parameters.py33
-rw-r--r--yardstick/vTC/apexlake/experimental_framework/heat_template_generation.py235
5 files changed, 376 insertions, 0 deletions
diff --git a/tools/ubuntu-server-cloudimg-modify.sh b/tools/ubuntu-server-cloudimg-modify.sh
index 06579ff9a..bdf96ba5a 100755
--- a/tools/ubuntu-server-cloudimg-modify.sh
+++ b/tools/ubuntu-server-cloudimg-modify.sh
@@ -32,6 +32,11 @@ grep trusty /etc/apt/sources.list && \
# Force apt to use ipv4 due to build problems on LF POD.
echo 'Acquire::ForceIPv4 "true";' > /etc/apt/apt.conf.d/99force-ipv4
+# Add hostname to /etc/hosts.
+cat <<EOF >/etc/cloud/cloud.cfg.d/10_etc_hosts.cfg
+manage_etc_hosts: True
+EOF
+
apt-get update
apt-get install -y \
fio \
diff --git a/yardstick/vTC/apexlake/experimental_framework/constants/__init__.py b/yardstick/vTC/apexlake/experimental_framework/constants/__init__.py
new file mode 100644
index 000000000..8178e022d
--- /dev/null
+++ b/yardstick/vTC/apexlake/experimental_framework/constants/__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.
+
+"""
+Constants
+"""
diff --git a/yardstick/vTC/apexlake/experimental_framework/constants/conf_file_sections.py b/yardstick/vTC/apexlake/experimental_framework/constants/conf_file_sections.py
new file mode 100644
index 000000000..eed00bce0
--- /dev/null
+++ b/yardstick/vTC/apexlake/experimental_framework/constants/conf_file_sections.py
@@ -0,0 +1,86 @@
+# 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.
+
+
+# ------------------------------------------------------
+# Configuration File Sections
+# ------------------------------------------------------
+CFS_PKTGEN = 'PacketGen'
+CFS_GENERAL = 'General'
+CFS_OPENSTACK = 'OpenStack'
+CFS_EXPERIMENT_VNF = 'Experiment-VNF'
+CFS_EXPERIMENT_GENERIC = 'Experiment-generic'
+CFS_TESTCASE_PARAMETERS = 'Testcase-parameters'
+CFS_DEPLOYMENT_PARAMETERS = 'Deployment-parameters'
+
+
+def get_sections():
+ return [
+ CFS_PKTGEN,
+ CFS_GENERAL,
+ CFS_OPENSTACK,
+ CFS_EXPERIMENT_VNF,
+ CFS_EXPERIMENT_GENERIC,
+ CFS_TESTCASE_PARAMETERS,
+ CFS_DEPLOYMENT_PARAMETERS
+ # Add here eventually new sections in configuration file ...
+ ]
+
+
+def get_sections_api():
+ return [
+ CFS_PKTGEN,
+ CFS_GENERAL,
+ # TODO: TO BE REMOVED AFTER TESTING THE API
+ CFS_OPENSTACK
+ # Add here eventually new sections in configuration file ...
+ ]
+
+# ------------------------------------------------------
+# General section parameters
+# ------------------------------------------------------
+CFSG_ITERATIONS = 'iterations'
+CFSG_TEMPLATE_DIR = 'template_dir'
+CFSG_TEMPLATE_NAME = 'template_base_name'
+CFSG_RESULT_DIRECTORY = 'results_directory'
+CFSG_BENCHMARKS = 'benchmarks'
+
+
+# ------------------------------------------------------
+# Packet generator section parameters
+# ------------------------------------------------------
+CFSP_PACKET_GENERATOR = 'packet_generator'
+CFSP_DPDK_DIRECTORY = 'directory'
+CFSP_DPDK_PROGRAM_NAME = 'program_name'
+CFSP_DPDK_COREMASK = 'coremask'
+CFSP_DPDK_MEMORY_CHANNEL = 'memory_channels'
+CFSP_DPDK_CORE_NICS = 'core_nics'
+
+
+# ------------------------------------------------------
+# Supported Packet generators
+# ------------------------------------------------------
+CFSP_PG_NONE = 'none'
+CFSP_PG_DPDK = 'dpdk_pktgen'
+
+
+# ------------------------------------------------------
+# OpenStack section variables
+# ------------------------------------------------------
+CFSO_IP_CONTROLLER = 'ip_controller'
+CFSO_HEAT_URL = 'heat_url'
+CFSO_USER = 'user'
+CFSO_PASSWORD = 'password'
+CFSO_AUTH_URI = 'auth_uri'
+CFSO_PROJECT = 'project'
diff --git a/yardstick/vTC/apexlake/experimental_framework/constants/framework_parameters.py b/yardstick/vTC/apexlake/experimental_framework/constants/framework_parameters.py
new file mode 100644
index 000000000..4ee3a8aa3
--- /dev/null
+++ b/yardstick/vTC/apexlake/experimental_framework/constants/framework_parameters.py
@@ -0,0 +1,33 @@
+# Copyright (c) 2015 Intel Research and Development Ireland Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+from experimental_framework.constants import conf_file_sections as cfs
+
+# ------------------------------------------------------
+# Directories and file locations
+# ------------------------------------------------------
+EXPERIMENTAL_FRAMEWORK_DIR = 'experimental_framework/'
+EXPERIMENT_TEMPLATE_NAME = 'experiment'
+TEMPLATE_FILE_EXTENSION = '.yaml'
+DPDK_PKTGEN_DIR = 'packet_generators/dpdk_pktgen/'
+PCAP_DIR = 'packet_generators/pcap_files/'
+
+
+def get_supported_packet_generators():
+ return [
+ cfs.CFSP_PG_NONE,
+ cfs.CFSP_PG_DPDK
+ # Add here any other supported packet generator
+ ]
diff --git a/yardstick/vTC/apexlake/experimental_framework/heat_template_generation.py b/yardstick/vTC/apexlake/experimental_framework/heat_template_generation.py
new file mode 100644
index 000000000..15c4eff36
--- /dev/null
+++ b/yardstick/vTC/apexlake/experimental_framework/heat_template_generation.py
@@ -0,0 +1,235 @@
+# 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.
+
+
+'''
+This file contains the code to Generate the heat templates from the base
+template
+'''
+
+import json
+import os
+import shutil
+from experimental_framework import common
+from experimental_framework.constants import framework_parameters as fp
+
+
+class TreeNode:
+ """
+ This class represent the node of the configuration tree.\
+ Each node represents a single configuration value for a single
+ configuration parameter.
+ """
+
+ def __init__(self):
+ self.up = None
+ self.down = []
+ self.variable_name = ''
+ self.variable_value = 0
+
+ def add_child(self, node):
+ """
+ Adds a node as a child for the current node
+ :param node: node to be added as a child (type: TreeNode)
+ :return: None
+ """
+ node.up = self
+ self.down.append(node)
+
+ def get_parent(self):
+ """
+ Returns the parent node of the current one
+ :return type: TreeNode
+ """
+ return self.up
+
+ def get_children(self):
+ """
+ Returns the children of the current node
+ :return type: list of TreeNode
+ """
+ if len(self.down) == 0:
+ # return [self]
+ return []
+ return self.down
+
+ def get_variable_name(self):
+ """
+ Returns the name of the variable correspondent to the current node
+ :return type: str
+ """
+ return self.variable_name
+
+ def get_variable_value(self):
+ """
+ Returns the value of the variable correspondent to the current node
+ :return type: str or int
+ """
+ return self.variable_value
+
+ def set_variable_name(self, name):
+ """
+ Sets the name of the variable for the current node
+ :param name: Name of the variable (type: str)
+ :return None
+ """
+ self.variable_name = name
+
+ def set_variable_value(self, value):
+ """
+ Sets the value of the variable for the current node
+ :param value: value of the variable (type: str)
+ :return None
+ """
+ self.variable_value = value
+
+ def get_path(self):
+ """
+ Returns all the path from the current node to the root of the tree.
+ :return type: list of TreeNode
+ """
+ ret_val = []
+ if not self.up:
+ ret_val.append(self)
+ return ret_val
+ for node in self.up.get_path():
+ ret_val.append(node)
+ ret_val.append(self)
+ return ret_val
+
+ def __str__(self):
+ return str(self.variable_name) + " --> " + str(self.variable_value)
+
+ def __repr__(self):
+ return str(self.variable_name) + " = " + str(self.variable_value)
+
+ @staticmethod
+ def _get_leaves(node, leaves):
+ """
+ Returns all the leaves of a tree.
+ It changes the "leaves" list.
+ :param node: root of the tree (type: TreeNode)
+ :param leaves: partial list of leaves (type: list of TreeNode)
+ :return type: None
+ """
+ children = node.get_children()
+ if len(children) == 0:
+ leaves.append(node)
+ return
+ for child in children:
+ TreeNode._get_leaves(child, leaves)
+
+ @staticmethod
+ def get_leaves(node):
+ """
+ Returns all the leaves of a tree.
+ :param node: root of the tree (TreeNode)
+ :return type: list
+ """
+ leaves = list()
+ TreeNode._get_leaves(node, leaves)
+ return leaves
+
+
+template_name = fp.EXPERIMENT_TEMPLATE_NAME
+
+
+def generates_templates(base_heat_template, deployment_configuration):
+ """
+ Generates the heat templates for the experiments
+ :return: None
+ """
+ # Load useful parameters from file
+ template_dir = common.get_template_dir()
+ template_file_extension = fp.TEMPLATE_FILE_EXTENSION
+ template_base_name = base_heat_template
+
+ variables = deployment_configuration
+
+ # Delete the templates eventually generated in previous running of the
+ # framework
+ common.LOG.info("Removing the heat templates previously generated")
+ os.system("rm " + template_dir + template_name + "_*")
+
+ # Creation of the tree with all the new configurations
+ common.LOG.info("Creation of the tree with all the new configurations")
+ tree = TreeNode()
+ for variable in variables:
+ leaves = TreeNode.get_leaves(tree)
+ common.LOG.debug("LEAVES: " + str(leaves))
+ common.LOG.debug("VALUES: " + str(variables[variable]))
+
+ for value in variables[variable]:
+ for leaf in leaves:
+ new_node = TreeNode()
+ new_node.set_variable_name(variable)
+ new_node.set_variable_value(value)
+ leaf.add_child(new_node)
+
+ common.LOG.debug("CONFIGURATION TREE: " + str(tree))
+
+ common.LOG.info("Heat Template and metadata file creation")
+ leaves = TreeNode.get_leaves(tree)
+ counter = 1
+ for leaf in leaves:
+ heat_template_vars = leaf.get_path()
+ if os.path.isabs(template_base_name):
+ base_template = template_base_name
+ else:
+ base_template = template_dir + template_base_name
+ if os.path.isabs(template_name):
+ new_template = template_name
+ else:
+ new_template = template_dir + template_name
+ new_template += "_" + str(counter) + template_file_extension
+ shutil.copy(base_template, new_template)
+
+ metadata = dict()
+ for var in heat_template_vars:
+ if var.get_variable_name():
+ common.replace_in_file(new_template, "#" +
+ var.get_variable_name(),
+ var.get_variable_value())
+ metadata[var.get_variable_name()] = var.get_variable_value()
+
+ # Save the metadata on a JSON file
+ with open(new_template + ".json", 'w') as outfile:
+ json.dump(metadata, outfile)
+
+ common.LOG.debug("Heat Templates and Metadata file " + str(counter) +
+ " created")
+ counter += 1
+
+ # Creation of the template files
+ common.LOG.info(str(counter - 1) + " Heat Templates and Metadata files "
+ "created")
+
+
+def get_all_heat_templates(template_dir, template_file_extension):
+ """
+ Loads and returns all the generated heat templates
+ :param template_dir: directory to search in (type: str)
+ :param template_file_extension: extension of the file for templates
+ (type: str)
+ :return: type: list
+ """
+ template_files = list()
+ for dirname, dirnames, filenames in os.walk(template_dir):
+ for filename in filenames:
+ if template_file_extension in filename and \
+ filename.endswith(template_file_extension) and \
+ template_name in filename:
+ template_files.append(filename)
+ template_files.sort()
+ return template_files