Skip to content

Fix test suite under Rack 3 - #318

Merged
jvendetti merged 1 commit into
masterfrom
fix/rack-3-test-compatibility
Aug 20, 2026
Merged

jvendetti merged 1 commit into
masterfrom
fix/rack-3-test-compatibility

Conversation

@jvendetti

Copy link
Copy Markdown
Member

Problem

The unit test suite passes on develop but fails with 6 errors on master.

Merging develop into master re-resolved Gemfile.lock and bumped rack 2.2.24 → 3.2.7, because the Gemfile declared gem 'rack' with no version constraint:

Branch rack in Gemfile.lock
develop 2.2.24
master (59b1732e^) 2.2.23
master (before this PR) 3.2.7

Rack 3.0 removed Rack::Server (extracted into the separate rackup gem, which is not in the bundle). test/models/test_ontology_common.rb used it to stand up a throwaway HTTP server serving "test file", which the ontology pull tests download from.

One removed constant, six errors

Test Mechanism
TestOntologySubmission#test_download_ontology_file Direct hit — start_server raises NameError: uninitialized constant Rack::Server
TestOntology#test_duplicate_contacts, #test_next_submission_id, #test_ontology_deletes_submissions, #test_ontology_acronym_unique before_suite starts the same dead server, so nothing listens on the port and goo rejects the save: pullLocation ... does not point to a valid file
TestOntology#test_purl_creation Collateral. test/test_case.rb sets Thread.abort_on_exception = true, so the dead server thread's NameError is re-raised in the main thread — it landed inside a Net::HTTP call to localhost:9000 (that's GOO_PORT, the triplestore, not purl). enable_purl is false, so this test body never actually ran. It needed no fix of its own.

Changes

Replace Rack::Server with WEBrick::HTTPServer in start_server. webrick is already a test-group dependency, and this works under both rack 2 and rack 3, so it merges back to develop without divergence. Two incidental improvements:

  • StartCallback + Queue#pop replaces the old Thread.pass / sleep 3 startup guesswork and blocks until the socket actually accepts. TestOntology.before_suite had no sleep at all — a latent flake.
  • thread[:webrick] exposes the server so teardown can shutdown it; Thread.kill alone left the listening socket open until GC.

Pin rack to ~> 3.2 so the major version is a deliberate choice rather than an accident of lockfile re-resolution. The gemspec stays unpinned, as a library's should.

Bump rack-test from ~> 0.6 (0.6.3, released 2014, predates the Rack 3 SPEC) to ~> 2.1. This required adding an explicit require "rack/builder" to the test/rack tests — 0.6.3 loaded all of rack as a side effect, 2.x does not.

Lowercase response header keys in Serializer.response. Rack 3 requires lowercase keys (rack 2's Rack::Utils::HeaderHash used to normalize case and no longer exists). Rack::Utils.set_cookie_header! already emits a lowercase set-cookie, so responses were carrying mixed-case keys and any downstream headers['content-type'] lookup would silently miss.

Rack 3 audit

Checked the rest of the codebase against the installed rack-3.2.7. Rack::Request, Rack::Response#finish, and Rack::Utils.parse_query / build_query / build_nested_query / parse_cookies / set_cookie_header! all still exist and behave correctly. Nothing references the removed Rack::Utils::HeaderHash. Rack::Server was the only removed constant this repo touched.

Testing

Full suite, before and after:

Before After
Runs 325 325
Errors 6 0
Failures 0 0
Skips 5 5
Assertions 18012 18025
325 runs, 18025 assertions, 0 failures, 0 errors, 5 skips

Same run count and same 5 skips, so nothing was silently dropped. The 13 added assertions are the test_download_ontology_file assertions that previously never executed because start_server blew up first.

Also verified:

  • rake test:rack passes (guards the header-case and rack-test changes).
  • test/models/test_ontology.rb run 3× consecutively, 16/16 each time — confirms the startup race is gone.
  • No leaked listeners in the 55000–65535 range after the suite, confirming the WEBrick shutdown calls land.
  • test_purl_creation passes without being touched, confirming it was collateral rather than a purl problem.

Follow-up, not in this PR

  • develop still locks rack 2.2.24 and still has gem 'rack' unpinned, so its next re-resolve can jump to rack 3 on its own and reintroduce this exact breakage there. Everything in this PR works under both rack 2 and 3 except the Gemfile pin — worth pinning develop deliberately to one major version.
  • ontologies_api content negotiation. serializer.rb reads env['rack-accept.request'], injected by the rack-accept gem — not a dependency here, unmaintained, no Rack 3 release. This library degrades gracefully (falls back to env["HTTP_ACCEPT"]), but the API app needs checking when it moves to rack 3.

🤖 Generated with Claude Code

Merging develop into master re-resolved Gemfile.lock and bumped rack
2.2.24 -> 3.2.7, since the Gemfile declared `gem 'rack'` unpinned. Rack
3.0 removed Rack::Server (extracted into the separate rackup gem, which
is not in the bundle), and test/models/test_ontology_common.rb used it
to stand up a throwaway HTTP server for ontology pull tests.

That single removed constant produced 6 errors: one direct hit in
test_download_ontology_file, four in TestOntology where pullLocation
validation failed against a server that never started, and one in
test_purl_creation as collateral -- test_case.rb sets
Thread.abort_on_exception = true, so the dead server thread's NameError
was re-raised inside an unrelated test.

Changes:

- Replace Rack::Server with WEBrick::HTTPServer in start_server. webrick
  is already a test dependency and works under both rack 2 and 3, so
  this merges back to develop without divergence. Also replaces the
  Thread.pass/sleep startup guesswork with a StartCallback + Queue#pop
  that blocks until the socket accepts, and exposes the server via
  thread[:webrick] so teardown shuts it down instead of leaking it.

- Pin rack to ~> 3.2 so the major version is a decision, not an
  accident of lockfile re-resolution. The gemspec stays unpinned.

- Bump rack-test ~> 0.6 (0.6.3, 2014) to ~> 2.1. It predates the Rack 3
  SPEC. This required adding an explicit require of rack/builder to the
  test/rack tests, since 0.6.3 loaded all of rack while 2.x does not.

- Lowercase response header keys in Serializer.response. Rack 3 requires
  lowercase keys, and Rack::Utils.set_cookie_header! already emits a
  lowercase set-cookie, so responses were carrying mixed-case keys.

Full suite: 325 runs, 18025 assertions, 0 failures, 0 errors, 5 skips.
Run count and skips unchanged; the 13 added assertions are the
test_download_ontology_file assertions that previously never ran.

Note: develop still locks rack 2.2.24. Everything here works under both,
except the Gemfile pin.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.03%. Comparing base (fd64046) to head (286ce13).
⚠️ Report is 15 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #318   +/-   ##
=======================================
  Coverage   82.03%   82.03%           
=======================================
  Files         101      101           
  Lines        6853     6853           
=======================================
  Hits         5622     5622           
  Misses       1231     1231           
Flag Coverage Δ
ag 81.96% <100.00%> (+0.02%) ⬆️
fs 82.00% <100.00%> (+0.07%) ⬆️
gd 81.97% <100.00%> (+0.01%) ⬆️
unittests 82.03% <100.00%> (ø)
vo 81.92% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jvendetti
jvendetti merged commit 59f630f into master Aug 20, 2026
12 checks 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.

1 participant