summaryrefslogtreecommitdiff
path: root/smoketest/scripts/cli
diff options
context:
space:
mode:
authorJohn Estabrook <jestabro@vyos.io>2026-08-21 08:00:50 -0500
committerGitHub <noreply@github.com>2026-08-21 08:00:50 -0500
commit0712fac9dddb4dbfede4409867d2973ccbfb5aa2 (patch)
tree54b01fae4c493735918efb5229b613017521fe74 /smoketest/scripts/cli
parentac99e72affedc97c62d47d2391ade14fd6c2e884 (diff)
parent7b960007e817b722596b7e388577d73ad7a87ed7 (diff)
downloadvyos-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-xsmoketest/scripts/cli/test_system_option.py153
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())