<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux/tools/testing/kunit/kunit.py, branch v5.17</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
</subtitle>
<id>https://git.shady.money/linux/atom?h=v5.17</id>
<link rel='self' href='https://git.shady.money/linux/atom?h=v5.17'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/'/>
<updated>2021-12-15T23:44:55Z</updated>
<entry>
<title>kunit: tool: Default --jobs to number of CPUs</title>
<updated>2021-12-15T23:44:55Z</updated>
<author>
<name>David Gow</name>
<email>davidgow@google.com</email>
</author>
<published>2021-12-15T20:50:14Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=ad659ccb5412874c6a89d3588cb18857c00e9d0f'/>
<id>urn:sha1:ad659ccb5412874c6a89d3588cb18857c00e9d0f</id>
<content type='text'>
The --jobs parameter for kunit_tool currently defaults to 8 CPUs,
regardless of the number available. For systems with significantly more
(or less), this is not as efficient. Instead, default --jobs to the
number of CPUs available to the process: while there are as many
superstitions as to exactly what the ideal jobs:CPU ratio is, this seems
sufficiently sensible to me.

A new helper function to get the default number of jobs is added:
get_default_jobs() -- this is used in kunit_tool_test instead of a
hardcoded value, or an explicit call to len(os.sched_getaffinity()), so
should be more flexible if this needs to change in the future.

Signed-off-by: David Gow &lt;davidgow@google.com&gt;
Signed-off-by: Daniel Latypov &lt;dlatypov@google.com&gt;
Reviewed-by: Daniel Latypov &lt;dlatypov@google.com&gt;
Reviewed-by: Brendan Higgins &lt;brendanhiggins@google.com&gt;
Signed-off-by: Shuah Khan &lt;skhan@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>kunit: tool: make `build` subcommand also reconfigure if needed</title>
<updated>2021-12-15T18:51:16Z</updated>
<author>
<name>Daniel Latypov</name>
<email>dlatypov@google.com</email>
</author>
<published>2021-12-14T19:30:10Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=1ee2ba89bea86d6389509e426583b49ac19b86f2'/>
<id>urn:sha1:1ee2ba89bea86d6389509e426583b49ac19b86f2</id>
<content type='text'>
If I created a kunitconfig file that was incomplete, then
$ ./tools/testing/kunit/kunit.py build --kunitconfig=my_kunitconfig
would silently drop all the options with unmet dependencies!

This is because it doesn't do the config check that `kunit.py config`
does.

So if I want to safely build a kernel for testing, I have to do
$ ./tools/testing/kunit/kunit.py config &lt;flags&gt;
$ ./tools/testing/kunit/kunit.py build &lt;flags, again&gt;

It seems unlikely that any user of kunit.py would want the current
`build` semantics.
So make it effectively do `kunit.py config` + `kunit.py build`.

Signed-off-by: Daniel Latypov &lt;dlatypov@google.com&gt;
Reviewed-by: Brendan Higgins &lt;brendanhiggins@google.com&gt;
Signed-off-by: Shuah Khan &lt;skhan@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>kunit: tool: delete kunit_parser.TestResult type</title>
<updated>2021-12-15T18:50:56Z</updated>
<author>
<name>Daniel Latypov</name>
<email>dlatypov@google.com</email>
</author>
<published>2021-12-14T19:26:12Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=e0cc8c052a3992b01f51df1d51eaae49e5b2710f'/>
<id>urn:sha1:e0cc8c052a3992b01f51df1d51eaae49e5b2710f</id>
<content type='text'>
The `log` field is unused, and the `status` field is accessible via
`test.status`.

So it's simpler to just return the main `Test` object directly.

And since we're no longer returning a namedtuple, which has no type
annotations, this hopefully means typecheckers are better equipped to
find any errors.

Signed-off-by: Daniel Latypov &lt;dlatypov@google.com&gt;
Reviewed-by: Brendan Higgins &lt;brendanhiggins@google.com&gt;
Signed-off-by: Shuah Khan &lt;skhan@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>kunit: tool: use dataclass instead of collections.namedtuple</title>
<updated>2021-12-15T18:50:41Z</updated>
<author>
<name>Daniel Latypov</name>
<email>dlatypov@google.com</email>
</author>
<published>2021-12-14T19:26:11Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=db1679813f9f86b05bbbc6f05f4cdbe481d59352'/>
<id>urn:sha1:db1679813f9f86b05bbbc6f05f4cdbe481d59352</id>
<content type='text'>
namedtuple is a terse way of defining a collection of fields.
However, it does not allow us to annotate the type of these fields.
It also doesn't let us have any sort of inheritance between types.

Since commit df4b0807ca1a ("kunit: tool: Assert the version
requirement"), kunit.py has asserted that it's running on python &gt;=3.7.

So in that case use a 3.7 feature, dataclasses, to replace these.

Changes in detail:
* Make KunitExecRequest contain all the fields needed for exec_tests
* Use inheritance to dedupe fields
  * also allows us to e.g. pass a KUnitRequest in as a KUnitParseRequest
  * this has changed around the order of some fields
* Use named arguments when constructing all request objects in kunit.py
  * This is to prevent accidentally mixing up fields, etc.

Signed-off-by: Daniel Latypov &lt;dlatypov@google.com&gt;
Reviewed-by: Brendan Higgins &lt;brendanhiggins@google.com&gt;
Signed-off-by: Shuah Khan &lt;skhan@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>kunit: tool: suggest using decode_stacktrace.sh on kernel crash</title>
<updated>2021-12-13T20:59:19Z</updated>
<author>
<name>Daniel Latypov</name>
<email>dlatypov@google.com</email>
</author>
<published>2021-11-20T03:24:01Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=7fa7ffcf9babaea2f0a81681b4ef460ee4b93278'/>
<id>urn:sha1:7fa7ffcf9babaea2f0a81681b4ef460ee4b93278</id>
<content type='text'>
kunit.py isn't very clear that
1) it stashes a copy of the unparsed output in $BUILD_DIR/test.log
2) it sets $BUILD_DIR=.kunit by default

So it's trickier than it should be for a user to come up with the right
command to do so.

Make kunit.py print out a command for this if
a) we saw a test case crash
b) we only ran one kernel (test.log only contains output from the last)

Example suggested command:
$ scripts/decode_stacktrace.sh .kunit/vmlinux .kunit &lt; .kunit/test.log | tee .kunit/decoded.log | ./tools/testing/kunit/kunit.py parse

Without debug info a user might see something like
[14:11:25] Call Trace:
[14:11:25] ? kunit_binary_assert_format (:?)
[14:11:25] kunit_try_run_case (test.c:?)
[14:11:25] ? __kthread_parkme (kthread.c:?)
[14:11:25] kunit_generic_run_threadfn_adapter (try-catch.c:?)
[14:11:25] ? kunit_generic_run_threadfn_adapter (try-catch.c:?)
[14:11:25] kthread (kthread.c:?)
[14:11:25] new_thread_handler (:?)
[14:11:25] [CRASHED]

`tee` is in GNU coreutils, so it seems fine to add that into the
pipeline by default, that way users can inspect the otuput in more
detail.

Note: to turn on debug info, users would need to do something like
$ echo -e 'CONFIG_DEBUG_KERNEL=y\nCONFIG_DEBUG_INFO=y' &gt;&gt; .kunit/.kunitconfig
$ ./tools/testing/kunit/kunit.py config
$ ./tools/testing/kunit/kunit.py build
$ &lt;then run decode_stacktrace.sh now vmlinux is updated&gt;

This feels too clunky to include in the instructions.
With --kconfig_add [1], it would become a bit less painful.

[1] https://lore.kernel.org/linux-kselftest/20211106013058.2621799-2-dlatypov@google.com/

Signed-off-by: Daniel Latypov &lt;dlatypov@google.com&gt;
Reviewed-by: Brendan Higgins &lt;brendanhiggins@google.com&gt;
Signed-off-by: Shuah Khan &lt;skhan@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>kunit: tool: add --kconfig_add to allow easily tweaking kunitconfigs</title>
<updated>2021-12-13T20:56:27Z</updated>
<author>
<name>Daniel Latypov</name>
<email>dlatypov@google.com</email>
</author>
<published>2021-11-06T01:30:58Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=9f57cc76eccc1e0a369bb051c4b0d596e7d15e30'/>
<id>urn:sha1:9f57cc76eccc1e0a369bb051c4b0d596e7d15e30</id>
<content type='text'>
E.g. run tests but with KASAN
$ ./tools/testing/kunit/kunit.py run --arch=x86_64 --kconfig_add=CONFIG_KASAN=y

This also works with --kunitconfig
$ ./tools/testing/kunit/kunit.py run --arch=x86_64 --kunitconfig=fs/ext4 --kconfig_add=CONFIG_KASAN=y

This flag is inspired by TuxMake's --kconfig-add, see
https://gitlab.com/Linaro/tuxmake#examples.

Our version just uses "_" as the delimiter for consistency with
pre-existing flags like --build_dir, --make_options, --kernel_args, etc.

Note: this does make it easier to run into a pre-existing edge case:
$ ./tools/testing/kunit/kunit.py run --arch=x86_64 --kconfig_add=CONFIG_KASAN=y
$ ./tools/testing/kunit/kunit.py run --arch=x86_64
This second invocation ^ still has KASAN enabled!

kunit.py won't call olddefconfig if our current .config is already a
superset of the provided kunitconfig.

Signed-off-by: Daniel Latypov &lt;dlatypov@google.com&gt;
Reviewed-by: David Gow &lt;davidgow@google.com&gt;
Reviewed-by: Brendan Higgins &lt;brendanhiggins@google.com&gt;
Signed-off-by: Shuah Khan &lt;skhan@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>kunit: tool: continue past invalid utf-8 output</title>
<updated>2021-10-25T19:06:45Z</updated>
<author>
<name>Daniel Latypov</name>
<email>dlatypov@google.com</email>
</author>
<published>2021-10-20T23:21:21Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=2ab5d5e67f7ab2d2ecf67b8855ac65691f4e4b4d'/>
<id>urn:sha1:2ab5d5e67f7ab2d2ecf67b8855ac65691f4e4b4d</id>
<content type='text'>
kunit.py currently crashes and fails to parse kernel output if it's not
fully valid utf-8.

This can come from memory corruption or just inadvertently printing
out binary data as strings.

E.g. adding this line into a kunit test
  pr_info("\x80")
will cause this exception
  UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position
  1961: invalid start byte

We can tell Python how to handle errors, see
https://docs.python.org/3/library/codecs.html#error-handlers

Unfortunately, it doesn't seem like there's a way to specify this in
just one location, so we need to repeat ourselves quite a bit.

Specify `errors='backslashreplace'` so we instead:
* print out the offending byte as '\x80'
* try and continue parsing the output.
  * as long as the TAP lines themselves are valid, we're fine.

Fixed spelling/grammar in commit log:
Shuah Khan &lt;&lt;skhan@linuxfoundation.org&gt;

Signed-off-by: Daniel Latypov &lt;dlatypov@google.com&gt;
Reviewed-by: Brendan Higgins &lt;brendanhiggins@google.com&gt;
Tested-by: David Gow &lt;davidgow@google.com&gt;
Signed-off-by: Shuah Khan &lt;skhan@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>kunit: tool: improve compatibility of kunit_parser with KTAP specification</title>
<updated>2021-10-19T20:22:02Z</updated>
<author>
<name>Rae Moar</name>
<email>rmoar@google.com</email>
</author>
<published>2021-10-11T21:50:37Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=d65d07cb5b01dcf3707b9cd7987ead96bd41b3cb'/>
<id>urn:sha1:d65d07cb5b01dcf3707b9cd7987ead96bd41b3cb</id>
<content type='text'>
Update to kunit_parser to improve compatibility with KTAP
specification including arbitrarily nested tests. Patch accomplishes
three major changes:

- Use a general Test object to represent all tests rather than TestCase
and TestSuite objects. This allows for easier implementation of arbitrary
levels of nested tests and promotes the idea that both test suites and test
cases are tests.

- Print errors incrementally rather than all at once after the
parsing finishes to maximize information given to the user in the
case of the parser given invalid input and to increase the helpfulness
of the timestamps given during printing. Note that kunit.py parse does
not print incrementally yet. However, this fix brings us closer to
this feature.

- Increase compatibility for different formats of input. Arbitrary levels
of nested tests supported. Also, test cases and test suites are now
supported to be present on the same level of testing.

This patch now implements the draft KTAP specification here:
https://lore.kernel.org/linux-kselftest/CA+GJov6tdjvY9x12JsJT14qn6c7NViJxqaJk+r-K1YJzPggFDQ@mail.gmail.com/
We'll update the parser as the spec evolves.

This patch adjusts the kunit_tool_test.py file to check for
the correct outputs from the new parser and adds a new test to check
the parsing for a KTAP result log with correct format for multiple nested
subtests (test_is_test_passed-all_passed_nested.log).

This patch also alters the kunit_json.py file to allow for arbitrarily
nested tests.

Signed-off-by: Rae Moar &lt;rmoar@google.com&gt;
Reviewed-by: Brendan Higgins &lt;brendanhiggins@google.com&gt;
Signed-off-by: Daniel Latypov &lt;dlatypov@google.com&gt;
Reviewed-by: David Gow &lt;davidgow@google.com&gt;
Signed-off-by: Shuah Khan &lt;skhan@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>kunit: tool: support running each suite/test separately</title>
<updated>2021-10-19T20:21:08Z</updated>
<author>
<name>Daniel Latypov</name>
<email>dlatypov@google.com</email>
</author>
<published>2021-09-30T22:20:48Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=ff9e09a3762fbd7aba83cfd1530972b57ae52b3b'/>
<id>urn:sha1:ff9e09a3762fbd7aba83cfd1530972b57ae52b3b</id>
<content type='text'>
The new --run_isolated flag makes the tool boot the kernel once per
suite or test, preventing leftover state from one suite to impact the
other. This can be useful as a starting point to debugging test
hermeticity issues.

Note: it takes a lot longer, so people should not use it normally.

Consider the following very simplified example:

  bool disable_something_for_test = false;
  void function_being_tested() {
    ...
    if (disable_something_for_test) return;
    ...
  }

  static void test_before(struct kunit *test)
  {
    disable_something_for_test = true;
    function_being_tested();
    /* oops, we forgot to reset it back to false */
  }

  static void test_after(struct kunit *test)
  {
    /* oops, now "fixing" test_before can cause test_after to fail! */
    function_being_tested();
  }

Presented like this, the issues are obvious, but it gets a lot more
complicated to track down as the amount of test setup and helper
functions increases.

Another use case is memory corruption. It might not be surfaced as a
failure/crash in the test case or suite that caused it. I've noticed in
kunit's own unit tests, the 3rd suite after might be the one to finally
crash after an out-of-bounds write, for example.

Example usage:

Per suite:
$ ./tools/testing/kunit/kunit.py run --kunitconfig=lib/kunit --run_isolated=suite
...
Starting KUnit Kernel (1/7)...
============================================================
======== [PASSED] kunit_executor_test ========
....
Testing complete. 5 tests run. 0 failed. 0 crashed. 0 skipped.
Starting KUnit Kernel (2/7)...
============================================================
======== [PASSED] kunit-try-catch-test ========
...

Per test:
$ ./tools/testing/kunit/kunit.py run --kunitconfig=lib/kunit --run_isolated=test
Starting KUnit Kernel (1/23)...
============================================================
======== [PASSED] kunit_executor_test ========
[PASSED] parse_filter_test
============================================================
Testing complete. 1 tests run. 0 failed. 0 crashed. 0 skipped.
Starting KUnit Kernel (2/23)...
============================================================
======== [PASSED] kunit_executor_test ========
[PASSED] filter_subsuite_test
...

It works with filters as well:
$ ./tools/testing/kunit/kunit.py run --kunitconfig=lib/kunit --run_isolated=suite example
...
Starting KUnit Kernel (1/1)...
============================================================
======== [PASSED] example ========
...

It also handles test filters, '*.*skip*' runs these 3 tests:
  kunit_status.kunit_status_mark_skipped_test
  example.example_skip_test
  example.example_mark_skipped_test

Fixed up merge conflict between:
  d8c23ead708b ("kunit: tool: better handling of quasi-bool args (--json, --raw_output)") and
  6710951ee039 ("kunit: tool: support running each suite/test separately")
    Reported-by: Stephen Rothwell &lt;sfr@canb.auug.org.au&gt;
    Shuah Khan &lt;skhan@linuxfoundation.org&gt;

Signed-off-by: Daniel Latypov &lt;dlatypov@google.com&gt;
Reviewed-by: David Gow &lt;davidgow@google.com&gt;
Reviewed-by: Brendan Higgins &lt;brendanhiggins@google.com&gt;
Signed-off-by: Shuah Khan &lt;skhan@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>kunit: tool: actually track how long it took to run tests</title>
<updated>2021-10-19T20:18:50Z</updated>
<author>
<name>Daniel Latypov</name>
<email>dlatypov@google.com</email>
</author>
<published>2021-09-30T22:20:47Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=5f6aa6d82e45d27f00f39844749ae812c7fd6ab3'/>
<id>urn:sha1:5f6aa6d82e45d27f00f39844749ae812c7fd6ab3</id>
<content type='text'>
This is a long standing bug in kunit tool.
Since these files were added, run_kernel() has always yielded lines.

That means, the call to run_kernel() returns before the kernel finishes
executing tests, potentially before a single line of output is even
produced.

So code like this
  time_start = time.time()
  result = linux.run_kernel(...)
  time_end = time.time()

would only measure the time taken for python to give back the generator
object.

From a caller's perspective, the only way to know the kernel has exited
is for us to consume all the output from the `result` generator object.
Alternatively, we could change run_kernel() to try and do its own book
keeping and return the total time, but that doesn't seem worth it.

This change makes us record `time_end` after we're done parsing all the
output (which should mean we've consumed all of it, or errored out).
That means we're including in the parsing time as well, but that should
be quite small, and it's better than claiming it took 0s to run tests.

Let's use this as an example:
$ ./tools/testing/kunit/kunit.py run --kunitconfig=lib/kunit example

Before:
Elapsed time: 7.684s total, 0.001s configuring, 4.692s building, 0.000s running

After:
Elapsed time: 6.283s total, 0.001s configuring, 3.202s building, 3.079s running

Signed-off-by: Daniel Latypov &lt;dlatypov@google.com&gt;
Reviewed-by: David Gow &lt;davidgow@google.com&gt;
Reviewed-by: Brendan Higgins &lt;brendanhiggins@google.com&gt;
Signed-off-by: Shuah Khan &lt;skhan@linuxfoundation.org&gt;
</content>
</entry>
</feed>
