From 21dfcb57d6f626ad2b2268f4786ad2e3e61637fc Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 18 Mar 2026 00:01:56 +0000
Subject: [PATCH 1/3] Initial plan
From d19da6f19e0178524880ee4756d2c4c8953d3ace Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 18 Mar 2026 00:08:24 +0000
Subject: [PATCH 2/3] fix: rename `currentRole` to `current-role` in health
check response for consistency
Co-authored-by: Aniruddh25 <3513779+Aniruddh25@users.noreply.github.com>
---
.../HealthCheck/ComprehensiveHealthReportResponseWriter.cs | 2 +-
src/Service/HealthCheck/Model/ComprehensiveHealthCheckReport.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Service/HealthCheck/ComprehensiveHealthReportResponseWriter.cs b/src/Service/HealthCheck/ComprehensiveHealthReportResponseWriter.cs
index 5027c5e059..26846e6b9c 100644
--- a/src/Service/HealthCheck/ComprehensiveHealthReportResponseWriter.cs
+++ b/src/Service/HealthCheck/ComprehensiveHealthReportResponseWriter.cs
@@ -109,7 +109,7 @@ public async Task WriteResponseAsync(HttpContext context)
// Ensure cachedResponse is not null before calling WriteAsync
if (report != null)
{
- // Set currentRole per-request (not cached) so each caller sees their own role
+ // Set current-role per-request (not cached) so each caller sees their own role
await context.Response.WriteAsync(SerializeReport(report with { CurrentRole = _healthCheckHelper.GetCurrentRole(roleHeader, roleToken) }));
}
else
diff --git a/src/Service/HealthCheck/Model/ComprehensiveHealthCheckReport.cs b/src/Service/HealthCheck/Model/ComprehensiveHealthCheckReport.cs
index 26a260af47..a63c2debf2 100644
--- a/src/Service/HealthCheck/Model/ComprehensiveHealthCheckReport.cs
+++ b/src/Service/HealthCheck/Model/ComprehensiveHealthCheckReport.cs
@@ -46,7 +46,7 @@ public record ComprehensiveHealthCheckReport
///
/// The current role of the user making the request (e.g., "anonymous", "authenticated").
///
- [JsonPropertyName("currentRole")]
+ [JsonPropertyName("current-role")]
public string? CurrentRole { get; set; }
///
From d0d1d0c9ae935535bc98912ced2ad155bb8a4111 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 20 Mar 2026 08:19:08 +0000
Subject: [PATCH 3/3] fix: add retry logic to HotReloadConfigConnectionString
and HotReloadConfigDatabaseType tests
Co-authored-by: souvikghosh04 <210500244+souvikghosh04@users.noreply.github.com>
---
.../HotReload/ConfigurationHotReloadTests.cs | 40 +++++++++++++++++--
1 file changed, 36 insertions(+), 4 deletions(-)
diff --git a/src/Service.Tests/Configuration/HotReload/ConfigurationHotReloadTests.cs b/src/Service.Tests/Configuration/HotReload/ConfigurationHotReloadTests.cs
index 18c19cbd7a..05a858a654 100644
--- a/src/Service.Tests/Configuration/HotReload/ConfigurationHotReloadTests.cs
+++ b/src/Service.Tests/Configuration/HotReload/ConfigurationHotReloadTests.cs
@@ -780,12 +780,28 @@ await WaitForConditionAsync(
succeedConfigLog = _writer.ToString();
}
- HttpResponseMessage restResult = await _testClient.GetAsync("/rest/Book");
+ // Retry REST request because metadata re-initialization happens asynchronously
+ // after the "Validated hot-reloaded configuration file" message. The metadata provider
+ // factory clears and re-initializes providers on the hot-reload thread, so requests
+ // arriving before that completes will fail.
+ HttpResponseMessage restResult = null;
+ bool restSucceeded = false;
+ for (int attempt = 1; attempt <= 10; attempt++)
+ {
+ restResult = await _testClient.GetAsync("/rest/Book");
+ if (restResult.StatusCode == HttpStatusCode.OK)
+ {
+ restSucceeded = true;
+ break;
+ }
+
+ await Task.Delay(1000);
+ }
// Assert
Assert.IsTrue(failedConfigLog.Contains(HOT_RELOAD_FAILURE_MESSAGE));
Assert.IsTrue(succeedConfigLog.Contains(HOT_RELOAD_SUCCESS_MESSAGE));
- Assert.AreEqual(HttpStatusCode.OK, restResult.StatusCode);
+ Assert.IsTrue(restSucceeded, $"REST request did not return OK after hot-reload. Last status: {restResult?.StatusCode}");
}
///
@@ -838,12 +854,28 @@ await WaitForConditionAsync(
succeedConfigLog = _writer.ToString();
}
- HttpResponseMessage restResult = await _testClient.GetAsync("/rest/Book");
+ // Retry REST request because metadata re-initialization happens asynchronously
+ // after the "Validated hot-reloaded configuration file" message. The metadata provider
+ // factory clears and re-initializes providers on the hot-reload thread, so requests
+ // arriving before that completes will fail.
+ HttpResponseMessage restResult = null;
+ bool restSucceeded = false;
+ for (int attempt = 1; attempt <= 10; attempt++)
+ {
+ restResult = await _testClient.GetAsync("/rest/Book");
+ if (restResult.StatusCode == HttpStatusCode.OK)
+ {
+ restSucceeded = true;
+ break;
+ }
+
+ await Task.Delay(1000);
+ }
// Assert
Assert.IsTrue(failedConfigLog.Contains(HOT_RELOAD_FAILURE_MESSAGE));
Assert.IsTrue(succeedConfigLog.Contains(HOT_RELOAD_SUCCESS_MESSAGE));
- Assert.AreEqual(HttpStatusCode.OK, restResult.StatusCode);
+ Assert.IsTrue(restSucceeded, $"REST request did not return OK after hot-reload. Last status: {restResult?.StatusCode}");
}
///