Skip to content

test: an end-to-end use-case suite driven through the real entry points, because every "unreachable source" bug passed its unit tests #462

Description

@sotashimozono

Four bugs this cycle share one shape: a source was implemented, gated, allowlisted and unit-tested,
and did not work.

found by passed its unit tests
#413 five Tier-2 sources never called yes
#442 three Tier-3 sources never called yes
#454 Tier-3 allowlists never registered in the client yes
#458 Tier-3 chain skipped whenever Crossref answers yes

In every case the unit test drove the Source impl directly, or asserted that a builder returned
the right value, and the production entry point was never in the picture. #454's guard even had a
doc comment describing the failure it could not catch.

Each fix added a targeted regression test, which is right, but they were written after a human
drove the real thing and noticed. Nothing drives the real thing on a schedule.

What is missing

A suite that starts where a user starts — doiget fetch, doiget_fetch_paper over MCP stdio —
and asserts on the observable outcome, for a small fixed set of DOIs chosen because each one
exercises a different route.

Not a replacement for the unit tests. The thing they cannot do is notice that a correct component
is never reached.

Sketch

DOI route it exercises expected
10.1109/TSP.2018.2812747 hybrid OA, repository copy, host not curated blocked, denial_context.attempted names the repository host
same, trust_academic_repos = true the user-extension trust flag fetched, non-zero bytes
10.1090/s0025-5718-04-01692-8 bronze OA, publisher rate-limits (#445) blocked, and the trace names every enabled source
an arXiv-preprinted DOI the #325 preprint fallback fetched via arXiv, PreprintFallback
a gold-OA DOAJ DOI the ADR-0037 apex redirect fetched
a DOI Crossref cannot resolve the Tier-2 optional chain the trace distinguishes "asked, nothing" from "never asked"

Each row asserts which route produced the outcome, not merely that one occurred — that is the
distinction every bug above slipped through.

Constraints, and the awkward part

These need the network, so they cannot sit in the ordinary test job: the network-purity job
exists precisely to keep the default suite hermetic. Options:

  • a separate scheduled workflow (nightly), continue-on-error: false but off the PR path, so an
    upstream change surfaces as a failing cron rather than a blocked PR;
  • #[ignore] by default, run explicitly;
  • record the responses as fixtures and replay them, with a much rarer live job that re-records.

The third is the most stable and the least likely to notice that the real world changed, which
is the whole point. Probably the first, accepting the flakiness, with the DOI list kept small and
the failures triaged rather than muted.

Politeness matters: a fixed handful of DOIs, a contact address set, and the existing rate limiter.

Why now

#430 shipped a source justified by a corpus nobody had fetched end-to-end. Driving it revealed
#458, #459 and #460 in one session — none of which any unit test could have found. That is a
strong argument that this suite pays for itself.

Refs #413, #442, #454, #458, #459, #460, #445.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions