Skip to content

Commit 00ae82a

Browse files
committed
test: Only emit metrics from PR CI perf tests
The snapshot performance tests where regressions are critical have been moved to the nightly CI, where we will get notified by our nightly infrastructure. The remaining (creation latency and resume of old snapshot versions) scenarios are either not on any hotpath (creation) or simply not used by anymore. Since these tests are also known for being very flaky in our CI, make them only emit metrics, but otherwise infallible. Signed-off-by: Patrick Roy <[email protected]>
1 parent 1dc5fc3 commit 00ae82a

File tree

1 file changed

+31
-148
lines changed

1 file changed

+31
-148
lines changed

tests/integration_tests/performance/test_snapshot_perf.py

Lines changed: 31 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -11,150 +11,36 @@
1111

1212
import host_tools.logging as log_tools
1313
from framework.artifacts import NetIfaceConfig
14-
from framework.builder import MicrovmBuilder, SnapshotBuilder, SnapshotType
15-
from framework.stats import consumer, criteria, function, producer, types
16-
from framework.utils import CpuMap, eager_map, get_kernel_version
17-
from framework.utils_cpuid import get_instance_type
14+
from framework.builder import MicrovmBuilder, SnapshotBuilder
15+
from framework.stats import consumer, producer, types
16+
from framework.utils import CpuMap
1817

1918
# How many latencies do we sample per test.
2019
SAMPLE_COUNT = 3
2120
USEC_IN_MSEC = 1000
2221
PLATFORM = platform.machine()
2322

24-
25-
# Latencies in milliseconds.
26-
# The latency for snapshot creation has high variance due to scheduler noise.
27-
# The issue is tracked here:
28-
# https://github.com/firecracker-microvm/firecracker/issues/2346
29-
# TODO: Update baseline values after fix.
30-
CREATE_LATENCY_BASELINES = {
31-
("x86_64", "2vcpu_256mb.json", "FULL"): 180,
32-
("x86_64", "2vcpu_256mb.json", "DIFF"): 70,
33-
("x86_64", "2vcpu_512mb.json", "FULL"): 280,
34-
("x86_64", "2vcpu_512mb.json", "DIFF"): 90,
35-
("aarch64", "2vcpu_256mb.json", "FULL"): 160,
36-
("aarch64", "2vcpu_256mb.json", "DIFF"): 70,
37-
("aarch64", "2vcpu_512mb.json", "FULL"): 300,
38-
("aarch64", "2vcpu_512mb.json", "DIFF"): 75,
39-
}
40-
41-
# The latencies for x86 are pretty high due to a design
42-
# in the cgroups V1 implementation in the kernel. We recommend
43-
# switching to cgroups v2 for much lower snap resume latencies.
44-
# More details on this:
45-
# https://github.com/firecracker-microvm/firecracker/issues/2027
46-
# Latencies for snap resume on cgroups V2 can be found in our
47-
# long-running performance configs (i.e. integration_tests/performance/configs).
48-
LOAD_LATENCY_BASELINES = {
49-
("m5d.metal", "4.14", "sync", "2vcpu_256mb.json"): 9,
50-
("m5d.metal", "4.14", "sync", "2vcpu_512mb.json"): 9,
51-
("m5d.metal", "5.10", "sync", "2vcpu_256mb.json"): 70,
52-
("m5d.metal", "5.10", "sync", "2vcpu_512mb.json"): 90,
53-
("m5d.metal", "5.10", "async", "2vcpu_256mb.json"): 210,
54-
("m5d.metal", "5.10", "async", "2vcpu_512mb.json"): 210,
55-
("m5d.metal", "6.1", "sync", "2vcpu_256mb.json"): 255,
56-
("m5d.metal", "6.1", "sync", "2vcpu_512mb.json"): 245,
57-
("m5d.metal", "6.1", "async", "2vcpu_256mb.json"): 245,
58-
("m5d.metal", "6.1", "async", "2vcpu_512mb.json"): 225,
59-
("m6a.metal", "4.14", "sync", "2vcpu_256mb.json"): 15,
60-
("m6a.metal", "4.14", "sync", "2vcpu_512mb.json"): 19,
61-
("m6a.metal", "5.10", "sync", "2vcpu_256mb.json"): 75,
62-
("m6a.metal", "5.10", "sync", "2vcpu_512mb.json"): 75,
63-
("m6a.metal", "5.10", "async", "2vcpu_256mb.json"): 220,
64-
("m6a.metal", "5.10", "async", "2vcpu_512mb.json"): 220,
65-
("m6a.metal", "6.1", "sync", "2vcpu_256mb.json"): 250,
66-
("m6a.metal", "6.1", "sync", "2vcpu_512mb.json"): 250,
67-
("m6a.metal", "6.1", "async", "2vcpu_256mb.json"): 250,
68-
("m6a.metal", "6.1", "async", "2vcpu_512mb.json"): 300,
69-
("m6i.metal", "4.14", "sync", "2vcpu_256mb.json"): 9,
70-
("m6i.metal", "4.14", "sync", "2vcpu_512mb.json"): 9,
71-
("m6i.metal", "5.10", "sync", "2vcpu_256mb.json"): 70,
72-
("m6i.metal", "5.10", "sync", "2vcpu_512mb.json"): 70,
73-
("m6i.metal", "5.10", "async", "2vcpu_256mb.json"): 245,
74-
("m6i.metal", "5.10", "async", "2vcpu_512mb.json"): 245,
75-
("m6i.metal", "6.1", "sync", "2vcpu_256mb.json"): 220,
76-
("m6i.metal", "6.1", "sync", "2vcpu_512mb.json"): 250,
77-
("m6i.metal", "6.1", "async", "2vcpu_256mb.json"): 220,
78-
("m6i.metal", "6.1", "async", "2vcpu_512mb.json"): 220,
79-
("m6g.metal", "4.14", "sync", "2vcpu_256mb.json"): 3,
80-
("m6g.metal", "4.14", "sync", "2vcpu_512mb.json"): 3,
81-
("m6g.metal", "5.10", "sync", "2vcpu_256mb.json"): 3,
82-
("m6g.metal", "5.10", "sync", "2vcpu_512mb.json"): 3,
83-
("m6g.metal", "5.10", "async", "2vcpu_256mb.json"): 320,
84-
("m6g.metal", "5.10", "async", "2vcpu_512mb.json"): 380,
85-
("m6g.metal", "6.1", "sync", "2vcpu_256mb.json"): 2,
86-
("m6g.metal", "6.1", "sync", "2vcpu_512mb.json"): 3,
87-
("m6g.metal", "6.1", "async", "2vcpu_256mb.json"): 2,
88-
("m6g.metal", "6.1", "async", "2vcpu_512mb.json"): 3,
89-
("c7g.metal", "4.14", "sync", "2vcpu_256mb.json"): 2,
90-
("c7g.metal", "4.14", "sync", "2vcpu_512mb.json"): 2,
91-
("c7g.metal", "5.10", "sync", "2vcpu_256mb.json"): 2,
92-
("c7g.metal", "5.10", "sync", "2vcpu_512mb.json"): 3,
93-
("c7g.metal", "5.10", "async", "2vcpu_256mb.json"): 320,
94-
("c7g.metal", "5.10", "async", "2vcpu_512mb.json"): 360,
95-
("c7g.metal", "6.1", "sync", "2vcpu_256mb.json"): 2,
96-
("c7g.metal", "6.1", "sync", "2vcpu_512mb.json"): 3,
97-
("c7g.metal", "6.1", "async", "2vcpu_256mb.json"): 2,
98-
("c7g.metal", "6.1", "async", "2vcpu_512mb.json"): 3,
99-
}
100-
101-
102-
def snapshot_create_measurements(vm_type, snapshot_type):
103-
"""Define measurements for snapshot create tests."""
104-
lower_than = {
105-
"target": CREATE_LATENCY_BASELINES[
106-
platform.machine(),
107-
vm_type,
108-
"FULL" if snapshot_type == SnapshotType.FULL else "DIFF",
109-
]
110-
}
111-
112-
latency = types.MeasurementDef.create_measurement(
113-
"latency",
114-
"ms",
115-
[function.Max("max")],
116-
{"max": criteria.LowerThan(lower_than)},
117-
)
118-
119-
return [latency]
23+
# measurement without pass criteria = test is infallible but still submits metrics. Nice!
24+
LATENCY_MEASUREMENT = types.MeasurementDef.create_measurement(
25+
"latency",
26+
"ms",
27+
[],
28+
{},
29+
)
12030

12131

122-
def snapshot_resume_measurements(vm_type, io_engine):
123-
"""Define measurements for snapshot resume tests."""
124-
load_latency = {
125-
"target": LOAD_LATENCY_BASELINES[
126-
get_instance_type(), get_kernel_version(level=1), io_engine, vm_type
127-
]
128-
}
129-
130-
latency = types.MeasurementDef.create_measurement(
131-
"latency",
132-
"ms",
133-
[function.Max("max")],
134-
{"max": criteria.LowerThan(load_latency)},
135-
)
136-
137-
return [latency]
138-
139-
140-
def snapshot_create_producer(
141-
logger, vm, disks, ssh_key, target_version, metrics_fifo, snapshot_type
142-
):
32+
def snapshot_create_producer(logger, vm, disks, ssh_key, target_version, metrics_fifo):
14333
"""Produce results for snapshot create tests."""
14434
snapshot_builder = SnapshotBuilder(vm)
14535
snapshot_builder.create(
14636
disks=disks,
14737
ssh_key=ssh_key,
148-
snapshot_type=snapshot_type,
14938
target_version=target_version,
15039
use_ramdisk=True,
15140
)
15241
metrics = vm.flush_metrics(metrics_fifo)
15342

154-
if snapshot_type == SnapshotType.FULL:
155-
value = metrics["latencies_us"]["full_create_snapshot"] / USEC_IN_MSEC
156-
else:
157-
value = metrics["latencies_us"]["diff_create_snapshot"] / USEC_IN_MSEC
43+
value = metrics["latencies_us"]["full_create_snapshot"] / USEC_IN_MSEC
15844

15945
logger.info("Latency {} ms".format(value))
16046

@@ -203,6 +89,12 @@ def test_older_snapshot_resume_latency(
20389
With each previous firecracker version, create a snapshot and try to
20490
restore in current version.
20591
"""
92+
93+
# The guest kernel does not "participate" in snapshot restore, so just pick some
94+
# arbitrary one
95+
if "4.14" not in guest_kernel.name():
96+
pytest.skip()
97+
20698
logger = logging.getLogger("old_snapshot_load")
20799
jailer = firecracker_release.jailer()
208100
fc_version = firecracker_release.base_name()[1:]
@@ -252,39 +144,37 @@ def test_older_snapshot_resume_latency(
252144
),
253145
func_kwargs={},
254146
)
255-
eager_map(
256-
cons.set_measurement_def,
257-
snapshot_resume_measurements(microvm_cfg, io_engine.lower()),
258-
)
147+
cons.set_measurement_def(LATENCY_MEASUREMENT)
259148

260149
st_core.add_pipe(producer=prod, consumer=cons, tag=microvm_cfg)
261150
# Gather results and verify pass criteria.
262151
st_core.run_exercise()
263152

264153

265-
@pytest.mark.parametrize("guest_mem_mib", [256, 512])
266-
@pytest.mark.parametrize("snapshot_type", [SnapshotType.FULL, SnapshotType.DIFF])
267154
def test_snapshot_create_latency(
268155
microvm_factory,
269156
guest_kernel,
270157
rootfs,
271-
guest_mem_mib,
272-
snapshot_type,
273158
firecracker_release,
274159
st_core,
275160
):
276161
"""
277-
Test scenario: Full/Diff snapshot create performance measurement.
162+
Test scenario: Full snapshot create performance measurement.
278163
279164
Testing matrix:
280165
- Guest kernel: all supported ones
281166
- Rootfs: Ubuntu 18.04
282-
- Microvm: 2vCPU with 256/512 MB RAM
283-
TODO: Multiple microvm sizes must be tested in the async pipeline.
167+
- Microvm: 2vCPU with 512 MB RAM
284168
"""
169+
170+
# The guest kernel does not "participate" in snapshot restore, so just pick some
171+
# arbitrary one
172+
if "4.14" not in guest_kernel.name():
173+
pytest.skip()
174+
285175
logger = logging.getLogger("snapshot_sequence")
286176

287-
diff_snapshots = snapshot_type == SnapshotType.DIFF
177+
guest_mem_mib = 512
288178
vcpus = 2
289179
microvm_cfg = f"{vcpus}vcpu_{guest_mem_mib}mb.json"
290180
vm = microvm_factory.build(guest_kernel, rootfs, monitor_memory=False)
@@ -293,7 +183,6 @@ def test_snapshot_create_latency(
293183
vcpu_count=vcpus,
294184
mem_size_mib=guest_mem_mib,
295185
use_initrd=True,
296-
track_dirty_pages=diff_snapshots,
297186
)
298187

299188
# Configure metrics system.
@@ -319,12 +208,10 @@ def test_snapshot_create_latency(
319208
idx_vcpu, current_cpu_id + idx_vcpu
320209
), f"Failed to pin fc_vcpu {idx_vcpu} thread."
321210

322-
st_core.name = f"snapshot_create_{snapshot_type}_latency"
211+
st_core.name = f"snapshot_create_SnapshotType.FULL_latency"
323212
st_core.iterations = SAMPLE_COUNT
324213
st_core.custom["guest_config"] = microvm_cfg.strip(".json")
325-
st_core.custom["snapshot_type"] = (
326-
"FULL" if snapshot_type == SnapshotType.FULL else "DIFF"
327-
)
214+
st_core.custom["snapshot_type"] = "FULL"
328215

329216
prod = producer.LambdaProducer(
330217
func=snapshot_create_producer,
@@ -335,7 +222,6 @@ def test_snapshot_create_latency(
335222
"ssh_key": rootfs.ssh_key(),
336223
"target_version": firecracker_release.snapshot_version,
337224
"metrics_fifo": metrics_fifo,
338-
"snapshot_type": snapshot_type,
339225
},
340226
)
341227

@@ -345,10 +231,7 @@ def test_snapshot_create_latency(
345231
),
346232
func_kwargs={},
347233
)
348-
eager_map(
349-
cons.set_measurement_def,
350-
snapshot_create_measurements(microvm_cfg, snapshot_type),
351-
)
234+
cons.set_measurement_def(LATENCY_MEASUREMENT)
352235

353236
st_core.add_pipe(producer=prod, consumer=cons, tag=microvm_cfg)
354237
# Gather results and verify pass criteria.

0 commit comments

Comments
 (0)