Skip to content

Serialize SelfLog-sharing tests to fix intermittent CarriesMessageTemplateProperties failure#73

Merged
KodrAus merged 1 commit into
datalust:devfrom
thekim1:fix-race-condition-in-tests
Jul 16, 2026
Merged

Serialize SelfLog-sharing tests to fix intermittent CarriesMessageTemplateProperties failure#73
KodrAus merged 1 commit into
datalust:devfrom
thekim1:fix-race-condition-in-tests

Conversation

@thekim1

@thekim1 thekim1 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Problem

I saw the pipeline fail in the build and publish stage after my last pr merged. Some tests failed in the pipeline even if they worked on local dev machine so I had a look at it.

CI failed intermittently in the Testing stage on net8.0/net9.0 (passed on net10.0/net48):

Failed Tests.Serilog.Extensions.Logging.SerilogLoggerTests.CarriesMessageTemplateProperties
  System.Exception : ... Exception System.Exception: Enricher Failed
     at Tests.Seq.Extensions.Logging.EnricherTests.<>c.<FailingEnricherIsHandled>b__1_1(...)
     at Seq.Extensions.Logging.Enricher.Enrich(...) ... caught while enriching ...

CarriesMessageTemplateProperties enables SelfLog, logs a message, asserts the captured
output is empty, and throws if not. The captured text was "Enricher Failed" — the exception
thrown by EnricherTests.FailingEnricherIsHandled.

Root cause

SelfLog is a process-global singleton (static Action<string>? _output) with no per-test
isolation. The two tests sit in different xUnit collections, which xUnit runs in parallel by
default. When FailingEnricherIsHandled triggers its failing enricher during the window where
CarriesMessageTemplateProperties has SelfLog._output pointed at its StringWriter, the
diagnostic write leaks into the other test's writer, making it throw the captured text.

It is timing-dependent (a race), which is why it surfaced on only 2 of 4 target frameworks in
this run and never reproduces locally — the .NET 10 / test-dependency bumps changed test
scheduling enough for the latent race to surface on CI. There is no product or test-logic
regression: the build, packaging, and the other 91 tests all passed with 0 warnings.

Fix

Put the two SelfLog-sharing test classes in a single xUnit collection with
DisableParallelization = true so they execute sequentially against each other, eliminating
the overlapping window. Other collections still run in parallel, so the suite stays fast.

  • Add Support/SelfLogCollection.cs[CollectionDefinition("SelfLog", DisableParallelization = true)]
  • [Collection("SelfLog")] on SerilogLoggerTests
  • [Collection("SelfLog")] on EnricherTests

Validation

I could not reproduce the failing tests on my dev machine so this needs to be validated in the pipeline runs.

Notes

  • This makes the tests run a bit slower as some tests are serialized instead of parallel
  • Current version of xUnit in the solution is depricated, migration to v3 should be done when possible but is not a blocker for future work in this repo. Info: Migration guide

@KodrAus KodrAus left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @thekim1!

@KodrAus
KodrAus merged commit 089e9cd into datalust:dev Jul 16, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants