summaryrefslogtreecommitdiffstats
path: root/dovetail/report.py
diff options
context:
space:
mode:
Diffstat (limited to 'dovetail/report.py')
-rw-r--r--dovetail/report.py144
1 files changed, 114 insertions, 30 deletions
diff --git a/dovetail/report.py b/dovetail/report.py
index 0d83831d..fa6a0ba4 100644
--- a/dovetail/report.py
+++ b/dovetail/report.py
@@ -13,6 +13,7 @@ import urllib2
import re
import os
import datetime
+import tarfile
from pbr import version
@@ -25,7 +26,7 @@ from testcase import Testcase
class Report(object):
- results = {'functest': {}, 'yardstick': {}, 'shell': {}}
+ results = {'functest': {}, 'yardstick': {}, 'bottlenecks': {}, 'shell': {}}
logger = None
@@ -112,8 +113,8 @@ class Report(object):
'|'.join(dt_cfg.dovetail_config['testarea_supported']))
area = pattern.findall(testcase['name'])
if not area:
- cls.logger.error("testcase %s not in supported testarea",
- testcase['name'])
+ cls.logger.error("Test case {} not in supported testarea."
+ .format(testcase['name']))
return None
area = area[0]
testarea_scope.append(area)
@@ -162,6 +163,17 @@ class Report(object):
# cls.save(report_txt)
return report_txt
+ @classmethod
+ def save_logs(cls):
+ logs_gz = "logs.tar.gz"
+ result_dir = dt_cfg.dovetail_config['result_dir']
+
+ with tarfile.open(os.path.join(result_dir, logs_gz), "w:gz") as f_out:
+ files = os.listdir(result_dir)
+ for f in files:
+ if f not in ['workspace']:
+ f_out.add(os.path.join(result_dir, f))
+
# save to disk as default
@classmethod
def save(cls, report):
@@ -170,9 +182,9 @@ class Report(object):
with open(os.path.join(dt_cfg.dovetail_config['result_dir'],
report_file_name), 'w') as report_file:
report_file.write(report)
- cls.logger.info('save report to %s', report_file_name)
+ cls.logger.info('Save report to {}'.format(report_file_name))
except Exception:
- cls.logger.error('Failed to save: %s', report_file_name)
+ cls.logger.exception('Failed to save: {}'.format(report_file_name))
@classmethod
def get_result(cls, testcase):
@@ -180,7 +192,7 @@ class Report(object):
type = testcase.validate_type()
crawler = CrawlerFactory.create(type)
if crawler is None:
- cls.logger.error('crawler is None:%s', testcase.name())
+ cls.logger.error('Crawler is None: {}'.format(testcase.name()))
return None
# if validate_testcase in cls.results[type]:
@@ -191,12 +203,12 @@ class Report(object):
if result is not None:
cls.results[type][validate_testcase] = result
# testcase.script_result_acquired(True)
- cls.logger.debug('testcase: %s -> result acquired',
- validate_testcase)
+ cls.logger.debug(
+ 'Test case: {} -> result acquired'.format(validate_testcase))
else:
retry = testcase.increase_retry()
- cls.logger.debug('testcase: %s -> result acquired retry:%d',
- validate_testcase, retry)
+ cls.logger.debug('Test case: {} -> result acquired retry: {}'
+ .format(validate_testcase, retry))
return result
@@ -206,7 +218,7 @@ class FunctestCrawler(object):
def __init__(self):
self.type = 'functest'
- self.logger.debug('create crawler:%s', self.type)
+ self.logger.debug('Create crawler: {}'.format(self.type))
@classmethod
def create_log(cls):
@@ -234,14 +246,15 @@ class FunctestCrawler(object):
os.path.join(dovetail_config['result_dir'],
dovetail_config[self.type]['result']['file_path'])
if not os.path.exists(file_path):
- self.logger.info('result file not found: %s', file_path)
+ self.logger.error('Result file not found: {}'.format(file_path))
return None
if testcase_name in dt_cfg.dovetail_config['functest_testcase']:
complex_testcase = False
elif testcase_name in dt_cfg.dovetail_config['functest_testsuite']:
complex_testcase = True
else:
- self.logger.error("Wrong Functest test case %s.", testcase_name)
+ self.logger.error(
+ "Wrong Functest test case {}.".format(testcase_name))
return None
with open(file_path, 'r') as f:
for jsonfile in f:
@@ -264,7 +277,8 @@ class FunctestCrawler(object):
"errors": error_case,
"skipped": skipped_case}
except KeyError as e:
- self.logger.error("Key error, exception: %s", e)
+ self.logger.exception(
+ "Result data don't have key {}.".format(e))
return None
except ValueError:
continue
@@ -273,20 +287,20 @@ class FunctestCrawler(object):
'timestop': timestop, 'duration': duration,
'details': details}
- self.logger.debug('Results: %s', str(json_results))
+ self.logger.debug('Results: {}'.format(str(json_results)))
return json_results
def crawl_from_url(self, testcase=None):
url = "%s?case=%s&last=1" % \
(dt_cfg.dovetail_config['report_dest'],
testcase.validate_testcase())
- self.logger.debug("Query to rest api: %s", url)
+ self.logger.debug("Query to rest api: {}".format(url))
try:
data = json.load(urllib2.urlopen(url))
return data['results'][0]
except Exception as e:
- self.logger.error("Cannot read content from the url: %s, "
- "exception: %s", url, e)
+ self.logger.exception("Cannot read content from the url: {}, "
+ "exception: {}".format(url, e))
return None
@@ -296,7 +310,7 @@ class YardstickCrawler(object):
def __init__(self):
self.type = 'yardstick'
- self.logger.debug('create crawler:%s', self.type)
+ self.logger.debug('Create crawler: {}'.format(self.type))
@classmethod
def create_log(cls):
@@ -313,9 +327,9 @@ class YardstickCrawler(object):
def crawl_from_file(self, testcase=None):
file_path = os.path.join(dt_cfg.dovetail_config['result_dir'],
- testcase.validate_testcase() + '.out')
+ testcase.name() + '.out')
if not os.path.exists(file_path):
- self.logger.info('result file not found: %s', file_path)
+ self.logger.error('Result file not found: {}'.format(file_path))
return None
criteria = 'FAIL'
with open(file_path, 'r') as f:
@@ -327,9 +341,57 @@ class YardstickCrawler(object):
if 1 == v:
criteria = 'PASS'
except KeyError as e:
- self.logger.error('pass flag not found %s', e)
+ self.logger.exception(
+ 'Pass flag not found {}'.format(e))
json_results = {'criteria': criteria}
- self.logger.debug('Results: %s', str(json_results))
+ self.logger.debug('Results: {}'.format(str(json_results)))
+ return json_results
+
+ def crawl_from_url(self, testcase=None):
+ return None
+
+
+class BottlenecksCrawler(object):
+
+ logger = None
+
+ def __init__(self):
+ self.type = 'bottlenecks'
+ self.logger.debug('Create crawler: {}'.format(self.type))
+
+ @classmethod
+ def create_log(cls):
+ cls.logger = \
+ dt_logger.Logger(__name__ + '.BottlenecksCrawler').getLogger()
+
+ def crawl(self, testcase=None):
+ report_dest = dt_cfg.dovetail_config['report_dest']
+ if report_dest.lower() == 'file':
+ return self.crawl_from_file(testcase)
+
+ if report_dest.lower().startswith('http'):
+ return self.crawl_from_url(testcase)
+
+ def crawl_from_file(self, testcase=None):
+ file_path = os.path.join(dt_cfg.dovetail_config['result_dir'],
+ testcase.name() + '.out')
+ if not os.path.exists(file_path):
+ self.logger.error('Result file not found: {}'.format(file_path))
+ return None
+ criteria = 'FAIL'
+ with open(file_path, 'r') as f:
+ for jsonfile in f:
+ data = json.loads(jsonfile)
+ try:
+ if 'PASS' == data["data_body"]["result"]:
+ criteria = 'PASS'
+ else:
+ criteria = 'FAIL'
+ break
+ except KeyError as e:
+ self.logger.exception('Pass flag not found {}'.format(e))
+ json_results = {'criteria': criteria}
+ self.logger.debug('Results: {}'.format(str(json_results)))
return json_results
def crawl_from_url(self, testcase=None):
@@ -361,6 +423,7 @@ class CrawlerFactory(object):
CRAWLER_MAP = {'functest': FunctestCrawler,
'yardstick': YardstickCrawler,
+ 'bottlenecks': BottlenecksCrawler,
'shell': ShellCrawler}
@classmethod
@@ -394,14 +457,16 @@ class FunctestChecker(object):
sub_testcase = re.sub("\[.*?\]", "", sub_testcase)
reg = sub_testcase + '[\s+\d+]'
find_reg = re.compile(reg)
- match = find_reg.findall(result)
- if match:
- return True
+ for tc in result:
+ match = find_reg.findall(tc)
+ if match:
+ return True
reg = sub_testcase + '$'
find_reg = re.compile(reg)
- match = find_reg.findall(result)
- if match:
- return True
+ for tc in result:
+ match = find_reg.findall(tc)
+ if match:
+ return True
return False
def check(self, testcase, db_result):
@@ -420,7 +485,7 @@ class FunctestChecker(object):
testcase_passed = 'SKIP'
for sub_testcase in sub_testcase_list:
- self.logger.debug('check sub_testcase:%s', sub_testcase)
+ self.logger.debug('Check sub_testcase: {}'.format(sub_testcase))
try:
if self.get_sub_testcase(sub_testcase,
db_result['details']['errors']):
@@ -463,6 +528,24 @@ class YardstickChecker(object):
return
+class BottlenecksChecker(object):
+
+ logger = None
+
+ @classmethod
+ def create_log(cls):
+ cls.logger = \
+ dt_logger.Logger(__name__ + '.BottlenecksChecker').getLogger()
+
+ @staticmethod
+ def check(testcase, result):
+ if not result:
+ testcase.passed('FAIL')
+ else:
+ testcase.passed(result['criteria'])
+ return
+
+
class ShellChecker(object):
@staticmethod
@@ -477,6 +560,7 @@ class CheckerFactory(object):
CHECKER_MAP = {'functest': FunctestChecker,
'yardstick': YardstickChecker,
+ 'bottlenecks': BottlenecksChecker,
'shell': ShellChecker}
@classmethod