Add premium data-disk performance validation against rated SKU maximum - #4628
Add premium data-disk performance validation against rated SKU maximum#4628SrikanthMyakam (SRIKKANTH) wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds an Azure-only post-run validation step for premium data-disk fio performance tests, comparing measured random-read performance against the VM SKU’s published disk limits so underperforming SKUs fail the test (or are skipped when SKU capabilities aren’t available).
Changes:
- Updated
perf_disk()/perf_premium_datadisks()to return the emittedDiskPerformanceMessagelist so callers can perform additional validation. - Added Azure SKU capability lookup and premium data-disk rated-max validation logic in
common.py. - Wired the new validation into the premium data-disk test cases (4K, 1024K, and io_uring variants).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| lisa/microsoft/testsuites/performance/storageperf.py | Captures fio perf messages and invokes the new rated-max validation for premium data-disk test cases. |
| lisa/microsoft/testsuites/performance/common.py | Returns fio perf messages from helpers and introduces Azure SKU capability lookup + premium data-disk rated-max validation logic/constants. |
Suppressed comments (1)
lisa/microsoft/testsuites/performance/common.py:1107
- The validation loop claims to average random-read across iterations per IO depth, but it currently uses the maximum ("best") sample at each depth. This makes the pass/fail decision more permissive than the stated rule and the PR description.
Compute an average per IO depth (or update the doc/logic consistently) so the check matches the documented behavior.
# The best observed value at this depth (max across iterations).
best = max(randread_by_iodepth[iodepth])
percent_of_rated = best / rated_max * 100
per_depth_percentages.append(percent_of_rated)
log.info(
f"premium data-disk check on {node.name} at iodepth {iodepth}: "
f"best random-read {best:.1f} {rated_unit} = "
f"{percent_of_rated:.1f}% of rated maximum {rated_max:.1f} "
f"{rated_unit} (required >= {pass_percent:.0f}%)."
)
if best < required:
failing_iodepths.append(
f"iodepth {iodepth}: {best:.1f} {rated_unit} "
f"({percent_of_rated:.1f}%)"
)
| environment = test_result.environment | ||
| assert environment, "fail to get environment from testresult" | ||
| node = cast(RemoteNode, environment.nodes[0]) | ||
| log = node.log |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Suppressed comments (2)
lisa/microsoft/testsuites/performance/common.py:1103
- The validation says it averages random-read per IO depth across iterations, but the implementation currently uses the max ("best") sample. This makes the check more permissive than described (and than the PR description) and also contradicts the comment directly above the aggregation loop.
for iodepth in sorted(randread_by_iodepth):
# The best observed value at this depth (max across iterations).
best = max(randread_by_iodepth[iodepth])
percent_of_rated = best / rated_max * 100
per_depth_percentages.append(percent_of_rated)
lisa/microsoft/testsuites/performance/common.py:1031
- Using a bare
assertfortest_result.environmentis unsafe because Python can remove asserts with optimization flags, and this would turn a missing environment into an unhandled downstream error. Prefer an explicit exception with a clear message so the failure mode is consistent in all runs.
environment = test_result.environment
assert environment, "fail to get environment from testresult"
node = cast(RemoteNode, environment.nodes[0])
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Suppressed comments (2)
lisa/microsoft/testsuites/performance/common.py:1100
- The function docstring/comment says the per-IO-depth random-read value is averaged across iterations, but the implementation takes
max(...)(“best”). If multiple samples per IO depth are ever present, this can incorrectly pass underperforming depths. Either compute the mean (and log it as such) or update the docstring/requirements to explicitly validate against the best value.
# The best observed value at this depth (max across iterations).
best = max(randread_by_iodepth[iodepth])
percent_of_rated = best / rated_max * 100
lisa/microsoft/testsuites/performance/common.py:1029
- Using a bare
assertfor the environment check is unsafe (asserts can be stripped with-O) and inconsistent with the repo’s generalassert_that()usage. Prefer an explicitassert_that(...).is_not_none()check and then cast toEnvironmentbefore indexing nodes.
environment = test_result.environment
assert environment, "fail to get environment from testresult"
node = cast(RemoteNode, environment.nodes[0])
AI Test Case SelectionSelected 4 test case(s): perf_premium_datadisks_4k,perf_premium_datadisks_1024k,perf_premium_datadisks_4k_io_uring,perf_premium_datadisks_1024k_io_uring Marketplace image: Result: Canceled |
verify_repository_installed hard-coded `ports.ubuntu.com` as the only valid repository host for every Ubuntu ARM64 image. Ubuntu 26.04 ARM64 (canonical ubuntu-26_04-lts server-arm64) serves packages from `azure.archive.ubuntu.com`, so the hostname check failed even though the image was healthy. Observed on Standard_D2plds_v6 / westus2: AssertionError: [`ports.ubuntu.com`, `security`, `updates` should be in `apt-get update` output] Expected <True>, but was not. Both `apt-get update` runs exited 0 and the resolute-updates and resolute-security pockets were present, so only the host predicate was false. This was a stale test expectation, not an image or network failure. Change the per-architecture map to hold a list of accepted hosts and allow Ubuntu ARM64 to match either `ports.ubuntu.com` or `azure.archive.ubuntu.com`, keeping existing ports-based ARM64 images passing. x64 behavior is unchanged. The assertion message now lists the accepted hosts. Key Test Cases: verify_repository_installed Impacted LISA Features: None Tested Azure Marketplace Images: - canonical ubuntu-24_04-lts server-arm64 latest - canonical 0001-com-ubuntu-server-jammy 22_04-lts-arm64 latest - canonical ubuntu-24_04-lts server latest
ade2002 to
215c861
Compare
AI Test Case SelectionSelected 4 test case(s): perf_premium_datadisks_4k,perf_premium_datadisks_1024k,perf_premium_datadisks_4k_io_uring,perf_premium_datadisks_1024k_io_uring Marketplace image: Result: Canceled |
Add premium data-disk performance validation against rated SKU maximum
Summary
-------
Adds a post-run validation step for the premium data-disk fio performance
tests that compares the measured random-read results against the Azure VM
SKU's rated disk maximum, so the tests fail when a VM under-performs its
published disk limits instead of only recording numbers.
Changes
-------
lisa/microsoft/testsuites/performance/common.py
- Add `_get_azure_sku_capabilities()` to resolve the Azure SKU capability
name/value map for the node's VM size (returns None on non-Azure platforms
or when capabilities are unavailable).
- Add `check_premium_datadisks_performance()` which:
- Ignores IO depths at or below the saturation threshold
(`PREMIUM_DATADISK_MIN_IODEPTH = 8`).
- Averages the random-read value per IO depth across iterations.
- Compares against `UncachedDiskIOPS` for 4K (IOPS-bound) runs and
`UncachedDiskBytesPerSecond` for 1024K (bandwidth-bound) runs, converting
IOPS to bytes/sec via block size where needed.
- Requires every qualifying IO depth to reach at least
`PREMIUM_DATADISK_PASS_RATIO` (95%) of the rated maximum.
- Raise `SkippedException` (not a failure) when rated disk performance or the
required capability is not published for the VM size/platform.
- Derive the pass percentage in log/assertion messages from
`PREMIUM_DATADISK_PASS_RATIO` instead of a hardcoded 95%.
lisa/microsoft/testsuites/performance/storageperf.py
- Capture the messages returned by `perf_premium_datadisks(...)` and invoke
`check_premium_datadisks_performance()` in the 4K, 1024K, and io_uring
(4K/1024K) premium data-disk test cases.
Notes
-----
- The rated-max validation only applies on Azure; other platforms are skipped.
Co-Authored-By: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
043edef to
01507d4
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Suppressed comments (2)
lisa/microsoft/testsuites/performance/common.py:1136
- The docstring/PR description say the random-read value is averaged per IO depth across iterations, but the implementation uses
max(...)(best across iterations). This makes the check less strict than described and the log message is also labeled as "best". Consider using an average to match the stated behavior (or update the docs if "best" is intended).
measured = randread_iops * block_size_bytes
else:
measured = randread_iops
randread_by_iodepth.setdefault(message.iodepth, []).append(measured)
lisa/microsoft/testsuites/performance/common.py:1056
- Avoid using a bare
assertfor runtime validation here; assertions can be stripped with Python optimization flags and will turn this into an AttributeError later. Prefer an explicit check that raisesLisaExceptionwith context.
The validation can be turned off from the runbook with the shared
``enable_perf_check`` variable.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Suppressed comments (3)
lisa/microsoft/testsuites/performance/common.py:1152
- The per-IO-depth value is documented as an average across iterations, but the implementation uses the maximum sample (
max(...)) and logs it as "best". This can hide under-performance (passes if any single iteration spikes) and contradicts both the docstring and the PR description. Compute the mean for each IO depth and use that for the comparison/logging.
for iodepth in sorted(randread_by_iodepth):
# The best observed value at this depth (max across iterations).
best = max(randread_by_iodepth[iodepth])
percent_of_rated = best / rated_max * 100
per_depth_percentages.append(percent_of_rated)
lisa/microsoft/testsuites/performance/common.py:1073
- This uses a bare
assertto validatetest_result.environment. Python assertions can be stripped with optimization flags and don't provide a great failure message for test runs. Prefer an explicit exception (or an assertpy check) so the failure is always enforced and actionable.
environment = test_result.environment
assert environment, "fail to get environment from testresult"
node = cast(RemoteNode, environment.nodes[0])
lisa/microsoft/testsuites/core/azure_image_standard.py:858
- The assertion message currently interpolates the Python list (
repo_urls) directly, which produces a noisy representation (brackets/quotes) in failure output. Joining into a human-readable string makes failures easier to interpret.
assert_that(
is_repository_configured_correctly,
f"one of `{repo_urls}`, `security`, "
"`updates` should be in `apt-get "
"update` output",
AI Test Case SelectionSelected 1 test case(s): verify_repository_installed Marketplace image: Result: Succeeded |
Summary
Adds a post-run validation step for the premium data-disk fio performance tests that compares the measured random-read results against the Azure VM SKU's rated disk maximum, so the tests fail when a VM under-performs its published disk limits instead of only recording numbers.
Changes
lisa/microsoft/testsuites/performance/common.py
_get_azure_sku_capabilities()to resolve the Azure SKU capability name/value map for the node's VM size (returns None on non-Azure platforms or when capabilities are unavailable).check_premium_datadisks_performance()which:PREMIUM_DATADISK_MIN_IODEPTH = 8).UncachedDiskIOPSfor 4K (IOPS-bound) runs andUncachedDiskBytesPerSecondfor 1024K (bandwidth-bound) runs, converting IOPS to bytes/sec via block size where needed.PREMIUM_DATADISK_PASS_RATIO(95%) of the rated maximum.SkippedException(not a failure) when rated disk performance or the required capability is not published for the VM size/platform.PREMIUM_DATADISK_PASS_RATIOinstead of a hardcoded 95%.lisa/microsoft/testsuites/performance/storageperf.py
perf_premium_datadisks(...)and invokecheck_premium_datadisks_performance()in the 4K, 1024K, and io_uring (4K/1024K) premium data-disk test cases.Notes
Description
Related Issue
Type of Change
Checklist
Test Validation
Key Test Cases:
perf_tcp_ntttcp_sriov
Impacted LISA Features:
Tested Azure Marketplace Images:
Test Results