diff options
Diffstat (limited to 'lib/oeqa/runtime/cases/xtf_minimal.py')
-rw-r--r-- | lib/oeqa/runtime/cases/xtf_minimal.py | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/lib/oeqa/runtime/cases/xtf_minimal.py b/lib/oeqa/runtime/cases/xtf_minimal.py new file mode 100644 index 00000000..6094cd92 --- /dev/null +++ b/lib/oeqa/runtime/cases/xtf_minimal.py | |||
@@ -0,0 +1,116 @@ | |||
1 | # | ||
2 | # SPDX-License-Identifier: MIT | ||
3 | # | ||
4 | # Author: Christopher Clark | ||
5 | # Copyright (c) Star Lab Corp, 2021 | ||
6 | # | ||
7 | # Integration of the Xen Test Framework (XTF) into OpenEmbedded QA | ||
8 | # | ||
9 | # Since not all XTF test cases are appropriate for all test environments, | ||
10 | # images or machine configurations the selection of XTF test cases to run | ||
11 | # is determined by variables that can be set in an image recipe. | ||
12 | # | ||
13 | # * XTF_TEST_CASES_POPULATE | ||
14 | # Specifies the list of queries passed to xtf-runner to populate the test list. | ||
15 | # eg. 'pv64 livepatch-priv-check' | ||
16 | # | ||
17 | # Since the space character is meaningful and may be required within a populate clause, | ||
18 | # the '|' character is used for separating multiple queries. | ||
19 | # eg. 'pv64 livepatch-priv-check|pv32pae selftest' | ||
20 | # | ||
21 | # * XTF_TEST_CASES_SKIP | ||
22 | # A space-separate list of test cases that should be skipped even if returned | ||
23 | # from the queries specified in XTF_TEST_CASES_POPULATE. | ||
24 | # eg. 'test-pv64-livepatch-priv-check' | ||
25 | # | ||
26 | # * XTF_TEST_CASES_REQUIRE | ||
27 | # A space-separate list of test cases that must not be skipped even if missing | ||
28 | # from the results of the queries specified in XTF_TEST_CASES_POPULATE. | ||
29 | |||
30 | #---------- | ||
31 | # The default single test case here is chosen because it exercises XTF | ||
32 | # and just Xen itself rather than any specifics of the hardware | ||
33 | # (virtual or not) that Xen is running on. | ||
34 | # TODO: this is an x86-specific test - revisit this choice when XTF supports Arm | ||
35 | DEFAULT_POPULATE = 'pv64 livepatch-priv-check' | ||
36 | #---------- | ||
37 | |||
38 | import json | ||
39 | from oeqa.runtime.case import OERuntimeTestCase | ||
40 | from oeqa.core.decorator.depends import OETestDepends | ||
41 | from oeqa.core.decorator.oetimeout import OETimeout | ||
42 | from oeqa.runtime.decorator.package import OEHasPackage | ||
43 | |||
44 | def xtf_runner_exit_status(state): | ||
45 | """ Convert a xtf-runner exit code to a test result. """ | ||
46 | return { 0: "SUCCESS", | ||
47 | 1: "sys.exit 1", | ||
48 | 2: "sys.exit 2", | ||
49 | 3: "SKIP", | ||
50 | 4: "ERROR", | ||
51 | 5: "FAILURE", | ||
52 | 6: "CRASH", | ||
53 | }[state] | ||
54 | |||
55 | xtf_rundir = '/usr/libexec/xtf' | ||
56 | |||
57 | class XTFMinimalTest(OERuntimeTestCase): | ||
58 | |||
59 | def query_xtf_cases(self, query_item): | ||
60 | (status, output) = self.target.run( | ||
61 | 'cd %s; ./xtf-runner --list %s' % \ | ||
62 | (xtf_rundir, query_item)) | ||
63 | self.assertTrue(status == 0, msg='XTF runner failed') | ||
64 | |||
65 | populate_case_lines = output.split('\n') | ||
66 | while '' in populate_case_lines: | ||
67 | populate_case_lines.remove('') | ||
68 | |||
69 | return list(map(lambda x: x.lstrip().rstrip(), populate_case_lines)) | ||
70 | |||
71 | def get_xtf_case_list(self): | ||
72 | xtf_cases = [] | ||
73 | |||
74 | populate = self.tc.td.get('XTF_TEST_CASES_POPULATE') | ||
75 | skip = self.tc.td.get('XTF_TEST_CASES_SKIP') | ||
76 | require = self.tc.td.get('XTF_TEST_CASES_REQUIRE') | ||
77 | |||
78 | if populate is None: | ||
79 | populate = DEFAULT_POPULATE | ||
80 | |||
81 | for query_item in populate.split('|'): | ||
82 | xtf_cases.extend( self.query_xtf_cases(query_item) ) | ||
83 | |||
84 | if skip is not None: | ||
85 | for skip_item in skip.split(' '): | ||
86 | while skip_item in xtf_cases: | ||
87 | xtf_cases.remove(skip_item) | ||
88 | |||
89 | if require is not None: | ||
90 | for require_item in require.split(' '): | ||
91 | if require_item == '': | ||
92 | continue | ||
93 | if not require_item in xtf_cases: | ||
94 | xtf_cases.append(require_item) | ||
95 | |||
96 | self.logger.info('XTF cases: %s' % str(xtf_cases)) | ||
97 | return xtf_cases | ||
98 | |||
99 | def run_xtf_case(self, xtf_case_name): | ||
100 | (status, output) = self.target.run('cd %s; ./xtf-runner %s' % \ | ||
101 | (xtf_rundir, xtf_case_name)) | ||
102 | self.assertTrue(status == 0, msg='XTF test %s failed: %s' % \ | ||
103 | (xtf_case_name, xtf_runner_exit_status(status))) | ||
104 | |||
105 | @OETimeout(2400) | ||
106 | @OETestDepends(['ssh.SSHTest.test_ssh']) | ||
107 | @OEHasPackage(['xtf']) | ||
108 | @OEHasPackage(['xen-tools']) | ||
109 | def test_xtf_minimal(self): | ||
110 | |||
111 | xtf_cases = self.get_xtf_case_list() | ||
112 | |||
113 | for xtf_case_name in xtf_cases: | ||
114 | self.logger.debug('Running XTF case: %s' % xtf_case_name) | ||
115 | |||
116 | self.run_xtf_case(xtf_case_name) | ||