diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 4ac797e..18ee687 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -41,7 +41,9 @@ jobs: - name: Build run: dotnet build --no-restore --configuration Release -p:Version=${{ steps.gitversion.outputs.semVer }} -p:ContinuousIntegrationBuild=true -p:Deterministic=true - name: Test - run: dotnet test --no-build --configuration Release --verbosity normal --filter Category!=Explicit + # xUnit v3 runs on Microsoft.Testing.Platform (global.json). Exit code 8 means a project ran no tests, + # as the transport test projects only contain Explicit tests. + run: dotnet test --solution Obvs.sln --no-build --configuration Release -- --filter-not-trait "Category=Explicit" --ignore-exit-code 8 - name: Pack if: github.event_name == 'push' run: | diff --git a/Directory.Packages.props b/Directory.Packages.props index ec3fc53..1398065 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -28,7 +28,7 @@ - + diff --git a/Obvs.ActiveMQ.Tests/Obvs.ActiveMQ.Tests.csproj b/Obvs.ActiveMQ.Tests/Obvs.ActiveMQ.Tests.csproj index ef273a5..185f3b4 100644 --- a/Obvs.ActiveMQ.Tests/Obvs.ActiveMQ.Tests.csproj +++ b/Obvs.ActiveMQ.Tests/Obvs.ActiveMQ.Tests.csproj @@ -1,5 +1,6 @@  + Exe net10.0 Christopher Read Copyright © Christopher Read 2014 @@ -10,7 +11,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Obvs.Kafka.Tests/Obvs.Kafka.Tests.csproj b/Obvs.Kafka.Tests/Obvs.Kafka.Tests.csproj index b2c2c56..4d01604 100644 --- a/Obvs.Kafka.Tests/Obvs.Kafka.Tests.csproj +++ b/Obvs.Kafka.Tests/Obvs.Kafka.Tests.csproj @@ -1,12 +1,13 @@  + Exe net10.0 - + all runtime; build; native; contentfiles; analyzers diff --git a/Obvs.Kafka.Tests/TestMessageSendAndReceive.cs b/Obvs.Kafka.Tests/TestMessageSendAndReceive.cs index 3924300..714639e 100644 --- a/Obvs.Kafka.Tests/TestMessageSendAndReceive.cs +++ b/Obvs.Kafka.Tests/TestMessageSendAndReceive.cs @@ -82,7 +82,7 @@ public async Task TestSendAndReceiveMessage() var delay1 = TimeSpan.FromSeconds(2); Console.WriteLine($"Waiting {delay1}..."); - await Task.Delay(delay1); + await Task.Delay(delay1, TestContext.Current.CancellationToken); await _publisher.PublishAsync(new TestMessage($"hello world {DateTime.Now}")); await _publisher.PublishAsync(new TestMessage($"hello world {DateTime.Now}")); @@ -90,7 +90,7 @@ public async Task TestSendAndReceiveMessage() var delay2 = TimeSpan.FromSeconds(2); Console.WriteLine($"Waiting {delay2}..."); - await Task.Delay(delay2); + await Task.Delay(delay2, TestContext.Current.CancellationToken); Assert.NotEmpty(messages); Assert.Equal(3, messages.Count); diff --git a/Obvs.Logging.Tests/Obvs.Logging.Tests.csproj b/Obvs.Logging.Tests/Obvs.Logging.Tests.csproj index fc49db7..7547126 100644 --- a/Obvs.Logging.Tests/Obvs.Logging.Tests.csproj +++ b/Obvs.Logging.Tests/Obvs.Logging.Tests.csproj @@ -1,11 +1,12 @@  + Exe net10.0 - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Obvs.Monitoring.Tests/Obvs.Monitoring.Tests.csproj b/Obvs.Monitoring.Tests/Obvs.Monitoring.Tests.csproj index dd3a4a2..736a933 100644 --- a/Obvs.Monitoring.Tests/Obvs.Monitoring.Tests.csproj +++ b/Obvs.Monitoring.Tests/Obvs.Monitoring.Tests.csproj @@ -1,5 +1,6 @@  + Exe net10.0 Christopher Read Copyright © Christopher Read 2014 @@ -10,7 +11,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/Obvs.NATS.Tests/Obvs.NATS.Tests.csproj b/Obvs.NATS.Tests/Obvs.NATS.Tests.csproj index 1cf729c..188814a 100644 --- a/Obvs.NATS.Tests/Obvs.NATS.Tests.csproj +++ b/Obvs.NATS.Tests/Obvs.NATS.Tests.csproj @@ -1,12 +1,13 @@  + Exe net10.0 - + all runtime; build; native; contentfiles; analyzers diff --git a/Obvs.NATS.Tests/TestServiceBus.cs b/Obvs.NATS.Tests/TestServiceBus.cs index e7bb5ca..be60588 100644 --- a/Obvs.NATS.Tests/TestServiceBus.cs +++ b/Obvs.NATS.Tests/TestServiceBus.cs @@ -49,7 +49,7 @@ public async Task TestBasicSendReceiveOfAllMessageTypes() var response = await bus.GetResponse(new TestRequest()); Console.WriteLine(response); - await Task.Delay(TimeSpan.FromSeconds(1)); + await Task.Delay(TimeSpan.FromSeconds(1), TestContext.Current.CancellationToken); ((IDisposable)bus).Dispose(); } diff --git a/Obvs.NATS.Tests/TestSourceAndPublisher.cs b/Obvs.NATS.Tests/TestSourceAndPublisher.cs index 1838bf6..ea880a1 100644 --- a/Obvs.NATS.Tests/TestSourceAndPublisher.cs +++ b/Obvs.NATS.Tests/TestSourceAndPublisher.cs @@ -39,7 +39,7 @@ public async Task TestSendAndReceiveMessage() await publisher.PublishAsync(new TestMessage {Id = i}); } - await Task.Delay(TimeSpan.FromSeconds(1)); + await Task.Delay(TimeSpan.FromSeconds(1), TestContext.Current.CancellationToken); subscription.Dispose(); } } diff --git a/Obvs.NetMQ.Tests/Obvs.NetMQ.Tests.csproj b/Obvs.NetMQ.Tests/Obvs.NetMQ.Tests.csproj index 4372533..bca51df 100644 --- a/Obvs.NetMQ.Tests/Obvs.NetMQ.Tests.csproj +++ b/Obvs.NetMQ.Tests/Obvs.NetMQ.Tests.csproj @@ -1,12 +1,13 @@  + Exe net10.0 - + all runtime; build; native; contentfiles; analyzers diff --git a/Obvs.NetMQ.Tests/TestPublishSubscribe.cs b/Obvs.NetMQ.Tests/TestPublishSubscribe.cs index 1c2a9e9..cec7c3c 100644 --- a/Obvs.NetMQ.Tests/TestPublishSubscribe.cs +++ b/Obvs.NetMQ.Tests/TestPublishSubscribe.cs @@ -13,6 +13,8 @@ namespace Obvs.NetMQ.Tests { + // Each test uses its own port, clear of the ranges TestServiceBusWithNetMq binds, + // because xUnit runs test classes in parallel public class TestPublishSubscribe { [Fact, Trait("Category", "Explicit")] @@ -29,7 +31,7 @@ public async Task TestSendingAndReceivingStringsOverLocalHost() }, err => Console.WriteLine("Error: " + err)); - IMessageSource source = new MessageSource("tcp://localhost:5556", + IMessageSource source = new MessageSource("tcp://localhost:5560", new IMessageDeserializer[] { new JsonMessageDeserializer(), @@ -39,7 +41,7 @@ public async Task TestSendingAndReceivingStringsOverLocalHost() var sub = source.Messages.Subscribe(observer); - IMessagePublisher publisher = new MessagePublisher("tcp://localhost:5556", + IMessagePublisher publisher = new MessagePublisher("tcp://localhost:5560", new JsonMessageSerializer(), topic); await publisher.PublishAsync(new TestMessage1 { Id = 1 }); @@ -48,7 +50,11 @@ public async Task TestSendingAndReceivingStringsOverLocalHost() await publisher.PublishAsync(new TestMessage2 { Id = 2 }); await publisher.PublishAsync(new TestMessage1 { Id = 3 }); await publisher.PublishAsync(new TestMessage2 { Id = 3 }); - await Task.Delay(TimeSpan.FromSeconds(2)); + await Task.Delay(TimeSpan.FromSeconds(2), TestContext.Current.CancellationToken); + + sub.Dispose(); + source.Dispose(); + publisher.Dispose(); Assert.True(messages.OfType().Any(msg => msg.Id == 1), "TestMessage1 1 not received"); Assert.True(messages.OfType().Any(msg => msg.Id == 2), "TestMessage1 2 not received"); @@ -57,9 +63,6 @@ public async Task TestSendingAndReceivingStringsOverLocalHost() Assert.True(messages.OfType().Any(msg => msg.Id == 1), "TestMessage2 1 not received"); Assert.True(messages.OfType().Any(msg => msg.Id == 2), "TestMessage2 2 not received"); Assert.True(messages.OfType().Any(msg => msg.Id == 3), "TestMessage2 3 not received"); - - sub.Dispose(); - source.Dispose(); } [Fact, Trait("Category", "Explicit")] @@ -76,7 +79,7 @@ public async Task TestSendingAndReceivingBytesOverLocalHost() }, err => Console.WriteLine("Error: " + err)); - IMessageSource source = new MessageSource("tcp://localhost:5556", + IMessageSource source = new MessageSource("tcp://localhost:5561", new IMessageDeserializer[] { new ProtoBufMessageDeserializer(), @@ -86,7 +89,7 @@ public async Task TestSendingAndReceivingBytesOverLocalHost() var sub = source.Messages.Subscribe(observer); - IMessagePublisher publisher = new MessagePublisher("tcp://localhost:5556", + IMessagePublisher publisher = new MessagePublisher("tcp://localhost:5561", new ProtoBufMessageSerializer(), topic); await publisher.PublishAsync(new TestMessage1 { Id = 1 }); @@ -95,7 +98,11 @@ public async Task TestSendingAndReceivingBytesOverLocalHost() await publisher.PublishAsync(new TestMessage2 { Id = 2 }); await publisher.PublishAsync(new TestMessage1 { Id = 3 }); await publisher.PublishAsync(new TestMessage2 { Id = 3 }); - await Task.Delay(TimeSpan.FromSeconds(2)); + await Task.Delay(TimeSpan.FromSeconds(2), TestContext.Current.CancellationToken); + + sub.Dispose(); + source.Dispose(); + publisher.Dispose(); Assert.True(messages.OfType().Any(msg => msg.Id == 1), "TestMessage1 1 not received"); Assert.True(messages.OfType().Any(msg => msg.Id == 2), "TestMessage1 2 not received"); @@ -104,9 +111,6 @@ public async Task TestSendingAndReceivingBytesOverLocalHost() Assert.True(messages.OfType().Any(msg => msg.Id == 1), "TestMessage2 1 not received"); Assert.True(messages.OfType().Any(msg => msg.Id == 2), "TestMessage2 2 not received"); Assert.True(messages.OfType().Any(msg => msg.Id == 3), "TestMessage2 3 not received"); - - sub.Dispose(); - source.Dispose(); } [Fact, Trait("Category", "Explicit")] @@ -117,8 +121,10 @@ public async Task TestMessagesLongerThan32Characters() const string topic = "TestTopicxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; IDisposable sub; + MessageSource source; + MessagePublisher publisher; { - var source = new MessageSource("tcp://localhost:5557", + source = new MessageSource("tcp://localhost:5562", new IMessageDeserializer[] { new ProtoBufMessageDeserializer(), @@ -134,7 +140,7 @@ public async Task TestMessagesLongerThan32Characters() } { - var publisher = new MessagePublisher("tcp://localhost:5557", + publisher = new MessagePublisher("tcp://localhost:5562", new ProtoBufMessageSerializer(), topic); @@ -147,9 +153,11 @@ await publisher.PublishAsync(new TestMessageWhereTypeIsVeryMuchDefinitionLongerT } } - await Task.Delay(TimeSpan.FromSeconds(2)); + await Task.Delay(TimeSpan.FromSeconds(2), TestContext.Current.CancellationToken); sub.Dispose(); + source.Dispose(); + publisher.Dispose(); } [ProtoContract] diff --git a/Obvs.NetMQ.Tests/TestServiceBusWithNetMq.cs b/Obvs.NetMQ.Tests/TestServiceBusWithNetMq.cs index 851819c..0ce3fb6 100644 --- a/Obvs.NetMQ.Tests/TestServiceBusWithNetMq.cs +++ b/Obvs.NetMQ.Tests/TestServiceBusWithNetMq.cs @@ -139,7 +139,12 @@ public async Task TestServiceEndpointsOverLocalHostSockets() serviceBusClient2.GetResponses(new TestRequest1 { Id = 6 }).Subscribe(fakeClient1); // wait some time until we think all messages have been sent and received - await Task.Delay(TimeSpan.FromSeconds(3)); + await Task.Delay(TimeSpan.FromSeconds(3), TestContext.Current.CancellationToken); + + // dispose before asserting, so a failed assertion doesn't leave sockets bound for other tests + ((IDisposable)serviceBus).Dispose(); + ((IDisposable)serviceBusClient1).Dispose(); + ((IDisposable)serviceBusClient2).Dispose(); // test we got everything we expected Assert.True(messages.OfType().Count() == 2, "TestCommand1"); diff --git a/Obvs.RabbitMQ.Tests/Obvs.RabbitMQ.Tests.csproj b/Obvs.RabbitMQ.Tests/Obvs.RabbitMQ.Tests.csproj index 7326434..3913650 100644 --- a/Obvs.RabbitMQ.Tests/Obvs.RabbitMQ.Tests.csproj +++ b/Obvs.RabbitMQ.Tests/Obvs.RabbitMQ.Tests.csproj @@ -1,5 +1,6 @@  + Exe net10.0 @@ -11,7 +12,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Obvs.RabbitMQ.Tests/TestSendingAndReceiving.cs b/Obvs.RabbitMQ.Tests/TestSendingAndReceiving.cs index 428391d..6b053c8 100644 --- a/Obvs.RabbitMQ.Tests/TestSendingAndReceiving.cs +++ b/Obvs.RabbitMQ.Tests/TestSendingAndReceiving.cs @@ -62,7 +62,7 @@ public async Task TestSendReceiveAs(string format) await messagePublisher.PublishAsync(message); } - await Task.Delay(TimeSpan.FromSeconds(2)); + await Task.Delay(TimeSpan.FromSeconds(2), TestContext.Current.CancellationToken); Assert.True(receivedMessages1.Count == 7, "Incorrect number of messages received for first subscription"); Assert.True(receivedMessages2.Count == 7, "Incorrect number of messages received for second subscription"); @@ -80,7 +80,7 @@ public async Task TestSendReceiveAs(string format) sub2.Dispose(); messagePublisher.Dispose(); messageSource.Dispose(); - await connection.Value.CloseAsync(); + await connection.Value.CloseAsync(cancellationToken: TestContext.Current.CancellationToken); } private static IMessagePublisher CreateMessagePublisher(string format, Lazy connection, diff --git a/Obvs.RabbitMQ.Tests/TestServiceBus.cs b/Obvs.RabbitMQ.Tests/TestServiceBus.cs index 4208d07..f062580 100644 --- a/Obvs.RabbitMQ.Tests/TestServiceBus.cs +++ b/Obvs.RabbitMQ.Tests/TestServiceBus.cs @@ -48,7 +48,7 @@ public async Task ShouldSendAndReceiveMessagesOverServiceBus() var sub6 = serviceBus.GetResponses(new TestRequest { Id = 456 }).Subscribe(observer); // wait some time until we think all messages have been sent and received from RabbitMQ - await Task.Delay(TimeSpan.FromSeconds(1)); + await Task.Delay(TimeSpan.FromSeconds(1), TestContext.Current.CancellationToken); // test we got everything we expected Assert.True(messages.OfType().Count() == 1, "TestCommand not received"); diff --git a/Obvs.Serialization.Tests/Obvs.Serialization.Tests.csproj b/Obvs.Serialization.Tests/Obvs.Serialization.Tests.csproj index 5a5cc4d..8078577 100644 --- a/Obvs.Serialization.Tests/Obvs.Serialization.Tests.csproj +++ b/Obvs.Serialization.Tests/Obvs.Serialization.Tests.csproj @@ -1,5 +1,6 @@  + Exe net10.0 Christopher Read Copyright © Christopher Read 2014 @@ -10,7 +11,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/Obvs.Tests/Obvs.Tests.csproj b/Obvs.Tests/Obvs.Tests.csproj index 79be17f..3c838ce 100644 --- a/Obvs.Tests/Obvs.Tests.csproj +++ b/Obvs.Tests/Obvs.Tests.csproj @@ -1,5 +1,6 @@  + Exe net10.0 Christopher Read Copyright © Christopher Read 2014 @@ -10,7 +11,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/Obvs.Tests/TestServiceBus.cs b/Obvs.Tests/TestServiceBus.cs index b31f12f..42e2b24 100644 --- a/Obvs.Tests/TestServiceBus.cs +++ b/Obvs.Tests/TestServiceBus.cs @@ -12,7 +12,6 @@ using Obvs.Monitoring; using Obvs.Types; using Xunit; -using Xunit.Abstractions; namespace Obvs.Tests { diff --git a/Obvs.Tests/TestSubjectMessageBus.cs b/Obvs.Tests/TestSubjectMessageBus.cs index 7a8a1e5..880c692 100644 --- a/Obvs.Tests/TestSubjectMessageBus.cs +++ b/Obvs.Tests/TestSubjectMessageBus.cs @@ -1,5 +1,6 @@ using System; using System.Threading; +using System.Threading.Tasks; using Xunit; namespace Obvs.Tests @@ -15,7 +16,7 @@ public TestSubjectMessageBus() } [Fact] - public void PublishBlocksUntilMessageHasBeenConsumed() + public async Task PublishBlocksUntilMessageHasBeenConsumed() { int subscriberThreadId = -1; _testObj.Messages.Subscribe(_ => subscriberThreadId = Thread.CurrentThread.ManagedThreadId); @@ -27,14 +28,14 @@ public void PublishBlocksUntilMessageHasBeenConsumed() Assert.NotEqual(-1, subscriberThreadId); Assert.Equal(threadId, subscriberThreadId); - task.Wait(); + await task; } [Fact] public void PublishReturnsWithNoObservers() { - Assert.True(_testObj.PublishAsync("Bleb").Wait(1)); + Assert.True(_testObj.PublishAsync("Bleb").IsCompleted); } } } \ No newline at end of file diff --git a/Obvs.Tests/TestSubjectMessageBusWithScheduler.cs b/Obvs.Tests/TestSubjectMessageBusWithScheduler.cs index a71c459..ee007d2 100644 --- a/Obvs.Tests/TestSubjectMessageBusWithScheduler.cs +++ b/Obvs.Tests/TestSubjectMessageBusWithScheduler.cs @@ -1,5 +1,6 @@ using System; using Microsoft.Reactive.Testing; +using System.Threading.Tasks; using Xunit; namespace Obvs.Tests @@ -17,23 +18,23 @@ public TestSubjectMessageBusWithScheduler() } [Fact] - public void OnNextReturnsImmediatelyEvenIfMessageIsntEmitted() + public async Task OnNextReturnsImmediatelyEvenIfMessageIsntEmitted() { bool received = false; _testObj.Messages.Subscribe(_ => received = true); - _testObj.PublishAsync("Bleb").Wait(); + await _testObj.PublishAsync("Bleb"); Assert.False(received); } [Fact] - public void OnNextReturnsImmediatelyThenMessageEmitted() + public async Task OnNextReturnsImmediatelyThenMessageEmitted() { bool received = false; _testObj.Messages.Subscribe(_ => received = true); - _testObj.PublishAsync("Bleb").Wait(); + await _testObj.PublishAsync("Bleb"); _scheduler.AdvanceBy(1); @@ -41,15 +42,15 @@ public void OnNextReturnsImmediatelyThenMessageEmitted() } [Fact] - public void PublishReturnsImmediatelyWithNoObservers() + public async Task PublishReturnsImmediatelyWithNoObservers() { - _testObj.PublishAsync("Bleb").Wait(); + await _testObj.PublishAsync("Bleb"); } [Fact] - public void PublishReturnsImmediatelyWithNoObservers_NoCachedMessages() + public async Task PublishReturnsImmediatelyWithNoObservers_NoCachedMessages() { - _testObj.PublishAsync("Bleb").Wait(); + await _testObj.PublishAsync("Bleb"); bool received = false; _testObj.Messages.Subscribe(_ => received = true); diff --git a/Obvs.Tests/TestSubjectServiceBus.cs b/Obvs.Tests/TestSubjectServiceBus.cs index 3e5380c..6f22667 100644 --- a/Obvs.Tests/TestSubjectServiceBus.cs +++ b/Obvs.Tests/TestSubjectServiceBus.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Threading; using Obvs.Types; +using System.Threading.Tasks; using Xunit; namespace Obvs.Tests @@ -17,7 +18,7 @@ public TestSubjectServiceBus() } [Fact] - public void PublishBlocksUntilMessageHasBeenConsumed() + public async Task PublishBlocksUntilMessageHasBeenConsumed() { var subscriberThreadId = -1; _testObj.Events.Subscribe(_ => subscriberThreadId = Thread.CurrentThread.ManagedThreadId); @@ -29,11 +30,11 @@ public void PublishBlocksUntilMessageHasBeenConsumed() Assert.NotEqual(-1, subscriberThreadId); Assert.Equal(threadId, subscriberThreadId); - task.Wait(); + await task; } [Fact] - public void SendBlocksUntilMessageHasBeenConsumed() + public async Task SendBlocksUntilMessageHasBeenConsumed() { var subscriberThreadId = -1; _testObj.Commands.Subscribe(_ => subscriberThreadId = Thread.CurrentThread.ManagedThreadId); @@ -45,7 +46,7 @@ public void SendBlocksUntilMessageHasBeenConsumed() Assert.NotEqual(-1, subscriberThreadId); Assert.Equal(threadId, subscriberThreadId); - task.Wait(); + await task; } [Fact] @@ -78,13 +79,13 @@ public void GetResponsesReturnsResponseFromReply() [Fact] public void PublishReturnsWithNoObservers() { - Assert.True(_testObj.PublishAsync(new TestServiceEvent1()).Wait(1)); + Assert.True(_testObj.PublishAsync(new TestServiceEvent1()).IsCompleted); } [Fact] public void SendReturnsWithNoObservers() { - Assert.True(_testObj.SendAsync(new TestServiceCommand1()).Wait(1)); + Assert.True(_testObj.SendAsync(new TestServiceCommand1()).IsCompleted); } } } \ No newline at end of file diff --git a/global.json b/global.json new file mode 100644 index 0000000..3140116 --- /dev/null +++ b/global.json @@ -0,0 +1,5 @@ +{ + "test": { + "runner": "Microsoft.Testing.Platform" + } +}