summaryrefslogtreecommitdiffstats
path: root/meta/lib/oeqa
diff options
context:
space:
mode:
authorAníbal Limón <anibal.limon@linux.intel.com>2016-11-09 11:09:07 -0600
committerRichard Purdie <richard.purdie@linuxfoundation.org>2017-01-23 12:05:18 +0000
commit95a2ec6aab25a666a7163e7ddb9fcbf51bfa4c7e (patch)
tree0a5924adafd2d2246d2420c5bc09ad802373f0e7 /meta/lib/oeqa
parent13c8c08b95191829705b5a4c8f0d368c251f0174 (diff)
downloadpoky-95a2ec6aab25a666a7163e7ddb9fcbf51bfa4c7e.tar.gz
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>
Diffstat (limited to 'meta/lib/oeqa')
-rw-r--r--meta/lib/oeqa/core/decorator/depends.py94
1 files changed, 94 insertions, 0 deletions
diff --git a/meta/lib/oeqa/core/decorator/depends.py b/meta/lib/oeqa/core/decorator/depends.py
new file mode 100644
index 0000000000..195711cf1e
--- /dev/null
+++ b/meta/lib/oeqa/core/decorator/depends.py
@@ -0,0 +1,94 @@
1# Copyright (C) 2016 Intel Corporation
2# Released under the MIT license (see COPYING.MIT)
3
4from unittest import SkipTest
5
6from oeqa.core.exception import OEQADependency
7
8from . import OETestDiscover, registerDecorator
9
10def _add_depends(registry, case, depends):
11 module_name = case.__module__
12 class_name = case.__class__.__name__
13
14 case_id = case.id()
15
16 for depend in depends:
17 dparts = depend.split('.')
18
19 if len(dparts) == 1:
20 depend_id = ".".join((module_name, class_name, dparts[0]))
21 elif len(dparts) == 2:
22 depend_id = ".".join((module_name, dparts[0], dparts[1]))
23 else:
24 depend_id = depend
25
26 if not case_id in registry:
27 registry[case_id] = []
28 if not depend_id in registry[case_id]:
29 registry[case_id].append(depend_id)
30
31def _validate_test_case_depends(cases, depends):
32 for case in depends:
33 if not case in cases:
34 continue
35 for dep in depends[case]:
36 if not dep in cases:
37 raise OEQADependency("TestCase %s depends on %s and isn't available"\
38 ", cases available %s." % (case, dep, str(cases.keys())))
39
40def _order_test_case_by_depends(cases, depends):
41 def _dep_resolve(graph, node, resolved, seen):
42 seen.append(node)
43 for edge in graph[node]:
44 if edge not in resolved:
45 if edge in seen:
46 raise OEQADependency("Test cases %s and %s have a circular" \
47 " dependency." % (node, edge))
48 _dep_resolve(graph, edge, resolved, seen)
49 resolved.append(node)
50
51 dep_graph = {}
52 dep_graph['__root__'] = cases.keys()
53 for case in cases:
54 if case in depends:
55 dep_graph[case] = depends[case]
56 else:
57 dep_graph[case] = []
58
59 cases_ordered = []
60 _dep_resolve(dep_graph, '__root__', cases_ordered, [])
61 cases_ordered.remove('__root__')
62
63 return [cases[case_id] for case_id in cases_ordered]
64
65def _skipTestDependency(case, depends):
66 results = case.tc._results
67 skipReasons = ['errors', 'failures', 'skipped']
68
69 for reason in skipReasons:
70 for test, _ in results[reason]:
71 if test.id() in depends:
72 raise SkipTest("Test case %s depends on %s and was in %s." \
73 % (case.id(), test.id(), reason))
74
75@registerDecorator
76class OETestDepends(OETestDiscover):
77 attrs = ('depends',)
78
79 def bind(self, registry, case):
80 super(OETestDepends, self).bind(registry, case)
81 if not registry.get('depends'):
82 registry['depends'] = {}
83 _add_depends(registry['depends'], case, self.depends)
84
85 @staticmethod
86 def discover(registry):
87 if registry.get('depends'):
88 _validate_test_case_depends(registry['cases'], registry['depends'])
89 return _order_test_case_by_depends(registry['cases'], registry['depends'])
90 else:
91 return [registry['cases'][case_id] for case_id in registry['cases']]
92
93 def setUpDecorator(self):
94 _skipTestDependency(self.case, self.depends)