diff --git a/src/firecracker/src/main.rs b/src/firecracker/src/main.rs index cf95ff1f9953..682f4c974762 100644 --- a/src/firecracker/src/main.rs +++ b/src/firecracker/src/main.rs @@ -83,6 +83,7 @@ impl From for ExitCode { MainError::InvalidLogLevel(_) => FcExitCode::BadConfiguration, MainError::RunWithApi(ApiServerError::MicroVMStoppedWithoutError(code)) => code, MainError::RunWithApi(ApiServerError::MicroVMStoppedWithError(code)) => code, + MainError::RunWithoutApiError(RunWithoutApiError::Shutdown(code)) => code, _ => FcExitCode::GenericError, }; diff --git a/tests/framework/vm_config.json b/tests/framework/vm_config.json index 718305890c88..ea50ccb5bfab 100644 --- a/tests/framework/vm_config.json +++ b/tests/framework/vm_config.json @@ -1,33 +1,34 @@ { - "boot-source": { - "kernel_image_path": "vmlinux.bin", - "boot_args": "console=ttyS0 reboot=k panic=1 pci=off", - "initrd_path": null - }, - "drives": [ - { - "drive_id": "rootfs", - "path_on_host": "bionic.rootfs.ext4", - "is_root_device": true, - "partuuid": null, - "is_read_only": false, - "cache_type": "Unsafe", - "io_engine": "Sync", - "rate_limiter": null - } - ], - "machine-config": { - "vcpu_count": 2, - "mem_size_mib": 1024, - "smt": false, - "track_dirty_pages": false - }, - "cpu-config": null, - "balloon": null, - "network-interfaces": [], - "vsock": null, - "logger": null, - "metrics": null, - "mmds-config": null, - "entropy": null -} + "boot-source": { + "kernel_image_path": "vmlinux.bin", + "boot_args": "console=ttyS0 reboot=k panic=1 pci=off", + "initrd_path": null + }, + "drives": [ + { + "drive_id": "rootfs", + "path_on_host": "bionic.rootfs.ext4", + "is_root_device": true, + "partuuid": null, + "is_read_only": false, + "cache_type": "Unsafe", + "io_engine": "Sync", + "rate_limiter": null + } + ], + "machine-config": { + "vcpu_count": 2, + "mem_size_mib": 1024, + "smt": false, + "track_dirty_pages": false + }, + "cpu-config": null, + "balloon": null, + "network-interfaces": [], + "vsock": null, + "logger": null, + "metrics": null, + "mmds-config": null, + "entropy": null + } + \ No newline at end of file diff --git a/tests/framework/vm_config_network.json b/tests/framework/vm_config_network.json new file mode 100644 index 000000000000..64c5fca511ec --- /dev/null +++ b/tests/framework/vm_config_network.json @@ -0,0 +1,42 @@ +{ + "boot-source": { + "kernel_image_path": "vmlinux.bin", + "boot_args": "console=ttyS0 reboot=k panic=1 pci=off", + "initrd_path": null + }, + "drives": [ + { + "drive_id": "rootfs", + "path_on_host": "bionic.rootfs.ext4", + "is_root_device": true, + "partuuid": null, + "is_read_only": false, + "cache_type": "Unsafe", + "io_engine": "Sync", + "rate_limiter": null + } + ], + "machine-config": { + "vcpu_count": 2, + "mem_size_mib": 1024, + "smt": false, + "track_dirty_pages": false + }, + "cpu-config": null, + "balloon": null, + "network-interfaces": [ + { + "iface_id": "1", + "host_dev_name": "tap0", + "guest_mac": "06:00:c0:a8:00:02", + "rx_rate_limiter": null, + "tx_rate_limiter": null + } + ], + "vsock": null, + "logger": null, + "metrics": null, + "mmds-config": null, + "entropy": null + } + \ No newline at end of file diff --git a/tests/integration_tests/functional/test_cmd_line_start.py b/tests/integration_tests/functional/test_cmd_line_start.py index 3c2a3750a763..0066f919360f 100644 --- a/tests/integration_tests/functional/test_cmd_line_start.py +++ b/tests/integration_tests/functional/test_cmd_line_start.py @@ -7,6 +7,7 @@ import platform import re import shutil +import time from pathlib import Path import pytest @@ -156,6 +157,26 @@ def test_config_start_no_api(uvm_plain, vm_config_file): ) +@pytest.mark.parametrize("vm_config_file", ["framework/vm_config_network.json"]) +def test_config_start_no_api_exit(uvm_plain, vm_config_file): + """ + Test microvm exit when API server is disabled. + """ + test_microvm = uvm_plain + _configure_vm_from_json(test_microvm, vm_config_file) + _configure_network_interface(test_microvm) + test_microvm.jailer.extra_args.update({"no-api": None}) + + test_microvm.spawn() # Start Firecracker and MicroVM + time.sleep(3) + test_microvm.ssh.run("reboot") # Exit + + # Check error log + test_microvm.check_log_message( + "RunWithoutApiError error: MicroVMStopped without an error: Ok" + ) + + @pytest.mark.parametrize( "vm_config_file", [