2010-12-14 13 views
8

Podczas korzystania z mojej aplikacji natknąłem się na stan wyścigu w jakimś kodzie, który używa NSOperationQueue do uruchamiania zadań asynchronicznie po zdarzeniach wyzwalanych przez użytkownika. Wiem, jak naprawić stan wyścigu, ponieważ jest to głupi błąd projektowy, do którego nie będę się zagłębiał, ale chciałbym udowodnić błąd w przypadku testowym (aby nie wrócił podczas optymalizacji/refaktoryzacji dalej w dół linii). To mnie zaskoczyło. W jaki sposób można testować coś wielowątkowego, zwłaszcza gdy celem testu jest wygenerowanie warunków wyścigu?Kodowanie oparte na wątku testowym jednostki? Wymuszanie warunków wyścigu

Czy ktoś ma jakieś linki do materiałów referencyjnych, do których mogę się odnieść, jeśli chodzi o rozwiązywanie wątków i testowanie jednostkowe? Szczególnie interesuje mnie generowanie warunków wyścigowych.

+0

Przypuszczam, że można kpić z dowolnych współdzielonych struktur danych, a wewnątrz symulowanych obiektów można wykonać dowolną synchronizację, której wymaga wykonanie różnych wątków w "niewłaściwej" kolejności. –

Odpowiedz

4

Musisz upewnić się, że sekwencja zdarzeń powodująca stan wyścigu faktycznie powstaje podczas testowania. W tym celu należy wpłynąć na przeplatanie gwintów wewnątrz przypadku testowego.

Można to osiągnąć poprzez dodatkową (warunkową) synchronizację lub (prostsze i mniej niezawodne) dodatkowe liczniki czasu. Wstaw kilka wywołań sleep() w krytyczne sekcje, aby upewnić się, że działają wystarczająco długo, aby inny wątek znalazł się w niepożądanym stanie. Kiedy już to działa, zamień wywołania snu na jawną synchronizację (tj. Zablokuj jeden wątek, aż ten drugi rzeczywiście uzna, że ​​przybył).

Wszystko to uzależnione od flagi globalnej ustawionej w teście.

+3

Szczerze mówiąc, nie sądzę, aby ścisłe powiązanie kodu produkcyjnego z tym konkretnym testem było dobrym pomysłem. Oznacza to, że musisz uważać, aby nie zakłócić tego sprzężenia za każdym razem, gdy dokonasz refaktoryzacji kodu, co w pierwszej kolejności powoduje porażkę. –

+0

Nie, kruchość wrt. do refaktoryzacji faktycznie obsługuje to podejście testowe. Kiedy refaktoryzujesz, będziesz musiał ponownie przemyśleć warunki wyścigu. Wtedy może się okazać, że refaktoryzacja rzeczywiście wprowadziła nowe lub że te, na które wcześniej było podatne, nie mogą już się wydarzyć. –

+0

Po prostu nie rozumiem, jak to "zmusza" kogokolwiek do refaktoryzacji, aby przemyśleć potencjalne warunki wyścigu, lub że jest to naprawdę użyteczne. Najwyraźniej myślenie o warunkach wyścigu nie zadziałało po raz pierwszy. Każdy, kto w znacznym stopniu refaktoryzuje kod, musiałby całkowicie wyrzucić istniejący kod testowy i napisać nowe lub uczynić kod testowy bezużytecznym. Tak czy inaczej, to pokonuje cel posiadania kodu testowego. Lepiej byłoby mieć kod testowy, który nie zanieczyszcza głównej bazy kodu, ale zamiast tego sygnalizuje kompilację jako uszkodzoną, jeśli tak jest. –

Powiązane problemy