提交 6b506e6c 编写于 作者: L Lucas Meneghel Rodrigues 提交者: Lucas Meneghel Rodrigues

Merge pull request #120 from lmr/flat-tests-2

Flat tests
......@@ -36,6 +36,14 @@ class JobError(Exception):
status = "ERROR"
class OptionValidationError(Exception):
"""
An invalid option was passed to the test runner
"""
status = "ERROR"
class TestBaseException(Exception):
"""
......
......@@ -69,28 +69,44 @@ class TestRunner(object):
:type params: dict
:return: an instance of :class:`avocado.test.Test`.
"""
shortname = params.get('shortname')
url = shortname.split('.')[0]
path_attempt = os.path.abspath(shortname)
if os.path.exists(path_attempt):
test_class = test.DropinTest
test_instance = test_class(path=path_attempt,
base_logdir=self.job.logdir,
job=self.job)
else:
t_id = params.get('id')
test_path = os.path.abspath(t_id)
path_analyzer = path.PathInspector(test_path)
module_name = os.path.basename(test_path).split('.')[0]
if not os.path.exists(test_path):
# Try to resolve test ID (keep compatibility)
test_path = os.path.join(data_dir.get_test_dir(), '%s.py' % t_id)
if os.path.exists(test_path):
path_analyzer = path.PathInspector(test_path)
else:
test_class = test.MissingTest
test_instance = test_class(name=t_id,
base_logdir=self.job.logdir,
params=params,
job=self.job)
return test_instance
if path_analyzer.is_python():
try:
test_module_dir = os.path.join(self.job.test_dir, url)
f, p, d = imp.find_module(url, [test_module_dir])
test_module = imp.load_module(url, f, p, d)
test_module_dir = os.path.dirname(test_path)
f, p, d = imp.find_module(module_name, [test_module_dir])
test_module = imp.load_module(module_name, f, p, d)
f.close()
test_class = getattr(test_module, url)
test_class = getattr(test_module, module_name)
except ImportError:
test_class = test.MissingTest
finally:
test_instance = test_class(name=url,
test_instance = test_class(name=t_id,
base_logdir=self.job.logdir,
params=params,
job=self.job)
else:
test_class = test.DropinTest
test_instance = test_class(path=test_path,
base_logdir=self.job.logdir,
job=self.job)
return test_instance
def run_test(self, instance, queue):
......@@ -287,7 +303,7 @@ class Job(object):
if urls is not None:
for url in urls:
params_list.append({'shortname': url})
params_list.append({'id': url})
if multiplex_file is None:
if self.args and self.args.multiplex_file is not None:
......@@ -299,18 +315,19 @@ class Job(object):
params_list = []
if urls is not None:
for url in urls:
test_module = os.path.basename(url).split('.')[0]
parser = multiplex_config.Parser(multiplex_file)
parser.only_filter(url)
parser.only_filter(test_module)
dcts = [d for d in parser.get_dicts()]
if dcts:
for dct in dcts:
dct['id'] = url
params_list.append(dct)
else:
params_list.append({'shortname': url})
params_list.append({'id': url})
else:
parser = multiplex_config.Parser(multiplex_file)
for dct in parser.get_dicts():
params_list.append(dct)
e_msg = "Empty test ID. A test path or alias must be provided"
raise exceptions.OptionValidationError(e_msg)
if self.args is not None:
self.args.test_result_total = len(params_list)
......@@ -371,6 +388,10 @@ class Job(object):
self.output_manager.log_fail_header('Avocado job failed: %s: %s' %
(fail_class, details))
return error_codes.numeric_status['AVOCADO_JOB_FAIL']
except exceptions.OptionValidationError, details:
self.output_manager.log_fail_header(str(details))
return error_codes.numeric_status['AVOCADO_JOB_FAIL']
except Exception, details:
self.status = "ERROR"
exc_type, exc_value, exc_traceback = sys.exc_info()
......
......@@ -21,6 +21,7 @@ import os
from avocado.plugins import plugin
from avocado.core import data_dir
from avocado.core import output
from avocado.utils import path
from avocado import sysinfo
from avocado import job
......@@ -53,7 +54,12 @@ class TestLister(plugin.Plugin):
"""
bcolors = output.colors
pipe = output.get_paginator()
test_dirs = os.listdir(data_dir.get_test_dir())
test_files = os.listdir(data_dir.get_test_dir())
test_dirs = []
for t in test_files:
inspector = path.PathInspector(path=t)
if inspector.is_python():
test_dirs.append(t.split('.')[0])
pipe.write(bcolors.header_str('Tests available:'))
pipe.write("\n")
for test_dir in test_dirs:
......
......@@ -17,6 +17,7 @@ Contains the base test implementation, used as a base for the actual
framework tests.
"""
import inspect
import logging
import os
import sys
......@@ -115,14 +116,22 @@ class Test(unittest.TestCase):
s_tag = ".".join(split_shortname[1:])
self.tag = tag or s_tag
self.job = job
self.basedir = os.path.join(data_dir.get_test_dir(), self.name)
self.datadir = os.path.join(self.basedir, 'data')
self.workdir = path.init_dir(data_dir.get_tmp_dir(), self.name)
basename = os.path.basename(self.name)
self.basedir = os.path.dirname(inspect.getfile(self.__class__))
self.datadir = os.path.join(self.basedir, '%s.data' % basename)
self.workdir = path.init_dir(data_dir.get_tmp_dir(), basename)
self.srcdir = path.init_dir(self.workdir, 'src')
if base_logdir is None:
base_logdir = data_dir.get_job_logs_dir()
self.tagged_name = self.get_tagged_name(base_logdir)
self.logdir = path.init_dir(base_logdir, self.tagged_name)
# We need log directory names to be unique
tagged_name = self.tagged_name.replace('/', '.')
if tagged_name.startswith('.'):
tagged_name = tagged_name[1:]
self.logdir = path.init_dir(base_logdir, tagged_name)
self.logfile = os.path.join(self.logdir, 'debug.log')
self.outputdir = path.init_dir(self.logdir, 'data')
self.sysinfodir = path.init_dir(self.logdir, 'sysinfo')
......@@ -386,10 +395,8 @@ class DropinTest(Test):
"""
def __init__(self, path, params=None, base_logdir=None, tag=None, job=None):
basename = os.path.basename(path)
name = basename.split(".")[0]
self.path = os.path.abspath(path)
super(DropinTest, self).__init__(name=name, base_logdir=base_logdir,
super(DropinTest, self).__init__(name=path, base_logdir=base_logdir,
params=params, tag=tag, job=job)
def _log_detailed_cmd_info(self, result):
......
......@@ -17,6 +17,10 @@ Avocado path related functions.
"""
import os
import stat
PY_EXTENSIONS = ['.py']
SHEBANG = '#!'
def init_dir(*args):
......@@ -32,3 +36,42 @@ def init_dir(*args):
if not os.path.isdir(directory):
os.makedirs(directory)
return directory
class PathInspector(object):
def __init__(self, path):
self.path = path
def get_first_line(self):
first_line = ""
if os.path.isfile(self.path):
checked_file = open(self.path, "r")
first_line = checked_file.readline()
checked_file.close()
return first_line
def has_exec_permission(self):
mode = os.stat(self.path)[stat.ST_MODE]
return mode & stat.S_IXUSR
def is_empty(self):
size = os.stat(self.path)[stat.ST_SIZE]
return size == 0
def is_script(self, language=None):
first_line = self.get_first_line()
if first_line:
if first_line.startswith(SHEBANG):
if language is None:
return True
elif language in first_line:
return True
return False
def is_python(self):
for extension in PY_EXTENSIONS:
if self.path.endswith(extension):
return True
return self.is_script(language='python')
......@@ -46,6 +46,11 @@ class RunnerOperationTest(unittest.TestCase):
cmd_line = './scripts/avocado run "sleeptest sleeptest"'
process.run(cmd_line)
def test_runner_noalias(self):
os.chdir(basedir)
cmd_line = "./scripts/avocado run 'tests/sleeptest.py tests/sleeptest.py'"
process.run(cmd_line)
def test_runner_tests_fail(self):
os.chdir(basedir)
cmd_line = './scripts/avocado run "sleeptest failtest sleeptest"'
......
......@@ -60,7 +60,7 @@ class MultiplexTests(unittest.TestCase):
"%d:\n%s" % (cmd_line, expected_rc, result))
def test_mplex_plugin(self):
cmd_line = './scripts/avocado multiplex tests/sleeptest/sleeptest.mplx'
cmd_line = './scripts/avocado multiplex tests/sleeptest.py.data/sleeptest.mplx'
expected_rc = 0
self.run_and_check(cmd_line, expected_rc)
......@@ -69,8 +69,22 @@ class MultiplexTests(unittest.TestCase):
expected_rc = 2
self.run_and_check(cmd_line, expected_rc)
def test_run_mplex_noid(self):
cmd_line = './scripts/avocado run --multiplex tests/sleeptest.py.data/sleeptest.mplx'
expected_rc = 0
self.run_and_check(cmd_line, 2)
def test_run_mplex_sleeptest(self):
cmd_line = './scripts/avocado run sleeptest --multiplex tests/sleeptest/sleeptest.mplx'
cmd_line = './scripts/avocado run sleeptest --multiplex tests/sleeptest.py.data/sleeptest.mplx'
expected_rc = 0
# A typical sleeptest has about 14 lines of output,
# so we expect the full job log has at least 3 times
# this value. If that is not the case, something is wrong with
# the output.
self.run_and_check(cmd_line, expected_rc, 14*3)
def test_run_mplex_noalias_sleeptest(self):
cmd_line = './scripts/avocado run tests/sleeptest.py --multiplex tests/sleeptest.py.data/sleeptest.mplx'
expected_rc = 0
# A typical sleeptest has about 14 lines of output,
# so we expect the full job log has at least 3 times
......@@ -79,12 +93,12 @@ class MultiplexTests(unittest.TestCase):
self.run_and_check(cmd_line, expected_rc, 14*3)
def test_run_mplex_doublesleep(self):
cmd_line = './scripts/avocado run "sleeptest sleeptest" --multiplex tests/sleeptest/sleeptest.mplx'
cmd_line = './scripts/avocado run "sleeptest sleeptest" --multiplex tests/sleeptest.py.data/sleeptest.mplx'
expected_rc = 0
self.run_and_check(cmd_line, expected_rc)
def test_run_mplex_failtest(self):
cmd_line = './scripts/avocado run "sleeptest failtest" --multiplex tests/sleeptest/sleeptest.mplx'
cmd_line = './scripts/avocado run "sleeptest failtest" --multiplex tests/sleeptest.py.data/sleeptest.mplx'
expected_rc = 1
self.run_and_check(cmd_line, expected_rc)
......
......@@ -44,27 +44,27 @@ class StandaloneTests(unittest.TestCase):
"%d:\n%s" % (tstname, expected_rc, result))
def test_sleeptest(self):
cmd_line = './tests/sleeptest/sleeptest.py'
cmd_line = './tests/sleeptest.py'
expected_rc = 0
self.run_and_check(cmd_line, expected_rc, 'sleeptest')
def test_skiptest(self):
cmd_line = './tests/skiptest/skiptest.py'
cmd_line = './tests/skiptest.py'
expected_rc = 0
self.run_and_check(cmd_line, expected_rc, 'skiptest')
def test_failtest(self):
cmd_line = './tests/failtest/failtest.py'
cmd_line = './tests/failtest.py'
expected_rc = 1
self.run_and_check(cmd_line, expected_rc, 'failtest')
def test_errortest(self):
cmd_line = './tests/errortest/errortest.py'
cmd_line = './tests/errortest.py'
expected_rc = 1
self.run_and_check(cmd_line, expected_rc, 'errortest')
def test_warntest(self):
cmd_line = './tests/warntest/warntest.py'
cmd_line = './tests/warntest.py'
expected_rc = 1
self.run_and_check(cmd_line, expected_rc, 'warntest')
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册