|
7 | 7 | import json |
8 | 8 | import os |
9 | 9 | import pprint |
| 10 | +import re |
10 | 11 | import sys |
11 | 12 | from abc import ABC, abstractmethod |
12 | 13 | from collections.abc import Mapping, Sequence |
| 14 | +from datetime import datetime, timezone |
13 | 15 | from pathlib import Path |
14 | 16 | from typing import TYPE_CHECKING, ClassVar |
15 | 17 |
|
|
19 | 21 | from dvsim.job.data import CompletedJobStatus |
20 | 22 | from dvsim.launcher.factory import get_launcher_cls |
21 | 23 | from dvsim.logging import log |
| 24 | +from dvsim.report.data import IPMeta, ResultsSummary |
22 | 25 | from dvsim.scheduler import Scheduler |
23 | 26 | from dvsim.utils import ( |
24 | 27 | find_and_substitute_wildcards, |
@@ -493,8 +496,52 @@ def gen_results(self, results: Sequence[CompletedJobStatus]) -> None: |
493 | 496 | self.errors_seen |= item.errors_seen |
494 | 497 |
|
495 | 498 | if self.is_primary_cfg: |
| 499 | + json_str = self._gen_json_results_summary() |
496 | 500 | self.gen_results_summary() |
497 | | - self.write_results(self.results_html_name, self.results_summary_md) |
| 501 | + |
| 502 | + self.write_results( |
| 503 | + html_filename=self.results_html_name, |
| 504 | + text_md=self.results_summary_md, |
| 505 | + json_str=json_str, |
| 506 | + ) |
| 507 | + |
| 508 | + def _gen_json_results_summary(self) -> str: |
| 509 | + """Generate results summary in JSON format.""" |
| 510 | + # The timestamp for this run has been taken with `utcnow()` and is |
| 511 | + # stored in a custom format. Store it in standard ISO format with |
| 512 | + # explicit timezone annotation. |
| 513 | + timestamp = ( |
| 514 | + datetime.strptime(self.timestamp, "%Y%m%d_%H%M%S") |
| 515 | + .replace(tzinfo=timezone.utc) |
| 516 | + .isoformat() |
| 517 | + ) |
| 518 | + |
| 519 | + # Extract Git properties. |
| 520 | + m = re.search( |
| 521 | + r"https://github.com/.+?/tree/([0-9a-fA-F]+)", |
| 522 | + self.revision, |
| 523 | + ) |
| 524 | + commit = m.group(1) if m else None |
| 525 | + |
| 526 | + reports_dir = Path(self.scratch_base_path) / "reports" |
| 527 | + |
| 528 | + return ResultsSummary( |
| 529 | + top=IPMeta( |
| 530 | + name=self.name, |
| 531 | + variant=self.variant, |
| 532 | + commit=str(commit), |
| 533 | + branch=self.branch, |
| 534 | + url=self.revision, |
| 535 | + ), |
| 536 | + timestamp=timestamp, |
| 537 | + report_index={ |
| 538 | + item.name: (item.results_dir / item.results_html_name).relative_to(reports_dir) |
| 539 | + for item in self.cfgs |
| 540 | + }, |
| 541 | + report_path=(Path(self.results_dir) / self.results_html_name) |
| 542 | + .with_suffix(".json") |
| 543 | + .relative_to(reports_dir), |
| 544 | + ).model_dump_json() |
498 | 545 |
|
499 | 546 | @abstractmethod |
500 | 547 | def gen_results_summary(self) -> str: |
|
0 commit comments