public inbox for buildroot@busybox.net
 help / color / mirror / Atom feed
* [Buildroot] [PATCH 1/1] support/testing: transfer config in environment instead of class variables
@ 2026-02-27 19:21 Fiona Klute via buildroot
  2026-02-28 19:50 ` Peter Korsgaard
  0 siblings, 1 reply; 7+ messages in thread
From: Fiona Klute via buildroot @ 2026-02-27 19:21 UTC (permalink / raw)
  To: buildroot
  Cc: Ricardo Martincoski, Jimmy Durand Wesolowski, Julien Olivain,
	guenther.harrasser, Fiona Klute

With Python 3.14 the default process start method in the
multiprocessing module for POSIX platfroms changed from "fork" to
"forkserver". Unlike with "fork" the new process does not inherit
loaded modules, classes, etc., instead it has to load any it
needs. This means that class variables modified in the parent process
are lost, which breaks the way support/testing/run-tests sets
configuration in BRConfigTest.

Instead add a method to serialize the configuration into an
environment variable, and read it during
BRConfigTest.__init__(). Reading is skipped if the environment
variable is not set so test discovery (not execution) works without
configuration (e.g. utils/get-developers uses this).

The (de-)serialization could be simpler using a dedicated
@dataclasses.dataclass class, but the dataclasses module was added
with Python 3.7, while support/dependencies/check-host-python3.mk
specifies 3.4 as the minimum for Buildroot.

Remove the "fork" method override added in
3d2141bceefda32bef06ddda594eaf8665913276. This fixes a crash that
occured in combination with an incorrect [1] patch added to the Debian
python3-nose2 package with version 0.15.1-2 [2] because setting the
default multiprocessing start method twice is an error.

[1] https://github.com/nose-devs/nose2/pull/644#issuecomment-3902982437
[2] https://salsa.debian.org/python-team/packages/nose2/-/blob/debian/0.15.1-2/debian/patches/0004-plugins-mp-set-context-to-fork-for-Python-3.14-mp-AP.patch?ref_type=tags

Signed-off-by: Fiona Klute <fiona.klute@gmx.de>
---
I'd be happy to rewrite using @dataclasses.dataclass if a bit less
backwards compatibility is fine, but getting that crash fixed is more
important to me. That said, the oldest Python version still supported
upstream is 3.10, Debian Trixie has 3.13, Bookworm (oldstable) 3.11,
so maybe raising the requirement a little is fine?

 support/testing/infra/basetest.py | 33 +++++++++++++++++++++++++++++++
 support/testing/run-tests         |  3 ++-
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/support/testing/infra/basetest.py b/support/testing/infra/basetest.py
index 13f9b2d398..55567448fe 100644
--- a/support/testing/infra/basetest.py
+++ b/support/testing/infra/basetest.py
@@ -1,6 +1,7 @@
 import unittest
 import os
 import datetime
+import json
 
 from infra.builder import Builder
 from infra.emulator import Emulator
@@ -33,8 +34,16 @@ class BRConfigTest(unittest.TestCase):
     jlevel = 0
     timeout_multiplier = 1
 
+    # name of the environment variable for config transfer
+    CONF_ENV = 'BR_TEST_CONFIG_JSON'
+    _CONF_FIELDS = (
+        'downloaddir', 'outputdir', 'logtofile', 'keepbuilds', 'jlevel',
+        'timeout_multiplier')
+
     def __init__(self, names):
         super(BRConfigTest, self).__init__(names)
+        if self.CONF_ENV in os.environ:
+            self.load_conf(os.environ[self.CONF_ENV])
         self.testname = self.__class__.__name__
         self.builddir = self.outputdir and os.path.join(self.outputdir, self.testname)
         self.config += '\nBR2_DL_DIR="{}"\n'.format(self.downloaddir)
@@ -44,6 +53,30 @@ class BRConfigTest(unittest.TestCase):
         print("{} {:40s} {}".format(datetime.datetime.now().strftime("%H:%M:%S"),
                                     self.testname, msg))
 
+    @classmethod
+    def dump_conf(cls) -> str:
+        """support/testing/run-tests builds runtime config in class
+        variables, and then uses this method to serialize them into an
+        environment variable. On instantiation, tests use load_conf()
+        (below) to load this configuration. That way configuration can
+        be transferred into multiprocessing worker processes without
+        requiring the "fork" start method.
+
+        """
+        conf = dict()
+        for c in cls._CONF_FIELDS:
+            v = getattr(cls, c)
+            assert v is not None
+            conf[c] = v
+        return json.dumps(conf)
+
+    def load_conf(self, data: str) -> None:
+        conf = json.loads(data)
+        for c in self._CONF_FIELDS:
+            v = conf[c]
+            assert v is not None
+            setattr(self, c, v)
+
     def setUp(self):
         self.show_msg("Starting")
         self.b = Builder(self.config, self.builddir, self.logtofile, self.jlevel)
diff --git a/support/testing/run-tests b/support/testing/run-tests
index 1c4d2b4a85..8a79cbb104 100755
--- a/support/testing/run-tests
+++ b/support/testing/run-tests
@@ -127,6 +127,8 @@ def main():
         return 1
     BRConfigTest.timeout_multiplier = args.timeout_multiplier
 
+    os.environ[BRConfigTest.CONF_ENV] = BRConfigTest.dump_conf()
+
     nose2_args = ["-v",
                   "-N", str(args.testcases),
                   "-s", test_dir,
@@ -142,5 +144,4 @@ def main():
 
 
 if __name__ == "__main__":
-    multiprocessing.set_start_method("fork")
     sys.exit(main())
-- 
2.51.0

_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Buildroot] [PATCH 1/1] support/testing: transfer config in environment instead of class variables
  2026-02-27 19:21 [Buildroot] [PATCH 1/1] support/testing: transfer config in environment instead of class variables Fiona Klute via buildroot
@ 2026-02-28 19:50 ` Peter Korsgaard
  2026-02-28 20:41   ` Fiona Klute via buildroot
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Korsgaard @ 2026-02-28 19:50 UTC (permalink / raw)
  To: Fiona Klute
  Cc: buildroot, Ricardo Martincoski, Julien Olivain,
	Jimmy Durand Wesolowski, guenther.harrasser

>>>>> "Fiona" == Fiona Klute <fiona.klute@gmx.de> writes:

 > With Python 3.14 the default process start method in the
 > multiprocessing module for POSIX platfroms changed from "fork" to
 > "forkserver". Unlike with "fork" the new process does not inherit
 > loaded modules, classes, etc., instead it has to load any it
 > needs. This means that class variables modified in the parent process
 > are lost, which breaks the way support/testing/run-tests sets
 > configuration in BRConfigTest.

 > Instead add a method to serialize the configuration into an
 > environment variable, and read it during
 > BRConfigTest.__init__(). Reading is skipped if the environment
 > variable is not set so test discovery (not execution) works without
 > configuration (e.g. utils/get-developers uses this).

 > The (de-)serialization could be simpler using a dedicated
 > @dataclasses.dataclass class, but the dataclasses module was added
 > with Python 3.7, while support/dependencies/check-host-python3.mk
 > specifies 3.4 as the minimum for Buildroot.

 > Remove the "fork" method override added in
 > 3d2141bceefda32bef06ddda594eaf8665913276. This fixes a crash that
 > occured in combination with an incorrect [1] patch added to the Debian
 > python3-nose2 package with version 0.15.1-2 [2] because setting the
 > default multiprocessing start method twice is an error.

Looking at https://wiki.debian.org/Python, python 3.7+ was included
since Debian 10 (released July 2019, EOL September 2022), so I do think
that we can start relying on 3.7 for new releases, but for 2026.02 (and
2025.02.x) why not just change run-tests to do:

# set_start_method() may only be called once
if multiprocessing.get_start_method() != 'fork:
   multiprocessing.set_start_method('fork')

Wouldn't that work?

-- 
Bye, Peter Korsgaard
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Buildroot] [PATCH 1/1] support/testing: transfer config in environment instead of class variables
  2026-02-28 19:50 ` Peter Korsgaard
@ 2026-02-28 20:41   ` Fiona Klute via buildroot
  2026-02-28 22:21     ` Peter Korsgaard
  0 siblings, 1 reply; 7+ messages in thread
From: Fiona Klute via buildroot @ 2026-02-28 20:41 UTC (permalink / raw)
  To: Peter Korsgaard
  Cc: buildroot, Ricardo Martincoski, Julien Olivain,
	Jimmy Durand Wesolowski, guenther.harrasser

Am 28.02.26 um 20:50 schrieb Peter Korsgaard:
>>>>>> "Fiona" == Fiona Klute <fiona.klute@gmx.de> writes:
> 
>   > With Python 3.14 the default process start method in the
>   > multiprocessing module for POSIX platfroms changed from "fork" to
>   > "forkserver". Unlike with "fork" the new process does not inherit
>   > loaded modules, classes, etc., instead it has to load any it
>   > needs. This means that class variables modified in the parent process
>   > are lost, which breaks the way support/testing/run-tests sets
>   > configuration in BRConfigTest.
> 
>   > Instead add a method to serialize the configuration into an
>   > environment variable, and read it during
>   > BRConfigTest.__init__(). Reading is skipped if the environment
>   > variable is not set so test discovery (not execution) works without
>   > configuration (e.g. utils/get-developers uses this).
> 
>   > The (de-)serialization could be simpler using a dedicated
>   > @dataclasses.dataclass class, but the dataclasses module was added
>   > with Python 3.7, while support/dependencies/check-host-python3.mk
>   > specifies 3.4 as the minimum for Buildroot.
> 
>   > Remove the "fork" method override added in
>   > 3d2141bceefda32bef06ddda594eaf8665913276. This fixes a crash that
>   > occured in combination with an incorrect [1] patch added to the Debian
>   > python3-nose2 package with version 0.15.1-2 [2] because setting the
>   > default multiprocessing start method twice is an error.
> 
> Looking at https://wiki.debian.org/Python, python 3.7+ was included
> since Debian 10 (released July 2019, EOL September 2022), so I do think
> that we can start relying on 3.7 for new releases, but for 2026.02 (and
> 2025.02.x) why not just change run-tests to do:
> 
> # set_start_method() may only be called once
> if multiprocessing.get_start_method() != 'fork:
>     multiprocessing.set_start_method('fork')
> 
> Wouldn't that work?
No, because with the execution order in support/testing/run-tests that 
is the *first* call (so it would still happen, except on pre-3.14 Python 
where "fork" is the default), the second one (which then causes an 
exception) happens in the Debian-patched "mp" plugin of Nose, 
specifically when it's loaded. Otherwise we could just catch the 
exception and ignore it if the start method is what we expect.

The main issue is with Debian, of course (without that incorrect patch 
run-tests would work as it is), but relying on a specific 
multiprocessing start method was always fragile. For stable branches I 
think it'd be fair to point at the problem being a Debian bug, if this 
patch (or something similar) is considered too big to backport. The 
buggy Nose version is only in unstable & testing right now, I hope 
there'll be a properly fixed one before the Forky release.

A very simple alternative would be to disable the "mp" plugin, but that 
has obvious disadvantages.

Best regards,
Fiona

_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Buildroot] [PATCH 1/1] support/testing: transfer config in environment instead of class variables
  2026-02-28 20:41   ` Fiona Klute via buildroot
@ 2026-02-28 22:21     ` Peter Korsgaard
  2026-02-28 22:30       ` Fiona Klute via buildroot
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Korsgaard @ 2026-02-28 22:21 UTC (permalink / raw)
  To: Fiona Klute
  Cc: buildroot, Ricardo Martincoski, Julien Olivain,
	Jimmy Durand Wesolowski, guenther.harrasser

>>>>> "Fiona" == Fiona Klute <fiona.klute@gmx.de> writes:

Hi,

 >> Wouldn't that work?

 > No, because with the execution order in support/testing/run-tests that
 > is the *first* call (so it would still happen, except on pre-3.14
 > Python where "fork" is the default), the second one (which then causes
 > an exception) happens in the Debian-patched "mp" plugin of Nose,
 > specifically when it's loaded. Otherwise we could just catch the
 > exception and ignore it if the start method is what we expect.

Ahh, true.


 > The main issue is with Debian, of course (without that incorrect patch
 > run-tests would work as it is), but relying on a specific
 > multiprocessing start method was always fragile. For stable branches I
 > think it'd be fair to point at the problem being a Debian bug, if this
 > patch (or something similar) is considered too big to backport. The
 > buggy Nose version is only in unstable & testing right now, I hope
 > there'll be a properly fixed one before the Forky release.

What we could also do is to only add the workaround for python >= 3.14.x
(which is not yet in Debian), E.G.

if sys.version_info >= (3,14):
  multiprocessing.set_start_method('fork')

-- 
Bye, Peter Korsgaard
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Buildroot] [PATCH 1/1] support/testing: transfer config in environment instead of class variables
  2026-02-28 22:21     ` Peter Korsgaard
@ 2026-02-28 22:30       ` Fiona Klute via buildroot
  2026-03-01 10:10         ` Peter Korsgaard
  0 siblings, 1 reply; 7+ messages in thread
From: Fiona Klute via buildroot @ 2026-02-28 22:30 UTC (permalink / raw)
  To: Peter Korsgaard
  Cc: buildroot, Ricardo Martincoski, Julien Olivain,
	Jimmy Durand Wesolowski, guenther.harrasser

Am 28.02.26 um 23:21 schrieb Peter Korsgaard:
>>>>>> "Fiona" == Fiona Klute <fiona.klute@gmx.de> writes:
> 
> Hi,
> 
>   >> Wouldn't that work?
> 
>   > No, because with the execution order in support/testing/run-tests that
>   > is the *first* call (so it would still happen, except on pre-3.14
>   > Python where "fork" is the default), the second one (which then causes
>   > an exception) happens in the Debian-patched "mp" plugin of Nose,
>   > specifically when it's loaded. Otherwise we could just catch the
>   > exception and ignore it if the start method is what we expect.
> 
> Ahh, true.
> 
> 
>   > The main issue is with Debian, of course (without that incorrect patch
>   > run-tests would work as it is), but relying on a specific
>   > multiprocessing start method was always fragile. For stable branches I
>   > think it'd be fair to point at the problem being a Debian bug, if this
>   > patch (or something similar) is considered too big to backport. The
>   > buggy Nose version is only in unstable & testing right now, I hope
>   > there'll be a properly fixed one before the Forky release.
> 
> What we could also do is to only add the workaround for python >= 3.14.x
> (which is not yet in Debian), E.G.
> 
> if sys.version_info >= (3,14):
>    multiprocessing.set_start_method('fork')
That would fix the immediate issue, yes. If Debian updates to 3.14 
before Nose is fixed we'll be back where we started, and I think it'd be 
good not to rely on a specific start method in general. But I suppose 
the version check would be a reasonable compromise for the stable 
branches. :-)

Best regards,
Fiona

_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Buildroot] [PATCH 1/1] support/testing: transfer config in environment instead of class variables
  2026-02-28 22:30       ` Fiona Klute via buildroot
@ 2026-03-01 10:10         ` Peter Korsgaard
  2026-03-01 10:11           ` Peter Korsgaard
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Korsgaard @ 2026-03-01 10:10 UTC (permalink / raw)
  To: Fiona Klute
  Cc: buildroot, Ricardo Martincoski, Julien Olivain,
	Jimmy Durand Wesolowski, guenther.harrasser

>>>>> "Fiona" == Fiona Klute <fiona.klute@gmx.de> writes:

Hi,

 >> What we could also do is to only add the workaround for python >=
 >> 3.14.x
 >> (which is not yet in Debian), E.G.
 >> if sys.version_info >= (3,14):
 >> multiprocessing.set_start_method('fork')
 
 > That would fix the immediate issue, yes. If Debian updates to 3.14
 > before Nose is fixed we'll be back where we started, and I think it'd
 > be good not to rely on a specific start method in general. But I
 > suppose the version check would be a reasonable compromise for the
 > stable branches. :-)

Indeed. I started by reporting the issue to Debian so the package
(hopefully) does not transition to stable:

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1129350

Another hacky workaround would be to monkey patch set_start_method() to
ignore the call from nose2, E.G.:

if multiprocessing.get_start_method() != 'fork':
   multiprocessing.set_start_method('fork')
   multiprocessing.set_start_method = = lambda *args: None

Which may be better than the python version check.

-- 
Bye, Peter Korsgaard
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Buildroot] [PATCH 1/1] support/testing: transfer config in environment instead of class variables
  2026-03-01 10:10         ` Peter Korsgaard
@ 2026-03-01 10:11           ` Peter Korsgaard
  0 siblings, 0 replies; 7+ messages in thread
From: Peter Korsgaard @ 2026-03-01 10:11 UTC (permalink / raw)
  To: Fiona Klute
  Cc: buildroot, Ricardo Martincoski, Julien Olivain,
	Jimmy Durand Wesolowski, guenther.harrasser

>>>>> "Peter" == Peter Korsgaard <peter@korsgaard.com> writes:

Hi,

 > Another hacky workaround would be to monkey patch set_start_method() to
 > ignore the call from nose2, E.G.:

 > if multiprocessing.get_start_method() != 'fork':
 >    multiprocessing.set_start_method('fork')
 >    multiprocessing.set_start_method = = lambda *args: None

Ehh, without the 2nd '=' naturally ;)

-- 
Bye, Peter Korsgaard
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-03-01 10:11 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-27 19:21 [Buildroot] [PATCH 1/1] support/testing: transfer config in environment instead of class variables Fiona Klute via buildroot
2026-02-28 19:50 ` Peter Korsgaard
2026-02-28 20:41   ` Fiona Klute via buildroot
2026-02-28 22:21     ` Peter Korsgaard
2026-02-28 22:30       ` Fiona Klute via buildroot
2026-03-01 10:10         ` Peter Korsgaard
2026-03-01 10:11           ` Peter Korsgaard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox