diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index d19c3a99..feafd8ad 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -21,9 +21,15 @@ env:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
pg_db: marten_testing
pg_user: postgres
+ # CONFIGURATION binds to the Nuke [Parameter] of the same name (Nuke reads parameters from the
+ # environment), so it genuinely selects the Release build. FRAMEWORK and
+ # DISABLE_TEST_PARALLELIZATION used to sit here too but bound to nothing: there is no Framework
+ # parameter, and no test project, runner config, or build target ever read the latter. The two
+ # suites that actually must not run concurrently (CodegenTests mutates process-wide statics and
+ # compiles assemblies; CommandLineTests redirects Console) declare that in code via
+ # [assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)], which xunit v3 still
+ # honors, so the serialization is enforced where it can't be silently dropped.
CONFIGURATION: Release
- FRAMEWORK: net9.0
- DISABLE_TEST_PARALLELIZATION: true
NUKE_TELEMETRY_OPTOUT: true
jobs:
diff --git a/Directory.Packages.props b/Directory.Packages.props
index d341748b..8132fade 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -80,11 +80,11 @@
-
+
-
-
+
+
diff --git a/src/CodegenTests.FSharp/CodegenTests.FSharp.csproj b/src/CodegenTests.FSharp/CodegenTests.FSharp.csproj
index 757bbe0a..a806e676 100644
--- a/src/CodegenTests.FSharp/CodegenTests.FSharp.csproj
+++ b/src/CodegenTests.FSharp/CodegenTests.FSharp.csproj
@@ -24,7 +24,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/CodegenTests.FSharp/FSharpCompilationGate.cs b/src/CodegenTests.FSharp/FSharpCompilationGate.cs
index 35af2488..82ae7c40 100644
--- a/src/CodegenTests.FSharp/FSharpCompilationGate.cs
+++ b/src/CodegenTests.FSharp/FSharpCompilationGate.cs
@@ -1,6 +1,5 @@
using System.Diagnostics;
using Shouldly;
-using Xunit.Abstractions;
namespace CodegenTests.FSharp;
diff --git a/src/CodegenTests/CodeGeneration_ordering_determinism.cs b/src/CodegenTests/CodeGeneration_ordering_determinism.cs
index fc7cbacd..75b444d5 100644
--- a/src/CodegenTests/CodeGeneration_ordering_determinism.cs
+++ b/src/CodegenTests/CodeGeneration_ordering_determinism.cs
@@ -3,7 +3,6 @@
using JasperFx.CodeGeneration.Model;
using Shouldly;
using Xunit;
-using Xunit.Abstractions;
namespace CodegenTests;
diff --git a/src/CodegenTests/CodegenTests.csproj b/src/CodegenTests/CodegenTests.csproj
index 0768ed8b..697b779e 100644
--- a/src/CodegenTests/CodegenTests.csproj
+++ b/src/CodegenTests/CodegenTests.csproj
@@ -10,7 +10,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/CodegenTests/FSharpControlFlowTests.cs b/src/CodegenTests/FSharpControlFlowTests.cs
index 5088aac6..28049f5b 100644
--- a/src/CodegenTests/FSharpControlFlowTests.cs
+++ b/src/CodegenTests/FSharpControlFlowTests.cs
@@ -2,7 +2,6 @@
using JasperFx.CodeGeneration.Frames;
using JasperFx.CodeGeneration.Model;
using Shouldly;
-using Xunit.Abstractions;
namespace CodegenTests;
diff --git a/src/CodegenTests/GeneratedTypeTests.cs b/src/CodegenTests/GeneratedTypeTests.cs
index 9f21b4db..c3c1ac5c 100644
--- a/src/CodegenTests/GeneratedTypeTests.cs
+++ b/src/CodegenTests/GeneratedTypeTests.cs
@@ -2,7 +2,6 @@
using JasperFx.CodeGeneration.Model;
using JasperFx.Core;
using Shouldly;
-using Xunit.Abstractions;
namespace CodegenTests;
diff --git a/src/CodegenTests/MethodCallTester.cs b/src/CodegenTests/MethodCallTester.cs
index e9054ec0..9d84063a 100644
--- a/src/CodegenTests/MethodCallTester.cs
+++ b/src/CodegenTests/MethodCallTester.cs
@@ -3,7 +3,6 @@
using JasperFx.CodeGeneration.Model;
using NSubstitute;
using Shouldly;
-using Xunit.Sdk;
namespace CodegenTests;
@@ -478,5 +477,15 @@ public Task GetString()
public interface IMartenOp
{
-
+
+}
+
+///
+/// A return type for the MethodCallTarget probes below. The tests only assert that
+/// MethodCall infers this exact type (and the argument name derived from it), so any reference
+/// type does; it previously borrowed Xunit.Sdk.ErrorMessage via a stray `using Xunit.Sdk`,
+/// which quietly tied a codegen test to xunit's internals and broke on the v3 upgrade.
+///
+public class ErrorMessage
+{
}
\ No newline at end of file
diff --git a/src/CodegenTests/Samples/Frames.cs b/src/CodegenTests/Samples/Frames.cs
index dec0f56d..d086ab49 100644
--- a/src/CodegenTests/Samples/Frames.cs
+++ b/src/CodegenTests/Samples/Frames.cs
@@ -3,7 +3,6 @@
using JasperFx.CodeGeneration.Frames;
using JasperFx.CodeGeneration.Model;
using Xunit;
-using Xunit.Abstractions;
namespace CodegenTests.Samples;
diff --git a/src/CodegenTests/Samples/HelloWorld.cs b/src/CodegenTests/Samples/HelloWorld.cs
index 06cd78f5..3b4ab63d 100644
--- a/src/CodegenTests/Samples/HelloWorld.cs
+++ b/src/CodegenTests/Samples/HelloWorld.cs
@@ -2,7 +2,6 @@
using System.Linq;
using JasperFx.RuntimeCompiler;
using Xunit;
-using Xunit.Abstractions;
namespace CodegenTests.Samples;
diff --git a/src/CodegenTests/Samples/InjectedFieldUsage.cs b/src/CodegenTests/Samples/InjectedFieldUsage.cs
index 069437a2..a96305f6 100644
--- a/src/CodegenTests/Samples/InjectedFieldUsage.cs
+++ b/src/CodegenTests/Samples/InjectedFieldUsage.cs
@@ -3,7 +3,6 @@
using JasperFx.CodeGeneration.Frames;
using JasperFx.CodeGeneration.Model;
using Xunit;
-using Xunit.Abstractions;
namespace CodegenTests.Samples;
diff --git a/src/CodegenTests/Samples/UsingSourceWriter.cs b/src/CodegenTests/Samples/UsingSourceWriter.cs
index 78567679..54fdb234 100644
--- a/src/CodegenTests/Samples/UsingSourceWriter.cs
+++ b/src/CodegenTests/Samples/UsingSourceWriter.cs
@@ -1,7 +1,6 @@
using System;
using JasperFx.CodeGeneration;
using Xunit;
-using Xunit.Abstractions;
namespace CodegenTests.Samples;
diff --git a/src/CodegenTests/Services/BruteForceTests.cs b/src/CodegenTests/Services/BruteForceTests.cs
index 0823fed9..7b393cd5 100644
--- a/src/CodegenTests/Services/BruteForceTests.cs
+++ b/src/CodegenTests/Services/BruteForceTests.cs
@@ -5,7 +5,6 @@
using JasperFx.RuntimeCompiler;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
-using Xunit.Abstractions;
namespace CodegenTests.Services;
diff --git a/src/CodegenTests/Services/inline_enumerable_with_mixed_lifetimes.cs b/src/CodegenTests/Services/inline_enumerable_with_mixed_lifetimes.cs
index 5e179293..f590daee 100644
--- a/src/CodegenTests/Services/inline_enumerable_with_mixed_lifetimes.cs
+++ b/src/CodegenTests/Services/inline_enumerable_with_mixed_lifetimes.cs
@@ -7,7 +7,6 @@
using JasperFx.RuntimeCompiler;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
-using Xunit.Abstractions;
namespace CodegenTests.Services;
diff --git a/src/CodegenTests/Services/keyed_constructor_injection.cs b/src/CodegenTests/Services/keyed_constructor_injection.cs
index 98fe597e..45ac0729 100644
--- a/src/CodegenTests/Services/keyed_constructor_injection.cs
+++ b/src/CodegenTests/Services/keyed_constructor_injection.cs
@@ -6,7 +6,6 @@
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Xunit;
-using Xunit.Abstractions;
namespace CodegenTests.Services;
diff --git a/src/CodegenTests/Services/keyed_service_location.cs b/src/CodegenTests/Services/keyed_service_location.cs
index af92e298..25f37cc0 100644
--- a/src/CodegenTests/Services/keyed_service_location.cs
+++ b/src/CodegenTests/Services/keyed_service_location.cs
@@ -5,7 +5,6 @@
using JasperFx.RuntimeCompiler;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
-using Xunit.Abstractions;
namespace CodegenTests.Services;
diff --git a/src/CommandLineTests/CommandExecutorTester.cs b/src/CommandLineTests/CommandExecutorTester.cs
index c520115e..4c54f5ac 100644
--- a/src/CommandLineTests/CommandExecutorTester.cs
+++ b/src/CommandLineTests/CommandExecutorTester.cs
@@ -2,6 +2,7 @@
using JasperFx.CommandLine;
using JasperFx.Core;
using Shouldly;
+using Spectre.Console;
namespace CommandLineTests
{
@@ -23,6 +24,17 @@ public CommandExecutorTester()
{
Console.SetOut(theOutput);
+ // CommandExecutor renders failures through Spectre's AnsiConsole, which caches the
+ // TextWriter it binds to on first use anywhere in the process. Console.SetOut alone
+ // therefore does NOT redirect the failure path -- whichever test touched Spectre first
+ // has already pinned the writer. That made run_an_async_command_that_fails pass or fail
+ // purely on test ordering (it survived xunit v2's order and broke under v3's). Bind
+ // Spectre explicitly so this class captures failure output regardless of order.
+ AnsiConsole.Console = AnsiConsole.Create(new AnsiConsoleSettings
+ {
+ Out = new AnsiConsoleOutput(theOutput)
+ });
+
executor = CommandExecutor.For(_ =>
{
_.RegisterCommands(GetType().GetTypeInfo().Assembly);
diff --git a/src/CommandLineTests/CommandLineTests.csproj b/src/CommandLineTests/CommandLineTests.csproj
index 87221f58..177cd71b 100644
--- a/src/CommandLineTests/CommandLineTests.csproj
+++ b/src/CommandLineTests/CommandLineTests.csproj
@@ -8,7 +8,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/CoreTests/Core/data_segregation.cs b/src/CoreTests/Core/data_segregation.cs
index 9633fbdb..fb8efd77 100644
--- a/src/CoreTests/Core/data_segregation.cs
+++ b/src/CoreTests/Core/data_segregation.cs
@@ -1,5 +1,4 @@
using JasperFx.Core;
-using Xunit.Abstractions;
namespace CoreTests.Core;
diff --git a/src/CoreTests/CoreTests.csproj b/src/CoreTests/CoreTests.csproj
index c3124487..3be00c2a 100644
--- a/src/CoreTests/CoreTests.csproj
+++ b/src/CoreTests/CoreTests.csproj
@@ -10,7 +10,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/DocSamples/DocSamples.csproj b/src/DocSamples/DocSamples.csproj
index d0539fe1..3daffb5b 100644
--- a/src/DocSamples/DocSamples.csproj
+++ b/src/DocSamples/DocSamples.csproj
@@ -5,16 +5,13 @@
false
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
+
diff --git a/src/EventStoreTests/EventStoreTests.csproj b/src/EventStoreTests/EventStoreTests.csproj
index 65c7ddfb..7f50890f 100644
--- a/src/EventStoreTests/EventStoreTests.csproj
+++ b/src/EventStoreTests/EventStoreTests.csproj
@@ -8,7 +8,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/EventStoreTests/TestingSupport/TestLogger.cs b/src/EventStoreTests/TestingSupport/TestLogger.cs
index 145431e5..8d96df15 100644
--- a/src/EventStoreTests/TestingSupport/TestLogger.cs
+++ b/src/EventStoreTests/TestingSupport/TestLogger.cs
@@ -1,7 +1,6 @@
using System.Diagnostics;
using JasperFx.Core.Reflection;
using Microsoft.Extensions.Logging;
-using Xunit.Abstractions;
namespace EventStoreTests.TestingSupport;
diff --git a/src/EventTests/EventTests.csproj b/src/EventTests/EventTests.csproj
index 803e7cb2..7a806155 100644
--- a/src/EventTests/EventTests.csproj
+++ b/src/EventTests/EventTests.csproj
@@ -11,7 +11,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/EventTests/Projections/SliceGroupTests.cs b/src/EventTests/Projections/SliceGroupTests.cs
index 77775aa8..27554d71 100644
--- a/src/EventTests/Projections/SliceGroupTests.cs
+++ b/src/EventTests/Projections/SliceGroupTests.cs
@@ -544,9 +544,12 @@ Task IProjectionStorage.LoadAsync(string id, CancellationTok
throw new NotImplementedException();
}
+ // Part of the IProjectionStorage contract this class self-stubs, NOT xunit lifecycle -- but
+ // xunit v3 disposes a test class that implements IAsyncDisposable, so a throwing stub here
+ // fails every test in the class during teardown. Nothing in these tests needs disposal.
ValueTask IAsyncDisposable.DisposeAsync()
{
- throw new NotImplementedException();
+ return ValueTask.CompletedTask;
}
Task> IStorageOperations.FetchProjectionStorageAsync(string tenantId, CancellationToken cancellationToken)
diff --git a/src/EventTests/TestingSupport/TestLogger.cs b/src/EventTests/TestingSupport/TestLogger.cs
index 38f2bd49..80ed6ed5 100644
--- a/src/EventTests/TestingSupport/TestLogger.cs
+++ b/src/EventTests/TestingSupport/TestLogger.cs
@@ -1,7 +1,6 @@
using System.Diagnostics;
using JasperFx.Core.Reflection;
using Microsoft.Extensions.Logging;
-using Xunit.Abstractions;
namespace EventTests.TestingSupport;
diff --git a/src/JasperFx.Aspire.Tests/JasperFx.Aspire.Tests.csproj b/src/JasperFx.Aspire.Tests/JasperFx.Aspire.Tests.csproj
index 935b095a..58fd08d2 100644
--- a/src/JasperFx.Aspire.Tests/JasperFx.Aspire.Tests.csproj
+++ b/src/JasperFx.Aspire.Tests/JasperFx.Aspire.Tests.csproj
@@ -11,7 +11,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/JasperFx.Events.SourceGenerator.Tests/JasperFx.Events.SourceGenerator.Tests.csproj b/src/JasperFx.Events.SourceGenerator.Tests/JasperFx.Events.SourceGenerator.Tests.csproj
index 1deb41c3..4acb5299 100644
--- a/src/JasperFx.Events.SourceGenerator.Tests/JasperFx.Events.SourceGenerator.Tests.csproj
+++ b/src/JasperFx.Events.SourceGenerator.Tests/JasperFx.Events.SourceGenerator.Tests.csproj
@@ -11,7 +11,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/JasperFx.SourceGenerator.Tests/JasperFx.SourceGenerator.Tests.csproj b/src/JasperFx.SourceGenerator.Tests/JasperFx.SourceGenerator.Tests.csproj
index 0540ca50..e041b46c 100644
--- a/src/JasperFx.SourceGenerator.Tests/JasperFx.SourceGenerator.Tests.csproj
+++ b/src/JasperFx.SourceGenerator.Tests/JasperFx.SourceGenerator.Tests.csproj
@@ -12,7 +12,7 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/JasperFx/JasperFxOptions.cs b/src/JasperFx/JasperFxOptions.cs
index 76f6d9f9..877731c3 100644
--- a/src/JasperFx/JasperFxOptions.cs
+++ b/src/JasperFx/JasperFxOptions.cs
@@ -22,8 +22,21 @@ public static bool HasReferenceToJasperFxTool(Assembly assembly)
var names = assembly.GetReferencedAssemblies();
foreach (var name in names)
{
- var reference = Assembly.Load(name);
- if (reference != null && reference.HasAttribute()) return true;
+ // Best-effort detection: an application's assembly graph routinely contains references
+ // that cannot be loaded or reflected over at runtime -- optional dependencies that were
+ // never deployed, assemblies trimmed away, or (as here) a reference whose own
+ // dependencies are missing from the output so that enumerating its custom attributes
+ // throws. None of that means the app is a JasperFx tool, and none of it is worth
+ // failing host startup over, so skip the assembly and keep looking.
+ try
+ {
+ var reference = Assembly.Load(name);
+ if (reference != null && reference.HasAttribute()) return true;
+ }
+ catch (Exception)
+ {
+ // Intentionally ignored; see above.
+ }
}
return false;