コード例 #1
0
def test_load_snapshot_failure_handling(test_microvm_with_api):
    """
    Test error case of loading empty snapshot files.

    @type: functional
    """
    logger = logging.getLogger("snapshot_load_failure")
    vm = test_microvm_with_api
    vm.spawn(log_level="Info")

    # Create two empty files for snapshot state and snapshot memory
    chroot_path = vm.jailer.chroot_path()
    snapshot_dir = os.path.join(chroot_path, "snapshot")
    Path(snapshot_dir).mkdir(parents=True, exist_ok=True)

    snapshot_mem = os.path.join(snapshot_dir, "snapshot_mem")
    open(snapshot_mem, "w+", encoding="utf-8").close()
    snapshot_vmstate = os.path.join(snapshot_dir, "snapshot_vmstate")
    open(snapshot_vmstate, "w+", encoding="utf-8").close()

    # Hardlink the snapshot files into the microvm jail.
    jailed_mem = vm.create_jailed_resource(snapshot_mem)
    jailed_vmstate = vm.create_jailed_resource(snapshot_vmstate)

    # Load the snapshot
    response = vm.snapshot.load(mem_file_path=jailed_mem,
                                snapshot_path=jailed_vmstate)

    logger.info("Response status code %d, content: %s.", response.status_code,
                response.text)
    assert vm.api_session.is_status_bad_request(response.status_code)
    assert "Cannot deserialize the microVM state" in response.text

    # Check if FC process is closed
    wait_process_termination(vm.jailer_clone_pid)
コード例 #2
0
def test_enosys_error_code(test_microvm_with_initrd):
    """
    Test that ENOSYS error is caught and firecracker exits gracefully.

    @type: functional
    """
    # On aarch64 we trigger this error by adding to initrd a C program that
    # maps a file into memory and then tries to load the content from an
    # offset in the file bigger than its length into a register asm volatile
    # ("ldr %0, [%1], 4" : "=r" (ret), "+r" (buf));
    vm = test_microvm_with_initrd
    vm.jailer.daemonize = False
    vm.spawn()
    vm.memory_monitor = None

    vm.initrd_file = os.path.join(vm.path, "fsfiles/", "initrd_enosys.img")
    vm.basic_config(add_root_device=False,
                    vcpu_count=1,
                    boot_args='console=ttyS0 reboot=k panic=1 pci=off',
                    use_initrd=True)

    vm.start()

    # Check if FC process is closed
    wait_process_termination(vm.jailer_clone_pid)

    vm.check_log_message("Received ENOSYS error because KVM failed to"
                         " emulate an instruction.")
    vm.check_log_message("Vmm is stopping.")
コード例 #3
0
def test_generic_signal_handler(test_microvm_with_api, signum):
    """
    Test signal handling for all handled signals.

    @type: functional
    """
    microvm = test_microvm_with_api
    microvm.spawn()

    # We don't need to monitor the memory for this test.
    microvm.memory_monitor = None

    microvm.basic_config()

    # Configure metrics based on a file.
    metrics_path = os.path.join(microvm.path, 'metrics_fifo')
    utils.run_cmd("touch {}".format(metrics_path))
    response = microvm.metrics.put(
        metrics_path=microvm.create_jailed_resource(metrics_path)
    )
    assert microvm.api_session.is_status_no_content(response.status_code)

    microvm.start()
    firecracker_pid = int(microvm.jailer_clone_pid)
    sleep(0.5)

    metrics_jail_path = os.path.join(microvm.chroot(), metrics_path)
    metrics_fd = open(metrics_jail_path, encoding='utf-8')

    line_metrics = metrics_fd.readlines()
    assert len(line_metrics) == 1

    os.kill(firecracker_pid, signum)
    # Firecracker gracefully handles SIGPIPE (doesn't terminate).
    if signum == int(SIGPIPE):
        msg = 'Received signal 13'
        # Flush metrics to file, so we can see the SIGPIPE at bottom assert.
        # This is going to fail if process has exited.
        response = microvm.actions.put(action_type='FlushMetrics')
        assert microvm.api_session.is_status_no_content(response.status_code)
    else:
        microvm.expect_kill_by_signal = True
        # Ensure that the process was terminated.
        utils.wait_process_termination(firecracker_pid)
        msg = 'Shutting down VM after intercepting signal {}'.format(signum)

    microvm.check_log_message(msg)

    if signum != SIGSYS:
        metric_line = json.loads(metrics_fd.readlines()[0])
        assert metric_line["signals"][signum_str[signum]] == 1
コード例 #4
0
def test_load_snapshot_failure_handling(test_microvm_with_api):
    """
    Test scenario.

    1. Create two empty files representing snapshot memory and
    microvm state
    2. Try to load a VM snapshot out of the empty files.
    3. Verify that an error was shown and the FC process is terminated.
    """
    logger = logging.getLogger("snapshot_load_failure")
    vm = test_microvm_with_api
    vm.spawn(log_level='Info')

    # Create two empty files for snapshot state and snapshot memory
    chroot_path = vm.jailer.chroot_path()
    snapshot_dir = os.path.join(chroot_path, "snapshot")
    Path(snapshot_dir).mkdir(parents=True, exist_ok=True)

    snapshot_mem = os.path.join(snapshot_dir, "snapshot_mem")
    open(snapshot_mem, "w+").close()
    snapshot_vmstate = os.path.join(snapshot_dir, "snapshot_vmstate")
    open(snapshot_vmstate, "w+").close()

    # Hardlink the snapshot files into the microvm jail.
    jailed_mem = vm.create_jailed_resource(snapshot_mem)
    jailed_vmstate = vm.create_jailed_resource(snapshot_vmstate)

    # Load the snapshot
    response = vm.snapshot.load(mem_file_path=jailed_mem,
                                snapshot_path=jailed_vmstate)

    logger.info("Response status code %d, content: %s.",
                response.status_code,
                response.text)
    assert vm.api_session.is_status_bad_request(response.status_code)
    assert "Cannot deserialize MicrovmState" in response.text

    # Check if FC process is closed
    wait_process_termination(vm.jailer_clone_pid)