blob: 4f7cd10658ad12344f966ba372c149b14847e5bd [file] [log] [blame]
Brad Bishopc342db32019-05-15 21:57:59 -04001#
Patrick Williams92b42cb2022-09-03 06:53:57 -05002# Copyright OpenEmbedded Contributors
3#
Brad Bishopc342db32019-05-15 21:57:59 -04004# SPDX-License-Identifier: MIT
5#
6
Brad Bishopd7bf8c12018-02-25 22:55:05 -05007from oeqa.selftest.case import OESelftestTestCase
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08008from oeqa.utils.commands import bitbake, get_bb_vars, get_bb_var, runqemu
Brad Bishopd7bf8c12018-02-25 22:55:05 -05009import subprocess, os
10import oe.path
Brad Bishop15ae2502019-06-18 21:44:24 -040011import re
Brad Bishopd7bf8c12018-02-25 22:55:05 -050012
13class VersionOrdering(OESelftestTestCase):
14 # version1, version2, sort order
15 tests = (
16 ("1.0", "1.0", 0),
17 ("1.0", "2.0", -1),
18 ("2.0", "1.0", 1),
19 ("2.0-rc", "2.0", 1),
20 ("2.0~rc", "2.0", -1),
21 ("1.2rc2", "1.2.0", -1)
22 )
23
24 @classmethod
25 def setUpClass(cls):
26 super().setUpClass()
27
28 # Build the tools we need and populate a sysroot
29 bitbake("dpkg-native opkg-native rpm-native python3-native")
30 bitbake("build-sysroots -c build_native_sysroot")
31
32 # Get the paths so we can point into the sysroot correctly
33 vars = get_bb_vars(["STAGING_DIR", "BUILD_ARCH", "bindir_native", "libdir_native"])
34 cls.staging = oe.path.join(vars["STAGING_DIR"], vars["BUILD_ARCH"])
35 cls.bindir = oe.path.join(cls.staging, vars["bindir_native"])
36 cls.libdir = oe.path.join(cls.staging, vars["libdir_native"])
37
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080038 def setUpLocal(self):
Brad Bishopd7bf8c12018-02-25 22:55:05 -050039 # Just for convenience
40 self.staging = type(self).staging
41 self.bindir = type(self).bindir
42 self.libdir = type(self).libdir
43
Brad Bishopd7bf8c12018-02-25 22:55:05 -050044 def test_dpkg(self):
45 for ver1, ver2, sort in self.tests:
46 op = { -1: "<<", 0: "=", 1: ">>" }[sort]
47 status = subprocess.call((oe.path.join(self.bindir, "dpkg"), "--compare-versions", ver1, op, ver2))
48 self.assertEqual(status, 0, "%s %s %s failed" % (ver1, op, ver2))
49
50 # Now do it again but with incorrect operations
51 op = { -1: ">>", 0: ">>", 1: "<<" }[sort]
52 status = subprocess.call((oe.path.join(self.bindir, "dpkg"), "--compare-versions", ver1, op, ver2))
53 self.assertNotEqual(status, 0, "%s %s %s failed" % (ver1, op, ver2))
54
55 # Now do it again but with incorrect operations
56 op = { -1: "=", 0: "<<", 1: "=" }[sort]
57 status = subprocess.call((oe.path.join(self.bindir, "dpkg"), "--compare-versions", ver1, op, ver2))
58 self.assertNotEqual(status, 0, "%s %s %s failed" % (ver1, op, ver2))
59
Brad Bishopd7bf8c12018-02-25 22:55:05 -050060 def test_opkg(self):
61 for ver1, ver2, sort in self.tests:
62 op = { -1: "<<", 0: "=", 1: ">>" }[sort]
63 status = subprocess.call((oe.path.join(self.bindir, "opkg"), "compare-versions", ver1, op, ver2))
64 self.assertEqual(status, 0, "%s %s %s failed" % (ver1, op, ver2))
65
66 # Now do it again but with incorrect operations
67 op = { -1: ">>", 0: ">>", 1: "<<" }[sort]
68 status = subprocess.call((oe.path.join(self.bindir, "opkg"), "compare-versions", ver1, op, ver2))
69 self.assertNotEqual(status, 0, "%s %s %s failed" % (ver1, op, ver2))
70
71 # Now do it again but with incorrect operations
72 op = { -1: "=", 0: "<<", 1: "=" }[sort]
73 status = subprocess.call((oe.path.join(self.bindir, "opkg"), "compare-versions", ver1, op, ver2))
74 self.assertNotEqual(status, 0, "%s %s %s failed" % (ver1, op, ver2))
75
Brad Bishopd7bf8c12018-02-25 22:55:05 -050076 def test_rpm(self):
77 # Need to tell the Python bindings where to find its configuration
78 env = os.environ.copy()
79 env["RPM_CONFIGDIR"] = oe.path.join(self.libdir, "rpm")
80
81 for ver1, ver2, sort in self.tests:
82 # The only way to test rpm is via the Python module, so we need to
83 # execute python3-native. labelCompare returns -1/0/1 (like strcmp)
84 # so add 100 and use that as the exit code.
85 command = (oe.path.join(self.bindir, "python3-native", "python3"), "-c",
86 "import sys, rpm; v1=(None, \"%s\", None); v2=(None, \"%s\", None); sys.exit(rpm.labelCompare(v1, v2) + 100)" % (ver1, ver2))
87 status = subprocess.call(command, env=env)
88 self.assertIn(status, (99, 100, 101))
89 self.assertEqual(status - 100, sort, "%s %s (%d) failed" % (ver1, ver2, sort))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080090
91class PackageTests(OESelftestTestCase):
92 # Verify that a recipe which sets up hardlink files has those preserved into split packages
93 # Also test file sparseness is preserved
94 def test_preserve_sparse_hardlinks(self):
95 bitbake("selftest-hardlink -c package")
96
97 dest = get_bb_var('PKGDEST', 'selftest-hardlink')
98 bindir = get_bb_var('bindir', 'selftest-hardlink')
99
100 def checkfiles():
101 # Recipe creates 4 hardlinked files, there is a copy in package/ and a copy in packages-split/
102 # so expect 8 in total.
103 self.assertEqual(os.stat(dest + "/selftest-hardlink" + bindir + "/hello1").st_nlink, 8)
104
105 # Test a sparse file remains sparse
106 sparsestat = os.stat(dest + "/selftest-hardlink" + bindir + "/sparsetest")
107 self.assertEqual(sparsestat.st_blocks, 0)
108 self.assertEqual(sparsestat.st_size, 1048576)
109
110 checkfiles()
111
112 # Clean and reinstall so its now definitely from sstate, then retest.
113 bitbake("selftest-hardlink -c clean")
114 bitbake("selftest-hardlink -c package")
115
116 checkfiles()
117
118 # Verify gdb to read symbols from separated debug hardlink file correctly
119 def test_gdb_hardlink_debug(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500120 features = 'IMAGE_INSTALL:append = " selftest-hardlink"\n'
121 features += 'IMAGE_INSTALL:append = " selftest-hardlink-dbg"\n'
122 features += 'IMAGE_INSTALL:append = " selftest-hardlink-gdb"\n'
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800123 self.write_config(features)
124 bitbake("core-image-minimal")
125
126 def gdbtest(qemu, binary):
127 """
128 Check that gdb ``binary`` to read symbols from separated debug file
129 """
130 self.logger.info("gdbtest %s" % binary)
131 status, output = qemu.run_serial('/usr/bin/gdb.sh %s' % binary, timeout=60)
132 for l in output.split('\n'):
133 # Check debugging symbols exists
134 if '(no debugging symbols found)' in l:
135 self.logger.error("No debugging symbols found. GDB result:\n%s" % output)
136 return False
137
Patrick Williams7784c422022-11-17 07:29:11 -0600138 # Check debugging symbols works correctly. Don't look for a
139 # source file as optimisation can put the breakpoint inside
140 # stdio.h.
141 elif "Breakpoint 1 at" in l:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800142 return True
143
Brad Bishop19323692019-04-05 15:28:33 -0400144 self.logger.error("GDB result:\n%d: %s", status, output)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800145 return False
146
147 with runqemu('core-image-minimal') as qemu:
148 for binary in ['/usr/bin/hello1',
149 '/usr/bin/hello2',
150 '/usr/libexec/hello3',
151 '/usr/libexec/hello4']:
152 if not gdbtest(qemu, binary):
153 self.fail('GDB %s failed' % binary)
Andrew Geissler82c905d2020-04-13 13:39:40 -0500154
155 def test_preserve_ownership(self):
Patrick Williams213cb262021-08-07 19:21:33 -0500156 features = 'IMAGE_INSTALL:append = " selftest-chown"\n'
Andrew Geissler82c905d2020-04-13 13:39:40 -0500157 self.write_config(features)
158 bitbake("core-image-minimal")
159
Patrick Williams7784c422022-11-17 07:29:11 -0600160 def check_ownership(qemu, expected_gid, expected_uid, path):
Andrew Geissler82c905d2020-04-13 13:39:40 -0500161 self.logger.info("Check ownership of %s", path)
Patrick Williams7784c422022-11-17 07:29:11 -0600162 status, output = qemu.run_serial('stat -c "%U %G" ' + path)
163 self.assertEqual(status, 1, "stat failed: " + output)
164 try:
165 uid, gid = output.split()
166 self.assertEqual(uid, expected_uid)
167 self.assertEqual(gid, expected_gid)
168 except ValueError:
169 self.fail("Cannot parse output: " + output)
Andrew Geissler82c905d2020-04-13 13:39:40 -0500170
Patrick Williams7784c422022-11-17 07:29:11 -0600171 sysconfdir = get_bb_var('sysconfdir', 'selftest-chown')
Andrew Geissler82c905d2020-04-13 13:39:40 -0500172 with runqemu('core-image-minimal') as qemu:
173 for path in [ sysconfdir + "/selftest-chown/file",
174 sysconfdir + "/selftest-chown/dir",
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600175 sysconfdir + "/selftest-chown/symlink",
176 sysconfdir + "/selftest-chown/fifotest/fifo"]:
Patrick Williams7784c422022-11-17 07:29:11 -0600177 check_ownership(qemu, "test", "test", path)