1# Run with: nix-build -A nixosTests.nixos-test-driver.console-log 2{ 3 name = "nixos-test-driver.console-log"; 4 5 nodes = { 6 machine = { 7 # Configure the machine to print some distinctive messages to console 8 boot.kernelParams = [ "console=ttyS0,115200n8" ]; 9 10 # TODO: add a system service that logs to /dev/console, and test that 11 # blocked on https://github.com/NixOS/nixpkgs/issues/442382 12 }; 13 }; 14 15 testScript = '' 16 # Start the machine and wait for it to boot 17 machine.start() 18 machine.wait_for_unit("multi-user.target") 19 20 with subtest("get_console_log returns console output"): 21 # Get the console log 22 console_log = machine.get_console_log() 23 # Verify it's a non-empty string 24 assert isinstance(console_log, str), f"Expected string, got {type(console_log)}" 25 assert len(console_log) > 0, "Console log should not be empty" 26 27 print(f"Console log length: {len(console_log)} characters") 28 print("Console log preview (first 500 chars):") 29 print(console_log[:500]) 30 31 with subtest("console log contains boot messages"): 32 # Check for typical boot messages 33 assert "systemd" in console_log, "Console log should contain systemd messages" 34 35 # Test direct stderr capture 36 machine.succeed("echo 'DIRECT_TEST_MESSAGE_12345' >&2") 37 import time 38 time.sleep(1) 39 40 updated_log = machine.get_console_log() 41 assert "DIRECT_TEST_MESSAGE_12345" in updated_log, "Console log should capture stderr messages" 42 print("Successfully captured stderr message in console log") 43 44 with subtest("console log captures command output"): 45 # Execute a command that prints to console via kernel messages 46 machine.succeed("echo 'KERNEL_TEST_MESSAGE_12345' > /dev/kmsg") 47 48 # Wait a moment for the message to be captured 49 import time 50 time.sleep(2) 51 52 # Get updated console log 53 updated_log = machine.get_console_log() 54 if "KERNEL_TEST_MESSAGE_12345" in updated_log: 55 print("Successfully captured kernel message in console log") 56 else: 57 print("Kernel message not found in console log - this may be expected depending on log level") 58 59 with subtest("console log persists across multiple calls"): 60 # Get console log twice and verify they're consistent 61 log1 = machine.get_console_log() 62 log2 = machine.get_console_log() 63 64 # Both logs should contain the same content (log2 might have additional content) 65 assert "systemd" in log1, "First log should contain systemd messages" 66 assert "systemd" in log2, "Second log should contain systemd messages" 67 assert len(log2) >= len(log1), "Second log should be at least as long as first log" 68 assert "KERNEL_TEST_MESSAGE_12345" in log2, "Second log should contain our kernel test message" 69 70 with subtest("console log contains kernel messages"): 71 # Look for typical kernel boot messages 72 kernel_indicators = ["Linux version", "Command line:", "Kernel command line"] 73 kernel_found = any(indicator in console_log for indicator in kernel_indicators) 74 assert kernel_found, f"Console log should contain kernel messages. Indicators checked: {kernel_indicators}" 75 76 with subtest("console log is cleared on machine restart"): 77 # Get the current console log and verify it contains our test messages 78 pre_shutdown_log = machine.get_console_log() 79 assert "KERNEL_TEST_MESSAGE_12345" in pre_shutdown_log, "Pre-shutdown log should contain our kernel test message" 80 assert "DIRECT_TEST_MESSAGE_12345" in pre_shutdown_log, "Pre-shutdown log should contain our stderr test message" 81 pre_shutdown_length = len(pre_shutdown_log) 82 print(f"Pre-shutdown console log length: {pre_shutdown_length} characters") 83 84 # Shutdown the machine 85 machine.shutdown() 86 87 # Start the machine again 88 machine.start() 89 machine.wait_for_unit("multi-user.target") 90 91 # Get the console log after restart 92 post_restart_log = machine.get_console_log() 93 post_restart_length = len(post_restart_log) 94 print(f"Post-restart console log length: {post_restart_length} characters") 95 96 # Verify the old messages are gone (log should be fresh) 97 assert "KERNEL_TEST_MESSAGE_12345" not in post_restart_log, "Post-restart log should not contain old kernel test message" 98 assert "DIRECT_TEST_MESSAGE_12345" not in post_restart_log, "Post-restart log should not contain old stderr test message" 99 100 # Verify we still have boot messages (log should contain new boot sequence) 101 assert "systemd" in post_restart_log, "Post-restart log should contain systemd messages from new boot" 102 kernel_found_restart = any(indicator in post_restart_log for indicator in kernel_indicators) 103 assert kernel_found_restart, "Post-restart log should contain kernel messages from new boot" 104 105 # Add a new test message to verify the log is working after restart 106 machine.succeed("echo 'POST_RESTART_TEST_MESSAGE_67890' > /dev/kmsg") 107 import time 108 time.sleep(1) 109 110 final_log = machine.get_console_log() 111 assert "POST_RESTART_TEST_MESSAGE_67890" in final_log, "Should capture new messages after restart" 112 113 print("Console log successfully cleared on restart and is functional again") 114 115 print("All console log tests passed successfully!") 116 ''; 117}