diff options
author | Mariano Lopez <mariano.lopez@linux.intel.com> | 2016-06-06 07:15:41 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2016-06-07 15:22:38 +0100 |
commit | 938f05333b94e91a628c940588e2bafc88b8bdef (patch) | |
tree | 0feb8cae22ed025cc6ac30c38aa00931684c970f | |
parent | d9b3ee8b38f877c1723e48f1aa311c28102786fb (diff) | |
download | poky-938f05333b94e91a628c940588e2bafc88b8bdef.tar.gz |
oetest.py: Add install/uninstall functionality for DUTs
Add the functionality to install/unistall packages in the
DUTs without the use of the package manager. This is possible
with the extraction introduced in package manager class.
testimage and testexport bbclasses has been modified in order
to support this new feature.
[YOCTO #8694]
(From OE-Core rev: b7111d9e9d64d21f57729d1ac1865aea6e54cc8b)
Signed-off-by: Mariano Lopez <mariano.lopez@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-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) |