summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dovetail/conf/dovetail_config.py6
-rw-r--r--dovetail/container.py33
-rw-r--r--dovetail/parser.py7
-rw-r--r--dovetail/prepare_env.py3
-rw-r--r--dovetail/report.py74
-rwxr-xr-xdovetail/run.py22
-rw-r--r--dovetail/testcase.py72
-rw-r--r--dovetail/utils/dovetail_logger.py2
-rw-r--r--dovetail/utils/dovetail_utils.py26
9 files changed, 142 insertions, 103 deletions
diff --git a/dovetail/conf/dovetail_config.py b/dovetail/conf/dovetail_config.py
index f822d3ad..6f3eebf2 100644
--- a/dovetail/conf/dovetail_config.py
+++ b/dovetail/conf/dovetail_config.py
@@ -7,13 +7,13 @@
# http://www.apache.org/licenses/LICENSE-2.0
#
+import yaml
+import os
+
CERT_PATH = './cert/'
TESTCASE_PATH = './testcase/'
SCENARIO_NAMING_FMT = 'certification_%s'
-import yaml
-import os
-
curr_path = os.path.dirname(os.path.abspath(__file__))
with open(os.path.join(curr_path, 'dovetail_config.yml')) as f:
dovetail_config = yaml.safe_load(f)
diff --git a/dovetail/container.py b/dovetail/container.py
index 918edb33..54c43adc 100644
--- a/dovetail/container.py
+++ b/dovetail/container.py
@@ -9,14 +9,14 @@
import utils.dovetail_logger as dt_logger
import utils.dovetail_utils as dt_utils
-from conf.dovetail_config import *
-
+from conf.dovetail_config import dovetail_config
logger = dt_logger.Logger('container.py').getLogger()
+
class Container:
container_list = {}
- has_pull_latest_image = {'yardstick':False, 'functest':False}
+ has_pull_latest_image = {'yardstick': False, 'functest': False}
def __init__(cls):
pass
@@ -30,40 +30,45 @@ class Container:
@classmethod
def get_docker_image(cls, type):
- return '%s:%s' % (dovetail_config[type]['image_name'], dovetail_config[type]['docker_tag'])
+ return '%s:%s' % (dovetail_config[type]['image_name'],
+ dovetail_config[type]['docker_tag'])
@classmethod
def create(cls, type):
- #sshkey="-v /root/.ssh/id_rsa:/root/.ssh/id_rsa "
+ # sshkey="-v /root/.ssh/id_rsa:/root/.ssh/id_rsa "
docker_image = cls.get_docker_image(type)
envs = dovetail_config[type]['envs']
opts = dovetail_config[type]['opts']
sshkey = ''
- result_volume = ' -v %s:%s ' % (dovetail_config['result_dir'],dovetail_config[type]['result']['dir'])
- cmd = 'sudo docker run %s %s %s %s %s /bin/bash' % (opts, envs, sshkey, result_volume, docker_image)
- dt_utils.exec_cmd(cmd,logger)
- ret, container_id=dt_utils.exec_cmd("sudo docker ps | grep "+ docker_image + " | awk '{print $1}' | head -1",logger)
+ result_volume = ' -v %s:%s ' % (dovetail_config['result_dir'],
+ dovetail_config[type]['result']['dir'])
+ cmd = 'sudo docker run %s %s %s %s %s /bin/bash' % \
+ (opts, envs, sshkey, result_volume, docker_image)
+ dt_utils.exec_cmd(cmd, logger)
+ ret, container_id = \
+ dt_utils.exec_cmd("sudo docker ps | grep " + docker_image +
+ " | awk '{print $1}' | head -1", logger)
cls.container_list[type] = container_id
return container_id
@classmethod
def pull_image(cls, type):
docker_image = cls.get_docker_image(type)
- if cls.has_pull_latest_image[type] == True:
+ if cls.has_pull_latest_image[type] is True:
logger.debug('%s is already the newest version.' % (docker_image))
else:
cmd = 'sudo docker pull %s' % (docker_image)
- dt_utils.exec_cmd(cmd,logger)
+ dt_utils.exec_cmd(cmd, logger)
cls.has_pull_latest_image[type] = True
@classmethod
def clean(cls, container_id):
cmd1 = 'sudo docker stop %s' % (container_id)
- dt_utils.exec_cmd(cmd1,logger)
+ dt_utils.exec_cmd(cmd1, logger)
cmd2 = 'sudo docker rm %s' % (container_id)
- dt_utils.exec_cmd(cmd2,logger)
+ dt_utils.exec_cmd(cmd2, logger)
@classmethod
def exec_cmd(cls, container_id, sub_cmd, exit_on_error=False):
cmd = 'sudo docker exec %s /bin/bash -c "%s"' % (container_id, sub_cmd)
- dt_utils.exec_cmd(cmd,logger,exit_on_error)
+ dt_utils.exec_cmd(cmd, logger, exit_on_error)
diff --git a/dovetail/parser.py b/dovetail/parser.py
index 1c0c0450..a9edb36e 100644
--- a/dovetail/parser.py
+++ b/dovetail/parser.py
@@ -12,10 +12,10 @@ import jinja2
import utils.dovetail_logger as dt_logger
import utils.dovetail_utils as dt_utils
+from conf.dovetail_config import dovetail_config
logger = dt_logger.Logger('parser.py').getLogger()
-from conf.dovetail_config import *
class Parser:
'''preprocess configuration files'''
@@ -29,9 +29,10 @@ class Parser:
for arg in dovetail_config['parameters']:
path = eval(arg['path'])
logger.debug('name: %s, eval path: %s ' % (arg['name'], path))
- kwargs[arg['name']] = dt_utils.get_obj_by_path(testcase.testcase,path)
+ kwargs[arg['name']] = \
+ dt_utils.get_obj_by_path(testcase.testcase, path)
- logger.debug('kwargs: %s' % kwargs)
+ logger.debug('kwargs: %s' % kwargs)
cmd_lines = template.render(**kwargs)
except Exception as e:
logger.error('failed to parse cmd %s, exception:%s' % (cmd, e))
diff --git a/dovetail/prepare_env.py b/dovetail/prepare_env.py
index bd484302..785d5c3d 100644
--- a/dovetail/prepare_env.py
+++ b/dovetail/prepare_env.py
@@ -7,8 +7,6 @@
# http://www.apache.org/licenses/LICENSE-2.0
#
-import os
-
import utils.dovetail_logger as dt_logger
import utils.dovetail_utils as dt_utils
@@ -20,4 +18,3 @@ dt_utils.exec_cmd(cmd, logger)
cmd = "sudo pip install click pyyaml jinja2"
dt_utils.exec_cmd(cmd, logger)
-
diff --git a/dovetail/report.py b/dovetail/report.py
index 5dfa5890..c937011f 100644
--- a/dovetail/report.py
+++ b/dovetail/report.py
@@ -9,24 +9,26 @@
import json
import urllib2
import re
+import os
import utils.dovetail_logger as dt_logger
-import utils.dovetail_utils as dt_utils
-from conf.dovetail_config import *
-from testcase import *
+from conf.dovetail_config import dovetail_config
+from testcase import Testcase
logger = dt_logger.Logger('report.py').getLogger()
+
def get_pass_str(passed):
if passed:
return 'PASS'
else:
return 'FAIL'
+
class Report:
- results = {'functest':{},'yardstick':{}}
+ results = {'functest': {}, 'yardstick': {}}
@classmethod
def check_result(cls, testcase, db_result):
@@ -38,32 +40,37 @@ class Report:
report = ''
report += '\n\
-+=============================================================================+\n\
-| report | \n\
-+-----------------------------------------------------------------------------+\n'
++==========================================================================+\n\
+| report |\n\
++--------------------------------------------------------------------------+\n'
report += '|scenario: %s\n' % scenario_yaml['name']
for testcase_name in scenario_yaml['testcase_list']:
testcase = Testcase.get(testcase_name)
- report += '| [testcase]: %s\t\t\t\t[%s]\n' % (testcase_name, get_pass_str(testcase.passed()))
+ report += '| [testcase]: %s\t\t\t\t[%s]\n' % \
+ (testcase_name, get_pass_str(testcase.passed()))
report += '| |-objective: %s\n' % testcase.objective()
if testcase.sub_testcase() is not None:
for subtest in testcase.sub_testcase():
- report += '| |-%s \t\t [%s]\n' % (subtest, get_pass_str(testcase.sub_testcase_passed(subtest)))
- report += '+-----------------------------------------------------------------------------+\n'
+ report += '| |-%s \t\t [%s]\n' % \
+ (subtest,
+ get_pass_str(testcase.sub_testcase_passed(subtest)))
+ report += '+-----------------------------------------------------'
+ report += '---------------------+\n'
logger.info(report)
cls.save(report)
return report
- #save to disk as default
+ # save to disk as default
@classmethod
def save(cls, report):
report_file_path = dovetail_config['report_file']
try:
- with open(os.path.join(dovetail_config['result_dir'], report_file_path),'w') as report_file:
+ with open(os.path.join(dovetail_config['result_dir'],
+ report_file_path), 'w') as report_file:
report_file.write(report)
logger.info('save report to %s' % report_file_path)
- except Exception as e:
+ except Exception:
logger.error('Failed to save: %s' % report_file_path)
@classmethod
@@ -83,9 +90,11 @@ class Report:
logger.debug('testcase: %s -> result acquired' % script_testcase)
else:
retry = testcase.increase_retry()
- logger.debug('testcase: %s -> result acquired retry:%d' % (script_testcase, retry))
+ logger.debug('testcase: %s -> result acquired retry:%d' %
+ (script_testcase, retry))
return result
+
class CrawlerFactory:
@classmethod
@@ -98,6 +107,7 @@ class CrawlerFactory:
return None
+
class FunctestCrawler:
def __init__(self):
@@ -112,7 +122,9 @@ class FunctestCrawler:
return self.crawl_from_url(testcase)
def crawl_from_file(self, testcase=None):
- file_path = os.path.join(dovetail_config['result_dir'],dovetail_config[self.type]['result']['file_path'])
+ file_path = \
+ os.path.join(dovetail_config['result_dir'],
+ dovetail_config[self.type]['result']['file_path'])
if not os.path.exists(file_path):
logger.info('result file not found: %s' % file_path)
return None
@@ -130,15 +142,17 @@ class FunctestCrawler:
if failed_num != 0:
criteria = 'FAIL'
- match = re.findall('Ran: (\d*) tests in (\d*)\.\d* sec.', output)
+ match = re.findall('Ran: (\d*) tests in (\d*)\.\d* sec.', output)
num_tests, dur_sec_int = match[0]
- json_results = {'criteria':criteria,'details':{"timestart": '', "duration": int(dur_sec_int),
+ json_results = {'criteria': criteria, 'details': {"timestart": '',
+ "duration": int(dur_sec_int),
"tests": int(num_tests), "failures": failed_num,
"errors": error_logs}}
logger.debug('Results: %s' % str(json_results))
return json_results
except Exception as e:
- logger.error('Cannot read content from the file: %s, exception: %s' % (file_path, e))
+ logger.error('Cannot read content from the file: %s, exception: %s'
+ % (file_path, e))
return None
def crawl_from_url(self, testcase=None):
@@ -148,9 +162,11 @@ class FunctestCrawler:
data = json.load(urllib2.urlopen(url))
return data['results'][0]
except Exception as e:
- logger.error("Cannot read content from the url: %s, exception: %s" % (url, e))
+ logger.error("Cannot read content from the url: %s, exception: %s"
+ % (url, e))
return None
+
class YardstickCrawler:
def __init__(self):
@@ -165,28 +181,31 @@ class YardstickCrawler:
return self.crawl_from_url(testcase)
def crawl_from_file(self, testcase=None):
- file_path = os.path.join(dovetail_config['result_dir'], testcase+'.out')
+ file_path = os.path.join(dovetail_config['result_dir'],
+ testcase+'.out')
if not os.path.exists(file_path):
logger.info('result file not found: %s' % file_path)
return None
try:
with open(file_path, 'r') as myfile:
- output = myfile.read()
+ myfile.read()
criteria = 'PASS'
- json_results = {'criteria':criteria}
+ json_results = {'criteria': criteria}
logger.debug('Results: %s' % str(json_results))
return json_results
except Exception as e:
- logger.error('Cannot read content from the file: %s, exception: %s' % (file_path, e))
+ logger.error('Cannot read content from the file: %s, exception: %s'
+ % (file_path, e))
return None
def crawl_from_url(self, testcase=None):
return None
+
class CheckerFactory:
@classmethod
- def create(cls,type):
+ def create(cls, type):
if type == 'functest':
return FunctestChecker()
@@ -195,17 +214,19 @@ class CheckerFactory:
return None
+
class ResultChecker:
def check(cls):
return 'PASS'
+
class FunctestChecker:
def check(cls, testcase, db_result):
if not db_result:
for sub_testcase in testcase.sub_testcase():
- testcase.sub_testcase_passed(sub_testcase,False)
+ testcase.sub_testcase_passed(sub_testcase, False)
return
testcase.passed(db_result['criteria'] == 'PASS')
@@ -213,7 +234,7 @@ class FunctestChecker:
if testcase.sub_testcase() is None:
return
- if testcase.testcase['passed'] == True:
+ if testcase.testcase['passed'] is True:
for sub_testcase in testcase.sub_testcase():
testcase.sub_testcase_passed(sub_testcase, True)
return
@@ -229,6 +250,7 @@ class FunctestChecker:
testcase.passed(all_passed)
+
class YardstickChecker:
def check(cls, testcase, result):
diff --git a/dovetail/run.py b/dovetail/run.py
index 85871fab..8fe27c59 100755
--- a/dovetail/run.py
+++ b/dovetail/run.py
@@ -9,28 +9,28 @@
import click
-import yaml
-import os
-import time
import utils.dovetail_logger as dt_logger
-import utils.dovetail_utils as dt_utils
from container import Container
-from testcase import *
-from report import *
-from conf.dovetail_config import *
+from testcase import Testcase
+from testcase import Scenario
+from report import Report
+from conf.dovetail_config import SCENARIO_NAMING_FMT
logger = dt_logger.Logger('run.py').getLogger()
+
def load_scenario(scenario):
Scenario.load()
return Scenario.get(SCENARIO_NAMING_FMT % scenario)
+
def load_testcase():
Testcase.load()
+
def run_test(scenario):
for testcase_name in scenario['testcase_list']:
logger.info('>>[testcase]: %s' % (testcase_name))
@@ -49,11 +49,12 @@ def run_test(scenario):
logger.debug('container id:%s' % container_id)
if not Testcase.prepared(testcase.script_type()):
- cmds = Testcase.pre_condition(testcase.script_type())['cmds']
+ cmds = \
+ Testcase.pre_condition_cls(testcase.script_type())['cmds']
if cmds:
for cmd in cmds:
Container.exec_cmd(container_id, cmd)
- Testcase.prepared(testcase.script_type(),True)
+ Testcase.prepared(testcase.script_type(), True)
if not testcase.prepare_cmd():
logger.error('failed to prepare testcase:%s' % testcase.name())
@@ -61,13 +62,14 @@ def run_test(scenario):
for cmd in testcase.cmds:
Container.exec_cmd(container_id, cmd)
- #testcase.post_condition()
+ # testcase.post_condition()
Container.clean(container_id)
db_result = Report.get_result(testcase)
Report.check_result(testcase, db_result)
+
@click.command()
@click.option('--scenario', default='basic', help='certification scenario')
def main(scenario):
diff --git a/dovetail/testcase.py b/dovetail/testcase.py
index 4deabe2e..51714e37 100644
--- a/dovetail/testcase.py
+++ b/dovetail/testcase.py
@@ -7,16 +7,18 @@
# http://www.apache.org/licenses/LICENSE-2.0
#
-import jinja2
+import os
+import yaml
import utils.dovetail_logger as dt_logger
-import utils.dovetail_utils as dt_utils
-from parser import *
+from parser import Parser
+from conf.dovetail_config import CERT_PATH
+from conf.dovetail_config import TESTCASE_PATH
+from conf.dovetail_config import dovetail_config
logger = dt_logger.Logger('testcase.py').getLogger()
-from conf.dovetail_config import *
class Testcase:
@@ -25,11 +27,12 @@ class Testcase:
self.testcase['passed'] = False
self.cmds = []
self.sub_testcase_status = {}
- Testcase.update_script_testcase(self.script_type(), self.script_testcase())
+ Testcase.update_script_testcase(self.script_type(),
+ self.script_testcase())
def prepare_cmd(self):
for cmd in dovetail_config[self.script_type()]['testcase']['cmds']:
- cmd_lines = Parser.parse_cmd(cmd,self)
+ cmd_lines = Parser.parse_cmd(cmd, self)
if not cmd_lines:
return False
self.cmds.append(cmd_lines)
@@ -61,33 +64,35 @@ class Testcase:
return self.testcase['scripts']['testcase']
def exceed_max_retry_times(self):
- #logger.debug('retry times:%d' % self.testcase['retry'])
- return Testcase._exceed_max_retry_times(self.script_type(), self.script_testcase())
+ # logger.debug('retry times:%d' % self.testcase['retry'])
+ return Testcase._exceed_max_retry_times(self.script_type(),
+ self.script_testcase())
def increase_retry(self):
- #self.testcase['retry'] = self.testcase['retry'] + 1
- #return self.testcase['retry']
- return Testcase._increase_retry(self.script_type(), self.script_testcase())
+ # self.testcase['retry'] = self.testcase['retry'] + 1
+ # return self.testcase['retry']
+ return Testcase._increase_retry(self.script_type(),
+ self.script_testcase())
- def passed(self, passed = None):
+ def passed(self, passed=None):
if passed is not None:
self.testcase['passed'] = passed
return self.testcase['passed']
def script_result_acquired(self, acquired=None):
- return Testcase._result_acquired(self.script_type(), self.script_testcase(), acquired)
+ return Testcase._result_acquired(self.script_type(),
+ self.script_testcase(), acquired)
def pre_condition(self):
- return Testcase.pre_condition(self.script_type())
+ return Testcase.pre_condition_cls(self.script_type())
def post_condition(self):
- return Testcase.post_condition(self.script_type())
+ return Testcase.post_condition_cls(self.script_type())
+ # testcase in upstream testing project
+ script_testcase_list = {'functest': {}, 'yardstick': {}}
- #testcase in upstream testing project
- script_testcase_list = {'functest':{}, 'yardstick':{}}
-
- #testcase in dovetail
+ # testcase in dovetail
testcase_list = {}
@classmethod
@@ -103,23 +108,24 @@ class Testcase:
return cls.script_testcase_list[script_type]['cleaned']
@classmethod
- def pre_condition(cls, script_type):
+ def pre_condition_cls(cls, script_type):
return dovetail_config[script_type]['pre_condition']
- def post_condition(cls, script_type):
+ def post_condition_cls(cls, script_type):
return dovetail_config[script_type]['post_condition']
-
@classmethod
- def update_script_testcase(cls,script_type, script_testcase):
+ def update_script_testcase(cls, script_type, script_testcase):
if script_testcase not in cls.script_testcase_list[script_type]:
- cls.script_testcase_list[script_type][script_testcase] = {'retry':0, 'acquired':False}
+ cls.script_testcase_list[script_type][script_testcase] = \
+ {'retry': 0, 'acquired': False}
cls.script_testcase_list[script_type]['prepared'] = False
cls.script_testcase_list[script_type]['cleaned'] = False
@classmethod
- def _exceed_max_retry_times(cls, script_type, script_testcase ):
- return cls.script_testcase_list[script_type][script_testcase]['retry'] > 1
+ def _exceed_max_retry_times(cls, script_type, script_testcase):
+ retry = cls.script_testcase_list[script_type][script_testcase]['retry']
+ return retry > 1
@classmethod
def _increase_retry(cls, script_type, script_testcase):
@@ -127,10 +133,11 @@ class Testcase:
return cls.script_testcase_list[script_type][script_testcase]['retry']
@classmethod
- def _result_acquired(cls, script_type, script_testcase, acquired=None):
+ def _result_acquired(cls, script_type, testcase, acquired=None):
if acquired is not None:
- cls.script_testcase_list[script_type][script_testcase]['acquired'] = acquired
- return cls.script_testcase_list[script_type][script_testcase]['acquired']
+ cls.script_testcase_list[script_type][testcase]['acquired'] = \
+ acquired
+ return cls.script_testcase_list[script_type][testcase]['acquired']
@classmethod
def load(cls):
@@ -138,8 +145,9 @@ class Testcase:
for testcase_file in files:
with open(os.path.join(root, testcase_file)) as f:
testcase_yaml = yaml.safe_load(f)
- cls.testcase_list[testcase_yaml.keys()[0]] = Testcase(testcase_yaml)
- logger.debug( cls.testcase_list )
+ cls.testcase_list[testcase_yaml.keys()[0]] = \
+ Testcase(testcase_yaml)
+ logger.debug(cls.testcase_list)
@classmethod
def get(cls, testcase_name):
@@ -160,6 +168,7 @@ class Scenario:
return None
scenario_list = {}
+
@classmethod
def load(cls):
for root, dirs, files in os.walk(CERT_PATH):
@@ -175,4 +184,3 @@ class Scenario:
if scenario_name in cls.scenario_list:
return cls.scenario_list[scenario_name]
return None
-
diff --git a/dovetail/utils/dovetail_logger.py b/dovetail/utils/dovetail_logger.py
index 9b20225c..bd13508d 100644
--- a/dovetail/utils/dovetail_logger.py
+++ b/dovetail/utils/dovetail_logger.py
@@ -24,6 +24,7 @@
import logging
import os
+
class Logger:
def __init__(self, logger_name):
@@ -52,4 +53,3 @@ class Logger:
def getLogger(self):
return self.logger
-
diff --git a/dovetail/utils/dovetail_utils.py b/dovetail/utils/dovetail_utils.py
index 4c671552..2e33b53a 100644
--- a/dovetail/utils/dovetail_utils.py
+++ b/dovetail/utils/dovetail_utils.py
@@ -11,12 +11,11 @@
import sys
import subprocess
+from collections import Mapping, Set, Sequence
+
-def exec_cmd(cmd, logger=None,
- exit_on_error=True,
- info=False,
- error_msg="",
- verbose=True):
+def exec_cmd(cmd, logger=None, exit_on_error=True, info=False,
+ error_msg="", verbose=True):
if not error_msg:
error_msg = ("The command '%s' failed." % cmd)
msg_exec = ("Executing command: '%s'" % cmd)
@@ -55,12 +54,16 @@ def exec_cmd(cmd, logger=None,
return returncode, output[0].strip()
-#walkthrough the object, yield path and value
-from collections import Mapping, Set, Sequence
+# walkthrough the object, yield path and value
# dual python 2/3 compatability, inspired by the "six" library
string_types = (str, unicode) if str is bytes else (str, bytes)
-iteritems = lambda mapping: getattr(mapping, 'iteritems', mapping.items)()
+# iteritems = lambda mapping: getattr(mapping, 'iteritems', mapping.items)()
+
+
+def iteritems(mapping):
+ return getattr(mapping, 'iteritems', mapping.items)()
+
def objwalk(obj, path=(), memo=None):
if memo is None:
@@ -68,7 +71,8 @@ def objwalk(obj, path=(), memo=None):
iterator = None
if isinstance(obj, Mapping):
iterator = iteritems
- elif isinstance(obj, (Sequence, Set)) and not isinstance(obj, string_types):
+ elif isinstance(obj, (Sequence, Set)) and not isinstance(obj,
+ string_types):
iterator = enumerate
if iterator:
if id(obj) not in memo:
@@ -80,8 +84,8 @@ def objwalk(obj, path=(), memo=None):
else:
yield path, obj
-def get_obj_by_path(obj,dst_path):
+
+def get_obj_by_path(obj, dst_path):
for path, obj in objwalk(obj):
if path == dst_path:
return obj
-