diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 76c75882..97043007 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -15,6 +15,12 @@ updates: patterns: - "NUnit*" - "coverlet*" + ignore: + # 6.3.x makes Microsoft.Testing.Extensions.CodeCoverage statically + # instrument every DLL under the repo root instead of the test bin dir, + # so parallel test hosts rewrite each other's binaries and CI hangs. + - dependency-name: "NUnit3TestAdapter" + versions: ["6.3.0", "6.3.1"] - package-ecosystem: github-actions directory: / diff --git a/Directory.Packages.props b/Directory.Packages.props index dd74b353..49b907bd 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -9,7 +9,7 @@ - + diff --git a/tests/SharpDicom.Codecs.Tests/NativeCodecsTests.cs b/tests/SharpDicom.Codecs.Tests/NativeCodecsTests.cs index 5f89dec5..c0ba0db0 100644 --- a/tests/SharpDicom.Codecs.Tests/NativeCodecsTests.cs +++ b/tests/SharpDicom.Codecs.Tests/NativeCodecsTests.cs @@ -43,7 +43,6 @@ public void IsAvailable_BeforeInitialize_ReturnsFalse() #if NET5_0_OR_GREATER [Test] [Category("NativeCodecs")] - [Order(0)] // Run this test first to check initialization before other tests public void InitializeWithCustomPath_WhenLibraryExists_Succeeds() { // This test explicitly passes the library path to Initialize diff --git a/tests/SharpDicom.Tests/Cli/LintCommandTests.cs b/tests/SharpDicom.Tests/Cli/LintCommandTests.cs index cfd8aeb0..a298369c 100644 --- a/tests/SharpDicom.Tests/Cli/LintCommandTests.cs +++ b/tests/SharpDicom.Tests/Cli/LintCommandTests.cs @@ -122,7 +122,7 @@ public async Task InvalidUidFile_StrictProfile_ThrowsOnError() }; // Strict mode throws on invalid UIDs rather than collecting them - Assert.ThrowsAsync( + await Assert.ThrowsAsync( async () => await DicomFile.OpenAsync(path, options)); } diff --git a/tests/SharpDicom.Tests/Deidentification/BatchDeidentifierTests.cs b/tests/SharpDicom.Tests/Deidentification/BatchDeidentifierTests.cs index eda38df7..1129b5bb 100644 --- a/tests/SharpDicom.Tests/Deidentification/BatchDeidentifierTests.cs +++ b/tests/SharpDicom.Tests/Deidentification/BatchDeidentifierTests.cs @@ -391,7 +391,7 @@ public async Task BatchDeidentifier_InvalidInputDir_ThrowsDirectoryNotFoundExcep var config = DeidentificationConfigLoader.GetPreset("basic-profile"); await using var batch = new BatchDeidentifier(_dbPath, config); - Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { await batch.ProcessDirectoryAsync("/nonexistent/path", _outputDir); }); diff --git a/tests/SharpDicom.Tests/IO/DicomFileReaderSequenceTests.cs b/tests/SharpDicom.Tests/IO/DicomFileReaderSequenceTests.cs index 13859ffa..430f9725 100644 --- a/tests/SharpDicom.Tests/IO/DicomFileReaderSequenceTests.cs +++ b/tests/SharpDicom.Tests/IO/DicomFileReaderSequenceTests.cs @@ -58,7 +58,7 @@ public async Task ReadElementsAsync_FileWithSequence_YieldsSequenceElement() // Assert - should have the sequence Assert.That(elements, Has.Some.Matches(e => - e.Tag == new DicomTag(0x0040, 0x0100) && e is DicomSequence)); + e is DicomSequence sequence && sequence.Tag == new DicomTag(0x0040, 0x0100))); } [Test] @@ -128,7 +128,7 @@ public async Task ReadElementsAsync_ImplicitVRFileWithSequence_ParsesCorrectly() // Assert - should have the sequence Assert.That(elements, Has.Some.Matches(e => - e.Tag == new DicomTag(0x0040, 0x0100) && e is DicomSequence)); + e is DicomSequence sequence && sequence.Tag == new DicomTag(0x0040, 0x0100))); } [Test] diff --git a/tests/SharpDicom.Tests/IO/DicomFileReaderTests.cs b/tests/SharpDicom.Tests/IO/DicomFileReaderTests.cs index d3059767..53340c04 100644 --- a/tests/SharpDicom.Tests/IO/DicomFileReaderTests.cs +++ b/tests/SharpDicom.Tests/IO/DicomFileReaderTests.cs @@ -38,7 +38,7 @@ public async Task ReadFileMetaInfoAsync_EmptyFile_Throws() await using var reader = new DicomFileReader(stream); - Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => await reader.ReadFileMetaInfoAsync()); } @@ -106,7 +106,7 @@ public async Task ReadElementsAsync_RespectsCancellation() cts.Cancel(); // TaskCanceledException is a subclass of OperationCanceledException - var ex = Assert.CatchAsync(async () => + var ex = await Assert.CatchAsync(async () => { await foreach (var _ in reader.ReadElementsAsync(cts.Token)) { @@ -219,7 +219,7 @@ public async Task AfterDispose_ReadThrows() var reader = new DicomFileReader(stream); await reader.DisposeAsync(); - Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => await reader.ReadFileMetaInfoAsync()); } diff --git a/tests/SharpDicom.Tests/IO/PixelDataSourceTests.cs b/tests/SharpDicom.Tests/IO/PixelDataSourceTests.cs index c4a9af51..12aa1b62 100644 --- a/tests/SharpDicom.Tests/IO/PixelDataSourceTests.cs +++ b/tests/SharpDicom.Tests/IO/PixelDataSourceTests.cs @@ -354,24 +354,24 @@ public void SkippedPixelDataSource_GetData_ThrowsInvalidOperationException() } [Test] - public void SkippedPixelDataSource_GetDataAsync_ThrowsInvalidOperationException() + public async Task SkippedPixelDataSource_GetDataAsync_ThrowsInvalidOperationException() { // Arrange using var source = new SkippedPixelDataSource(0, 100); // Act & Assert - Assert.ThrowsAsync(async () => await source.GetDataAsync()); + await Assert.ThrowsAsync(async () => await source.GetDataAsync()); } [Test] - public void SkippedPixelDataSource_CopyToAsync_ThrowsInvalidOperationException() + public async Task SkippedPixelDataSource_CopyToAsync_ThrowsInvalidOperationException() { // Arrange using var source = new SkippedPixelDataSource(0, 100); using var destination = new MemoryStream(); // Act & Assert - Assert.ThrowsAsync(async () => await source.CopyToAsync(destination)); + await Assert.ThrowsAsync(async () => await source.CopyToAsync(destination)); } [Test] diff --git a/tests/SharpDicom.Tests/Integration/ImplicitVRSequenceTests.cs b/tests/SharpDicom.Tests/Integration/ImplicitVRSequenceTests.cs index 335c5613..8c243cd1 100644 --- a/tests/SharpDicom.Tests/Integration/ImplicitVRSequenceTests.cs +++ b/tests/SharpDicom.Tests/Integration/ImplicitVRSequenceTests.cs @@ -141,14 +141,14 @@ public async Task Parse_NestedSequences_ParentChainCorrect() } [Test] - public void Parse_NestedSequences_ExceedsMaxDepth_ThrowsException() + public async Task Parse_NestedSequences_ExceedsMaxDepth_ThrowsException() { var data = CreateDeeplyNestedSequenceFile(10); using var stream = new MemoryStream(data); var options = new DicomReaderOptions { MaxSequenceDepth = 4 }; - Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { await DicomFile.OpenAsync(stream, options); }); diff --git a/tests/SharpDicom.Tests/Network/CEchoTests.cs b/tests/SharpDicom.Tests/Network/CEchoTests.cs index 03ea1a26..6b75d821 100644 --- a/tests/SharpDicom.Tests/Network/CEchoTests.cs +++ b/tests/SharpDicom.Tests/Network/CEchoTests.cs @@ -259,7 +259,7 @@ public async Task AssociationReject_ClientThrowsException() }; // Act & Assert - var ex = Assert.ThrowsAsync( + var ex = await Assert.ThrowsAsync( async () => await client.ConnectAsync(contexts)); Assert.That(ex, Is.Not.Null); @@ -281,7 +281,7 @@ public async Task CEchoAsync_BeforeConnect_ThrowsException() await using var client = new DicomClient(clientOptions); // Act & Assert - var ex = Assert.ThrowsAsync( + var ex = await Assert.ThrowsAsync( async () => await client.CEchoAsync()); Assert.That(ex, Is.Not.Null); @@ -326,7 +326,7 @@ public async Task CEchoAsync_VerificationNotNegotiated_ThrowsException() await client.ConnectAsync(contexts); // Act & Assert - C-ECHO should fail because Verification SOP Class not negotiated - var ex = Assert.ThrowsAsync( + var ex = await Assert.ThrowsAsync( async () => await client.CEchoAsync()); Assert.That(ex, Is.Not.Null); diff --git a/tests/SharpDicom.Tests/Network/DicomClientTests.cs b/tests/SharpDicom.Tests/Network/DicomClientTests.cs index a4d55992..c46a5e66 100644 --- a/tests/SharpDicom.Tests/Network/DicomClientTests.cs +++ b/tests/SharpDicom.Tests/Network/DicomClientTests.cs @@ -290,7 +290,7 @@ public async Task ConnectAsync_AfterDispose_ThrowsObjectDisposedException() new PresentationContext(1, DicomUID.Verification, TransferSyntax.ImplicitVRLittleEndian) }; - Assert.ThrowsAsync( + await Assert.ThrowsAsync( async () => await client.ConnectAsync(contexts)); } @@ -301,7 +301,7 @@ public async Task CEchoAsync_AfterDispose_ThrowsObjectDisposedException() var client = new DicomClient(options); await client.DisposeAsync(); - Assert.ThrowsAsync( + await Assert.ThrowsAsync( async () => await client.CEchoAsync()); } diff --git a/tests/SharpDicom.Tests/Network/Tls/TlsIntegrationTests.cs b/tests/SharpDicom.Tests/Network/Tls/TlsIntegrationTests.cs index 232be517..0c24e8fe 100644 --- a/tests/SharpDicom.Tests/Network/Tls/TlsIntegrationTests.cs +++ b/tests/SharpDicom.Tests/Network/Tls/TlsIntegrationTests.cs @@ -429,7 +429,7 @@ public async Task SelfSigned_AcceptedViaThumbprint() } [Test] - public void SelfSigned_RejectedWithoutThumbprint() + public async Task SelfSigned_RejectedWithoutThumbprint() { // Arrange var serverCert = TlsCertificateHelper.CreateSelfSignedCertificate("localhost", TimeSpan.FromHours(1)); @@ -450,7 +450,7 @@ public void SelfSigned_RejectedWithoutThumbprint() var server = new DicomServer(serverOptions); server.Start(); - Task.Delay(100).Wait(); + await Task.Delay(100); try { @@ -476,7 +476,7 @@ public void SelfSigned_RejectedWithoutThumbprint() }; // Act & Assert - Assert.ThrowsAsync(async () => + await Assert.ThrowsAsync(async () => { await using (client) { @@ -561,7 +561,7 @@ public async Task CustomCA_AcceptedWithCAInTrustStore() #if NET6_0_OR_GREATER [Test] - public void MutualTls_MissingClientCert_Fails() + public async Task MutualTls_MissingClientCert_Fails() { // Arrange using var serverCert = TlsCertificateHelper.CreateSelfSignedCertificate("localhost", TimeSpan.FromHours(1)); @@ -584,7 +584,7 @@ public void MutualTls_MissingClientCert_Fails() var server = new DicomServer(serverOptions); server.Start(); - Task.Delay(100).Wait(); + await Task.Delay(100); try { @@ -612,7 +612,7 @@ public void MutualTls_MissingClientCert_Fails() // Act & Assert - Server will close connection when client doesn't provide cert // This can manifest as TlsHandshakeException or EndOfStreamException - Assert.CatchAsync(async () => + await Assert.CatchAsync(async () => { await using (client) { @@ -628,7 +628,7 @@ public void MutualTls_MissingClientCert_Fails() } [Test] - public void InvalidCert_Rejected() + public async Task InvalidCert_Rejected() { // Arrange - Use expired certificate var expiredCert = TlsCertificateHelper.CreateExpiredCertificate("localhost"); @@ -649,7 +649,7 @@ public void InvalidCert_Rejected() var server = new DicomServer(serverOptions); server.Start(); - Task.Delay(100).Wait(); + await Task.Delay(100); try { @@ -675,7 +675,7 @@ public void InvalidCert_Rejected() }; // Act & Assert - var ex = Assert.ThrowsAsync(async () => + var ex = await Assert.ThrowsAsync(async () => { await using (client) {