Controllo di qualità - Bibisect
TDF LibreOffice Document Liberation Project Blog comunitari Weblate Nextcloud Redmine Ask LibreOffice Donazione
Introduzione
Bibisect significa "binary bisect". È una procedura che facilita l'identificazione dei commit che hanno causato una regressione. Le regressioni sono gli artefatti più fastidiosi che purtroppo fanno parte dello sviluppo e del controllo di qualità. Vogliamo gestire le regressioni rapidamente prima che il tempo passi e diventi sempre più difficile gestirne il triage e la risoluzione.
Come funziona il Bibisect?
Ogni pacchetto di bibisect consiste in un repository di git popolato con centinaia o migliaia di compilazioni di LibreOffice. Queste sono aggiunte al repository in ordine cronologico, le compilazioni forniscono un modo veloce e semplice per testare un bug su diverse versioni senza dover compilare ogni volta LibreOffice che si passa a una versione differente.
È possibile fare uso degli strumenti incorporati in git per la ricerca dei binari nei commit (es. git bisect), così come beneficiare delle funzioni di compressione de-duplicazione incluse in git. Per esempio, in una serie di compilazioni, ciascuna delle quali può occupare anche 500MB di spazio su disco, attraverso la de-duplicazione si possono potenzialmente usare solo 25MB per compilazione aggiuntiva.
Guardate Effective Bisection and Bibisection (la presentazione di Matthew Francis alla LibOCon 2015 su YouTube) per un'introduzione e dettagli pratici.
Dettagli
Un bibisect eseguito bene lascierà agli sviluppatori solo pochi commit tra i quali cercare il 'colpevole' che si suppone abbia introdotto una regressione. Il controllo di qualità può eseguire il passaggio aggiuntivo del bisect completo (determinando l'esatto commit) oppure lasciarlo agli sviluppatori. Dopo il bibisect del bug, spesso è facile trovare il commit che ha causato il problema.
Con approssimativamente 10 giga, avrete centinaia di compilazioni sulle quali lavorare. Un bibisect può richiedere meno di 15.
Attualmente, il bibisect è possibile su:
Come potete vedere dai Commits in range e dal Number of builds nella tabella, a seconda di un determinato repository di bibisect, l'intervallo può essere in media di 80 commit per il vecchio repository "43max" (raggiungendo centinaia di commit dei sorgenti per alcune compilazioni) fino a 1 o 2 commit per i repository più recenti. (Ci sono anche dei repository di bibisect molto 'grezzi' che utilizzano le versioni di rilascio + le beta + le compilazioni Release Canditate, questi possono avere intervalli che coprono diverse centinaia di commit).
Se viene trovato il commit nella compilazione o un intervallo, il bug viene segnalato con la parola chiave "bibisected" e se viene trovato il commit del sorgente, il bug è segnato anche come "bisected".
Istruzioni generali
Per i principianti potrebbe essere una buona idea iniziare tracciando i passaggi di un bibisect che è già stato completato positivamente. Per questo scopo esiste un tutorial sul bibisect.
Prima di eseguire per la prima volta il Bibisect dovrete:
- Impostare l'ambiente (possibilmente comprensivo del software aggiuntivo)
- Scaricare il repository di bibisect di interesse
Una volta impostato, per ciascuno bug:
- Eseguire il bibisect del bug
- Commentare la segnalazione del bug riportando i risultati
- Sostituire la parola chiave 'bibisectRequest' con 'bibisected'
- Se l'esatto commit che causa la regressione è stato identificato, aggiungere anche della parola chiave 'bisected', lo sviluppatore in CC e commentare con 'Adding Cc: to <nome dello sviluppatore>'
Fate attenzione che dovreste aggiungere in CC solo l'autore del commit originale ("author" su git.libreoffice.org o "owner" su gerrit), non gli altri revisori. Se uno sviluppatore si è ritirato dal progetto (controllate la data del suo ultimo commit), non ha senso aggiungere qualcuno in CC. Piuttosto, in questo caso, dovreste innalzare la priorità della segnalazione di bug.
Intervalli di Commit
Alcuni repository di bibisect hanno intervalli di commit di sorgenti raggruppati in un singolo pezzo. Se dopo avere completato il bibisect vi si presenta uno solo di questi pezzi di commit, potete ottenere l'intervallo copiando prima l'hash (nota: non l'hash del sorgente) e usandolo all'interno di un log di git con un comando come:
git log c3f9dc54188b316a61dd871b63734d49b05f5d7f
Ora potete copiare gli hash del sorgente del primo commit visualizzato e di quelli precedenti e separarli con ..
per costruire una ricerca dell'intervallo in questo modo:
https://git.libreoffice.org/core/log/7c4d3ea6ba4d42b4dda5148a00c8c411b5d7703d..5b195fbcf7a441aeb193f6abd08b877e580938e0
Questo vi permetterà di scremare i messaggi di commit alla ricerca degli oggetti appropriati. Per un esame più approfondito, vedete la sezione sul lavoro di investigazione.
Ricerca della prima versione interessata
Se avete una copia locale del repository core, potete aggiornare il campo Versione nella segnalazione del bug grazie ad alcuni comandi di git:
1. Per prima cosa, assicuratevi di avere tutti i tag:
git fetch --tag
2. Poi, usate `name-rev` per trovare il contesto (più precisamente, di quante revisioni precede il primissimo tag che contiene il commit):
git name-rev <commit>
3. Se questo non restituisce un tag utile a trovare una versione di LibreOffice, potete elencare tutti i tag che contengono il commit ed hanno "libreoffice" nel nome con:
git tag --contains <commit> | grep libreoffice
Limitazioni
L'esecuzione di un bibisect è possibile solo se è disponibile un repository per il sistema operativo correntemente usato, che copra l'intervallo corretto di commit di LibreOffice. La copertura è molto buona in GNU/Linux e sta migliorando su Windows e macOS.
Alcune regressioni sono difficili da riprodurre e possono richiedere più esecuzioni del test perché il bug si presenti. Come potete immaginare, provare a fare il bibisect di queste regressioni è molto difficile e richiede l'esecuzione ripetuta molte volte dei test dopo ogni uscita di una nuova versione di LibreOffice per fornire alcune certezze/statistiche che il bug è effettivamente presente o meno nella versione in esame.
Attualmente non c'è supporto per il bibisect di
- LibreOffice per Android
- BSD (anche se i pacchetti di bibisect di GNU/Linux potrebbero funzionare, con piccoli aggiustamenti)
- LibreOffice Online
- LibreOffice Vanilla per Mac (nel Mac App Store)
Versioni
Le versioni solo elencate nella pagina di ogni sistema operativo. Vedete i Dettagli di cui sopra.
Non adatti al Bibisect
Per alcuni bug non è fattibile il bibisect. Questi comprendono:
- Bug che non si presentano su di una piattaforma supportata (vedete #Limitazioni)
- Bug precedono le compilazioni del bibisect (Si sta lavorando per estendere l'intervallo coperto)
- Bug che dipendono da opzioni di compilazione non abilitate nelle compilazioni di TDF (es. -kde)
Se un con la parola chiave bibisectRequest si rivela essere tra quelli su cui non è possibile eseguire il bibisect, lasciate un commento al bug spiegando perchè non siete stati in grado di usare il bibisect per rintracciare l'introduzione del problema e sostituire la parola chiave bibisectRequest con notBibisectable. Se un bug è precedente alle compilazione del bibisect, sostituite la parola chiave bibisectRequest con preBibisect.
Trovare i bug
Trovare i bug che richiedono il bibisect
I seguenti bug con la parola chiave bibisectRequest sono in attesa del bibisect:
Trovare i bug sui quali è già stato eseguito il bibisect
Per i collegamenti alle ricerche su bugzilla, vedete qui.
Con le informazioni di cui sopra aggiunte al bug, uno sviluppatore sa che quella regressione è stata introdotta nel master tra i commit fb754a0df859e30255c25af8fa19bfaa75f257e7 (buono) e 2d19e9bb07ccff3134f855812dddfda5c07b1fe4 (errato).
git log fb754a0df859e30255c25af8fa19bfaa75f257e7..2d19e9bb07ccff3134f855812dddfda5c07b1fe4
Il comando soprastante eseguito nel repository dei sorgenti mostrerà i 128 commit compreso quello che ha introdotto il bug, rendendo molto più semplice per lo sviluppatore stringere il cerchio attorno al colpevole. Per maggiori dettagli, vedete:
- bisect all'interno del libro della comunità di git
- questa discussione nella mailing list degli sviluppatori
Situazioni particolari
Bibisect di bug legati a una specifica lingua
I repositori per il bibisect forniti da TDF non comprendono alcun pacchetto delle lingue.
Per eseguire il bibisect di bug che funzionano correttamente con l'interfaccia utente in inglese, ma in modo errato con lingue differenti (come CJK): dovreste copiare e incollare i seguenti file, da una compilazione di rilascio che contiene la vostra lingua, nella stessa posizione dei repository del bibisect:
- program/resource/<identificatore_della_vostra_lingua>
- share/registry/Langpack-<identificatore_della_vostra_lingua>.xcd
- share/registry/res/fcfg_langpack_<identificatore_della_vostra_lingua>.xcd
- share/registry/res/registry_<identificatore_della_vostra_lingua>.xcd
Le risorse suggerite per le lingue che dovreste copiare sono uniche per la stessa versione major. Ad esempio, per il repository bibisect-linux-64-6.0, potete copiarle dalla versione 6.0.1.1.
Esecuzione con un profilo utente separato
Per creare una cartella per il profilo separato in /tmp/ (che sarà automaticamente rimossa al successivo riavvio della macchina):
./opt/program/soffice -env:UserInstallation=file:///tmp/soffice-bisect
Se volete iniziare in maniera pulita per ogni iterazione del bisect, potete aggiungere l'hash del commit di git al nome della cartella. Per esempio:
./opt/program/soffice \
-env:UserInstallation=file:///tmp/soffice-bisect-$(git rev-parse HEAD)
Trovare una soluzione
Alle volte un bug è un danno collaterale di un altro bug (probabilmente minore), in modo non evidente. In questi casi l'altro bug dovrebbe essere risolto nel master, ma non ne è stato fatto il backport nella branch della versione. Per identificare il commit che risolve il problema potete usare:
git bisect start --term-new=fixed --term-old=unfixed
git bisect fixed master
git bisect unfixed <some-old-sha> # you can use "git log --reverse" to detect the first revision in the bibisected package
Mentre eseguite il test, dite
git bisect fixed
o
git bisect unfixed
a seconda del caso.
Se la soluzione è piccola e abbastanza importante, è probabile che ne possa essere fatto il backport nella branch della versione.
Verificate uno specifico commit in base all'hash del sorgente
Alle volte sapete già che uno specifico commit di sorgente contiene o meno il bug al quale state dando la caccia.
Copiate l'hash del sorgente dalla cronologia di git di LibreOffice e usatelo con grep nel log del repository di bibisect in questo modo:
git log --all --grep='29a9f433c268414747d8ec7343fc2b5987971738'
Copiate L'hash del commit del repository di bibisect ed eseguite un suo checkout per verificare la vostra supposizione:
git checkout 38758b70f5278d4d8292a2e857e80a9a1130f38e
Potete usare l'hash del commit del repository quanto determinate l'intervallo errati-buoni su cui eseguire il bisect:
git bisect start 38758b70f5278d4d8292a2e857e80a9a1130f38e oldest
Esecuzione dell'indagine all'interno di un intervallo di commit
Nel caso in cui il risultato del bibisect sia un intervallo di commit ed abbiate problemi a localizzare il commit colpevole, potreste semplificavi la vita effettuando una ricerca con una parola chiave.
L'esempio di un caso, nel quale si sa che il problema è nella visualizzazione del Navigatore in Calc:
git log --stat --pretty=short --graph 169bd7718264b0e312052757f9bbd2321e1399c2...ff8b873936aa72b17309da4bfc2775573a5b1f55 | grep -B 10 -A 10 --color=always "sc/source/ui/navipi" | less -R
Regolate i parametri -B e -A di grep per controllare quante linee prima e dopo quella trovata volete visualizzare. Quando invita a tramite la pipe, -R conserva la colorazione dei risultati della ricerca.
L'inferno dei salti del Bisect
Alle volte ci si imbatte in una situazione deprimente, nella quale è necessario saltare e ripetere il bisect ripetutamente a causa di diverse ragioni. Esistono dei modi per uscire da queste situazioni intricate ed esasperanti e qui ne illustreremo una.
Bug di esempio: tdf#123095
Il bug è comparso nell'intervallo 4.0-4.1.
Ci sono molti commit, nei quali il filtro automatico non viene proprio visualizzato, perciò è necessario saltarli.
Potete usare la visualizzazione del bisect di git per mostrare i restanti commit sospetti:
git bisect visualize --oneline > /some/path/bisect-viz-123095.txt
I primi risultati errati sono in cima, mentre quelli che avete saltato sono in fondo. Il commit sotto al fondo è l'ultimo corretto conosciuto.
I primi risultati comprendono
b842ac1 source-hash-7b4d76772ef76a8de852ed647ed0cad368f70189 40ef04e source-hash-dc173b7f2a550185404aacbc6da744cb6d1880fc 8e697de source-hash-eb96e4325278f31b9e6fbc1d5c6a01543204ded6
Effettuando il checkout di git su b842ac1, ed il suo test, continuando con il successivo ecc., si comprende che il terzo dalla cima è già un commit che è possibile saltare.
È possibile eseguire una ricerca di un intervallo con gli hash dei sorgenti, del tipo bottomcommit..firstbadcommit.
Cercando "filter" tra i risultati visualizzati arriverete ad un commit sospetto relativo al menu a comparsa per l'ordinamento degli elementi del filtro automatico.
Se soffice fallisce restituendo un codice diverso da zero (questo probabilmente comporta un crash) una soluzione come in Curiosità per l'efficienza offre uno script per alleviare la frustrazione di ripetute prove saltate e fallite.
Specialmente nei repository più vecchi, alle volte può capiare di ritrovarsi con un elenco di dozzine di potenziali commit errati. I commit potrebbero non essere in ordine, perciò non è semplice costruire un intervallo di ricerca. È possibile salvare l'elenco dei commit in un file di testo ed eseguire git show
per ognuno di essi, indirizzando l'output ad un file:
while IFS="" read -r p || [ -n "$p" ]
do
git show --no-patch "$p" >> /path/to/bisectlog.txt
done < /path/to/bisect_range.txt
Il vecchio repository comprende il messaggio originale di commit, perciò questo file di log risulterà immediatamente utile. Se il repository binario non comprende il messaggio originale, dovrete prima effettuare un passaggio con git show --oneline --no-patch
, riordinare l'elenco delle hash dei sorgenti e poi effettuare un ultimo giro nel repository del core di LibreOffice.
Trovare i commit sorgenti dal bibisect
Se il bibisect è stato eseguito, ma non propriamente nel modo corretto o in un repository noto per avere un ampio intervallo di commit, potete controllare l'intervallo trovando il commit di una compilazione precedente a quella trovata e quindi trovare l'intervallo dei sorgenti.
$ git log -1 1f14665c5624bc7a502738aa8f4f2bd70a211e72^
$ git log --oneline b6c016da23d309b4ac7d154bc33a22397974ed73..d85fd8a85501547d5bb87822d2589a07aed7f2d6
Risoluzione dei problemi
Siete pregati di aggiungere i problemi che avete riscontrati e come li avete risolti. Questa sezione riguarda problemi che affliggono più di un sistema operativo. Per problemi specifici a un sistema operativo, vedete le singole pagine del wiki per ogni OS.
Impossibilità di estrarre dei file
Se non riuscite a estrarre dei file (dovreste ottenere un messaggio di errore). Provate a rinominare il file da *.tar.lzma a *.tar.xz.
La versione installata di LibreOffice si modifica inaspettatamente
Problema / Messaggi:
error: Your local changes to the following files would be overwritten by checkout: opt/program/pythonloader.pyc opt/program/uno.pyc opt/program/unohelper.pyc Please, commit your changes or stash them before you can switch branches. Aborting
Soluzioni:
git checkout .
Il comando soprastante risolverà il problema. Dopodiché potrete iniziare l'esecuzione del prossimo test, come di consueto con
git bisect good # or git bisect bad
Se ciò non risolve il problema, potete provare i seguenti comandi:
git clean -fd
git reset --hard
L'ultima soluzione è quella di cancellare tutto tranne la cartella nascosta .git/, ed eseguire
git checkout oldest
Impossibilità di avviare soffice
Problema 1: Provando a eseguire soffice all'interno del bibisect ricevete il messaggio di errore "unexpected operator terminate called after throwing an instance of 'com::sun::star::uno::DeploymentException'"
Soluzione: Reimpostate il profilo di LibreOffice che si trova in ~/.config/libreoffice. Assicuratevi di fare un backup della cartella se avete delle impostazioni che volete conservare per usarle con la vostra versione stabile di LibreOffice. Dopo aver terminato il bibisect potete provare a tornare al profilo salvato copiandolo nella posizione originaria (es. cancellate la cartella del nuovo profilo e sostituitela con quella del backup)
Problema 2: Provando a eseguire soffice all'interno del bibisect ottenete frequenti errori del tipo "Application Error" e saltarli usando 'git bisect skip' è noioso.
Soluzione: Eseguire uno script one-line per saltare il commit in caso di errori. Lo script si fermerà quando soffice sarà eseguito correttamente e quindi potrete procedere con 'git bisect good' o 'git bisect bad'. Se l'errore si ripete, lo script può essere eseguito nuovamente.
while (git clean -f -X && git bisect skip && ! instdir/program/soffice); do : ; done
Una versione per PowerShell su Windows, che inoltre mostra come passare degli argomenti a soffice:
Do {
git clean -f -X && git bisect skip
$proc = Start-Process -PassThru -FilePath .\instdir\program\soffice -ArgumentList "--norestore C:\path\to\file.odt"
Wait-Process -InputObject $proc
} until ($proc.ExitCode -eq 0)
Da notare che se bug causa dei crash, è necessario uscire del ciclo saltato chiudendo normalmente LibreOffice prima di eseguire il test.
Esecuzione del bisect di bug relativi a lingue RTL
Nel caso dobbiate eseguire il bisect di un bug relativo a una lingua RTL (Right-To-Left - da destra verso sinistra), importate questa variabile prima di chiamare LibreOffice:
SAL_RTL_ENABLED=1
Esecuzione del bisect di bug relativi al Ripristino di File
Nel caso dobbiate eseguire il bisect di bug relativi al Ripristino di File (es. tdf#129210), commentate la linea OOO_DISABLE_RECOVERY=1 nel file instdir/program/ooenv
Potreste anche usare il parametro da linea di comando:
soffice --norestore file-that-recovers.ext
Esecuzione del bisect di file che si bloccano / bug che saturano la CPU o la memoria
Nel caso dobbiate eseguire il bisect di bug che causano blocchi o esauriscono la memoria, potete limitare la memoria, l'uso della CPU o il tempo di esecuzione.
In Linux, potete usare l'utilità timeout. Per evitare confusione con il comando incorporato "timeout", qui viene rinominato in "tmt".
Per esempio, se il commit 'buono' di LibreOffice apre un file di 1 GB di memoria, potreste impostare il limite di memoria per soffice a 1.500.000 kilobyte in modo di evitare che un commit 'errato' causi il blocco del computer.
tmt -m 1500000 instdir/program/soffice
Oppure, per limitare il tempo di utilizzo di CPU+SYS (dove il tempo normale è rilevabile da un'esecuzione andata a buon fine):
tmt -t 20 instdir/program/soffice
Un'opzione più avanzata è quella di usare l'utilità benchexec. È necessario che l'utente sia aggiunto al gruppo appropriato (benchexec). Runexec può essere usato per eseguire un singolo comando misurando il suo consumo di risorse, in modo simile allo strumento "time" ma con misurazioni dei tempi più affidabili e con la rilevazione dell'uso della memoria.
In Windows, potete usare l'utilità process-governor.
Ulteriori informazioni
Automazione
Vedete l'articolo separato relativo all'automazione del bisecting.
Note
Per dettagli su come vengono generati gli archivi del bibisect: