summaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/installer-adapter/ApexAdapter.py35
-rw-r--r--utils/installer-adapter/CompassAdapter.py35
-rw-r--r--utils/installer-adapter/FuelAdapter.py219
-rw-r--r--utils/installer-adapter/InstallerHandler.py78
-rw-r--r--utils/installer-adapter/JoidAdapter.py35
-rw-r--r--utils/installer-adapter/RelengLogger.py52
-rw-r--r--utils/installer-adapter/SSHUtils.py130
-rw-r--r--utils/installer-adapter/__init__.py0
-rw-r--r--utils/installer-adapter/example.py22
-rw-r--r--utils/test/dashboard/dashboard/elastic2kibana/main.py2
-rw-r--r--utils/test/dashboard/dashboard/mongo2elastic/format.py204
-rw-r--r--utils/test/dashboard/dashboard/mongo2elastic/main.py2
-rw-r--r--utils/test/reporting/yardstick/reporting-status.py50
-rw-r--r--utils/test/reporting/yardstick/reportingUtils.py21
-rw-r--r--utils/test/reporting/yardstick/scenarioResult.py7
-rw-r--r--utils/test/reporting/yardstick/template/index-status-tmpl.html63
-rw-r--r--utils/test/result_collection_api/3rd_party/static/.gitignore (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/.gitignore)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/css/highlight.default.css (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/css/highlight.default.css)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/css/hightlight.default.css (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/css/hightlight.default.css)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/css/screen.css (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/css/screen.css)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/endpoint.html (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/endpoint.html)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/images/explorer_icons.png (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/images/explorer_icons.png)bin5763 -> 5763 bytes
-rw-r--r--utils/test/result_collection_api/3rd_party/static/images/logo_small.png (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/images/logo_small.png)bin770 -> 770 bytes
-rw-r--r--utils/test/result_collection_api/3rd_party/static/images/pet_store_api.png (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/images/pet_store_api.png)bin824 -> 824 bytes
-rw-r--r--utils/test/result_collection_api/3rd_party/static/images/throbber.gif (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/images/throbber.gif)bin9257 -> 9257 bytes
-rw-r--r--utils/test/result_collection_api/3rd_party/static/images/wordnik_api.png (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/images/wordnik_api.png)bin980 -> 980 bytes
-rw-r--r--utils/test/result_collection_api/3rd_party/static/index.html (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/index.html)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/lib/backbone-min.js (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/backbone-min.js)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/lib/handlebars-1.0.0.js (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/handlebars-1.0.0.js)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/lib/highlight.7.3.pack.js (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/highlight.7.3.pack.js)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/lib/jquery-1.8.0.min.js (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/jquery-1.8.0.min.js)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/lib/jquery.ba-bbq.min.js (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/jquery.ba-bbq.min.js)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/lib/jquery.slideto.min.js (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/jquery.slideto.min.js)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/lib/jquery.wiggle.min.js (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/jquery.wiggle.min.js)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/lib/shred.bundle.js (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/shred.bundle.js)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/lib/shred/content.js (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/shred/content.js)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/lib/swagger-oauth.js (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/swagger-oauth.js)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/lib/swagger.js (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/swagger.js)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/lib/underscore-min.js (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/underscore-min.js)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/o2c.html (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/o2c.html)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/swagger-ui.js (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/swagger-ui.js)0
-rw-r--r--utils/test/result_collection_api/3rd_party/static/swagger-ui.min.js (renamed from utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/swagger-ui.min.js)0
-rw-r--r--utils/test/result_collection_api/README.rst2
-rwxr-xr-xutils/test/result_collection_api/install.sh20
44 files changed, 740 insertions, 237 deletions
diff --git a/utils/installer-adapter/ApexAdapter.py b/utils/installer-adapter/ApexAdapter.py
new file mode 100644
index 000000000..bf451f3d2
--- /dev/null
+++ b/utils/installer-adapter/ApexAdapter.py
@@ -0,0 +1,35 @@
+##############################################################################
+# Copyright (c) 2016 Ericsson AB and others.
+# Author: Jose Lausuch (jose.lausuch@ericsson.com)
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+from SSHUtils import SSH_Connection
+
+
+class ApexAdapter:
+
+ def __init__(self, installer_ip):
+ self.installer_ip = installer_ip
+
+ def get_deployment_info(self):
+ pass
+
+ def get_nodes(self):
+ pass
+
+ def get_controller_ips(self):
+ pass
+
+ def get_compute_ips(self):
+ pass
+
+ def get_file_from_installer(self, origin, target, options=None):
+ pass
+
+ def get_file_from_controller(self, origin, target, ip=None, options=None):
+ pass \ No newline at end of file
diff --git a/utils/installer-adapter/CompassAdapter.py b/utils/installer-adapter/CompassAdapter.py
new file mode 100644
index 000000000..b40a8d788
--- /dev/null
+++ b/utils/installer-adapter/CompassAdapter.py
@@ -0,0 +1,35 @@
+##############################################################################
+# Copyright (c) 2016 Ericsson AB and others.
+# Author: Jose Lausuch (jose.lausuch@ericsson.com)
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+from SSHUtils import SSH_Connection
+
+
+class CompassAdapter:
+
+ def __init__(self, installer_ip):
+ self.installer_ip = installer_ip
+
+ def get_deployment_info(self):
+ pass
+
+ def get_nodes(self):
+ pass
+
+ def get_controller_ips(self):
+ pass
+
+ def get_compute_ips(self):
+ pass
+
+ def get_file_from_installer(self, origin, target, options=None):
+ pass
+
+ def get_file_from_controller(self, origin, target, ip=None, options=None):
+ pass \ No newline at end of file
diff --git a/utils/installer-adapter/FuelAdapter.py b/utils/installer-adapter/FuelAdapter.py
new file mode 100644
index 000000000..15f0e929f
--- /dev/null
+++ b/utils/installer-adapter/FuelAdapter.py
@@ -0,0 +1,219 @@
+##############################################################################
+# Copyright (c) 2016 Ericsson AB and others.
+# Author: Jose Lausuch (jose.lausuch@ericsson.com)
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+from SSHUtils import SSH_Connection
+import RelengLogger as rl
+
+
+class FuelAdapter:
+
+ def __init__(self, installer_ip, user="root", password="r00tme"):
+ self.installer_ip = installer_ip
+ self.user = user
+ self.password = password
+ self.connection = SSH_Connection(
+ installer_ip, self.user, self.password, use_system_keys=False)
+ self.logger = rl.Logger("Handler").getLogger()
+
+ def runcmd_fuel_nodes(self):
+ output, error = self.connection.run_remote_cmd('fuel nodes')
+ if len(error) > 0:
+ self.logger.error("error %s" % error)
+ return error
+ return output
+
+ def runcmd_fuel_env(self):
+ output, error = self.connection.run_remote_cmd('fuel env')
+ if len(error) > 0:
+ self.logger.error("error %s" % error)
+ return error
+ return output
+
+ def get_clusters(self):
+ environments = []
+ output = self.runcmd_fuel_env()
+ lines = output.rsplit('\n')
+ if len(lines) < 2:
+ self.logger.infp("No environments found in the deployment.")
+ return None
+ else:
+ fields = lines[0].rsplit(' | ')
+
+ index_id = -1
+ index_status = -1
+ index_name = -1
+ index_release_id = -1
+
+ for i in range(0, len(fields) - 1):
+ if "id" in fields[i]:
+ index_id = i
+ elif "status" in fields[i]:
+ index_status = i
+ elif "name" in fields[i]:
+ index_name = i
+ elif "release_id" in fields[i]:
+ index_release_id = i
+
+ # order env info
+ for i in range(2, len(lines) - 1):
+ fields = lines[i].rsplit(' | ')
+ dict = {"id": fields[index_id].strip(),
+ "status": fields[index_status].strip(),
+ "name": fields[index_name].strip(),
+ "release_id": fields[index_release_id].strip()}
+ environments.append(dict)
+
+ return environments
+
+ def get_nodes(self, options=None):
+ nodes = []
+ output = self.runcmd_fuel_nodes()
+ lines = output.rsplit('\n')
+ if len(lines) < 2:
+ self.logger.info("No nodes found in the deployment.")
+ return None
+ else:
+ # get fields indexes
+ fields = lines[0].rsplit(' | ')
+
+ index_id = -1
+ index_status = -1
+ index_name = -1
+ index_cluster = -1
+ index_ip = -1
+ index_mac = -1
+ index_roles = -1
+ index_online = -1
+
+ for i in range(0, len(fields) - 1):
+ if "id" in fields[i]:
+ index_id = i
+ elif "status" in fields[i]:
+ index_status = i
+ elif "name" in fields[i]:
+ index_name = i
+ elif "cluster" in fields[i]:
+ index_cluster = i
+ elif "ip" in fields[i]:
+ index_ip = i
+ elif "mac" in fields[i]:
+ index_mac = i
+ elif "roles " in fields[i]:
+ index_roles = i
+ elif "online" in fields[i]:
+ index_online = i
+
+ # order nodes info
+ for i in range(2, len(lines) - 1):
+ fields = lines[i].rsplit(' | ')
+ dict = {"id": fields[index_id].strip(),
+ "status": fields[index_status].strip(),
+ "name": fields[index_name].strip(),
+ "cluster": fields[index_cluster].strip(),
+ "ip": fields[index_ip].strip(),
+ "mac": fields[index_mac].strip(),
+ "roles": fields[index_roles].strip(),
+ "online": fields[index_online].strip()}
+ if options and options['cluster']:
+ if fields[index_cluster].strip() == options['cluster']:
+ nodes.append(dict)
+ else:
+ nodes.append(dict)
+
+ return nodes
+
+ def get_controller_ips(self, options):
+ nodes = self.get_nodes(options=options)
+ controllers = []
+ for node in nodes:
+ if "controller" in node["roles"]:
+ controllers.append(node['ip'])
+ return controllers
+
+ def get_compute_ips(self, options=None):
+ nodes = self.get_nodes(options=options)
+ computes = []
+ for node in nodes:
+ if "compute" in node["roles"]:
+ computes.append(node['ip'])
+ return computes
+
+ def get_deployment_info(self):
+ str = "Deployment details:\n"
+ str += "\tInstaller: Fuel\n"
+ str += "\tScenario: Unknown\n"
+ sdn = "None"
+ clusters = self.get_clusters()
+ str += "\tN.Clusters: %s\n" % len(clusters)
+ for cluster in clusters:
+ cluster_dic = {'cluster': cluster['id']}
+ str += "\tCluster info:\n"
+ str += "\t ID: %s\n" % cluster['id']
+ str += "\t NAME: %s\n" % cluster['name']
+ str += "\t STATUS: %s\n" % cluster['status']
+ nodes = self.get_nodes(options=cluster_dic)
+ num_nodes = len(nodes)
+ for node in nodes:
+ if "opendaylight" in node['roles']:
+ sdn = "OpenDaylight"
+ elif "onos" in node['roles']:
+ sdn = "ONOS"
+ num_controllers = len(
+ self.get_controller_ips(options=cluster_dic))
+ num_computes = len(self.get_compute_ips(options=cluster_dic))
+ ha = False
+ if num_controllers > 1:
+ ha = True
+
+ str += "\t HA: %s\n" % ha
+ str += "\t NUM.NODES: %s\n" % num_nodes
+ str += "\t CONTROLLERS: %s\n" % num_controllers
+ str += "\t COMPUTES: %s\n" % num_computes
+ str += "\t SDN CONTR.: %s\n\n" % sdn
+ str += self.runcmd_fuel_nodes()
+ return str
+
+ def get_file_from_installer(self, remote_path, local_path, options=None):
+ self.logger.debug("Fetching %s from %s" %
+ (remote_path, self.installer_ip))
+ if self.connection.scp_get(local_path, remote_path) != 0:
+ self.logger.error("SCP failed to retrieve the file.")
+ return 1
+ self.logger.info("%s successfully copied from Fuel to %s" %
+ (remote_path, local_path))
+
+ def get_file_from_controller(self,
+ remote_path,
+ local_path,
+ ip=None,
+ options=None):
+ if ip is None:
+ controllers = self.get_controller_ips(options=options)
+ if len(controllers) == 0:
+ self.logger.info("No controllers found in the deployment.")
+ return 1
+ else:
+ target_ip = controllers[0]
+ else:
+ target_ip = ip
+
+ fuel_dir = '/root/scp/'
+ cmd = 'mkdir -p %s;rsync -Rav %s:%s %s' % (
+ fuel_dir, target_ip, remote_path, fuel_dir)
+ self.logger.info("Copying %s from %s to Fuel..." %
+ (remote_path, target_ip))
+ output, error = self.connection.run_remote_cmd(cmd)
+ self.logger.debug("Copying files from Fuel to %s..." % local_path)
+ self.get_file_from_installer(
+ fuel_dir + remote_path, local_path, options)
+ cmd = 'rm -r %s' % fuel_dir
+ output, error = self.connection.run_remote_cmd(cmd)
+ self.logger.info("%s successfully copied from %s to %s" %
+ (remote_path, target_ip, local_path))
diff --git a/utils/installer-adapter/InstallerHandler.py b/utils/installer-adapter/InstallerHandler.py
new file mode 100644
index 000000000..b81b806ca
--- /dev/null
+++ b/utils/installer-adapter/InstallerHandler.py
@@ -0,0 +1,78 @@
+##############################################################################
+# Copyright (c) 2015 Ericsson AB and others.
+# Author: Jose Lausuch (jose.lausuch@ericsson.com)
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+from FuelAdapter import FuelAdapter
+from ApexAdapter import ApexAdapter
+from CompassAdapter import CompassAdapter
+from JoidAdapter import JoidAdapter
+
+
+INSTALLERS = ["fuel", "apex", "compass", "joid"]
+
+
+class InstallerHandler:
+
+ def __init__(self,
+ installer,
+ installer_ip,
+ installer_user,
+ installer_pwd=None):
+ self.installer = installer.lower()
+ self.installer_ip = installer_ip
+ self.installer_user = installer_user
+ self.installer_pwd = installer_pwd
+
+ if self.installer == INSTALLERS[0]:
+ self.InstallerAdapter = FuelAdapter(self.installer_ip,
+ self.installer_user,
+ self.installer_pwd)
+ elif self.installer == INSTALLERS[1]:
+ self.InstallerAdapter = ApexAdapter(self.installer_ip)
+ elif self.installer == INSTALLERS[2]:
+ self.InstallerAdapter = CompassAdapter(self.installer_ip)
+ elif self.installer == INSTALLERS[3]:
+ self.InstallerAdapter = JoidAdapter(self.installer_ip)
+ else:
+ print("Installer %s is not valid. "
+ "Please use one of the followings: %s"
+ % (self.installer, INSTALLERS))
+ exit(1)
+
+ def get_deployment_info(self):
+ return self.InstallerAdapter.get_deployment_info()
+
+ def get_nodes(self, options=None):
+ return self.InstallerAdapter.get_nodes(options=options)
+
+ def get_controller_ips(self, options=None):
+ return self.InstallerAdapter.get_controller_ips(options=options)
+
+ def get_compute_ips(self, options=None):
+ return self.InstallerAdapter.get_compute_ips(options=options)
+
+ def get_file_from_installer(self,
+ remote_path,
+ local_path,
+ options=None):
+ return self.InstallerAdapter.get_file_from_installer(remote_path,
+ local_path,
+ options=options)
+
+ def get_file_from_controller(self,
+ remote_path,
+ local_path,
+ ip=None,
+ options=None):
+ return self.InstallerAdapter.get_file_from_controller(remote_path,
+ local_path,
+ ip=ip,
+ options=options)
+
+ def get_all(self):
+ pass
diff --git a/utils/installer-adapter/JoidAdapter.py b/utils/installer-adapter/JoidAdapter.py
new file mode 100644
index 000000000..e78ca0fae
--- /dev/null
+++ b/utils/installer-adapter/JoidAdapter.py
@@ -0,0 +1,35 @@
+##############################################################################
+# Copyright (c) 2016 Ericsson AB and others.
+# Author: Jose Lausuch (jose.lausuch@ericsson.com)
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+from SSHUtils import SSH_Connection
+
+
+class JoidAdapter:
+
+ def __init__(self, installer_ip):
+ self.installer_ip = installer_ip
+
+ def get_deployment_info(self):
+ pass
+
+ def get_nodes(self):
+ pass
+
+ def get_controller_ips(self):
+ pass
+
+ def get_compute_ips(self):
+ pass
+
+ def get_file_from_installer(self, origin, target, options=None):
+ pass
+
+ def get_file_from_controller(self, origin, target, ip=None, options=None):
+ pass \ No newline at end of file
diff --git a/utils/installer-adapter/RelengLogger.py b/utils/installer-adapter/RelengLogger.py
new file mode 100644
index 000000000..b38e78095
--- /dev/null
+++ b/utils/installer-adapter/RelengLogger.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+#
+# jose.lausuch@ericsson.com
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Logging levels:
+# Level Numeric value
+# CRITICAL 50
+# ERROR 40
+# WARNING 30
+# INFO 20
+# DEBUG 10
+# NOTSET 0
+#
+# Usage:
+# import RelengLogger as rl
+# logger = fl.Logger("script_name").getLogger()
+# logger.info("message to be shown with - INFO - ")
+# logger.debug("message to be shown with - DEBUG -")
+
+import logging
+import os
+
+
+class Logger:
+
+ def __init__(self, logger_name, level="INFO"):
+
+ self.logger = logging.getLogger(logger_name)
+ self.logger.propagate = 0
+ self.logger.setLevel(logging.DEBUG)
+
+ ch = logging.StreamHandler()
+ formatter = logging.Formatter('%(asctime)s - %(name)s - '
+ '%(levelname)s - %(message)s')
+ ch.setFormatter(formatter)
+ if level.lower() == "debug":
+ ch.setLevel(logging.DEBUG)
+ else:
+ ch.setLevel(logging.INFO)
+ self.logger.addHandler(ch)
+
+ hdlr = logging.FileHandler('/tmp/releng.log')
+ hdlr.setFormatter(formatter)
+ hdlr.setLevel(logging.DEBUG)
+ self.logger.addHandler(hdlr)
+
+ def getLogger(self):
+ return self.logger
diff --git a/utils/installer-adapter/SSHUtils.py b/utils/installer-adapter/SSHUtils.py
new file mode 100644
index 000000000..9c92a3be1
--- /dev/null
+++ b/utils/installer-adapter/SSHUtils.py
@@ -0,0 +1,130 @@
+##############################################################################
+# Copyright (c) 2015 Ericsson AB and others.
+# Author: Jose Lausuch (jose.lausuch@ericsson.com)
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+import paramiko
+from scp import SCPClient
+import time
+import RelengLogger as rl
+
+
+class SSH_Connection:
+
+ def __init__(self,
+ host,
+ user,
+ password,
+ use_system_keys=True,
+ private_key=None,
+ use_proxy=False,
+ proxy_host=None,
+ proxy_user=None,
+ proxy_password=None,
+ timeout=10):
+ self.host = host
+ self.user = user
+ self.password = password
+ self.use_system_keys = use_system_keys
+ self.private_key = private_key
+ self.use_proxy = use_proxy
+ self.proxy_host = proxy_host
+ self.proxy_user = proxy_user
+ self.proxy_password = proxy_password
+ self.timeout = timeout
+ paramiko.util.log_to_file("paramiko.log")
+ self.logger = rl.Logger("SSHUtils").getLogger()
+
+ def connect(self):
+ client = paramiko.SSHClient()
+ if self.use_system_keys:
+ client.load_system_host_keys()
+ elif self.private_key:
+ client.load_host_keys(self.private_key)
+ else:
+ client.load_host_keys('/dev/null')
+
+ client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+
+ t = self.timeout
+ proxy = None
+ if self.use_proxy:
+ proxy_command = 'ssh -o UserKnownHostsFile=/dev/null '
+ '-o StrictHostKeyChecking=no %s@%s -W %s:%s' % (self.proxy_user,
+ self.proxy_host,
+ self.host, 22)
+ proxy = paramiko.ProxyCommand(proxy_command)
+ self.logger.debug("Proxy command: %s" % proxy_command)
+ while t > 0:
+ try:
+ self.logger.debug(
+ "Trying to stablish ssh connection to %s..." % self.host)
+ client.connect(self.host,
+ username=self.user,
+ password=self.password,
+ look_for_keys=True,
+ sock=proxy,
+ pkey=self.private_key,
+ timeout=self.timeout)
+ self.logger.debug("Successfully connected to %s!" % self.host)
+ return client
+ except:
+ time.sleep(1)
+ t -= 1
+
+ if t == 0:
+ return None
+
+ def scp_put(self, local_path, remote_path):
+ client = self.connect()
+ if client:
+ scp = SCPClient(client.get_transport())
+ try:
+ scp.put(local_path, remote_path)
+ client.close()
+ return 0
+ except Exception, e:
+ self.logger.error(e)
+ client.close()
+ return 1
+ else:
+ self.logger.error("Cannot stablish ssh connection.")
+
+ def scp_get(self, local_path, remote_path):
+ client = self.connect()
+ if client:
+ scp = SCPClient(client.get_transport())
+ try:
+ scp.get(remote_path, local_path)
+ client.close()
+ return 0
+ except Exception, e:
+ self.logger.error(e)
+ client.close()
+ return 1
+ else:
+ self.logger.error("Cannot stablish ssh connection.")
+ return 1
+
+ def run_remote_cmd(self, command):
+ client = self.connect()
+ if client:
+ try:
+ stdin, stdout, stderr = client.exec_command(command)
+ out = ''
+ for line in stdout.readlines():
+ out += line
+ err = stderr.readlines()
+ client.close()
+ return out, err
+ except:
+ client.close()
+ return 1
+ else:
+ self.logger.error("Cannot stablish ssh connection.")
+ return 1
diff --git a/utils/installer-adapter/__init__.py b/utils/installer-adapter/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/utils/installer-adapter/__init__.py
diff --git a/utils/installer-adapter/example.py b/utils/installer-adapter/example.py
new file mode 100644
index 000000000..804d79c3d
--- /dev/null
+++ b/utils/installer-adapter/example.py
@@ -0,0 +1,22 @@
+# This is an example of usage of this Tool
+# Author: Jose Lausuch (jose.lausuch@ericsson.com)
+
+from InstallerHandler import InstallerHandler
+
+fuel_handler = InstallerHandler(installer='fuel',
+ installer_ip='10.20.0.2',
+ installer_user='root',
+ installer_pwd='r00tme')
+print("Nodes in cluster 1:\n%s\n" %
+ fuel_handler.get_nodes(options={'cluster': '1'}))
+print("Nodes in cluster 2:\n%s\n" %
+ fuel_handler.get_nodes(options={'cluster': '2'}))
+print("Nodes:\n%s\n" % fuel_handler.get_nodes())
+print("Controller nodes:\n%s\n" % fuel_handler.get_controller_ips())
+print("Compute nodes:\n%s\n" % fuel_handler.get_compute_ips())
+print("\n%s\n" % fuel_handler.get_deployment_info())
+fuel_handler.get_file_from_installer('/root/deploy/dea.yaml', './dea.yaml')
+fuel_handler.get_file_from_controller(
+ '/etc/neutron/neutron.conf', './neutron.conf')
+fuel_handler.get_file_from_controller(
+ '/root/openrc', './openrc')
diff --git a/utils/test/dashboard/dashboard/elastic2kibana/main.py b/utils/test/dashboard/dashboard/elastic2kibana/main.py
index e4c17d737..5af512e2f 100644
--- a/utils/test/dashboard/dashboard/elastic2kibana/main.py
+++ b/utils/test/dashboard/dashboard/elastic2kibana/main.py
@@ -132,7 +132,7 @@ class KibanaConstructor(object):
})
elastic_data = elastic_access.get_docs(
- urlparse.urljoin(CONF.es_url, '/test_results/mongo2elastic'),
+ urlparse.urljoin(CONF.es_url, '/testapi/results'),
CONF.es_creds,
query)
diff --git a/utils/test/dashboard/dashboard/mongo2elastic/format.py b/utils/test/dashboard/dashboard/mongo2elastic/format.py
deleted file mode 100644
index 0bbde1746..000000000
--- a/utils/test/dashboard/dashboard/mongo2elastic/format.py
+++ /dev/null
@@ -1,204 +0,0 @@
-#! /usr/bin/env python
-
-
-def _convert_value(value):
- return value if value != '' else 0
-
-
-def _convert_duration(duration):
- if (isinstance(duration, str) or isinstance(duration, unicode)) and ':' in duration:
- hours, minutes, seconds = duration.split(":")
- hours = _convert_value(hours)
- minutes = _convert_value(minutes)
- seconds = _convert_value(seconds)
- int_duration = 3600 * int(hours) + 60 * int(minutes) + float(seconds)
- else:
- int_duration = duration
- return int_duration
-
-
-def format_normal(testcase):
- """
- Look for these and leave any of those:
- details.duration
- details.tests
- details.failures
-
- If none are present, then return False
- """
- found = False
- testcase_details = testcase['details']
- fields = ['duration', 'tests', 'failures']
- if isinstance(testcase_details, dict):
- for key, value in testcase_details.items():
- if key in fields:
- found = True
- if key == 'duration':
- testcase_details[key] = _convert_duration(value)
- else:
- del testcase_details[key]
-
- if 'tests' in testcase_details and 'failures' in testcase_details:
- testcase_tests = float(testcase_details['tests'])
- testcase_failures = float(testcase_details['failures'])
- if testcase_tests != 0:
- testcase_details['success_percentage'] = 100 * (testcase_tests - testcase_failures) / testcase_tests
- else:
- testcase_details['success_percentage'] = 0
-
-
- return found
-
-
-def format_rally(testcase):
- """
- Structure:
- details.[{summary.duration}]
- details.[{summary.nb success}]
- details.[{summary.nb tests}]
-
- Find data for these fields
- -> details.duration
- -> details.tests
- -> details.success_percentage
- """
- details = testcase['details']
- summary = None
- for item in details:
- if 'summary' in item:
- summary = item['summary']
-
- if not summary:
- return False
-
- testcase['details'] = {
- 'duration': summary['duration'],
- 'tests': summary['nb tests'],
- 'success_percentage': summary['nb success']
- }
- return True
-
-
-def _get_statistics(orig_data, stat_fields, stat_values=None):
- test_results = {}
- for stat_data in orig_data:
- for field in stat_fields:
- stat_value = stat_data[field]
- if stat_value in test_results:
- test_results[stat_value] += 1
- else:
- test_results[stat_value] = 1
-
- if stat_values is not None:
- for stat_value in stat_values:
- if stat_value not in test_results:
- test_results[stat_value] = 0
-
- return test_results
-
-
-def format_onos(testcase):
- """
- Structure:
- details.FUNCvirNet.duration
- details.FUNCvirNet.status.[{Case result}]
- details.FUNCvirNetL3.duration
- details.FUNCvirNetL3.status.[{Case result}]
-
- Find data for these fields
- -> details.FUNCvirNet.duration
- -> details.FUNCvirNet.tests
- -> details.FUNCvirNet.failures
- -> details.FUNCvirNetL3.duration
- -> details.FUNCvirNetL3.tests
- -> details.FUNCvirNetL3.failures
- """
- testcase_details = testcase['details']
-
- if 'FUNCvirNet' not in testcase_details or 'FUNCvirNetL3' not in testcase_details:
- return False
-
- funcvirnet_details = testcase_details['FUNCvirNet']['status']
- funcvirnet_stats = _get_statistics(funcvirnet_details, ('Case result',), ('PASS', 'FAIL'))
- funcvirnet_passed = funcvirnet_stats['PASS']
- funcvirnet_failed = funcvirnet_stats['FAIL']
- funcvirnet_all = funcvirnet_passed + funcvirnet_failed
-
- funcvirnetl3_details = testcase_details['FUNCvirNetL3']['status']
- funcvirnetl3_stats = _get_statistics(funcvirnetl3_details, ('Case result',), ('PASS', 'FAIL'))
- funcvirnetl3_passed = funcvirnetl3_stats['PASS']
- funcvirnetl3_failed = funcvirnetl3_stats['FAIL']
- funcvirnetl3_all = funcvirnetl3_passed + funcvirnetl3_failed
-
- testcase_details['FUNCvirNet'] = {
- 'duration': _convert_duration(testcase_details['FUNCvirNet']['duration']),
- 'tests': funcvirnet_all,
- 'failures': funcvirnet_failed
- }
- testcase_details['FUNCvirNetL3'] = {
- 'duration': _convert_duration(testcase_details['FUNCvirNetL3']['duration']),
- 'tests': funcvirnetl3_all,
- 'failures': funcvirnetl3_failed
- }
- return True
-
-
-def format_vims(testcase):
- """
- Structure:
- details.sig_test.result.[{result}]
- details.sig_test.duration
- details.vIMS.duration
- details.orchestrator.duration
-
- Find data for these fields
- -> details.sig_test.duration
- -> details.sig_test.tests
- -> details.sig_test.failures
- -> details.sig_test.passed
- -> details.sig_test.skipped
- -> details.vIMS.duration
- -> details.orchestrator.duration
- """
- testcase_details = testcase['details']
- test_results = _get_statistics(testcase_details['sig_test']['result'],
- ('result',),
- ('Passed', 'Skipped', 'Failed'))
- passed = test_results['Passed']
- skipped = test_results['Skipped']
- failures = test_results['Failed']
- all_tests = passed + skipped + failures
- testcase['details'] = {
- 'sig_test': {
- 'duration': testcase_details['sig_test']['duration'],
- 'tests': all_tests,
- 'failures': failures,
- 'passed': passed,
- 'skipped': skipped
- },
- 'vIMS': {
- 'duration': testcase_details['vIMS']['duration']
- },
- 'orchestrator': {
- 'duration': testcase_details['orchestrator']['duration']
- }
- }
- return True
-
-
-def format_qpi(testcase):
- """
- Look for these and leave any of those:
- details.index
-
- If none are present, then return False
- """
- details = testcase['details']
- if 'index' not in details:
- return False
-
- for key, value in details.items():
- if key != 'index':
- del details[key]
-
- return True
diff --git a/utils/test/dashboard/dashboard/mongo2elastic/main.py b/utils/test/dashboard/dashboard/mongo2elastic/main.py
index 3f92c5699..c2a8d1149 100644
--- a/utils/test/dashboard/dashboard/mongo2elastic/main.py
+++ b/utils/test/dashboard/dashboard/mongo2elastic/main.py
@@ -242,7 +242,7 @@ class DocumentsPublisher(object):
def main():
- base_elastic_url = urlparse.urljoin(CONF.es_url, '/test_results/mongo2elastic')
+ base_elastic_url = urlparse.urljoin(CONF.es_url, '/testapi/results')
days = args.latest_days
es_creds = CONF.es_creds
diff --git a/utils/test/reporting/yardstick/reporting-status.py b/utils/test/reporting/yardstick/reporting-status.py
index 60f1523bb..49809e9d8 100644
--- a/utils/test/reporting/yardstick/reporting-status.py
+++ b/utils/test/reporting/yardstick/reporting-status.py
@@ -8,10 +8,7 @@
#
import datetime
import jinja2
-import requests
-import sys
-import time
-import yaml
+import os
import reportingUtils as utils
import reportingConf as conf
@@ -20,6 +17,7 @@ from scenarios import config as cf
# Logger
logger = utils.getLogger("Yardstick-Status")
+reportingDate = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
logger.info("*******************************************")
logger.info("* Generating reporting scenario status *")
@@ -35,21 +33,23 @@ for version in conf.versions:
# get scenarios results data
scenario_results = utils.getScenarioStatus(installer, version)
if 'colorado' == version:
- stable_result = utils.getScenarioStatus(installer, 'stable/colorado')
- for k,v in stable_result.items():
- if not scenario_results.has_key(k):
+ stable_result = utils.getScenarioStatus(installer,
+ 'stable/colorado')
+ for k, v in stable_result.items():
+ if k not in scenario_results.keys():
scenario_results[k] = []
scenario_results[k] += stable_result[k]
scenario_result_criteria = {}
for s in scenario_results.keys():
- if cf.has_key(installer) and cf[installer].has_key(s):
+ if installer in cf.keys() and s in cf[installer].keys():
scenario_results.pop(s)
# From each scenarios get results list
for s, s_result in scenario_results.items():
logger.info("---------------------------------")
- logger.info("installer %s, version %s, scenario %s:" % (installer, version, s))
+ logger.info("installer %s, version %s, scenario %s:" % (installer,
+ version, s))
ten_criteria = len(s_result)
ten_score = 0
@@ -62,15 +62,38 @@ for version in conf.versions:
for v in four_result:
four_score += v
- s_status = str(utils.get_status(four_result, s_result))
+ s_status = str(utils.get_percent(four_result, s_result))
s_four_score = str(four_score) + '/' + str(four_criteria)
s_ten_score = str(ten_score) + '/' + str(ten_criteria)
- scenario_result_criteria[s] = sr.ScenarioResult(s_status, s_four_score, s_ten_score)
+ s_score_percent = utils.get_percent(four_result, s_result)
if '100' == s_status:
logger.info(">>>>> scenario OK, save the information")
else:
- logger.info(">>>> scenario not OK, last 4 iterations = %s, last 10 days = %s" % (s_four_score, s_ten_score))
+ logger.info(">>>> scenario not OK, last 4 iterations = %s, \
+ last 10 days = %s" % (s_four_score, s_ten_score))
+
+ # Save daily results in a file
+ path_validation_file = (conf.REPORTING_PATH +
+ "/release/" + version +
+ "/scenario_history.txt")
+
+ if not os.path.exists(path_validation_file):
+ with open(path_validation_file, 'w') as f:
+ info = 'date,scenario,installer,details,score\n'
+ f.write(info)
+
+ with open(path_validation_file, "a") as f:
+ info = (reportingDate + "," + s + "," + installer +
+ "," + s_ten_score + "," +
+ str(s_score_percent) + "\n")
+ f.write(info)
+
+ scenario_result_criteria[s] = sr.ScenarioResult(s_status,
+ s_four_score,
+ s_ten_score,
+ s_score_percent)
+
logger.info("--------------------------")
templateLoader = jinja2.FileSystemLoader(conf.REPORTING_PATH)
@@ -82,7 +105,8 @@ for version in conf.versions:
outputText = template.render(scenario_results=scenario_result_criteria,
installer=installer,
period=conf.PERIOD,
- version=version)
+ version=version,
+ date=reportingDate)
with open(conf.REPORTING_PATH + "/release/" + version +
"/index-status-" + installer + ".html", "wb") as fh:
diff --git a/utils/test/reporting/yardstick/reportingUtils.py b/utils/test/reporting/yardstick/reportingUtils.py
index 71eb9196c..ec9ed76dc 100644
--- a/utils/test/reporting/yardstick/reportingUtils.py
+++ b/utils/test/reporting/yardstick/reportingUtils.py
@@ -32,7 +32,7 @@ def getLogger(module):
def getScenarioStatus(installer, version):
url = (conf.URL_BASE + "?case=" + "scenario_status" +
"&installer=" + installer +
- "&version=" + version +"&period=" + str(conf.PERIOD))
+ "&version=" + version + "&period=" + str(conf.PERIOD))
request = Request(url)
try:
@@ -53,7 +53,7 @@ def getScenarioStatus(installer, version):
scenario_results[r['scenario']] = []
scenario_results[r['scenario']].append(r)
- for k,v in scenario_results.items():
+ for k, v in scenario_results.items():
# scenario_results[k] = v[:conf.LASTEST_TESTS]
s_list = []
for element in v:
@@ -66,20 +66,25 @@ def getScenarioStatus(installer, version):
# return scenario_results
return result_dict
+
def subfind(given_list, pattern_list):
+
for i in range(len(given_list)):
- if given_list[i] == pattern_list[0] and given_list[i:i + conf.LASTEST_TESTS] == pattern_list:
+ if given_list[i] == pattern_list[0] and \
+ given_list[i:i + conf.LASTEST_TESTS] == pattern_list:
return True
return False
-def get_percent(status):
-
+
+def _get_percent(status):
+
if status * 100 % 6:
return round(float(status) * 100 / 6, 1)
else:
return status * 100 / 6
-def get_status(four_list, ten_list):
+
+def get_percent(four_list, ten_list):
four_score = 0
ten_score = 0
@@ -97,13 +102,13 @@ def get_status(four_list, ten_list):
else:
status = four_score + 1
- return get_percent(status)
+ return _get_percent(status)
def _test():
status = getScenarioStatus("compass", "master")
print "status:++++++++++++++++++++++++"
- print json.dumps(status,indent=4)
+ print json.dumps(status, indent=4)
if __name__ == '__main__': # pragma: no cover
diff --git a/utils/test/reporting/yardstick/scenarioResult.py b/utils/test/reporting/yardstick/scenarioResult.py
index 61ffb2ce7..1f7eb2b24 100644
--- a/utils/test/reporting/yardstick/scenarioResult.py
+++ b/utils/test/reporting/yardstick/scenarioResult.py
@@ -9,10 +9,12 @@
class ScenarioResult(object):
- def __init__(self, status, four_days_score='', ten_days_score=''):
+ def __init__(self, status, four_days_score='', ten_days_score='',
+ score_percent=0.0):
self.status = status
self.four_days_score = four_days_score
self.ten_days_score = ten_days_score
+ self.score_percent = score_percent
def getStatus(self):
return self.status
@@ -22,3 +24,6 @@ class ScenarioResult(object):
def getFourDaysScore(self):
return self.four_days_score
+
+ def getScorePercent(self):
+ return self.score_percent
diff --git a/utils/test/reporting/yardstick/template/index-status-tmpl.html b/utils/test/reporting/yardstick/template/index-status-tmpl.html
index 602ce8a74..5a4dc347c 100644
--- a/utils/test/reporting/yardstick/template/index-status-tmpl.html
+++ b/utils/test/reporting/yardstick/template/index-status-tmpl.html
@@ -3,9 +3,56 @@
<meta charset="utf-8">
<!-- Bootstrap core CSS -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
- <link href="default.css" rel="stylesheet">
+ <link href="../../../css/default.css" rel="stylesheet">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
+ <script type="text/javascript" src="http://d3js.org/d3.v2.min.js"></script>
+ <script type="text/javascript" src="../../../js/gauge.js"></script>
+ <script type="text/javascript" src="../../../js/trend.js"></script>
+ <script>
+ function onDocumentReady() {
+ // Gauge management
+ {% for scenario in scenario_results.keys() -%}
+ var gaugeScenario{{loop.index}} = gauge('#gaugeScenario{{loop.index}}');
+ {%- endfor %}
+ // assign success rate to the gauge
+ function updateReadings() {
+ {% for scenario in scenario_results.keys() -%}
+ gaugeScenario{{loop.index}}.update({{scenario_results[scenario].getScorePercent()}});
+ {%- endfor %}
+ }
+ updateReadings();
+ }
+
+ // trend line management
+ //d3.csv("./scenario_history.txt", function(data) {
+ d3.csv("./scenario_history.txt", function(data) {
+ // ***************************************
+ // Create the trend line
+ {% for scenario in scenario_results.keys() -%}
+ // for scenario {{scenario}}
+ // Filter results
+ var trend{{loop.index}} = data.filter(function(row) {
+ return row["scenario"]=="{{scenario}}" && row["installer"]=="{{installer}}";
+ })
+ // Parse the date
+ trend{{loop.index}}.forEach(function(d) {
+ d.date = parseDate(d.date);
+ d.score = +d.score
+ });
+ // Draw the trend line
+ var mytrend = trend("#trend_svg{{loop.index}}",trend{{loop.index}})
+ // ****************************************
+ {%- endfor %}
+ });
+ if ( !window.isLoaded ) {
+ window.addEventListener("load", function() {
+ onDocumentReady();
+ }, false);
+ } else {
+ onDocumentReady();
+ }
+ </script>
<script type="text/javascript">
$(document).ready(function (){
$(".btn-more").click(function() {
@@ -18,10 +65,10 @@
<body>
<div class="container">
<div class="masthead">
- <h3 class="text-muted">Yardstick status page ({{version}})</h3>
+ <h3 class="text-muted">Yardstick status page ({{version}}, {{date}})</h3>
<nav>
<ul class="nav nav-justified">
- <li class="active"><a href="index.html">Home</a></li>
+ <li class="active"><a href="http://testresults.opnfv.org/reporting/index.html">Home</a></li>
<li><a href="index-status-apex.html">Apex</a></li>
<li><a href="index-status-compass.html">Compass</a></li>
<li><a href="index-status-fuel.html">Fuel</a></li>
@@ -42,15 +89,15 @@
<tr>
<th width="40%">Scenario</th>
<th width="20%">Status</th>
- <th width="20%">Last 4 Iterations</th>
- <th width="20%">Last 10 Days</th>
+ <th width="20%">Trend</th>
+ <th width="10%">Last 4 Iterations</th>
+ <th width="10%">Last 10 Days</th>
</tr>
{% for scenario,result in scenario_results.iteritems() -%}
<tr class="tr-ok">
<td>{{scenario}}</td>
- <td>
- <img src="../../img/gauge_{{ scenario_results[scenario].getStatus() }}.png">
- </td>
+ <td><div id="gaugeScenario{{loop.index}}"></div></td>
+ <td><div id="trend_svg{{loop.index}}"></div></td>
<td>{{scenario_results[scenario].getFourDaysScore()}}</td>
<td>{{scenario_results[scenario].getTenDaysScore()}}</td>
</tr>
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/.gitignore b/utils/test/result_collection_api/3rd_party/static/.gitignore
index ebf4281dc..ebf4281dc 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/.gitignore
+++ b/utils/test/result_collection_api/3rd_party/static/.gitignore
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/css/highlight.default.css b/utils/test/result_collection_api/3rd_party/static/css/highlight.default.css
index e417fc179..e417fc179 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/css/highlight.default.css
+++ b/utils/test/result_collection_api/3rd_party/static/css/highlight.default.css
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/css/hightlight.default.css b/utils/test/result_collection_api/3rd_party/static/css/hightlight.default.css
index e417fc179..e417fc179 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/css/hightlight.default.css
+++ b/utils/test/result_collection_api/3rd_party/static/css/hightlight.default.css
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/css/screen.css b/utils/test/result_collection_api/3rd_party/static/css/screen.css
index 2882b8d66..2882b8d66 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/css/screen.css
+++ b/utils/test/result_collection_api/3rd_party/static/css/screen.css
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/endpoint.html b/utils/test/result_collection_api/3rd_party/static/endpoint.html
index 4ae3bde0c..4ae3bde0c 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/endpoint.html
+++ b/utils/test/result_collection_api/3rd_party/static/endpoint.html
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/images/explorer_icons.png b/utils/test/result_collection_api/3rd_party/static/images/explorer_icons.png
index ed9d2fffb..ed9d2fffb 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/images/explorer_icons.png
+++ b/utils/test/result_collection_api/3rd_party/static/images/explorer_icons.png
Binary files differ
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/images/logo_small.png b/utils/test/result_collection_api/3rd_party/static/images/logo_small.png
index 5496a6557..5496a6557 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/images/logo_small.png
+++ b/utils/test/result_collection_api/3rd_party/static/images/logo_small.png
Binary files differ
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/images/pet_store_api.png b/utils/test/result_collection_api/3rd_party/static/images/pet_store_api.png
index f9f9cd4ae..f9f9cd4ae 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/images/pet_store_api.png
+++ b/utils/test/result_collection_api/3rd_party/static/images/pet_store_api.png
Binary files differ
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/images/throbber.gif b/utils/test/result_collection_api/3rd_party/static/images/throbber.gif
index 063938892..063938892 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/images/throbber.gif
+++ b/utils/test/result_collection_api/3rd_party/static/images/throbber.gif
Binary files differ
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/images/wordnik_api.png b/utils/test/result_collection_api/3rd_party/static/images/wordnik_api.png
index dca4f1455..dca4f1455 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/images/wordnik_api.png
+++ b/utils/test/result_collection_api/3rd_party/static/images/wordnik_api.png
Binary files differ
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/index.html b/utils/test/result_collection_api/3rd_party/static/index.html
index db209f4a8..db209f4a8 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/index.html
+++ b/utils/test/result_collection_api/3rd_party/static/index.html
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/backbone-min.js b/utils/test/result_collection_api/3rd_party/static/lib/backbone-min.js
index c1c0d4fff..c1c0d4fff 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/backbone-min.js
+++ b/utils/test/result_collection_api/3rd_party/static/lib/backbone-min.js
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/handlebars-1.0.0.js b/utils/test/result_collection_api/3rd_party/static/lib/handlebars-1.0.0.js
index c70f09d1d..c70f09d1d 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/handlebars-1.0.0.js
+++ b/utils/test/result_collection_api/3rd_party/static/lib/handlebars-1.0.0.js
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/highlight.7.3.pack.js b/utils/test/result_collection_api/3rd_party/static/lib/highlight.7.3.pack.js
index 9a95a75ea..9a95a75ea 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/highlight.7.3.pack.js
+++ b/utils/test/result_collection_api/3rd_party/static/lib/highlight.7.3.pack.js
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/jquery-1.8.0.min.js b/utils/test/result_collection_api/3rd_party/static/lib/jquery-1.8.0.min.js
index 066d72c7e..066d72c7e 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/jquery-1.8.0.min.js
+++ b/utils/test/result_collection_api/3rd_party/static/lib/jquery-1.8.0.min.js
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/jquery.ba-bbq.min.js b/utils/test/result_collection_api/3rd_party/static/lib/jquery.ba-bbq.min.js
index bcbf24834..bcbf24834 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/jquery.ba-bbq.min.js
+++ b/utils/test/result_collection_api/3rd_party/static/lib/jquery.ba-bbq.min.js
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/jquery.slideto.min.js b/utils/test/result_collection_api/3rd_party/static/lib/jquery.slideto.min.js
index ba32cff36..ba32cff36 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/jquery.slideto.min.js
+++ b/utils/test/result_collection_api/3rd_party/static/lib/jquery.slideto.min.js
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/jquery.wiggle.min.js b/utils/test/result_collection_api/3rd_party/static/lib/jquery.wiggle.min.js
index 2adb0d6d5..2adb0d6d5 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/jquery.wiggle.min.js
+++ b/utils/test/result_collection_api/3rd_party/static/lib/jquery.wiggle.min.js
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/shred.bundle.js b/utils/test/result_collection_api/3rd_party/static/lib/shred.bundle.js
index 74d081689..74d081689 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/shred.bundle.js
+++ b/utils/test/result_collection_api/3rd_party/static/lib/shred.bundle.js
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/shred/content.js b/utils/test/result_collection_api/3rd_party/static/lib/shred/content.js
index b8051fedd..b8051fedd 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/shred/content.js
+++ b/utils/test/result_collection_api/3rd_party/static/lib/shred/content.js
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/swagger-oauth.js b/utils/test/result_collection_api/3rd_party/static/lib/swagger-oauth.js
index 7c8839a95..7c8839a95 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/swagger-oauth.js
+++ b/utils/test/result_collection_api/3rd_party/static/lib/swagger-oauth.js
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/swagger.js b/utils/test/result_collection_api/3rd_party/static/lib/swagger.js
index 78e8b2949..78e8b2949 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/swagger.js
+++ b/utils/test/result_collection_api/3rd_party/static/lib/swagger.js
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/underscore-min.js b/utils/test/result_collection_api/3rd_party/static/lib/underscore-min.js
index 5a0cb3b00..5a0cb3b00 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/lib/underscore-min.js
+++ b/utils/test/result_collection_api/3rd_party/static/lib/underscore-min.js
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/o2c.html b/utils/test/result_collection_api/3rd_party/static/o2c.html
index d32d130ec..d32d130ec 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/o2c.html
+++ b/utils/test/result_collection_api/3rd_party/static/o2c.html
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/swagger-ui.js b/utils/test/result_collection_api/3rd_party/static/swagger-ui.js
index 4c9922642..4c9922642 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/swagger-ui.js
+++ b/utils/test/result_collection_api/3rd_party/static/swagger-ui.js
diff --git a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/swagger-ui.min.js b/utils/test/result_collection_api/3rd_party/static/swagger-ui.min.js
index 28cb9e6a4..28cb9e6a4 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tornado_swagger/static/swagger-ui.min.js
+++ b/utils/test/result_collection_api/3rd_party/static/swagger-ui.min.js
diff --git a/utils/test/result_collection_api/README.rst b/utils/test/result_collection_api/README.rst
index c0075bc76..44ab2a475 100644
--- a/utils/test/result_collection_api/README.rst
+++ b/utils/test/result_collection_api/README.rst
@@ -25,7 +25,7 @@ How to install
From within your environment, just run:
- python setup.py install
+ ./install.sh
How to run
^^^^^^^^^^
diff --git a/utils/test/result_collection_api/install.sh b/utils/test/result_collection_api/install.sh
new file mode 100755
index 000000000..43229eabb
--- /dev/null
+++ b/utils/test/result_collection_api/install.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+usage="
+Script to install opnfv_tesgtapi automatically.
+This script should be run under root.
+
+usage:
+ bash $(basename "$0") [-h|--help] [-t <test_name>]
+
+where:
+ -h|--help show this help text"
+
+if [[ $(whoami) != "root" ]]; then
+ echo "Error: This script must be run as root!"
+ exit 1
+fi
+
+cp -fr 3rd_party/static opnfv_testapi/tornado_swagger
+python setup.py install
+rm -fr opnfv_testapi/tornado_swagger/static