diff mbox series

[2/2] oe-selftest: usergrouptests: compare shadow files across package backends

Message ID 20261106141348.2757557-3-peter@berginkonsult.se
State Under Review
Headers show
Series useradd: consistent shadow files across package backends | expand

Commit Message

Peter Bergin Nov. 6, 2026, 2:13 p.m. UTC
Build core-image-minimal with rpm, ipk and deb rootfs and check that
/etc/shadow and /etc/gshadow match per account. passwd/group are not
compared as dynamically allocated IDs depend on install order.

[YOCTO #14139]

AI-Generated: Uses Claude Code (Claude Opus 5.5)
Signed-off-by: Peter Bergin <peter@berginkonsult.se>
---
 .../lib/oeqa/selftest/cases/usergrouptests.py | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)
diff mbox series

Patch

diff --git a/meta/lib/oeqa/selftest/cases/usergrouptests.py b/meta/lib/oeqa/selftest/cases/usergrouptests.py
index 69025a59aa..40e6e24606 100644
--- a/meta/lib/oeqa/selftest/cases/usergrouptests.py
+++ b/meta/lib/oeqa/selftest/cases/usergrouptests.py
@@ -56,6 +56,30 @@  class UserGroupTests(OESelftestTestCase):
         self.logger.info("Rebuild with other staticids")
         self.assertTrue(bitbake(' core-image-minimal'))
 
+    def test_shadow_files_match_across_package_backends(self):
+        # Test for YOCTO #14139
+        image = 'core-image-minimal'
+        backends = ('rpm', 'ipk', 'deb')
+        # Dynamic IDs and line order vary by backend: skip passwd/group, key by name
+        files = ('shadow', 'gshadow')
+        results = {}
+        for backend in backends:
+            classes = ' '.join(['package_' + backend] + ['package_' + b for b in backends if b != backend])
+            self.write_config('PACKAGE_CLASSES = "%s"\nIMAGE_INSTALL:append = " creategroup1"\n' % classes)
+            self.logger.info("Building %s with %s rootfs" % (image, backend))
+            bitbake(image)
+            etcdir = os.path.join(get_bb_var('IMAGE_ROOTFS', image), 'etc')
+            results[backend] = {}
+            for f in files:
+                with open(os.path.join(etcdir, f)) as fd:
+                    results[backend][f] = dict(line.split(':', 1) for line in fd.read().splitlines())
+
+        self.maxDiff = None
+        for backend in backends[1:]:
+            for f in files:
+                self.assertEqual(results[backends[0]][f], results[backend][f],
+                                 "/etc/%s differs between %s and %s rootfs" % (f, backends[0], backend))
+
     def test_useradd_depends_only(self):
         # Test that a recipe inheriting useradd with only USERADD_DEPENDS
         # (and no USERADD_PACKAGES) parses and builds successfully. [YOCTO #15863]