Zdaje się, że niektórzy trzymają się zasady, ze każdy bug musi mieć test który tego buga odtwarza i pilnuje, by odtąd bug nigdy nie powrócił. (@jarekr000000 o ile pamiętam o tym pisał kiedyś; ale już mi się nie chce teraz szukać)
W zasadzie założenie wydaje mi się sensowne, tylko czasem trudne w realizacji.
No dobrze, załóżmy, że mamy kod, który jest błędny, ale te błędy wyskakują tylko raz na jakiś czas, bo jest błąd we współbiezności - w jakimś szczególnym przypadku jakaś tablica jest odczytywana przez jeden wątek, modyfikowana przez drugi, zabrakło mutexu, albo ktoś chciał być mądry i celowo nie dał mutexu, bo sądził że memory barriers wystarczą, jednak nie wystarczyły i tego rodzaju rak.
Nie wiem, jak napisać test automatyczny, który to odtworzy. Chyba jedyny sposób to taki, by odtworzyć konkretny przeplot: znaleźć instrukcję A, znaleźć instrukcję B, uruchomić dwa wątki, zatrzymać jeden na instrukcji A, zatrzymać drugi na instrukcji B, puścić oba, powtarzać 100 razy aż wreszcie będziemy mieli jednoczesny zapis z dwóch wątków do tej samej zmiennej i błędy z tego wynikłe. Wygląda na w opór uciążliwe do napisania, ale pewnie możliwe.
Tyle że teraz naprawiamy buga. Mało tego, naprawiamy go porządnie: nie (tylko) dajemy mutex tam, gdzie go zabrakło, ale także przebudowujemy architekturę tak, by bug nie mógł się powtórzyć. Usuwamy sekcję krytyczną: usuwamy zmienną, która może być jednocześnie zapisywana z dwóch wątków (albo zapisywana z jednego i czytana z drugiego, whatever). Stosujemy wytyczne programowania funkcyjnego i za ich pomocą uwspółbieżniamy ponownie kod. Nie może być nieprawidłowej mutacji, skoro nie ma mutacji w ogóle.
Co teraz z naszym testem? Został on napisany tak, że zatrzymywał wątek na instrukcji A, puszczał drugi wątek na instrukcję B i tak dalej, by wymusić jeden konkretny przeplot. Ale nie ma już instruckji A ani instrukcji B. Czyli test w zasadzie należy wyrzucić?
Czy jest sens pisać test, któy jest w opór uciążliwy do napisania, jeśli natychmiast po naprawie buga musimy skasować test?