WERKZEUGE UND FRAMEWORKS

Unser Techstack.

Als Software Entwickler und Cyber Security Experten haben wir Erfahrung mit den unterschiedlichsten Technologien. Wir sind breit aufgestellt, können uns aber schnell in ein Thema vertiefen und Spezialaufgaben lösen.

Softwareentwicklung

Programmiersprachen

Im Laufe der Jahre haben wir unsere Kenntnisse in mehreren Programmiersprachen vertiefen können. Die meisten davon haben wir in großen Projekten mit Zehntausenden von Codezeilen eingesetzt.

Sprache Beschreibung
C/C++
C/C++ ist die Sprache bei der wir auf über mehr als 15 Jahre Erfahrung zurückgreifen können: von ANSI C bis C11, von C++11 bis C++20. Wir haben auch umfassendes Wissen und Praxiserfahrung über die Build-Infrastruktur (Continuous Integration, CI/CD), die es braucht, um erfolgreich Projekte mit diesen Sprachen umsetzen zu können. Neben Code-Generatoren, die z. B. von der IEC 61131-3 in diese Sprache übersetzen, haben wir auch hoch portable SPS-Laufzeitsysteme (bis SIL3 bzw. ASIL C; ISO 262626, IEC 61508) und Interpreter implementiert, die für den Einsatz in Mikrocontrollern geeignet sind. Wir haben bereits mit GCC, Clang/LLVM, IAR, Keil und Microsoft Visual C++ gearbeitet.
Python
Python bietet aufgrund seiner weiten Verbreitung über eine Vielzahl an Paketen, die bereitstehen, um Aufgabenstellungen schnell lösen zu können. Mit Python haben wir beispielsweise modellbasierte Code-Generatoren implementiert, die Build-Skripte und Test-Stubs für SPS-Laufzeitsysteme erzeugen und dabei maschinell überprüfbar machen, ob Architekturvorgaben eingehalten werden. Weiters wurde auch ein eigener Python Disassembler für "Obfuscated Code", unter Verwendung einer speziell dafür modifizierten CPython Runtime, für ein Reverse Engineering Projekt entwickelt.
Go
Go ist die Sprache unserer Wahl zur Implementierung von Backend-Services oder von Werkzeugen, die möglichst abhängigkeitsfrei eingesetzt und plattformübergreifend gebaut werden können. Im Go-Umfeld haben wir insbesondere Erfahrung mit X.509 Mechanismen, GraphQL Schnittstellen und Netzwerkprotokollen.
Java
Java kennen wir aus dem Bereich der IDE-Entwicklung. Wir verfügen über Erfahrung im Eclipse Ökosystem und haben bereits Eclipse-basierende IDEs um OSGi-Komponenten erweitert. Beispiele hierfür sind Code-Generatoren zur Implementierung von SPS-Logik in C++ und Python, Build-Systemen für SPS-Applikationen und Services, die es erlauben, C/C++ Toolchains deklarativ in IDEs einzubinden.
Lua
Lua schätzen wir aufgrund seiner Schlankheit und der universellen Einsatzbarkeit. Den Interpreter haben wir bereits mehrfach in bestehende C/C++ Applikationen eingebettet. Auch haben wir Erfahrung mit der Anbindung bestehender Bibliotheken in Lua-Applikationen. Lua-Applikationen lassen sich auch hervorragend Test-Driven entwickeln.
Shell
Shell-Skripte setzen wir gerne ein, um High-Level Abläufe zu automatisieren. Dazu zählen Initialisierungs-Skripte, aber auch komplizierte Logik in beispielsweise Embedded Systems.
andere Sollte es Tasks geben, die Tätigkeiten in anderen Sprachen erfordern, trauen wir uns das grundsätzlich zu, erwarten uns aber eine verhältnismäßig größere Einarbeitungszeit, da unser Fokus auf die erwähnten Sprachen gerichtet ist. Wir hatten in Projekten bereits mit PHP, Ruby, Perl und diversen Assembler-Dialekten zu tun.

Test und Mocking Frameworks

Wir sind Verfechter von testgetriebener Entwicklung. Den größten Vorteil sehen wir in der mit der Testerstellung einhergehenden formalen Definition des Systems.

Framework Beschreibung
doctest
doctest nutzen wir gerne, um Applikationen, die in modernem C++ erstellt wurden, zu testen. Es zeichnet sich durch rasend schnelle Compiles aus, was gerade während der Entwicklung vorteilhaft ist.
Catch2
Catch2 setzen wir ebenfalls gerne ein, um Applikationen zu testen, die in modernem C++ erstellt wurden. Es ist weit verbreitet und bietet für praktisch alle Mechanismen von C++ einfach zu verwendende und gut lesbare Überprüfungsroutinen.
Unity Unity zeichnet sich durch geringe Anforderungen an das darunterliegende System aus. Es ist hoch portabel und lässt sich auch wunderbar auf Embedded Systems einsetzen. Wir haben bereits einen Artikel über die Integration des Frameworks in CMake-basierte Projekte veröffentlicht.
ucunit ucunit ist ein älteres, ultra-leichtes Test-Framework, das wir insbesondere im Zusammenhang mit Embedded Systems eingesetzt haben. Wir haben ein Team begleitet, das dieses Framework für den Einsatz zum Test von sicherheitskritischen Anwendungen (bis SIL3, ASIL C) zertifiziert hat.
cmocka cmocka haben wir ebenfalls in Projekten eingesetzt, bei denen ein C Library bereitstand. An diesem Framework schätzen wir die gute Auswertbarkeit der Testergebnisse.
cppunit CppUnit haben wir in älteren C++ Projekten verwendet. Mittlerweile setzen wir lieber auf Catch2.
pytest
pytest verwenden wir zum Testen von Python Code. Auch ist dieses Framework gut geeignet, um Integrations- und/oder Systemtests für C/C++ Applikationen zu erstellen.
Testify Testify setzen wir für Tests von in Go geschriebenen Softwarekomponenten ein. Die Standardbibliothek der Programmiersprache selbst bietet bereits umfangreiche Unterstützung (beispielsweise HTTP-Server und -Client Komponenten) bei der Erstellung von Unit- und Integrationstests, die wir gerne nutzen.
mockery mockery nutzen wir zur automatisierten Erstellung von Mocks. Letztere können dann einfach von außen instruiert werden, um sich wie gewünscht zu verhalten. Damit lassen sich ausgezeichnet "Schlechtwetter-Szenarien" testen.
JUnit
JUnit haben wir umfangreich zur Erstellung von Unit- und Integrationstests für Java-Applikationen verwendet.
mockito
mockito nutzen wir zur Erstellung von Mocks für Unit- und Integrationtests für in Java entwickelte Applikationen. Wir haben es verwendet, um Tests für Parser und Transpiler zu erstellen.
RCP Testing Tool (RCPTT)
RCPTT haben wir umfangreich genutzt, um Systemtests für Eclipse RCP basierte Applikationen zu erstellen. Die Tests wurden dann "headless" durch eine CI/CD Umgebung ausgeführt, um Ende-zu-Ende Szenarien reproduzierbar zu machen.
LuaUnit LuaUnit ist unser Framework der Wahl zur Erstellung von Unit- und Integrationstests für in Lua entwickelte Komponenten. Es ist einfach integrierbar und bietet eine Vielzahl an fertigen, gut lesbaren Überprüfungsroutinen. Mocks haben wir meistens manuell erstellt, da dies mit Lua einfach und schnell möglich ist.
shUnit2 shUnit2 verwenden wir gerne im Zusammenhang mit komplexerer Logik in Shell-Skripten. In unserem Blog haben wir bereits einen Artikel veröffentlicht, in dem wir beschreiben, wie wir Shell-Skripte mit diesem Framework testen.