TABLE OF CONTENTS:
Autor: Michał Zaczyński (Test Manager)
Piotr Strzałkowski i Maciej Gajdzica – nasi eksperci od systemów safety-critical wzięli udział w webinarze na zaproszenie SoDA. Podczas rozmowy zdradzili kilka dobrych praktyk, które warto wdrożyć w każdym projekcie, nawet jeśli nie jest to oprogramowanie typu safety-critical.
Przeczytaj nasz wpis lub obejrzyj film, który znajdziesz na końcu artykułu.
Cześć, jestem Piotr Strzałkowski. Niestety nie mogłem wziąć udziału w spotkaniu na żywo, dlatego postanowiliśmy z Maćkiem nagrać naszą rozmowę, na temat naszej drogi od zwykłych systemów embedded do systemów, gdzie bezpieczeństwo ludzkie jest priorytetem. Chcemy Wam dziś przedstawić sposoby jak przeszczepić pewne procesy do systemów mniej krytycznych.
Piotr Strzałkowski: Projekt ten był dla mnie wyzwaniem. Choć wcześniej pracowałem z normami to jednak systemy safety-critical i tworzenie oprogramowania do takich systemów jest bardzo wymagające ze względu na to, że musimy spełnić odpowiednie normy dla danej branży na przykład: kolejowej, samochodowej, albo dla branży lotniczej.
Te normy nie do końca opisują ścieżkę czy sposób, w jaki powinniśmy pracować. Omawiają procesy, omawiają pewne metryki jednak nie ma szczegółowej informacji, jak należy działać.
Tworząc zwykłe oprogramowanie embedded nie musimy takich norm spełniać, nie musimy zbierać pewnych metryk (możemy, ale nie musimy). A w tym przypadku jest to wymagane.
Wszystkie procesy muszą być dokładnie opisane. Czasami z kolegami żartowaliśmy, że przez procedury na jedną linię kodu mamy 100 linii dokumentacji. W tych projektach tak jest i trzeba się z tym pogodzić.
Konieczne jest także wprowadzenie różnych procesów testowania, na różnych poziomach. Począwszy od najniższego poziomu testów czyli unit testów, przechodząc do testów integracyjnych między modułami. Następnie do testów integracyjnych z hardware, i dalej do jeszcze wyższych testów – funkcjonalnych.
Dlatego cały zespół musi być wyszkolony i zaznajomiony z normami. Musi być świadomy jak powinien kodować, jakie kroki podejmować i dobrze znać narzędzia, których będziemy używać.
Maciej Gajdzica: Normy i procesy mogą się wydawać przytłaczające. Gdy nabraliśmy doświadczenia w projektowaniu systemów safety-critical, zdarzało nam się wracać do projektów o takiej samej charakterystyce i sami proponowaliśmy podobne rozwiązania dotyczące na przykład unit testów, statycznej analizy lub używania złożoności cyklomatycznej.
Jeśli to było możliwe, to dążyliśmy do wprowadzenia takich elementów, bo uważaliśmy, że warto.
Może się wydawać że te wszystkie ograniczenia, certyfikacje, normy, dokumentacja, testy, dodatkowe narzędzia są obciążeniem i spowalniają projekt. Wymagają nauki i nie warto stosować ich w zwykłych projektach.
Nie warto może przenosić w 100% tych schematów, ale niektóre elementy były bardzo przydatne. Kiedy realizowaliśmy projekty, które nie miały określonych norm bezpieczeństwa i restrykcyjnych wymagań, my po prostu chcieliśmy sprawdzonych metod pracy.
Pamiętam pierwszy projekt, który wspólnie realizowaliśmy. Na początku była niepewność, dlatego, że systemy safety critical mają dużo dodatkowych obostrzeń i dużo dodatkowych elementów, które musimy wykonać.
Wszyscy nie czuliśmy się do końca pewnie i nie widzieliśmy czy te techniki faktycznie działają. Czy one nam pomogą i czy będziemy po prostu dobrze pracować.
Punktem przełomowym, które przekonał mnie do tego procesu (pracy zgodnie z normami) było zadanie jakie miałem do wykonania: byłem odpowiedzialny za komunikację pomiędzy procesorami. System zawierał kilka procesorów i ta komunikacja było dość skomplikowana.
Miałem zaimplementować komunikację na jednym z tych procesorów, a następnie mieliśmy je zintegrować z innymi fragmentami kodu, które były tworzone przez inne zespoły.
Pamiętałem swoje doświadczenia z poprzednich projektów, o niższym poziomie bezpieczeństwa. Nie mieliśmy w nich takiego poziomu dokumentacji testów i pamiętam to jako naprawdę ciężką przeprawę.
Musieliśmy zabrać wiele osób, musieliśmy testować to przez długi czas, często musieliśmy też testować ręcznie. Gdy coś się zepsuło to zwykle jedna osoba to naprawiała, a reszta odpowiedzialna za inne części systemu tak naprawdę się nudziła i trwało to długo.
Natomiast zarządzanie projektami IT wymaga pewnych usprawnień, dlatego w kolejnym projekcie to wyglądało już zupełnie inaczej. Najpierw zrobiliśmy dokumentację, przemyśleliśmy na papierze, w jaki sposób ta komunikacja powinna wyglądać, przeanalizowaliśmy wszystkie przypadki.
Potem ja zaimplementowałem swoją część, wykonałem unit-testy, sprawdziłem czy dobrze działa ta część, za którą byłem odpowiedzialny. Później przeprowadziłem testy z danymi wejściowymi od innych części systemu. Kiedy doszło już do tej właściwej integracji, okazało się, że po pierwszych małych problemach i nieporozumieniach, bardzo szybko udało nam się dojść do końcowego rezultatu. Byłem zaskoczony, że tak szybko poszło. To był ten moment, kiedy przekonałem się, że faktycznie te procedury (wykorzystywane w systemach safety-critical) są dobre, faktycznie mogą pomóc!
To nie jest tak, że musimy po prostu je stosować, żeby dopełnić formalności. One przynoszą wymierne korzyści, pomagając podnosić bezpieczeństwo systemów informatycznych.
Utwierdziłem się w tym przekonaniu, gdy pracowaliśmy przy kolejnym projekcie – wersji demo systemu, dla jednego z naszych klientów. Projekt był na wczesnym etapie rozwoju. Były dwa procesory, które miały robić praktycznie to samo, ale 2 różne zespoły pracowały nad ich funkcjonalnościami.
Nasz zespół pracował procesowo. Wybraliśmy drogę iteracyjną, gdzie mieszaliśmy ze sobą development, testy i różnego rodzaju sprawdzenia.
Drugi zespół poszedł bardziej klasyczną ścieżką, którą znaliśmy z wcześniejszych projektów. Najpierw wykonywało się development pewnej większej części, a dopiero później zajmowaliśmy się testami i zapewnieniem dodatkowej jakości. Było to podzielone na większe bloki.
Początkowo odczuwałem niepewność, bo nam wszystkim w zespole wydawało się, że nam idzie to wolniej, a drugi zespół ma lepsze wyniki. Z drugiej strony, od strony inżynierskiej mieliśmy wrażenie, że jest to dobrze zrobione, przemyślane. Wszystko przechodziło testy. W czasie trwania projektu okazało się, że my już dawno rozwiązaliśmy pewne problemy, z których ten drugi zespół w ogóle nie zdawał sobie sprawy. Odłożyli testy na później i musieli to robić większymi blokami. Wtedy przekonałem się, że droga, która wymaga od nas więcej trudu i dodatkowych narzędzi czy praktyk może mieć sens i przynieść faktyczne korzyści, które możemy wyrazić w liczbach. Piotrek, co myślisz na ten temat?
Piotr Strzałkowski: Cóż mogę powiedzieć. No, to była lekcja. Było to poniekąd zderzenie ze ścianą. Przy poprzednich projektach pracowałem z normami, jednak w tym projekcie obostrzenia były bardzo wysokie i normy do końca nie stwierdzały, którą ścieżką trzeba iść.
Normy regulowały jakość kodu, sugerowały jakie metryki zastosować, ale decyzję, z których metryk możemy skorzystać musieliśmy podjąć sami. Pojawiło się najważniejsze pytanie: czym jest tak naprawdę kod wysokiej jakości? Według mnie to taki, który jest utrzymywalny, niezawodny i umożliwia przenoszenie na inne platformy albo do innych projektów.
Piotr Strzałkowski: Kod powinien być czytelny, podzielony na moduły, powinien mieć zdefiniowane odpowiednio interfejsy. Te cechy mają też swoje metryki: złożoność cyklomatyczna, złożoność Halstead’a lub takie podstawowe jak ilość błędów czy ilość linii kodu.
Dzięki tym metrykom możemy zdefiniować jak dobry kod mamy. Żeby uzyskać te metryki, musimy zastosować odpowiednie testy, na przykład statyczną analizę kodu, review czy unit testy. W ten sposób otrzymujemy metrykę pokrycia linii kodu, funkcji albo decyzji.
Łącząc te dane z innymi danymi z projektu, możemy profilować nasz projekt. Nasz zespół poinformuje nas, że wystąpiły jakieś problemy gdy spojrzymy na te metryki.
Gdy w pewnych modułach lub częściach kodu pojawią się problemy, będzie można przeorganizować pracę zespołu. Dzięki metrykom, lider nie zaglądając do kodu, może zauważyć niespójności: architektoniczne lub związane z procesem testowania i szybciej podejmować decyzje.
Maciej Gajdzica: Sprawdzamy metryki, które sugerują błędy. W kodzie teoretycznie wszystko jest ok. Metryki wskazują nam miejsca, którym możemy przyjrzeć. Intuicyjnie wiemy, że coś jest nie tak, po angielsku mówimy code smell i to jest fajna metafora – wiemy, że coś tu śmierdzi, jeszcze nie wiemy co, ale musimy to znaleźć. Te metryki są drogowskazem, ale też powinny być później zinterpretowane. Zdarza się, że metryka wskaże jakieś miejsce do poprawy, ale to miejsce powinno zostać tak, jak jest. Wtedy wiemy, że powinniśmy to opisać jako wyjątek od reguły i uzasadnić dlaczego uważamy, że tutaj możemy tę metrykę przekroczyć.
Piotr Strzałkowski: Jako menadżer bazuję na liczbach. Mam dokładne dane, które może omówić z innym menadżerem lub z zespołem i na tej bazie podejmować decyzje. Mogę łączyć ze sobą dane, profilować np. ilość błędów z ilością danych rzucanych na GITa. To może nam powiedzieć czy mamy problem z process review, z procesem testowania czy np. z jakością kodu. Dzięki temu możemy skutecznie podejmować decyzje, a zarazem prezentować rzetelne dane klientowi.
Maciej Gajdzica: te metryki wspierają dyskusje i dzięki temu zespół czuje się bardziej zaangażowany. Po pierwsze mamy poczucie dobrze zrobionej inżynierskiej roboty. Po drugie bazujemy na danych. Po trzecie, mamy też poczucie, że jesteśmy słyszani i nasze pomysły są później analizowane na forum, a najlepsze wchodzą do projektu. To poprawia atmosferę.
Piotr Strzałkowski: Nie od razu Rzym zbudowano i dobór metryk jest kluczowy. Nie zawsze wszystkie początkowe nasze założenia muszą się sprawdzić. Po to jest proces iteracyjny, żeby co sprint sprawdzać: jakie są wartości i czy metryki się sprawdzają. Jeśli dane nie są dobre i trzeba zmienić metryki.
Jest wiele metryk. Warto poszukać, zastanowić, jakie mamy dostępne narzędzia i dobrać takie metryki do swojego projektu, które będą odpowiedni. Ważnym jest również to, w jaki sposób podejmujemy decyzje w zespole (czy to architektoniczne, czy dookoła projektowe). Z naszego doświadczenia wynika, że autorytarne podejmowanie decyzji przez jednego architekta nie do końca się sprawdza. Pewne rozwiązania techniczne mogą stać się nietestowalne albo zaangażowanie innych członków zespołu może drastycznie spaść. Dlatego ostateczną decyzję powinien podejmować lider, ale biorąc pod uwagę opinie członków zespołu.
Burze mózgów i spotkania, na których ludzie z różnym doświadczeniem mogą wymienić się wiedzą, angażują członków zespołu. Z punktu widzenia lidera nie jest to zespół jednostek i fachowców. Tworzy się więź – prawdziwy zespół, który ze sobą współpracuje.
Kolejnym ważnym elementem w takich projektach są narzędzia.
Maciej Gajdzica: Członkowie zespołu często polecają narzędzia, których już używali. I tu trzeba podjąć decyzję, bo w systemach safety-critical często mamy do dyspozycji drogie, zaawansowane narzędzia, ale one nie załatwiają za nas całej pracy. Można wpaść w pułapkę: wydaje nam się, że kupimy drugie narzędzie i po prostu wszystko jest załatwione, a w praktyce okazuje się, że tak nie jest.
Piotr Strzałkowski: Zgadzam się z tobą. Problem jest wtedy, gdy nie uwzględnimy czasu na przeszkolenie zespołu z obsługi tych narzędzi. Po co nam narzędzie, które jest źle skonfigurowane i źle określone metryki. Metryki nie pokazują nam tego co powinny i tak naprawdę mamy bałagan w projekcie: metryki pokazują nam złe rzeczy, podejmujemy złe decyzje, pojawiają się coraz większe problemy.
Maciej Gajdzica: Ja tutaj jako przykład mogę podać systemy operacyjne, które były wykorzystywane w projektach safety-critical. Tam problemem było to, że mogliśmy używać kodu tego systemu operacyjnego, mogliśmy go dołączyć, ale trzeba go było odpowiednio umieścić w projekcie. Czyli trzeba było spełnić te wszystkie normy, które były nakładane i to nas nauczyło że tak naprawdę oprogramowanie nigdy nie jest darmowe. Oczywiście to nie znaczy, że powinniśmy używać tylko Polyspace’a czy VectorCasta, które kosztują po kilkadziesiąt tysięcy euro. Można wdrożyć darmowe narzędzia i jeżeli uda nam się to zrobić to powinny być te, które bardziej odpowiadają zespołowi.
Musimy mieć na uwadze, że to nie jest tak, że dostajemy narzędzia, które są bardzo drogie i wszystko robią za nas oraz obniżają odpowiedzialność zespołu. Albo mamy darmowe narzędzia, oszczędzamy bardzo dużo pieniędzy i w ogóle nie musimy w związku z tym ponosić żadnych kosztów.
Gdy zrealizowaliśmy kilka projektów, zbudowaliśmy sobie cały system różnych narzędzi. Były ze sobą połączone i wydawało, że mamy już wszystko gotowe. Że wystarczy przenieść i wszystko będzie dobrze działało w innych okolicznościach, przy innych projektach.
Piotr Strzałkowski: Rzeczywistość okazała się brutalna i nie wszystko było łatwo skalowalne. Nie da się więc przenieść wszystkich narzędzi 1:1 do innych projektów. Z niektórych trzeba zrezygnować. Niektóre trzeba dopasować, niektóre metryki całkowicie nie pasują do pewnych projektów. Trzeba więc samodzielnie sprawdzić, czy narzędzia i metryki pasują do danego projektu i iteracyjnie je dostosowywać.
Maciej Gajdzica: dobrze, że poruszyłeś iteracyjność. My już później wiedzieliśmy jakie narzędzia będą nam potrzebne, do czego one służą i w jaki sposób je wykorzystywać. Teraz załóżmy, że wchodzimy do nowego projektu, który trochę się różni od poprzednich. Są też inne osoby w zespole. Wiemy co chcemy osiągnąć, ale nie możemy tego wszystkiego wrzucić na raz. Podejście iteracyjne jest najlepsze. Mamy już narzędzie, które wcześniej działało i poprawiło jakość naszego kodu. Przykładowo: nie od razu jest nam potrzebna pełna automatyzacja wszystkiego. Z doświadczeń z Continous Integration wiemy w jaki sposób konfigurować serwery, co powinniśmy wypuszczać w testach nocnych, jaką część testów przenosić na hardware. Gdybyśmy chcieli to wszystko od razu wdrażać do nowego projektu to byt po prostu nie działało.
Piotr Strzałkowski: Są takie kluczowe elementy, których nie powinno się wprowadzać od razu, na samym początku. Lepiej jest się wstrzymać, poczekać, a gdy projekt się rozwinie zobaczyć co może być potrzebne. Wiadomo, że czasami zaczniemy od języka C kończymy na C++. Czasami są takie funkcjonalności, do których dostosowujemy narzędzia. Albo klient zmienia wymagania, zmieniają się warunki środowiskowe, zmienia się hardware – wtedy musimy to wszystko pozmieniać. Tak więc, są pewne elementy, które można w prosty i łatwy sposób przeskalować. Z niektórymi trzeba się wstrzymać i zobaczyć jak to się rozwinie.
Maciej Gajdzica: Dla tych, którzy inwestują w projekt jest on najważniejszy na świecie i dla nich jest krytyczny. Z drugiej strony, dla nas jako inżynierów ważne jest to, żeby zrobić go dobrze i zgodnie ze sztuką – najlepiej jak potrafimy. Możemy pomóc zrealizować te oczekiwania wykorzystując kilka czysto inżynierskich technik wyniesionych z naszych doświadczeń w budowie systemów safety-critical. Kluczowy jest proces wytwarzania oprogramowania. Zawsze chcemy żeby mieć dobrze przetestowane oprogramowanie. Dzięki, testom we wczesnej fazie projektu i dlatego, że łączymy zadania deweloperskie i testowe, jesteśmy w stanie szybko osiągać dobre rezultaty. Rozplanowanie testów na różnych poziomach, Continous Integration, statyczna analiza kodu są tym, co pomaga w każdym projekcie.
Piotr Strzałkowski: Z mojego punktu widzenia, kluczowym jest, żeby jak najszybciej wybrać i zdefiniować podstawowy zestaw metryk. Dzięki temu, od samego początku widzimy jak rozwija się projekt, co się w nim dzieje, jakie mamy problemy i w jakich obszarach. Dobór metryk, sprawdzanie wartości, nauka zespołu – wytłumaczenie na co każdy powinien zwrócić uwagę jest najważniejsze.
Maciej Gajdzica: Z punktu widzenia zespołu też widzę plusy: zespół bierze udział w podejmowaniu decyzji, ma realny wpływ na projekt. Nie są to tylko osoby wykonujące czyjąś wizję tylko czują się częścią tego projektu. Dzięki temu mamy większe zaangażowanie i to widać praktycznie we wszystkich działaniach, które realizujemy.
Piotr Strzałkowski: Zgadzam się z tobą ponieważ każdy chce wykonać swoją pracę jak najlepiej i chcę być dumny z tego co robi.
Dowiedz się więcej o tym jak projektujemy systemy safety-critical.
Maciej Gajdzica – Senior Software Developer, Programista systemów embedded, specjalizujący się w systemach safety-critical. Pracował m.in. nad systemem sterującym ruchem pociągów, a ostatnio rozwija oprogramowanie dla branży medycznej. Propagator dobrych praktyk – szczególnie TDD – w branży embedded. W wolnych chwilach konstruuje robota Micromouse odnajdującego drogę w labiryncie i opisuje ten proces na swoim blogu http://ucgosu.pl/
Piotr Strzałkowski – Embedded Domain Manager, inżynier z trzynastoletnim doświadczeniem w branży systemów wbudowanych o specjalizacji w projektach automotive i safety-critical. Miłośnik modelarstwa RC i tuningu mechanicznego wszelkich pojazdów.