diff options
Diffstat (limited to 'meta/lib/oeqa/selftest')
23 files changed, 432 insertions, 88 deletions
diff --git a/meta/lib/oeqa/selftest/cases/archiver.py b/meta/lib/oeqa/selftest/cases/archiver.py index bc5447d2a3..6a5c8ec71e 100644 --- a/meta/lib/oeqa/selftest/cases/archiver.py +++ b/meta/lib/oeqa/selftest/cases/archiver.py | |||
@@ -35,11 +35,11 @@ class Archiver(OESelftestTestCase): | |||
35 | src_path = os.path.join(bb_vars['DEPLOY_DIR_SRC'], bb_vars['TARGET_SYS']) | 35 | src_path = os.path.join(bb_vars['DEPLOY_DIR_SRC'], bb_vars['TARGET_SYS']) |
36 | 36 | ||
37 | # Check that include_recipe was included | 37 | # Check that include_recipe was included |
38 | included_present = len(glob.glob(src_path + '/%s-*' % include_recipe)) | 38 | included_present = len(glob.glob(src_path + '/%s-*/*' % include_recipe)) |
39 | self.assertTrue(included_present, 'Recipe %s was not included.' % include_recipe) | 39 | self.assertTrue(included_present, 'Recipe %s was not included.' % include_recipe) |
40 | 40 | ||
41 | # Check that exclude_recipe was excluded | 41 | # Check that exclude_recipe was excluded |
42 | excluded_present = len(glob.glob(src_path + '/%s-*' % exclude_recipe)) | 42 | excluded_present = len(glob.glob(src_path + '/%s-*/*' % exclude_recipe)) |
43 | self.assertFalse(excluded_present, 'Recipe %s was not excluded.' % exclude_recipe) | 43 | self.assertFalse(excluded_present, 'Recipe %s was not excluded.' % exclude_recipe) |
44 | 44 | ||
45 | def test_archiver_filters_by_type(self): | 45 | def test_archiver_filters_by_type(self): |
@@ -67,11 +67,11 @@ class Archiver(OESelftestTestCase): | |||
67 | src_path_native = os.path.join(bb_vars['DEPLOY_DIR_SRC'], bb_vars['BUILD_SYS']) | 67 | src_path_native = os.path.join(bb_vars['DEPLOY_DIR_SRC'], bb_vars['BUILD_SYS']) |
68 | 68 | ||
69 | # Check that target_recipe was included | 69 | # Check that target_recipe was included |
70 | included_present = len(glob.glob(src_path_target + '/%s-*' % target_recipe)) | 70 | included_present = len(glob.glob(src_path_target + '/%s-*/*' % target_recipe)) |
71 | self.assertTrue(included_present, 'Recipe %s was not included.' % target_recipe) | 71 | self.assertTrue(included_present, 'Recipe %s was not included.' % target_recipe) |
72 | 72 | ||
73 | # Check that native_recipe was excluded | 73 | # Check that native_recipe was excluded |
74 | excluded_present = len(glob.glob(src_path_native + '/%s-*' % native_recipe)) | 74 | excluded_present = len(glob.glob(src_path_native + '/%s-*/*' % native_recipe)) |
75 | self.assertFalse(excluded_present, 'Recipe %s was not excluded.' % native_recipe) | 75 | self.assertFalse(excluded_present, 'Recipe %s was not excluded.' % native_recipe) |
76 | 76 | ||
77 | def test_archiver_filters_by_type_and_name(self): | 77 | def test_archiver_filters_by_type_and_name(self): |
@@ -104,17 +104,17 @@ class Archiver(OESelftestTestCase): | |||
104 | src_path_native = os.path.join(bb_vars['DEPLOY_DIR_SRC'], bb_vars['BUILD_SYS']) | 104 | src_path_native = os.path.join(bb_vars['DEPLOY_DIR_SRC'], bb_vars['BUILD_SYS']) |
105 | 105 | ||
106 | # Check that target_recipe[0] and native_recipes[1] were included | 106 | # Check that target_recipe[0] and native_recipes[1] were included |
107 | included_present = len(glob.glob(src_path_target + '/%s-*' % target_recipes[0])) | 107 | included_present = len(glob.glob(src_path_target + '/%s-*/*' % target_recipes[0])) |
108 | self.assertTrue(included_present, 'Recipe %s was not included.' % target_recipes[0]) | 108 | self.assertTrue(included_present, 'Recipe %s was not included.' % target_recipes[0]) |
109 | 109 | ||
110 | included_present = len(glob.glob(src_path_native + '/%s-*' % native_recipes[1])) | 110 | included_present = len(glob.glob(src_path_native + '/%s-*/*' % native_recipes[1])) |
111 | self.assertTrue(included_present, 'Recipe %s was not included.' % native_recipes[1]) | 111 | self.assertTrue(included_present, 'Recipe %s was not included.' % native_recipes[1]) |
112 | 112 | ||
113 | # Check that native_recipes[0] and target_recipes[1] were excluded | 113 | # Check that native_recipes[0] and target_recipes[1] were excluded |
114 | excluded_present = len(glob.glob(src_path_native + '/%s-*' % native_recipes[0])) | 114 | excluded_present = len(glob.glob(src_path_native + '/%s-*/*' % native_recipes[0])) |
115 | self.assertFalse(excluded_present, 'Recipe %s was not excluded.' % native_recipes[0]) | 115 | self.assertFalse(excluded_present, 'Recipe %s was not excluded.' % native_recipes[0]) |
116 | 116 | ||
117 | excluded_present = len(glob.glob(src_path_target + '/%s-*' % target_recipes[1])) | 117 | excluded_present = len(glob.glob(src_path_target + '/%s-*/*' % target_recipes[1])) |
118 | self.assertFalse(excluded_present, 'Recipe %s was not excluded.' % target_recipes[1]) | 118 | self.assertFalse(excluded_present, 'Recipe %s was not excluded.' % target_recipes[1]) |
119 | 119 | ||
120 | 120 | ||
diff --git a/meta/lib/oeqa/selftest/cases/bblayers.py b/meta/lib/oeqa/selftest/cases/bblayers.py index f131d9856c..7d74833f61 100644 --- a/meta/lib/oeqa/selftest/cases/bblayers.py +++ b/meta/lib/oeqa/selftest/cases/bblayers.py | |||
@@ -12,6 +12,11 @@ from oeqa.selftest.case import OESelftestTestCase | |||
12 | 12 | ||
13 | class BitbakeLayers(OESelftestTestCase): | 13 | class BitbakeLayers(OESelftestTestCase): |
14 | 14 | ||
15 | def test_bitbakelayers_layerindexshowdepends(self): | ||
16 | result = runCmd('bitbake-layers layerindex-show-depends meta-poky') | ||
17 | find_in_contents = re.search("openembedded-core", result.output) | ||
18 | self.assertTrue(find_in_contents, msg = "openembedded-core should have been listed at this step. bitbake-layers layerindex-show-depends meta-poky output: %s" % result.output) | ||
19 | |||
15 | def test_bitbakelayers_showcrossdepends(self): | 20 | def test_bitbakelayers_showcrossdepends(self): |
16 | result = runCmd('bitbake-layers show-cross-depends') | 21 | result = runCmd('bitbake-layers show-cross-depends') |
17 | self.assertIn('aspell', result.output) | 22 | self.assertIn('aspell', result.output) |
diff --git a/meta/lib/oeqa/selftest/cases/bbtests.py b/meta/lib/oeqa/selftest/cases/bbtests.py index dc423ec439..0b88316950 100644 --- a/meta/lib/oeqa/selftest/cases/bbtests.py +++ b/meta/lib/oeqa/selftest/cases/bbtests.py | |||
@@ -148,9 +148,6 @@ INHERIT_remove = \"report-error\" | |||
148 | self.delete_recipeinc('man-db') | 148 | self.delete_recipeinc('man-db') |
149 | self.assertEqual(result.status, 1, msg="Command succeded when it should have failed. bitbake output: %s" % result.output) | 149 | self.assertEqual(result.status, 1, msg="Command succeded when it should have failed. bitbake output: %s" % result.output) |
150 | self.assertIn('Fetcher failure: Unable to find file file://invalid anywhere. The paths that were searched were:', result.output) | 150 | self.assertIn('Fetcher failure: Unable to find file file://invalid anywhere. The paths that were searched were:', result.output) |
151 | line = self.getline(result, 'Fetcher failure for URL: \'file://invalid\'. Unable to fetch URL from any source.') | ||
152 | self.assertTrue(line and line.startswith("ERROR:"), msg = "\"invalid\" file \ | ||
153 | doesn't exist, yet fetcher didn't report any error. bitbake output: %s" % result.output) | ||
154 | 151 | ||
155 | def test_rename_downloaded_file(self): | 152 | def test_rename_downloaded_file(self): |
156 | # TODO unique dldir instead of using cleanall | 153 | # TODO unique dldir instead of using cleanall |
@@ -160,7 +157,7 @@ SSTATE_DIR = \"${TOPDIR}/download-selftest\" | |||
160 | """) | 157 | """) |
161 | self.track_for_cleanup(os.path.join(self.builddir, "download-selftest")) | 158 | self.track_for_cleanup(os.path.join(self.builddir, "download-selftest")) |
162 | 159 | ||
163 | data = 'SRC_URI = "${GNU_MIRROR}/aspell/aspell-${PV}.tar.gz;downloadfilename=test-aspell.tar.gz"' | 160 | data = 'SRC_URI = "https://downloads.yoctoproject.org/mirror/sources/aspell-${PV}.tar.gz;downloadfilename=test-aspell.tar.gz"' |
164 | self.write_recipeinc('aspell', data) | 161 | self.write_recipeinc('aspell', data) |
165 | result = bitbake('-f -c fetch aspell', ignore_status=True) | 162 | result = bitbake('-f -c fetch aspell', ignore_status=True) |
166 | self.delete_recipeinc('aspell') | 163 | self.delete_recipeinc('aspell') |
@@ -188,6 +185,10 @@ SSTATE_DIR = \"${TOPDIR}/download-selftest\" | |||
188 | self.assertTrue(find, "No version returned for searched recipe. bitbake output: %s" % result.output) | 185 | self.assertTrue(find, "No version returned for searched recipe. bitbake output: %s" % result.output) |
189 | 186 | ||
190 | def test_prefile(self): | 187 | def test_prefile(self): |
188 | # Test when the prefile does not exist | ||
189 | result = runCmd('bitbake -r conf/prefile.conf', ignore_status=True) | ||
190 | self.assertEqual(1, result.status, "bitbake didn't error and should have when a specified prefile didn't exist: %s" % result.output) | ||
191 | # Test when the prefile exists | ||
191 | preconf = os.path.join(self.builddir, 'conf/prefile.conf') | 192 | preconf = os.path.join(self.builddir, 'conf/prefile.conf') |
192 | self.track_for_cleanup(preconf) | 193 | self.track_for_cleanup(preconf) |
193 | ftools.write_file(preconf ,"TEST_PREFILE=\"prefile\"") | 194 | ftools.write_file(preconf ,"TEST_PREFILE=\"prefile\"") |
@@ -198,6 +199,10 @@ SSTATE_DIR = \"${TOPDIR}/download-selftest\" | |||
198 | self.assertIn('localconf', result.output) | 199 | self.assertIn('localconf', result.output) |
199 | 200 | ||
200 | def test_postfile(self): | 201 | def test_postfile(self): |
202 | # Test when the postfile does not exist | ||
203 | result = runCmd('bitbake -R conf/postfile.conf', ignore_status=True) | ||
204 | self.assertEqual(1, result.status, "bitbake didn't error and should have when a specified postfile didn't exist: %s" % result.output) | ||
205 | # Test when the postfile exists | ||
201 | postconf = os.path.join(self.builddir, 'conf/postfile.conf') | 206 | postconf = os.path.join(self.builddir, 'conf/postfile.conf') |
202 | self.track_for_cleanup(postconf) | 207 | self.track_for_cleanup(postconf) |
203 | ftools.write_file(postconf , "TEST_POSTFILE=\"postfile\"") | 208 | ftools.write_file(postconf , "TEST_POSTFILE=\"postfile\"") |
diff --git a/meta/lib/oeqa/selftest/cases/buildoptions.py b/meta/lib/oeqa/selftest/cases/buildoptions.py index e91f0bd18f..b1b9ea7e55 100644 --- a/meta/lib/oeqa/selftest/cases/buildoptions.py +++ b/meta/lib/oeqa/selftest/cases/buildoptions.py | |||
@@ -57,15 +57,15 @@ class ImageOptionsTests(OESelftestTestCase): | |||
57 | class DiskMonTest(OESelftestTestCase): | 57 | class DiskMonTest(OESelftestTestCase): |
58 | 58 | ||
59 | def test_stoptask_behavior(self): | 59 | def test_stoptask_behavior(self): |
60 | self.write_config('BB_DISKMON_DIRS = "STOPTASKS,${TMPDIR},100000G,100K"') | 60 | self.write_config('BB_DISKMON_DIRS = "STOPTASKS,${TMPDIR},100000G,100K"\nBB_HEARTBEAT_EVENT = "1"') |
61 | res = bitbake("delay -c delay", ignore_status = True) | 61 | res = bitbake("delay -c delay", ignore_status = True) |
62 | self.assertTrue('ERROR: No new tasks can be executed since the disk space monitor action is "STOPTASKS"!' in res.output, msg = "Tasks should have stopped. Disk monitor is set to STOPTASK: %s" % res.output) | 62 | self.assertTrue('ERROR: No new tasks can be executed since the disk space monitor action is "STOPTASKS"!' in res.output, msg = "Tasks should have stopped. Disk monitor is set to STOPTASK: %s" % res.output) |
63 | self.assertEqual(res.status, 1, msg = "bitbake reported exit code %s. It should have been 1. Bitbake output: %s" % (str(res.status), res.output)) | 63 | self.assertEqual(res.status, 1, msg = "bitbake reported exit code %s. It should have been 1. Bitbake output: %s" % (str(res.status), res.output)) |
64 | self.write_config('BB_DISKMON_DIRS = "ABORT,${TMPDIR},100000G,100K"') | 64 | self.write_config('BB_DISKMON_DIRS = "ABORT,${TMPDIR},100000G,100K"\nBB_HEARTBEAT_EVENT = "1"') |
65 | res = bitbake("delay -c delay", ignore_status = True) | 65 | res = bitbake("delay -c delay", ignore_status = True) |
66 | self.assertTrue('ERROR: Immediately abort since the disk space monitor action is "ABORT"!' in res.output, "Tasks should have been aborted immediatelly. Disk monitor is set to ABORT: %s" % res.output) | 66 | self.assertTrue('ERROR: Immediately abort since the disk space monitor action is "ABORT"!' in res.output, "Tasks should have been aborted immediatelly. Disk monitor is set to ABORT: %s" % res.output) |
67 | self.assertEqual(res.status, 1, msg = "bitbake reported exit code %s. It should have been 1. Bitbake output: %s" % (str(res.status), res.output)) | 67 | self.assertEqual(res.status, 1, msg = "bitbake reported exit code %s. It should have been 1. Bitbake output: %s" % (str(res.status), res.output)) |
68 | self.write_config('BB_DISKMON_DIRS = "WARN,${TMPDIR},100000G,100K"') | 68 | self.write_config('BB_DISKMON_DIRS = "WARN,${TMPDIR},100000G,100K"\nBB_HEARTBEAT_EVENT = "1"') |
69 | res = bitbake("delay -c delay") | 69 | res = bitbake("delay -c delay") |
70 | self.assertTrue('WARNING: The free space' in res.output, msg = "A warning should have been displayed for disk monitor is set to WARN: %s" %res.output) | 70 | self.assertTrue('WARNING: The free space' in res.output, msg = "A warning should have been displayed for disk monitor is set to WARN: %s" %res.output) |
71 | 71 | ||
diff --git a/meta/lib/oeqa/selftest/cases/cve_check.py b/meta/lib/oeqa/selftest/cases/cve_check.py index 3f343a2841..22ffeffd29 100644 --- a/meta/lib/oeqa/selftest/cases/cve_check.py +++ b/meta/lib/oeqa/selftest/cases/cve_check.py | |||
@@ -1,9 +1,13 @@ | |||
1 | from oe.cve_check import Version | 1 | import json |
2 | import os | ||
2 | from oeqa.selftest.case import OESelftestTestCase | 3 | from oeqa.selftest.case import OESelftestTestCase |
4 | from oeqa.utils.commands import bitbake, get_bb_vars | ||
3 | 5 | ||
4 | class CVECheck(OESelftestTestCase): | 6 | class CVECheck(OESelftestTestCase): |
5 | 7 | ||
6 | def test_version_compare(self): | 8 | def test_version_compare(self): |
9 | from oe.cve_check import Version | ||
10 | |||
7 | result = Version("100") > Version("99") | 11 | result = Version("100") > Version("99") |
8 | self.assertTrue( result, msg="Failed to compare version '100' > '99'") | 12 | self.assertTrue( result, msg="Failed to compare version '100' > '99'") |
9 | result = Version("2.3.1") > Version("2.2.3") | 13 | result = Version("2.3.1") > Version("2.2.3") |
@@ -34,3 +38,183 @@ class CVECheck(OESelftestTestCase): | |||
34 | self.assertTrue( result ,msg="Failed to compare version with suffix '1.0b' < '1.0r'") | 38 | self.assertTrue( result ,msg="Failed to compare version with suffix '1.0b' < '1.0r'") |
35 | result = Version("1.0b","alphabetical") > Version("1.0","alphabetical") | 39 | result = Version("1.0b","alphabetical") > Version("1.0","alphabetical") |
36 | self.assertTrue( result ,msg="Failed to compare version with suffix '1.0b' > '1.0'") | 40 | self.assertTrue( result ,msg="Failed to compare version with suffix '1.0b' > '1.0'") |
41 | |||
42 | # consider the trailing "p" and "patch" as patched released when comparing | ||
43 | result = Version("1.0","patch") < Version("1.0p1","patch") | ||
44 | self.assertTrue( result ,msg="Failed to compare version with suffix '1.0' < '1.0p1'") | ||
45 | result = Version("1.0p2","patch") > Version("1.0p1","patch") | ||
46 | self.assertTrue( result ,msg="Failed to compare version with suffix '1.0p2' > '1.0p1'") | ||
47 | result = Version("1.0_patch2","patch") < Version("1.0_patch3","patch") | ||
48 | self.assertTrue( result ,msg="Failed to compare version with suffix '1.0_patch2' < '1.0_patch3'") | ||
49 | |||
50 | |||
51 | def test_convert_cve_version(self): | ||
52 | from oe.cve_check import convert_cve_version | ||
53 | |||
54 | # Default format | ||
55 | self.assertEqual(convert_cve_version("8.3"), "8.3") | ||
56 | self.assertEqual(convert_cve_version(""), "") | ||
57 | |||
58 | # OpenSSL format version | ||
59 | self.assertEqual(convert_cve_version("1.1.1t"), "1.1.1t") | ||
60 | |||
61 | # OpenSSH format | ||
62 | self.assertEqual(convert_cve_version("8.3_p1"), "8.3p1") | ||
63 | self.assertEqual(convert_cve_version("8.3_p22"), "8.3p22") | ||
64 | |||
65 | # Linux kernel format | ||
66 | self.assertEqual(convert_cve_version("6.2_rc8"), "6.2-rc8") | ||
67 | self.assertEqual(convert_cve_version("6.2_rc31"), "6.2-rc31") | ||
68 | |||
69 | |||
70 | def test_recipe_report_json(self): | ||
71 | config = """ | ||
72 | INHERIT += "cve-check" | ||
73 | CVE_CHECK_FORMAT_JSON = "1" | ||
74 | """ | ||
75 | self.write_config(config) | ||
76 | |||
77 | vars = get_bb_vars(["CVE_CHECK_SUMMARY_DIR", "CVE_CHECK_SUMMARY_FILE_NAME_JSON"]) | ||
78 | summary_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], vars["CVE_CHECK_SUMMARY_FILE_NAME_JSON"]) | ||
79 | recipe_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], "m4-native_cve.json") | ||
80 | |||
81 | try: | ||
82 | os.remove(summary_json) | ||
83 | os.remove(recipe_json) | ||
84 | except FileNotFoundError: | ||
85 | pass | ||
86 | |||
87 | bitbake("m4-native -c cve_check") | ||
88 | |||
89 | def check_m4_json(filename): | ||
90 | with open(filename) as f: | ||
91 | report = json.load(f) | ||
92 | self.assertEqual(report["version"], "1") | ||
93 | self.assertEqual(len(report["package"]), 1) | ||
94 | package = report["package"][0] | ||
95 | self.assertEqual(package["name"], "m4-native") | ||
96 | found_cves = { issue["id"]: issue["status"] for issue in package["issue"]} | ||
97 | self.assertIn("CVE-2008-1687", found_cves) | ||
98 | self.assertEqual(found_cves["CVE-2008-1687"], "Patched") | ||
99 | |||
100 | self.assertExists(summary_json) | ||
101 | check_m4_json(summary_json) | ||
102 | self.assertExists(recipe_json) | ||
103 | check_m4_json(recipe_json) | ||
104 | |||
105 | |||
106 | def test_image_json(self): | ||
107 | config = """ | ||
108 | INHERIT += "cve-check" | ||
109 | CVE_CHECK_FORMAT_JSON = "1" | ||
110 | """ | ||
111 | self.write_config(config) | ||
112 | |||
113 | vars = get_bb_vars(["CVE_CHECK_DIR", "CVE_CHECK_SUMMARY_DIR", "CVE_CHECK_SUMMARY_FILE_NAME_JSON"]) | ||
114 | report_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], vars["CVE_CHECK_SUMMARY_FILE_NAME_JSON"]) | ||
115 | print(report_json) | ||
116 | try: | ||
117 | os.remove(report_json) | ||
118 | except FileNotFoundError: | ||
119 | pass | ||
120 | |||
121 | bitbake("core-image-minimal-initramfs") | ||
122 | self.assertExists(report_json) | ||
123 | |||
124 | # Check that the summary report lists at least one package | ||
125 | with open(report_json) as f: | ||
126 | report = json.load(f) | ||
127 | self.assertEqual(report["version"], "1") | ||
128 | self.assertGreater(len(report["package"]), 1) | ||
129 | |||
130 | # Check that a random recipe wrote a recipe report to deploy/cve/ | ||
131 | recipename = report["package"][0]["name"] | ||
132 | recipe_report = os.path.join(vars["CVE_CHECK_DIR"], recipename + "_cve.json") | ||
133 | self.assertExists(recipe_report) | ||
134 | with open(recipe_report) as f: | ||
135 | report = json.load(f) | ||
136 | self.assertEqual(report["version"], "1") | ||
137 | self.assertEqual(len(report["package"]), 1) | ||
138 | self.assertEqual(report["package"][0]["name"], recipename) | ||
139 | |||
140 | |||
141 | def test_recipe_report_json_unpatched(self): | ||
142 | config = """ | ||
143 | INHERIT += "cve-check" | ||
144 | CVE_CHECK_FORMAT_JSON = "1" | ||
145 | CVE_CHECK_REPORT_PATCHED = "0" | ||
146 | """ | ||
147 | self.write_config(config) | ||
148 | |||
149 | vars = get_bb_vars(["CVE_CHECK_SUMMARY_DIR", "CVE_CHECK_SUMMARY_FILE_NAME_JSON"]) | ||
150 | summary_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], vars["CVE_CHECK_SUMMARY_FILE_NAME_JSON"]) | ||
151 | recipe_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], "m4-native_cve.json") | ||
152 | |||
153 | try: | ||
154 | os.remove(summary_json) | ||
155 | os.remove(recipe_json) | ||
156 | except FileNotFoundError: | ||
157 | pass | ||
158 | |||
159 | bitbake("m4-native -c cve_check") | ||
160 | |||
161 | def check_m4_json(filename): | ||
162 | with open(filename) as f: | ||
163 | report = json.load(f) | ||
164 | self.assertEqual(report["version"], "1") | ||
165 | self.assertEqual(len(report["package"]), 1) | ||
166 | package = report["package"][0] | ||
167 | self.assertEqual(package["name"], "m4-native") | ||
168 | #m4 had only Patched CVEs, so the issues array will be empty | ||
169 | self.assertEqual(package["issue"], []) | ||
170 | |||
171 | self.assertExists(summary_json) | ||
172 | check_m4_json(summary_json) | ||
173 | self.assertExists(recipe_json) | ||
174 | check_m4_json(recipe_json) | ||
175 | |||
176 | |||
177 | def test_recipe_report_json_ignored(self): | ||
178 | config = """ | ||
179 | INHERIT += "cve-check" | ||
180 | CVE_CHECK_FORMAT_JSON = "1" | ||
181 | CVE_CHECK_REPORT_PATCHED = "1" | ||
182 | """ | ||
183 | self.write_config(config) | ||
184 | |||
185 | vars = get_bb_vars(["CVE_CHECK_SUMMARY_DIR", "CVE_CHECK_SUMMARY_FILE_NAME_JSON"]) | ||
186 | summary_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], vars["CVE_CHECK_SUMMARY_FILE_NAME_JSON"]) | ||
187 | recipe_json = os.path.join(vars["CVE_CHECK_SUMMARY_DIR"], "logrotate_cve.json") | ||
188 | |||
189 | try: | ||
190 | os.remove(summary_json) | ||
191 | os.remove(recipe_json) | ||
192 | except FileNotFoundError: | ||
193 | pass | ||
194 | |||
195 | bitbake("logrotate -c cve_check") | ||
196 | |||
197 | def check_m4_json(filename): | ||
198 | with open(filename) as f: | ||
199 | report = json.load(f) | ||
200 | self.assertEqual(report["version"], "1") | ||
201 | self.assertEqual(len(report["package"]), 1) | ||
202 | package = report["package"][0] | ||
203 | self.assertEqual(package["name"], "logrotate") | ||
204 | found_cves = { issue["id"]: issue["status"] for issue in package["issue"]} | ||
205 | # m4 CVE should not be in logrotate | ||
206 | self.assertNotIn("CVE-2008-1687", found_cves) | ||
207 | # logrotate has both Patched and Ignored CVEs | ||
208 | self.assertIn("CVE-2011-1098", found_cves) | ||
209 | self.assertEqual(found_cves["CVE-2011-1098"], "Patched") | ||
210 | self.assertIn("CVE-2011-1548", found_cves) | ||
211 | self.assertEqual(found_cves["CVE-2011-1548"], "Ignored") | ||
212 | self.assertIn("CVE-2011-1549", found_cves) | ||
213 | self.assertEqual(found_cves["CVE-2011-1549"], "Ignored") | ||
214 | self.assertIn("CVE-2011-1550", found_cves) | ||
215 | self.assertEqual(found_cves["CVE-2011-1550"], "Ignored") | ||
216 | |||
217 | self.assertExists(summary_json) | ||
218 | check_m4_json(summary_json) | ||
219 | self.assertExists(recipe_json) | ||
220 | check_m4_json(recipe_json) | ||
diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index 0985434238..9efe342a0d 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py | |||
@@ -8,6 +8,7 @@ import shutil | |||
8 | import tempfile | 8 | import tempfile |
9 | import glob | 9 | import glob |
10 | import fnmatch | 10 | import fnmatch |
11 | import unittest | ||
11 | 12 | ||
12 | import oeqa.utils.ftools as ftools | 13 | import oeqa.utils.ftools as ftools |
13 | from oeqa.selftest.case import OESelftestTestCase | 14 | from oeqa.selftest.case import OESelftestTestCase |
@@ -38,6 +39,13 @@ def setUpModule(): | |||
38 | canonical_layerpath = os.path.realpath(canonical_layerpath) + '/' | 39 | canonical_layerpath = os.path.realpath(canonical_layerpath) + '/' |
39 | edited_layers.append(layerpath) | 40 | edited_layers.append(layerpath) |
40 | oldmetapath = os.path.realpath(layerpath) | 41 | oldmetapath = os.path.realpath(layerpath) |
42 | |||
43 | # when downloading poky from tar.gz some tests will be skipped (BUG 12389) | ||
44 | try: | ||
45 | runCmd('git rev-parse --is-inside-work-tree', cwd=canonical_layerpath) | ||
46 | except: | ||
47 | raise unittest.SkipTest("devtool tests require folder to be a git repo") | ||
48 | |||
41 | result = runCmd('git rev-parse --show-toplevel', cwd=canonical_layerpath) | 49 | result = runCmd('git rev-parse --show-toplevel', cwd=canonical_layerpath) |
42 | oldreporoot = result.output.rstrip() | 50 | oldreporoot = result.output.rstrip() |
43 | newmetapath = os.path.join(corecopydir, os.path.relpath(oldmetapath, oldreporoot)) | 51 | newmetapath = os.path.join(corecopydir, os.path.relpath(oldmetapath, oldreporoot)) |
@@ -340,7 +348,7 @@ class DevtoolAddTests(DevtoolBase): | |||
340 | checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263' | 348 | checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263' |
341 | checkvars['S'] = '${WORKDIR}/git' | 349 | checkvars['S'] = '${WORKDIR}/git' |
342 | checkvars['PV'] = '0.1+git${SRCPV}' | 350 | checkvars['PV'] = '0.1+git${SRCPV}' |
343 | checkvars['SRC_URI'] = 'git://git.yoctoproject.org/git/dbus-wait;protocol=https' | 351 | checkvars['SRC_URI'] = 'git://git.yoctoproject.org/git/dbus-wait;protocol=https;branch=master' |
344 | checkvars['SRCREV'] = srcrev | 352 | checkvars['SRCREV'] = srcrev |
345 | checkvars['DEPENDS'] = set(['dbus']) | 353 | checkvars['DEPENDS'] = set(['dbus']) |
346 | self._test_recipe_contents(recipefile, checkvars, []) | 354 | self._test_recipe_contents(recipefile, checkvars, []) |
@@ -442,6 +450,7 @@ class DevtoolAddTests(DevtoolBase): | |||
442 | tempdir = tempfile.mkdtemp(prefix='devtoolqa') | 450 | tempdir = tempfile.mkdtemp(prefix='devtoolqa') |
443 | self.track_for_cleanup(tempdir) | 451 | self.track_for_cleanup(tempdir) |
444 | url = 'gitsm://git.yoctoproject.org/mraa' | 452 | url = 'gitsm://git.yoctoproject.org/mraa' |
453 | url_branch = '%s;branch=master' % url | ||
445 | checkrev = 'ae127b19a50aa54255e4330ccfdd9a5d058e581d' | 454 | checkrev = 'ae127b19a50aa54255e4330ccfdd9a5d058e581d' |
446 | testrecipe = 'mraa' | 455 | testrecipe = 'mraa' |
447 | srcdir = os.path.join(tempdir, testrecipe) | 456 | srcdir = os.path.join(tempdir, testrecipe) |
@@ -462,7 +471,7 @@ class DevtoolAddTests(DevtoolBase): | |||
462 | checkvars = {} | 471 | checkvars = {} |
463 | checkvars['S'] = '${WORKDIR}/git' | 472 | checkvars['S'] = '${WORKDIR}/git' |
464 | checkvars['PV'] = '1.0+git${SRCPV}' | 473 | checkvars['PV'] = '1.0+git${SRCPV}' |
465 | checkvars['SRC_URI'] = url | 474 | checkvars['SRC_URI'] = url_branch |
466 | checkvars['SRCREV'] = '${AUTOREV}' | 475 | checkvars['SRCREV'] = '${AUTOREV}' |
467 | self._test_recipe_contents(recipefile, checkvars, []) | 476 | self._test_recipe_contents(recipefile, checkvars, []) |
468 | # Try with revision and version specified | 477 | # Try with revision and version specified |
@@ -481,7 +490,7 @@ class DevtoolAddTests(DevtoolBase): | |||
481 | checkvars = {} | 490 | checkvars = {} |
482 | checkvars['S'] = '${WORKDIR}/git' | 491 | checkvars['S'] = '${WORKDIR}/git' |
483 | checkvars['PV'] = '1.5+git${SRCPV}' | 492 | checkvars['PV'] = '1.5+git${SRCPV}' |
484 | checkvars['SRC_URI'] = url | 493 | checkvars['SRC_URI'] = url_branch |
485 | checkvars['SRCREV'] = checkrev | 494 | checkvars['SRCREV'] = checkrev |
486 | self._test_recipe_contents(recipefile, checkvars, []) | 495 | self._test_recipe_contents(recipefile, checkvars, []) |
487 | 496 | ||
@@ -880,7 +889,7 @@ class DevtoolUpdateTests(DevtoolBase): | |||
880 | self._check_repo_status(os.path.dirname(recipefile), expected_status) | 889 | self._check_repo_status(os.path.dirname(recipefile), expected_status) |
881 | 890 | ||
882 | result = runCmd('git diff %s' % os.path.basename(recipefile), cwd=os.path.dirname(recipefile)) | 891 | result = runCmd('git diff %s' % os.path.basename(recipefile), cwd=os.path.dirname(recipefile)) |
883 | addlines = ['SRCREV = ".*"', 'SRC_URI = "git://git.infradead.org/mtd-utils.git"'] | 892 | addlines = ['SRCREV = ".*"', 'SRC_URI = "git://git.infradead.org/mtd-utils.git;branch=master"'] |
884 | srcurilines = src_uri.split() | 893 | srcurilines = src_uri.split() |
885 | srcurilines[0] = 'SRC_URI = "' + srcurilines[0] | 894 | srcurilines[0] = 'SRC_URI = "' + srcurilines[0] |
886 | srcurilines.append('"') | 895 | srcurilines.append('"') |
@@ -1322,7 +1331,7 @@ class DevtoolExtractTests(DevtoolBase): | |||
1322 | # Now really test deploy-target | 1331 | # Now really test deploy-target |
1323 | result = runCmd('devtool deploy-target -c %s root@%s' % (testrecipe, qemu.ip)) | 1332 | result = runCmd('devtool deploy-target -c %s root@%s' % (testrecipe, qemu.ip)) |
1324 | # Run a test command to see if it was installed properly | 1333 | # Run a test command to see if it was installed properly |
1325 | sshargs = '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' | 1334 | sshargs = '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o HostKeyAlgorithms=+ssh-rsa' |
1326 | result = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, testcommand)) | 1335 | result = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, testcommand)) |
1327 | # Check if it deployed all of the files with the right ownership/perms | 1336 | # Check if it deployed all of the files with the right ownership/perms |
1328 | # First look on the host - need to do this under pseudo to get the correct ownership/perms | 1337 | # First look on the host - need to do this under pseudo to get the correct ownership/perms |
diff --git a/meta/lib/oeqa/selftest/cases/diffoscope/A/file.txt b/meta/lib/oeqa/selftest/cases/diffoscope/A/file.txt new file mode 100644 index 0000000000..f70f10e4db --- /dev/null +++ b/meta/lib/oeqa/selftest/cases/diffoscope/A/file.txt | |||
@@ -0,0 +1 @@ | |||
A | |||
diff --git a/meta/lib/oeqa/selftest/cases/diffoscope/B/file.txt b/meta/lib/oeqa/selftest/cases/diffoscope/B/file.txt new file mode 100644 index 0000000000..223b7836fb --- /dev/null +++ b/meta/lib/oeqa/selftest/cases/diffoscope/B/file.txt | |||
@@ -0,0 +1 @@ | |||
B | |||
diff --git a/meta/lib/oeqa/selftest/cases/distrodata.py b/meta/lib/oeqa/selftest/cases/distrodata.py index e1cfc3b621..8e5e24db3d 100644 --- a/meta/lib/oeqa/selftest/cases/distrodata.py +++ b/meta/lib/oeqa/selftest/cases/distrodata.py | |||
@@ -63,7 +63,7 @@ but their recipes claim otherwise by setting UPSTREAM_VERSION_UNKNOWN. Please re | |||
63 | return True | 63 | return True |
64 | return False | 64 | return False |
65 | 65 | ||
66 | feature = 'require conf/distro/include/maintainers.inc\nLICENSE_FLAGS_WHITELIST += " commercial"\nPARSE_ALL_RECIPES = "1"\n' | 66 | feature = 'require conf/distro/include/maintainers.inc\nLICENSE_FLAGS_WHITELIST += " commercial"\nPARSE_ALL_RECIPES = "1"\nPACKAGE_CLASSES = "package_ipk package_deb package_rpm"\n' |
67 | self.write_config(feature) | 67 | self.write_config(feature) |
68 | 68 | ||
69 | with bb.tinfoil.Tinfoil() as tinfoil: | 69 | with bb.tinfoil.Tinfoil() as tinfoil: |
diff --git a/meta/lib/oeqa/selftest/cases/glibc.py b/meta/lib/oeqa/selftest/cases/glibc.py index c687f6ef93..c1f6e4c1fb 100644 --- a/meta/lib/oeqa/selftest/cases/glibc.py +++ b/meta/lib/oeqa/selftest/cases/glibc.py | |||
@@ -33,7 +33,7 @@ class GlibcSelfTestBase(OESelftestTestCase, OEPTestResultTestCase): | |||
33 | 33 | ||
34 | ptestsuite = "glibc-user" if ssh is None else "glibc" | 34 | ptestsuite = "glibc-user" if ssh is None else "glibc" |
35 | self.ptest_section(ptestsuite) | 35 | self.ptest_section(ptestsuite) |
36 | with open(os.path.join(builddir, "tests.sum"), "r") as f: | 36 | with open(os.path.join(builddir, "tests.sum"), "r", errors='replace') as f: |
37 | for test, result in parse_values(f): | 37 | for test, result in parse_values(f): |
38 | self.ptest_result(ptestsuite, test, result) | 38 | self.ptest_result(ptestsuite, test, result) |
39 | 39 | ||
@@ -41,7 +41,7 @@ class GlibcSelfTestBase(OESelftestTestCase, OEPTestResultTestCase): | |||
41 | with contextlib.ExitStack() as s: | 41 | with contextlib.ExitStack() as s: |
42 | # use the base work dir, as the nfs mount, since the recipe directory may not exist | 42 | # use the base work dir, as the nfs mount, since the recipe directory may not exist |
43 | tmpdir = get_bb_var("BASE_WORKDIR") | 43 | tmpdir = get_bb_var("BASE_WORKDIR") |
44 | nfsport, mountport = s.enter_context(unfs_server(tmpdir)) | 44 | nfsport, mountport = s.enter_context(unfs_server(tmpdir, udp = False)) |
45 | 45 | ||
46 | # build core-image-minimal with required packages | 46 | # build core-image-minimal with required packages |
47 | default_installed_packages = [ | 47 | default_installed_packages = [ |
@@ -61,7 +61,7 @@ class GlibcSelfTestBase(OESelftestTestCase, OEPTestResultTestCase): | |||
61 | bitbake("core-image-minimal") | 61 | bitbake("core-image-minimal") |
62 | 62 | ||
63 | # start runqemu | 63 | # start runqemu |
64 | qemu = s.enter_context(runqemu("core-image-minimal", runqemuparams = "nographic")) | 64 | qemu = s.enter_context(runqemu("core-image-minimal", runqemuparams = "nographic", qemuparams = "-m 1024")) |
65 | 65 | ||
66 | # validate that SSH is working | 66 | # validate that SSH is working |
67 | status, _ = qemu.run("uname") | 67 | status, _ = qemu.run("uname") |
@@ -70,7 +70,7 @@ class GlibcSelfTestBase(OESelftestTestCase, OEPTestResultTestCase): | |||
70 | # setup nfs mount | 70 | # setup nfs mount |
71 | if qemu.run("mkdir -p \"{0}\"".format(tmpdir))[0] != 0: | 71 | if qemu.run("mkdir -p \"{0}\"".format(tmpdir))[0] != 0: |
72 | raise Exception("Failed to setup NFS mount directory on target") | 72 | raise Exception("Failed to setup NFS mount directory on target") |
73 | mountcmd = "mount -o noac,nfsvers=3,port={0},udp,mountport={1} \"{2}:{3}\" \"{3}\"".format(nfsport, mountport, qemu.server_ip, tmpdir) | 73 | mountcmd = "mount -o noac,nfsvers=3,port={0},mountport={1} \"{2}:{3}\" \"{3}\"".format(nfsport, mountport, qemu.server_ip, tmpdir) |
74 | status, output = qemu.run(mountcmd) | 74 | status, output = qemu.run(mountcmd) |
75 | if status != 0: | 75 | if status != 0: |
76 | raise Exception("Failed to setup NFS mount on target ({})".format(repr(output))) | 76 | raise Exception("Failed to setup NFS mount on target ({})".format(repr(output))) |
diff --git a/meta/lib/oeqa/selftest/cases/gotoolchain.py b/meta/lib/oeqa/selftest/cases/gotoolchain.py index 3119520f0d..59f80aad28 100644 --- a/meta/lib/oeqa/selftest/cases/gotoolchain.py +++ b/meta/lib/oeqa/selftest/cases/gotoolchain.py | |||
@@ -43,6 +43,12 @@ class oeGoToolchainSelfTest(OESelftestTestCase): | |||
43 | 43 | ||
44 | @classmethod | 44 | @classmethod |
45 | def tearDownClass(cls): | 45 | def tearDownClass(cls): |
46 | # Go creates file which are readonly | ||
47 | for dirpath, dirnames, filenames in os.walk(cls.tmpdir_SDKQA): | ||
48 | for filename in filenames + dirnames: | ||
49 | f = os.path.join(dirpath, filename) | ||
50 | if not os.path.islink(f): | ||
51 | os.chmod(f, 0o775) | ||
46 | shutil.rmtree(cls.tmpdir_SDKQA, ignore_errors=True) | 52 | shutil.rmtree(cls.tmpdir_SDKQA, ignore_errors=True) |
47 | super(oeGoToolchainSelfTest, cls).tearDownClass() | 53 | super(oeGoToolchainSelfTest, cls).tearDownClass() |
48 | 54 | ||
diff --git a/meta/lib/oeqa/selftest/cases/imagefeatures.py b/meta/lib/oeqa/selftest/cases/imagefeatures.py index 2b9c4998f7..535d80cb86 100644 --- a/meta/lib/oeqa/selftest/cases/imagefeatures.py +++ b/meta/lib/oeqa/selftest/cases/imagefeatures.py | |||
@@ -240,7 +240,7 @@ USERADD_GID_TABLES += "files/static-group" | |||
240 | def test_no_busybox_base_utils(self): | 240 | def test_no_busybox_base_utils(self): |
241 | config = """ | 241 | config = """ |
242 | # Enable x11 | 242 | # Enable x11 |
243 | DISTRO_FEATURES_append += "x11" | 243 | DISTRO_FEATURES_append = " x11" |
244 | 244 | ||
245 | # Switch to systemd | 245 | # Switch to systemd |
246 | DISTRO_FEATURES += "systemd" | 246 | DISTRO_FEATURES += "systemd" |
diff --git a/meta/lib/oeqa/selftest/cases/oelib/utils.py b/meta/lib/oeqa/selftest/cases/oelib/utils.py index a7214beb4c..bbf67bf9c9 100644 --- a/meta/lib/oeqa/selftest/cases/oelib/utils.py +++ b/meta/lib/oeqa/selftest/cases/oelib/utils.py | |||
@@ -64,7 +64,7 @@ class TestMultiprocessLaunch(TestCase): | |||
64 | import bb | 64 | import bb |
65 | 65 | ||
66 | def testfunction(item, d): | 66 | def testfunction(item, d): |
67 | if item == "2" or item == "1": | 67 | if item == "2": |
68 | raise KeyError("Invalid number %s" % item) | 68 | raise KeyError("Invalid number %s" % item) |
69 | return "Found %s" % item | 69 | return "Found %s" % item |
70 | 70 | ||
@@ -99,5 +99,4 @@ class TestMultiprocessLaunch(TestCase): | |||
99 | # Assert the function prints exceptions | 99 | # Assert the function prints exceptions |
100 | with captured_output() as (out, err): | 100 | with captured_output() as (out, err): |
101 | self.assertRaises(bb.BBHandledException, multiprocess_launch, testfunction, ["1", "2", "3", "4", "5", "6"], d, extraargs=(d,)) | 101 | self.assertRaises(bb.BBHandledException, multiprocess_launch, testfunction, ["1", "2", "3", "4", "5", "6"], d, extraargs=(d,)) |
102 | self.assertIn("KeyError: 'Invalid number 1'", out.getvalue()) | ||
103 | self.assertIn("KeyError: 'Invalid number 2'", out.getvalue()) | 102 | self.assertIn("KeyError: 'Invalid number 2'", out.getvalue()) |
diff --git a/meta/lib/oeqa/selftest/cases/oescripts.py b/meta/lib/oeqa/selftest/cases/oescripts.py index 726daff7c6..fb99be447e 100644 --- a/meta/lib/oeqa/selftest/cases/oescripts.py +++ b/meta/lib/oeqa/selftest/cases/oescripts.py | |||
@@ -133,7 +133,8 @@ class OEListPackageconfigTests(OEScriptTests): | |||
133 | def check_endlines(self, results, expected_endlines): | 133 | def check_endlines(self, results, expected_endlines): |
134 | for line in results.output.splitlines(): | 134 | for line in results.output.splitlines(): |
135 | for el in expected_endlines: | 135 | for el in expected_endlines: |
136 | if line.split() == el.split(): | 136 | if line and line.split()[0] == el.split()[0] and \ |
137 | ' '.join(sorted(el.split())) in ' '.join(sorted(line.split())): | ||
137 | expected_endlines.remove(el) | 138 | expected_endlines.remove(el) |
138 | break | 139 | break |
139 | 140 | ||
diff --git a/meta/lib/oeqa/selftest/cases/prservice.py b/meta/lib/oeqa/selftest/cases/prservice.py index 578b2b4dd9..fdc1e40058 100644 --- a/meta/lib/oeqa/selftest/cases/prservice.py +++ b/meta/lib/oeqa/selftest/cases/prservice.py | |||
@@ -75,7 +75,7 @@ class BitbakePrTests(OESelftestTestCase): | |||
75 | exported_db_path = os.path.join(self.builddir, 'export.inc') | 75 | exported_db_path = os.path.join(self.builddir, 'export.inc') |
76 | export_result = runCmd("bitbake-prserv-tool export %s" % exported_db_path, ignore_status=True) | 76 | export_result = runCmd("bitbake-prserv-tool export %s" % exported_db_path, ignore_status=True) |
77 | self.assertEqual(export_result.status, 0, msg="PR Service database export failed: %s" % export_result.output) | 77 | self.assertEqual(export_result.status, 0, msg="PR Service database export failed: %s" % export_result.output) |
78 | self.assertTrue(os.path.exists(exported_db_path)) | 78 | self.assertTrue(os.path.exists(exported_db_path), msg="%s didn't exist, tool output %s" % (exported_db_path, export_result.output)) |
79 | 79 | ||
80 | if replace_current_db: | 80 | if replace_current_db: |
81 | current_db_path = os.path.join(get_bb_var('PERSISTENT_DIR'), 'prserv.sqlite3') | 81 | current_db_path = os.path.join(get_bb_var('PERSISTENT_DIR'), 'prserv.sqlite3') |
diff --git a/meta/lib/oeqa/selftest/cases/recipetool.py b/meta/lib/oeqa/selftest/cases/recipetool.py index c2ade2543a..e8aeea3023 100644 --- a/meta/lib/oeqa/selftest/cases/recipetool.py +++ b/meta/lib/oeqa/selftest/cases/recipetool.py | |||
@@ -370,7 +370,7 @@ class RecipetoolTests(RecipetoolBase): | |||
370 | tempsrc = os.path.join(self.tempdir, 'srctree') | 370 | tempsrc = os.path.join(self.tempdir, 'srctree') |
371 | os.makedirs(tempsrc) | 371 | os.makedirs(tempsrc) |
372 | recipefile = os.path.join(self.tempdir, 'libmatchbox.bb') | 372 | recipefile = os.path.join(self.tempdir, 'libmatchbox.bb') |
373 | srcuri = 'git://git.yoctoproject.org/libmatchbox' | 373 | srcuri = 'git://git.yoctoproject.org/libmatchbox;branch=master' |
374 | result = runCmd(['recipetool', 'create', '-o', recipefile, srcuri + ";rev=9f7cf8895ae2d39c465c04cc78e918c157420269", '-x', tempsrc]) | 374 | result = runCmd(['recipetool', 'create', '-o', recipefile, srcuri + ";rev=9f7cf8895ae2d39c465c04cc78e918c157420269", '-x', tempsrc]) |
375 | self.assertTrue(os.path.isfile(recipefile), 'recipetool did not create recipe file; output:\n%s' % result.output) | 375 | self.assertTrue(os.path.isfile(recipefile), 'recipetool did not create recipe file; output:\n%s' % result.output) |
376 | checkvars = {} | 376 | checkvars = {} |
@@ -456,7 +456,7 @@ class RecipetoolTests(RecipetoolBase): | |||
456 | self.assertTrue(os.path.isfile(recipefile)) | 456 | self.assertTrue(os.path.isfile(recipefile)) |
457 | checkvars = {} | 457 | checkvars = {} |
458 | checkvars['LICENSE'] = set(['Apache-2.0']) | 458 | checkvars['LICENSE'] = set(['Apache-2.0']) |
459 | checkvars['SRC_URI'] = 'git://github.com/mesonbuild/meson;protocol=https' | 459 | checkvars['SRC_URI'] = 'git://github.com/mesonbuild/meson;protocol=https;branch=master' |
460 | inherits = ['setuptools3'] | 460 | inherits = ['setuptools3'] |
461 | self._test_recipe_contents(recipefile, checkvars, inherits) | 461 | self._test_recipe_contents(recipefile, checkvars, inherits) |
462 | 462 | ||
@@ -523,7 +523,7 @@ class RecipetoolTests(RecipetoolBase): | |||
523 | self.assertTrue(os.path.isfile(recipefile)) | 523 | self.assertTrue(os.path.isfile(recipefile)) |
524 | checkvars = {} | 524 | checkvars = {} |
525 | checkvars['LICENSE'] = set(['GPLv2']) | 525 | checkvars['LICENSE'] = set(['GPLv2']) |
526 | checkvars['SRC_URI'] = 'git://git.yoctoproject.org/git/matchbox-terminal;protocol=http' | 526 | checkvars['SRC_URI'] = 'git://git.yoctoproject.org/git/matchbox-terminal;protocol=http;branch=master' |
527 | inherits = ['pkgconfig', 'autotools'] | 527 | inherits = ['pkgconfig', 'autotools'] |
528 | self._test_recipe_contents(recipefile, checkvars, inherits) | 528 | self._test_recipe_contents(recipefile, checkvars, inherits) |
529 | 529 | ||
diff --git a/meta/lib/oeqa/selftest/cases/reproducible.py b/meta/lib/oeqa/selftest/cases/reproducible.py index d4800022df..be4cdcc429 100644 --- a/meta/lib/oeqa/selftest/cases/reproducible.py +++ b/meta/lib/oeqa/selftest/cases/reproducible.py | |||
@@ -17,6 +17,57 @@ import stat | |||
17 | import os | 17 | import os |
18 | import datetime | 18 | import datetime |
19 | 19 | ||
20 | # For sample packages, see: | ||
21 | # https://autobuilder.yocto.io/pub/repro-fail/oe-reproducible-20201127-0t7wr_oo/ | ||
22 | # https://autobuilder.yocto.io/pub/repro-fail/oe-reproducible-20201127-4s9ejwyp/ | ||
23 | # https://autobuilder.yocto.io/pub/repro-fail/oe-reproducible-20201127-haiwdlbr/ | ||
24 | # https://autobuilder.yocto.io/pub/repro-fail/oe-reproducible-20201127-hwds3mcl/ | ||
25 | # https://autobuilder.yocto.io/pub/repro-fail/oe-reproducible-20201203-sua0pzvc/ | ||
26 | # (both packages/ and packages-excluded/) | ||
27 | exclude_packages = [ | ||
28 | 'acpica-src', | ||
29 | 'babeltrace2-ptest', | ||
30 | 'bind', | ||
31 | 'bootchart2-doc', | ||
32 | 'epiphany', | ||
33 | 'gcr', | ||
34 | 'glide', | ||
35 | 'go-dep', | ||
36 | 'go-helloworld', | ||
37 | 'go-runtime', | ||
38 | 'go_', | ||
39 | 'gstreamer1.0-python', | ||
40 | 'hwlatdetect', | ||
41 | 'kernel-devsrc', | ||
42 | 'libcap-ng', | ||
43 | 'libjson', | ||
44 | 'libproxy', | ||
45 | 'lttng-tools-dbg', | ||
46 | 'lttng-tools-ptest', | ||
47 | 'ltp', | ||
48 | 'ovmf-shell-efi', | ||
49 | 'parted-ptest', | ||
50 | 'perf', | ||
51 | 'piglit', | ||
52 | 'pybootchartgui', | ||
53 | 'qemu', | ||
54 | 'quilt-ptest', | ||
55 | 'rsync', | ||
56 | 'ruby', | ||
57 | 'stress-ng', | ||
58 | 'systemd-bootchart', | ||
59 | 'systemtap', | ||
60 | 'valgrind-ptest', | ||
61 | 'webkitgtk', | ||
62 | ] | ||
63 | |||
64 | def is_excluded(package): | ||
65 | package_name = os.path.basename(package) | ||
66 | for i in exclude_packages: | ||
67 | if package_name.startswith(i): | ||
68 | return i | ||
69 | return None | ||
70 | |||
20 | MISSING = 'MISSING' | 71 | MISSING = 'MISSING' |
21 | DIFFERENT = 'DIFFERENT' | 72 | DIFFERENT = 'DIFFERENT' |
22 | SAME = 'SAME' | 73 | SAME = 'SAME' |
@@ -39,14 +90,21 @@ class PackageCompareResults(object): | |||
39 | self.total = [] | 90 | self.total = [] |
40 | self.missing = [] | 91 | self.missing = [] |
41 | self.different = [] | 92 | self.different = [] |
93 | self.different_excluded = [] | ||
42 | self.same = [] | 94 | self.same = [] |
95 | self.active_exclusions = set() | ||
43 | 96 | ||
44 | def add_result(self, r): | 97 | def add_result(self, r): |
45 | self.total.append(r) | 98 | self.total.append(r) |
46 | if r.status == MISSING: | 99 | if r.status == MISSING: |
47 | self.missing.append(r) | 100 | self.missing.append(r) |
48 | elif r.status == DIFFERENT: | 101 | elif r.status == DIFFERENT: |
49 | self.different.append(r) | 102 | exclusion = is_excluded(r.reference) |
103 | if exclusion: | ||
104 | self.different_excluded.append(r) | ||
105 | self.active_exclusions.add(exclusion) | ||
106 | else: | ||
107 | self.different.append(r) | ||
50 | else: | 108 | else: |
51 | self.same.append(r) | 109 | self.same.append(r) |
52 | 110 | ||
@@ -54,10 +112,14 @@ class PackageCompareResults(object): | |||
54 | self.total.sort() | 112 | self.total.sort() |
55 | self.missing.sort() | 113 | self.missing.sort() |
56 | self.different.sort() | 114 | self.different.sort() |
115 | self.different_excluded.sort() | ||
57 | self.same.sort() | 116 | self.same.sort() |
58 | 117 | ||
59 | def __str__(self): | 118 | def __str__(self): |
60 | return 'same=%i different=%i missing=%i total=%i' % (len(self.same), len(self.different), len(self.missing), len(self.total)) | 119 | return 'same=%i different=%i different_excluded=%i missing=%i total=%i\nunused_exclusions=%s' % (len(self.same), len(self.different), len(self.different_excluded), len(self.missing), len(self.total), self.unused_exclusions()) |
120 | |||
121 | def unused_exclusions(self): | ||
122 | return sorted(set(exclude_packages) - self.active_exclusions) | ||
61 | 123 | ||
62 | def compare_file(reference, test, diffutils_sysroot): | 124 | def compare_file(reference, test, diffutils_sysroot): |
63 | result = CompareResult() | 125 | result = CompareResult() |
@@ -68,7 +130,7 @@ def compare_file(reference, test, diffutils_sysroot): | |||
68 | result.status = MISSING | 130 | result.status = MISSING |
69 | return result | 131 | return result |
70 | 132 | ||
71 | r = runCmd(['cmp', '--quiet', reference, test], native_sysroot=diffutils_sysroot, ignore_status=True) | 133 | r = runCmd(['cmp', '--quiet', reference, test], native_sysroot=diffutils_sysroot, ignore_status=True, sync=False) |
72 | 134 | ||
73 | if r.status: | 135 | if r.status: |
74 | result.status = DIFFERENT | 136 | result.status = DIFFERENT |
@@ -77,9 +139,41 @@ def compare_file(reference, test, diffutils_sysroot): | |||
77 | result.status = SAME | 139 | result.status = SAME |
78 | return result | 140 | return result |
79 | 141 | ||
142 | def run_diffoscope(a_dir, b_dir, html_dir, **kwargs): | ||
143 | return runCmd(['diffoscope', '--no-default-limits', '--exclude-directory-metadata', 'yes', '--html-dir', html_dir, a_dir, b_dir], | ||
144 | **kwargs) | ||
145 | |||
146 | class DiffoscopeTests(OESelftestTestCase): | ||
147 | diffoscope_test_files = os.path.join(os.path.dirname(os.path.abspath(__file__)), "diffoscope") | ||
148 | |||
149 | def test_diffoscope(self): | ||
150 | bitbake("diffoscope-native -c addto_recipe_sysroot") | ||
151 | diffoscope_sysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", "diffoscope-native") | ||
152 | |||
153 | # Check that diffoscope doesn't return an error when the files compare | ||
154 | # the same (a general check that diffoscope is working) | ||
155 | with tempfile.TemporaryDirectory() as tmpdir: | ||
156 | run_diffoscope('A', 'A', tmpdir, | ||
157 | native_sysroot=diffoscope_sysroot, cwd=self.diffoscope_test_files) | ||
158 | |||
159 | # Check that diffoscope generates an index.html file when the files are | ||
160 | # different | ||
161 | with tempfile.TemporaryDirectory() as tmpdir: | ||
162 | r = run_diffoscope('A', 'B', tmpdir, | ||
163 | native_sysroot=diffoscope_sysroot, ignore_status=True, cwd=self.diffoscope_test_files) | ||
164 | |||
165 | self.assertNotEqual(r.status, 0, msg="diffoscope was successful when an error was expected") | ||
166 | self.assertTrue(os.path.exists(os.path.join(tmpdir, 'index.html')), "HTML index not found!") | ||
167 | |||
80 | class ReproducibleTests(OESelftestTestCase): | 168 | class ReproducibleTests(OESelftestTestCase): |
169 | # Test the reproducibility of whatever is built between sstate_targets and targets | ||
170 | |||
81 | package_classes = ['deb', 'ipk'] | 171 | package_classes = ['deb', 'ipk'] |
82 | images = ['core-image-minimal', 'core-image-sato', 'core-image-full-cmdline'] | 172 | |
173 | # targets are the things we want to test the reproducibility of | ||
174 | targets = ['core-image-minimal', 'core-image-sato', 'core-image-full-cmdline', 'world'] | ||
175 | # sstate targets are things to pull from sstate to potentially cut build/debugging time | ||
176 | sstate_targets = [] | ||
83 | save_results = False | 177 | save_results = False |
84 | if 'OEQA_DEBUGGING_SAVED_OUTPUT' in os.environ: | 178 | if 'OEQA_DEBUGGING_SAVED_OUTPUT' in os.environ: |
85 | save_results = os.environ['OEQA_DEBUGGING_SAVED_OUTPUT'] | 179 | save_results = os.environ['OEQA_DEBUGGING_SAVED_OUTPUT'] |
@@ -94,7 +188,7 @@ class ReproducibleTests(OESelftestTestCase): | |||
94 | 188 | ||
95 | def setUpLocal(self): | 189 | def setUpLocal(self): |
96 | super().setUpLocal() | 190 | super().setUpLocal() |
97 | needed_vars = ['TOPDIR', 'TARGET_PREFIX', 'BB_NUMBER_THREADS'] | 191 | needed_vars = ['TOPDIR', 'TARGET_PREFIX', 'BB_NUMBER_THREADS', 'BB_HASHSERVE'] |
98 | bb_vars = get_bb_vars(needed_vars) | 192 | bb_vars = get_bb_vars(needed_vars) |
99 | for v in needed_vars: | 193 | for v in needed_vars: |
100 | setattr(self, v.lower(), bb_vars[v]) | 194 | setattr(self, v.lower(), bb_vars[v]) |
@@ -150,21 +244,29 @@ class ReproducibleTests(OESelftestTestCase): | |||
150 | PACKAGE_CLASSES = "{package_classes}" | 244 | PACKAGE_CLASSES = "{package_classes}" |
151 | INHIBIT_PACKAGE_STRIP = "1" | 245 | INHIBIT_PACKAGE_STRIP = "1" |
152 | TMPDIR = "{tmpdir}" | 246 | TMPDIR = "{tmpdir}" |
247 | LICENSE_FLAGS_WHITELIST = "commercial" | ||
248 | DISTRO_FEATURES_append = ' systemd pam' | ||
153 | ''').format(package_classes=' '.join('package_%s' % c for c in self.package_classes), | 249 | ''').format(package_classes=' '.join('package_%s' % c for c in self.package_classes), |
154 | tmpdir=tmpdir) | 250 | tmpdir=tmpdir) |
155 | 251 | ||
156 | if not use_sstate: | 252 | if not use_sstate: |
253 | if self.sstate_targets: | ||
254 | self.logger.info("Building prebuild for %s (sstate allowed)..." % (name)) | ||
255 | self.write_config(config) | ||
256 | bitbake(' '.join(self.sstate_targets)) | ||
257 | |||
157 | # This config fragment will disable using shared and the sstate | 258 | # This config fragment will disable using shared and the sstate |
158 | # mirror, forcing a complete build from scratch | 259 | # mirror, forcing a complete build from scratch |
159 | config += textwrap.dedent('''\ | 260 | config += textwrap.dedent('''\ |
160 | SSTATE_DIR = "${TMPDIR}/sstate" | 261 | SSTATE_DIR = "${TMPDIR}/sstate" |
161 | SSTATE_MIRRORS = "" | 262 | SSTATE_MIRRORS = "file://.*/.*-native.* http://sstate.yoctoproject.org/all/PATH;downloadfilename=PATH file://.*/.*-cross.* http://sstate.yoctoproject.org/all/PATH;downloadfilename=PATH" |
162 | ''') | 263 | ''') |
163 | 264 | ||
164 | self.logger.info("Building %s (sstate%s allowed)..." % (name, '' if use_sstate else ' NOT')) | 265 | self.logger.info("Building %s (sstate%s allowed)..." % (name, '' if use_sstate else ' NOT')) |
165 | self.write_config(config) | 266 | self.write_config(config) |
166 | d = get_bb_vars(capture_vars) | 267 | d = get_bb_vars(capture_vars) |
167 | bitbake(' '.join(self.images)) | 268 | # targets used to be called images |
269 | bitbake(' '.join(getattr(self, 'images', self.targets))) | ||
168 | return d | 270 | return d |
169 | 271 | ||
170 | def test_reproducible_builds(self): | 272 | def test_reproducible_builds(self): |
@@ -212,6 +314,7 @@ class ReproducibleTests(OESelftestTestCase): | |||
212 | 314 | ||
213 | self.write_package_list(package_class, 'missing', result.missing) | 315 | self.write_package_list(package_class, 'missing', result.missing) |
214 | self.write_package_list(package_class, 'different', result.different) | 316 | self.write_package_list(package_class, 'different', result.different) |
317 | self.write_package_list(package_class, 'different_excluded', result.different_excluded) | ||
215 | self.write_package_list(package_class, 'same', result.same) | 318 | self.write_package_list(package_class, 'same', result.same) |
216 | 319 | ||
217 | if self.save_results: | 320 | if self.save_results: |
@@ -219,8 +322,12 @@ class ReproducibleTests(OESelftestTestCase): | |||
219 | self.copy_file(d.reference, '/'.join([save_dir, 'packages', strip_topdir(d.reference)])) | 322 | self.copy_file(d.reference, '/'.join([save_dir, 'packages', strip_topdir(d.reference)])) |
220 | self.copy_file(d.test, '/'.join([save_dir, 'packages', strip_topdir(d.test)])) | 323 | self.copy_file(d.test, '/'.join([save_dir, 'packages', strip_topdir(d.test)])) |
221 | 324 | ||
325 | for d in result.different_excluded: | ||
326 | self.copy_file(d.reference, '/'.join([save_dir, 'packages-excluded', strip_topdir(d.reference)])) | ||
327 | self.copy_file(d.test, '/'.join([save_dir, 'packages-excluded', strip_topdir(d.test)])) | ||
328 | |||
222 | if result.missing or result.different: | 329 | if result.missing or result.different: |
223 | fails.append("The following %s packages are missing or different: %s" % | 330 | fails.append("The following %s packages are missing or different and not in exclusion list: %s" % |
224 | (c, '\n'.join(r.test for r in (result.missing + result.different)))) | 331 | (c, '\n'.join(r.test for r in (result.missing + result.different)))) |
225 | 332 | ||
226 | # Clean up empty directories | 333 | # Clean up empty directories |
@@ -235,7 +342,7 @@ class ReproducibleTests(OESelftestTestCase): | |||
235 | # Copy jquery to improve the diffoscope output usability | 342 | # Copy jquery to improve the diffoscope output usability |
236 | self.copy_file(os.path.join(jquery_sysroot, 'usr/share/javascript/jquery/jquery.min.js'), os.path.join(package_html_dir, 'jquery.js')) | 343 | self.copy_file(os.path.join(jquery_sysroot, 'usr/share/javascript/jquery/jquery.min.js'), os.path.join(package_html_dir, 'jquery.js')) |
237 | 344 | ||
238 | runCmd(['diffoscope', '--no-default-limits', '--exclude-directory-metadata', '--html-dir', package_html_dir, 'reproducibleA', 'reproducibleB'], | 345 | run_diffoscope('reproducibleA', 'reproducibleB', package_html_dir, |
239 | native_sysroot=diffoscope_sysroot, ignore_status=True, cwd=package_dir) | 346 | native_sysroot=diffoscope_sysroot, ignore_status=True, cwd=package_dir) |
240 | 347 | ||
241 | if fails: | 348 | if fails: |
diff --git a/meta/lib/oeqa/selftest/cases/runcmd.py b/meta/lib/oeqa/selftest/cases/runcmd.py index fa6113d7fa..e9612389fe 100644 --- a/meta/lib/oeqa/selftest/cases/runcmd.py +++ b/meta/lib/oeqa/selftest/cases/runcmd.py | |||
@@ -27,8 +27,8 @@ class RunCmdTests(OESelftestTestCase): | |||
27 | 27 | ||
28 | # The delta is intentionally smaller than the timeout, to detect cases where | 28 | # The delta is intentionally smaller than the timeout, to detect cases where |
29 | # we incorrectly apply the timeout more than once. | 29 | # we incorrectly apply the timeout more than once. |
30 | TIMEOUT = 5 | 30 | TIMEOUT = 10 |
31 | DELTA = 3 | 31 | DELTA = 8 |
32 | 32 | ||
33 | def test_result_okay(self): | 33 | def test_result_okay(self): |
34 | result = runCmd("true") | 34 | result = runCmd("true") |
diff --git a/meta/lib/oeqa/selftest/cases/runqemu.py b/meta/lib/oeqa/selftest/cases/runqemu.py index 7e676bcb41..da22f77b27 100644 --- a/meta/lib/oeqa/selftest/cases/runqemu.py +++ b/meta/lib/oeqa/selftest/cases/runqemu.py | |||
@@ -163,12 +163,11 @@ class QemuTest(OESelftestTestCase): | |||
163 | bitbake(cls.recipe) | 163 | bitbake(cls.recipe) |
164 | 164 | ||
165 | def _start_qemu_shutdown_check_if_shutdown_succeeded(self, qemu, timeout): | 165 | def _start_qemu_shutdown_check_if_shutdown_succeeded(self, qemu, timeout): |
166 | # Allow the runner's LoggingThread instance to exit without errors | ||
167 | # (such as the exception "Console connection closed unexpectedly") | ||
168 | # as qemu will disappear when we shut it down | ||
169 | qemu.runner.allowexit() | ||
166 | qemu.run_serial("shutdown -h now") | 170 | qemu.run_serial("shutdown -h now") |
167 | # Stop thread will stop the LoggingThread instance used for logging | ||
168 | # qemu through serial console, stop thread will prevent this code | ||
169 | # from facing exception (Console connection closed unexpectedly) | ||
170 | # when qemu was shutdown by the above shutdown command | ||
171 | qemu.runner.stop_thread() | ||
172 | time_track = 0 | 171 | time_track = 0 |
173 | try: | 172 | try: |
174 | while True: | 173 | while True: |
diff --git a/meta/lib/oeqa/selftest/cases/runtime_test.py b/meta/lib/oeqa/selftest/cases/runtime_test.py index 976b513727..cc4190c1d6 100644 --- a/meta/lib/oeqa/selftest/cases/runtime_test.py +++ b/meta/lib/oeqa/selftest/cases/runtime_test.py | |||
@@ -14,11 +14,6 @@ from oeqa.core.decorator.data import skipIfNotQemu | |||
14 | 14 | ||
15 | class TestExport(OESelftestTestCase): | 15 | class TestExport(OESelftestTestCase): |
16 | 16 | ||
17 | @classmethod | ||
18 | def tearDownClass(cls): | ||
19 | runCmd("rm -rf /tmp/sdk") | ||
20 | super(TestExport, cls).tearDownClass() | ||
21 | |||
22 | def test_testexport_basic(self): | 17 | def test_testexport_basic(self): |
23 | """ | 18 | """ |
24 | Summary: Check basic testexport functionality with only ping test enabled. | 19 | Summary: Check basic testexport functionality with only ping test enabled. |
@@ -95,19 +90,20 @@ class TestExport(OESelftestTestCase): | |||
95 | msg = "Couldn't find SDK tarball: %s" % tarball_path | 90 | msg = "Couldn't find SDK tarball: %s" % tarball_path |
96 | self.assertEqual(os.path.isfile(tarball_path), True, msg) | 91 | self.assertEqual(os.path.isfile(tarball_path), True, msg) |
97 | 92 | ||
98 | # Extract SDK and run tar from SDK | 93 | with tempfile.TemporaryDirectory() as tmpdirname: |
99 | result = runCmd("%s -y -d /tmp/sdk" % tarball_path) | 94 | # Extract SDK and run tar from SDK |
100 | self.assertEqual(0, result.status, "Couldn't extract SDK") | 95 | result = runCmd("%s -y -d %s" % (tarball_path, tmpdirname)) |
96 | self.assertEqual(0, result.status, "Couldn't extract SDK") | ||
101 | 97 | ||
102 | env_script = result.output.split()[-1] | 98 | env_script = result.output.split()[-1] |
103 | result = runCmd(". %s; which tar" % env_script, shell=True) | 99 | result = runCmd(". %s; which tar" % env_script, shell=True) |
104 | self.assertEqual(0, result.status, "Couldn't setup SDK environment") | 100 | self.assertEqual(0, result.status, "Couldn't setup SDK environment") |
105 | is_sdk_tar = True if "/tmp/sdk" in result.output else False | 101 | is_sdk_tar = True if tmpdirname in result.output else False |
106 | self.assertTrue(is_sdk_tar, "Couldn't setup SDK environment") | 102 | self.assertTrue(is_sdk_tar, "Couldn't setup SDK environment") |
107 | 103 | ||
108 | tar_sdk = result.output | 104 | tar_sdk = result.output |
109 | result = runCmd("%s --version" % tar_sdk) | 105 | result = runCmd("%s --version" % tar_sdk) |
110 | self.assertEqual(0, result.status, "Couldn't run tar from SDK") | 106 | self.assertEqual(0, result.status, "Couldn't run tar from SDK") |
111 | 107 | ||
112 | 108 | ||
113 | class TestImage(OESelftestTestCase): | 109 | class TestImage(OESelftestTestCase): |
@@ -179,12 +175,24 @@ class TestImage(OESelftestTestCase): | |||
179 | if "DISPLAY" not in os.environ: | 175 | if "DISPLAY" not in os.environ: |
180 | self.skipTest("virgl gtk test must be run inside a X session") | 176 | self.skipTest("virgl gtk test must be run inside a X session") |
181 | distro = oe.lsb.distro_identifier() | 177 | distro = oe.lsb.distro_identifier() |
178 | if distro and distro.startswith('almalinux'): | ||
179 | self.skipTest('virgl isn\'t working with Alma Linux') | ||
180 | if distro and distro.startswith('rocky'): | ||
181 | self.skipTest('virgl isn\'t working with Rocky Linux') | ||
182 | if distro and distro == 'debian-8': | 182 | if distro and distro == 'debian-8': |
183 | self.skipTest('virgl isn\'t working with Debian 8') | 183 | self.skipTest('virgl isn\'t working with Debian 8') |
184 | if distro and distro == 'centos-7': | 184 | if distro and distro == 'centos-7': |
185 | self.skipTest('virgl isn\'t working with Centos 7') | 185 | self.skipTest('virgl isn\'t working with Centos 7') |
186 | if distro and distro == 'centos-8': | ||
187 | self.skipTest('virgl isn\'t working with Centos 8') | ||
188 | if distro and distro.startswith('fedora'): | ||
189 | self.skipTest('virgl isn\'t working with Fedora') | ||
186 | if distro and distro == 'opensuseleap-15.0': | 190 | if distro and distro == 'opensuseleap-15.0': |
187 | self.skipTest('virgl isn\'t working with Opensuse 15.0') | 191 | self.skipTest('virgl isn\'t working with Opensuse 15.0') |
192 | if distro and distro == 'ubuntu-22.04': | ||
193 | self.skipTest('virgl isn\'t working with Ubuntu 22.04') | ||
194 | if distro and distro == 'ubuntu-22.10': | ||
195 | self.skipTest('virgl isn\'t working with Ubuntu 22.10') | ||
188 | 196 | ||
189 | qemu_packageconfig = get_bb_var('PACKAGECONFIG', 'qemu-system-native') | 197 | qemu_packageconfig = get_bb_var('PACKAGECONFIG', 'qemu-system-native') |
190 | sdl_packageconfig = get_bb_var('PACKAGECONFIG', 'libsdl2-native') | 198 | sdl_packageconfig = get_bb_var('PACKAGECONFIG', 'libsdl2-native') |
@@ -220,6 +228,7 @@ class TestImage(OESelftestTestCase): | |||
220 | Author: Alexander Kanavin <alex.kanavin@gmail.com> | 228 | Author: Alexander Kanavin <alex.kanavin@gmail.com> |
221 | """ | 229 | """ |
222 | import subprocess, os | 230 | import subprocess, os |
231 | self.skipTest("Crashes in mesa observed with this test on dunfell: https://bugzilla.yoctoproject.org/show_bug.cgi?id=14527") | ||
223 | try: | 232 | try: |
224 | content = os.listdir("/dev/dri") | 233 | content = os.listdir("/dev/dri") |
225 | if len([i for i in content if i.startswith('render')]) == 0: | 234 | if len([i for i in content if i.startswith('render')]) == 0: |
@@ -227,7 +236,7 @@ class TestImage(OESelftestTestCase): | |||
227 | except FileNotFoundError: | 236 | except FileNotFoundError: |
228 | self.skipTest("/dev/dri directory does not exist; no render nodes available on this machine.") | 237 | self.skipTest("/dev/dri directory does not exist; no render nodes available on this machine.") |
229 | try: | 238 | try: |
230 | dripath = subprocess.check_output("pkg-config --variable=dridriverdir dri", shell=True) | 239 | dripath = subprocess.check_output("PATH=/bin:/usr/bin:$PATH pkg-config --variable=dridriverdir dri", shell=True) |
231 | except subprocess.CalledProcessError as e: | 240 | except subprocess.CalledProcessError as e: |
232 | self.skipTest("Could not determine the path to dri drivers on the host via pkg-config.\nPlease install Mesa development files (particularly, dri.pc) on the host machine.") | 241 | self.skipTest("Could not determine the path to dri drivers on the host via pkg-config.\nPlease install Mesa development files (particularly, dri.pc) on the host machine.") |
233 | qemu_packageconfig = get_bb_var('PACKAGECONFIG', 'qemu-system-native') | 242 | qemu_packageconfig = get_bb_var('PACKAGECONFIG', 'qemu-system-native') |
diff --git a/meta/lib/oeqa/selftest/cases/sstatetests.py b/meta/lib/oeqa/selftest/cases/sstatetests.py index c46e8ba489..1bfe88c87d 100644 --- a/meta/lib/oeqa/selftest/cases/sstatetests.py +++ b/meta/lib/oeqa/selftest/cases/sstatetests.py | |||
@@ -39,7 +39,7 @@ class SStateTests(SStateBase): | |||
39 | 39 | ||
40 | recipefile = os.path.join(tempdir, "recipes-test", "dbus-wait-test", 'dbus-wait-test_git.bb') | 40 | recipefile = os.path.join(tempdir, "recipes-test", "dbus-wait-test", 'dbus-wait-test_git.bb') |
41 | os.makedirs(os.path.dirname(recipefile)) | 41 | os.makedirs(os.path.dirname(recipefile)) |
42 | srcuri = 'git://' + srcdir + ';protocol=file' | 42 | srcuri = 'git://' + srcdir + ';protocol=file;branch=master' |
43 | result = runCmd(['recipetool', 'create', '-o', recipefile, srcuri]) | 43 | result = runCmd(['recipetool', 'create', '-o', recipefile, srcuri]) |
44 | self.assertTrue(os.path.isfile(recipefile), 'recipetool did not create recipe file; output:\n%s' % result.output) | 44 | self.assertTrue(os.path.isfile(recipefile), 'recipetool did not create recipe file; output:\n%s' % result.output) |
45 | 45 | ||
@@ -137,7 +137,7 @@ class SStateTests(SStateBase): | |||
137 | filtered_results.append(r) | 137 | filtered_results.append(r) |
138 | self.assertTrue(filtered_results == [], msg="Found distro non-specific sstate for: %s (%s)" % (', '.join(map(str, targets)), str(filtered_results))) | 138 | self.assertTrue(filtered_results == [], msg="Found distro non-specific sstate for: %s (%s)" % (', '.join(map(str, targets)), str(filtered_results))) |
139 | file_tracker_1 = self.search_sstate('|'.join(map(str, [s + r'.*?\.tgz$' for s in targets])), distro_specific=True, distro_nonspecific=False) | 139 | file_tracker_1 = self.search_sstate('|'.join(map(str, [s + r'.*?\.tgz$' for s in targets])), distro_specific=True, distro_nonspecific=False) |
140 | self.assertTrue(len(file_tracker_1) >= len(targets), msg = "Not all sstate files ware created for: %s" % ', '.join(map(str, targets))) | 140 | self.assertTrue(len(file_tracker_1) >= len(targets), msg = "Not all sstate files were created for: %s" % ', '.join(map(str, targets))) |
141 | 141 | ||
142 | self.track_for_cleanup(self.distro_specific_sstate + "_old") | 142 | self.track_for_cleanup(self.distro_specific_sstate + "_old") |
143 | shutil.copytree(self.distro_specific_sstate, self.distro_specific_sstate + "_old") | 143 | shutil.copytree(self.distro_specific_sstate, self.distro_specific_sstate + "_old") |
@@ -146,13 +146,13 @@ class SStateTests(SStateBase): | |||
146 | bitbake(['-cclean'] + targets) | 146 | bitbake(['-cclean'] + targets) |
147 | bitbake(targets) | 147 | bitbake(targets) |
148 | file_tracker_2 = self.search_sstate('|'.join(map(str, [s + r'.*?\.tgz$' for s in targets])), distro_specific=True, distro_nonspecific=False) | 148 | file_tracker_2 = self.search_sstate('|'.join(map(str, [s + r'.*?\.tgz$' for s in targets])), distro_specific=True, distro_nonspecific=False) |
149 | self.assertTrue(len(file_tracker_2) >= len(targets), msg = "Not all sstate files ware created for: %s" % ', '.join(map(str, targets))) | 149 | self.assertTrue(len(file_tracker_2) >= len(targets), msg = "Not all sstate files were created for: %s" % ', '.join(map(str, targets))) |
150 | 150 | ||
151 | not_recreated = [x for x in file_tracker_1 if x not in file_tracker_2] | 151 | not_recreated = [x for x in file_tracker_1 if x not in file_tracker_2] |
152 | self.assertTrue(not_recreated == [], msg="The following sstate files ware not recreated: %s" % ', '.join(map(str, not_recreated))) | 152 | self.assertTrue(not_recreated == [], msg="The following sstate files were not recreated: %s" % ', '.join(map(str, not_recreated))) |
153 | 153 | ||
154 | created_once = [x for x in file_tracker_2 if x not in file_tracker_1] | 154 | created_once = [x for x in file_tracker_2 if x not in file_tracker_1] |
155 | self.assertTrue(created_once == [], msg="The following sstate files ware created only in the second run: %s" % ', '.join(map(str, created_once))) | 155 | self.assertTrue(created_once == [], msg="The following sstate files were created only in the second run: %s" % ', '.join(map(str, created_once))) |
156 | 156 | ||
157 | def test_rebuild_distro_specific_sstate_cross_native_targets(self): | 157 | def test_rebuild_distro_specific_sstate_cross_native_targets(self): |
158 | self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + self.tune_arch, 'binutils-native'], temp_sstate_location=True) | 158 | self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + self.tune_arch, 'binutils-native'], temp_sstate_location=True) |
@@ -202,9 +202,9 @@ class SStateTests(SStateBase): | |||
202 | actual_remaining_sstate = [x for x in self.search_sstate(target + r'.*?\.tgz$') if not any(pattern in x for pattern in ignore_patterns)] | 202 | actual_remaining_sstate = [x for x in self.search_sstate(target + r'.*?\.tgz$') if not any(pattern in x for pattern in ignore_patterns)] |
203 | 203 | ||
204 | actual_not_expected = [x for x in actual_remaining_sstate if x not in expected_remaining_sstate] | 204 | actual_not_expected = [x for x in actual_remaining_sstate if x not in expected_remaining_sstate] |
205 | self.assertFalse(actual_not_expected, msg="Files should have been removed but ware not: %s" % ', '.join(map(str, actual_not_expected))) | 205 | self.assertFalse(actual_not_expected, msg="Files should have been removed but were not: %s" % ', '.join(map(str, actual_not_expected))) |
206 | expected_not_actual = [x for x in expected_remaining_sstate if x not in actual_remaining_sstate] | 206 | expected_not_actual = [x for x in expected_remaining_sstate if x not in actual_remaining_sstate] |
207 | self.assertFalse(expected_not_actual, msg="Extra files ware removed: %s" ', '.join(map(str, expected_not_actual))) | 207 | self.assertFalse(expected_not_actual, msg="Extra files were removed: %s" ', '.join(map(str, expected_not_actual))) |
208 | 208 | ||
209 | def test_sstate_cache_management_script_using_pr_1(self): | 209 | def test_sstate_cache_management_script_using_pr_1(self): |
210 | global_config = [] | 210 | global_config = [] |
diff --git a/meta/lib/oeqa/selftest/cases/tinfoil.py b/meta/lib/oeqa/selftest/cases/tinfoil.py index a51c6048d3..6668d7cdc8 100644 --- a/meta/lib/oeqa/selftest/cases/tinfoil.py +++ b/meta/lib/oeqa/selftest/cases/tinfoil.py | |||
@@ -65,6 +65,20 @@ class TinfoilTests(OESelftestTestCase): | |||
65 | localdata.setVar('PN', 'hello') | 65 | localdata.setVar('PN', 'hello') |
66 | self.assertEqual('hello', localdata.getVar('BPN')) | 66 | self.assertEqual('hello', localdata.getVar('BPN')) |
67 | 67 | ||
68 | # The config_data API tp parse_recipe_file is used by: | ||
69 | # layerindex-web layerindex/update_layer.py | ||
70 | def test_parse_recipe_custom_data(self): | ||
71 | with bb.tinfoil.Tinfoil() as tinfoil: | ||
72 | tinfoil.prepare(config_only=False, quiet=2) | ||
73 | localdata = bb.data.createCopy(tinfoil.config_data) | ||
74 | localdata.setVar("TESTVAR", "testval") | ||
75 | testrecipe = 'mdadm' | ||
76 | best = tinfoil.find_best_provider(testrecipe) | ||
77 | if not best: | ||
78 | self.fail('Unable to find recipe providing %s' % testrecipe) | ||
79 | rd = tinfoil.parse_recipe_file(best[3], config_data=localdata) | ||
80 | self.assertEqual("testval", rd.getVar('TESTVAR')) | ||
81 | |||
68 | def test_list_recipes(self): | 82 | def test_list_recipes(self): |
69 | with bb.tinfoil.Tinfoil() as tinfoil: | 83 | with bb.tinfoil.Tinfoil() as tinfoil: |
70 | tinfoil.prepare(config_only=False, quiet=2) | 84 | tinfoil.prepare(config_only=False, quiet=2) |
@@ -87,23 +101,22 @@ class TinfoilTests(OESelftestTestCase): | |||
87 | with bb.tinfoil.Tinfoil() as tinfoil: | 101 | with bb.tinfoil.Tinfoil() as tinfoil: |
88 | tinfoil.prepare(config_only=True) | 102 | tinfoil.prepare(config_only=True) |
89 | 103 | ||
90 | tinfoil.set_event_mask(['bb.event.FilesMatchingFound', 'bb.command.CommandCompleted']) | 104 | tinfoil.set_event_mask(['bb.event.FilesMatchingFound', 'bb.command.CommandCompleted', 'bb.command.CommandFailed', 'bb.command.CommandExit']) |
91 | 105 | ||
92 | # Need to drain events otherwise events that were masked may still be in the queue | 106 | # Need to drain events otherwise events that were masked may still be in the queue |
93 | while tinfoil.wait_event(): | 107 | while tinfoil.wait_event(): |
94 | pass | 108 | pass |
95 | 109 | ||
96 | pattern = 'conf' | 110 | pattern = 'conf' |
97 | res = tinfoil.run_command('findFilesMatchingInDir', pattern, 'conf/machine') | 111 | res = tinfoil.run_command('testCookerCommandEvent', pattern, handle_events=False) |
98 | self.assertTrue(res) | 112 | self.assertTrue(res) |
99 | 113 | ||
100 | eventreceived = False | 114 | eventreceived = False |
101 | commandcomplete = False | 115 | commandcomplete = False |
102 | start = time.time() | 116 | start = time.time() |
103 | # Wait for maximum 60s in total so we'd detect spurious heartbeat events for example | 117 | # Wait for maximum 120s in total so we'd detect spurious heartbeat events for example |
104 | # The test is IO load sensitive too | ||
105 | while (not (eventreceived == True and commandcomplete == True) | 118 | while (not (eventreceived == True and commandcomplete == True) |
106 | and (time.time() - start < 60)): | 119 | and (time.time() - start < 120)): |
107 | # if we received both events (on let's say a good day), we are done | 120 | # if we received both events (on let's say a good day), we are done |
108 | event = tinfoil.wait_event(1) | 121 | event = tinfoil.wait_event(1) |
109 | if event: | 122 | if event: |
@@ -111,14 +124,15 @@ class TinfoilTests(OESelftestTestCase): | |||
111 | commandcomplete = True | 124 | commandcomplete = True |
112 | elif isinstance(event, bb.event.FilesMatchingFound): | 125 | elif isinstance(event, bb.event.FilesMatchingFound): |
113 | self.assertEqual(pattern, event._pattern) | 126 | self.assertEqual(pattern, event._pattern) |
114 | self.assertIn('qemuarm.conf', event._matches) | 127 | self.assertIn('A', event._matches) |
128 | self.assertIn('B', event._matches) | ||
115 | eventreceived = True | 129 | eventreceived = True |
116 | elif isinstance(event, logging.LogRecord): | 130 | elif isinstance(event, logging.LogRecord): |
117 | continue | 131 | continue |
118 | else: | 132 | else: |
119 | self.fail('Unexpected event: %s' % event) | 133 | self.fail('Unexpected event: %s' % event) |
120 | 134 | ||
121 | self.assertTrue(commandcomplete, 'Timed out waiting for CommandCompleted event from bitbake server') | 135 | self.assertTrue(commandcomplete, 'Timed out waiting for CommandCompleted event from bitbake server (Matching event received: %s)' % str(eventreceived)) |
122 | self.assertTrue(eventreceived, 'Did not receive FilesMatchingFound event from bitbake server') | 136 | self.assertTrue(eventreceived, 'Did not receive FilesMatchingFound event from bitbake server') |
123 | 137 | ||
124 | def test_setvariable_clean(self): | 138 | def test_setvariable_clean(self): |
diff --git a/meta/lib/oeqa/selftest/cases/wic.py b/meta/lib/oeqa/selftest/cases/wic.py index 0435aa29c9..f7abdba015 100644 --- a/meta/lib/oeqa/selftest/cases/wic.py +++ b/meta/lib/oeqa/selftest/cases/wic.py | |||
@@ -905,14 +905,18 @@ class Wic2(WicTestCase): | |||
905 | @only_for_arch(['i586', 'i686', 'x86_64']) | 905 | @only_for_arch(['i586', 'i686', 'x86_64']) |
906 | def test_rawcopy_plugin_qemu(self): | 906 | def test_rawcopy_plugin_qemu(self): |
907 | """Test rawcopy plugin in qemu""" | 907 | """Test rawcopy plugin in qemu""" |
908 | # build ext4 and wic images | 908 | # build ext4 and then use it for a wic image |
909 | for fstype in ("ext4", "wic"): | 909 | config = 'IMAGE_FSTYPES = "ext4"\n' |
910 | config = 'IMAGE_FSTYPES = "%s"\nWKS_FILE = "test_rawcopy_plugin.wks.in"\n' % fstype | 910 | self.append_config(config) |
911 | self.append_config(config) | 911 | self.assertEqual(0, bitbake('core-image-minimal').status) |
912 | self.assertEqual(0, bitbake('core-image-minimal').status) | 912 | self.remove_config(config) |
913 | self.remove_config(config) | ||
914 | 913 | ||
915 | with runqemu('core-image-minimal', ssh=False, image_fstype='wic') as qemu: | 914 | config = 'IMAGE_FSTYPES = "wic"\nWKS_FILE = "test_rawcopy_plugin.wks.in"\n' |
915 | self.append_config(config) | ||
916 | self.assertEqual(0, bitbake('core-image-minimal-mtdutils').status) | ||
917 | self.remove_config(config) | ||
918 | |||
919 | with runqemu('core-image-minimal-mtdutils', ssh=False, image_fstype='wic') as qemu: | ||
916 | cmd = "grep sda. /proc/partitions |wc -l" | 920 | cmd = "grep sda. /proc/partitions |wc -l" |
917 | status, output = qemu.run_serial(cmd) | 921 | status, output = qemu.run_serial(cmd) |
918 | self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output)) | 922 | self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output)) |