|
| 1 | +# Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| 2 | +# SPDX-License-Identifier: Apache-2.0 |
| 3 | +"""Tests to collect Firecracker metrics for vhost-user devices.""" |
| 4 | + |
| 5 | +import time |
| 6 | + |
| 7 | +import pytest |
| 8 | + |
| 9 | +import host_tools.drive as drive_tools |
| 10 | +from framework.utils_drive import resize_vhost_user_drive, spawn_vhost_user_backend |
| 11 | + |
| 12 | + |
| 13 | +@pytest.mark.parametrize("vcpu_count", [1, 2], ids=["1vcpu", "2vcpu"]) |
| 14 | +def test_vhost_user_block_metrics( |
| 15 | + microvm_factory, guest_kernel, rootfs_ubuntu_22, vcpu_count, metrics |
| 16 | +): |
| 17 | + """ |
| 18 | + This test tries to boot a VM with vhost-user-block |
| 19 | + as a scratch device, resize the vhost-user scratch drive to have |
| 20 | + config change notifications, collects and then uploads the related |
| 21 | + vhost-user FirecrackerMetrics to Cloudwatch. |
| 22 | + Having vhost-user as root device vs a scratch should not impact metrics, however, |
| 23 | + we choose to have it as a scratch device because we are interested in config change |
| 24 | + metrics which we cannot extract when vhost-user is root device |
| 25 | + (read only rootfs won't have a config change). |
| 26 | + """ |
| 27 | + orig_size = 10 # MB |
| 28 | + # Picked from test_config_change assuming that the intention is to change size from |
| 29 | + # low->high->low->high and so the numbers are not in monotonic sequence. |
| 30 | + new_sizes = [20, 10, 30] # MB |
| 31 | + vhost_user_socket = "/vub.socket" |
| 32 | + |
| 33 | + vm = microvm_factory.build(guest_kernel, rootfs_ubuntu_22, monitor_memory=False) |
| 34 | + vm.spawn(log_level="Info") |
| 35 | + vm.basic_config(vcpu_count=vcpu_count) |
| 36 | + |
| 37 | + # Add a block device to test resizing. |
| 38 | + fs = drive_tools.FilesystemFile(size=orig_size) |
| 39 | + _backend = spawn_vhost_user_backend(vm, fs.path, vhost_user_socket) |
| 40 | + vm.add_vhost_user_drive("scratch", vhost_user_socket) |
| 41 | + vm.start() |
| 42 | + |
| 43 | + # vhost-user-block is activated during boot but it takes a while so we wait. |
| 44 | + # 300msec picked by the limited number of experiments tried to see how long |
| 45 | + # it takes to get the activate_time_us metrics. |
| 46 | + time.sleep(0.3) |
| 47 | + |
| 48 | + metrics.set_dimensions( |
| 49 | + { |
| 50 | + "performance_test": "vhost_user_block_metrics", |
| 51 | + "io_engine": "vhost-user", |
| 52 | + **vm.dimensions, |
| 53 | + } |
| 54 | + ) |
| 55 | + fc_metrics = vm.flush_metrics() |
| 56 | + assert 0 == fc_metrics["vhost_user_block_scratch"]["activate_fails"] |
| 57 | + assert fc_metrics["vhost_user_block_scratch"]["init_time_us"] |
| 58 | + assert fc_metrics["vhost_user_block_scratch"]["activate_time_us"] |
| 59 | + |
| 60 | + metrics.put_metric( |
| 61 | + "init_time_us", |
| 62 | + fc_metrics["vhost_user_block_scratch"]["init_time_us"], |
| 63 | + unit="Microseconds", |
| 64 | + ) |
| 65 | + metrics.put_metric( |
| 66 | + "activate_time_us", |
| 67 | + fc_metrics["vhost_user_block_scratch"]["activate_time_us"], |
| 68 | + unit="Microseconds", |
| 69 | + ) |
| 70 | + |
| 71 | + for new_size in new_sizes: |
| 72 | + # Instruct the backend to resize the device. |
| 73 | + # It will both resize the file and update its device config. |
| 74 | + resize_vhost_user_drive(vm, new_size) |
| 75 | + |
| 76 | + # Instruct Firecracker to reread device config and notify |
| 77 | + # the guest of a config change. |
| 78 | + vm.patch_drive("scratch") |
| 79 | + |
| 80 | + fc_metrics = vm.flush_metrics() |
| 81 | + assert 0 == fc_metrics["vhost_user_block_scratch"]["cfg_fails"] |
| 82 | + assert fc_metrics["vhost_user_block_scratch"]["config_change_time_us"] |
| 83 | + metrics.put_metric( |
| 84 | + "config_change_time_us", |
| 85 | + fc_metrics["vhost_user_block_scratch"]["config_change_time_us"], |
| 86 | + unit="Microseconds", |
| 87 | + ) |
0 commit comments