Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 1 | from oeqa.selftest.case import OESelftestTestCase |
| 2 | from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars, runqemu |
| 3 | from oeqa.utils.sshcontrol import SSHControl |
| 4 | from oeqa.core.decorator.oeid import OETestID |
| 5 | import os |
| 6 | import re |
| 7 | import tempfile |
| 8 | import shutil |
| 9 | |
| 10 | class TestExport(OESelftestTestCase): |
| 11 | |
| 12 | @classmethod |
| 13 | def tearDownClass(cls): |
| 14 | runCmd("rm -rf /tmp/sdk") |
| 15 | super(TestExport, cls).tearDownClass() |
| 16 | |
| 17 | @OETestID(1499) |
| 18 | def test_testexport_basic(self): |
| 19 | """ |
| 20 | Summary: Check basic testexport functionality with only ping test enabled. |
| 21 | Expected: 1. testexport directory must be created. |
| 22 | 2. runexported.py must run without any error/exception. |
| 23 | 3. ping test must succeed. |
| 24 | Product: oe-core |
| 25 | Author: Mariano Lopez <mariano.lopez@intel.com> |
| 26 | """ |
| 27 | |
| 28 | features = 'INHERIT += "testexport"\n' |
| 29 | # These aren't the actual IP addresses but testexport class needs something defined |
| 30 | features += 'TEST_SERVER_IP = "192.168.7.1"\n' |
| 31 | features += 'TEST_TARGET_IP = "192.168.7.1"\n' |
| 32 | features += 'TEST_SUITES = "ping"\n' |
| 33 | self.write_config(features) |
| 34 | |
| 35 | # Build tesexport for core-image-minimal |
| 36 | bitbake('core-image-minimal') |
| 37 | bitbake('-c testexport core-image-minimal') |
| 38 | |
| 39 | testexport_dir = get_bb_var('TEST_EXPORT_DIR', 'core-image-minimal') |
| 40 | |
| 41 | # Verify if TEST_EXPORT_DIR was created |
| 42 | isdir = os.path.isdir(testexport_dir) |
| 43 | self.assertEqual(True, isdir, 'Failed to create testexport dir: %s' % testexport_dir) |
| 44 | |
| 45 | with runqemu('core-image-minimal') as qemu: |
| 46 | # Attempt to run runexported.py to perform ping test |
| 47 | test_path = os.path.join(testexport_dir, "oe-test") |
| 48 | data_file = os.path.join(testexport_dir, 'data', 'testdata.json') |
| 49 | manifest = os.path.join(testexport_dir, 'data', 'manifest') |
| 50 | cmd = ("%s runtime --test-data-file %s --packages-manifest %s " |
| 51 | "--target-ip %s --server-ip %s --quiet" |
| 52 | % (test_path, data_file, manifest, qemu.ip, qemu.server_ip)) |
| 53 | result = runCmd(cmd) |
| 54 | # Verify ping test was succesful |
| 55 | self.assertEqual(0, result.status, 'oe-test runtime returned a non 0 status') |
| 56 | |
| 57 | @OETestID(1641) |
| 58 | def test_testexport_sdk(self): |
| 59 | """ |
| 60 | Summary: Check sdk functionality for testexport. |
| 61 | Expected: 1. testexport directory must be created. |
| 62 | 2. SDK tarball must exists. |
| 63 | 3. Uncompressing of tarball must succeed. |
| 64 | 4. Check if the SDK directory is added to PATH. |
| 65 | 5. Run tar from the SDK directory. |
| 66 | Product: oe-core |
| 67 | Author: Mariano Lopez <mariano.lopez@intel.com> |
| 68 | """ |
| 69 | |
| 70 | features = 'INHERIT += "testexport"\n' |
| 71 | # These aren't the actual IP addresses but testexport class needs something defined |
| 72 | features += 'TEST_SERVER_IP = "192.168.7.1"\n' |
| 73 | features += 'TEST_TARGET_IP = "192.168.7.1"\n' |
| 74 | features += 'TEST_SUITES = "ping"\n' |
| 75 | features += 'TEST_EXPORT_SDK_ENABLED = "1"\n' |
| 76 | features += 'TEST_EXPORT_SDK_PACKAGES = "nativesdk-tar"\n' |
| 77 | self.write_config(features) |
| 78 | |
| 79 | # Build tesexport for core-image-minimal |
| 80 | bitbake('core-image-minimal') |
| 81 | bitbake('-c testexport core-image-minimal') |
| 82 | |
| 83 | needed_vars = ['TEST_EXPORT_DIR', 'TEST_EXPORT_SDK_DIR', 'TEST_EXPORT_SDK_NAME'] |
| 84 | bb_vars = get_bb_vars(needed_vars, 'core-image-minimal') |
| 85 | testexport_dir = bb_vars['TEST_EXPORT_DIR'] |
| 86 | sdk_dir = bb_vars['TEST_EXPORT_SDK_DIR'] |
| 87 | sdk_name = bb_vars['TEST_EXPORT_SDK_NAME'] |
| 88 | |
| 89 | # Check for SDK |
| 90 | tarball_name = "%s.sh" % sdk_name |
| 91 | tarball_path = os.path.join(testexport_dir, sdk_dir, tarball_name) |
| 92 | msg = "Couldn't find SDK tarball: %s" % tarball_path |
| 93 | self.assertEqual(os.path.isfile(tarball_path), True, msg) |
| 94 | |
| 95 | # Extract SDK and run tar from SDK |
| 96 | result = runCmd("%s -y -d /tmp/sdk" % tarball_path) |
| 97 | self.assertEqual(0, result.status, "Couldn't extract SDK") |
| 98 | |
| 99 | env_script = result.output.split()[-1] |
| 100 | result = runCmd(". %s; which tar" % env_script, shell=True) |
| 101 | self.assertEqual(0, result.status, "Couldn't setup SDK environment") |
| 102 | is_sdk_tar = True if "/tmp/sdk" in result.output else False |
| 103 | self.assertTrue(is_sdk_tar, "Couldn't setup SDK environment") |
| 104 | |
| 105 | tar_sdk = result.output |
| 106 | result = runCmd("%s --version" % tar_sdk) |
| 107 | self.assertEqual(0, result.status, "Couldn't run tar from SDK") |
| 108 | |
| 109 | |
| 110 | class TestImage(OESelftestTestCase): |
| 111 | |
| 112 | @OETestID(1644) |
| 113 | def test_testimage_install(self): |
| 114 | """ |
| 115 | Summary: Check install packages functionality for testimage/testexport. |
| 116 | Expected: 1. Import tests from a directory other than meta. |
| 117 | 2. Check install/uninstall of socat. |
| 118 | Product: oe-core |
| 119 | Author: Mariano Lopez <mariano.lopez@intel.com> |
| 120 | """ |
| 121 | if get_bb_var('DISTRO') == 'poky-tiny': |
| 122 | self.skipTest('core-image-full-cmdline not buildable for poky-tiny') |
| 123 | |
| 124 | features = 'INHERIT += "testimage"\n' |
Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame^] | 125 | features += 'IMAGE_INSTALL_append = " libssl"\n' |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 126 | features += 'TEST_SUITES = "ping ssh selftest"\n' |
| 127 | self.write_config(features) |
| 128 | |
| 129 | # Build core-image-sato and testimage |
| 130 | bitbake('core-image-full-cmdline socat') |
| 131 | bitbake('-c testimage core-image-full-cmdline') |
| 132 | |
| 133 | @OETestID(1883) |
| 134 | def test_testimage_dnf(self): |
| 135 | """ |
| 136 | Summary: Check package feeds functionality for dnf |
| 137 | Expected: 1. Check that remote package feeds can be accessed |
| 138 | Product: oe-core |
Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame^] | 139 | Author: Alexander Kanavin <alex.kanavin@gmail.com> |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 140 | """ |
| 141 | if get_bb_var('DISTRO') == 'poky-tiny': |
| 142 | self.skipTest('core-image-full-cmdline not buildable for poky-tiny') |
| 143 | |
| 144 | features = 'INHERIT += "testimage"\n' |
| 145 | features += 'TEST_SUITES = "ping ssh dnf_runtime dnf.DnfBasicTest.test_dnf_help"\n' |
| 146 | # We don't yet know what the server ip and port will be - they will be patched |
| 147 | # in at the start of the on-image test |
| 148 | features += 'PACKAGE_FEED_URIS = "http://bogus_ip:bogus_port"\n' |
| 149 | features += 'EXTRA_IMAGE_FEATURES += "package-management"\n' |
| 150 | features += 'PACKAGE_CLASSES = "package_rpm"\n' |
| 151 | |
Brad Bishop | 6f8dcde | 2018-10-16 10:47:12 +0800 | [diff] [blame] | 152 | bitbake('gnupg-native -c addto_recipe_sysroot') |
| 153 | |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 154 | # Enable package feed signing |
| 155 | self.gpg_home = tempfile.mkdtemp(prefix="oeqa-feed-sign-") |
| 156 | signing_key_dir = os.path.join(self.testlayer_path, 'files', 'signing') |
Brad Bishop | 6f8dcde | 2018-10-16 10:47:12 +0800 | [diff] [blame] | 157 | runCmd('gpg --batch --homedir %s --import %s' % (self.gpg_home, os.path.join(signing_key_dir, 'key.secret')), native_sysroot=get_bb_var("RECIPE_SYSROOT_NATIVE", "gnupg-native")) |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 158 | features += 'INHERIT += "sign_package_feed"\n' |
| 159 | features += 'PACKAGE_FEED_GPG_NAME = "testuser"\n' |
| 160 | features += 'PACKAGE_FEED_GPG_PASSPHRASE_FILE = "%s"\n' % os.path.join(signing_key_dir, 'key.passphrase') |
| 161 | features += 'GPG_PATH = "%s"\n' % self.gpg_home |
| 162 | self.write_config(features) |
| 163 | |
| 164 | # Build core-image-sato and testimage |
| 165 | bitbake('core-image-full-cmdline socat') |
| 166 | bitbake('-c testimage core-image-full-cmdline') |
| 167 | |
| 168 | # remove the oeqa-feed-sign temporal directory |
| 169 | shutil.rmtree(self.gpg_home, ignore_errors=True) |
| 170 | |
| 171 | class Postinst(OESelftestTestCase): |
| 172 | @OETestID(1540) |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 173 | @OETestID(1545) |
| 174 | def test_postinst_rootfs_and_boot(self): |
| 175 | """ |
| 176 | Summary: The purpose of this test case is to verify Post-installation |
| 177 | scripts are called when rootfs is created and also test |
| 178 | that script can be delayed to run at first boot. |
| 179 | Dependencies: NA |
| 180 | Steps: 1. Add proper configuration to local.conf file |
| 181 | 2. Build a "core-image-minimal" image |
| 182 | 3. Verify that file created by postinst_rootfs recipe is |
| 183 | present on rootfs dir. |
| 184 | 4. Boot the image created on qemu and verify that the file |
| 185 | created by postinst_boot recipe is present on image. |
| 186 | Expected: The files are successfully created during rootfs and boot |
| 187 | time for 3 different package managers: rpm,ipk,deb and |
| 188 | for initialization managers: sysvinit and systemd. |
| 189 | |
| 190 | """ |
Brad Bishop | 316dfdd | 2018-06-25 12:45:53 -0400 | [diff] [blame] | 191 | |
| 192 | import oe.path |
| 193 | |
| 194 | vars = get_bb_vars(("IMAGE_ROOTFS", "sysconfdir"), "core-image-minimal") |
| 195 | rootfs = vars["IMAGE_ROOTFS"] |
| 196 | self.assertIsNotNone(rootfs) |
| 197 | sysconfdir = vars["sysconfdir"] |
| 198 | self.assertIsNotNone(sysconfdir) |
| 199 | # Need to use oe.path here as sysconfdir starts with / |
| 200 | hosttestdir = oe.path.join(rootfs, sysconfdir, "postinst-test") |
| 201 | targettestdir = os.path.join(sysconfdir, "postinst-test") |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 202 | |
| 203 | for init_manager in ("sysvinit", "systemd"): |
| 204 | for classes in ("package_rpm", "package_deb", "package_ipk"): |
| 205 | with self.subTest(init_manager=init_manager, package_class=classes): |
Brad Bishop | 316dfdd | 2018-06-25 12:45:53 -0400 | [diff] [blame] | 206 | features = 'CORE_IMAGE_EXTRA_INSTALL = "postinst-delayed-b"\n' |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 207 | features += 'IMAGE_FEATURES += "package-management empty-root-password"\n' |
| 208 | features += 'PACKAGE_CLASSES = "%s"\n' % classes |
| 209 | if init_manager == "systemd": |
| 210 | features += 'DISTRO_FEATURES_append = " systemd"\n' |
| 211 | features += 'VIRTUAL-RUNTIME_init_manager = "systemd"\n' |
| 212 | features += 'DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"\n' |
| 213 | features += 'VIRTUAL-RUNTIME_initscripts = ""\n' |
| 214 | self.write_config(features) |
| 215 | |
| 216 | bitbake('core-image-minimal') |
| 217 | |
Brad Bishop | 316dfdd | 2018-06-25 12:45:53 -0400 | [diff] [blame] | 218 | self.assertTrue(os.path.isfile(os.path.join(hosttestdir, "rootfs")), |
| 219 | "rootfs state file was not created") |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 220 | |
Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 221 | with runqemu('core-image-minimal') as qemu: |
Brad Bishop | 316dfdd | 2018-06-25 12:45:53 -0400 | [diff] [blame] | 222 | # Make the test echo a string and search for that as |
| 223 | # run_serial()'s status code is useless.' |
| 224 | for filename in ("rootfs", "delayed-a", "delayed-b"): |
| 225 | status, output = qemu.run_serial("test -f %s && echo found" % os.path.join(targettestdir, filename)) |
| 226 | self.assertEqual(output, "found", "%s was not present on boot" % filename) |
| 227 | |
| 228 | |
| 229 | |
| 230 | def test_failing_postinst(self): |
| 231 | """ |
| 232 | Summary: The purpose of this test case is to verify that post-installation |
| 233 | scripts that contain errors are properly reported. |
| 234 | Expected: The scriptlet failure is properly reported. |
| 235 | The file that is created after the error in the scriptlet is not present. |
| 236 | Product: oe-core |
Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame^] | 237 | Author: Alexander Kanavin <alex.kanavin@gmail.com> |
Brad Bishop | 316dfdd | 2018-06-25 12:45:53 -0400 | [diff] [blame] | 238 | """ |
| 239 | |
| 240 | import oe.path |
| 241 | |
| 242 | vars = get_bb_vars(("IMAGE_ROOTFS", "sysconfdir"), "core-image-minimal") |
| 243 | rootfs = vars["IMAGE_ROOTFS"] |
| 244 | self.assertIsNotNone(rootfs) |
| 245 | sysconfdir = vars["sysconfdir"] |
| 246 | self.assertIsNotNone(sysconfdir) |
| 247 | # Need to use oe.path here as sysconfdir starts with / |
| 248 | hosttestdir = oe.path.join(rootfs, sysconfdir, "postinst-test") |
| 249 | |
| 250 | for classes in ("package_rpm", "package_deb", "package_ipk"): |
| 251 | with self.subTest(package_class=classes): |
| 252 | features = 'CORE_IMAGE_EXTRA_INSTALL = "postinst-rootfs-failing"\n' |
| 253 | features += 'PACKAGE_CLASSES = "%s"\n' % classes |
| 254 | self.write_config(features) |
Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame^] | 255 | bb_result = bitbake('core-image-minimal', ignore_status=True) |
| 256 | self.assertGreaterEqual(bb_result.output.find("Postinstall scriptlets of ['postinst-rootfs-failing'] have failed."), 0, |
Brad Bishop | 316dfdd | 2018-06-25 12:45:53 -0400 | [diff] [blame] | 257 | "Warning about a failed scriptlet not found in bitbake output: %s" %(bb_result.output)) |
| 258 | |
| 259 | self.assertTrue(os.path.isfile(os.path.join(hosttestdir, "rootfs-before-failure")), |
| 260 | "rootfs-before-failure file was not created") |
| 261 | self.assertFalse(os.path.isfile(os.path.join(hosttestdir, "rootfs-after-failure")), |
| 262 | "rootfs-after-failure file was created") |
| 263 | |