Files
PolyTraderSharp/docs/TESTUMGEBUNG-Linux-VM.md
T
RichardandClaude Opus 5 a39ad67181
CI / Build & Tests (Linux) (push) Canceled after 0s
CI / Plattformneutralität & Hygiene (push) Canceled after 0s
Modulfenster geprueft; Screenshot-Verfahren in die Testanleitung aufgenommen
Nach der Lizenzaktivierung durch Richard sind alle vier Module aktiv - die
Anwendung meldet "Lizenz gueltig (online geprueft)", der Cache steht auf valid,
die Statusleiste zeigt vier Module. Damit ist D-2 live abgenommen, inklusive
HWID v2 auf Basis der Linux-machine-id. Ein Stueck von Roadmap A3 nebenbei.

Vier weitere Befunde:
- B-9: In den Datumsfeldern erscheint statt des Kalendersymbols ein Artefakt.
  Die Icon-Schriftart fehlt unter Linux, Fontconfig ersetzt sie stillschweigend
  durch eine andere. Nur im Bild zu sehen, nie im Log.
- B-10 (schwerwiegend, im vorigen Commit behoben): kein einziges DataGrid wurde
  gerendert.
- B-11: Spaltenueberschriften werden abgeschnitten, die letzten drei Spalten
  zeigen gar keinen Text mehr. Genau der A5-Punkt Spaltenbreiten: die festen
  Pixelwerte stammen aus der WinForms-Fassung mit schmalerer Schrift. Nicht
  behoben - Spaltenbreiten legt man sinnvoll erst mit echten Daten fest.
- B-12: Der Lizenzschluessel liegt im Klartext in server_settings.xml, obwohl
  die Projektkonvention Verschluesselung at-rest vorsieht und der Code beides
  unterstuetzt.

Positiv: Die acht KPI-Kacheln im Accounting brechen sinnvoll um - eine offene
A5-Frage ist damit beantwortet.

docs/TESTUMGEBUNG-Linux-VM.md Abschnitt 4.7 neu: wie ein Agent Oberflaechen
eigenstaendig begutachtet - Xvfb dauerhaft starten, mit xdotool navigieren, mit
import aufnehmen, Ausschnitte vergroessern, Kontraste nachmessen. Mit den
Lehren aus diesem Durchgang: grosszuegige Wartezeiten, nur eine Instanz
gleichzeitig (sonst kollidiert die zweite mit dem systemd-Dienst in der
Datenbank), und auf Zeichen achten, die falsch aussehen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 22:31:41 +02:00

11 KiB

Linux-Testumgebung (gemeinsam genutzte VM)

Stand: 26.08.2026 · Eingerichtet beim ersten Linux-Lauf von PolyTrader (Roadmap A4a).

Diese Anleitung gilt projektübergreifend. Sie richtet sich an alle Agenten und Entwickler, die auf der VM testen — nicht nur an PolyTrader. Die maßgebliche Fassung liegt auf der Maschine selbst unter ~/TESTUMGEBUNG.md; dieses Dokument im PolyTrader-Repo ist die versionierte Kopie. Wer etwas an der Umgebung ändert, zieht beide nach.


1. Was diese Maschine ist

Eine Ubuntu-Desktop-VM zum Testen — nicht für Produktivbetrieb, nicht für echte Zugangsdaten, nicht für Geld bewegende Läufe.

System Ubuntu 26.04 LTS, Kernel 7.0, x86_64
Ausstattung 31 GB RAM, 5 CPUs, ~33 GB freier Plattenplatz
Erreichbar 192.168.40.48 über einen WireGuard-Tunnel
Benutzer richard
Besonderheit Desktop-Umgebung vorhanden — grafische Anwendungen sind testbar, nicht nur Dienste

Warum eine Desktop-VM? Weil sich damit beides prüfen lässt: der kopflose Serverbetrieb (systemd) und die grafische Oberfläche auf der Zielplattform.


2. Zugang einrichten

Der Zugang läuft über SSH-Schlüssel. Passwort-Anmeldung wird nicht verwendet — Agenten geben grundsätzlich keine Passwörter ein.

2.1 Schlüssel erzeugen (auf dem eigenen Rechner)

ssh-keygen -t ed25519 -f ~/.ssh/testvm_<projekt> -N "" -C "<projekt>@testvm"

Ein eigener Schlüssel je Projekt — dann lässt sich einzelnen Projekten der Zugang entziehen, ohne alle anderen auszusperren.

2.2 Öffentlichen Schlüssel hinterlegen

Der Inhalt von ~/.ssh/testvm_<projekt>.pub wird auf der VM in ~/.ssh/authorized_keys eingetragen. Das muss ein Mensch tun (einmalig, mit Passwort). Direkt auf der VM:

mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo '<INHALT DER .pub-DATEI>' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys

2.3 SSH-Konfiguration (auf dem eigenen Rechner)

Host testvm
    HostName 192.168.40.48
    User richard
    IdentityFile ~/.ssh/testvm_<projekt>
    IdentitiesOnly yes
    ServerAliveInterval 30
    ServerAliveCountMax 4

⚠️ Kein ControlMaster/ControlPath eintragen, wenn der Client unter Windows läuft — Windows-OpenSSH unterstützt Verbindungs-Multiplexing nicht und scheitert mit „Failed to connect to new control master". Stattdessen mehrere Prüfschritte pro Aufruf bündeln.

Test: ssh testvm "hostname"


3. Was installiert ist

Werkzeug Version Anmerkung
.NET SDK 10.0.111 (Runtime 10.0.11) SDK, nicht nur Runtime — auf der VM kann gebaut werden
MariaDB 11.8.6 Dienst mariadb, lauscht auf localhost:3306
Git 2.53.0
Xvfb vorhanden Virtueller Framebuffer für GUI-Tests ohne Bildschirm (siehe 4.7)
xdotool vorhanden Klicks und Tastatureingaben skripten
ImageMagick vorhanden import für Bildschirmaufnahmen, convert zum Zuschneiden
JetBrains Rider vorhanden
Docker nicht installiert
Node.js nicht installiert

Nicht vorhandene Werkzeuge dürfen installiert werden — aber bitte in der Belegungsliste (Abschnitt 6) vermerken, damit andere wissen, was sich geändert hat.


4. Konventionen für mehrere Projekte

Die Maschine wird von mehreren Projekten geteilt. Diese Regeln verhindern, dass sich Tests gegenseitig zerstören:

4.1 Datenbanken — je Projekt eine eigene

Niemals eine fremde Datenbank mitbenutzen und niemals eine Produktivdatenbank verbinden.

# Passwort erzeugen und ablegen (nur für den Besitzer lesbar)
PW=$(openssl rand -base64 18 | tr -d "/+=" | head -c 20)
echo "$PW" > ~/.<projekt>_test_dbpw && chmod 600 ~/.<projekt>_test_dbpw

sudo mariadb -e "CREATE DATABASE IF NOT EXISTS <projekt>_test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
                 CREATE USER IF NOT EXISTS '<projekt>_test'@'localhost' IDENTIFIED BY '$PW';
                 GRANT ALL PRIVILEGES ON <projekt>_test.* TO '<projekt>_test'@'localhost';
                 FLUSH PRIVILEGES;"
Was Schema Beispiel
Datenbank <projekt>_test polytrader_test
Benutzer <projekt>_test@localhost polytrader_test
Passwortdatei ~/.<projekt>_test_dbpw (Rechte 600)

Die Rechte enden an der eigenen Datenbank — GRANT ALL ON <projekt>_test.*, nie global.

4.2 Verzeichnisse

Zweck Ort
Quellcode ~/RiderProjects/<projekt>
Publish/Testlauf im Benutzerkontext ~/<projekt>-test
Installation als Dienst /opt/<projekt>

4.3 systemd-Dienste

Unit-Name = Projektname: <projekt>.service. Eigenes Dienstkonto je Projekt:

sudo useradd --system --home-dir /opt/<projekt> --shell /usr/sbin/nologin <projekt>

Nach dem Test abschalten (Abschnitt 7) — sonst laufen irgendwann fünf Dienste, die niemand mehr zuordnen kann, und der nächste Test misst gegen fremde Last.

4.4 Ports

Vor dem Belegen prüfen: ss -tlnp. Belegte Ports stehen in Abschnitt 6. Wer einen Port dauerhaft belegt, trägt ihn dort ein.

4.5 Erhöhte Rechte

sudo verlangt normalerweise ein Passwort. Für Testläufe kann es befristet freigeschaltet werden (ein Mensch, einmalig):

echo "richard ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/99-testing && sudo chmod 440 /etc/sudoers.d/99-testing

Nach Abschluss wieder entfernen:

sudo rm /etc/sudoers.d/99-testing

Das hebt den Schutz für das Konto vollständig auf — vertretbar auf einer Test-VM hinter VPN, aber nicht dauerhaft und niemals auf einer Produktivmaschine.

4.6 GUI-Anwendungen ohne Bildschirm testen

Braucht eine Anwendung X11, scheitert sie über SSH mit XOpenDisplay failed. Für einen einzelnen Durchlauf genügt:

xvfb-run -a ./MeineAnwendung --irgendein-schalter

4.7 Oberflächen selbst begutachten — ohne Bildschirm, ohne fremde Hilfe

Ein Agent kann die Oberfläche eigenständig prüfen. Kein Mensch muss am Bildschirm sitzen und Bildschirmfotos schicken. Das Verfahren hat sich am 26.08.2026 bewährt und sieben Befunde zutage gefördert, darunter einen, der sämtliche Tabellen der Anwendung unsichtbar machte.

Drei Werkzeuge, alle installiert: Xvfb (virtuelles Display), xdotool (Klicken und Tippen), ImageMagick (import für Aufnahmen, convert zum Zuschneiden).

Anders als xvfb-run wird das Display hier dauerhaft gestartet, damit sich zwischen den Aufnahmen navigieren lässt:

#!/bin/bash
cd ~/<projekt>-test
export DISPLAY=:99

pkill -f "Xvfb :99" 2>/dev/null; sleep 1
Xvfb :99 -screen 0 1600x1000x24 >/dev/null 2>&1 &
sleep 3

nohup ./MeineAnwendung > /tmp/gui.log 2>&1 &
APP=$!
sleep 25                      # Startzeit großzügig bemessen

# Fenster-ID ermitteln (bestaetigt, dass die Oberflaeche ueberhaupt erscheint)
xdotool search --name "^MeinFenstertitel$" | head -1

# navigieren und aufnehmen
shoot() { sleep 5; import -window root /tmp/v_$1.png; }
shoot 1_start
xdotool mousemove 127 205 click 1; shoot 2_zweite_ansicht
xdotool mousemove 127 237 click 1; shoot 3_dritte_ansicht

kill $APP 2>/dev/null; sleep 2; pkill -f "Xvfb :99" 2>/dev/null

Danach die Bilder abholen und ansehen:

scp testvm:'/tmp/v_*.png' .

Was sich dabei bewährt hat:

  • Großzügige Wartezeiten. 25 Sekunden nach dem Start, 5 Sekunden nach jedem Klick. Wird zu früh aufgenommen, entsteht ein halb gezeichnetes Fenster, und man sucht Fehler, die keine sind.
  • Klickpunkte aus dem ersten Bild ablesen. Erst eine Aufnahme machen, dort die Koordinaten der Menüpunkte bestimmen, dann das Skript damit bestücken.
  • Details vergrößern statt raten. Bei einem Verdacht den Ausschnitt herausschneiden:
    convert v_1_start.png -crop 560x130+265+540 +repage -resize 200% /tmp/detail.png
    
  • Kontraste nachmessen statt schätzen. Ob Text lesbar ist, lässt sich ausrechnen — Pixelfarben auslesen und das WCAG-Verhältnis bestimmen (4,5:1 für normalen Text). So wird aus „wirkt blass" ein belegter Befund.
  • Nur eine Instanz gleichzeitig. Läuft der systemd-Dienst noch, schreiben zwei Prozesse in dieselbe Datenbank und es entstehen Fehler, die nichts mit der Oberfläche zu tun haben. Vorher sudo systemctl stop <projekt>.
  • Auf Zeichen achten, die falsch aussehen. Fehlt eine Icon-Schriftart, ersetzt Fontconfig sie stillschweigend durch etwas anderes — ein Kalendersymbol wird dann zu einer sinnlosen Zahl. Das fällt nur im Bild auf, nie im Log.

Für einen Test mit echtem Bildschirm kann trotzdem jemand am Desktop der VM sitzen (oder RDP nutzen, Port 3389 ist offen) — nötig ist es für die Sichtprüfung nicht.


5. Was hier nicht passieren darf

  1. Keine Produktivdatenbank verbinden. Hintergrunddienste schreiben oft ungefragt — bei PolyTrader etwa synchronisiert der MarketSyncService selbständig Marktdaten.
  2. Keine echten Handels-/Zugangsdaten hinterlegen. Keine privaten Schlüssel, keine Live-API-Zugänge, keine Lizenzschlüssel für Produktivsysteme.
  3. Keine fremden Projektverzeichnisse oder Datenbanken anfassen.
  4. Nichts Dauerhaftes hinterlassen, was nicht in Abschnitt 6 steht.

6. Belegung (bei Änderungen fortschreiben)

Datenbanken

Datenbank Benutzer Projekt seit
polytrader_test polytrader_test@localhost PolyTrader 26.08.2026

Dienste

Unit Konto Verzeichnis Projekt seit
polytrader.service polytrader /opt/polytrader PolyTrader 26.08.2026

Ports (Stand 26.08.2026)

Port Belegt durch
22 SSH
3306 MariaDB (nur localhost)
3389 RDP
5000 vorhandener Dienst (nur IPv6-localhost)
631 CUPS

Nachträglich installiert: MariaDB 11.8.6, Xvfb, xdotool, ImageMagick, x11-utils (alle am 26.08.2026 für PolyTrader).


7. Aufräumen nach dem Test

# Dienst abschalten und entfernen
sudo systemctl disable --now <projekt>
sudo rm -f /etc/systemd/system/<projekt>.service /etc/logrotate.d/<projekt>
sudo systemctl daemon-reload

# Dateien
sudo rm -rf /opt/<projekt> ~/<projekt>-test
sudo userdel <projekt>

# Datenbank (nur wenn nicht mehr gebraucht)
sudo mariadb -e "DROP DATABASE <projekt>_test; DROP USER '<projekt>_test'@'localhost';"
rm -f ~/.<projekt>_test_dbpw

# sudo-Freigabe zurücknehmen
sudo rm -f /etc/sudoers.d/99-testing

Danach Abschnitt 6 nachziehen.


8. Bekannte Einschränkungen

  • Claude Code lässt sich auf dieser VM nicht betreiben. Es blockiert die Maschine bis zum Neustart; mehrere Reparaturversuche waren erfolglos, es wird auf ein Update gewartet. Agenten arbeiten deshalb über SSH von außen. (Speichermangel ist nicht die Ursache — die Maschine hat 31 GB, davon 25 GB frei.)
  • Verbindungs-Multiplexing funktioniert nicht mit Windows-OpenSSH (siehe 2.3).
  • Die Systemzeitzone ist Testgegenstand. Für realistische Servertests wird sie zeitweise auf UTC gestellt (sudo timedatectl set-timezone UTC). Wer sie ändert, stellt sie danach zurück — Standard hier ist Europe/Berlin.