Skip to content

Commit

Permalink
test(vmgenid): integration test for VMGenID kernel notification
Browse files Browse the repository at this point in the history
Add an integration test that launches a microVM, snapshots it repeatedly
and checks for the existence of the message that the kernel emits every
time it receives the VMGenID notification.

Signed-off-by: Babis Chalios <bchalios@amazon.es>
  • Loading branch information
bchalios committed Apr 9, 2024
1 parent de1eb0d commit 9a71fba
Showing 1 changed file with 64 additions and 0 deletions.
64 changes: 64 additions & 0 deletions tests/integration_tests/functional/test_snapshot_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import host_tools.drive as drive_tools
from framework.microvm import SnapshotType
from framework.properties import global_props
from framework.utils import check_filesystem, run_cmd, wait_process_termination
from framework.utils_vsock import (
ECHO_SERVER_PORT,
Expand All @@ -25,6 +26,20 @@
start_guest_echo_server,
)

# Kernel emits this message when it resumes from a snapshot with VMGenID device
# present
DMESG_VMGENID_RESUME = "random: crng reseeded due to virtual machine fork"


def check_vmgenid_update_count(vm, resume_count):
"""
Kernel will emit the DMESG_VMGENID_RESUME every time we resume
from a snapshot
"""
rc, stdout, stderr = vm.ssh.run("dmesg")
assert rc == 0, stderr
assert resume_count == stdout.count(DMESG_VMGENID_RESUME)


def _get_guest_drive_size(ssh_connection, guest_dev_name="/dev/vdb"):
# `lsblk` command outputs 2 lines to STDOUT:
Expand Down Expand Up @@ -118,6 +133,7 @@ def test_5_snapshots(
microvm = microvm_factory.build()
microvm.spawn()
microvm.restore_from_snapshot(snapshot, resume=True)

# TODO: SIGCONT here and SIGSTOP later before creating snapshot
# is a temporary fix to avoid vsock timeout in
# _vsock_connect_to_guest(). This will be removed once we
Expand Down Expand Up @@ -187,6 +203,7 @@ def test_patch_drive_snapshot(uvm_nano, microvm_factory):
vm = microvm_factory.build()
vm.spawn()
vm.restore_from_snapshot(snapshot, resume=True)

# Attempt to connect to resumed microvm and verify the new microVM has the
# right scratch drive.
guest_drive_size = _get_guest_drive_size(vm.ssh)
Expand Down Expand Up @@ -495,3 +512,50 @@ def test_snapshot_overwrite_self(guest_kernel, rootfs, microvm_factory):
# restored, with a new snapshot of this vm, does not break the VM
rc, _, stderr = vm.ssh.run("true")
assert rc == 0, stderr


@pytest.mark.parametrize("snapshot_type", [SnapshotType.DIFF, SnapshotType.FULL])
def test_vmgenid(guest_kernel_linux_6_1, rootfs, microvm_factory, snapshot_type):
"""
Test VMGenID device upon snapshot resume
"""
if global_props.cpu_architecture != "x86_64":
pytest.skip("At the moment we only support VMGenID on x86_64")

base_vm = microvm_factory.build(guest_kernel_linux_6_1, rootfs)
base_vm.spawn()
base_vm.basic_config(track_dirty_pages=True)
base_vm.add_net_iface()
base_vm.start()

# Wait for microVM to be booted
rc, _, stderr = base_vm.ssh.run("true")
assert rc == 0, stderr

snapshot = base_vm.make_snapshot(snapshot_type)
base_snapshot = snapshot
base_vm.kill()

for i in range(5):
vm = microvm_factory.build()
vm.spawn()
vm.restore_from_snapshot(snapshot, resume=True)

# Make sure the microVM is up
rc, _, stderr = vm.ssh.run("true")
assert rc == 0, stderr

# We should have as DMESG_VMGENID_RESUME messages as
# snapshots we have resumed
check_vmgenid_update_count(vm, i + 1)

snapshot = vm.make_snapshot(snapshot_type)
vm.kill()

# If we are testing incremental snapshots we ust merge the base with
# current layer.
if snapshot.is_diff:
snapshot = snapshot.rebase_snapshot(base_snapshot)

# Update the base for next iteration
base_snapshot = snapshot

0 comments on commit 9a71fba

Please sign in to comment.