blob: 51d835259e4896f8daa7853e884591121912a468 [file] [log] [blame]
Brad Bishopc342db32019-05-15 21:57:59 -04001#
2# SPDX-License-Identifier: MIT
3#
4
Brad Bishopd7bf8c12018-02-25 22:55:05 -05005from oeqa.selftest.case import OESelftestTestCase
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08006from oeqa.utils.commands import bitbake, get_bb_vars, get_bb_var, runqemu
Brad Bishopd7bf8c12018-02-25 22:55:05 -05007import subprocess, os
8import oe.path
Brad Bishop15ae2502019-06-18 21:44:24 -04009import re
Brad Bishopd7bf8c12018-02-25 22:55:05 -050010
11class VersionOrdering(OESelftestTestCase):
12 # version1, version2, sort order
13 tests = (
14 ("1.0", "1.0", 0),
15 ("1.0", "2.0", -1),
16 ("2.0", "1.0", 1),
17 ("2.0-rc", "2.0", 1),
18 ("2.0~rc", "2.0", -1),
19 ("1.2rc2", "1.2.0", -1)
20 )
21
22 @classmethod
23 def setUpClass(cls):
24 super().setUpClass()
25
26 # Build the tools we need and populate a sysroot
27 bitbake("dpkg-native opkg-native rpm-native python3-native")
28 bitbake("build-sysroots -c build_native_sysroot")
29
30 # Get the paths so we can point into the sysroot correctly
31 vars = get_bb_vars(["STAGING_DIR", "BUILD_ARCH", "bindir_native", "libdir_native"])
32 cls.staging = oe.path.join(vars["STAGING_DIR"], vars["BUILD_ARCH"])
33 cls.bindir = oe.path.join(cls.staging, vars["bindir_native"])
34 cls.libdir = oe.path.join(cls.staging, vars["libdir_native"])
35
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080036 def setUpLocal(self):
Brad Bishopd7bf8c12018-02-25 22:55:05 -050037 # Just for convenience
38 self.staging = type(self).staging
39 self.bindir = type(self).bindir
40 self.libdir = type(self).libdir
41
Brad Bishopd7bf8c12018-02-25 22:55:05 -050042 def test_dpkg(self):
43 for ver1, ver2, sort in self.tests:
44 op = { -1: "<<", 0: "=", 1: ">>" }[sort]
45 status = subprocess.call((oe.path.join(self.bindir, "dpkg"), "--compare-versions", ver1, op, ver2))
46 self.assertEqual(status, 0, "%s %s %s failed" % (ver1, op, ver2))
47
48 # Now do it again but with incorrect operations
49 op = { -1: ">>", 0: ">>", 1: "<<" }[sort]
50 status = subprocess.call((oe.path.join(self.bindir, "dpkg"), "--compare-versions", ver1, op, ver2))
51 self.assertNotEqual(status, 0, "%s %s %s failed" % (ver1, op, ver2))
52
53 # Now do it again but with incorrect operations
54 op = { -1: "=", 0: "<<", 1: "=" }[sort]
55 status = subprocess.call((oe.path.join(self.bindir, "dpkg"), "--compare-versions", ver1, op, ver2))
56 self.assertNotEqual(status, 0, "%s %s %s failed" % (ver1, op, ver2))
57
Brad Bishopd7bf8c12018-02-25 22:55:05 -050058 def test_opkg(self):
59 for ver1, ver2, sort in self.tests:
60 op = { -1: "<<", 0: "=", 1: ">>" }[sort]
61 status = subprocess.call((oe.path.join(self.bindir, "opkg"), "compare-versions", ver1, op, ver2))
62 self.assertEqual(status, 0, "%s %s %s failed" % (ver1, op, ver2))
63
64 # Now do it again but with incorrect operations
65 op = { -1: ">>", 0: ">>", 1: "<<" }[sort]
66 status = subprocess.call((oe.path.join(self.bindir, "opkg"), "compare-versions", ver1, op, ver2))
67 self.assertNotEqual(status, 0, "%s %s %s failed" % (ver1, op, ver2))
68
69 # Now do it again but with incorrect operations
70 op = { -1: "=", 0: "<<", 1: "=" }[sort]
71 status = subprocess.call((oe.path.join(self.bindir, "opkg"), "compare-versions", ver1, op, ver2))
72 self.assertNotEqual(status, 0, "%s %s %s failed" % (ver1, op, ver2))
73
Brad Bishopd7bf8c12018-02-25 22:55:05 -050074 def test_rpm(self):
75 # Need to tell the Python bindings where to find its configuration
76 env = os.environ.copy()
77 env["RPM_CONFIGDIR"] = oe.path.join(self.libdir, "rpm")
78
79 for ver1, ver2, sort in self.tests:
80 # The only way to test rpm is via the Python module, so we need to
81 # execute python3-native. labelCompare returns -1/0/1 (like strcmp)
82 # so add 100 and use that as the exit code.
83 command = (oe.path.join(self.bindir, "python3-native", "python3"), "-c",
84 "import sys, rpm; v1=(None, \"%s\", None); v2=(None, \"%s\", None); sys.exit(rpm.labelCompare(v1, v2) + 100)" % (ver1, ver2))
85 status = subprocess.call(command, env=env)
86 self.assertIn(status, (99, 100, 101))
87 self.assertEqual(status - 100, sort, "%s %s (%d) failed" % (ver1, ver2, sort))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080088
89class PackageTests(OESelftestTestCase):
90 # Verify that a recipe which sets up hardlink files has those preserved into split packages
91 # Also test file sparseness is preserved
92 def test_preserve_sparse_hardlinks(self):
93 bitbake("selftest-hardlink -c package")
94
95 dest = get_bb_var('PKGDEST', 'selftest-hardlink')
96 bindir = get_bb_var('bindir', 'selftest-hardlink')
97
98 def checkfiles():
99 # Recipe creates 4 hardlinked files, there is a copy in package/ and a copy in packages-split/
100 # so expect 8 in total.
101 self.assertEqual(os.stat(dest + "/selftest-hardlink" + bindir + "/hello1").st_nlink, 8)
102
103 # Test a sparse file remains sparse
104 sparsestat = os.stat(dest + "/selftest-hardlink" + bindir + "/sparsetest")
105 self.assertEqual(sparsestat.st_blocks, 0)
106 self.assertEqual(sparsestat.st_size, 1048576)
107
108 checkfiles()
109
110 # Clean and reinstall so its now definitely from sstate, then retest.
111 bitbake("selftest-hardlink -c clean")
112 bitbake("selftest-hardlink -c package")
113
114 checkfiles()
115
116 # Verify gdb to read symbols from separated debug hardlink file correctly
117 def test_gdb_hardlink_debug(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500118 features = 'IMAGE_INSTALL:append = " selftest-hardlink"\n'
119 features += 'IMAGE_INSTALL:append = " selftest-hardlink-dbg"\n'
120 features += 'IMAGE_INSTALL:append = " selftest-hardlink-gdb"\n'
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800121 self.write_config(features)
122 bitbake("core-image-minimal")
123
124 def gdbtest(qemu, binary):
125 """
126 Check that gdb ``binary`` to read symbols from separated debug file
127 """
128 self.logger.info("gdbtest %s" % binary)
129 status, output = qemu.run_serial('/usr/bin/gdb.sh %s' % binary, timeout=60)
130 for l in output.split('\n'):
131 # Check debugging symbols exists
132 if '(no debugging symbols found)' in l:
133 self.logger.error("No debugging symbols found. GDB result:\n%s" % output)
134 return False
135
136 # Check debugging symbols works correctly
Andrew Geissler82c905d2020-04-13 13:39:40 -0500137 elif re.match(r"Breakpoint 1.*hello\.c.*4", l):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800138 return True
139
Brad Bishop19323692019-04-05 15:28:33 -0400140 self.logger.error("GDB result:\n%d: %s", status, output)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800141 return False
142
143 with runqemu('core-image-minimal') as qemu:
144 for binary in ['/usr/bin/hello1',
145 '/usr/bin/hello2',
146 '/usr/libexec/hello3',
147 '/usr/libexec/hello4']:
148 if not gdbtest(qemu, binary):
149 self.fail('GDB %s failed' % binary)
Andrew Geissler82c905d2020-04-13 13:39:40 -0500150
151 def test_preserve_ownership(self):
152 import os, stat, oe.cachedpath
Patrick Williams213cb262021-08-07 19:21:33 -0500153 features = 'IMAGE_INSTALL:append = " selftest-chown"\n'
Andrew Geissler82c905d2020-04-13 13:39:40 -0500154 self.write_config(features)
155 bitbake("core-image-minimal")
156
157 sysconfdir = get_bb_var('sysconfdir', 'selftest-chown')
158 def check_ownership(qemu, gid, uid, path):
159 self.logger.info("Check ownership of %s", path)
160 status, output = qemu.run_serial(r'/bin/stat -c "%U %G" ' + path, timeout=60)
161 output = output.split(" ")
162 if output[0] != uid or output[1] != gid :
163 self.logger.error("Incrrect ownership %s [%s:%s]", path, output[0], output[1])
164 return False
165 return True
166
167 with runqemu('core-image-minimal') as qemu:
168 for path in [ sysconfdir + "/selftest-chown/file",
169 sysconfdir + "/selftest-chown/dir",
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600170 sysconfdir + "/selftest-chown/symlink",
171 sysconfdir + "/selftest-chown/fifotest/fifo"]:
Andrew Geissler82c905d2020-04-13 13:39:40 -0500172 if not check_ownership(qemu, "test", "test", path):
173 self.fail('Test ownership %s failed' % path)