[TUnit.Aspire] First-class resource-diagnostics helper + retained log buffer
Labels: enhancement, TUnit.Aspire
Problem
Consumers who want a resource's logs on failure today must hand-roll ResourceLoggerService.WatchAsync(...) themselves. That pattern is racy: if you only fetch logs after a startup failure (e.g. in a catch), a resource that has already exited returns "(no logs available)" — the backlog is gone. A real fixture did exactly this and lost the crash output.
Proposal
-
Retain a rolling per-resource log buffer inside the fixture (subscribed from StartAsync, capped, e.g. last 500 lines/resource). This makes post-mortem retrieval reliable even for resources that already exited.
-
Expose first-class helpers so consumers stop re-implementing the plumbing:
// last N lines (from the retained buffer — works even after the resource exited)
IReadOnlyList<string> logs = await fixture.GetResourceLogsAsync("chat", maxLines: 200);
// full diagnostic block for all resources: state, exit code (decoded), last-N logs
string report = await fixture.DumpResourceDiagnosticsAsync();
// state/exit introspection
ResourceSnapshot snap = fixture.GetResourceSnapshot("chat"); // Name, State, ExitCode, StartedAt, ...
- Optionally, auto-invoke
DumpResourceDiagnosticsAsync() on fixture-init failure (gated by the same opt-in as log forwarding), so a failed boot self-documents.
Acceptance criteria
GetResourceLogsAsync returns buffered lines even for an exited resource (no "(no logs available)" race).
DumpResourceDiagnosticsAsync produces a single string with per-resource state + decoded exit code + last-N logs.
- Buffer is bounded (configurable cap) to avoid unbounded memory on long/noisy runs.
Related
[TUnit.Aspire] First-class resource-diagnostics helper + retained log buffer
Labels:
enhancement,TUnit.AspireProblem
Consumers who want a resource's logs on failure today must hand-roll
ResourceLoggerService.WatchAsync(...)themselves. That pattern is racy: if you only fetch logs after a startup failure (e.g. in acatch), a resource that has already exited returns "(no logs available)" — the backlog is gone. A real fixture did exactly this and lost the crash output.Proposal
Retain a rolling per-resource log buffer inside the fixture (subscribed from
StartAsync, capped, e.g. last 500 lines/resource). This makes post-mortem retrieval reliable even for resources that already exited.Expose first-class helpers so consumers stop re-implementing the plumbing:
DumpResourceDiagnosticsAsync()on fixture-init failure (gated by the same opt-in as log forwarding), so a failed boot self-documents.Acceptance criteria
GetResourceLogsAsyncreturns buffered lines even for an exited resource (no "(no logs available)" race).DumpResourceDiagnosticsAsyncproduces a single string with per-resource state + decoded exit code + last-N logs.Related