Přeskočit na obsah

Tato stránka byla automaticky přeložena z angličtiny, jediného jazyka, ve kterém se tento web píše. Číst originál.

Pokrytí: jedno měření, dvě otázky

pokrytí testy u Rust executable: jedno měření (scripts/rust-coverage), spodní hranice crate a doména relací/kontinuity a rozdílová kontrola změněného kódu z #214, která odmítá nový dluh a nedotčený starý dluh nechává být

Vykresleno z docs/COVERAGE.md — stejný Markdown, jaký zobrazuje GitHub.

Pokrytí testy Rust executable se měří jednou a kladou se mu dvě otázky. Měřením je scripts/rust-coverage: jeden export cargo llvm-cov, testovací kód vyloučený z obou stran každého zlomku, jedno pravidlo počítání řádků, funkcí a regionů (autoritou, jak se který počítá, je hlavička samotného skriptu). Každý konzument — kontrola cratu, kontrola domény, diferenciální kontrola a jakýkoli report — čte tentýž jeden soud. Neexistuje druhý práh, druhý parser ani procento počítané jinde jinak.

Dvě hranice a rozdílové měření

Podlaha crate (scripts/rust-coverage-threshold) je dolní mez pokrytí řádků celého spustitelného souboru, přičemž testovací kód je mimo jmenovatele. Je to ratchet proti hnití crate, nikoli příslib úplnosti.

Doména relace/kontinuity (scripts/session-coverage-threshold, nad soubory v scripts/session-coverage-domain) drží jeden subsystém na jeho vlastní spodní hranici, stejně na řádcích, funkcích i regionech. Spodní hranice pro celý crate neříká nic o tom, zda je subsystém, na kterém závisí kontinuita repozitáře, vůbec testován; tady se to hlídá.

Obě hranice jsou západky. Každá je pokrytí, které její předmět skutečně naměřil, když byla stanovena, a smí růst, nikdy klesat; když se pokrytí zlepší, zvyšte soubor i jeho mez společně. Pevná hranice nad tím, čeho kdy kterýkoli běh dosáhl, nekontroluje nic — jen učí lidi očekávat, že úloha bude červená — takže žádná z nich takovou hranicí není. Mez hranice crate drží pravidlo: project.rust-command-tested-in-file odmítne hranici pod FLOOR_BOUND, kterou deklaruje její kontrola scripts/ci/rust-command-check, a test/cases/77_rust_evidence.sh čte tutéž mez. Mez hranice domény drží samotné test/cases/77_rust_evidence.sh. Nový nepokrytý kód je odmítnut bez ohledu na kterýkoli agregát diferenciální kontrolou níže.

Diferenční kontrola (scripts/ci/coverage-differential, pravidlo project.new-code-is-covered) je invariant změněného kódu z úkolu #214. Drží v pokrytí každý spustitelný řádek, funkci a region, který změna přidává nebo se jich dotýká — měřeno proti merge-base větve s trunkem, včetně pracovního stromu, takže necommitnutá úprava se drží přesně jako commitnutá.

Proč diferenciální a co nedělá

Pokrytí celého repozitáře je pod 100 % a starý dluh je skutečný. Jediná podlaha pro celý crate nemůže zakázat nový dluh: změna může přidat nepokrytý kód, zatímco souhrn se sotva pohne. Diferenční kontrola vede hranici tam, kde ji lze udržet bez přepisování historie — u kódu, kterého se změna dotýká:

Co změna děláCo kontrola vyžaduje
přidá souborkaždý spustitelný řádek, funkce a region v něm pokrytý
přidává funkcipokryto
mění spustitelný řádekpokryto
mění větev nebo oblastpokryto
ponechává starý kód nedotčenýnic: není to věc této kontroly

Invariant je new_debt == 0 a legacy_debt_after <= legacy_debt_before. Kontrola se nikdy nedívá na řádek, kterého se změna nedotkla, takže nemůže chtít, aby se splácel starý dluh; selže na prvním změněném řádku, který se spouští a žádný test ho nezkouší. Změněný řádek, který se nemapuje na nic spustitelného — komentář, prázdný řádek, use, deklarace typu nebo testovací kód — není nález: není tam co spouštět, takže diff jen s dokumentací nebo jen s testy projde bez nálezů.

Pět výsledků, nikdy nesměšovaných

Kontrola hlásí a končí v jednom slovníku — stejném, který používá scripts/rust-coverage:

výsledekvýznamukončení
PASSkaždá změněná spustitelná položka je pokryta0
PASSzměna se nedotkla žádného zdrojového řádku crate0
SELHÁNÍzměněný spustitelný řádek, funkce nebo oblast je nepokrytá10
NEZNÁMÉgit nedokáže vyřešit základ, proti kterému se má diffovat (mělký klon, žádný vzdálený server)13
BLOCKEDcargo-llvm-cov chybí, nebo instrumentovanému běhu nešlo věřit12

Neznámé není průchod. Blokované není průchod. Spadlé měření není nikdy zelené — kontrola, která z „nástroj pokrytí selhal“ udělá průchod, je přesně ten způsob selhání, který celé úsilí existuje, aby odmítlo.

Test, který selže pod instrumentací, je také BLOCKED: cargo-llvm-cov nezapíše žádný export pro sadu, která selhala. Kontrola pak vypíše, co hlásil testovací harness, sekci failures: každé selhávající binárky s názvem a panikou každého selhávajícího testu, takže log úlohy jmenuje test, ne jen jeho binárku. Binárka ukončená signálem takovou sekci nezapíše a ani řádek test result:, takže se vypíše i její nedokončený blok running N tests: jeho hlavička, kolik testů dokončilo a jeho poslední řádky. Nemůže jmenovat test, který běžel, protože paralelní harness zapisuje řádek testu až po jeho dokončení; stderr cargo jmenuje binárku a signál. Zelený běh nevypíše nic z výstupu harnessu. test/cases/536_the_coverage_gate_names_the_failing_test.sh toto chování drží.

Spuštění

scripts/ci/coverage-differential                 # against origin/master's merge-base
scripts/ci/coverage-differential <base>          # against an explicit base
MJ_COVERAGE_EXPORT=<file> scripts/ci/coverage-differential   # reuse an existing export

scripts/rust-coverage --changed <base>           # the measurement directly
scripts/rust-coverage                            # both floors
scripts/rust-coverage --report                   # measure, hold nothing
scripts/rust-coverage --domain                   # the session/continuity domain only

CI spouští kontrolu v jobu coverage při každé změně pod apps/majordomus-cli/; lokální check a cesta pre-commit dospějí ke stejnému posouzení. Behaviorální důkaz je test/cases/132_coverage_differential.sh: spouští kontrolu proti pevnému exportu a syntetickým diffům a ověřuje, že záměrně nepokrytý změněný řádek selže, tentýž řádek pokrytý projde, změna jen v dokumentaci se nemá k ničemu držet a nerozlišitelná báze je UNKNOWN, ne tichý průchod.

Záznam, který čte předběžná kontrola

Měření celého cratu, které scripts/rust-coverage spouští samo (kontrola nebo --report), zanechá záznam v .ai/local/state/coverage/rust.json: součty cratu a domén, výsledek (pass, fail nebo report), návratový kód cargo pro instrumentovanou sadu a commit a strom, které změřilo. Strom se čte před během sady a znovu po něm a záznam říká clean jen tehdy, když jsou obě čtení čistá a jmenují stejný HEAD. --from, --changed a --domain nezaznamenávají nic: první měří strom, který skript nikdy neviděl, ostatní dva měří část cratu.

Kontrola verification.coverage preflightu (docs/PREFLIGHT.md) posuzuje pokrytí podle tohoto záznamu samotného. Záznam jiného commitu nebo stromu, který se pohnul, je stale a selhávající sada je failed i tam, kde prahy platí. Bez záznamu je kontrola unavailable. Záznam je lokální stav, takže odpověď pokrývá jen tento checkout. Měření z CI se k němu nikdy nedostane. test/cases/552_coverage_is_recorded_for_the_preflight.sh spouští skutečný skript proti náhradnímu cargo a nechá skutečný spustitelný soubor posoudit každý záznam, který zapíše.

Čím toto zatím není

Diferenciální kontrola drží pokrytí řádků, funkcí a regionů — dimenze, které cargo-llvm-cov pro tento crate měří. Neprovádí mutační testování ani injekci chyb; tam, kde záleží na smyslu predikátu (kontrola autorizace, rozhodnutí o důvěře, přechod stavu), číslo pokrytí dokazuje, že řádek běžel, ne že by test selhal, kdyby řádek byl špatně. Tyto subsystémy nesou vlastní adverzární testy (například sady důvěry a protokolu meshe) a kontrola pokrytí je pro ně nutná, nikoli postačující. Zastarání důkazů pokrytí je vázáno na export, proti němuž kontrola běží a který CI regeneruje při každém běhu; trvalý model důkazů a zastarání nad zaznamenanými běhy (území ADR 0041) není součástí této kontroly.

Tvrzení, která tento dokument definuje

Každý odkazuje na vlastní stránku s implementací, testem a místy použití.

Prohledává názvy a popisy všech stránek, které tento web publikuje.