it-swarm-eu.dev

Jak mohu testovat vícevláknový kód jednotky?

Existují způsoby, jak jednotce otestovat váš vícevláknový kód na závodní podmínky a zablokování?

Chcete-li zjistit, zda provádějí způsob, jakým by měli být ...

34
Tamara Wijsman

ŠACHY , projekt Microsoft Research. Citace jejich webu:

CHESS je nástroj pro vyhledávání a reprodukci Heisenbugs v souběžných programech. CHESS opakovaně provádí souběžný test, který zajistí, že každý běh provede jiné prokládání. Pokud prokládání vede k chybě, může CHESS reprodukovat prokládání pro vylepšené ladění. CHESS je k dispozici pro řízené i nativní programy.

Aktualizace (23.9.2015): Pro C, C++ a Go můžete použít ThreadSanitizer .

19
Josh Kelley

ValgrindHelgrind což opravdu pomáhá. Pomáhá nejen poukázat na závody, které by mohly vést k hladovění nebo k zablokování, ale mírné zpomalení profilování programu někdy odhaluje závody, které by jinak nebyly vidět.

Takže, i když jdete komando s nějakou metodou bez zámku, stále to pomůže :)

Je však zaměřen na POSIX. Dodává se se záhlavími, díky nimž si jednoduché knihovny testů jednotek, jako je TAP, uvědomí, že běží, což je také velmi užitečné. Například byste mohli mít vlákno, které by normálně neblokovalo, když se snažíte získat zámek, do toho a blokovat (možná náhodně), jen simulovat hladovění.

10
Tim Post

Nepamatuji si podrobnosti přesně, ale tohle je obecný nápad. A udělal jsem to jen jednou, ale to, co jsem udělal, bylo oddělit re-entrant kód od kódu provádějícího úlohu, pomocí rozhraní, abych mohl zesměšňovat třídu úkolů.

Poté jsem navrhl mock-up, aby bylo možné zamknout hovor tak, abych věděl, že vlákno je v kritické sekci, a pak jej znovu zavolám a ověřím, že čeká, než uvolním první vlákno a čistě dokončím.

Něco takového.

Nejsem si jistý, že by to fungovalo pro složitější scénáře, ale pomáhá to zachovat chování během refaktorů.

5

V JAOO/GOTO letos jsem viděl tuto prezentaci:

http://gotocon.com/aarhus-2010/presentation/Testing%20Asynchronous%20Behaviour%20in%20an%20Instant%20Messaging%20Server

Trik spočívá v tom, že modelujete, co má vaše aplikace na kadeřnictví dělat, a to jak kroků vyvolání , tak i skutečných operací ve vaší aplikaci. Software John Hughes pak systematicky zkouší mnoho permutací kroků vyvolání opakovaně paralelně a poté kontroluje, zda stav aplikace odpovídá stavu modelu. Pokud je nalezena chyba, software ví, jak snížit kroky na minimální případ, který chybu způsobil.

Živě předvedl, jak zachytit několik chyb v základních knihovnách Erlang, které už 15 let číhaly, a občas hlásil, ale nikdo nedokázal přijít na to, odkud pocházejí, a jak tedy opravit. S minimálními případy, které software nahlásil, mohl správce knihovny opravit každou chybu během dne .

Bylo to SO působivé.

John Hughes prodává tento software prostřednictvím své společnosti.

2
user1249
  1. Testy s nereprodukovatelnými výsledky jsou zbytečné. To vylučuje zcela náhodné testy, ale ponechává v testech generovaných pseudonáhodnými sekvencemi.
  2. Každý herec v souběžném prostředí má algoritmické nebo jinak nesouvislé komponenty, které lze testovat konvenčními prostředky. Po jejich testování musí být všechny zbývající selhání v logice souběhu.
  3. Události v souběžném systému jsou ve skutečnosti vždy lineárním sledem událostí. Pokud se k měření času používá dostatečná přesnost, nedochází k „událostem současně“. To znamená, že aktéři v souběžném systému mohou být testováni sekvenčním generováním událostí. Pořízení sekvence událostí v době selhání souběžného systému poskytuje požadované testovací případy.
  4. Kód, který poskytuje aktérům živost (vlákna), je častěji než poskytován operačním systémem nebo knihovnami systému. Je bezpečné předpokládat, že uvedený kód nemusí být testován. Kód zodpovědný za komunikaci a synchronizaci je obvykle psán aplikačním programátorem. Tento kód lze otestovat bez vyvolání systémového kódu, tj. Bez spuštění podprocesů.
  5. Hraniční podmínky v algoritmickém kódu (fronta prázdná) často vyžadují zpracování v synchronizačním kódu, což je dobrý cíl pro testování.
  6. Definování serverů proxy kolem systémového kódu (t.wait ()) umožňuje během testování použití stubů/falešných funkcí.
2
Apalala

Můžete zkusit můj Relacy Race Detector . Je navržen tak, aby pečlivě a přesně ověřoval synchronizační algoritmy, jako jsou fronty výrobců a spotřebitelů a souběžné kontejnery, ale není příliš vhodný pro ověření celých programů. Možná je však dobrý nápad rozšířit synchronizaci a mutexovat po celém programu, ale soustředit synchronizaci na specializované komponenty (které lze ověřit pomocí Relacy).

1
Dmitry Vyukov

Není to snadné, ale v zásadě jediným způsobem je volat vícevláknový kód souběžně z více vláken a změnit načasování a řazení náhodně hraním s náhodnými Thread.sleep() a Thread.yield() volání (za předpokladu Java).

K dispozici jsou také připravené nástroje (například TestNG), které dělají něco, co je popsáno výše, ale pokud ještě vím, ještě nejsou příliš zralé.

0
Joonas Pulakka

Nejedná se o přísný test jednotky, ale o runtime kontrolu, která mi pomohla s některými přerušovanými testy. Je to rychlé a špinavé, ale fungovalo to.

Když je udělen mutex, sleduji, které vlákno má. Všechny žádosti o mutex mají časový limit třicet sekund, po kterém křičí na mrtvém bodě.

Poté mohu použít seznam udělených mutexů, abych zjistil, které vlákno drží blokující mutex a proč tak dlouho. V mých případech je to zatím proto, že to bylo uvázlé na něčem jiném, takže můžu tuto situaci napravit.

Fungovalo to pro mě, protože moje mutexy mají třídu platforem pro různé platformy, což usnadňuje vkládání záznamů a vypršení časového limitu. Také jsem věděl dost o aplikaci, abych věděl, že by nikdy neměla blokovat na mutexu po dobu 30 sekund.

Nemusí to být úplně obecný účel, ale ušetří to spoustu ladění asi za pár hodin programovacího úsilí. Režie je zanedbatelná a lze ji vytvořit pouze pro ladění.

Podívám se na jeho rozšíření, abych zaznamenal sekvence vnořených požadavků na mutex, a uvidím, zda nějaké potenciálně vyvolávají zablokování (např. Jedno vláknové blokování A pak B a další zámky B pak A), spíše než jen skutečně indukující zablokování, ale zatím to bylo hodně přínosem pro triviální úsilí.

0
Andy Krouwel