From a1d4af1bc83a4e3615f7d93b79cfd51db8476b79 Mon Sep 17 00:00:00 2001 From: Adrian Codrington Date: Mon, 2 Oct 2023 11:02:40 +0800 Subject: [PATCH 1/2] Add xUnit --- .../Diagnostics/CachingLogFactoryFixture.cs | 18 +++++++++--------- source/Halibut.Tests/Halibut.Tests.csproj | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/source/Halibut.Tests/Diagnostics/CachingLogFactoryFixture.cs b/source/Halibut.Tests/Diagnostics/CachingLogFactoryFixture.cs index 8aa7483c..5c3c3513 100644 --- a/source/Halibut.Tests/Diagnostics/CachingLogFactoryFixture.cs +++ b/source/Halibut.Tests/Diagnostics/CachingLogFactoryFixture.cs @@ -4,13 +4,13 @@ using Halibut.Diagnostics; using Halibut.Diagnostics.LogCreators; using Halibut.Tests.Support.Logging; -using NUnit.Framework; +using Xunit; namespace Halibut.Tests.Diagnostics { public class CachingLogFactoryFixture { - [Test] + [Fact] public void TheSameILogIsReturnedForTheSamePrefix() { var cachingLogFactory = new InMemoryConnectionLogCreator().ToCachingLogFactory(); @@ -20,7 +20,7 @@ public void TheSameILogIsReturnedForTheSamePrefix() ReferenceEquals(first, second).Should().BeTrue(); } - [Test] + [Fact] public void TheSameILogIsReturnedForTheSameEndPoint() { var cachingLogFactory = new InMemoryConnectionLogCreator().ToCachingLogFactory(); @@ -30,7 +30,7 @@ public void TheSameILogIsReturnedForTheSameEndPoint() ReferenceEquals(first, second).Should().BeTrue(); } - [Test] + [Fact] public void TheSameILogIsReturnedForTheSameEndPointAndPrefix() { var cachingLogFactory = new InMemoryConnectionLogCreator().ToCachingLogFactory(); @@ -40,7 +40,7 @@ public void TheSameILogIsReturnedForTheSameEndPointAndPrefix() ReferenceEquals(first, second).Should().BeTrue(); } - [Test] + [Fact] public void ADifferentILogIsReturnedForTheDifferentPrefixes() { var cachingLogFactory = new InMemoryConnectionLogCreator().ToCachingLogFactory(); @@ -50,7 +50,7 @@ public void ADifferentILogIsReturnedForTheDifferentPrefixes() ReferenceEquals(first, second).Should().BeFalse(); } - [Test] + [Fact] public void ADifferentILogIsReturnedForTheDifferentEndPoints() { var cachingLogFactory = new InMemoryConnectionLogCreator().ToCachingLogFactory(); @@ -60,7 +60,7 @@ public void ADifferentILogIsReturnedForTheDifferentEndPoints() ReferenceEquals(first, second).Should().BeFalse(); } - [Test] + [Fact] public void CachingAInMemoryConnectionLogMeansTheLogsAreRetained() { var cachingLogFactory = new InMemoryConnectionLogCreator().ToCachingLogFactory(); @@ -83,7 +83,7 @@ public void CachingAInMemoryConnectionLogMeansTheLogsAreRetained() /// /// Something similar to what we actually want to do, so lets test it here. /// - [Test] + [Fact] public void CachingWithAggregateLogWriterLogCreatorAndInMemoryConnectionLogCreatorWorksAsExpected() { var logWriter = new InMemoryLogWriter(); @@ -113,4 +113,4 @@ public void CachingWithAggregateLogWriterLogCreatorAndInMemoryConnectionLogCreat logsFromWriter[1].FormattedMessage.Should().Be("Hello from endpoint"); } } -} \ No newline at end of file +} diff --git a/source/Halibut.Tests/Halibut.Tests.csproj b/source/Halibut.Tests/Halibut.Tests.csproj index 60573996..4bcd47f2 100644 --- a/source/Halibut.Tests/Halibut.Tests.csproj +++ b/source/Halibut.Tests/Halibut.Tests.csproj @@ -46,6 +46,7 @@ + From b6537a87cda349278f1c55ef98bed3f7282707fd Mon Sep 17 00:00:00 2001 From: Stephen Burman Date: Mon, 2 Oct 2023 15:50:38 +1100 Subject: [PATCH 2/2] Creating xUnit version of BaseTest, as well as xUnit versions of startup logic --- source/Halibut.Tests/BaseTest.cs | 32 +++++++++++++++++++ .../BindCertificatesForAllTests.cs | 10 ++++++ .../BumpThreadPoolForAllTests.cs | 11 +++++++ .../LowerHalibutLimitsForAllTests.cs | 23 +++++++++++++ .../ServiceModel/ServiceInvokerFixture.cs | 28 ++++++++-------- 5 files changed, 90 insertions(+), 14 deletions(-) diff --git a/source/Halibut.Tests/BaseTest.cs b/source/Halibut.Tests/BaseTest.cs index 6a88ec4e..8afa1825 100644 --- a/source/Halibut.Tests/BaseTest.cs +++ b/source/Halibut.Tests/BaseTest.cs @@ -1,7 +1,9 @@ +using System; using System.Threading; using Halibut.Tests.Support; using NUnit.Framework; using Serilog; +using Xunit; namespace Halibut.Tests { @@ -31,4 +33,34 @@ public void TearDown() Logger.Information("Finished Test Tearing Down"); } } + + // TODO: @server-at-scale - Merge with above when tests are completely cut over to xUnit. + public class BaseTestXUnit : + IClassFixture, + IClassFixture, + IClassFixture, + IDisposable + { + readonly CancellationTokenSource? cancellationTokenSource; + public CancellationToken CancellationToken { get; private set; } + public ILogger Logger { get; } + + public BaseTestXUnit() + { + Logger = new SerilogLoggerBuilder().Build().ForContext(GetType()); + Logger.Information("Test started"); + cancellationTokenSource = new CancellationTokenSource(); + CancellationToken = cancellationTokenSource.Token; + } + + public void Dispose() + { + Logger.Information("Staring Test Tearing Down"); + Logger.Information("Cancelling CancellationTokenSource"); + cancellationTokenSource?.Cancel(); + Logger.Information("Disposing CancellationTokenSource"); + cancellationTokenSource?.Dispose(); + Logger.Information("Finished Test Tearing Down"); + } + } } \ No newline at end of file diff --git a/source/Halibut.Tests/BindCertificatesForAllTests.cs b/source/Halibut.Tests/BindCertificatesForAllTests.cs index 52317e20..198891b5 100644 --- a/source/Halibut.Tests/BindCertificatesForAllTests.cs +++ b/source/Halibut.Tests/BindCertificatesForAllTests.cs @@ -1,3 +1,4 @@ +using System; using Halibut.Tests.Support; using NUnit.Framework; @@ -5,10 +6,19 @@ namespace Halibut.Tests { public class BindCertificatesForAllTests { + public BindCertificatesForAllTests() + { +#if SUPPORTS_WEB_SOCKET_CLIENT + WebSocketSslCertificateHelper.AddSslCertToLocalStore(); +#endif + } + [SetUpFixture] + [Obsolete("Remove when NUnit is fully replaced with xUnit")] public class TestsSetupClass { [OneTimeSetUp] + [Obsolete("Remove when NUnit is fully replaced with xUnit")] public void GlobalSetup() { #if SUPPORTS_WEB_SOCKET_CLIENT diff --git a/source/Halibut.Tests/BumpThreadPoolForAllTests.cs b/source/Halibut.Tests/BumpThreadPoolForAllTests.cs index 50a26874..2517f711 100644 --- a/source/Halibut.Tests/BumpThreadPoolForAllTests.cs +++ b/source/Halibut.Tests/BumpThreadPoolForAllTests.cs @@ -6,10 +6,21 @@ namespace Halibut.Tests { public class BumpThreadPoolForAllTests { + public BumpThreadPoolForAllTests() + { + var minWorkerPoolThreads = 400; + ThreadPool.GetMinThreads(out _, out var minCompletionPortThreads); + ThreadPool.GetMaxThreads(out var maxWorkerThreads, out var maxCompletionPortThreads); + ThreadPool.SetMaxThreads(Math.Max(minWorkerPoolThreads, maxWorkerThreads), Math.Max(minCompletionPortThreads, maxCompletionPortThreads)); + ThreadPool.SetMinThreads(minWorkerPoolThreads, minCompletionPortThreads); + } + [SetUpFixture] + [Obsolete("Remove when NUnit is fully replaced with xUnit")] public class TestsSetupClass { [OneTimeSetUp] + [Obsolete("Remove when NUnit is fully replaced with xUnit")] public void GlobalSetup() { var minWorkerPoolThreads = 400; diff --git a/source/Halibut.Tests/LowerHalibutLimitsForAllTests.cs b/source/Halibut.Tests/LowerHalibutLimitsForAllTests.cs index 680f1d20..b0080699 100644 --- a/source/Halibut.Tests/LowerHalibutLimitsForAllTests.cs +++ b/source/Halibut.Tests/LowerHalibutLimitsForAllTests.cs @@ -5,12 +5,35 @@ namespace Halibut.Tests { + //TODO: @server-at-scale - Remove attribute when NUnit is fully replaced with xUnit [SetUpFixture] public class LowerHalibutLimitsForAllTests { public static readonly TimeSpan HalfTheTcpReceiveTimeout = TimeSpan.FromSeconds(22.5); + + public LowerHalibutLimitsForAllTests() + { + var halibutLimitType = typeof(HalibutLimits); + + // The following 4 can be overriden, so set them high and let the test author drop the values as needed. + // Also set to a "weird value" to make it more obvious which timeout is at play in tests. + halibutLimitType.ReflectionSetFieldValue(nameof(HalibutLimits.PollingRequestQueueTimeout), TimeSpan.FromSeconds(66)); + halibutLimitType.ReflectionSetFieldValue(nameof(HalibutLimits.PollingRequestMaximumMessageProcessingTimeout), TimeSpan.FromSeconds(66)); + halibutLimitType.ReflectionSetFieldValue(nameof(HalibutLimits.RetryListeningSleepInterval), TimeSpan.FromSeconds(1)); + halibutLimitType.ReflectionSetFieldValue(nameof(HalibutLimits.ConnectionErrorRetryTimeout), TimeSpan.FromSeconds(66)); // Must always be greater than the heartbeat timeout. + + // Intentionally set higher than the heart beat, since some tests need to determine that the hart beat timeout applies. + halibutLimitType.ReflectionSetFieldValue(nameof(HalibutLimits.TcpClientSendTimeout), HalfTheTcpReceiveTimeout + HalfTheTcpReceiveTimeout); + halibutLimitType.ReflectionSetFieldValue(nameof(HalibutLimits.TcpClientReceiveTimeout), HalfTheTcpReceiveTimeout + HalfTheTcpReceiveTimeout); + + halibutLimitType.ReflectionSetFieldValue(nameof(HalibutLimits.TcpClientHeartbeatSendTimeout), TimeSpan.FromSeconds(15)); + halibutLimitType.ReflectionSetFieldValue(nameof(HalibutLimits.TcpClientHeartbeatReceiveTimeout), TimeSpan.FromSeconds(15)); + halibutLimitType.ReflectionSetFieldValue(nameof(HalibutLimits.TcpClientConnectTimeout), TimeSpan.FromSeconds(20)); + halibutLimitType.ReflectionSetFieldValue(nameof(HalibutLimits.PollingQueueWaitTimeout), TimeSpan.FromSeconds(20)); + } [OneTimeSetUp] + [Obsolete("Remove when NUnit is fully replaced with xUnit")] public static void LowerHalibutLimits() { var halibutLimitType = typeof(HalibutLimits); diff --git a/source/Halibut.Tests/ServiceModel/ServiceInvokerFixture.cs b/source/Halibut.Tests/ServiceModel/ServiceInvokerFixture.cs index cef68eb6..f192ae2f 100644 --- a/source/Halibut.Tests/ServiceModel/ServiceInvokerFixture.cs +++ b/source/Halibut.Tests/ServiceModel/ServiceInvokerFixture.cs @@ -7,14 +7,14 @@ using Halibut.Tests.Util; using Halibut.TestUtils.Contracts; using Halibut.Transport.Protocol; -using NUnit.Framework; +using Xunit; namespace Halibut.Tests.ServiceModel { - public class ServiceInvokerFixture : BaseTest + public class ServiceInvokerFixture : BaseTestXUnit { - [Test] + [Fact] public void InvokeWithParams() { var serviceFactory = new ServiceFactoryBuilder() @@ -33,8 +33,8 @@ public void InvokeWithParams() var response = sut.Invoke(request); response.Result.Should().Be($"{value}..."); } - - [Test] + + [Fact] public void InvokeWithNoParams() { var serviceFactory = new ServiceFactoryBuilder() @@ -51,8 +51,8 @@ public void InvokeWithNoParams() var response = sut.Invoke(request); response.Result.Should().Be(1); } - - [Test] + + [Fact] public async Task AsyncInvokeWithParamsOnAsyncService() { var serviceFactory = new ServiceFactoryBuilder() @@ -72,7 +72,7 @@ public async Task AsyncInvokeWithParamsOnAsyncService() response.Result.Should().Be($"{value}Async..."); } - [Test] + [Fact] public async Task AsyncInvokeWithNoParamsOnAsyncService() { var serviceFactory = new ServiceFactoryBuilder() @@ -90,7 +90,7 @@ public async Task AsyncInvokeWithNoParamsOnAsyncService() response.Result.Should().Be(1); } - [Test] + [Fact] public async Task AsyncInvokeWithParamsOnSyncService() { var serviceFactory = new ServiceFactoryBuilder() @@ -110,7 +110,7 @@ public async Task AsyncInvokeWithParamsOnSyncService() response.Result.Should().Be($"{value}..."); } - [Test] + [Fact] public async Task AsyncInvokeWithNoParamsOnSyncService() { var serviceFactory = new ServiceFactoryBuilder() @@ -128,7 +128,7 @@ public async Task AsyncInvokeWithNoParamsOnSyncService() response.Result.Should().Be(1); } - [Test] + [Fact] public async Task AsyncInvokeWithNoParams_AsyncServiceMissingSuffix() { var serviceFactory = new ServiceFactoryBuilder() @@ -146,7 +146,7 @@ public async Task AsyncInvokeWithNoParams_AsyncServiceMissingSuffix() await AssertAsync.Throws(() => sut.InvokeAsync(request)); } - [Test] + [Fact] public async Task AsyncInvokeWithNoParams_AsyncServiceMissingCancellationToken() { var serviceFactory = new ServiceFactoryBuilder() @@ -164,7 +164,7 @@ public async Task AsyncInvokeWithNoParams_AsyncServiceMissingCancellationToken() await AssertAsync.Throws(() => sut.InvokeAsync(request)); } - [Test] + [Fact] public async Task AsyncInvokeWithParams_AsyncServiceMissingSuffix() { var serviceFactory = new ServiceFactoryBuilder() @@ -184,7 +184,7 @@ public async Task AsyncInvokeWithParams_AsyncServiceMissingSuffix() await AssertAsync.Throws(() => sut.InvokeAsync(request)); } - [Test] + [Fact] public async Task AsyncInvokeWithParams_AsyncServiceMissingCancellationToken() { var serviceFactory = new ServiceFactoryBuilder()