diff options
Diffstat (limited to 'meta')
-rw-r--r-- | meta/classes/testexport.bbclass | 33 | ||||
-rw-r--r-- | meta/classes/testimage.bbclass | 18 | ||||
-rw-r--r-- | meta/lib/oeqa/oetest.py | 74 |
3 files changed, 120 insertions, 5 deletions
diff --git a/meta/classes/testexport.bbclass b/meta/classes/testexport.bbclass index c86eaac197..8046e29655 100644 --- a/meta/classes/testexport.bbclass +++ b/meta/classes/testexport.bbclass | |||
@@ -16,6 +16,9 @@ | |||
16 | 16 | ||
17 | TEST_LOG_DIR ?= "${WORKDIR}/testexport" | 17 | TEST_LOG_DIR ?= "${WORKDIR}/testexport" |
18 | TEST_EXPORT_DIR ?= "${TMPDIR}/testexport/${PN}" | 18 | TEST_EXPORT_DIR ?= "${TMPDIR}/testexport/${PN}" |
19 | TEST_EXPORT_PACKAGED_DIR ?= "packages/packaged" | ||
20 | TEST_EXPORT_EXTRACTED_DIR ?= "packages/extracted" | ||
21 | |||
19 | TEST_TARGET ?= "simpleremote" | 22 | TEST_TARGET ?= "simpleremote" |
20 | TEST_TARGET_IP ?= "" | 23 | TEST_TARGET_IP ?= "" |
21 | TEST_SERVER_IP ?= "" | 24 | TEST_SERVER_IP ?= "" |
@@ -28,9 +31,9 @@ python do_testexport() { | |||
28 | } | 31 | } |
29 | 32 | ||
30 | addtask testexport | 33 | addtask testexport |
31 | do_testimage[nostamp] = "1" | 34 | do_testexport[nostamp] = "1" |
32 | do_testimage[depends] += "${TEST_EXPORT_DEPENDS}" | 35 | do_testexport[depends] += "${TEST_EXPORT_DEPENDS} ${TESTIMAGEDEPENDS}" |
33 | do_testimage[lockfiles] += "${TEST_EXPORT_LOCK}" | 36 | do_testexport[lockfiles] += "${TEST_EXPORT_LOCK}" |
34 | 37 | ||
35 | def exportTests(d,tc): | 38 | def exportTests(d,tc): |
36 | import json | 39 | import json |
@@ -96,6 +99,9 @@ def exportTests(d,tc): | |||
96 | shutil.copytree(foldername, target_folder) | 99 | shutil.copytree(foldername, target_folder) |
97 | if not isfolder: | 100 | if not isfolder: |
98 | shutil.copy2(mod.path, os.path.join(exportpath, "oeqa/runtime")) | 101 | shutil.copy2(mod.path, os.path.join(exportpath, "oeqa/runtime")) |
102 | json_file = "%s.json" % mod.path.rsplit(".", 1)[0] | ||
103 | if os.path.isfile(json_file): | ||
104 | shutil.copy2(json_file, os.path.join(exportpath, "oeqa/runtime")) | ||
99 | # Get meta layer | 105 | # Get meta layer |
100 | for layer in d.getVar("BBLAYERS", True).split(): | 106 | for layer in d.getVar("BBLAYERS", True).split(): |
101 | if os.path.basename(layer) == "meta": | 107 | if os.path.basename(layer) == "meta": |
@@ -115,6 +121,20 @@ def exportTests(d,tc): | |||
115 | for f in files: | 121 | for f in files: |
116 | shutil.copy2(os.path.join(root, f), os.path.join(exportpath, "oeqa/runtime/files")) | 122 | shutil.copy2(os.path.join(root, f), os.path.join(exportpath, "oeqa/runtime/files")) |
117 | 123 | ||
124 | # Copy packages needed for runtime testing | ||
125 | export_pkg_dir = os.path.join(d.getVar("TEST_EXPORT_DIR", True), "packages") | ||
126 | test_pkg_dir = d.getVar("TEST_NEEDED_PACKAGES_DIR", True) | ||
127 | for root, subdirs, files in os.walk(test_pkg_dir): | ||
128 | for subdir in subdirs: | ||
129 | tmp_dir = os.path.join(root.replace(test_pkg_dir, "").lstrip("/"), subdir) | ||
130 | new_dir = os.path.join(export_pkg_dir, tmp_dir) | ||
131 | bb.utils.mkdirhier(new_dir) | ||
132 | |||
133 | for f in files: | ||
134 | src_f = os.path.join(root, f) | ||
135 | dst_f = os.path.join(export_pkg_dir, root.replace(test_pkg_dir, "").lstrip("/"), f) | ||
136 | shutil.copy2(src_f, dst_f) | ||
137 | |||
118 | bb.plain("Exported tests to: %s" % exportpath) | 138 | bb.plain("Exported tests to: %s" % exportpath) |
119 | 139 | ||
120 | def testexport_main(d): | 140 | def testexport_main(d): |
@@ -122,9 +142,11 @@ def testexport_main(d): | |||
122 | from oeqa.targetcontrol import get_target_controller | 142 | from oeqa.targetcontrol import get_target_controller |
123 | from oeqa.utils.dump import get_host_dumper | 143 | from oeqa.utils.dump import get_host_dumper |
124 | 144 | ||
145 | test_create_extract_dirs(d) | ||
146 | export_dir = d.getVar("TEST_EXPORT_DIR", True) | ||
125 | bb.utils.mkdirhier(d.getVar("TEST_LOG_DIR", True)) | 147 | bb.utils.mkdirhier(d.getVar("TEST_LOG_DIR", True)) |
126 | bb.utils.remove(d.getVar("TEST_EXPORT_DIR", True), recurse=True) | 148 | bb.utils.remove(export_dir, recurse=True) |
127 | bb.utils.mkdirhier(d.getVar("TEST_EXPORT_DIR", True)) | 149 | bb.utils.mkdirhier(export_dir) |
128 | 150 | ||
129 | # the robot dance | 151 | # the robot dance |
130 | target = get_target_controller(d) | 152 | target = get_target_controller(d) |
@@ -141,6 +163,7 @@ def testexport_main(d): | |||
141 | import traceback | 163 | import traceback |
142 | bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) | 164 | bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) |
143 | 165 | ||
166 | tc.extract_packages() | ||
144 | exportTests(d,tc) | 167 | exportTests(d,tc) |
145 | 168 | ||
146 | testexport_main[vardepsexclude] =+ "BB_ORIGENV" | 169 | testexport_main[vardepsexclude] =+ "BB_ORIGENV" |
diff --git a/meta/classes/testimage.bbclass b/meta/classes/testimage.bbclass index a2e13df710..a70d3a885e 100644 --- a/meta/classes/testimage.bbclass +++ b/meta/classes/testimage.bbclass | |||
@@ -30,6 +30,10 @@ | |||
30 | TEST_LOG_DIR ?= "${WORKDIR}/testimage" | 30 | TEST_LOG_DIR ?= "${WORKDIR}/testimage" |
31 | 31 | ||
32 | TEST_EXPORT_DIR ?= "${TMPDIR}/testimage/${PN}" | 32 | TEST_EXPORT_DIR ?= "${TMPDIR}/testimage/${PN}" |
33 | TEST_INSTALL_TMP_DIR ?= "${WORKDIR}/testimage/install_tmp" | ||
34 | TEST_NEEDED_PACKAGES_DIR ?= "${WORKDIR}/testimage/packages" | ||
35 | TEST_EXTRACTED_DIR ?= "${TEST_NEEDED_PACKAGES_DIR}/extracted" | ||
36 | TEST_PACKAGED_DIR ?= "${TEST_NEEDED_PACKAGES_DIR}/packaged" | ||
33 | 37 | ||
34 | RPMTESTSUITE = "${@bb.utils.contains('IMAGE_PKGTYPE', 'rpm', 'smart rpm', '', d)}" | 38 | RPMTESTSUITE = "${@bb.utils.contains('IMAGE_PKGTYPE', 'rpm', 'smart rpm', '', d)}" |
35 | MINTESTSUITE = "ping" | 39 | MINTESTSUITE = "ping" |
@@ -100,6 +104,7 @@ testimage_dump_host () { | |||
100 | python do_testimage() { | 104 | python do_testimage() { |
101 | testimage_main(d) | 105 | testimage_main(d) |
102 | } | 106 | } |
107 | |||
103 | addtask testimage | 108 | addtask testimage |
104 | do_testimage[nostamp] = "1" | 109 | do_testimage[nostamp] = "1" |
105 | do_testimage[depends] += "${TESTIMAGEDEPENDS}" | 110 | do_testimage[depends] += "${TESTIMAGEDEPENDS}" |
@@ -117,6 +122,7 @@ def testimage_main(d): | |||
117 | 122 | ||
118 | pn = d.getVar("PN", True) | 123 | pn = d.getVar("PN", True) |
119 | bb.utils.mkdirhier(d.getVar("TEST_LOG_DIR", True)) | 124 | bb.utils.mkdirhier(d.getVar("TEST_LOG_DIR", True)) |
125 | test_create_extract_dirs(d) | ||
120 | 126 | ||
121 | # we need the host dumper in test context | 127 | # we need the host dumper in test context |
122 | host_dumper = get_host_dumper(d) | 128 | host_dumper = get_host_dumper(d) |
@@ -136,6 +142,7 @@ def testimage_main(d): | |||
136 | import traceback | 142 | import traceback |
137 | bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) | 143 | bb.fatal("Loading tests failed:\n%s" % traceback.format_exc()) |
138 | 144 | ||
145 | tc.extract_packages() | ||
139 | target.deploy() | 146 | target.deploy() |
140 | try: | 147 | try: |
141 | target.start() | 148 | target.start() |
@@ -155,6 +162,17 @@ def testimage_main(d): | |||
155 | signal.signal(signal.SIGTERM, tc.origsigtermhandler) | 162 | signal.signal(signal.SIGTERM, tc.origsigtermhandler) |
156 | target.stop() | 163 | target.stop() |
157 | 164 | ||
165 | def test_create_extract_dirs(d): | ||
166 | install_path = d.getVar("TEST_INSTALL_TMP_DIR", True) | ||
167 | package_path = d.getVar("TEST_PACKAGED_DIR", True) | ||
168 | extracted_path = d.getVar("TEST_EXTRACTED_DIR", True) | ||
169 | bb.utils.mkdirhier(d.getVar("TEST_LOG_DIR", True)) | ||
170 | bb.utils.remove(package_path, recurse=True) | ||
171 | bb.utils.mkdirhier(install_path) | ||
172 | bb.utils.mkdirhier(package_path) | ||
173 | bb.utils.mkdirhier(extracted_path) | ||
174 | |||
175 | |||
158 | testimage_main[vardepsexclude] =+ "BB_ORIGENV" | 176 | testimage_main[vardepsexclude] =+ "BB_ORIGENV" |
159 | 177 | ||
160 | inherit testsdk | 178 | inherit testsdk |
diff --git a/meta/lib/oeqa/oetest.py b/meta/lib/oeqa/oetest.py index 819f95987b..feb0f71eb4 100644 --- a/meta/lib/oeqa/oetest.py +++ b/meta/lib/oeqa/oetest.py | |||
@@ -81,6 +81,9 @@ class oeRuntimeTest(oeTest): | |||
81 | super(oeRuntimeTest, self).__init__(methodName) | 81 | super(oeRuntimeTest, self).__init__(methodName) |
82 | 82 | ||
83 | def setUp(self): | 83 | def setUp(self): |
84 | # Install packages in the DUT | ||
85 | self.tc.install_uninstall_packages(self.id()) | ||
86 | |||
84 | # Check if test needs to run | 87 | # Check if test needs to run |
85 | if self.tc.sigterm: | 88 | if self.tc.sigterm: |
86 | self.fail("Got SIGTERM") | 89 | self.fail("Got SIGTERM") |
@@ -94,6 +97,9 @@ class oeRuntimeTest(oeTest): | |||
94 | pass | 97 | pass |
95 | 98 | ||
96 | def tearDown(self): | 99 | def tearDown(self): |
100 | # Unistall packages in the DUT | ||
101 | self.tc.install_uninstall_packages(self.id(), False) | ||
102 | |||
97 | res = getResults() | 103 | res = getResults() |
98 | # If a test fails or there is an exception dump | 104 | # If a test fails or there is an exception dump |
99 | # for QemuTarget only | 105 | # for QemuTarget only |
@@ -281,6 +287,19 @@ class TestContext(object): | |||
281 | 287 | ||
282 | return modules | 288 | return modules |
283 | 289 | ||
290 | def getModulefromID(self, test_id): | ||
291 | """ | ||
292 | Returns the test module based on a test id. | ||
293 | """ | ||
294 | |||
295 | module_name = ".".join(test_id.split(".")[:3]) | ||
296 | modules = self.getTestModules() | ||
297 | for module in modules: | ||
298 | if module.name == module_name: | ||
299 | return module | ||
300 | |||
301 | return None | ||
302 | |||
284 | def getTests(self, test): | 303 | def getTests(self, test): |
285 | '''Return all individual tests executed when running the suite.''' | 304 | '''Return all individual tests executed when running the suite.''' |
286 | # Unfortunately unittest does not have an API for this, so we have | 305 | # Unfortunately unittest does not have an API for this, so we have |
@@ -521,6 +540,43 @@ class RuntimeTestContext(TestContext): | |||
521 | shutil.copy2(file_path, dst_dir) | 540 | shutil.copy2(file_path, dst_dir) |
522 | shutil.rmtree(pkg_path) | 541 | shutil.rmtree(pkg_path) |
523 | 542 | ||
543 | def install_uninstall_packages(self, test_id, pkg_dir, install): | ||
544 | """ | ||
545 | Check if the test requires a package and Install/Unistall it in the DUT | ||
546 | """ | ||
547 | |||
548 | test = test_id.split(".")[4] | ||
549 | module = self.getModulefromID(test_id) | ||
550 | json = self._getJsonFile(module) | ||
551 | if json: | ||
552 | needed_packages = self._getNeededPackages(json, test) | ||
553 | if needed_packages: | ||
554 | self._install_uninstall_packages(needed_packages, pkg_dir, install) | ||
555 | |||
556 | def _install_uninstall_packages(self, needed_packages, pkg_dir, install=True): | ||
557 | """ | ||
558 | Install/Unistall packages in the DUT without using a package manager | ||
559 | """ | ||
560 | |||
561 | if isinstance(needed_packages, dict): | ||
562 | packages = [needed_packages] | ||
563 | elif isinstance(needed_packages, list): | ||
564 | packages = needed_packages | ||
565 | |||
566 | for package in packages: | ||
567 | pkg = package["pkg"] | ||
568 | rm = package.get("rm", False) | ||
569 | extract = package.get("extract", True) | ||
570 | src_dir = os.path.join(pkg_dir, pkg) | ||
571 | |||
572 | # Install package | ||
573 | if install and extract: | ||
574 | self.target.connection.copy_dir_to(src_dir, "/") | ||
575 | |||
576 | # Unistall package | ||
577 | elif not install and rm: | ||
578 | self.target.connection.delete_dir_structure(src_dir, "/") | ||
579 | |||
524 | class ImageTestContext(RuntimeTestContext): | 580 | class ImageTestContext(RuntimeTestContext): |
525 | def __init__(self, d, target, host_dumper): | 581 | def __init__(self, d, target, host_dumper): |
526 | super(ImageTestContext, self).__init__(d, target) | 582 | super(ImageTestContext, self).__init__(d, target) |
@@ -536,11 +592,29 @@ class ImageTestContext(RuntimeTestContext): | |||
536 | self.sigterm = True | 592 | self.sigterm = True |
537 | self.target.stop() | 593 | self.target.stop() |
538 | 594 | ||
595 | def install_uninstall_packages(self, test_id, install=True): | ||
596 | """ | ||
597 | Check if the test requires a package and Install/Unistall it in the DUT | ||
598 | """ | ||
599 | |||
600 | pkg_dir = self.d.getVar("TEST_EXTRACTED_DIR", True) | ||
601 | super(ImageTestContext, self).install_uninstall_packages(test_id, pkg_dir, install) | ||
602 | |||
539 | class ExportTestContext(RuntimeTestContext): | 603 | class ExportTestContext(RuntimeTestContext): |
540 | def __init__(self, d, target, exported=False): | 604 | def __init__(self, d, target, exported=False): |
541 | super(ExportTestContext, self).__init__(d, target, exported) | 605 | super(ExportTestContext, self).__init__(d, target, exported) |
542 | self.sigterm = None | 606 | self.sigterm = None |
543 | 607 | ||
608 | def install_uninstall_packages(self, test_id, install=True): | ||
609 | """ | ||
610 | Check if the test requires a package and Install/Unistall it in the DUT | ||
611 | """ | ||
612 | |||
613 | export_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) | ||
614 | extracted_dir = self.d.getVar("TEST_EXPORT_EXTRACTED_DIR", True) | ||
615 | pkg_dir = os.path.join(export_dir, extracted_dir) | ||
616 | super(ExportTestContext, self).install_uninstall_packages(test_id, pkg_dir, install) | ||
617 | |||
544 | class SDKTestContext(TestContext): | 618 | class SDKTestContext(TestContext): |
545 | def __init__(self, d, sdktestdir, sdkenv, tcname, *args): | 619 | def __init__(self, d, sdktestdir, sdkenv, tcname, *args): |
546 | super(SDKTestContext, self).__init__(d) | 620 | super(SDKTestContext, self).__init__(d) |