d08323bb2ff524e4964a0922ecfb8336ab662007 braney Wed Sep 16 10:25:56 2026 -0700 docent: two tests for gaps a cart-visibility branch went past, refs #37892 The #37547 branch broke quickLift and nine scripts in tests/regress caught it without help. Two other things went past the whole suite, and these are the tests for them. heavysession is selftest on a cart with weight behind it. selftest saves a session and loads it back, which is the right shape, but the cart it round-trips holds two rows. Saving a cart is not a copy of it: outIfNotPresent() in hg/hgSession/hgSession.c writes a trackDb default for every track that is deliberately NOT in the cart, so the file says what is hidden as well as what is shown, and a two-track cart barely reaches that code. A save-and-reload path that returned a 38-row clinical session as 34 rows left selftest green. The weight comes from a Recommended Track Set, which is where a clinical user starts: View/Clinical_SNVs_hg38, out of DOCUMENT_ROOT/data/recTrackSets/recTrackSets.hg38.tab. It draws 33 tracks and the ruler, and the file the session: step writes out of that cart is 741 settings, 248 of them visibilities and 154 of those hide. Both halves of the trip assert the row set with exact: true, because rows: alone would pass on a reload that lost four of them, and a count cannot say which row went missing. It is a saved session on the server, so make preflight already checks it is still there -- a deleted one answers 200 with a page that has no track image, on which every noText: check passes. firstrequest is about a bug that lags by exactly one request: the visibility reaches the cart, the image drawn in reply does not carry the row, and the next request draws it. A script shaped track: -> go: -> expect: supplies that extra request itself and passes on the broken build. So this one asserts with no go:, open: or convert: between the track: step and the check. Which track it names is the other half, and it is not free choice. A top-level track passes on a build with the bug, because hgTracks adds every top-level track as a lightweight stub so the track controls can list it -- microsat, gtexGene and windowmaskerSdust all drew. A default-visible child passes too, because its container is in the list already: wgEncodeRegMarkH3k27ac drew while its sibling wgEncodeRegMarkH3k4me1 did not, same superTrack and same request. So the script names wgEncodeRegMarkH3k4me1, which is visibility hide under a superTrack that is itself superTrack on hide, and the hideKids step before it is what stops the other members coming back at their own trackDb visibility. expected/firstrequest.derive is committed with it, and it is not decoration. The test only means anything while the step under test is ONE round: step 5 track {"wgEncodeRegMarkH3k4me1":"full"} round 1 (2 vars): wgEncodeRegMarkH3k4me1=full wgEncodeReg=show If Docent ever splits that the way it splits a container-plus-subtrack-hide, the browser test would go on passing and stop being able to see the bug. The baseline says so out loud. README.txt describes both, and adds hgCollection to "Still to write": no script in either directory reaches that CGI, and hg/hgCollection/hgCollection.c carries its own verbatim copy of isParentVisible() from hg/lib/trackHub.c. Nine scripts caught the trackHub.c copy on the branch; nothing caught this one. Covering it needs a collection: verb, since tracks go into a collection by dragging between two jsTrees and drag: is the genomic drag-select on the track image. Seventeen of seventeen pass in tests/, including the four xfails. diff --git src/hg/utils/docent/tests/heavysession.docent.yaml src/hg/utils/docent/tests/heavysession.docent.yaml new file mode 100644 index 00000000000..63cd7dc35f0 --- /dev/null +++ src/hg/utils/docent/tests/heavysession.docent.yaml @@ -0,0 +1,72 @@ +# The session round trip, on a cart with real weight behind it. +# +# selftest already does session: -> expect: -> loadSession:, which is the right shape, and +# it does it on a cart holding two rows. That is not enough to exercise the part of +# hgSession that actually breaks. Saving a cart is not a copy of it: outIfNotPresent() in +# hg/hgSession/hgSession.c writes a trackDb DEFAULT for every track that is deliberately +# NOT in the cart, so the file says what is hidden as well as what is shown. On a two-track +# cart that function has almost nothing to do. A save-and-reload path that dropped rows was +# watched to leave selftest green, and this script is what would have gone red. +# +# The weight comes from a Recommended Track Set, which is where a clinical user starts: +# View/Clinical_SNVs_hg38, listed in DOCUMENT_ROOT/data/recTrackSets/recTrackSets.hg38.tab +# and loaded by hg/hgTracks/recTrackSets.c. It draws 33 tracks and the ruler, and the file +# the `session:` step below writes out of that cart is 741 settings, 248 of them track +# visibilities and 154 of those `hide`. It is a saved session on the server, so +# `make preflight` checks it is still there -- a deleted session answers 200 with a page +# that has no track image, on which every noText: check passes. +# +# `exact: true` is on both halves and it is the whole test. Naming the rows that came back +# is what says the cart survived; `rows:` on its own would pass on a reload that lost four +# of them. The set is stated in full rather than counted because a count cannot say WHICH +# row went missing, and the failure message prints the rows actually drawn. +# +# When genome-test's trackDb changes what this session draws, this script goes red for an +# honest reason. Read the failure before editing the list: a row that arrives is news +# about trackDb, a row that leaves on one half of the trip and not the other is the bug +# this exists for. +target: genome-test +db: hg38 +reset: true +fast: true +steps: + # No go: and no position: -- the session carries its own window (chr12, near FGF23). + - loadSession: {user: View, name: Clinical_SNVs_hg38} + + # The baseline, and at the same time the check that the session really loaded. + - expect: + rows: [ruler, avada, caddA, caddC, caddDel, caddG, caddIns, caddT, clinvarMain, + clinvarSubLolly, genCC, geneReviews, gnomadConstraint, + gnomadGenomesVariantsV3_1_1, hgmd, lovdShort, mane, mastermind, + missenseByGene, missenseByTranscriptV4_1_1, multiz100way, ncbiRefSeqCurated, + ncbiRefSeqHgmd, omimGene2, phyloP100way, pliByTranscriptV4_1_1, revelA, + revelC, revelG, revelT, unipDisulfBond, unipInterest, unipLocSignal, + unipModif] + exact: true + noText: "Could not find session" + + # The whole cart at this step, written the way hgSession's "save settings to a local + # file" button writes it. + - session: clinical + + # Move somewhere the saved state has to undo. Two rows, so a restore that half worked + # cannot be mistaken for one that worked. + - hide: all + - track: {mane: pack} + - expect: {rows: [ruler, mane], exact: true, noRows: [clinvarMain, revelA]} + + # Back up through hgSession's own upload form. + - loadSession: {file: clinical} + + # The same 34 rows, stated again in full rather than referred to, because a test that + # said "as before" would have nothing to print when it failed. + - expect: + rows: [ruler, avada, caddA, caddC, caddDel, caddG, caddIns, caddT, clinvarMain, + clinvarSubLolly, genCC, geneReviews, gnomadConstraint, + gnomadGenomesVariantsV3_1_1, hgmd, lovdShort, mane, mastermind, + missenseByGene, missenseByTranscriptV4_1_1, multiz100way, ncbiRefSeqCurated, + ncbiRefSeqHgmd, omimGene2, phyloP100way, pliByTranscriptV4_1_1, revelA, + revelC, revelG, revelT, unipDisulfBond, unipInterest, unipLocSignal, + unipModif] + exact: true + noText: "Could not find session"