2
1
Эх сурвалжийг харах

support/testing: add systemd tests for factory and overlayfs

Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
[Arnout:
 - use a simple mount unit for
   TestInitSystemSystemdRoFullOverlayfsVarBacking;
 - change the test of TestInitSystemSystemdRoFullOverlayfsVarBacking to
   check that the exact expected mount was performed;
 - add a test of var backing with fstab instead of mount unit.
]
Signed-off-by: Arnout Vandecappelle <arnout@mind.be>
Yann E. MORIN 2 жил өмнө
parent
commit
083e65a67c

+ 1 - 0
support/testing/conf/overlayfs-kernel-fragment.config

@@ -0,0 +1 @@
+CONFIG_OVERLAY_FS=y

+ 13 - 0
support/testing/tests/init/systemd-overlay-mount-unit/usr/lib/systemd/system/run-buildroot-mounts-var.mount

@@ -0,0 +1,13 @@
+[Unit]
+Description=Variable permanent storage overlay
+ConditionPathIsSymbolicLink=!/var
+DefaultDependencies=no
+After=local-fs-pre.target
+
+[Mount]
+# Rather than creating an actual writable partition, we just create
+# another tmpfs. For tmpfs, the What is not relevant - but we use it in
+# the test to distinguish it from other tmpfses
+What=other-var-backing-store
+Where=/run/buildroot/mounts/var
+Type=tmpfs

+ 224 - 9
support/testing/tests/init/test_systemd.py

@@ -1,7 +1,15 @@
 import infra.basetest
 import infra.basetest
+import re
 from tests.init.base import InitSystemBase as InitSystemBase
 from tests.init.base import InitSystemBase as InitSystemBase
 
 
 
 
+# In the following tests, the read-only cases use the default settings,
+# which historically used both a factory to populate a tmpfs on /var,
+# and pre-populated /var at buildtime. Since these are the default
+# settings, and they proved to generate a system that ultimately boots,
+# we still want to keep testing that. See later, below, for the
+# specialised test cases.
+
 class InitSystemSystemdBase(InitSystemBase):
 class InitSystemSystemdBase(InitSystemBase):
     config = \
     config = \
         """
         """
@@ -17,7 +25,10 @@ class InitSystemSystemdBase(InitSystemBase):
         """
         """
 
 
     def check_systemd(self, fs):
     def check_systemd(self, fs):
-        self.start_emulator(fs)
+        if "BR2_LINUX_KERNEL=y" in self.config:
+            self.start_emulator(fs, "zImage", "vexpress-v2p-ca9")
+        else:
+            self.start_emulator(fs)
         self.check_init("/lib/systemd/systemd")
         self.check_init("/lib/systemd/systemd")
 
 
         # Test all units are OK
         # Test all units are OK
@@ -40,19 +51,12 @@ class TestInitSystemSystemdRoNetworkd(InitSystemSystemdBase):
         """
         """
         BR2_SYSTEM_DHCP="eth0"
         BR2_SYSTEM_DHCP="eth0"
         # BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW is not set
         # BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW is not set
-        BR2_ROOTFS_OVERLAY="{}"
         BR2_TARGET_ROOTFS_SQUASHFS=y
         BR2_TARGET_ROOTFS_SQUASHFS=y
-        """.format(infra.filepath("tests/init/systemd-factory"))
+        """
 
 
     def test_run(self):
     def test_run(self):
         self.check_systemd("squashfs")
         self.check_systemd("squashfs")
 
 
-        # This one must be executed on the target, to check that
-        # the factory feature works as expected
-        out, exit_code = self.emulator.run("cat /var/foo/bar")
-        self.assertEqual(exit_code, 0)
-        self.assertEqual(out[0], "foobar")
-
 
 
 class TestInitSystemSystemdRwNetworkd(InitSystemSystemdBase):
 class TestInitSystemSystemdRwNetworkd(InitSystemSystemdBase):
     config = InitSystemSystemdBase.config + \
     config = InitSystemSystemdBase.config + \
@@ -191,3 +195,214 @@ class TestInitSystemSystemdRwFull(InitSystemSystemdBase):
 
 
     def test_run(self):
     def test_run(self):
         self.check_systemd("ext2")
         self.check_systemd("ext2")
+
+
+# The following tests are all about read-only rootfs, and exercise either
+# using an un-populated factory for /var, or an overlaysfs ontop of a
+# pre-populated /var. They all specialise the TestInitSystemSystemdRo*
+# test cases above.
+
+
+# Helper class for factory-based tests
+class InitSystemSystemdBaseFactory():
+    config = \
+        """
+        # BR2_INIT_SYSTEMD_POPULATE_TMPFILES is not set
+        BR2_ROOTFS_OVERLAY="{}"
+        """.format(infra.filepath("tests/init/systemd-factory"))
+
+    def test_run(self):
+        super().test_run()
+
+        # This one must be executed on the target, to check that
+        # the factory feature works as expected
+        out, exit_code = self.emulator.run("cat /var/foo/bar")
+        self.assertEqual(exit_code, 0)
+        self.assertEqual(out[0], "foobar")
+
+        # /var/foo/bar is from the /var factory
+        _, exit_code = self.emulator.run("test -e /usr/share/factory/var/foo/bar")
+        self.assertEqual(exit_code, 0)
+
+        # We can write in /var/foo/bar
+        _, exit_code = self.emulator.run("echo barfoo >/var/foo/bar")
+        self.assertEqual(exit_code, 0)
+        # ... and it contains the new content
+        out, exit_code = self.emulator.run("cat /var/foo/bar")
+        self.assertEqual(exit_code, 0)
+        self.assertEqual(out[0], "barfoo")
+        # ... but the factory is umodified
+        out, exit_code = self.emulator.run("cat /usr/share/factory/var/foo/bar")
+        self.assertEqual(exit_code, 0)
+        self.assertEqual(out[0], "foobar")
+
+
+class TestInitSystemSystemdRoNetworkdFactory(
+    InitSystemSystemdBaseFactory,
+    TestInitSystemSystemdRoNetworkd,
+):
+    config = InitSystemSystemdBaseFactory.config + \
+        TestInitSystemSystemdRoNetworkd.config
+
+
+class TestInitSystemSystemdRoIfupdownFactory(
+    InitSystemSystemdBaseFactory,
+    TestInitSystemSystemdRoIfupdown,
+):
+    config = InitSystemSystemdBaseFactory.config + \
+        TestInitSystemSystemdRoIfupdown.config
+
+
+class TestInitSystemSystemdRoIfupdownDbusbrokerFactory(
+    InitSystemSystemdBaseFactory,
+    TestInitSystemSystemdRoIfupdownDbusbroker,
+):
+    config = InitSystemSystemdBaseFactory.config + \
+        TestInitSystemSystemdRoIfupdownDbusbroker.config
+
+
+class TestInitSystemSystemdRoIfupdownDbusbrokerDbusFactory(
+    InitSystemSystemdBaseFactory,
+    TestInitSystemSystemdRoIfupdownDbusbrokerDbus,
+):
+    config = InitSystemSystemdBaseFactory.config + \
+        TestInitSystemSystemdRoIfupdownDbusbrokerDbus.config
+
+
+class TestInitSystemSystemdRoFullFactory(
+    InitSystemSystemdBaseFactory,
+    TestInitSystemSystemdRoFull,
+):
+    config = InitSystemSystemdBaseFactory.config + \
+        TestInitSystemSystemdRoFull.config
+
+
+# Helper class for overlayfs-based tests
+class InitSystemSystemdBaseOverlayfs():
+    config = \
+        """
+        # BR2_INIT_SYSTEMD_VAR_FACTORY is not set
+        BR2_INIT_SYSTEMD_VAR_OVERLAYFS=y
+        BR2_ROOTFS_OVERLAY="{}"
+        BR2_LINUX_KERNEL=y
+        BR2_LINUX_KERNEL_CUSTOM_VERSION=y
+        BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="5.10.7"
+        BR2_LINUX_KERNEL_DEFCONFIG="vexpress"
+        BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="{}"
+        BR2_LINUX_KERNEL_DTS_SUPPORT=y
+        BR2_LINUX_KERNEL_INTREE_DTS_NAME="vexpress-v2p-ca9"
+        """.format(infra.filepath("tests/init/systemd-factory"),
+                   infra.filepath("conf/overlayfs-kernel-fragment.config"))
+
+    def test_run(self):
+        super().test_run()
+
+        # This one must be executed on the target, to check that
+        # the tmpfiles pre-populate works as expected
+        out, exit_code = self.emulator.run("cat /var/foo/bar")
+        self.assertEqual(exit_code, 0)
+        self.assertEqual(out[0], "foobar")
+
+        # /var/foo/bar is from the pre-populated /var, so it should
+        # not be present in the upper of the overlay
+        _, exit_code = self.emulator.run("test -e /run/buildroot/mounts/var/upper/foo/bar")
+        self.assertNotEqual(exit_code, 0)
+
+        # We can write in /var/foo/bar
+        _, exit_code = self.emulator.run("echo barfoo >/var/foo/bar")
+        self.assertEqual(exit_code, 0)
+        # ... and it contains the new content
+        out, exit_code = self.emulator.run("cat /var/foo/bar")
+        self.assertEqual(exit_code, 0)
+        self.assertEqual(out[0], "barfoo")
+        # ... and it to appears in the upper
+        _, exit_code = self.emulator.run("test -e /run/buildroot/mounts/var/upper/foo/bar")
+        self.assertEqual(exit_code, 0)
+        # ... with the new content
+        out, exit_code = self.emulator.run("cat /run/buildroot/mounts/var/upper/foo/bar")
+        self.assertEqual(exit_code, 0)
+        self.assertEqual(out[0], "barfoo")
+        # ... while the lower still has the oldcontent
+        out, exit_code = self.emulator.run("cat /run/buildroot/mounts/var/lower/foo/bar")
+        self.assertEqual(exit_code, 0)
+        self.assertEqual(out[0], "foobar")
+
+
+class TestInitSystemSystemdRoNetworkdOverlayfs(
+    InitSystemSystemdBaseOverlayfs,
+    TestInitSystemSystemdRoNetworkd,
+):
+    config = InitSystemSystemdBaseOverlayfs.config + \
+        TestInitSystemSystemdRoNetworkd.config
+
+
+class TestInitSystemSystemdRoIfupdownOverlayfs(
+    InitSystemSystemdBaseOverlayfs,
+    TestInitSystemSystemdRoIfupdown,
+):
+    config = InitSystemSystemdBaseOverlayfs.config + \
+        TestInitSystemSystemdRoIfupdown.config
+
+
+class TestInitSystemSystemdRoIfupdownDbusbrokerOverlayfs(
+    InitSystemSystemdBaseOverlayfs,
+    TestInitSystemSystemdRoIfupdownDbusbroker,
+):
+    config = InitSystemSystemdBaseOverlayfs.config + \
+        TestInitSystemSystemdRoIfupdownDbusbroker.config
+
+
+class TestInitSystemSystemdRoIfupdownDbusbrokerDbusOverlayfs(
+    InitSystemSystemdBaseOverlayfs,
+    TestInitSystemSystemdRoIfupdownDbusbrokerDbus,
+):
+    config = InitSystemSystemdBaseOverlayfs.config + \
+        TestInitSystemSystemdRoIfupdownDbusbrokerDbus.config
+
+
+class TestInitSystemSystemdRoFullOverlayfs(
+    InitSystemSystemdBaseOverlayfs,
+    TestInitSystemSystemdRoFull,
+):
+    config = InitSystemSystemdBaseOverlayfs.config + \
+        TestInitSystemSystemdRoFull.config
+
+
+class InitSystemSystemdBaseOverlayfsVarBacking(InitSystemBase):
+    @classmethod
+    def gen_config(cls, overlaydir: str) -> str:
+        return re.sub(
+            r'^\s*BR2_ROOTFS_OVERLAY="(.*)"$',
+            'BR2_ROOTFS_OVERLAY="\\1 {}"'.format(infra.filepath(overlaydir)),
+            TestInitSystemSystemdRoFullOverlayfs.config,
+            flags=re.MULTILINE,
+        )
+
+    def check_var_mounted(self):
+        self.assertRunOk("grep '^other-var-backing-store /run/buildroot/mounts/var tmpfs' /proc/mounts")
+
+
+class TestInitSystemSystemdRoFullOverlayfsVarBackingMountUnit(
+    TestInitSystemSystemdRoFullOverlayfs,
+    InitSystemSystemdBaseOverlayfsVarBacking,
+):
+    config = InitSystemSystemdBaseOverlayfsVarBacking.gen_config(
+        'tests/init/systemd-overlay-mount-unit',
+    )
+
+    def test_run(self):
+        super().test_run()
+        self.check_var_mounted()
+
+
+class TestInitSystemSystemdRoFullOverlayfsVarBackingFstab(
+    TestInitSystemSystemdRoFullOverlayfs,
+    InitSystemSystemdBaseOverlayfsVarBacking,
+):
+    config = InitSystemSystemdBaseOverlayfsVarBacking.gen_config(
+        'tests/init/systemd-overlay-fstab',
+    )
+
+    def test_run(self):
+        super().test_run()
+        self.check_var_mounted()