Vor einem Jahr haben wir angekündigt uns mit Continuous Integration und Testing
von Gluon auf echter Hardware beschäftigen zu wollen. Dieser Beitrag soll unsere
bisherigen Ergebnisse zusammenfassen und einen aktuellen Ausblick geben.
Eines vorweg: Continuous Integration ist noch nicht gelöst. Aktuell bauen wir
unsere Software händisch. Dieser Betrag beschreibt unseren Fortschritt beim
Testing.
Hardware
Die von uns zusammengestellte Hardware ist stark von den folgenden Faktoren
getrieben:
- Wir brauchen bestimmte Funktionen, wie z.z. B.nbsp;B. Power Switches und Serial-Ports.
- Die Hardware darf nicht teuer sein, um einfach weitere Instanzen aufbauen
zu können.
- Tests müssen vollständig automatisch ohne Eingriff eines Benutzers möglich
sein.
Unsere Hardware besteht daher aus den folgenden Komponenten:
- Test-Server: Ein RaspberryPi 3 mit Raspbian
- Power Switch: Zum Schalten der Spannungsversorgung des Routers benutzen wir
8-fach Relaisboards aus dem Maker-Zubehör. Die Relais werden direkt von
GPIOs des RaspberryPi gesteuert. Die Relais werden auf der Ausgangsseite
der Netzteile der Router eingeschleift.
- Knöpfe am Router drucken: zum Drücken von Knöpfen am Router benutzen wir
ebenfalls Relais. Hierzu wird das Relais parallel zum Knopf des Routers
angeschlossen.
- Serial Port: Die Serielle Schnittstelle des Routers wird mit einem
USB-Seriell-Wandler (auch aus dem Maker-Zubehör) per USB an den
RaspberryPi angeschlossen. Diese Wandler sind auch direkt mit 3.3V Logik-
Spannung verfügbar und daher ohne weitere Wandler einsetzbar.
- Ethernet: Mindestens die Client-Seite des Routers muss vom RaspberryPi aus
erreichbar sein. Wir schließen das Client-Netz daher direkt mit einem
USB-Ethernet Adapter an.
- Device under Test: Welche Hardware hier zum Einsatz kommt ist davon
abhängig welche Hardware getestet werden soll. Wir haben unsere Tests mit
einem TP-Link WR-841 gestartet. Im Wesentlichen haben wir diesen Router
gewählt, weil der finanzielle Schaden so gering ist, falls wir den Router
in der Entwicklung zerstören.
Die folgenden Bilder sollen einen Überblick über unseren Aufbau geben:
Software
Unsere Software besteht aus den folgenden Teilen:
- Betriebssystem auf dem Testserver
- Test-Automation
- Wissen, wie der Router zu bedienen ist
- Tests
Betriebssystem
Als Betriebssystem auf dem Test-Server kommt ein Stock Raspbian zum Einsatz.
Somit steht uns auf dem Test-Server alle Werkzeuge eines normalen Linux zur
Verfügung.
Wesentliche Änderungen am Betriebssystem sind:
- Hardware-Initialisierung: Um GPIOs nutzen zu können müssen die
GPIOs exportiert werden. Die Tests gehen davon aus, dass vom System
durchgeführt wurde. Hierfür können z. B. Systemd-Units zum Einsatz kommen.
- Benutzer: Für alle Braunschweiger Freifunker, die an dieser Hardware
arbeiten werden eigene Benutzer angelegt.
Test-Automation
Als Testautomatisierung kommt labgrid zum Einsatz. Labgrid bietet
die Infrastruktur, die notwendig ist, um ein Embedded Device in einen bestimmten
Zustand zu bringen und anschließend auf diesem Gerät Befehle ausführen zu können.
Labgrid wurde zuvor nicht in einer low-cost Umgebung eingesetzt. Daher mussten
einige zusätzliche Treiber entwickelt werden:
- SmallUbootDriver: Der Bootloader auf den günstigen TP-Link Routern
ist, im Gegensatz zu Bootloadern auf größeren Embedded-Devices, sehr
minimalistisch. Darüber hinaus verhält sich der Bootloader anders, als
andere UBoot-basierte Bootloader. Der SmallUbootDriver ist in der Lage
diesen Bootloader zu steuern.
- SysfsDigitalOutput: Um die GPIOs auf dem RaspberryPi nutzen zu können
ist ein Treiber für diese notwendig. Dieser wird von SysfsDigitalOutput
bereit gestellt.
Hardwarewissen
Hardwarewissen, sowie die Tests sind im Git-Repository ffbs-ci
zusammengefasst.
Um die Hardware ansteuern und somit den Zustand des Device under Test steuern
zu können muss labgrid Wissen über Hardware und Software haben.
Das Wissen über die vorhandene Hardware ist im local.yaml abgelegt. Dort ist
beschrieben, wie die serielle Schnittstelle erreicht wird, welche GPIOs für
die Steuerung der Spannungsversorgung und des Reset-Buttons verwendet werden
sollen. Darüber hinaus können dort Konfigurationen für die verwendeten Treiber
angegeben werden.
Auch wird dort festgelegt welche Strategy labgrid zur Steuerung
der Hardware benutzt. In einer Strategy ist das Wissen abgelegt, wie das DUT
in Zustände gebracht werden kann. Im Fall des TP-Link WR-841 sind die folgenden
und einige weitere) Zustände in der SmallUbootStrategy definiert:
- uboot: Das System befindet sich in einer UBoot-Konsole.
- good_config: Das System wurde mit einer als funktionierend bekannten
Firmware per TFTP geflashed und befindet sich nun im Config-Mode.
- good_running: Das System hat den Config-Mode verlassen und befindet
sich nun im normalen Betrieb.
- new_running: Eine neue Firmware wurde über den Auto-Updater des
als funktionierend bekannten Systems geflashed und befindet sich nun
im normalen Betrieb.
Tests
Labgrid kommt mit einem Plugin für pytest. Die Tests sind daher für pytest
geschrieben. Unsere Tests befinden sich aktuell in test_uboot_strategy.py.
Um das Schreiben von Tests zu vereinfachen setzen wir auf pytest-fixtures:
Erwartet ein Test einen Parameter und es gibt eine Fixture mit diesem Namen,
so gibt pytest die Fixture als Parameter mit in den Test.
Für unsere Tests sind Fixtures definiert, die das DUT vor einem Test
in die Zustände der Strategy bringen. Die folgende Fixture bringt das DUT
in den Zustand uboot, also den Bootloader.
1
2
3
| @pytest.fixture(scope="function")
def in_uboot(strategy):
strategy.transition("uboot")
|
Der folgende Test prüft dann, ob der Bootloader überhaupt funktioniert.
Dieser Test ist eher als ein vorbereitender Test zu verstehen.
1
2
3
4
5
6
7
| def test_uboot(target, in_uboot):
command = target.get_driver('UBootDriver')
stdout, stderr, returncode = command.run('version')
assert returncode == 0
assert len(stdout) > 0
assert len(stderr) == 0
assert 'U-Boot' in '\n'.join(stdout)
|
Der folgende Test hingegen prüft, ob im Config-Mode, die vorgeschlagenen
Koordinaten korrekt sind. Wir ändern diese Koordinaten in unserem Gluon auf
eine Koordinate in Braunschweig, (etwas unauffälliger Lokalpatriotismus) daher
ist es sinnvoll zu prüfen, ob diese im Image auch korrekt abgelegt werden.
1
2
3
4
5
6
7
8
| def assert_web(url, text_to_find):
r = requests.get(url)
assert r.status_code == 200, "Trying to get url {} failed with status code {}. Was looking for text '{}' there...".format(url, r.status_code, text_to_find)
assert text_to_find in r.text, "Could not find '{}' in {}. Site returned:\n{}".format(text_to_find, url, r.text)
def test_good_config_default_coordinates(target, in_good_config):
assert_web("http://192.168.1.1/cgi-bin/config/wizard", "10.52378")
assert_web("http://192.168.1.1/cgi-bin/config/wizard", "52.26469")
|
Testabdeckung
Aktuell befinden sich in unserer Sammlung insgesamt 73 Tests.
Mit diesen Tests sind wir in der Lage das Update eines Routers von einer
als funktionierend bekannten Version auf eine neue Version zu testen und
in dieser neuen Version Tests durchzuführen.
Die Tests beschränken sich dabei aktuell auf Tests der für Freifunk Braunschweig
spezifischen Erweiterungen, sowie der grundsätzlichen Überprüfung der
Konnektivität zum Freifunk Braunschweig Netzwerk.
Hierbei werden viele für den Benutzer wahrnehmbare Funktionen, wie z. B. das
Aussehen und der Funktionsumfang der Weboberfläche der Router noch gar nicht
getestet.
Hier ist also durchaus noch Luft nach oben.
Ausblick
Mit den nächsten Schritten soll es nun in zwei Richtungen weiter
gehen.
Zum Einen soll das Freifunk-Lab um weitere Router erweitert und die
Testsammlung auf diese Router angepasst werden.
Hierbei soll besonders auf andere Architekturen geachtet werden.
Zum Anderen soll eine wirkliche Continuous Integration erreicht werden:
Werden Änderungen auf eines der Freifunk Braunschweig Repositories
gepusht, so sollen diese automatisch gebaut und auf der Hardware getestet
werden.
Anschließend ist denkbar dies ebenfalls für den Gluon Upstream zu tun.
Dies könnte die Gluon-Entwickler mit zeitnahen Smoke Tests ihrer
Änderungen versorgen.
Mitarbeit an diesen Themen ist gern gesehen. Freifunk Braunschweig ist unter
Kontakt zu erreichen.