On Wed, 28 Jan 2026 10:15:51 -0800
Jacob Keller <[email protected]> wrote:

> On 1/28/2026 9:27 AM, Jonathan Corbet wrote:
> > Mauro Carvalho Chehab <[email protected]> writes:
> >   
> >> Hi Jon,
> >>
> >> It is impressive how a single patch became a series with 25 ones ;-)  
> > 
> > *sigh*
> >   
> 
> Splitting things up helped me understand all the changes at least :)
> 
> > I will try to have a good look at these shortly.  It seems pretty clear
> > that this isn't 7.0 material at this point, though.
> > 
> > One thing that jumped at me:
> >   
> >> Ah, due to the complexity of NestedMatch, I opted to write
> >> some unit tests to verify that the logic there is correct.
> >> We can use it to add other border cases.
> >>
> >> Using it is as easy as running:
> >>
> >>    $ tools/unittests/nested_match.py
> >>
> >> (I opted to create a separate directory for it, as this
> >> is not really documentation)  
> > 
> > Do we really need another unit-testing setup in the kernel?  I can't say
> > I'm familiar enough with kunit to say whether it would work for
> > non-kernel code; have you looked and verified that it isn't suitable?
> >   
> 
> I'm not sure kunit would be suitable here, since its meant for running 
> kernel code and does a lot of stuff to make that possible. It might be 
> able to be extended, but.. this is python code. Why *shouldn't* we use 
> one of the python unit test frameworks for it?

This is not using kunit. It is using standard "import unittest" from
Python internal lib.

> We have other python code in tree. Does any of that code have unit tests?

Good question. On a quick grep, it sounds so:

        $ git grep "import unittest" tools scripts
        scripts/rust_is_available_test.py:import unittest
        tools/crypto/ccp/test_dbc.py:import unittest
        tools/perf/pmu-events/metric_test.py:import unittest
        tools/testing/kunit/kunit_tool_test.py:import unittest
        tools/testing/selftests/bpf/test_bpftool.py:import unittest
        tools/testing/selftests/tpm2/tpm2.py:import unittest
        tools/testing/selftests/tpm2/tpm2_tests.py:import unittest

> I agree that it doesn't make sense to build new bespoke unit tests 
> different or unique per each python module, so if we want to adopt 
> python unit tests we should try to pick something that works for the 
> python tools in the kernel.
> 
> Perhaps finding a way to integrate this with kunit so that you can use 
> "kunit run" and get python tests executed as well would make sense? 
> But.. then again this isn't kernel code so I'm not sure it makes sense 
> to conflate the tests with kernel unit tests.

It shouldn't be hard to add it there - or to have a separate script
to run python unittests.

Assuming that we place all unittests at the same directory
(tools/unittests), the enclosed path will run all of them
altogether:

        $ tools/unittests/run.py
        Ran 35 tests in 0.001s

        OK
        nested_match:
            TestStructGroup:
                test_struct_group_01:            OK
                test_struct_group_02:            OK
                test_struct_group_03:            OK
                test_struct_group_04:            OK
                test_struct_group_05:            OK
                test_struct_group_06:            OK
                test_struct_group_07:            OK
                test_struct_group_08:            OK
                test_struct_group_09:            OK
                test_struct_group_10:            OK
                test_struct_group_11:            OK
                test_struct_group_12:            OK
                test_struct_group_13:            OK
                test_struct_group_14:            OK
                test_struct_group_15:            OK
                test_struct_group_16:            OK
                test_struct_group_17:            OK
                test_struct_group_18:            OK
                test_struct_group_19:            OK
                test_struct_group_sub:           OK
            TestSubMacros:
                test_acquires_multiple:          OK
                test_acquires_nested_paren:      OK
                test_acquires_simple:            OK
                test_mixed_macros:               OK
                test_must_hold:                  OK
                test_must_hold_shared:           OK
                test_no_false_positive:          OK
                test_no_macro_remains:           OK
            TestSubReplacement:
                test_sub_count_parameter:        OK
                test_sub_mixed_placeholders:     OK
                test_sub_multiple_placeholders:  OK
                test_sub_no_placeholder:         OK
                test_sub_single_placeholder:     OK
                test_sub_with_capture:           OK
                test_sub_zero_placeholder:       OK


        Ran 35 tests

And the helper will also provide an argparse to allow filtering
tests, change verbosity and filtering them with a regex:

        $ tools/unittests/run.py --help
        usage: run.py [-h] [-v] [-f] [-k KEYWORD]

        Test runner with regex filtering

        options:
          -h, --help            show this help message and exit
          -v, --verbose
          -f, --failfast
          -k, --keyword KEYWORD
                                Regex pattern to filter test methods

That's said, some integration with kunit can be interesting
to have it producing a KTAP output if needed by some CI.

---

[PATCH] [RFC] Run all tests from tools/unittests

This small example runs all unittests from tools/unittests with:

    $ tools/unittests/run.py

Signed-off-by: Mauro Carvalho Chehab <[email protected]>

diff --git a/tools/lib/python/unittest_helper.py 
b/tools/lib/python/unittest_helper.py
index 3cf1075b1de4..af16acc3af17 100755
--- a/tools/lib/python/unittest_helper.py
+++ b/tools/lib/python/unittest_helper.py
@@ -213,7 +213,7 @@ class TestUnits:
                             help="Regex pattern to filter test methods")
         return parser
 
-    def run(self, caller_file, parser=None, args=None, env=None):
+    def run(self, caller_file, suite=None, parser=None, args=None, env=None):
         """Execute all tests from the unity test file"""
         if not args:
             if not parser:
@@ -232,9 +232,10 @@ class TestUnits:
             unittest.TextTestRunner(verbosity=verbose).run = lambda suite: 
suite
 
         # Load ONLY tests from the calling file
-        loader = unittest.TestLoader()
-        suite = loader.discover(start_dir=os.path.dirname(caller_file),
-                                pattern=os.path.basename(caller_file))
+        if not suite:
+            loader = unittest.TestLoader()
+            suite = loader.discover(start_dir=os.path.dirname(caller_file),
+                                    pattern=os.path.basename(caller_file))
 
         # Flatten the suite for environment injection
         tests_to_inject = flatten_suite(suite)
diff --git a/tools/unittests/run.py b/tools/unittests/run.py
new file mode 100755
index 000000000000..2a5a754219de
--- /dev/null
+++ b/tools/unittests/run.py
@@ -0,0 +1,17 @@
+#!/bin/env python3
+import os
+import unittest
+import sys
+
+TOOLS_DIR=os.path.join(os.path.dirname(os.path.realpath(__file__)), "..")
+sys.path.insert(0, TOOLS_DIR)
+
+from lib.python.unittest_helper import TestUnits
+
+if __name__ == "__main__":
+    loader = unittest.TestLoader()
+
+    suite = loader.discover(start_dir=os.path.join(TOOLS_DIR, "unittests"),
+                            pattern="*.py")
+
+    TestUnits().run("", suite=suite)

Thanks,
Mauro

Reply via email to