Commit fa587876 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'linux-kselftest-kunit-fixes-5.15-rc6' of...

Merge tag 'linux-kselftest-kunit-fixes-5.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest

Pull Kunit fixes from Shuah Khan:

 - Fixes to address the structleak plugin causing the stack frame size
   to grow immensely when used with KUnit. Fixes include adding a new
   makefile to disable structleak and using it from KUnit iio, device
   property, thunderbolt, and bitfield tests to disable it.

 - KUnit framework reference count leak in kfree_at_end

 - KUnit tool fix to resolve conflict between --json and --raw_output
   and generate correct test output in either case.

 - kernel-doc warnings due to mismatched arg names

* tag 'linux-kselftest-kunit-fixes-5.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest:
  kunit: fix kernel-doc warnings due to mismatched arg names
  bitfield: build kunit tests without structleak plugin
  thunderbolt: build kunit tests without structleak plugin
  device property: build kunit tests without structleak plugin
  iio/test-format: build kunit tests without structleak plugin
  gcc-plugins/structleak: add makefile var for disabling structleak
  kunit: fix reference count leak in kfree_at_end
  kunit: tool: better handling of quasi-bool args (--json, --raw_output)
parents 459ea72c 361b57df
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
obj-$(CONFIG_TEST_ASYNC_DRIVER_PROBE) += test_async_driver_probe.o obj-$(CONFIG_TEST_ASYNC_DRIVER_PROBE) += test_async_driver_probe.o
obj-$(CONFIG_DRIVER_PE_KUNIT_TEST) += property-entry-test.o obj-$(CONFIG_DRIVER_PE_KUNIT_TEST) += property-entry-test.o
CFLAGS_REMOVE_property-entry-test.o += -fplugin-arg-structleak_plugin-byref -fplugin-arg-structleak_plugin-byref-all CFLAGS_property-entry-test.o += $(DISABLE_STRUCTLEAK_PLUGIN)
...@@ -5,3 +5,4 @@ ...@@ -5,3 +5,4 @@
# Keep in alphabetical order # Keep in alphabetical order
obj-$(CONFIG_IIO_TEST_FORMAT) += iio-test-format.o obj-$(CONFIG_IIO_TEST_FORMAT) += iio-test-format.o
CFLAGS_iio-test-format.o += $(DISABLE_STRUCTLEAK_PLUGIN)
...@@ -7,6 +7,7 @@ thunderbolt-objs += usb4_port.o nvm.o retimer.o quirks.o ...@@ -7,6 +7,7 @@ thunderbolt-objs += usb4_port.o nvm.o retimer.o quirks.o
thunderbolt-${CONFIG_ACPI} += acpi.o thunderbolt-${CONFIG_ACPI} += acpi.o
thunderbolt-$(CONFIG_DEBUG_FS) += debugfs.o thunderbolt-$(CONFIG_DEBUG_FS) += debugfs.o
thunderbolt-${CONFIG_USB4_KUNIT_TEST} += test.o thunderbolt-${CONFIG_USB4_KUNIT_TEST} += test.o
CFLAGS_test.o += $(DISABLE_STRUCTLEAK_PLUGIN)
thunderbolt_dma_test-${CONFIG_USB4_DMA_TEST} += dma_test.o thunderbolt_dma_test-${CONFIG_USB4_DMA_TEST} += dma_test.o
obj-$(CONFIG_USB4_DMA_TEST) += thunderbolt_dma_test.o obj-$(CONFIG_USB4_DMA_TEST) += thunderbolt_dma_test.o
...@@ -613,7 +613,7 @@ void kunit_remove_resource(struct kunit *test, struct kunit_resource *res); ...@@ -613,7 +613,7 @@ void kunit_remove_resource(struct kunit *test, struct kunit_resource *res);
* and is automatically cleaned up after the test case concludes. See &struct * and is automatically cleaned up after the test case concludes. See &struct
* kunit_resource for more information. * kunit_resource for more information.
*/ */
void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t flags); void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t gfp);
/** /**
* kunit_kmalloc() - Like kmalloc() except the allocation is *test managed*. * kunit_kmalloc() - Like kmalloc() except the allocation is *test managed*.
...@@ -657,9 +657,9 @@ static inline void *kunit_kzalloc(struct kunit *test, size_t size, gfp_t gfp) ...@@ -657,9 +657,9 @@ static inline void *kunit_kzalloc(struct kunit *test, size_t size, gfp_t gfp)
* *
* See kcalloc() and kunit_kmalloc_array() for more information. * See kcalloc() and kunit_kmalloc_array() for more information.
*/ */
static inline void *kunit_kcalloc(struct kunit *test, size_t n, size_t size, gfp_t flags) static inline void *kunit_kcalloc(struct kunit *test, size_t n, size_t size, gfp_t gfp)
{ {
return kunit_kmalloc_array(test, n, size, flags | __GFP_ZERO); return kunit_kmalloc_array(test, n, size, gfp | __GFP_ZERO);
} }
void kunit_cleanup(struct kunit *test); void kunit_cleanup(struct kunit *test);
......
...@@ -351,7 +351,7 @@ obj-$(CONFIG_OBJAGG) += objagg.o ...@@ -351,7 +351,7 @@ obj-$(CONFIG_OBJAGG) += objagg.o
obj-$(CONFIG_PLDMFW) += pldmfw/ obj-$(CONFIG_PLDMFW) += pldmfw/
# KUnit tests # KUnit tests
CFLAGS_bitfield_kunit.o := $(call cc-option,-Wframe-larger-than=10240) CFLAGS_bitfield_kunit.o := $(DISABLE_STRUCTLEAK_PLUGIN)
obj-$(CONFIG_BITFIELD_KUNIT) += bitfield_kunit.o obj-$(CONFIG_BITFIELD_KUNIT) += bitfield_kunit.o
obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o
obj-$(CONFIG_LINEAR_RANGES_TEST) += test_linear_ranges.o obj-$(CONFIG_LINEAR_RANGES_TEST) += test_linear_ranges.o
......
...@@ -116,7 +116,7 @@ static void kfree_at_end(struct kunit *test, const void *to_free) ...@@ -116,7 +116,7 @@ static void kfree_at_end(struct kunit *test, const void *to_free)
/* kfree() handles NULL already, but avoid allocating a no-op cleanup. */ /* kfree() handles NULL already, but avoid allocating a no-op cleanup. */
if (IS_ERR_OR_NULL(to_free)) if (IS_ERR_OR_NULL(to_free))
return; return;
kunit_alloc_and_get_resource(test, NULL, kfree_res_free, GFP_KERNEL, kunit_alloc_resource(test, NULL, kfree_res_free, GFP_KERNEL,
(void *)to_free); (void *)to_free);
} }
......
...@@ -19,6 +19,10 @@ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF) \ ...@@ -19,6 +19,10 @@ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF) \
+= -fplugin-arg-structleak_plugin-byref += -fplugin-arg-structleak_plugin-byref
gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL) \ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL) \
+= -fplugin-arg-structleak_plugin-byref-all += -fplugin-arg-structleak_plugin-byref-all
ifdef CONFIG_GCC_PLUGIN_STRUCTLEAK
DISABLE_STRUCTLEAK_PLUGIN += -fplugin-arg-structleak_plugin-disable
endif
export DISABLE_STRUCTLEAK_PLUGIN
gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) \ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) \
+= -DSTRUCTLEAK_PLUGIN += -DSTRUCTLEAK_PLUGIN
......
...@@ -16,7 +16,7 @@ assert sys.version_info >= (3, 7), "Python version is too old" ...@@ -16,7 +16,7 @@ assert sys.version_info >= (3, 7), "Python version is too old"
from collections import namedtuple from collections import namedtuple
from enum import Enum, auto from enum import Enum, auto
from typing import Iterable from typing import Iterable, Sequence
import kunit_config import kunit_config
import kunit_json import kunit_json
...@@ -186,6 +186,26 @@ def run_tests(linux: kunit_kernel.LinuxSourceTree, ...@@ -186,6 +186,26 @@ def run_tests(linux: kunit_kernel.LinuxSourceTree,
exec_result.elapsed_time)) exec_result.elapsed_time))
return parse_result return parse_result
# Problem:
# $ kunit.py run --json
# works as one would expect and prints the parsed test results as JSON.
# $ kunit.py run --json suite_name
# would *not* pass suite_name as the filter_glob and print as json.
# argparse will consider it to be another way of writing
# $ kunit.py run --json=suite_name
# i.e. it would run all tests, and dump the json to a `suite_name` file.
# So we hackily automatically rewrite --json => --json=stdout
pseudo_bool_flag_defaults = {
'--json': 'stdout',
'--raw_output': 'kunit',
}
def massage_argv(argv: Sequence[str]) -> Sequence[str]:
def massage_arg(arg: str) -> str:
if arg not in pseudo_bool_flag_defaults:
return arg
return f'{arg}={pseudo_bool_flag_defaults[arg]}'
return list(map(massage_arg, argv))
def add_common_opts(parser) -> None: def add_common_opts(parser) -> None:
parser.add_argument('--build_dir', parser.add_argument('--build_dir',
help='As in the make command, it specifies the build ' help='As in the make command, it specifies the build '
...@@ -303,7 +323,7 @@ def main(argv, linux=None): ...@@ -303,7 +323,7 @@ def main(argv, linux=None):
help='Specifies the file to read results from.', help='Specifies the file to read results from.',
type=str, nargs='?', metavar='input_file') type=str, nargs='?', metavar='input_file')
cli_args = parser.parse_args(argv) cli_args = parser.parse_args(massage_argv(argv))
if get_kernel_root_path(): if get_kernel_root_path():
os.chdir(get_kernel_root_path()) os.chdir(get_kernel_root_path())
......
...@@ -408,6 +408,14 @@ class KUnitMainTest(unittest.TestCase): ...@@ -408,6 +408,14 @@ class KUnitMainTest(unittest.TestCase):
self.assertNotEqual(call, mock.call(StrContains('Testing complete.'))) self.assertNotEqual(call, mock.call(StrContains('Testing complete.')))
self.assertNotEqual(call, mock.call(StrContains(' 0 tests run'))) self.assertNotEqual(call, mock.call(StrContains(' 0 tests run')))
def test_run_raw_output_does_not_take_positional_args(self):
# --raw_output is a string flag, but we don't want it to consume
# any positional arguments, only ones after an '='
self.linux_source_mock.run_kernel = mock.Mock(return_value=[])
kunit.main(['run', '--raw_output', 'filter_glob'], self.linux_source_mock)
self.linux_source_mock.run_kernel.assert_called_once_with(
args=None, build_dir='.kunit', filter_glob='filter_glob', timeout=300)
def test_exec_timeout(self): def test_exec_timeout(self):
timeout = 3453 timeout = 3453
kunit.main(['exec', '--timeout', str(timeout)], self.linux_source_mock) kunit.main(['exec', '--timeout', str(timeout)], self.linux_source_mock)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment