Skip to content

Debug Tests ​

This guide explains how to troubleshoot and debug Garden Linux tests when they fail or behave unexpectedly.

Debugging Approaches ​

The test framework provides several debugging approaches:

  • Debug logs - Understand what the test framework and plugins are doing internally
  • Login scripts - Interactively investigate the test environment (QEMU VMs or cloud instances)
  • Dev mode - Rapidly iterate on tests with automatic synchronization
  • Manual test execution - Run tests directly inside the test environment

Choose the approach based on your needs: inspect framework behavior, investigate system state, or manually verify test conditions.

Debug Logs ​

Enable debug-level logging to see detailed information about plugin operations, system interactions, and test execution flow.

Enable Debug Logging ​

Enable debug logging for all components:

bash
./test --test-args "--log-cli-level=DEBUG" .build/image.raw

Enable debug logging for a specific test:

bash
./test --test-args "--log-cli-level=DEBUG test_ssh.py" .build/image.raw

:::important Tests need to implement debug output. Results may vary depending on the test. :::

Debug Output in Tests ​

For information on adding debug output to tests, see Developing Tests.

Login Scripts ​

Use login scripts to access running VMs for interactive investigation. Once connected, you can explore the filesystem, check service status, examine logs, and run tests manually.

QEMU Environment ​

Connect to a running QEMU VM:

bash
# Get an SSH session
./util/login_qemu.sh

# Get an SSH session with custom user
./util/login_qemu.sh --user admin

# Execute a command directly
./util/login_qemu.sh "uname -a"

# Run tests manually after login
cd /run/gardenlinux-tests && ./run_tests --system-booted --allow-system-modifications --expected-users gardenlinux

# Run tests with sudo if you need root privileges
cd /run/gardenlinux-tests && sudo ./run_tests --system-booted --allow-system-modifications --expected-users gardenlinux

:::important Login to QEMU VMs is only possible if --ssh --skip-cleanup is passed when starting the test. Secure Shell Daemon (SSHD) is reachable on 127.0.0.1:2222 with the user gardenlinux. The QEMU VM stays open in the shell that started the test and can be stopped with ctrl + c. :::

Common debugging workflow:

  1. Start tests with --ssh --skip-cleanup to keep the VM running
  2. In a separate terminal, use ./util/login_qemu.sh to connect
  3. Investigate the system state, check logs, or run tests manually
  4. Return to the original terminal and stop the VM with ctrl + c when done

Cloud Environment ​

Connect to a cloud VM:

bash
# Basic SSH connection
./util/login_cloud.sh .build/aws-gardener_prod-amd64-today-13371337.raw

# Execute a command directly
./util/login_cloud.sh .build/aws-gardener_prod-amd64-today-13371337.raw "uname -a"

# Run tests manually after login
cd /run/gardenlinux-tests && ./run_tests --system-booted --allow-system-modifications --expected-users gardenlinux

# Run tests with sudo if you need root privileges
cd /run/gardenlinux-tests && sudo ./run_tests --system-booted --allow-system-modifications --expected-users gardenlinux

:::important Cloud VMs use the SSH user and Internet Protocol (IP) address from the OpenTofu output. The login script automatically retrieves this information from the Terraform state. :::

Common debugging workflow:

  1. Start tests with --skip-cleanup to keep the cloud instance running
  2. Use ./util/login_cloud.sh with the image file to connect
  3. Investigate the system state, check logs, or run tests manually
  4. Re-run tests without --skip-cleanup or use --only-cleanup to clean up resources when done

Dev Mode (Rapid Iteration) ​

Use the --dev flag to quickly iterate on tests with automatic file synchronization and re-execution.

QEMU Dev Mode ​

Start a QEMU VM in dev mode:

bash
./test --dev .build/aws-gardener_prod-amd64-today-local.raw

With specific tests:

bash
./test --dev --test-args "test_ssh.py -v" .build/aws-gardener_prod-amd64-today-local.raw

What happens:

  1. Starts a QEMU VM
  2. Syncs .build/dist.tar.gz into the VM
  3. Syncs the current tests/ tree
  4. Runs pytest inside the VM with the provided --test-args
  5. Waits for file changes in tests/ and features/
  6. Re-syncs changed tests into the VM
  7. Re-runs pytest with your given arguments after each change

Stop watch mode at any time with Ctrl+C.

:::note --dev is shorthand for --ssh --skip-cleanup --skip-tests --watch. :::

Cloud Dev Mode ​

Start a cloud VM in dev mode:

bash
./test --dev --cloud azure .build/azure-gardener_prod-amd64-today-local.raw

Or use an already uploaded image:

bash
./test --dev --cloud azure \
  --cloud-image --image-requirements-file .build/azure-gardener_prod-amd64-today-local.requirements \
  /CommunityGalleries/gardenlinux-13e998fe-534d-4b0a-8a27-f16a73aef620/Images/gardenlinux-nvme-gardener_prod-amd64/Versions/2150.0.0

With specific tests:

bash
./test --dev --cloud azure --test-args "test_ssh.py -v" .build/image.raw

What happens:

  1. Deploys a cloud VM
  2. Syncs .build/dist.tar.gz into the VM
  3. Syncs the current tests/ tree
  4. Runs pytest inside the VM with the provided --test-args
  5. Waits for file changes in tests/ and features/
  6. Re-syncs changed tests into the VM
  7. Re-runs pytest with your given arguments after each change

Stop watch mode at any time with Ctrl+C.

:::note --dev is shorthand for --skip-cleanup --skip-tests --watch in cloud mode. :::

Chroot Dev Mode ​

The --dev flag works the same way in chroot environments:

bash
./test --dev .build/image.tar

Common Debugging Scenarios ​

Test Fails Unexpectedly ​

  1. Enable debug logging to see what is happening:

    bash
    ./test --test-args "--log-cli-level=DEBUG test_failing.py" .build/image.raw
  2. Run the test in isolation to rule out dependencies:

    bash
    ./test --test-args "test_failing.py::test_specific_function -v" .build/image.raw
  3. Use dev mode to iterate quickly:

    bash
    ./test --dev --test-args "test_failing.py -v" .build/image.raw

Test Passes Locally But Fails in Continuous Integration (CI) ​

  1. Test in the same environment as CI (cloud testing):

    bash
    ./test --cloud aws .build/image.raw
  2. Check for environment-specific issues (markers, dependencies)

  3. Enable debug logging in CI by modifying test arguments

Need to Inspect System State ​

  1. Start VM with cleanup disabled:

    bash
    ./test --ssh --skip-cleanup .build/image.raw
  2. Login to inspect:

    bash
    ./util/login_qemu.sh
  3. Check logs, services, files:

    bash
    journalctl -xe
    systemctl status
    ls -la /etc/

Test Takes Too Long to Run ​

  1. Run only the specific test:

    bash
    ./test --test-args "test_specific.py" .build/image.raw
  2. Use chroot for faster iteration (if applicable):

    bash
    ./test .build/image.tar
  3. Skip expensive tests during development:

    bash
    ./test --test-args "-m 'not slow'" .build/image.raw

Troubleshooting Tips ​

Connection Issues ​

If you cannot connect to a VM:

  • Verify --ssh flag is used for QEMU
  • Check that --skip-cleanup is used
  • Verify VM is still running
  • Check firewall rules for cloud VMs

File Synchronization Issues in Dev Mode ​

If changes are not synced in dev mode:

  • Ensure files are saved
  • Check file paths match expected locations
  • Verify inotify-tools is installed
  • Look for errors in the watch mode output

Permission Issues ​

If tests fail with permission errors:

  • Check if tests require root privileges (should use @pytest.mark.root)
  • Use sudo when running tests manually if needed
  • Verify file permissions in the test environment

Test Environment Differences ​

If tests behave differently across environments:

  • Check test markers (@pytest.mark.booted, @pytest.mark.feature)
  • Verify the test is appropriate for the environment
  • Check for environment-specific configurations