summaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rwxr-xr-xutils/lab-reconfiguration/reconfigUcsNet.py2
-rw-r--r--utils/push-test-logs.sh2
-rw-r--r--utils/test/dashboard/js/opnfv_dashboard_tests_conf.js2
-rw-r--r--utils/test/reporting/functest/img/gauge_0.pngbin0 -> 3644 bytes
-rw-r--r--utils/test/reporting/functest/img/gauge_100.pngbin0 -> 3191 bytes
-rw-r--r--utils/test/reporting/functest/img/gauge_16.7.pngbin0 -> 3170 bytes
-rw-r--r--utils/test/reporting/functest/img/gauge_25.pngbin0 -> 3108 bytes
-rw-r--r--utils/test/reporting/functest/img/gauge_33.3.pngbin0 -> 3081 bytes
-rw-r--r--utils/test/reporting/functest/img/gauge_41.7.pngbin0 -> 3169 bytes
-rw-r--r--utils/test/reporting/functest/img/gauge_50.pngbin0 -> 3123 bytes
-rw-r--r--utils/test/reporting/functest/img/gauge_58.3.pngbin0 -> 3161 bytes
-rw-r--r--utils/test/reporting/functest/img/gauge_66.7.pngbin0 -> 3069 bytes
-rw-r--r--utils/test/reporting/functest/img/gauge_75.pngbin0 -> 3030 bytes
-rw-r--r--utils/test/reporting/functest/img/gauge_8.3.pngbin0 -> 2993 bytes
-rw-r--r--utils/test/reporting/functest/img/gauge_83.3.pngbin0 -> 3122 bytes
-rw-r--r--utils/test/reporting/functest/img/gauge_91.7.pngbin0 -> 3008 bytes
-rwxr-xr-xutils/test/reporting/functest/reporting-status.py10
-rw-r--r--utils/test/reporting/functest/scenarioResult.py7
-rw-r--r--utils/test/reporting/functest/template/index-status-tmpl.html38
-rw-r--r--utils/test/reporting/yardstick/reporting-status.py12
-rwxr-xr-xutils/test/result_collection_api/opnfv_testapi/dashboard/bottlenecks2Dashboard.py4
-rw-r--r--utils/test/result_collection_api/opnfv_testapi/dashboard/dashboard_utils.py10
-rw-r--r--utils/test/result_collection_api/opnfv_testapi/dashboard/doctor2Dashboard.py4
-rw-r--r--utils/test/result_collection_api/opnfv_testapi/dashboard/functest2Dashboard.py4
-rw-r--r--utils/test/result_collection_api/opnfv_testapi/dashboard/promise2Dashboard.py7
-rw-r--r--utils/test/result_collection_api/opnfv_testapi/dashboard/yardstick2Dashboard.py5
-rw-r--r--utils/test/result_collection_api/opnfv_testapi/resources/handlers.py5
-rw-r--r--utils/test/result_collection_api/opnfv_testapi/tests/unit/fake_pymongo.py4
-rw-r--r--utils/test/result_collection_api/opnfv_testapi/tests/unit/test_dashboard.py5
-rw-r--r--utils/test/result_collection_api/opnfv_testapi/tests/unit/test_fake_pymongo.py3
-rw-r--r--utils/test/result_collection_api/opnfv_testapi/tests/unit/test_result.py2
-rw-r--r--utils/test/result_collection_api/update/templates/changes_in_mongodb.py3
-rw-r--r--utils/test/result_collection_api/update/templates/update_mongodb.py9
-rw-r--r--utils/test/scripts/conf_utils.py20
-rw-r--r--utils/test/scripts/create_kibana_dashboards.py17
-rw-r--r--utils/test/scripts/kibana_cleanup.py2
-rw-r--r--utils/test/scripts/logger_utils.py65
-rw-r--r--utils/test/scripts/mongo2elastic_format.py179
-rw-r--r--utils/test/scripts/mongo_to_elasticsearch.py416
-rw-r--r--utils/test/scripts/shared_utils.py42
-rw-r--r--utils/test/scripts/testcases.yaml9
41 files changed, 467 insertions, 421 deletions
diff --git a/utils/lab-reconfiguration/reconfigUcsNet.py b/utils/lab-reconfiguration/reconfigUcsNet.py
index 45a72a398..4c08f3dc9 100755
--- a/utils/lab-reconfiguration/reconfigUcsNet.py
+++ b/utils/lab-reconfiguration/reconfigUcsNet.py
@@ -157,7 +157,7 @@ def read_yaml_file(yamlFile):
"""
# TODO: add check if vnic templates specified in file exist on UCS
with open(yamlFile, 'r') as stream:
- return yaml.load(stream)
+ return yaml.safe_load(stream)
def set_network(handle=None, yamlFile=None):
diff --git a/utils/push-test-logs.sh b/utils/push-test-logs.sh
index 0fa882bc9..f24d884f5 100644
--- a/utils/push-test-logs.sh
+++ b/utils/push-test-logs.sh
@@ -24,7 +24,7 @@ node_list=(\
'lf-pod1' 'lf-pod2' 'intel-pod2' 'intel-pod3' \
'intel-pod5' 'intel-pod6' 'intel-pod7' 'intel-pod8' \
'ericsson-pod2' \
-'arm-pod1' \
+'arm-pod1' 'arm-pod3' \
'huawei-pod1' 'huawei-pod2' 'huawei-virtual1' 'huawei-virtual2' 'huawei-virtual3' 'huawei-virtual4')
diff --git a/utils/test/dashboard/js/opnfv_dashboard_tests_conf.js b/utils/test/dashboard/js/opnfv_dashboard_tests_conf.js
index 870357c6d..a46332579 100644
--- a/utils/test/dashboard/js/opnfv_dashboard_tests_conf.js
+++ b/utils/test/dashboard/js/opnfv_dashboard_tests_conf.js
@@ -56,7 +56,7 @@ var opnfv_dashboard_testcases = {
var opnfv_dashboard_installers_pods = {};
opnfv_dashboard_installers_pods['apex'] = ['all','intel-pod7','opnfv-jump-1'];
opnfv_dashboard_installers_pods['compass'] = ['all','huawei-us-deploy-bare-1','huawei-us-deploy-vm-1','huawei-us-deploy-vm2','intel-pod8'];
-opnfv_dashboard_installers_pods['fuel'] = ['all','ericsson-pod2','opnfv-jump-2','arm-pod1','zte-pod1'];
+opnfv_dashboard_installers_pods['fuel'] = ['all','ericsson-pod2','opnfv-jump-2','arm-pod1','arm-pod3','zte-pod1'];
opnfv_dashboard_installers_pods['joid'] = ['all','intel-pod5','intel-pod6','orange-fr-pod2'];
var opnfv_dashboard_installers_pods_print = {};
diff --git a/utils/test/reporting/functest/img/gauge_0.png b/utils/test/reporting/functest/img/gauge_0.png
new file mode 100644
index 000000000..ecefc0e66
--- /dev/null
+++ b/utils/test/reporting/functest/img/gauge_0.png
Binary files differ
diff --git a/utils/test/reporting/functest/img/gauge_100.png b/utils/test/reporting/functest/img/gauge_100.png
new file mode 100644
index 000000000..e199e1561
--- /dev/null
+++ b/utils/test/reporting/functest/img/gauge_100.png
Binary files differ
diff --git a/utils/test/reporting/functest/img/gauge_16.7.png b/utils/test/reporting/functest/img/gauge_16.7.png
new file mode 100644
index 000000000..3e3993c3b
--- /dev/null
+++ b/utils/test/reporting/functest/img/gauge_16.7.png
Binary files differ
diff --git a/utils/test/reporting/functest/img/gauge_25.png b/utils/test/reporting/functest/img/gauge_25.png
new file mode 100644
index 000000000..4923659b9
--- /dev/null
+++ b/utils/test/reporting/functest/img/gauge_25.png
Binary files differ
diff --git a/utils/test/reporting/functest/img/gauge_33.3.png b/utils/test/reporting/functest/img/gauge_33.3.png
new file mode 100644
index 000000000..364574b4a
--- /dev/null
+++ b/utils/test/reporting/functest/img/gauge_33.3.png
Binary files differ
diff --git a/utils/test/reporting/functest/img/gauge_41.7.png b/utils/test/reporting/functest/img/gauge_41.7.png
new file mode 100644
index 000000000..8c3e910fa
--- /dev/null
+++ b/utils/test/reporting/functest/img/gauge_41.7.png
Binary files differ
diff --git a/utils/test/reporting/functest/img/gauge_50.png b/utils/test/reporting/functest/img/gauge_50.png
new file mode 100644
index 000000000..2874b9fcf
--- /dev/null
+++ b/utils/test/reporting/functest/img/gauge_50.png
Binary files differ
diff --git a/utils/test/reporting/functest/img/gauge_58.3.png b/utils/test/reporting/functest/img/gauge_58.3.png
new file mode 100644
index 000000000..beedc8aa9
--- /dev/null
+++ b/utils/test/reporting/functest/img/gauge_58.3.png
Binary files differ
diff --git a/utils/test/reporting/functest/img/gauge_66.7.png b/utils/test/reporting/functest/img/gauge_66.7.png
new file mode 100644
index 000000000..93f44d133
--- /dev/null
+++ b/utils/test/reporting/functest/img/gauge_66.7.png
Binary files differ
diff --git a/utils/test/reporting/functest/img/gauge_75.png b/utils/test/reporting/functest/img/gauge_75.png
new file mode 100644
index 000000000..9fc261ff8
--- /dev/null
+++ b/utils/test/reporting/functest/img/gauge_75.png
Binary files differ
diff --git a/utils/test/reporting/functest/img/gauge_8.3.png b/utils/test/reporting/functest/img/gauge_8.3.png
new file mode 100644
index 000000000..59f86571e
--- /dev/null
+++ b/utils/test/reporting/functest/img/gauge_8.3.png
Binary files differ
diff --git a/utils/test/reporting/functest/img/gauge_83.3.png b/utils/test/reporting/functest/img/gauge_83.3.png
new file mode 100644
index 000000000..27ae4ec54
--- /dev/null
+++ b/utils/test/reporting/functest/img/gauge_83.3.png
Binary files differ
diff --git a/utils/test/reporting/functest/img/gauge_91.7.png b/utils/test/reporting/functest/img/gauge_91.7.png
new file mode 100644
index 000000000..280865714
--- /dev/null
+++ b/utils/test/reporting/functest/img/gauge_91.7.png
Binary files differ
diff --git a/utils/test/reporting/functest/reporting-status.py b/utils/test/reporting/functest/reporting-status.py
index e9e167d16..ef567f17d 100755
--- a/utils/test/reporting/functest/reporting-status.py
+++ b/utils/test/reporting/functest/reporting-status.py
@@ -34,7 +34,7 @@ tempest = tc.TestCase("tempest_smoke_serial", "functest", -1)
cf = conf.TEST_CONF
response = requests.get(cf)
-functest_yaml_config = yaml.load(response.text)
+functest_yaml_config = yaml.safe_load(response.text)
logger.info("*******************************************")
logger.info("* Generating reporting scenario status *")
@@ -175,6 +175,8 @@ for version in conf.versions:
scenario_criteria = conf.MAX_SCENARIO_CRITERIA
s_score = str(scenario_score) + "/" + str(scenario_criteria)
+ s_score_percent = float(
+ scenario_score) / float(scenario_criteria) * 100
s_status = "KO"
if scenario_score < scenario_criteria:
logger.info(">>>> scenario not OK, score = %s/%s" %
@@ -191,11 +193,13 @@ for version in conf.versions:
";" + installer + ";" + s + "\n")
f.write(info)
- scenario_result_criteria[s] = sr.ScenarioResult(s_status, s_score)
+ scenario_result_criteria[s] = sr.ScenarioResult(s_status, s_score,
+ s_score_percent)
logger.info("--------------------------")
templateLoader = jinja2.FileSystemLoader(conf.REPORTING_PATH)
- templateEnv = jinja2.Environment(loader=templateLoader, autoescape=True)
+ templateEnv = jinja2.Environment(
+ loader=templateLoader, autoescape=True)
TEMPLATE_FILE = "/template/index-status-tmpl.html"
template = templateEnv.get_template(TEMPLATE_FILE)
diff --git a/utils/test/reporting/functest/scenarioResult.py b/utils/test/reporting/functest/scenarioResult.py
index 743346adc..c6c337330 100644
--- a/utils/test/reporting/functest/scenarioResult.py
+++ b/utils/test/reporting/functest/scenarioResult.py
@@ -9,12 +9,17 @@
class ScenarioResult(object):
- def __init__(self, status, score=0):
+
+ def __init__(self, status, score=0, score_percent=0):
self.status = status
self.score = score
+ self.score_percent = score_percent
def getStatus(self):
return self.status
def getScore(self):
return self.score
+
+ def getScorePercent(self):
+ return self.score_percent \ No newline at end of file
diff --git a/utils/test/reporting/functest/template/index-status-tmpl.html b/utils/test/reporting/functest/template/index-status-tmpl.html
index da2213bc0..96240de5b 100644
--- a/utils/test/reporting/functest/template/index-status-tmpl.html
+++ b/utils/test/reporting/functest/template/index-status-tmpl.html
@@ -48,11 +48,33 @@
{% for scenario,iteration in scenario_stats.iteritems() -%}
<tr class="tr-ok">
<td>{{scenario}}</td>
- <td>{%if scenario_results[scenario].getStatus() is sameas "OK" -%}
- <img src="../../img/icon-ok.png">
- {%- else -%}
- <img src="../../img/icon-nok.png">
- {%- endif %}</td>
+ <td>{%if scenario_results[scenario].getScorePercent() < 8.3 -%}
+ <img src="../../img/gauge_0.png">
+ {%elif scenario_results[scenario].getScorePercent() < 16.7 -%}
+ <img src="../../img/gauge_8.3.png">
+ {%elif scenario_results[scenario].getScorePercent() < 25 -%}
+ <img src="../../img/gauge_16.7.png">
+ {%elif scenario_results[scenario].getScorePercent() < 33.3 -%}
+ <img src="../../img/gauge_25.png">
+ {%elif scenario_results[scenario].getScorePercent() < 41.7 -%}
+ <img src="../../img/gauge_33.3.png">
+ {%elif scenario_results[scenario].getScorePercent() < 50 -%}
+ <img src="../../img/gauge_41.7.png">
+ {%elif scenario_results[scenario].getScorePercent() < 58.3 -%}
+ <img src="../../img/gauge_50.png">
+ {%elif scenario_results[scenario].getScorePercent() < 66.7 -%}
+ <img src="../../img/gauge_58.3.png">
+ {%elif scenario_results[scenario].getScorePercent() < 75 -%}
+ <img src="../../img/gauge_66.7.png">
+ {%elif scenario_results[scenario].getScorePercent() < 83.3 -%}
+ <img src="../../img/gauge_75.png">
+ {%elif scenario_results[scenario].getScorePercent() < 91.7 -%}
+ <img src="../../img/gauge_83.3.png">
+ {%elif scenario_results[scenario].getScorePercent() < 100 -%}
+ <img src="../../img/gauge_91.7.png">
+ {%- else -%}
+ <img src="../../img/gauge_100.png">
+ {%- endif %}</td>
<td>{{scenario_results[scenario].getScore()}}</td>
<td>{{iteration}}</td>
</tr>
@@ -78,14 +100,14 @@
{% if test.getCriteria() > -1 -%}
{{test.getDisplayName() }}
{%- endif %}
- {% if test.getTier() > 3 -%}
+ {% if test.getTier() > 3 -%}
*
{%- endif %}
- </th>
+ </th>
{%- endfor %}
</tr>
<tr class="tr-weather-weather">
- {% for test in items[scenario] -%}
+ {% for test in items[scenario] -%}
{% if test.getCriteria() > 2 -%}
<td><img src="../../img/weather-clear.png"></td>
{%- elif test.getCriteria() > 1 -%}
diff --git a/utils/test/reporting/yardstick/reporting-status.py b/utils/test/reporting/yardstick/reporting-status.py
index 546bf08c4..57a95947b 100644
--- a/utils/test/reporting/yardstick/reporting-status.py
+++ b/utils/test/reporting/yardstick/reporting-status.py
@@ -32,6 +32,14 @@ for version in conf.versions:
for installer in conf.installers:
# 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):
+ scenario_results[k] = []
+ scenario_results[k] += stable_result[k]
+ for k,v in scenario_results.items():
+ scenario_results[k] = v[0:conf.LASTEST_TESTS]
scenario_result_criteria = {}
# From each scenarios get results list
@@ -44,10 +52,10 @@ for version in conf.versions:
scenario_score = 0
for v in s_result:
- if v['details'] == 'SUCCESS':
+ if v['criteria'] == 'SUCCESS':
scenario_score += 1
- if scenario_score == scenario_criteria:
+ if scenario_score == scenario_criteria and scenario_criteria == 4:
s_status = 'OK'
logger.info(">>>>> scenario OK, save the information")
else:
diff --git a/utils/test/result_collection_api/opnfv_testapi/dashboard/bottlenecks2Dashboard.py b/utils/test/result_collection_api/opnfv_testapi/dashboard/bottlenecks2Dashboard.py
index 2e106bec8..f5e3d9a6e 100755
--- a/utils/test/result_collection_api/opnfv_testapi/dashboard/bottlenecks2Dashboard.py
+++ b/utils/test/result_collection_api/opnfv_testapi/dashboard/bottlenecks2Dashboard.py
@@ -48,8 +48,8 @@ def format_bottlenecks_for_dashboard(case, results):
then build the call to the specific method
"""
if check_bottlenecks_case_exist(case):
- cmd = "format_" + case + "_for_dashboard(results)"
- res = eval(cmd)
+ cmd = "format_" + case + "_for_dashboard"
+ res = globals()[cmd](results)
else:
res = []
print "Test cases not declared"
diff --git a/utils/test/result_collection_api/opnfv_testapi/dashboard/dashboard_utils.py b/utils/test/result_collection_api/opnfv_testapi/dashboard/dashboard_utils.py
index 121875d02..42c635846 100644
--- a/utils/test/result_collection_api/opnfv_testapi/dashboard/dashboard_utils.py
+++ b/utils/test/result_collection_api/opnfv_testapi/dashboard/dashboard_utils.py
@@ -14,7 +14,6 @@
#
# v0.1: basic example
#
-import os
import re
import sys
from functest2Dashboard import format_functest_for_dashboard, \
@@ -47,8 +46,8 @@ def check_dashboard_ready_project(test_project):
def check_dashboard_ready_case(project, case):
- cmd = "check_" + project + "_case_exist(case)"
- return eval(cmd)
+ cmd = "check_" + project + "_case_exist"
+ return globals()[cmd](case)
def get_dashboard_projects():
@@ -73,6 +72,5 @@ def get_dashboard_result(project, case, results=None):
# project: project name
# results: array of raw results pre-filterded
# according to the parameters of the request
- cmd = "format_" + project + "_for_dashboard(case,results)"
- res = eval(cmd)
- return res
+ cmd = "format_" + project + "_for_dashboard"
+ return globals()[cmd](case, results)
diff --git a/utils/test/result_collection_api/opnfv_testapi/dashboard/doctor2Dashboard.py b/utils/test/result_collection_api/opnfv_testapi/dashboard/doctor2Dashboard.py
index 38b23abb4..5b1f190a9 100644
--- a/utils/test/result_collection_api/opnfv_testapi/dashboard/doctor2Dashboard.py
+++ b/utils/test/result_collection_api/opnfv_testapi/dashboard/doctor2Dashboard.py
@@ -36,8 +36,8 @@ def format_doctor_for_dashboard(case, results):
# note we add _case because testcase and project had the same name
# TODO refactoring...looks fine at the beginning wit only 1 project
# not very ugly now and clearly not optimized...
- cmd = "format_" + case.replace('-','_') + "_case_for_dashboard(results)"
- res = eval(cmd)
+ cmd = "format_" + case.replace('-','_') + "_case_for_dashboard"
+ res = globals()[cmd](results)
else:
res = []
return res
diff --git a/utils/test/result_collection_api/opnfv_testapi/dashboard/functest2Dashboard.py b/utils/test/result_collection_api/opnfv_testapi/dashboard/functest2Dashboard.py
index 86521b984..01697f73b 100644
--- a/utils/test/result_collection_api/opnfv_testapi/dashboard/functest2Dashboard.py
+++ b/utils/test/result_collection_api/opnfv_testapi/dashboard/functest2Dashboard.py
@@ -34,8 +34,8 @@ def format_functest_for_dashboard(case, results):
then build the call to the specific method
"""
if check_functest_case_exist(case):
- cmd = "format_" + case + "_for_dashboard(results)"
- res = eval(cmd)
+ cmd = "format_" + case + "_for_dashboard"
+ res = globals()[cmd](results)
else:
res = []
print "Test cases not declared"
diff --git a/utils/test/result_collection_api/opnfv_testapi/dashboard/promise2Dashboard.py b/utils/test/result_collection_api/opnfv_testapi/dashboard/promise2Dashboard.py
index 84f43a7d1..c96341f6d 100644
--- a/utils/test/result_collection_api/opnfv_testapi/dashboard/promise2Dashboard.py
+++ b/utils/test/result_collection_api/opnfv_testapi/dashboard/promise2Dashboard.py
@@ -14,9 +14,6 @@
# a new method format_<Test_case>_for_dashboard(results)
# v0.1: basic example with methods for odl, Tempest, Rally and vPing
#
-import re
-import datetime
-
def get_promise_cases():
"""
@@ -36,8 +33,8 @@ def format_promise_for_dashboard(case, results):
# note we add _case because testcase and project had the same name
# TODO refactoring...looks fine at the beginning wit only 1 project
# not very ugly now and clearly not optimized...
- cmd = "format_" + case + "_case_for_dashboard(results)"
- res = eval(cmd)
+ cmd = "format_" + case + "_case_for_dashboard"
+ res = globals()[cmd](results)
else:
res = []
print "Test cases not declared"
diff --git a/utils/test/result_collection_api/opnfv_testapi/dashboard/yardstick2Dashboard.py b/utils/test/result_collection_api/opnfv_testapi/dashboard/yardstick2Dashboard.py
index 4f022d5b9..4df4b5007 100644
--- a/utils/test/result_collection_api/opnfv_testapi/dashboard/yardstick2Dashboard.py
+++ b/utils/test/result_collection_api/opnfv_testapi/dashboard/yardstick2Dashboard.py
@@ -16,7 +16,6 @@
# Fio, Lmbench, Perf, Cyclictest.
#
-
def get_yardstick_cases():
"""
get the list of the supported test cases
@@ -33,8 +32,8 @@ def format_yardstick_for_dashboard(case, results):
then build the call to the specific method
"""
if check_yardstick_case_exist(case):
- cmd = "format_" + case + "_for_dashboard(results)"
- res = eval(cmd)
+ cmd = "format_" + case + "_for_dashboard"
+ res = globals()[cmd](results)
else:
res = []
print "Test cases not declared"
diff --git a/utils/test/result_collection_api/opnfv_testapi/resources/handlers.py b/utils/test/result_collection_api/opnfv_testapi/resources/handlers.py
index f98c35e8f..5059f5d77 100644
--- a/utils/test/result_collection_api/opnfv_testapi/resources/handlers.py
+++ b/utils/test/result_collection_api/opnfv_testapi/resources/handlers.py
@@ -23,8 +23,8 @@
import json
from datetime import datetime
-from tornado.web import RequestHandler, asynchronous, HTTPError
from tornado import gen
+from tornado.web import RequestHandler, asynchronous, HTTPError
from models import CreateResponse
from opnfv_testapi.common.constants import DEFAULT_REPRESENTATION, \
@@ -217,7 +217,8 @@ class GenericApiHandler(RequestHandler):
return equal, query
def _eval_db(self, table, method, *args, **kwargs):
- return eval('self.db.%s.%s(*args, **kwargs)' % (table, method))
+ exec_collection = self.db.__getattr__(table)
+ return exec_collection.__getattribute__(method)(*args, **kwargs)
def _eval_db_find_one(self, query, table=None):
if table is None:
diff --git a/utils/test/result_collection_api/opnfv_testapi/tests/unit/fake_pymongo.py b/utils/test/result_collection_api/opnfv_testapi/tests/unit/fake_pymongo.py
index 450969248..3dd87e603 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tests/unit/fake_pymongo.py
+++ b/utils/test/result_collection_api/opnfv_testapi/tests/unit/fake_pymongo.py
@@ -181,6 +181,10 @@ class MemDb(object):
self._check_keys(doc.get(key))
+def __getattr__(name):
+ return globals()[name]
+
+
pods = MemDb()
projects = MemDb()
testcases = MemDb()
diff --git a/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_dashboard.py b/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_dashboard.py
index 8f729c0d0..27ec76385 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_dashboard.py
+++ b/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_dashboard.py
@@ -8,9 +8,10 @@
##############################################################################
import unittest
-from test_result import TestResultBase
from opnfv_testapi.common.constants import HTTP_NOT_FOUND, HTTP_OK
+from test_result import TestResultBase
+
class TestDashboardBase(TestResultBase):
def setUp(self):
@@ -63,7 +64,7 @@ class TestDashboardQuery(TestDashboardBase):
if k == 'self' or k == 'uri':
continue
if v is None:
- v = eval('self.' + k)
+ v = self.__getattribute__(k)
if v != 'missing':
uri += '{}={}&'.format(k, v)
uri += 'pod={}&'.format(self.pod)
diff --git a/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_fake_pymongo.py b/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_fake_pymongo.py
index 9a1253e94..5f50ba867 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_fake_pymongo.py
+++ b/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_fake_pymongo.py
@@ -115,7 +115,8 @@ class MyTest(AsyncHTTPTestCase):
self.assertEqual(name_error, error)
def _eval_pods_db(self, method, *args, **kwargs):
- return eval('self.db.pods.%s(*args, **kwargs)' % method)
+ table_obj = vars(self.db)['pods']
+ return table_obj.__getattribute__(method)(*args, **kwargs)
if __name__ == '__main__':
diff --git a/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_result.py b/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_result.py
index eee06c6e5..8479b35cd 100644
--- a/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_result.py
+++ b/utils/test/result_collection_api/opnfv_testapi/tests/unit/test_result.py
@@ -305,7 +305,7 @@ class TestResultGet(TestResultBase):
def _set_query(self, *args):
def get_value(arg):
- return eval('self.' + arg) \
+ return self.__getattribute__(arg) \
if arg != 'trust_indicator' else self.trust_indicator.current
uri = ''
for arg in args:
diff --git a/utils/test/result_collection_api/update/templates/changes_in_mongodb.py b/utils/test/result_collection_api/update/templates/changes_in_mongodb.py
index 9744dd9fe..1a4d5a16f 100644
--- a/utils/test/result_collection_api/update/templates/changes_in_mongodb.py
+++ b/utils/test/result_collection_api/update/templates/changes_in_mongodb.py
@@ -45,6 +45,7 @@ docs_old2New = {
# ({'case_name': 'ovno'}, {'case_name': 'ocl'})
# ]
'results': [
- ({'trust_indicator': 0}, {'trust_indicator': {'current': 0, 'histories': []}})
+ ({'trust_indicator': 0},
+ {'trust_indicator': {'current': 0, 'histories': []}})
]
}
diff --git a/utils/test/result_collection_api/update/templates/update_mongodb.py b/utils/test/result_collection_api/update/templates/update_mongodb.py
index b1e378dd7..ba4334aa3 100644
--- a/utils/test/result_collection_api/update/templates/update_mongodb.py
+++ b/utils/test/result_collection_api/update/templates/update_mongodb.py
@@ -10,7 +10,8 @@ import argparse
from pymongo import MongoClient
-from changes_in_mongodb import collections_old2New, fields_old2New, docs_old2New
+from changes_in_mongodb import collections_old2New, \
+ fields_old2New, docs_old2New
from utils import main, parse_mongodb_url
parser = argparse.ArgumentParser(description='Update MongoDBs')
@@ -54,11 +55,13 @@ def change_docs(a_dict):
def eval_db(method, *args, **kwargs):
- return eval('db.%s(*args, **kwargs)' % method)
+ exec_db = db.__getattribute__(method)
+ return exec_db(*args, **kwargs)
def eval_collection(collection, method, *args, **kwargs):
- return eval('db.%s.%s(*args, **kwargs)' % (collection, method))
+ exec_collection = db.__getattr__(collection)
+ return exec_collection.__getattribute__(method)(*args, **kwargs)
def collection_update(a_dict, operator):
diff --git a/utils/test/scripts/conf_utils.py b/utils/test/scripts/conf_utils.py
new file mode 100644
index 000000000..e35d5ed10
--- /dev/null
+++ b/utils/test/scripts/conf_utils.py
@@ -0,0 +1,20 @@
+import yaml
+
+
+with open('./testcases.yaml') as f:
+ testcases_yaml = yaml.safe_load(f)
+f.close()
+
+
+def get_format(project, case):
+ testcases = testcases_yaml.get(project)
+ if isinstance(testcases, list):
+ for case_dict in testcases:
+ if case_dict['name'] == case:
+ return 'format_' + case_dict['format'].strip()
+ return None
+
+
+if __name__ == '__main__':
+ fmt = get_format('functest', 'vping_ssh')
+ print fmt \ No newline at end of file
diff --git a/utils/test/scripts/create_kibana_dashboards.py b/utils/test/scripts/create_kibana_dashboards.py
index abb9471ac..efa6e177e 100644
--- a/utils/test/scripts/create_kibana_dashboards.py
+++ b/utils/test/scripts/create_kibana_dashboards.py
@@ -1,18 +1,14 @@
#! /usr/bin/env python
import json
-import logging
import urlparse
import argparse
-import yaml
+import conf_utils
+import logger_utils
import shared_utils
-logger = logging.getLogger('create_kibana_dashboards')
-logger.setLevel(logging.DEBUG)
-file_handler = logging.FileHandler('./{}.log'.format('create_kibana_dashboards'))
-file_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s'))
-logger.addHandler(file_handler)
+logger = logger_utils.KibanaDashboardLogger('elastic2kibana').get
_installers = {'fuel', 'apex', 'compass', 'joid'}
@@ -277,7 +273,7 @@ def _get_pods_and_scenarios(project_name, case_name, installer):
}
})
- elastic_data = shared_utils.get_elastic_data(urlparse.urljoin(base_elastic_url, '/test_results/mongo2elastic'),
+ elastic_data = shared_utils.get_elastic_docs(urlparse.urljoin(base_elastic_url, '/test_results/mongo2elastic'),
es_creds, query_json)
pods_and_scenarios = {}
@@ -307,10 +303,7 @@ def construct_dashboards():
:return: list of KibanaDashboards
"""
kibana_dashboards = []
- with open('./testcases.yaml') as f:
- testcases_yaml = yaml.safe_load(f)
-
- for project, case_dicts in testcases_yaml.items():
+ for project, case_dicts in conf_utils.testcases_yaml.items():
for case in case_dicts:
case_name = case.get('name')
visualizations = case.get('visualizations')
diff --git a/utils/test/scripts/kibana_cleanup.py b/utils/test/scripts/kibana_cleanup.py
index e8d452af2..e699db43c 100644
--- a/utils/test/scripts/kibana_cleanup.py
+++ b/utils/test/scripts/kibana_cleanup.py
@@ -13,7 +13,7 @@ logger.addHandler(file_handler)
def delete_all(url, es_creds):
- ids = shared_utils.get_elastic_data(url, es_creds, body=None, field='_id')
+ ids = shared_utils.get_elastic_docs(url, es_creds, body=None, field='_id')
for id in ids:
del_url = '/'.join([url, id])
shared_utils.delete_request(del_url, es_creds)
diff --git a/utils/test/scripts/logger_utils.py b/utils/test/scripts/logger_utils.py
new file mode 100644
index 000000000..25d28a582
--- /dev/null
+++ b/utils/test/scripts/logger_utils.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+#
+# feng.xiaowei@zte.com.cn
+# 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 functest_logger as fl
+# 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(object):
+ file_path = '/var/log'
+ formatter = logging.Formatter('%(asctime)s - %(name)s - '
+ '%(levelname)s - %(message)s')
+
+ def __init__(self, logger_name):
+
+ IF_DEBUG = os.getenv('IF_DEBUG')
+
+ self.logger_name = logger_name
+ self.logger = logging.getLogger(logger_name)
+ self.logger.propagate = 0
+ self.logger.setLevel(logging.DEBUG)
+
+ ch = logging.StreamHandler()
+ ch.setFormatter(self.formatter)
+ if IF_DEBUG is not None and IF_DEBUG.lower() == "true":
+ ch.setLevel(logging.DEBUG)
+ else:
+ ch.setLevel(logging.INFO)
+ self.logger.addHandler(ch)
+
+ hdlr = logging.FileHandler('%s/%s.log' % (self.file_path, logger_name))
+ hdlr.setFormatter(self.formatter)
+ hdlr.setLevel(logging.DEBUG)
+ self.logger.addHandler(hdlr)
+
+ @property
+ def get(self):
+ return self.logger
+
+
+class KibanaDashboardLogger(Logger):
+ file_path = '/var/log/kibana_dashboard'
+
+ def __init__(self, logger_name):
+ super(KibanaDashboardLogger, self).__init__(logger_name)
+
diff --git a/utils/test/scripts/mongo2elastic_format.py b/utils/test/scripts/mongo2elastic_format.py
new file mode 100644
index 000000000..0b036e3ff
--- /dev/null
+++ b/utils/test/scripts/mongo2elastic_format.py
@@ -0,0 +1,179 @@
+#! /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
+ """
+ summary = testcase['details']['summary']
+
+ 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
diff --git a/utils/test/scripts/mongo_to_elasticsearch.py b/utils/test/scripts/mongo_to_elasticsearch.py
index ded58ef4c..b722793b3 100644
--- a/utils/test/scripts/mongo_to_elasticsearch.py
+++ b/utils/test/scripts/mongo_to_elasticsearch.py
@@ -1,7 +1,6 @@
#! /usr/bin/env python
import datetime
import json
-import logging
import os
import subprocess
import traceback
@@ -10,266 +9,33 @@ import uuid
import argparse
+import conf_utils
+import logger_utils
+import mongo2elastic_format
import shared_utils
-logger = logging.getLogger('mongo_to_elasticsearch')
-logger.setLevel(logging.DEBUG)
-file_handler = logging.FileHandler('/var/log/{}.log'.format('mongo_to_elasticsearch'))
-file_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s'))
-logger.addHandler(file_handler)
+logger = logger_utils.KibanaDashboardLogger('mongo2elastic').get
+parser = argparse.ArgumentParser(description='Modify and filter mongo json data for elasticsearch')
+parser.add_argument('-od', '--output-destination',
+ default='elasticsearch',
+ choices=('elasticsearch', 'stdout'),
+ help='defaults to elasticsearch')
-def _get_dicts_from_list(testcase, dict_list, keys):
- dicts = []
- for dictionary in dict_list:
- # iterate over dictionaries in input list
- if not isinstance(dictionary, dict):
- logger.info("Skipping non-dict details testcase '{}'".format(testcase))
- continue
- if keys == set(dictionary.keys()):
- # check the dictionary structure
- dicts.append(dictionary)
- return dicts
+parser.add_argument('-ml', '--merge-latest', default=0, type=int, metavar='N',
+ help='get entries old at most N days from mongodb and'
+ ' parse those that are not already in elasticsearch.'
+ ' If not present, will get everything from mongodb, which is the default')
+parser.add_argument('-e', '--elasticsearch-url', default='http://localhost:9200',
+ help='the url of elasticsearch, defaults to http://localhost:9200')
-def _get_results_from_list_of_dicts(list_of_dict_statuses, dict_indexes, expected_results=None):
- test_results = {}
- for test_status in list_of_dict_statuses:
- status = test_status
- for index in dict_indexes:
- status = status[index]
- if status in test_results:
- test_results[status] += 1
- else:
- test_results[status] = 1
-
- if expected_results is not None:
- for expected_result in expected_results:
- if expected_result not in test_results:
- test_results[expected_result] = 0
-
- return test_results
-
-
-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 modify_functest_tempest(testcase):
- if modify_default_entry(testcase):
- testcase_details = 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 True
- else:
- return False
-
-
-def modify_functest_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']
- sig_test_results = _get_dicts_from_list(testcase, testcase_details['sig_test']['result'],
- {'duration', 'result', 'name', 'error'})
- if len(sig_test_results) < 1:
- logger.info("No 'result' from 'sig_test' found in vIMS details, skipping")
- return False
- else:
- test_results = _get_results_from_list_of_dicts(sig_test_results, ('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 modify_functest_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:
- return modify_default_entry(testcase)
-
- funcvirnet_details = testcase_details['FUNCvirNet']['status']
- funcvirnet_statuses = _get_dicts_from_list(testcase, funcvirnet_details, {'Case result', 'Case name:'})
-
- funcvirnetl3_details = testcase_details['FUNCvirNetL3']['status']
- funcvirnetl3_statuses = _get_dicts_from_list(testcase, funcvirnetl3_details, {'Case result', 'Case name:'})
-
- if len(funcvirnet_statuses) < 0:
- logger.info("No results found in 'FUNCvirNet' part of ONOS results")
- return False
- elif len(funcvirnetl3_statuses) < 0:
- logger.info("No results found in 'FUNCvirNetL3' part of ONOS results")
- return False
- else:
- funcvirnet_results = _get_results_from_list_of_dicts(funcvirnet_statuses,
- ('Case result',), ('PASS', 'FAIL'))
- funcvirnetl3_results = _get_results_from_list_of_dicts(funcvirnetl3_statuses,
- ('Case result',), ('PASS', 'FAIL'))
-
- funcvirnet_passed = funcvirnet_results['PASS']
- funcvirnet_failed = funcvirnet_results['FAIL']
- funcvirnet_all = funcvirnet_passed + funcvirnet_failed
-
- funcvirnetl3_passed = funcvirnetl3_results['PASS']
- funcvirnetl3_failed = funcvirnetl3_results['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 modify_functest_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
- """
- summaries = _get_dicts_from_list(testcase, testcase['details'], {'summary'})
-
- if len(summaries) != 1:
- logger.info("Found zero or more than one 'summaries' in Rally details, skipping")
- return False
- else:
- summary = summaries[0]['summary']
- testcase['details'] = {
- 'duration': summary['duration'],
- 'tests': summary['nb tests'],
- 'success_percentage': summary['nb success']
- }
- return True
+parser.add_argument('-u', '--elasticsearch-username', default=None,
+ help='The username with password for elasticsearch in format username:password')
+args = parser.parse_args()
-def modify_functest_odl(testcase):
- """
- Structure:
- details.details.[{test_status.@status}]
-
- Find data for these fields
- -> details.tests
- -> details.failures
- -> details.success_percentage?
- """
- test_statuses = _get_dicts_from_list(testcase, testcase['details']['details'],
- {'test_status', 'test_doc', 'test_name'})
- if len(test_statuses) < 1:
- logger.info("No 'test_status' found in ODL details, skipping")
- return False
- else:
- test_results = _get_results_from_list_of_dicts(test_statuses, ('test_status', '@status'), ('PASS', 'FAIL'))
-
- passed_tests = test_results['PASS']
- failed_tests = test_results['FAIL']
- all_tests = passed_tests + failed_tests
-
- testcase['details'] = {
- 'tests': all_tests,
- 'failures': failed_tests,
- 'success_percentage': 100 * passed_tests / float(all_tests)
- }
- logger.debug("Modified odl testcase: '{}'".format(json.dumps(testcase, indent=2)))
- return True
-
-
-def modify_default_entry(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]
-
- return found
+tmp_docs_file = './mongo-{}.json'.format(uuid.uuid4())
def _fix_date(date_string):
@@ -279,7 +45,7 @@ def _fix_date(date_string):
return date_string[:-3].replace(' ', 'T') + 'Z'
-def verify_mongo_entry(testcase):
+def verify_document(testcase):
"""
Mandatory fields:
installer
@@ -364,124 +130,70 @@ def verify_mongo_entry(testcase):
return True
-def modify_mongo_entry(testcase):
+def format_document(testcase):
# 1. verify and identify the testcase
# 2. if modification is implemented, then use that
# 3. if not, try to use default
# 4. if 2 or 3 is successful, return True, otherwise return False
- if verify_mongo_entry(testcase):
+ if verify_document(testcase):
project = testcase['project_name']
case_name = testcase['case_name']
- logger.info("Processing mongo test case '{}'".format(case_name))
- try:
- if project == 'functest':
- if case_name == 'rally_sanity':
- return modify_functest_rally(testcase)
- elif case_name.lower() == 'odl':
- return modify_functest_odl(testcase)
- elif case_name.lower() == 'onos':
- return modify_functest_onos(testcase)
- elif case_name.lower() == 'vims':
- return modify_functest_vims(testcase)
- elif case_name == 'tempest_smoke_serial':
- return modify_functest_tempest(testcase)
- return modify_default_entry(testcase)
- except Exception:
- logger.error("Fail in modify testcase[%s]\nerror message: %s" % (testcase, traceback.format_exc()))
+ fmt = conf_utils.get_format(project, case_name)
+ if fmt:
+ try:
+ logger.info("Processing %s/%s using format %s" % (project, case_name, fmt))
+ return vars(mongo2elastic_format)[fmt](testcase)
+ except Exception:
+ logger.error("Fail in format testcase[%s]\nerror message: %s" % (testcase, traceback.format_exc()))
+ return False
else:
return False
-def publish_mongo_data(output_destination):
- tmp_filename = 'mongo-{}.log'.format(uuid.uuid4())
- try:
- subprocess.check_call(['mongoexport', '--db', 'test_results_collection', '-c', 'results', '--out',
- tmp_filename])
- with open(tmp_filename) as fobj:
- for mongo_json_line in fobj:
- test_result = json.loads(mongo_json_line)
- if modify_mongo_entry(test_result):
- status, data = shared_utils.publish_json(test_result, es_creds, output_destination)
- if status > 300:
- project = test_result['project_name']
- case_name = test_result['case_name']
- logger.info('project {} case {} publish failed, due to [{}]'
- .format(project, case_name, json.loads(data)['error']['reason']))
- finally:
- if os.path.exists(tmp_filename):
- os.remove(tmp_filename)
-
-
-def get_mongo_data(days):
- past_time = datetime.datetime.today() - datetime.timedelta(days=days)
- mongo_json_lines = subprocess.check_output(['mongoexport', '--db', 'test_results_collection', '-c', 'results',
- '--query', '{{"start_date":{{$gt:"{}"}}}}'
- .format(past_time)]).splitlines()
+def export_documents(days):
+ cmd = ['mongoexport', '--db', 'test_results_collection', '-c', 'results']
+ if days > 0:
+ past_time = datetime.datetime.today() - datetime.timedelta(days=days)
+ cmd += ['--query', '{{"start_date":{{$gt:"{}"}}}}'.format(past_time)]
+ cmd += [ '--out', '{}'.format(tmp_docs_file)]
- mongo_data = []
- for mongo_json_line in mongo_json_lines:
- test_result = json.loads(mongo_json_line)
- if modify_mongo_entry(test_result):
- # if the modification could be applied, append the modified result
- mongo_data.append(test_result)
- return mongo_data
+ try:
+ subprocess.check_call(cmd)
+ except Exception, err:
+ logger.error("export mongodb failed: %s" % err)
+ exit(-1)
-def publish_difference(mongo_data, elastic_data, output_destination, es_creds):
- for elastic_entry in elastic_data:
- if elastic_entry in mongo_data:
- mongo_data.remove(elastic_entry)
+def publish_document(document, es_creds, to):
+ status, data = shared_utils.publish_json(document, es_creds, to)
+ if status > 300:
+ logger.error('Publish record[{}] failed, due to [{}]'
+ .format(document, json.loads(data)['error']['reason']))
- logger.info('number of parsed test results: {}'.format(len(mongo_data)))
- for parsed_test_result in mongo_data:
- shared_utils.publish_json(parsed_test_result, es_creds, output_destination)
+def publish_nonexist_documents(elastic_docs, es_creds, to):
+ try:
+ with open(tmp_docs_file) as fdocs:
+ for doc_line in fdocs:
+ doc = json.loads(doc_line)
+ if format_document(doc) and doc not in elastic_docs:
+ publish_document(doc, es_creds, to)
+ finally:
+ fdocs.close()
+ if os.path.exists(tmp_docs_file):
+ os.remove(tmp_docs_file)
if __name__ == '__main__':
- parser = argparse.ArgumentParser(description='Modify and filter mongo json data for elasticsearch')
- parser.add_argument('-od', '--output-destination',
- default='elasticsearch',
- choices=('elasticsearch', 'stdout'),
- help='defaults to elasticsearch')
-
- parser.add_argument('-ml', '--merge-latest', default=0, type=int, metavar='N',
- help='get entries old at most N days from mongodb and'
- ' parse those that are not already in elasticsearch.'
- ' If not present, will get everything from mongodb, which is the default')
-
- parser.add_argument('-e', '--elasticsearch-url', default='http://localhost:9200',
- help='the url of elasticsearch, defaults to http://localhost:9200')
-
- parser.add_argument('-u', '--elasticsearch-username', default=None,
- help='The username with password for elasticsearch in format username:password')
-
- args = parser.parse_args()
base_elastic_url = urlparse.urljoin(args.elasticsearch_url, '/test_results/mongo2elastic')
- output_destination = args.output_destination
+ to = args.output_destination
days = args.merge_latest
es_creds = args.elasticsearch_username
- if output_destination == 'elasticsearch':
- output_destination = base_elastic_url
-
- # parsed_test_results will be printed/sent to elasticsearch
- if days == 0:
- publish_mongo_data(output_destination)
- elif days > 0:
- body = '''{{
- "query" : {{
- "range" : {{
- "start_date" : {{
- "gte" : "now-{}d"
- }}
- }}
- }}
-}}'''.format(days)
- elastic_data = shared_utils.get_elastic_data(base_elastic_url, es_creds, body)
- logger.info('number of hits in elasticsearch for now-{}d: {}'.format(days, len(elastic_data)))
- mongo_data = get_mongo_data(days)
- publish_difference(mongo_data, elastic_data, output_destination, es_creds)
- else:
- raise Exception('Update must be non-negative')
+ if to == 'elasticsearch':
+ to = base_elastic_url
+ export_documents(days)
+ elastic_docs = shared_utils.get_elastic_docs_by_days(base_elastic_url, es_creds, days)
+ logger.info('number of hits in elasticsearch for now-{}d: {}'.format(days, len(elastic_docs)))
+ publish_nonexist_documents(elastic_docs, es_creds, to)
diff --git a/utils/test/scripts/shared_utils.py b/utils/test/scripts/shared_utils.py
index 8bbbdbe07..aa8a65d79 100644
--- a/utils/test/scripts/shared_utils.py
+++ b/utils/test/scripts/shared_utils.py
@@ -1,5 +1,7 @@
-import urllib3
import json
+
+import urllib3
+
http = urllib3.PoolManager()
@@ -8,14 +10,14 @@ def delete_request(url, creds, body=None):
http.request('DELETE', url, headers=headers, body=body)
-def publish_json(json_ojb, creds, output_destination):
+def publish_json(json_ojb, creds, to):
json_dump = json.dumps(json_ojb)
- if output_destination == 'stdout':
+ if to == 'stdout':
print json_dump
return 200, None
else:
headers = urllib3.make_headers(basic_auth=creds)
- result = http.request('POST', output_destination, headers=headers, body=json_dump)
+ result = http.request('POST', to, headers=headers, body=json_dump)
return result.status, result.data
@@ -23,17 +25,39 @@ def _get_nr_of_hits(elastic_json):
return elastic_json['hits']['total']
-def get_elastic_data(elastic_url, creds, body, field='_source'):
+def get_elastic_docs(elastic_url, creds, body=None, field = '_source'):
+
# 1. get the number of results
headers = urllib3.make_headers(basic_auth=creds)
elastic_json = json.loads(http.request('GET', elastic_url + '/_search?size=0', headers=headers, body=body).data)
+ print elastic_json
nr_of_hits = _get_nr_of_hits(elastic_json)
# 2. get all results
elastic_json = json.loads(http.request('GET', elastic_url + '/_search?size={}'.format(nr_of_hits), headers=headers, body=body).data)
- elastic_data = []
+ elastic_docs = []
for hit in elastic_json['hits']['hits']:
- elastic_data.append(hit[field])
- return elastic_data
-
+ elastic_docs.append(hit[field])
+ return elastic_docs
+
+def get_elastic_docs_by_days(elastic_url, creds, days):
+ if days == 0:
+ body = '''{
+ "query": {
+ "match_all": {}
+ }
+ }'''
+ elif days > 0:
+ body = '''{{
+ "query" : {{
+ "range" : {{
+ "start_date" : {{
+ "gte" : "now-{}d"
+ }}
+ }}
+ }}
+ }}'''.format(days)
+ else:
+ raise Exception('Update days must be non-negative')
+ return get_elastic_docs(elastic_url, creds, body)
diff --git a/utils/test/scripts/testcases.yaml b/utils/test/scripts/testcases.yaml
index 12031ef5d..9c33d2e6b 100644
--- a/utils/test/scripts/testcases.yaml
+++ b/utils/test/scripts/testcases.yaml
@@ -1,6 +1,7 @@
functest:
-
name: tempest_smoke_serial
+ format: normal
test_family: VIM
visualizations:
-
@@ -19,6 +20,7 @@ functest:
-
name: rally_sanity
test_family: VIM
+ format: rally
visualizations:
-
name: duration
@@ -34,6 +36,7 @@ functest:
- field: details.success_percentage
-
name: vping_ssh
+ format: normal
test_family: VIM
visualizations:
-
@@ -42,6 +45,7 @@ functest:
- field: details.duration
-
name: vping_userdata
+ format: normal
test_family: VIM
visualizations:
-
@@ -51,6 +55,7 @@ functest:
-
name: odl
test_family: Controller
+ format: odl
visualizations:
-
name: tests_failures
@@ -63,6 +68,7 @@ functest:
- field: details.success_percentage
-
name: onos
+ format: onos
test_family: Controller
visualizations:
-
@@ -89,6 +95,7 @@ functest:
- field: details.FUNCvirNetL3.failures
-
name: vims
+ format: vims
test_family: Features
visualizations:
-
@@ -107,6 +114,7 @@ functest:
promise:
-
name: promise
+ format: normal
test_family: Features
visualizations:
-
@@ -122,6 +130,7 @@ doctor:
-
name: doctor-notification
test_family: Features
+ format: normal
visualizations:
-
name: duration