De linux-gate viel elf keer om op een wachttijd, en de poort ertegen mat bijna niets (#1911) #1912

Merged
brenno merged 4 commits from fix/carousel-delete-flake into main 2026-09-01 23:32:57 +00:00
Owner

Sluit #1911.

Wat er misging

De linux-gate op main (taak 5317, commit b140c8cb) faalde op één test:
image_carousel_delete_test — "een verwijderde afbeelding verdwijnt uit de bibliotheek".

Dat bestand liet de gate tussen 21-08 en 01-09 negen keer omvallen (taken 2594, 3099, 3404, 3658, 4283, 4366, 4974, 4986, 5317), elke keer met een andere testnaam. Dat las als toeval. Het was negen keer dezelfde regel: pumpPicker gaf de afbeeldingkiezer 300 ms wandelklok en nam daarna aan dat de mapscan klaar was. Op de runner — vier kernen, --concurrency=14 — is hij dat soms niet, en dan staat de Verwijderen-knop nog niet in de boom.

Bij het doorzoeken van de joblogs bleken twee andere bestanden hetzelfde te doen: callout_accessibility_test (omgevallen 31-08 en 01-09, taken 5001 en 5200) en callout_reveal_test (01-09).

Alle drie gereproduceerd door de wachttijd op nul te zetten: exact de meldingen uit de joblogs.

Waarom niets dat tegenhield

De poort ertegen bestaat al — _fixedDelayInRunAsync in tool/check_conventions.dart, geschreven nadat vier tests op één dag om deze reden gerepareerd moesten worden. Hij heeft dit anderhalve maand niet gezien:

  • hij zocht de kale schrijfwijze Future.delayed(, terwijl 126 van de 129 wachtpunten in test/ Future<void>.delayed( schrijven;
  • hij keek 400 tekens voorbij de runAsync( — minder dan één pumpWidget met een widgetboom erin, en juist dáár stond het wachtpunt dat de negen storingen veroorzaakte.

Netto: 3 van de 129 gezien, en groen gemeld.

Wat deze PR doet

De poort kent nu het typeargument en telt haakjes tot het einde van de aanroep. Tegen de originele carousel-test vindt hij 4 wachtpunten waar hij er 0 vond. fixedDelaysIn is losgetrokken van de schijf (zoals classSizesIn) en test/fixed_delay_ratchet_test.dart houdt beide blinde vlekken vast, allebei bewezen rood tegen de oude implementatie. De achterstand die daardoor zichtbaar werd staat als krimp-alleen basislijn fixedDelayBaseline, geregistreerd in check_ratchet_trend.dart.

De carousel-test wacht op de uitkomst die hij daarna bewéért, via pumpUntil — de hulp die daar al voor bestond en die de zusterbestanden al gebruikten. Het bestand draait nu in 2 s.

De callout-tests doen iets anders, en met opzet. Daar is niet beter gewacht maar het wachten wéggehaald: de test laadt het beeld voor, waarna resolveIntrinsicSize zijn maat synchroon teruggeeft en de overlay in de eerste build tekent. Dat pad bestaat al voor de rasterexports, die hun beelden om precies dezelfde reden voorladen. Twee redenen om het hier zo te doen:

  • die tests draaien zelf al binnen runAsync, waar een geneste runAsync — en dus pumpUntil — verboden is;
  • twee van de toetsen bewijzen afwezigheid (geredigeerde dia, niet-onthulde groep). In de widgetboom is "met opzet niets getekend" niet te onderscheiden van "nog niet gedecodeerd", dus die slaagden ook wanneer er nog niets getekend wás. Er valt daar niets aan te wijzen om op te wachten; voorladen haalt de vraag weg.

Basislijn daarmee van 25 naar 24 bestanden, 37 naar 32 wachtpunten.

Wat er open blijft

De basislijn is geen schone lei: 32 wachtpunten, waarvan 7 bewuste uitzondering (de redenen staan in pump_until.dart) en 25 schuld. Bewezen rood en nog niet omgezet: document_editor_screen_test (vijf keer op 24/25-08) en export_dialog_pdf_end_to_end_test (24-08, toen is alleen het getal verhoogd).

Eén blinde vlek in de poort blijft, en staat als zodanig in CHECKS.md: een wachtpunt in een helper die vanuit runAsync wordt aangeroepen staat er niet lexicaal in. callout_reveal_test had precies die vorm — de poort zag hem nooit.

Getoetst

  • make check-static groen.
  • 170 tests over alles wat check_conventions.dart importeert, de drie carousel-bestanden en de callout-bestanden: groen.
  • Elke reparatie bewezen dragend met omgekeerde mutatie: oude regex → 4 van de 7 poorttests rood; oud 400-tekensvenster → het widgetboomgeval rood; voorladen eruit → precies de drie callout-toetsen die op gerenderde inhoud toetsen rood, de andere twee niet.
Sluit #1911. ## Wat er misging De linux-gate op `main` (taak 5317, commit b140c8cb) faalde op één test: `image_carousel_delete_test` — "een verwijderde afbeelding verdwijnt uit de bibliotheek". Dat bestand liet de gate tussen 21-08 en 01-09 **negen keer** omvallen (taken 2594, 3099, 3404, 3658, 4283, 4366, 4974, 4986, 5317), elke keer met een andere testnaam. Dat las als toeval. Het was negen keer dezelfde regel: `pumpPicker` gaf de afbeeldingkiezer 300 ms wandelklok en nam daarna aan dat de mapscan klaar was. Op de runner — vier kernen, `--concurrency=14` — is hij dat soms niet, en dan staat de Verwijderen-knop nog niet in de boom. Bij het doorzoeken van de joblogs bleken twee andere bestanden hetzelfde te doen: `callout_accessibility_test` (omgevallen 31-08 en 01-09, taken 5001 en 5200) en `callout_reveal_test` (01-09). Alle drie gereproduceerd door de wachttijd op nul te zetten: exact de meldingen uit de joblogs. ## Waarom niets dat tegenhield De poort ertegen bestaat al — `_fixedDelayInRunAsync` in `tool/check_conventions.dart`, geschreven nadat vier tests op één dag om deze reden gerepareerd moesten worden. Hij heeft dit anderhalve maand niet gezien: - hij zocht de kale schrijfwijze `Future.delayed(`, terwijl **126 van de 129** wachtpunten in `test/` `Future<void>.delayed(` schrijven; - hij keek 400 tekens voorbij de `runAsync(` — minder dan één `pumpWidget` met een widgetboom erin, en juist dáár stond het wachtpunt dat de negen storingen veroorzaakte. Netto: 3 van de 129 gezien, en groen gemeld. ## Wat deze PR doet **De poort** kent nu het typeargument en telt haakjes tot het einde van de aanroep. Tegen de originele carousel-test vindt hij 4 wachtpunten waar hij er 0 vond. `fixedDelaysIn` is losgetrokken van de schijf (zoals `classSizesIn`) en `test/fixed_delay_ratchet_test.dart` houdt beide blinde vlekken vast, allebei bewezen rood tegen de oude implementatie. De achterstand die daardoor zichtbaar werd staat als krimp-alleen basislijn `fixedDelayBaseline`, geregistreerd in `check_ratchet_trend.dart`. **De carousel-test** wacht op de uitkomst die hij daarna bewéért, via `pumpUntil` — de hulp die daar al voor bestond en die de zusterbestanden al gebruikten. Het bestand draait nu in 2 s. **De callout-tests** doen iets anders, en met opzet. Daar is niet beter gewacht maar het wachten wéggehaald: de test laadt het beeld voor, waarna `resolveIntrinsicSize` zijn maat synchroon teruggeeft en de overlay in de eerste build tekent. Dat pad bestaat al voor de rasterexports, die hun beelden om precies dezelfde reden voorladen. Twee redenen om het hier zo te doen: - die tests draaien zelf al binnen `runAsync`, waar een geneste `runAsync` — en dus `pumpUntil` — verboden is; - twee van de toetsen bewijzen *afwezigheid* (geredigeerde dia, niet-onthulde groep). In de widgetboom is "met opzet niets getekend" niet te onderscheiden van "nog niet gedecodeerd", dus die slaagden ook wanneer er nog niets getekend wás. Er valt daar niets aan te wijzen om op te wachten; voorladen haalt de vraag weg. Basislijn daarmee van 25 naar 24 bestanden, 37 naar 32 wachtpunten. ## Wat er open blijft De basislijn is geen schone lei: 32 wachtpunten, waarvan 7 bewuste uitzondering (de redenen staan in `pump_until.dart`) en 25 schuld. Bewezen rood en nog niet omgezet: `document_editor_screen_test` (vijf keer op 24/25-08) en `export_dialog_pdf_end_to_end_test` (24-08, toen is alleen het getal verhoogd). Eén blinde vlek in de poort blijft, en staat als zodanig in CHECKS.md: een wachtpunt in een helper die vanuit `runAsync` wordt *aangeroepen* staat er niet lexicaal in. `callout_reveal_test` had precies die vorm — de poort zag hem nooit. ## Getoetst - `make check-static` groen. - 170 tests over alles wat `check_conventions.dart` importeert, de drie carousel-bestanden en de callout-bestanden: groen. - Elke reparatie bewezen dragend met omgekeerde mutatie: oude regex → 4 van de 7 poorttests rood; oud 400-tekensvenster → het widgetboomgeval rood; voorladen eruit → precies de drie callout-toetsen die op gerenderde inhoud toetsen rood, de andere twee niet.
De linux-gate viel tussen 21-08 en 01-09 negen keer om op dit bestand
(taken 2594, 3099, 3404, 3658, 4283, 4366, 4974, 4986, 5317), elke keer
met een andere testnaam. Dat las als toeval en was het niet: het was
negen keer dezelfde regel.

`pumpPicker` gaf de kiezer 300 ms wandelklok en nam daarna aan dat de
mapscan klaar was. Op de runner — vier kernen, `--concurrency=14` — is
hij dat soms niet: `_loading` staat nog op true, de preview-kolom met de
Verwijderen-knop staat niet in de boom, en de `tap` erop vindt niets.
Welke test dat trof hing van de planning af.

Gereproduceerd door diezelfde wachttijd op 0 te zetten: alle zeven
tests vallen om met exact de melding uit het joblog.

Alle vier de wachtpunten in dit bestand wachten nu op de uitkomst die de
test daarna bewéért, via `pumpUntil` uit test/support/pump_until.dart —
de hulp die daar al voor bestond en die de zusterbestanden
(image_carousel_rename, image_carousel_picker_smoke) al gebruikten. Het
bestand draait daarmee in 2 s in plaats van per test 300 ms stil te
staan.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Deze poort bestaat sinds vier tests op één dag om dezelfde reden
gerepareerd moesten worden. Hij heeft daarna anderhalve maand niets
gezien, terwijl precies die fout de linux-gate negen keer deed omvallen.

Twee blinde vlekken, allebei in de meting zelf:

* hij zocht de kale schrijfwijze `Future.delayed(`. In `test/` staan 129
  wachtpunten en 126 daarvan schrijven `Future<void>.delayed(`.
* het zoekvenster was 400 tekens voorbij de `runAsync(`. Dat is minder
  dan één `pumpWidget` met een widgetboom erin — en juist dáár stond het
  wachtpunt van `image_carousel_delete_test.pumpPicker`, dat de negen
  storingen veroorzaakte. Het venster telt nu haakjes tot het einde van
  de aanroep.

Wat daardoor zichtbaar werd staat als krimp-alleen basislijn
`fixedDelayBaseline`: 25 bestanden, 37 wachtpunten. De regels erin
scheiden bewuste uitzondering (de reden staat in pump_until.dart) van
schuld, met per bewezen geval het taaknummer van de gate die erop
omviel. Een bestand dat eronder duikt wordt gemeld, zodat de winst
wordt vastgezet.

`fixedDelaysIn` is losgetrokken van de schijf zodat de meting zelf
toetsbaar is, zoals `classSizesIn` ernaast. Beide blinde vlekken staan
als geval in test/fixed_delay_ratchet_test.dart en zijn daar bewezen
rood tegen de oude implementatie — niet alle zeven tegelijk, maar de
gevallen die erover gaan.

Drieaanhalige stringliteralen worden nu ook gestript. Zonder dat valt de
poort over de specimens in zijn eigen test, dezelfde reden waarom
regelcommentaar al werd weggehaald: een poort die zijn eigen toets
afkeurt is niet te handhaven.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
docs: de vaste-wachttijdpoort is een ratchet, en wat hij niet zag (#1911)
Some checks failed
scans / scans (pull_request) Successful in 3m31s
static-gate / static-gate (pull_request) Has been cancelled
e1f86ba5a4
CHECKS.md beschreef de poort als absolute regel; hij draagt nu een
krimp-alleen basislijn. Het stuk benoemt ook wat de poort anderhalve
maand niet mat en waarom — een poort waarvan de blinde vlek niet
opgeschreven staat, wordt de volgende keer opnieuw geloofd.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
test(callouts): laad het beeld voor in plaats van 300 ms te gokken (#1911)
All checks were successful
scans / scans (pull_request) Successful in 2m37s
static-gate / static-gate (pull_request) Successful in 6m43s
1e9798dbaf
`callout_accessibility_test` viel op de linux-gate om op 31-08 (taak
5001) en 01-09 (taak 5200), `callout_reveal_test` op 01-09. Beide gaven
`CalloutOverlay` 300 ms wandelklok om zijn beeld te decoderen. Lokaal
gereproduceerd door die tijd op nul te zetten: exact dezelfde meldingen
als in de joblogs — een semantics-boom van drie lege labels, en `Found 0
widgets with text "A"`.

Hier is niet beter gewacht maar het wachten weggehaald.
`resolveIntrinsicSize` roept zijn listener meteen aan wanneer het beeld
al in de imagecache staat, en zet de maat dan nog vóór de eerste build.
Dat pad bestaat al voor de rasterexports, die hun beelden om precies
dezelfde reden voorladen — zonder dat komt de markering pas in het frame
dáárna en vangen die exports er maar één. `test/support/warm_image_cache`
doet in de test wat de productiecode al deed; de cachesleutel is het
bestandspad, dus de provider die de overlay zelf aanmaakt raakt dezelfde
ingang.

Dat repareert onderweg een stillere fout. Twee toetsen bewijzen
*afwezigheid* — de geredigeerde dia en de niet-onthulde groep tekenen
met opzet niets. In de widgetboom is dat niet te onderscheiden van "nog
niet gedecodeerd", dus die slaagden ook wanneer er nog niets getekend
wás. Met een warme cache is dat verschil er wel. Om diezelfde reden is
pollen hier geen alternatief: er valt niets aan te wijzen om op te
wachten.

Bewezen dragend: zonder de voorlaadaanroep vallen de drie toetsen die op
gerenderde inhoud toetsen om, en de andere twee niet.

fixedDelayBaseline gaat van 25 naar 24 bestanden, 37 naar 32
wachtpunten. CHECKS.md noemt nu ook de blinde vlek die blijft: een
wachtpunt in een helper die vanuit `runAsync` wordt aangeroepen staat er
niet lexicaal in, en callout_reveal_test had precies die vorm.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
brenno changed title from De linux-gate viel negen keer om op een wachttijd, en de poort ertegen mat bijna niets (#1911) to De linux-gate viel elf keer om op een wachttijd, en de poort ertegen mat bijna niets (#1911) 2026-09-01 20:04:51 +00:00
brenno force-pushed fix/carousel-delete-flake from 1e9798dbaf
All checks were successful
scans / scans (pull_request) Successful in 2m37s
static-gate / static-gate (pull_request) Successful in 6m43s
to db47954007
All checks were successful
scans / scans (pull_request) Successful in 3m15s
static-gate / static-gate (pull_request) Successful in 8m40s
2026-09-01 21:37:07 +00:00
Compare
brenno merged commit eaab7ac072 into main 2026-09-01 23:32:57 +00:00
Sign in to join this conversation.
No description provided.