d2a6107cdb
CentralDbTestEnvironment sets five process-wide environment variables, and
Program's AddEnvironmentVariables() reads them at an unpredictable point during
host boot. With xUnit collection parallelization on, one fixture's teardown
could clear a var mid-boot for a sibling. Since the secrets adoption (G-4)
three of those keys are ${secret:...} references that fail closed, turning a
previously benign empty value into a SecretNotFoundException that aborts the
boot — an intermittent CI failure.
Adds a HostBootCollection that serializes every fixture booting a real host
while depending on that shared state, folding in the narrower "ActorSystem"
collection so its members stay serialized with each other as before. Site-role
fixtures stay parallel: they call Configuration.Sources.Clear(), dropping the
env-var provider, so they cannot participate in the race.
CentralDbTestEnvironment now also fails fast if two instances are ever live at
once, making a regression (a fixture added outside the collection) deterministic
rather than intermittent — this is what surfaced the disposed-CTS defect fixed
in the previous commit. Fixture teardown is try/finally so a throwing host
teardown can no longer strand the vars for the rest of the run.
Cost: Host.Tests runs ~2m30s -> ~4m10s; the serialized Central-boot classes are
most of the assembly's parallelism.
Fixes: Gitea #15
26 lines
1.3 KiB
C#
26 lines
1.3 KiB
C#
namespace ZB.MOM.WW.ScadaBridge.Host.Tests;
|
|
|
|
/// <summary>
|
|
/// Serializes every fixture that boots a real host while depending on process-wide
|
|
/// state — the <c>DOTNET_ENVIRONMENT</c> role selector and the environment variables
|
|
/// <see cref="CentralDbTestEnvironment"/> sets.
|
|
///
|
|
/// <c>Program</c>'s configuration builder calls <c>AddEnvironmentVariables()</c> at an
|
|
/// unpredictable point during boot, so a sibling fixture's teardown (which restores or
|
|
/// clears those vars) can otherwise be observed mid-boot as a transient null. Since the
|
|
/// secrets adoption (G-4) three of those keys are <c>${secret:...}</c> references that
|
|
/// fail closed, which turns that race into a hard <c>SecretNotFoundException</c>.
|
|
/// xUnit runs classes in a shared collection sequentially, which removes the overlap.
|
|
///
|
|
/// Site-role fixtures are deliberately not members: they call
|
|
/// <c>Configuration.Sources.Clear()</c>, dropping the environment-variable provider, so
|
|
/// they neither read nor write the shared state and stay free to run in parallel.
|
|
///
|
|
/// Supersedes the narrower "ActorSystem" collection, whose members are folded in here.
|
|
/// </summary>
|
|
[CollectionDefinition(HostBootCollection.Name)]
|
|
public class HostBootCollection
|
|
{
|
|
public const string Name = "HostBoot";
|
|
}
|