Skip to content

Speed up the C# test suite (full run ~8m30s -> ~7m) (BL-16556)#8067

Merged
StephenMcConnel merged 1 commit into
masterfrom
speedUpCSharpTests
Jul 15, 2026
Merged

Speed up the C# test suite (full run ~8m30s -> ~7m) (BL-16556)#8067
StephenMcConnel merged 1 commit into
masterfrom
speedUpCSharpTests

Conversation

@andrew-polk

@andrew-polk andrew-polk commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

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.

  • 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. The undisposed ZipFile kept each .bloompub locked, so each TempFile Dispose sat in RobustIO/RetryUtility sleep-retry loops (~80% of the fixture's wall time). 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 up front (launcher, keytool, buildapp.bat on the PATH) and fail fast (~200ms) with an actionable message, instead of letting RAB churn for ~10s before failing with "'buildapp.bat' is not recognized".

🤖 Generated with Claude Code

Devin review


This change is Reviewable

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>
@greptile-apps

greptile-apps Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR shaves ~1m30s off the full C# test suite (and ~5m off the filtered run) by eliminating redundant WebView2 startups, fixing file-lock-induced retry loops, and tagging slow network tests with [Category("Integration")]. All optimizations are test-only — production code is unchanged except for the addition of an internal test hook field that is never set outside of tests.

  • Shared OffScreenBrowser per fixture: PublishHelper.ExternalPageChecksBrowserForTests lets epub and bloompub fixtures boot WebView2 once per fixture instead of once per export; teardown correctly clears the hook before disposing the browser, and ReleaseBrowser/Dispose leave the external browser alone.
  • ZipFile disposal in BloomPubMakerTests: wrapping the ZipFile opens in using blocks eliminates the file-lock that was causing each TempFile.Dispose to spin in RobustIO retry loops, cutting the fixture from ~1m41s to ~19s.
  • Real PNG in BloomServerTests.CanGetActivityImage: replacing RobustFile.Create (which left the file empty and the stream open) with a properly written and closed Bitmap stops the server's image pipeline from retrying for ~20 seconds on an invalid file.

Important Files Changed

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

@andrew-polk

Copy link
Copy Markdown
Contributor Author

[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.

@andrew-polk andrew-polk changed the title Speed up the C# test suite (full run ~8m30s -> ~7m) Speed up the C# test suite (full run ~8m30s -> ~7m) (BL-16556) Jul 15, 2026
@andrew-polk
andrew-polk marked this pull request as ready for review July 15, 2026 20:21

@StephenMcConnel StephenMcConnel left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@StephenMcConnel reviewed 9 files and all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on andrew-polk).

@StephenMcConnel
StephenMcConnel merged commit 3a57f92 into master Jul 15, 2026
4 checks passed
@StephenMcConnel
StephenMcConnel deleted the speedUpCSharpTests branch July 15, 2026 22:16
@andrew-polk
andrew-polk restored the speedUpCSharpTests branch July 16, 2026 15:21
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.

3 participants