Passa al contenuto

openQA per sviluppatori e responsabili

KDE Linux usa openQA per eseguire test automatici su ogni immagine di sistema prima della sua pubblicazione. openQA avvia ciascuna immagine in una macchina virtuale e controlla che possa essere installata, aggiornata e utilizzata correttamente.

openQA possiede una sua terminologia specifica (che verrà mantenuta): un job è una esecuzione di una suite di test su un'immagine, mentre un worker è la macchina o il contenitore che esegue il job. La documentazione openQA spiega tutti i concetti, inclusi moduli dei test, gruppi di job, risorse e interfaccia web.

Come funzionano i test

Il worker del test viene eseguito insieme alla pipeline CI, in modo che possa usare le immagini e i dischi virtuali prodotti dalla generazione senza caricare quei file di grandi dimensioni altrove. I test sono inviati alla macchina virtuale tramite un'estensione del sistema e comunicano con essa su SSH.

I test desktop usano l'API di accessibilità attraverso selenium-webdriver-at-spi, che permette loro di interagire con le applicazioni e verificare il loro stato senza dover fare affidamento esclusivamente sulla corrispondenza delle schermate (screenshot). La suite controlla anche gli errori dei servizi di sistema, i processi desktop con crash, i problemi di rete e le regressioni nei comandi di KDE Linux.

Pipeline CI e flusso di lavoro dei responsabili

Nel ramo predefinito protetto del deposito upstream di KDE Linux, la pipeline funziona come segue:

  1. Il job di creazione dell'immagine genera, firma e crea le fasi dell'immagine e del suo canale sysupdate su storage.kde.org.
  2. Il job trigger-openqa avvia la pipeline in os-autoinst-distri-kdelinux, passandogli l'URL dell'immagine modificata e l'URL del canale sysupdate.
  3. La pipeline downstream esegue il normale flusso install-and-sanity e aggiorna il flusso.
  4. Il job upstream publish viene eseguito solo dopo che la pipeline openQA è stata completata correttamente. Promuove l'immagine già modificata per l'utilizzo pubblico.

Questo fa sì che un errore di openQA diventi un ostacolo alla pubblicazione dell'immagine. Inizia aprendo la pipeline downstream dal job trigger-openqa, quindi apri il job openQA che ha restituito l'errore dal relativo registro CI. La pagina del job mostra i moduli di test in ordine e ti permette di identificare se l'errore è nell'installazione, nei test di integrità del sistema installato o nel percorso di aggiornamento.

Scaricare un'immagine modificata

Il link fornito dopo il messaggio di log “In case of failure, you can inspect and download the .iso image and sysupdate tree at…” apre un browser di archiviazione per la build in fase di test. Scarica il file .iso da lì per avviarlo manualmente o forniscilo a uno stack openQA locale. L'albero sysupdate contiene gli artefatti di aggiornamento modificati utilizzati dal test di aggiornamento.

Investigare un job con errore

Apri il job nell'interfaccia web di openQA e seleziona prima il modulo che ha generato l'errore. Il collegamento all'interfaccia web comparirà dopo il messaggio di registro del “job del test ora in esecuzione.”. I suoi dettagli includono i risultati del modulo, le schermate o i video (dove applicabile) e l'output diagnostico. Nella scheda Logs & Assets, scarica o visualizza autoinst-log.txt per il worker openQA e il registro test-engine. Questo è il registro principale per lo stesso job.

Per i test che eseguono comandi sul sistema in esame, KDE Linux li esegue in servizi systemd temporanei e registra il registro (journal) del servizio come output diagnostico nel risultato del test. Esamina il file autoinst-log.txt per visualizzare l'output del comando e il registro. Puoi anche scaricare il file *kde-linux-collected-logs.tar.zst per i registri acquisiti dallo strumento collect-logs.

Eseguire i test localmente

Prima di inviare una modifica, puoi usare openQA per un'immagine generata localmente. Ciò è richiesto quando lavori da un fork esterno a kde-linux/kde-linux - la sua pipeline CI genera un'immagine di test ma non attiva la pipeline openQA. È anche utile durante lo sviluppo di test per le tue modifiche personali.

Il deposito dei test openQA di KDE Linux include uno stack locale che contiene sia un'interfaccia web openQA, sia un worker. Richiede Podman e podman-compose, inclusi in KDE Linux.

Clona il deposito dei test, quindi posiziona l'immagine .iso di KDE Linux che vuoi testare nella sua cartella di root. Se non è presente alcuna immagine, l'esecutore dei test scaricherà l'ultima immagine disponibile pubblicamente.

Avvia lo stack locale.

./mock.sh up

Una volta pronta, apri http://localhost:1080 per ispezionare l'interfaccia web di openQA. I job non vengono inviati automaticamente, pertanto apri una shell nel container e invia il normale flusso install e sanity-test.

podman exec -it openqa-single-instance bash
./qa flow

Per eseguire invece un flusso di aggiornamento, aggiungi --upgrade:

./qa flow --upgrade

Per eseguire il flusso disk-encryption install-test, aggiungi --encrypt:

./qa flow --encrypt

Puoi anche combinare le opzioni --upgrade e --encrypt:

./qa flow --upgrade --encrypt

Il job sanity-test ha bisogno che sia eseguito prima il job install-system perché utilizza il disco virtuale creato dall'installazione. Per concentrarti su un test specifico, regola i job inviati in lib/worker/job_flow.py o eseguire un job individuale con ./qa job tenendo presente quella dipendenza. Esegui ./qa job --help per vedere le opzioni richieste.

Per esempio, per eseguire un job install-system in cui hai scaricato un .iso nella cartella del deposito:

./qa job \
    --live ./kde-linux_<build-id>.iso \
    --hdd kde-linux_<build-id>.qcow2 \
    --sysext ./openqa-sysext.img \
    --build <build-id> \
    --name install-system \
    --flavor live

Quando hai terminato, ferma lo stack e rimuovi i suoi volumi locali.

./mock.sh down -v

Scrivere un test

Le definizioni dei test e il codice di test si trovano in os-autoinst-distri-kdelinux. Aggiungi il test al flusso appropriato in main.pm: il flusso live-install, il flusso installed-system sanity o quello upgrade. I test sono in genere composti da un piccolo wrapper openQA in tests/ e da un test Python che viene eseguito sul sistema da testare da extensions/openqa/usr/lib/kde-linux-openqa/tests/.

Scegli il tipo di test in base a quello che stai verificando:

  • Usa un unittest Python standard per gli strumenti a riga di comando, i servizi, lo stato del filesystem o altri comportamenti non grafici.
  • Usa Selenium tramite selenium-webdriver-at-spi quando il comportamento richiede l'interazione con un'applicazione grafica.

Test Python standard

Crea un unittest nella cartella di test dell'estensione di sistema menzionata in precedenza. Dovrebbe eseguire delle asserzioni sul sistema in fase di test e scrivere i risultati in un file XML JUnit, che verrà automaticamente raccolto come risorsa openQA e report di GitLab CI.

import unittest
from lib.sut import openqa_junit_xml

class ExampleTests(unittest.TestCase):
    def test_expected_behaviour(self):
        self.assertTrue(True)

if __name__ == "__main__":
    openqa_junit_xml.run(ExampleTests, "esempio")

Crea un wrapper corrispondente nella cartella tests/ che permetta a openQA di eseguire il test sull'host.

from testapi import *
from lib.test import cli_test

def run(self):
    cli_test.CliTest("esempio").run_python()

Infine, registra il wrapper nel flusso pertinente in main.pm. Il wrapper raccogli il risultato JUnit e l'output dei comandi in modo che gli errori vengano visualizzati nel job openQA job e negli artefatti CI.

Test grafici con Selenium

I test grafici sono anch'essi classi unittest Python, ma utilizzano il driver Appium/Selenium per trovare e interagire con gli elementi di interfaccia accessibili. L'esecutore Selenium abilita l'infrastruttura per l'accessibilità e avvia il driver al posto tuo.

Per esempio, un test grafico crea un driver per la sua applicazione, interagisce con gli elementi accessibili e poi chiude il driver:

import unittest
from appium import webdriver
from appium.options.common.base import AppiumOptions
from appium.webdriver.common.appiumby import AppiumBy
from lib.test import openqa_junit_xml

class ExampleTests(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        options = AppiumOptions()
        options.set_capability("app", "org.kde.example.desktop")
        cls.driver = webdriver.Remote("http://127.0.0.1:4723", options=options)

    @classmethod
    def tearDownClass(cls):
        cls.driver.quit()

    def test_expected_behaviour(self):
        self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "example-control").click()

if __name__ == "__main__":
    openqa_junit_xml.run(ExampleTests, "esempio")

Esegui il wrapper corrispondente con run_selenium() anziché run_python(). Passa l'utente di test installato per le applicazioni desktop:

from testapi import *
from lib.test import cli_test
from lib.common import user_manager

def run(self):
    cli_test.CliTest("esempio").run_selenium(user=user_manager.installed())

Analogamente ai test Python standard, aggiungi il suo wrapper a main.pm, eseguilo localmente mentre lo sviluppi e and includilo nel flusso del test che simula la funzionalità.

Per ulteriori informazioni su come scrivere test con Selenium, vedi le pagine Appium automation testing e GUI Testing with selenium-webdriver-at-spi (in inglese).

Ulteriori informazioni

Per una spiegazione più dettagliata del flusso dei test e la sua implementazione, vedi openQA Testing in KDE Linux. L'infrastruttura dei test è sviluppata nel deposito os-autoinst-distri-kdelinux.


Articolo scritto da sotto licenza CC-BY-4.0.