diff --git a/src/WireMock.Net.Abstractions/IRequestMessage.cs b/src/WireMock.Net.Abstractions/IRequestMessage.cs
index 02a23b63..c60fbe8f 100644
--- a/src/WireMock.Net.Abstractions/IRequestMessage.cs
+++ b/src/WireMock.Net.Abstractions/IRequestMessage.cs
@@ -32,7 +32,7 @@ public interface IRequestMessage
string? ProxyUrl { get; set; }
///
- /// Gets the DateTime.
+ /// The DateTime when this request was done.
///
DateTime DateTime { get; }
diff --git a/src/WireMock.Net.Abstractions/IResponseMessage.cs b/src/WireMock.Net.Abstractions/IResponseMessage.cs
index 8abf4114..4993a649 100644
--- a/src/WireMock.Net.Abstractions/IResponseMessage.cs
+++ b/src/WireMock.Net.Abstractions/IResponseMessage.cs
@@ -52,7 +52,7 @@ public interface IResponseMessage
object? StatusCode { get; set; }
///
- /// Gets the DateTime.
+ /// The DateTime when this response was sent.
///
DateTime DateTime { get; }
diff --git a/src/WireMock.Net.Minimal/Extensions/HttpContextExtensions.cs b/src/WireMock.Net.Minimal/Extensions/HttpContextExtensions.cs
new file mode 100644
index 00000000..07ca7b81
--- /dev/null
+++ b/src/WireMock.Net.Minimal/Extensions/HttpContextExtensions.cs
@@ -0,0 +1,14 @@
+// Copyright © WireMock.Net
+
+using System.Diagnostics.CodeAnalysis;
+using Microsoft.AspNetCore.Http;
+
+namespace WireMock.Extensions;
+
+internal static class HttpContextExtensions
+{
+ internal static bool TryGet(this HttpContext httpContext, [NotNullWhen(true)] out T? value)
+ {
+ return httpContext.Items.TryGetValue(nameof(T), out value);
+ }
+}
\ No newline at end of file
diff --git a/src/WireMock.Net.Minimal/Owin/Mappers/OwinRequestMapper.cs b/src/WireMock.Net.Minimal/Owin/Mappers/OwinRequestMapper.cs
index 0db51eb4..a0d2c3c7 100644
--- a/src/WireMock.Net.Minimal/Owin/Mappers/OwinRequestMapper.cs
+++ b/src/WireMock.Net.Minimal/Owin/Mappers/OwinRequestMapper.cs
@@ -12,7 +12,7 @@ namespace WireMock.Owin.Mappers;
///
/// OwinRequestMapper
///
-internal class OwinRequestMapper : IOwinRequestMapper
+internal class OwinRequestMapper(IDateTimeUtils dateTimeUtils) : IOwinRequestMapper
{
///
public async Task MapAsync(HttpContext context, IWireMockMiddlewareOptions options)
@@ -72,7 +72,7 @@ internal class OwinRequestMapper : IOwinRequestMapper
await request.HttpContext.Connection.GetClientCertificateAsync()
)
{
- DateTime = DateTime.UtcNow
+ DateTime = dateTimeUtils.UtcNow
};
}
diff --git a/src/WireMock.Net.Minimal/Owin/WireMockMiddleware.cs b/src/WireMock.Net.Minimal/Owin/WireMockMiddleware.cs
index bd193e11..89528b3f 100644
--- a/src/WireMock.Net.Minimal/Owin/WireMockMiddleware.cs
+++ b/src/WireMock.Net.Minimal/Owin/WireMockMiddleware.cs
@@ -171,6 +171,12 @@ internal class WireMockMiddleware(
}
finally
{
+ // Set the DateTime from the Response to the current DateTime
+ if (response is ResponseMessage responseMessage)
+ {
+ responseMessage.DateTime = dateTimeUtils.UtcNow;
+ }
+
logger.LogRequestAndResponse(logRequest, request, response, result.Match, result.Partial, activity);
try
@@ -255,4 +261,4 @@ internal class WireMockMiddleware(
scenario.Finished = mapping.NextState == null;
});
}
-}
+}
\ No newline at end of file
diff --git a/src/WireMock.Net.Minimal/Owin/WireMockMiddlewareLogger.cs b/src/WireMock.Net.Minimal/Owin/WireMockMiddlewareLogger.cs
index 2f35b2ce..d44eaf7d 100644
--- a/src/WireMock.Net.Minimal/Owin/WireMockMiddlewareLogger.cs
+++ b/src/WireMock.Net.Minimal/Owin/WireMockMiddlewareLogger.cs
@@ -73,20 +73,20 @@ internal class WireMockMiddlewareLogger(
var logEntries = options.LogEntries.ToList();
foreach (var logEntry in logEntries
- .OrderBy(le => le.RequestMessage?.DateTime ?? le.ResponseMessage?.DateTime)
+ .OrderBy(le => le.RequestMessage?.DateTime)
.Take(logEntries.Count - options.MaxRequestLogCount.Value))
{
TryRemoveLogEntry(logEntry);
}
}
- // In case RequestLogExpirationDuration has a value greater than 0, try to delete existing request logs based on the date.
+ // In case RequestLogExpirationDuration has a value greater than 0, try to delete existing request logs based on the RequestMessage date.
if (options.RequestLogExpirationDuration is > 0)
{
var logEntries = options.LogEntries.ToList();
var checkTime = dateTimeUtils.UtcNow.AddHours(-options.RequestLogExpirationDuration.Value);
- foreach (var logEntry in logEntries.Where(le => le.RequestMessage?.DateTime < checkTime || le.ResponseMessage?.DateTime < checkTime))
+ foreach (var logEntry in logEntries.Where(le => le.RequestMessage?.DateTime < checkTime))
{
TryRemoveLogEntry(logEntry);
}
diff --git a/src/WireMock.Net.Minimal/ResponseBuilders/Response.cs b/src/WireMock.Net.Minimal/ResponseBuilders/Response.cs
index 60151c0e..b14631f5 100644
--- a/src/WireMock.Net.Minimal/ResponseBuilders/Response.cs
+++ b/src/WireMock.Net.Minimal/ResponseBuilders/Response.cs
@@ -87,7 +87,7 @@ public partial class Response : IResponseBuilder
{
var message = responseMessage ?? new ResponseMessage
{
- DateTime = DateTime.UtcNow // We set it here to the current time.
+ DateTime = DateTime.UtcNow // Initially, this is set to the current time, but will be updated to the real time once the response has been sent.
};
return new Response(message);
diff --git a/src/WireMock.Net.Minimal/ResponseMessage.cs b/src/WireMock.Net.Minimal/ResponseMessage.cs
index 1b5d3f9c..70ae16c1 100644
--- a/src/WireMock.Net.Minimal/ResponseMessage.cs
+++ b/src/WireMock.Net.Minimal/ResponseMessage.cs
@@ -2,7 +2,6 @@
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
-using System.Linq;
using Stef.Validation;
using WireMock.ResponseBuilders;
using WireMock.Types;
diff --git a/test/WireMock.Net.Tests/Facts/RunOnDockerFact.cs b/test/WireMock.Net.Tests/Facts/RunOnDockerFact.cs
new file mode 100644
index 00000000..dd179b1c
--- /dev/null
+++ b/test/WireMock.Net.Tests/Facts/RunOnDockerFact.cs
@@ -0,0 +1,29 @@
+// Copyright © WireMock.Net
+#if NET6_0_OR_GREATER
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using WireMock.Net.Testcontainers.Utils;
+
+namespace WireMock.Net.Tests.Facts;
+
+[ExcludeFromCodeCoverage]
+public sealed class RunOnDockerFact : FactAttribute
+{
+ public RunOnDockerFact(
+ [CallerFilePath] string? sourceFilePath = null,
+ [CallerLineNumber] int sourceLineNumber = -1) : base(sourceFilePath, sourceLineNumber)
+ {
+
+ OSPlatform currentPlatform;
+ try
+ {
+ currentPlatform = TestcontainersUtils.GetImageOSAsync.Value.Result;
+ }
+ catch
+ {
+ Skip = $"Only run test when Docker is installed.";
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/WireMock.Net.Tests/Facts/RunOnDockerPlatformFact.cs b/test/WireMock.Net.Tests/Facts/RunOnDockerPlatformFact.cs
index d12cdb4f..ee6980f1 100644
--- a/test/WireMock.Net.Tests/Facts/RunOnDockerPlatformFact.cs
+++ b/test/WireMock.Net.Tests/Facts/RunOnDockerPlatformFact.cs
@@ -15,7 +15,19 @@ public sealed class RunOnDockerPlatformFact : FactAttribute
[CallerFilePath] string? sourceFilePath = null,
[CallerLineNumber] int sourceLineNumber = -1) : base(sourceFilePath, sourceLineNumber)
{
- if (TestcontainersUtils.GetImageOSAsync.Value.Result != OSPlatform.Create(platform))
+
+ OSPlatform currentPlatform;
+ try
+ {
+ currentPlatform = TestcontainersUtils.GetImageOSAsync.Value.Result;
+ }
+ catch
+ {
+ Skip = $"Only run test when Docker is installed.";
+ return;
+ }
+
+ if (currentPlatform != OSPlatform.Create(platform))
{
Skip = $"Only run test when Docker OS Platform {platform} is used.";
}
diff --git a/test/WireMock.Net.Tests/Owin/WireMockMiddlewareTests.cs b/test/WireMock.Net.Tests/Owin/WireMockMiddlewareTests.cs
index fd149196..d25de1a0 100644
--- a/test/WireMock.Net.Tests/Owin/WireMockMiddlewareTests.cs
+++ b/test/WireMock.Net.Tests/Owin/WireMockMiddlewareTests.cs
@@ -106,6 +106,15 @@ public class WireMockMiddlewareTests
[Fact]
public async Task WireMockMiddleware_Invoke_NoMatch()
{
+ // Arrange
+ var inititalDateTime = new DateTime(2027, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+ var responseDateTime = new DateTime(2027, 1, 1, 0, 0, 42, DateTimeKind.Utc);
+
+ _dateTimeUtilsMock.Reset();
+ _dateTimeUtilsMock.SetupSequence(d => d.UtcNow)
+ .Returns(inititalDateTime)
+ .Returns(responseDateTime);
+
// Act
await _sut.Invoke(_contextMock.Object);
@@ -115,7 +124,7 @@ public class WireMockMiddlewareTests
Expression> match = r =>
(int)r.StatusCode! == 404 &&
((StatusModel)r.BodyData!.BodyAsJson!).Status == "No matching mapping found" &&
- r.DateTime == UtcNow;
+ r.DateTime == responseDateTime;
_responseMapperMock.Verify(m => m.MapAsync(It.Is(match), It.IsAny()), Times.Once);
}
diff --git a/test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs b/test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs
index 2de6a1a1..ace85d23 100644
--- a/test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs
+++ b/test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs
@@ -21,7 +21,7 @@ public class TestcontainersTests(ITestOutputHelper testOutputHelper)
TimestampFormat = "yyy-MM-dd HH:mm:ss.fff"
});
- [Fact]
+ [RunOnDockerFact]
public async Task WireMockContainer_Build_And_StartAsync_and_StopAsync()
{
// Act
@@ -57,7 +57,7 @@ public class TestcontainersTests(ITestOutputHelper testOutputHelper)
await StopAsync(wireMockContainer);
}
- [Fact]
+ [RunOnDockerFact]
public async Task WireMockContainer_Build_WithImage_And_StartAsync_and_StopAsync()
{
// Arrange
@@ -83,7 +83,7 @@ public class TestcontainersTests(ITestOutputHelper testOutputHelper)
await StopAsync(wireMockContainer);
}
- [Fact]
+ [RunOnDockerFact]
public async Task WireMockContainer_Build_WithImageAsText_And_StartAsync_and_StopAsync()
{
// Arrange
diff --git a/test/WireMock.Net.Tests/Testcontainers/TestcontainersTestsGrpc.cs b/test/WireMock.Net.Tests/Testcontainers/TestcontainersTestsGrpc.cs
index e01655c4..05a60757 100644
--- a/test/WireMock.Net.Tests/Testcontainers/TestcontainersTestsGrpc.cs
+++ b/test/WireMock.Net.Tests/Testcontainers/TestcontainersTestsGrpc.cs
@@ -10,6 +10,7 @@ using Meziantou.Extensions.Logging.Xunit.v3;
using Microsoft.Extensions.Logging;
using WireMock.Constants;
using WireMock.Net.Testcontainers;
+using WireMock.Net.Tests.Facts;
using WireMock.Util;
namespace WireMock.Net.Tests.Testcontainers;
@@ -25,7 +26,7 @@ public class TestcontainersTestsGrpc(ITestOutputHelper testOutputHelper)
TimestampFormat = "yyy-MM-dd HH:mm:ss.fff"
});
- [Fact]
+ [RunOnDockerFact]
public async Task WireMockContainer_Build_Grpc_TestPortsAndUrls1()
{
// Arrange
@@ -82,7 +83,7 @@ public class TestcontainersTestsGrpc(ITestOutputHelper testOutputHelper)
}
}
- [Fact]
+ [RunOnDockerFact]
public async Task WireMockContainer_Build_Grpc_TestPortsAndUrls2()
{
// Arrange
@@ -136,7 +137,7 @@ public class TestcontainersTestsGrpc(ITestOutputHelper testOutputHelper)
}
}
- [Fact]
+ [RunOnDockerFact]
public async Task WireMockContainer_Build_Grpc_ProtoDefinitionFromJson_UsingGrpcGeneratedClient()
{
var wireMockContainer = await Given_WireMockContainerIsStartedForHttpAndGrpcAsync();
@@ -150,7 +151,7 @@ public class TestcontainersTestsGrpc(ITestOutputHelper testOutputHelper)
await StopAsync(wireMockContainer);
}
- [Fact]
+ [RunOnDockerFact]
public async Task WireMockContainer_Build_Grpc_ProtoDefinitionAtServerLevel_UsingGrpcGeneratedClient()
{
var wireMockContainer = await Given_WireMockContainerWithProtoDefinitionAtServerLevelIsStartedForHttpAndGrpcAsync();
@@ -164,7 +165,7 @@ public class TestcontainersTestsGrpc(ITestOutputHelper testOutputHelper)
await StopAsync(wireMockContainer);
}
- [Fact]
+ [RunOnDockerFact]
public async Task WireMockContainer_Build_Grpc_ProtoDefinitionAtServerLevel_UsingGrpcGeneratedClient_AndWithWatchStaticMappings()
{
var wireMockContainer = await Given_WireMockContainerWithProtoDefinitionAtServerLevelWithWatchStaticMappingsIsStartedForHttpAndGrpcAsync();
diff --git a/test/WireMock.Net.Tests/WireMockServer.Proxy.cs b/test/WireMock.Net.Tests/WireMockServer.Proxy.cs
index df28f611..245940fe 100644
--- a/test/WireMock.Net.Tests/WireMockServer.Proxy.cs
+++ b/test/WireMock.Net.Tests/WireMockServer.Proxy.cs
@@ -18,6 +18,7 @@ using WireMock.Util;
namespace WireMock.Net.Tests;
+[Collection(nameof(WireMockServerProxyTests))]
public class WireMockServerProxyTests
{
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
diff --git a/test/WireMock.Net.Tests/WireMockServer.Proxy2.cs b/test/WireMock.Net.Tests/WireMockServer.Proxy2.cs
index da27e226..ba77567a 100644
--- a/test/WireMock.Net.Tests/WireMockServer.Proxy2.cs
+++ b/test/WireMock.Net.Tests/WireMockServer.Proxy2.cs
@@ -45,6 +45,4 @@ public class WireMockServerProxy2Tests
server.Dispose();
serverAsProxy.Dispose();
}
-}
-
-
+}
\ No newline at end of file