mirror of
https://github.com/SCST-project/scst.git
synced 2026-10-22 14:12:33 +00:00
Integrate optional native KUnit suites with out-of-tree SCST modules. A single CONFIG_SCST_KUNIT_TEST switch includes all test objects of each owner. Declare each suite name and label once and discover source registrations for kunit-list without a build or loaded modules. Preserve ordinary builds without KUnit. Start with a fixed-wire LUN regression. Centralize private visibility and task-scoped static-stub switches, and define retained-fixture reporting for asynchronous tests. Use current native KUnit APIs without compatibility shims. Keep optional execution messages behind CONFIG_SCST_KUNIT_LOG while leaving failure diagnostics unconditional. Add Makefile/Kbuild regression checks and document the shared switch. Keep compatibility builds free of KUnit, including inherited test options and allmodconfig. Generate ordinary in-tree SCST patches with private declarations but without test suites or KUnit build options. Check this boundary and preserve kernels without an unwinder option.
93 lines
3.5 KiB
Python
93 lines
3.5 KiB
Python
# SPDX-License-Identifier: GPL-2.0-only
|
|
"""Check plain regression builds without downloading or compiling a kernel."""
|
|
|
|
from pathlib import Path
|
|
import re
|
|
import subprocess
|
|
import tempfile
|
|
import unittest
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
SCRIPT = (ROOT / 'scripts/run-regression-tests').read_text()
|
|
CONFIGURE = re.search(r'^function patch_and_configure_kernel \{\n.*?^\}',
|
|
SCRIPT, re.M | re.S).group()
|
|
COMPILE = re.search(r'^function compile_scst \{\n.*?^\}', SCRIPT, re.M | re.S).group()
|
|
PREAMBLE = SCRIPT.split('function usage', 1)[0]
|
|
PREAMBLE = re.sub(r'^source .*$', '', PREAMBLE, flags=re.M)
|
|
|
|
|
|
class RegressionConfigTests(unittest.TestCase):
|
|
def configure(self, config, reenable=False):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
root = Path(tmp)
|
|
kernel = root / 'linux-4.9'
|
|
kernel.mkdir()
|
|
(root / 'input.config').write_text(config)
|
|
(root / 'scst-4.9-kernel-matching-line-numbers.patch').touch()
|
|
# Exercise the production function; only patch/make are inert.
|
|
harness = '''
|
|
outputdir=$1
|
|
reenable=$2
|
|
multiple_patches=false
|
|
ipv6=true
|
|
kernel_version() { printf '%s\\n' "$1"; }
|
|
patch() { cat >/dev/null; }
|
|
make() {
|
|
case "$*" in
|
|
'-s allmodconfig') cp "$outputdir/input.config" .config ;;
|
|
'-s oldconfig')
|
|
if [ "$reenable" = y ]; then
|
|
sed -i 's/^CONFIG_KUNIT=.*/CONFIG_KUNIT=y/' .config
|
|
fi ;;
|
|
*) return 1 ;;
|
|
esac
|
|
}
|
|
'''
|
|
result = subprocess.run(['bash', '-c', harness + CONFIGURE +
|
|
'\npatch_and_configure_kernel 4.9\n',
|
|
'test-regression', str(root), 'y' if reenable else 'n'],
|
|
capture_output=True, text=True)
|
|
return result, (kernel / '.config').read_text()
|
|
|
|
def test_plain_build_without_unwinder_or_kunit_option(self):
|
|
result, _ = self.configure('CONFIG_FRAME_POINTER=y\n')
|
|
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
|
|
|
|
def test_allmodconfig_kunit_is_disabled(self):
|
|
for mode in ('y', 'm'):
|
|
with self.subTest(mode=mode):
|
|
result, config = self.configure('CONFIG_UNWINDER_FRAME_POINTER=n\n'
|
|
f'CONFIG_KUNIT={mode}\n')
|
|
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
|
|
self.assertIn('CONFIG_KUNIT=n\n', config)
|
|
self.assertIn('CONFIG_UNWINDER_FRAME_POINTER=y\n', config)
|
|
|
|
def test_kconfig_reenabling_kunit_is_rejected(self):
|
|
result, _ = self.configure('CONFIG_KUNIT=m\n', reenable=True)
|
|
self.assertNotEqual(result.returncode, 0)
|
|
self.assertIn('Disabling CONFIG_KUNIT failed.', result.stdout)
|
|
|
|
def test_local_builds_override_inherited_test_options(self):
|
|
harness = '''
|
|
KUNIT_TEST=y
|
|
KUNIT_LOG=y
|
|
CONFIG_SCST_KUNIT_TEST=y
|
|
CONFIG_SCST_KUNIT_LOG=y
|
|
'''
|
|
stub = '''
|
|
make() {
|
|
printf '%s %s %s %s\\n' "$KUNIT_TEST" "$KUNIT_LOG" \\
|
|
"$CONFIG_SCST_KUNIT_TEST" "$CONFIG_SCST_KUNIT_LOG"
|
|
}
|
|
compile_scst
|
|
'''
|
|
result = subprocess.run(['bash', '-c', harness + PREAMBLE + COMPILE + stub],
|
|
capture_output=True, text=True)
|
|
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
|
|
self.assertTrue(result.stdout.splitlines())
|
|
self.assertEqual(set(result.stdout.splitlines()), {'n n n n'})
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|