diff options
| author | John Estabrook <jestabro@vyos.io> | 2026-08-21 08:00:50 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-21 08:00:50 -0500 |
| commit | 0712fac9dddb4dbfede4409867d2973ccbfb5aa2 (patch) | |
| tree | 54b01fae4c493735918efb5229b613017521fe74 /smoketest/scripts/cli | |
| parent | ac99e72affedc97c62d47d2391ade14fd6c2e884 (diff) | |
| parent | 7b960007e817b722596b7e388577d73ad7a87ed7 (diff) | |
| download | vyos-1x-0712fac9dddb4dbfede4409867d2973ccbfb5aa2.tar.gz vyos-1x-0712fac9dddb4dbfede4409867d2973ccbfb5aa2.zip | |
Merge pull request #5325 from alexandr-san4ez/T8868-rolling
kdump: T8868: Implement kernel crash dump support
Diffstat (limited to 'smoketest/scripts/cli')
| -rwxr-xr-x | smoketest/scripts/cli/test_system_option.py | 153 |
1 files changed, 152 insertions, 1 deletions
diff --git a/smoketest/scripts/cli/test_system_option.py b/smoketest/scripts/cli/test_system_option.py index f0b3bfb53..2ab27693b 100755 --- a/smoketest/scripts/cli/test_system_option.py +++ b/smoketest/scripts/cli/test_system_option.py @@ -17,22 +17,40 @@ import os import subprocess import unittest +import tempfile from base_vyostest_shim import VyOSUnitTestSHIM from vyos.configsession import ConfigSessionError +from vyos.defaults import systemd_services +from vyos.defaults import KDUMP_DEFAULT_MEMORY_AUTO from vyos.utils.cpu import get_cpus from vyos.utils.file import read_file +from vyos.utils.file import write_file from vyos.utils.process import is_systemd_service_active from vyos.utils.system import sysctl_read from vyos.system import image base_path = ['system', 'option'] +kdump_path = base_path + ['kdump'] + + +def _get_grub_config(): + """Read GRUB config file for current running image""" + return read_file(f'{image.grub.GRUB_DIR_VYOS_VERS}/{image.get_running_image()}.cfg') class TestSystemOption(VyOSUnitTestSHIM.TestCase): + def setUp(self): + self.tmp_path = tempfile.TemporaryDirectory(prefix='system-option-test-') + + # always forward to base class + super().setUp() + def tearDown(self): self.cli_delete(base_path) self.cli_commit() + self.tmp_path.cleanup() + # always forward to base class super().tearDown() @@ -129,7 +147,7 @@ class TestSystemOption(VyOSUnitTestSHIM.TestCase): self.cli_commit() # Read GRUB config file for current running image - tmp = read_file(f'{image.grub.GRUB_DIR_VYOS_VERS}/{image.get_running_image()}.cfg') + tmp = _get_grub_config() self.assertIn(' mitigations=off', tmp) self.assertIn(' intel_idle.max_cstate=0 processor.max_cstate=1', tmp) self.assertIn(' quiet', tmp) @@ -174,6 +192,139 @@ class TestSystemOption(VyOSUnitTestSHIM.TestCase): out = subprocess.check_output(['openssl', 'list', '-providers'], text=True) self.assertNotIn('OpenSSL FIPS Provider', out) + def test_kdump_base(self): + # Test basic kdump functionality + + dump_path = self.tmp_path.name + service = systemd_services['kdump'] + config_file = '/etc/default/kdump-tools' + initramfs_hook = '/etc/initramfs-tools/conf.d/zzzz-kdump-vyos-overlay' + + self.cli_set(kdump_path + ['dump-path', dump_path]) + self.cli_commit() + + self.assertTrue( + os.path.exists(config_file), + 'kdump-tools config file was not created after enabling kdump', + ) + + self.assertTrue( + os.path.exists(initramfs_hook), + 'initramfs conf.d hook was not created after enabling kdump', + ) + + hook_content = read_file(initramfs_hook) + self.assertIn( + 'MODULES=most', + hook_content, + 'initramfs hook must contain MODULES=most to work on OverlayFS root', + ) + + self.assertTrue( + is_systemd_service_active(service), + f'{service} must be active after enabling kdump', + ) + + # Disabling kdump must remove the initramfs conf.d drop-in + self.cli_delete(kdump_path) + self.cli_commit() + + self.assertFalse( + os.path.exists(initramfs_hook), + 'initramfs hook must be removed after disabling kdump', + ) + + self.assertTrue( + os.path.exists(config_file), + 'kdump-tools config file must still exist after disabling kdump', + ) + config_content = read_file(config_file) + self.assertIn( + 'USE_KDUMP=0', + config_content, + 'Disabled kdump-tools config must contain USE_KDUMP=0', + ) + + def test_kdump_memory(self): + # Test memory reservation logic + + memory = '128' + self.cli_set(kdump_path + ['memory', memory]) + self.cli_commit() + + grub_cfg = _get_grub_config() + self.assertIn( + f'crashkernel={memory}', + grub_cfg, + '`crashkernel` value not found in GRUB config after setting explicit memory', + ) + + # Tiered crashkernel= value produced when memory is set to 'auto' + auto_memory = KDUMP_DEFAULT_MEMORY_AUTO + + self.cli_set(kdump_path + ['memory', 'auto']) + self.cli_commit() + + grub_cfg = _get_grub_config() + self.assertIn( + f'crashkernel={auto_memory}', + grub_cfg, + "'memory auto' did not produce the expected tiered `crashkernel` value in GRUB config", + ) + + def test_kdump_memory_error(self): + # Test special cases where invalid memory range values should raise an error + + special_cases = ( + '1', # Invalid low value + '1048570', # ~1TB which often more then available RAM + ) + for case in special_cases: + with self.subTest(case=case): + with self.assertRaises(ConfigSessionError): + self.cli_set(kdump_path + ['memory', case]) + self.cli_commit() + + def test_op_show_kdump_status(self): + # Test operational mode command 'show system kdump' + + result = self.op_mode(['show', 'system', 'kdump']) + self.assertIn('not configured', result) + + memory = '256' + self.cli_set(kdump_path + ['memory', memory]) + self.cli_commit() + + result = self.op_mode(['show', 'system', 'kdump']) + self.assertIn('Crash kernel', result) + self.assertIn(memory, result) + + def test_op_show_kdump_dumps(self): + # Test operational mode command 'show system kdump dumps' + dump_path = self.tmp_path.name + + self.cli_set(kdump_path + ['dump-path', dump_path]) + self.cli_commit() + + result = self.op_mode(['show', 'system', 'kdump', 'dumps']) + self.assertIn('No kernel crash dumps recorded', result) + + timestamp1 = '202607070802' + timestamp2 = '202607070939' + + for ts in (timestamp1, timestamp2): + sub = os.path.join(dump_path, ts) + os.makedirs(sub) + + # Write a small synthetic vmcore so the size check is non-trivial + write_file(os.path.join(sub, f'dump.{ts}'), '0' * 1024) + write_file(os.path.join(sub, f'dmesg.{ts}'), f'synthetic dmesg {ts}') + + result = self.op_mode(['show', 'system', 'kdump', 'dumps']) + + self.assertIn(f'{dump_path}/{timestamp1}', result) + self.assertIn(f'{dump_path}/{timestamp2}', result) + if __name__ == '__main__': unittest.main(verbosity=2, failfast=VyOSUnitTestSHIM.TestCase.debug_on()) |
