Speed up the C# test suite (full run ~8m30s -> ~7m) (BL-16556)#8067
Conversation
Several test fixtures were paying for expensive resources per test, or
silently fighting robust-IO retry loops against locked/invalid files.
This commit addresses the main offenders; every test still exercises
the same real code paths as before. In addition to the ~1.5 minutes
cut from the full run, marking the network-dependent fixtures as
Integration lets a run that chooses to skip them
(--filter TestCategory!=Integration) finish in ~3m25s.
- Share one off-screen page-checks browser across the epub and
bloompub test fixtures via a new test hook,
PublishHelper.ExternalPageChecksBrowserForTests. Each epub export /
bloompub creation previously booted and tore down its own WebView2
environment (browser process + dedicated STA thread). The fixtures
create one browser per fixture and clear the hook on teardown; the
real browser-based visibility/font checks still run for every book.
Production is unaffected (the hook is never set outside tests).
Epub suite: 1m32s -> 1m9s.
- Dispose the ZipFiles in BloomPubMakerTests.TestHtmlAfterCompression.
Stack sampling showed ~80% of the fixture's wall time in
RobustIO.DeleteDirectoryAndContents/RetryUtility sleep-retry loops:
the undisposed ZipFile kept each .bloompub locked, so each TempFile
Dispose retried for seconds. Fixture: 1m41s -> 19s.
- Fix BloomServerTests.CanGetActivityImage, which used
RobustFile.Create to make its test image: that left the stream open
(file locked) and the file empty (invalid PNG), sending the server's
image pipeline into ~20s of PalasoImage.FromFileRobustly retries.
It now writes a real small PNG and closes it. Test: 23s -> <1s;
fixture: 27s -> 4s.
- Mark the four WebLibraryIntegration fixtures that talk to live web
services (unit-test S3 buckets, bloomlibrary API, production site)
with [Category("Integration")]. They still run by default; the
category just makes their ~3.5 minutes of network tests skippable
when a quick local iteration doesn't need them.
- Make the opt-in manual RAB build test check its whole toolchain
(launcher, keytool, buildapp.bat on the PATH) up front and fail fast
(~200ms) with an actionable message, instead of letting RAB churn
for ~10s before failing with "'buildapp.bat' is not recognized".
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
| Filename | Overview |
|---|---|
| src/BloomExe/Publish/PublishHelper.cs | Adds ExternalPageChecksBrowserForTests static test hook; ReleaseBrowser and Dispose correctly skip it, leaving ownership with the fixture. |
| src/BloomTests/Publish/BloomPub/BloomPubMakerTests.cs | Shares one browser across the fixture via the test hook and wraps ZipFiles in using blocks, fixing the file-lock retry-loop that dominated the fixture run time. |
| src/BloomTests/Publish/Epub/ExportEpubTestsBaseClass.cs | Shares one OffScreenBrowser per fixture via the test hook; setup/teardown are correctly balanced across the base class and all overriding subclasses. |
| src/BloomTests/Publish/Rab/RabRealBuildTests.cs | Adds up-front toolchain checks with actionable messages, making the opt-in test fail fast instead of after a confusing 10-second RAB run. |
| src/BloomTests/web/BloomServerTests.cs | Replaces empty-file RobustFile.Create with a real closed PNG, eliminating the server image-pipeline retry loop. |
| src/BloomTests/WebLibraryIntegration/BloomS3ClientTests.cs | Adds [Category(Integration)] to let callers skip live-network tests; no logic change. |
| src/BloomTests/WebLibraryIntegration/BloomS3StandardUpDownloadTests.cs | Adds [Category(Integration)]; no logic change. |
| src/BloomTests/WebLibraryIntegration/BookUploadAndDownloadTests.cs | Adds [Category(Integration)]; no logic change. |
| src/BloomTests/WebLibraryIntegration/ProblemBookUploaderTests.cs | Adds [Category(Integration)]; no logic change. |
Reviews (1): Last reviewed commit: "Speed up the C# test suite (full run ~8m..." | Re-trigger Greptile
|
[Claude Fable 5] Consulted Devin on 2026-07-15 ~18:35 UTC up to commit 2063bee. Review completed with no findings (no bugs, no flags). Greptile also reviewed this commit and raised no issues. |
StephenMcConnel
left a comment
There was a problem hiding this comment.
@StephenMcConnel reviewed 9 files and all commit messages.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on andrew-polk).
Ref: https://issues.bloomlibrary.org/youtrack/issue/BL-16556
Speeds up the C# test suite: full run ~8m30s → ~7m, and a run that skips network-dependent fixtures (
--filter TestCategory!=Integration) finishes in ~3m25s. Every test still exercises the same real code paths as before.PublishHelper.ExternalPageChecksBrowserForTests. Each epub export / bloompub creation previously booted and tore down its own WebView2 environment (browser process + dedicated STA thread). The fixtures create one browser per fixture and clear the hook on teardown; the real browser-based visibility/font checks still run for every book. Production is unaffected (the hook is never set outside tests). Epub suite: 1m32s → 1m9s.ZipFiles inBloomPubMakerTests.TestHtmlAfterCompression. The undisposedZipFilekept each .bloompub locked, so eachTempFileDispose sat inRobustIO/RetryUtilitysleep-retry loops (~80% of the fixture's wall time). Fixture: 1m41s → 19s.BloomServerTests.CanGetActivityImage, which usedRobustFile.Createto make its test image: that left the stream open (file locked) and the file empty (invalid PNG), sending the server's image pipeline into ~20s ofPalasoImage.FromFileRobustlyretries. It now writes a real small PNG and closes it. Test: 23s → <1s; fixture: 27s → 4s.[Category("Integration")]. They still run by default; the category just makes their ~3.5 minutes of network tests skippable when a quick local iteration doesn't need them.🤖 Generated with Claude Code
Devin review
This change is