feat(esg): honor per-system TimeoutSeconds in InvokeHttpAsync (falls back to DefaultHttpTimeout)

Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
This commit is contained in:
Joseph Doherty
2026-07-10 04:05:27 -04:00
parent 899af63b2a
commit 86d1a5cbf2
2 changed files with 39 additions and 8 deletions
@@ -872,6 +872,33 @@ public class ExternalSystemClientTests
e.Level >= LogLevel.Warning && e.Message.Contains("TestAPI"));
}
[Fact]
public async Task PerSystemTimeout_OverridesGatewayDefault()
{
// System timeout 1s; handler black-holes far longer; gateway default is 30s.
var system = new ExternalSystemDefinition("slow", "http://x", "none") { Id = 1, TimeoutSeconds = 1 };
var method = new ExternalSystemMethod("m", "GET", "/p") { Id = 1, ExternalSystemDefinitionId = 1 };
StubResolution(system, method);
var httpClient = new HttpClient(new HangingHttpMessageHandler(TimeSpan.FromMinutes(10)));
_httpClientFactory.CreateClient(Arg.Any<string>()).Returns(httpClient);
// No options override → DefaultHttpTimeout is the 30s default; only the
// per-system 1s should govern the round-trip.
var client = new ExternalSystemClient(
_httpClientFactory, _repository,
NullLogger<ExternalSystemClient>.Instance);
var sw = System.Diagnostics.Stopwatch.StartNew();
var result = await client.CallAsync("slow", "m");
sw.Stop();
Assert.False(result.Success);
Assert.Contains("Timeout", result.ErrorMessage);
Assert.True(sw.Elapsed < TimeSpan.FromSeconds(4),
"per-system 1s timeout must apply, not the 30s default");
}
[Fact]
public async Task Call_TransientFailure_DoesNotLogAtWarningOrAbove()
{