cd41fd4fa0efadea0cd412d1a39e9479f3aa9832
braney
  Tue Sep 15 14:45:24 2026 -0700
A nightly start-up and pixel check for hgTracks, refs #37547

Two builds of hgTracks, one machine, one moment: how long each takes to
start up and draw, and whether they draw the same pixels.  Eight cells --
native and GenArk, few tracks and many, narrow and wide.

compare.sh is the engine and takes any two builds, so the same test that
runs nightly against master also answers "is this branch slower than
genome-test, and does it still draw the same thing?"  A build is just a
directory holding hgTracks and hgRenderTracks, which `make compile` in
hg/hgTracks produces without installing anything.

nightly.sh is the cron wrapper, in the same shape as the Docent
regression nightly: its own clone, --update resets it to origin/master,
a mail every night whether or not anything failed, sixty days of logs,
always exit 0.  Its baseline is a rolling reference binary from the last
green night rather than a golden image, because two binaries reading the
same data at the same moment cannot disagree about pixels for a data
reason -- ClinVar, GENCODE and the GenArk hubs all move underneath a
saved render.

Five things here were measured rather than assumed, and each one
silently produces a wrong answer if it is left out.  README.txt has them
with the numbers; the short version:

- TRACKDB_VERSION is baked into each trackDb cache dump's filename, so
a build that bumped it starts with an empty cache and pays a full
parse per cell.  Each side gets its own cache dir and a per-cell
warmup, or a one-time cost reads as a permanent regression.
- Replaying a saved session's variables as a GET does not reproduce
the session: composite _sel state and the default-visibility pass
live in hgSession's load path.  Against a 71-track session a flat
replay drew 23 of them and invented four more.  The fixtures are
loaded with hgS_doLoadUrl instead.
- Running the binaries directly needs an htdocs symlink beside trash,
or freetype cannot find its font and every render dies.
- Always running side A first is worth 4.5% to side B, from the caches
A just warmed.  The order alternates.
- trackLog names every track hgTracks loaded, not the drawn rows -- a
default hg38 view logs 563 and draws 21.  Both are checked.

Cold and warm carts are reported separately and deliberately.  A
one-shot render gives every request a fresh cart, so it measures only
the first load; on #37547 that reported the branch slower while a
persistent cart showed it faster, on the same binaries.

Nothing is wired into the tree-wide build, for the same reason the
Docent tests are not: these drive a real server and need the network.

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

diff --git src/hg/utils/perfNightly/scenarios.tsv src/hg/utils/perfNightly/scenarios.tsv
new file mode 100644
index 00000000000..bfab6950ecb
--- /dev/null
+++ src/hg/utils/perfNightly/scenarios.tsv
@@ -0,0 +1,30 @@
+# hgTracks start-up scenarios.  ONE tab between fields.  refs #37547
+#
+# name		a label, and the stem of every file the run writes
+# db		assembly.  A GenArk hub assembly is reached by its bare accession.
+# load		how the cell's tracks get turned on in a fresh cart:
+#		  -			trackDb defaults
+#		  session:FILE		load sessions/FILE by URL.  The only form that
+#					reproduces a real session -- see compare.sh.
+#		  q:FRAGMENT		a literal query fragment
+# position	the view
+# pix		image width.  Sent explicitly so no cell takes the reload bootstrap.
+#
+# Four axes, eight cells: native and GenArk, few tracks and many, narrow and wide.
+# GenArk matters on its own because its start-up is a different path -- hub.txt and the
+# hub trackDb arrive over udc, not from MySQL.
+#
+# The GenArk heavy cells use hgt.visAllFromCt rather than a session file on purpose.
+# Every track in a hub is named hub_<hubStatusId>_<track>, and the id is assigned per
+# machine, so a frozen fixture naming those tracks would address the wrong rows -- or
+# nothing -- on any other machine or after a hubStatus change, and nothing would warn.
+#
+# name	db	load	position	pix
+hg38-few-narrow	hg38	-	chr17:43044295-43125483	1100
+hg38-few-wide	hg38	-	chr1:1-10000000	1100
+hg38-many-narrow	hg38	session:hg38-clinical.session	chr17:43000000-43150000	1100
+hg38-many-wide	hg38	session:hg38-clinical.session	chr1:1-10000000	1100
+genark-few-narrow	GCF_016699485.2	-	chr1:1000000-1100000	1100
+genark-few-wide	GCF_016699485.2	-	chr1:1-10000000	1100
+genark-many-narrow	GCF_000001735.4	q:hgt.visAllFromCt=pack	chr1:1-500000	1100
+genark-many-wide	GCF_000001735.4	q:hgt.visAllFromCt=pack	chr1:1-30000000	1100