mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: BAREBOX <barebox@lists.infradead.org>
Subject: [PATCH 05/10] test: py: add test for reverting globalvars after boot
Date: Fri, 30 Oct 2026 11:54:03 +0100	[thread overview]
Message-ID: <20261030-boot-globalvar-stack-v1-5-a03803e1100c@pengutronix.de> (raw)
In-Reply-To: <20261030-boot-globalvar-stack-v1-0-a03803e1100c@pengutronix.de>

Add tests for the globalvar scope around boot entries: a failing boot
script that changes, creates and removes global.bootm.* and
global.linux.bootargs.* variables and changes global.of.overlay.path and
global.linux.bootargs_append, where the configuration has them, must
leave them as they were before, while globalvars outside the scope keep
their new values. A
second test nests boot entries like devboot does and checks that the
outer entry's variables are visible in the inner one and survive it.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 test/py/test_boot_globalvar_scope.py | 117 +++++++++++++++++++++++++++++++++++
 1 file changed, 117 insertions(+)

diff --git a/test/py/test_boot_globalvar_scope.py b/test/py/test_boot_globalvar_scope.py
new file mode 100644
index 0000000000..041d38c814
--- /dev/null
+++ b/test/py/test_boot_globalvar_scope.py
@@ -0,0 +1,117 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import pytest
+from .helper import devinfo, skip_disabled
+
+
+def write_bootscript(barebox, name, lines):
+    barebox.run_check(f"echo -o /env/boot/{name} '#!/bin/sh'")
+    for line in lines:
+        # Variable references must reach the script unexpanded. Neither
+        # quoting nor a backslash achieves that here, so splice in the
+        # dollar sign from a variable.
+        line = line.replace("$", "${dollar}")
+        barebox.run_check(f"dollar='$'; echo -a /env/boot/{name} \"{line}\"")
+
+
+def globals_now(barebox):
+    params = devinfo(barebox, "global")["Parameters"]
+    # devinfo prints "value (type: ...)", strip the annotation
+    return {k: v.split(" (type:")[0].strip('"') for k, v in params.items()}
+
+
+@pytest.fixture(scope="function")
+def scope_globals(barebox, barebox_config):
+    skip_disabled(barebox_config, "CONFIG_CMD_BOOT", "CONFIG_CMD_GLOBAL",
+                  "CONFIG_CMD_ECHO")
+
+    barebox.run_check("global.bootm.image=/preset/image")
+    barebox.run_check("global linux.bootargs.preset=preset=1")
+    barebox.run_check("global linux.bootargs.removed=removed=1")
+    barebox.run_check("global.bootm.appendroot=0")
+    old_user = barebox.run_check("echo ${global.user}")[0]
+
+    yield old_user
+
+    barebox.run_check(f"global.user={old_user}")
+    barebox.run("global -r linux.bootargs.preset")
+    barebox.run("global -r linux.bootargs.removed")
+    barebox.run_check("global.bootm.image=")
+
+
+def test_boot_entry_reverts_globalvars(barebox, scope_globals):
+    old_user = scope_globals
+    before = globals_now(barebox)
+
+    # boot related globalvars outside of bootm.* and linux.bootargs.*,
+    # where the configuration has them
+    others = {var: val for var, val in (("of.overlay.path", "/does/not/exist"),
+                                        ("linux.bootargs_append", "1"))
+              if var in before}
+
+    write_bootscript(barebox, "scope", [
+        *(f"global.{var}={val}" for var, val in others.items()),
+        "global.bootm.image=/does/not/exist",
+        "global.bootm.oftree=/does/not/exist.dtb",
+        "global.bootm.appendroot=1",
+        "global.linux.bootargs.dyn.root=root=/dev/leak",
+        "global linux.bootargs.leak=leak=1",
+        "global.linux.bootargs.preset=preset=2",
+        "global -r linux.bootargs.removed",
+        "global.user=scope-test",
+    ])
+
+    # bootm fails on the nonexistent image, so boot returns
+    barebox.run("boot scope")
+
+    after = globals_now(barebox)
+
+    # values within the boot scope are restored...
+    assert after["bootm.image"] == "/preset/image"
+    assert after["bootm.oftree"] == before["bootm.oftree"]
+    assert after["bootm.appendroot"] == "0"
+    assert after["linux.bootargs.preset"] == "preset=1"
+    for var in others:
+        assert after[var] == before[var]
+
+    # ...vars created by the boot entry are gone...
+    assert "linux.bootargs.leak" not in after
+    assert "linux.bootargs.dyn.root" not in after
+    assert "linux.bootargs.dyn.ip" not in after
+
+    # ...vars removed by the boot entry are back...
+    assert after["linux.bootargs.removed"] == "removed=1"
+
+    # ...and the loadaddrs don't come back as 0xfffffffe after a failed boot
+    assert after["bootm.image.loadaddr"] == before["bootm.image.loadaddr"]
+
+    # globalvars outside the boot scope are left alone
+    assert after["user"] == "scope-test"
+    assert old_user != "scope-test"
+
+
+@pytest.mark.usefixtures("scope_globals")
+def test_boot_entry_scope_nests(barebox):
+    # devboot-style: an outer entry sets up bootargs that must be visible
+    # in, and survive, the inner boot entry
+    write_bootscript(barebox, "scope-inner", [
+        "global.bootm.image=/does/not/exist",
+        "echo inner-sees ${global.linux.bootargs.outer}",
+        "global.linux.bootargs.outer=outer=clobbered",
+        "global linux.bootargs.inner=inner=1",
+    ])
+    write_bootscript(barebox, "scope-outer", [
+        "global linux.bootargs.outer=outer=1",
+        "boot scope-inner",
+        "echo outer-sees ${global.linux.bootargs.outer} "
+        "inner=${global.linux.bootargs.inner}",
+    ])
+
+    stdout, _, _ = barebox.run("boot scope-outer")
+    assert "inner-sees outer=1" in stdout
+    assert "outer-sees outer=1 inner=" in stdout
+
+    after = globals_now(barebox)
+    assert "linux.bootargs.outer" not in after
+    assert "linux.bootargs.inner" not in after
+    assert after["bootm.image"] == "/preset/image"

-- 
2.47.3




  parent reply	other threads:[~2026-10-30 10:55 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-30 10:53 [PATCH 00/10] boot: revert boot related globalvars after booting Sascha Hauer
2026-10-30 10:53 ` [PATCH 01/10] globalvar: add scopes to snapshot and restore globalvars Sascha Hauer
2026-10-30 10:54 ` [PATCH 02/10] bootm: revert globalvar changes in bootm_boot_cleanup() Sascha Hauer
2026-10-30 10:54 ` [PATCH 03/10] boot: revert globalvar changes after each boot entry Sascha Hauer
2026-10-30 10:54 ` [PATCH 04/10] bootchooser: use a globalvar scope for its bootargs Sascha Hauer
2026-10-30 10:54 ` Sascha Hauer [this message]
2026-10-30 10:54 ` [PATCH 06/10] bootargs: remove unused linux_bootargs_overwrite() Sascha Hauer
2026-10-30 10:54 ` [PATCH 07/10] of: add watchdog bootarg directly instead of via a globalvar Sascha Hauer
2026-10-30 10:54 ` [PATCH 08/10] boot: drop the dyn infix from the bootentries bootargs variable Sascha Hauer
2026-10-30 10:54 ` [PATCH 09/10] defaultenv: don't use global.linux.bootargs.dyn.* in boot entries Sascha Hauer
2026-10-30 10:54 ` [PATCH 10/10] Documentation: migration-guides: describe reverting boot globalvars Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261030-boot-globalvar-stack-v1-5-a03803e1100c@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox