mirror of
https://git.yoctoproject.org/poky
synced 2026-05-30 12:29:55 +00:00
oeqa/core/decorator: Add support for OETestDepends
The OETestDepends decorator could be used over test cases to define some dependency between them. At loading time sorting the tests to grauntee that a test case executes before also raise an exception if found a circular dependency between test cases. At before test case run reviews if the dependency if meet, in the case of don't it skips the test case run. (From OE-Core rev: 2385bd3c8a7c012fd1cad5465ec7d34675552c75) Signed-off-by: Aníbal Limón <anibal.limon@linux.intel.com> Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
13c8c08b95
commit
95a2ec6aab
@@ -0,0 +1,94 @@
|
|||||||
|
# Copyright (C) 2016 Intel Corporation
|
||||||
|
# Released under the MIT license (see COPYING.MIT)
|
||||||
|
|
||||||
|
from unittest import SkipTest
|
||||||
|
|
||||||
|
from oeqa.core.exception import OEQADependency
|
||||||
|
|
||||||
|
from . import OETestDiscover, registerDecorator
|
||||||
|
|
||||||
|
def _add_depends(registry, case, depends):
|
||||||
|
module_name = case.__module__
|
||||||
|
class_name = case.__class__.__name__
|
||||||
|
|
||||||
|
case_id = case.id()
|
||||||
|
|
||||||
|
for depend in depends:
|
||||||
|
dparts = depend.split('.')
|
||||||
|
|
||||||
|
if len(dparts) == 1:
|
||||||
|
depend_id = ".".join((module_name, class_name, dparts[0]))
|
||||||
|
elif len(dparts) == 2:
|
||||||
|
depend_id = ".".join((module_name, dparts[0], dparts[1]))
|
||||||
|
else:
|
||||||
|
depend_id = depend
|
||||||
|
|
||||||
|
if not case_id in registry:
|
||||||
|
registry[case_id] = []
|
||||||
|
if not depend_id in registry[case_id]:
|
||||||
|
registry[case_id].append(depend_id)
|
||||||
|
|
||||||
|
def _validate_test_case_depends(cases, depends):
|
||||||
|
for case in depends:
|
||||||
|
if not case in cases:
|
||||||
|
continue
|
||||||
|
for dep in depends[case]:
|
||||||
|
if not dep in cases:
|
||||||
|
raise OEQADependency("TestCase %s depends on %s and isn't available"\
|
||||||
|
", cases available %s." % (case, dep, str(cases.keys())))
|
||||||
|
|
||||||
|
def _order_test_case_by_depends(cases, depends):
|
||||||
|
def _dep_resolve(graph, node, resolved, seen):
|
||||||
|
seen.append(node)
|
||||||
|
for edge in graph[node]:
|
||||||
|
if edge not in resolved:
|
||||||
|
if edge in seen:
|
||||||
|
raise OEQADependency("Test cases %s and %s have a circular" \
|
||||||
|
" dependency." % (node, edge))
|
||||||
|
_dep_resolve(graph, edge, resolved, seen)
|
||||||
|
resolved.append(node)
|
||||||
|
|
||||||
|
dep_graph = {}
|
||||||
|
dep_graph['__root__'] = cases.keys()
|
||||||
|
for case in cases:
|
||||||
|
if case in depends:
|
||||||
|
dep_graph[case] = depends[case]
|
||||||
|
else:
|
||||||
|
dep_graph[case] = []
|
||||||
|
|
||||||
|
cases_ordered = []
|
||||||
|
_dep_resolve(dep_graph, '__root__', cases_ordered, [])
|
||||||
|
cases_ordered.remove('__root__')
|
||||||
|
|
||||||
|
return [cases[case_id] for case_id in cases_ordered]
|
||||||
|
|
||||||
|
def _skipTestDependency(case, depends):
|
||||||
|
results = case.tc._results
|
||||||
|
skipReasons = ['errors', 'failures', 'skipped']
|
||||||
|
|
||||||
|
for reason in skipReasons:
|
||||||
|
for test, _ in results[reason]:
|
||||||
|
if test.id() in depends:
|
||||||
|
raise SkipTest("Test case %s depends on %s and was in %s." \
|
||||||
|
% (case.id(), test.id(), reason))
|
||||||
|
|
||||||
|
@registerDecorator
|
||||||
|
class OETestDepends(OETestDiscover):
|
||||||
|
attrs = ('depends',)
|
||||||
|
|
||||||
|
def bind(self, registry, case):
|
||||||
|
super(OETestDepends, self).bind(registry, case)
|
||||||
|
if not registry.get('depends'):
|
||||||
|
registry['depends'] = {}
|
||||||
|
_add_depends(registry['depends'], case, self.depends)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def discover(registry):
|
||||||
|
if registry.get('depends'):
|
||||||
|
_validate_test_case_depends(registry['cases'], registry['depends'])
|
||||||
|
return _order_test_case_by_depends(registry['cases'], registry['depends'])
|
||||||
|
else:
|
||||||
|
return [registry['cases'][case_id] for case_id in registry['cases']]
|
||||||
|
|
||||||
|
def setUpDecorator(self):
|
||||||
|
_skipTestDependency(self.case, self.depends)
|
||||||
Reference in New Issue
Block a user