[FIX]: Preserve reports with duplicate timestamps - #179
[FIX]: Preserve reports with duplicate timestamps#179Rio Yu (rioyu123) wants to merge 3 commits into
Conversation
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
|
@microsoft-github-policy-service agree |
7a7f44e to
489675a
Compare
Nina Chikanov (nina-msft)
left a comment
There was a problem hiding this comment.
Thanks for flagging this Rio Yu (@rioyu123)! Let me know what you think of the following comments :-)
Whoops - meant to comment only instead of approval :-)
Signed-off-by: Rio Yu <52408936+rioyu123@users.noreply.github.com>
| filepath = self._output_dir / f"run_report_{timestamp}.json" | ||
|
|
||
| timestamp = datetime.now(UTC).strftime("%Y-%m-%dT%H-%M-%S-%f")[:-3] | ||
| filepath = self._output_dir / f"run_report_{timestamp}_{uuid4().hex}.json" |
There was a problem hiding this comment.
Actually, could we add the UUID only when the millisecond filename collides? For example:
timestamp = datetime.now(UTC).strftime("%Y-%m-%dT%H-%M-%S-%f")[:-3]
content = json.dumps(data, indent=2, default=str)
filepath = self._output_dir / f"run_report_{timestamp}.json"
try:
report_file = filepath.open("x", encoding="utf-8")
except FileExistsError:
filepath = self._output_dir / f"run_report_{timestamp}_{uuid4().hex}.json"
report_file = filepath.open("x", encoding="utf-8")
with report_file:
report_file.write(content)This keeps the common filename concise while preserving atomic no-overwrite behavior.
There was a problem hiding this comment.
Done. The sink now opens run_report_<millisecond timestamp>.json exclusively first and appends a UUID only if that path already exists. The fallback is also opened exclusively, so the common filename stays concise and same-millisecond reports cannot overwrite each other. Tests cover both paths.
| Output: `.report/run_report_2026-04-25T14-30-00.json` | ||
| Output: `.report/run_report_2026-04-25T14-30-00-123_a3f18c92654d4b75ad15687d383d951b.json` | ||
|
|
||
| The filename contains a UTC timestamp (millisecond precision) and a random UUID. Reports created in the same millisecond receive different filenames. An exact filename collision raises `FileExistsError` instead of overwriting an existing report. Reports written within the same millisecond have no defined filename order relative to each other. |
There was a problem hiding this comment.
If we implement behavior that I commented on below, the exact filename collision will just be avoided by adding the uuid at the end and we shouldn't raise FileExistsError :-)
There was a problem hiding this comment.
Agreed. The guide now shows the concise millisecond filename and explains that a same-timestamp collision is handled by appending a UUID. It no longer says that an ordinary timestamp collision raises FileExistsError.
Description
JsonFileReportSinkused a seconds-precision timestamp withwrite_text(). Two reports emitted within the same second therefore resolved to the same path, allowing the later report to silently replace the first.This change preserves every report while keeping the common filename concise:
run_report_2026-04-25T14-30-00-123.json.x, so an existing report is never overwritten.The usage guide and API documentation now describe the concise common filename, collision fallback, and remaining error cases. Tests cover repeated timestamps, existing-file preservation, a forced fallback collision, and serialization failure.
Validation:
uv run pre-commit run --all-files— passeduv run pytest tests/unit/reporting -q— 46 passeduv run pytest tests/unit -q— 1035 passed on Linux; 1033 passed and 2 skipped on Windowsuv run --group docs mkdocs build --strict— passed on LinuxBreaking changes
There are no public API or report-schema changes. Generated filenames now include milliseconds and may include a UUID suffix on collision. Consumers using
run_report_*.jsonare unaffected; consumers parsing the exact timestamp format should account for the additional millisecond segment.Checklist
pre-commit run --all-filespasses