From 43b55a0e850b58a1107d61e28eeba212ecf27f46 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Tue, 25 Aug 2026 08:28:37 +0100 Subject: [PATCH] Improve integration test request resilience --- .../Common/DockerHelper.cs | 1 + .../Shared/ACLSteps.cs | 72 ++++++++++--------- 2 files changed, 40 insertions(+), 33 deletions(-) diff --git a/TransactionProcessorACL.IntegrationTests/Common/DockerHelper.cs b/TransactionProcessorACL.IntegrationTests/Common/DockerHelper.cs index a76d1c5..8fb362d 100644 --- a/TransactionProcessorACL.IntegrationTests/Common/DockerHelper.cs +++ b/TransactionProcessorACL.IntegrationTests/Common/DockerHelper.cs @@ -121,6 +121,7 @@ public override async Task StartContainersForScenarioRun(String scenarioName, Do this.HttpClient = new HttpClient(); this.HttpClient.BaseAddress = new Uri(TransactionProcessorAclBaseAddressResolver(string.Empty)); + this.HttpClient.Timeout = TimeSpan.FromMinutes(5); this.ProjectionManagementClient = new EventStoreProjectionManagementClient(ConfigureEventStoreSettings()); diff --git a/TransactionProcessorACL.IntegrationTests/Shared/ACLSteps.cs b/TransactionProcessorACL.IntegrationTests/Shared/ACLSteps.cs index 9bbcfcc..0c1605a 100644 --- a/TransactionProcessorACL.IntegrationTests/Shared/ACLSteps.cs +++ b/TransactionProcessorACL.IntegrationTests/Shared/ACLSteps.cs @@ -262,22 +262,24 @@ public async Task WhenIGetTheMerchantDailyPerformanceSummaryForMerchantForEstate }; - StringContent content = new StringContent(StringSerialiser.Serialise(request), Encoding.UTF8, "application/json"); + await Retry.For(async () => { + StringContent content = new(StringSerialiser.Serialise(request), Encoding.UTF8, "application/json"); - HttpResponseMessage response = await this.HttpClient.PostAsync(uri, content, cancellationToken).ConfigureAwait(false); + HttpResponseMessage response = await this.HttpClient.PostAsync(uri, content, cancellationToken).ConfigureAwait(false); + String responseContent = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); - response.IsSuccessStatusCode.ShouldBeTrue(); + response.IsSuccessStatusCode.ShouldBeTrue($"Daily performance summary request failed with {(Int32)response.StatusCode} {response.ReasonPhrase}. Body: {responseContent}"); - String responseContent = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); - responseContent.ShouldNotBeNullOrEmpty("No response message received"); + responseContent.ShouldNotBeNullOrEmpty("No response message received"); - ReportingDailyPerformanceSummaryResponse dailyPerformanceSummaryResponse = - StringSerialiser.Deserialise(responseContent, - new SerialiserOptions(SerialiserPropertyFormat.SnakeCase)); + ReportingDailyPerformanceSummaryResponse dailyPerformanceSummaryResponse = + StringSerialiser.Deserialise(responseContent, + new SerialiserOptions(SerialiserPropertyFormat.SnakeCase)); - es1.AddMerchantDailyPerformanceSummaryResponse(merchantId, dailyPerformanceSummaryResponse); - this.LastMerchantDailyPerformanceSummaryEstateDetails = es1; - this.LastMerchantDailyPerformanceSummaryMerchantId = merchantId; + es1.AddMerchantDailyPerformanceSummaryResponse(merchantId, dailyPerformanceSummaryResponse); + this.LastMerchantDailyPerformanceSummaryEstateDetails = es1; + this.LastMerchantDailyPerformanceSummaryMerchantId = merchantId; + }, TimeSpan.FromMinutes(5), TimeSpan.FromSeconds(5)); } public void ThenTheMerchantDailyPerformanceSummaryResponseShouldContainAtLeastOneMetricAndTheSaleAmount(Decimal saleAmount) @@ -320,22 +322,24 @@ public async Task WhenIGetTheMerchantTransactionMixSummaryForMerchantForEstate(S TopN = 5, }; - StringContent content = new StringContent(StringSerialiser.Serialise(request), Encoding.UTF8, "application/json"); + await Retry.For(async () => { + StringContent content = new(StringSerialiser.Serialise(request), Encoding.UTF8, "application/json"); - HttpResponseMessage response = await this.HttpClient.PostAsync(uri, content, cancellationToken).ConfigureAwait(false); + HttpResponseMessage response = await this.HttpClient.PostAsync(uri, content, cancellationToken).ConfigureAwait(false); + String responseContent = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); - response.IsSuccessStatusCode.ShouldBeTrue(); + response.IsSuccessStatusCode.ShouldBeTrue($"Transaction mix summary request failed with {(Int32)response.StatusCode} {response.ReasonPhrase}. Body: {responseContent}"); - String responseContent = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); - responseContent.ShouldNotBeNullOrEmpty("No response message received"); + responseContent.ShouldNotBeNullOrEmpty("No response message received"); - ReportingMerchantTransactionMixSummaryResponse transactionMixSummaryResponse = - StringSerialiser.Deserialise(responseContent, - new SerialiserOptions(SerialiserPropertyFormat.SnakeCase)); + ReportingMerchantTransactionMixSummaryResponse transactionMixSummaryResponse = + StringSerialiser.Deserialise(responseContent, + new SerialiserOptions(SerialiserPropertyFormat.SnakeCase)); - es1.AddMerchantTransactionMixSummaryResponse(merchantId, transactionMixSummaryResponse); - this.LastMerchantTransactionMixSummaryEstateDetails = es1; - this.LastMerchantTransactionMixSummaryMerchantId = merchantId; + es1.AddMerchantTransactionMixSummaryResponse(merchantId, transactionMixSummaryResponse); + this.LastMerchantTransactionMixSummaryEstateDetails = es1; + this.LastMerchantTransactionMixSummaryMerchantId = merchantId; + }, TimeSpan.FromMinutes(5), TimeSpan.FromSeconds(5)); } public async Task WhenIGetTheRecentActivityReceiptSearchForMerchantForEstate(String estateName, @@ -364,22 +368,24 @@ public async Task WhenIGetTheRecentActivityReceiptSearchForMerchantForEstate(Str PageSize = pageSize }; - StringContent content = new StringContent(StringSerialiser.Serialise(request), Encoding.UTF8, "application/json"); + await Retry.For(async () => { + StringContent content = new(StringSerialiser.Serialise(request), Encoding.UTF8, "application/json"); - HttpResponseMessage response = await this.HttpClient.PostAsync(uri, content, cancellationToken).ConfigureAwait(false); + HttpResponseMessage response = await this.HttpClient.PostAsync(uri, content, cancellationToken).ConfigureAwait(false); + String responseContent = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); - response.IsSuccessStatusCode.ShouldBeTrue(); + response.IsSuccessStatusCode.ShouldBeTrue($"Recent activity receipt search request failed with {(Int32)response.StatusCode} {response.ReasonPhrase}. Body: {responseContent}"); - String responseContent = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); - responseContent.ShouldNotBeNullOrEmpty("No response message received"); + responseContent.ShouldNotBeNullOrEmpty("No response message received"); - RecentActivityReceiptSearchResponse searchResponse = - StringSerialiser.Deserialise(responseContent, - new SerialiserOptions(SerialiserPropertyFormat.SnakeCase)); + RecentActivityReceiptSearchResponse searchResponse = + StringSerialiser.Deserialise(responseContent, + new SerialiserOptions(SerialiserPropertyFormat.SnakeCase)); - this.RecentActivityReceiptSearchResponses[pageNumber] = searchResponse; - this.LastRecentActivityReceiptSearchEstateDetails = es1; - this.LastRecentActivityReceiptSearchMerchantId = merchantId; + this.RecentActivityReceiptSearchResponses[pageNumber] = searchResponse; + this.LastRecentActivityReceiptSearchEstateDetails = es1; + this.LastRecentActivityReceiptSearchMerchantId = merchantId; + }, TimeSpan.FromMinutes(5), TimeSpan.FromSeconds(5)); } public void ThenTheMerchantTransactionMixSummaryResponseShouldContainAtLeastOneItemAndTheSaleAmount(Decimal saleAmount)