|
18 | 18 | import jsonschema
|
19 | 19 | import pytest
|
20 | 20 |
|
| 21 | +from framework import utils |
21 | 22 | from framework.properties import global_props
|
| 23 | +from framework.utils_repo import git_repo_files |
22 | 24 | from host_tools.metrics import get_metrics_logger
|
23 | 25 |
|
24 | 26 |
|
@@ -563,3 +565,61 @@ def run(self):
|
563 | 565 | time.sleep(1)
|
564 | 566 | if self.running is False:
|
565 | 567 | break
|
| 568 | + |
| 569 | + |
| 570 | +def find_metrics_files(): |
| 571 | + """Gets a list of all Firecracker sources files ending with 'metrics.rs'""" |
| 572 | + return list(git_repo_files(root="..", glob="*metrics.rs")) |
| 573 | + |
| 574 | + |
| 575 | +def extract_fields(file_path): |
| 576 | + """Gets a list of all metrics defined in the given file, in the form tuples (name, type)""" |
| 577 | + fields = utils.run_cmd( |
| 578 | + rf'grep -Po "(?<=pub )(\w+): (Shared(?:Inc|Store)Metric|LatencyAggregateMetrics)" {file_path}' |
| 579 | + ).stdout.strip() |
| 580 | + |
| 581 | + return [field.split(": ", maxsplit=1) for field in fields.splitlines()] |
| 582 | + |
| 583 | + |
| 584 | +def is_file_production(filepath): |
| 585 | + """Returns True iff accesses to metric fields in the given file should cause the metric be considered 'used in production code'. Excludes, for example, files in which the metrics are defined, where accesses happen as part of copy constructors, etc.""" |
| 586 | + path = filepath.lower() |
| 587 | + return ( |
| 588 | + "/test/" in path |
| 589 | + or "/tests/" in path |
| 590 | + or path.endswith("_test.rs") |
| 591 | + or "test_" in path |
| 592 | + or "tests.rs" in path |
| 593 | + or ("metrics.rs" in path and "vmm" in path) |
| 594 | + ) |
| 595 | + |
| 596 | + |
| 597 | +KNOWN_FALSE_POSITIVES = [ |
| 598 | + "min_us", |
| 599 | + "max_us", |
| 600 | + "sum_us", |
| 601 | + "process_startup_time_us", |
| 602 | + "process_startup_time_cpu_us", |
| 603 | +] |
| 604 | + |
| 605 | + |
| 606 | +def is_metric_used(field, field_type): |
| 607 | + """Returns True iff the given metric has a production use in the firecracker codebase""" |
| 608 | + if field in KNOWN_FALSE_POSITIVES: |
| 609 | + return True |
| 610 | + |
| 611 | + if field_type in ("SharedIncMetric", "SharedStoreMetric"): |
| 612 | + pattern = rf"{field}\s*\.\s*store|{field}\s*\.\s*inc|{field}\s*\.\s*add|{field}\s*\.\s*fetch|METRICS.*{field}" |
| 613 | + elif field_type == "LatencyAggregateMetrics": |
| 614 | + pattern = rf"{field}\s*\.\s*record_latency_metrics" |
| 615 | + else: |
| 616 | + raise RuntimeError(f"Unknown metric type: {field_type}") |
| 617 | + |
| 618 | + result = utils.run_cmd(f'grep -RPzo "{pattern}" ../src') |
| 619 | + |
| 620 | + for line in result.stdout.strip().split("\0"): |
| 621 | + if not line: |
| 622 | + continue |
| 623 | + if not is_file_production(line.split(":", maxsplit=1)[0]): |
| 624 | + return True |
| 625 | + return False |
0 commit comments