blob: 2d1b48a15dff40693608b98d7da8819ef55b6cb0 [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
138 # Check debugging symbols works correctly
Andrew Geissler82c905d2020-04-13 13:39:40 -0500139 elif re.match(r"Breakpoint 1.*hello\.c.*4", l):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800140 return True
141
Brad Bishop19323692019-04-05 15:28:33 -0400142 self.logger.error("GDB result:\n%d: %s", status, output)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800143 return False
144
145 with runqemu('core-image-minimal') as qemu:
146 for binary in ['/usr/bin/hello1',
147 '/usr/bin/hello2',
148 '/usr/libexec/hello3',
149 '/usr/libexec/hello4']:
150 if not gdbtest(qemu, binary):
151 self.fail('GDB %s failed' % binary)
Andrew Geissler82c905d2020-04-13 13:39:40 -0500152
153 def test_preserve_ownership(self):
154 import os, stat, oe.cachedpath
Patrick Williams213cb262021-08-07 19:21:33 -0500155 features = 'IMAGE_INSTALL:append = " selftest-chown"\n'
Andrew Geissler82c905d2020-04-13 13:39:40 -0500156 self.write_config(features)
157 bitbake("core-image-minimal")
158
159 sysconfdir = get_bb_var('sysconfdir', 'selftest-chown')
160 def check_ownership(qemu, gid, uid, path):
161 self.logger.info("Check ownership of %s", path)
162 status, output = qemu.run_serial(r'/bin/stat -c "%U %G" ' + path, timeout=60)
163 output = output.split(" ")
164 if output[0] != uid or output[1] != gid :
165 self.logger.error("Incrrect ownership %s [%s:%s]", path, output[0], output[1])
166 return False
167 return True
168
169 with runqemu('core-image-minimal') as qemu:
170 for path in [ sysconfdir + "/selftest-chown/file",
171 sysconfdir + "/selftest-chown/dir",
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600172 sysconfdir + "/selftest-chown/symlink",
173 sysconfdir + "/selftest-chown/fifotest/fifo"]:
Andrew Geissler82c905d2020-04-13 13:39:40 -0500174 if not check_ownership(qemu, "test", "test", path):
175 self.fail('Test ownership %s failed' % path)