Skip to content

Commit

Permalink
Test independent on Job class
Browse files Browse the repository at this point in the history
This commit removes the Job instance from the Test class. This is
preparation for legacy runner removal. For the nrunner doesn't make
sense to have Test dependent on Job instance, because Test is run inside
runner separated from Job.

Reference: #4425
Signed-off-by: Jan Richter <jarichte@redhat.com>
  • Loading branch information
richtja committed Mar 5, 2021
1 parent 4a6641a commit e293590
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 79 deletions.
4 changes: 2 additions & 2 deletions avocado/core/nrunner_avocado_instrumented.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import tempfile
import time

from . import job, loader, nrunner, teststatus
from . import loader, nrunner, teststatus
from .test import TestID
from .tree import TreeNode

Expand Down Expand Up @@ -38,7 +38,7 @@ def _run_avocado(runnable, queue):
test_factory = [klass,
{'name': TestID(1, klass_method),
'methodName': method,
'job': job.Job(),
'config': runnable.config,
'modulePath': module_path,
'params': (TreeNode(), []),
'tags': runnable.tags,
Expand Down
146 changes: 72 additions & 74 deletions avocado/core/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ class Test(unittest.TestCase, TestData):
timeout = None

def __init__(self, methodName='test', name=None, params=None,
base_logdir=None, job=None, runner_queue=None, tags=None):
base_logdir=None, config=None, runner_queue=None, tags=None):
"""
Initializes the test.
Expand All @@ -242,7 +242,9 @@ def __init__(self, methodName='test', name=None, params=None,
:type name: :class:`avocado.core.test.TestID`
:param base_logdir: Directory where test logs should go. If None
provided a temporary directory will be created.
:param job: The job that this test is part of.
:param config: the job configuration, usually set by command
line options and argument parsing
:type config: dict
"""
self.__phase = 'INIT'

Expand All @@ -257,9 +259,10 @@ def record_and_warn(*args, **kwargs):
else:
self.__name = TestID(0, self.__class__.__name__)

self.__job = job
self.__tags = tags

self.__config = config or settings.as_dict()

self.__base_logdir_tmp = None
if base_logdir is None:
prefix = 'avocado_test_'
Expand All @@ -282,10 +285,10 @@ def record_and_warn(*args, **kwargs):

self.__outputdir = utils_path.init_dir(self.logdir, 'data')

# For some reason, sometimes, job.config if None here.
# For some reason, sometimes, config if None here.
# This is the only place that we create a "default" in code.
try:
self.__sysinfo_enabled = job.config.get('sysinfo.collect.per_test')
self.__sysinfo_enabled = config.get('sysinfo.collect.per_test')
except AttributeError:
self.__sysinfo_enabled = False

Expand Down Expand Up @@ -325,11 +328,9 @@ def record_and_warn(*args, **kwargs):

self.__runner_queue = runner_queue

base_tmpdir = getattr(job, "tmpdir", None)
# When tmpdir not specified by job, use logdir to preserve all data
if base_tmpdir is None:
base_tmpdir = tempfile.mkdtemp(prefix="tmp_dir", dir=self.logdir)
self.__workdir = os.path.join(base_tmpdir,
self.__base_tmpdir = tempfile.mkdtemp(prefix="tmp_dir",
dir=base_logdir)
self.__workdir = os.path.join(self.__base_tmpdir,
self.name.str_filesystem)
utils_path.init_dir(self.__workdir)

Expand All @@ -356,13 +357,6 @@ def name(self):
"""
return self.__name

@property
def job(self):
"""
The job this test is associated with
"""
return self.__job

@property
def tags(self):
"""
Expand Down Expand Up @@ -560,8 +554,6 @@ def get_state(self):
self._update_time_elapsed()
state = {key: getattr(self, key, None) for (key) in TEST_STATE_ATTRIBUTES}
state['class_name'] = self.__class__.__name__
state['job_logdir'] = self.job.logdir
state['job_unique_id'] = self.job.unique_id
state['params'] = [(path, key, value)
for path, key, value
in self.__params.iteritems()] # pylint: disable=W1620
Expand Down Expand Up @@ -798,59 +790,58 @@ def _run_avocado(self):
whiteboard_file = os.path.join(self.logdir, 'whiteboard')
genio.write_file(whiteboard_file, self.whiteboard)

if self.job is not None:
output_check_record = self.job.config.get('run.output_check_record')
output_check = self.job.config.get('run.output_check')
output_check_record = self.__config.get('run.output_check_record')
output_check = self.__config.get('run.output_check')

# record the output if the modes are valid
if output_check_record == 'combined':
self._record_reference(self._output_file,
"output.expected")
else:
if output_check_record in ['all', 'both', 'stdout']:
self._record_reference(self._stdout_file,
"stdout.expected")
if output_check_record in ['all', 'both', 'stderr']:
self._record_reference(self._stderr_file,
"stderr.expected")

# check the output and produce test failures
if output_check_record != 'none' and output_check:
output_checked = False
# record the output if the modes are valid
if output_check_record == 'combined':
self._record_reference(self._output_file,
"output.expected")
else:
if output_check_record in ['all', 'both', 'stdout']:
self._record_reference(self._stdout_file,
"stdout.expected")
if output_check_record in ['all', 'both', 'stderr']:
self._record_reference(self._stderr_file,
"stderr.expected")

# check the output and produce test failures
if output_check_record != 'none' and output_check:
output_checked = False
try:
output_checked = self._check_reference(
self._output_file,
'output.expected',
'output.diff',
'output_diff',
'Output')
except exceptions.TestFail as details:
stacktrace.log_exc_info(sys.exc_info(),
logger=LOG_JOB)
output_check_exception = details
if not output_checked:
try:
self._check_reference(self._stdout_file,
'stdout.expected',
'stdout.diff',
'stdout_diff',
'Stdout')
except exceptions.TestFail as details:
# output check was performed (and failed)
output_checked = True
stacktrace.log_exc_info(sys.exc_info(),
logger=LOG_JOB)
stdout_check_exception = details
try:
output_checked = self._check_reference(
self._output_file,
'output.expected',
'output.diff',
'output_diff',
'Output')
self._check_reference(self._stderr_file,
'stderr.expected',
'stderr.diff',
'stderr_diff',
'Stderr')
except exceptions.TestFail as details:
stacktrace.log_exc_info(sys.exc_info(),
logger=LOG_JOB)
output_check_exception = details
if not output_checked:
try:
self._check_reference(self._stdout_file,
'stdout.expected',
'stdout.diff',
'stdout_diff',
'Stdout')
except exceptions.TestFail as details:
# output check was performed (and failed)
output_checked = True
stacktrace.log_exc_info(sys.exc_info(),
logger=LOG_JOB)
stdout_check_exception = details
try:
self._check_reference(self._stderr_file,
'stderr.expected',
'stderr.diff',
'stderr_diff',
'Stderr')
except exceptions.TestFail as details:
stacktrace.log_exc_info(sys.exc_info(),
logger=LOG_JOB)
stderr_check_exception = details
stderr_check_exception = details

# pylint: disable=E0702
if test_exception is not None:
Expand Down Expand Up @@ -1051,11 +1042,17 @@ def tearDown(self):
if self.__base_logdir_tmp is not None:
self.__base_logdir_tmp.cleanup()
self.__base_logdir_tmp = None
if not self.__config.get('run.keep_tmp') and os.path.exists(
self.__base_tmpdir):
shutil.rmtree(self.__base_tmpdir)

def __del__(self):
if self.__base_logdir_tmp is not None:
self.__base_logdir_tmp.cleanup()
self.__base_logdir_tmp = None
if not self.__config.get('run.keep_tmp') and os.path.exists(
self.__base_tmpdir):
shutil.rmtree(self.__base_tmpdir)


class SimpleTest(Test):
Expand All @@ -1066,13 +1063,14 @@ class SimpleTest(Test):

DATA_SOURCES = ["variant", "file"]

def __init__(self, name, params=None, base_logdir=None, job=None,
def __init__(self, name, params=None, base_logdir=None, config=None,
executable=None):
if executable is None:
executable = name.name
self._filename = executable
super(SimpleTest, self).__init__(name=name, params=params,
base_logdir=base_logdir, job=job)
base_logdir=base_logdir,
config=config)
# Maximal allowed file name length is 255
file_datadir = None
if (self.filename is not None and
Expand Down Expand Up @@ -1180,7 +1178,7 @@ def __init__(self, runner, chdir=None, test_dir=None):

class ExternalRunnerTest(SimpleTest):

def __init__(self, name, params=None, base_logdir=None, job=None,
def __init__(self, name, params=None, base_logdir=None, config=None,
external_runner=None, external_runner_argument=None):
if external_runner_argument is None:
external_runner_argument = name.name
Expand All @@ -1189,7 +1187,7 @@ def __init__(self, name, params=None, base_logdir=None, job=None,
"external_runner parameter, got None instead.")
self.external_runner = external_runner
super(ExternalRunnerTest, self).__init__(name, params, base_logdir,
job)
config)
self._command = "%s %s" % (external_runner.runner,
external_runner_argument)

Expand Down Expand Up @@ -1229,12 +1227,12 @@ class PythonUnittest(ExternalRunnerTest):
Python unittest test
"""

def __init__(self, name, params=None, base_logdir=None, job=None,
def __init__(self, name, params=None, base_logdir=None, config=None,
test_dir=None, python_unittest_module=None,
tags=None): # pylint: disable=W0613
runner = "%s -m unittest -q -c" % sys.executable
external_runner = ExternalRunnerSpec(runner, "test", test_dir)
super(PythonUnittest, self).__init__(name, params, base_logdir, job,
super(PythonUnittest, self).__init__(name, params, base_logdir, config,
external_runner=external_runner,
external_runner_argument=python_unittest_module)

Expand Down Expand Up @@ -1338,7 +1336,7 @@ def __init__(self, *args, **kwargs):
"""
super_kwargs = dict()
args = list(reversed(args))
for arg in ["methodName", "name", "params", "base_logdir", "job",
for arg in ["methodName", "name", "params", "base_logdir", "config",
"runner_queue"]:
if arg in kwargs:
super_kwargs[arg] = kwargs[arg]
Expand Down
6 changes: 5 additions & 1 deletion avocado/plugins/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ def sigterm_handler(signum, frame): # pylint: disable=W0613
instance.set_runner_queue(queue)
early_state = instance.get_state()
early_state['early_status'] = True
early_state['job_logdir'] = job.logdir
early_state['job_unique_id'] = job.unique_id
try:
queue.put(early_state)
except queueFullException:
Expand All @@ -118,6 +120,8 @@ def sigterm_handler(signum, frame): # pylint: disable=W0613
finally:
try:
state = instance.get_state()
state['job_logdir'] = job.logdir
state['job_unique_id'] = job.unique_id
queue.put(state)
except queueFullException:
instance.error(stacktrace.str_unpickable_object(state))
Expand Down Expand Up @@ -359,7 +363,7 @@ def run_suite(self, job, test_suite):
try:
for test_factory in test_suite.tests:
test_factory[1]["base_logdir"] = job.logdir
test_factory[1]["job"] = job
test_factory[1]["config"] = job.config
for test_factory, variant in self._iter_suite(test_suite,
execution_order):
test_parameters = test_factory[1]
Expand Down
2 changes: 1 addition & 1 deletion selftests/unit/test_jsonresult.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def test(self):
self.test_result = Result(UNIQUE_ID, LOGFILE)
self.test_result.filename = json_output_path
self.test_result.tests_total = 1
self.test1 = SimpleTest(job=self.job, base_logdir=self.tmpdir.name)
self.test1 = SimpleTest(config=self.job.config, base_logdir=self.tmpdir.name)
self.test1._Test__status = 'PASS'
self.test1.time_elapsed = 1.23

Expand Down
2 changes: 1 addition & 1 deletion selftests/unit/test_xunit.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def test(self):
self.test_result.tests_total = 1
self.test_result.logfile = ("/.../avocado/job-results/"
"job-2018-11-28T16.27-8fef221/job.log")
self.test1 = SimpleTest(job=self.job, base_logdir=self.tmpdir.name)
self.test1 = SimpleTest(config=self.job.config, base_logdir=self.tmpdir.name)
self.test1._Test__status = 'PASS'
self.test1._Test__logfile = ''
self.test1.time_elapsed = 678.23689
Expand Down

0 comments on commit e293590

Please sign in to comment.