QA/Bibisect/Automation

    From The Document Foundation Wiki
    < QA‎ | Bibisect
    This page is a translated version of the page QA/Bibisect/Automation and the translation is 40% complete.
    Outdated translations are marked like this.
    Other languages:

    L'automazione può essere eseguita su diversi livelli. Alcune shell e plugin come Oh My Zsh hanno già alias per git. Oppure possiamo creare i nostri alias per l'efficienza. Oppure possiamo utilizzare bibisect completamente automatizzato.

    Curiosità per l'efficienza

    La natura ripetitiva del bibisecting diventa noiosa velocemente, quindi ogni trucco che potete usare per rendere il processo più veloce è prezioso. Un modo tipico è definire alias per comandi complessi nel file .bashrc.

    Il .bashrc di un bibisecter attivo potrebbe includere un blocco come questo:

    alias bad='git bisect bad && instdir/program/soffice'
    alias good='git bisect good && instdir/program/soffice'
    alias skip='git bisect skip && instdir/program/soffice'
    alias next='git log --reverse --pretty=%H master | grep -A 1 $(git rev-parse HEAD) | tail -n1 | xargs git checkout'
    alias prev='git checkout HEAD^1'
    alias gallery='rm instdir/program/gengal'
    alias pycache='find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf'
    alias source='if [[ $(git log -1) =~ sha:([[:alnum:]]+) ]]; then git --git-dir ~/libreoffice/.git log -1 ${BASH_REMATCH[1]}; fi'
    alias sof="\$( if [[ -d instdir ]] ; then echo instdir ; else if [[ -d opt ]] ; then echo opt ; fi ; fi )/program/soffice --norestore --nologo"

    Abbiamo comandi per passare al commit successivo o precedente, "pycache" per gestire un fastidio specifico di Windows e infine "source" per visualizzare rapidamente le informazioni sul commit di origine. Il comando denominato "source" presuppone che voi siate in un repository bibisect, prende l'hash di origine del commit attualmente estratto e lo invia a un comando git mirato a un clone completo del codice sorgente di LibreOffice. Per ottenere un'analisi dettagliata del comando, si eda il Bash Reference Manual. "sof" introduce un comando singolo per i repository più recenti con instdir e quelli precedenti con le directory opt.

    Gli esempi precedenti non sono esclusivi dei sistemi *nix, ma funzionano bene in un ambiente cygwin su Windows. Se volete aprire documenti dalla riga di comando di cygwin, racchiudete il normale percorso di Windows tra virgolette singole in questo modo: instdir/program/soffice 'c:\users\test\downloads\example.ods'

    Un altro approccio sarebbe quello di presumere che si faranno anche bibisect inversi, quindi usate "prima" e "dopo" invece di "buono" e "cattivo". Il comando soffice rimane separato e può essere sostituito con "sof" e combinato con "gen" o "skia". "skip" è utile quando LO non si avvia, ma può anche essere modificato temporaneamente quando non è possibile caricare un file specifico. "loexit" viene utilizzato con "time" per misurare il tempo di caricamento con uscita automatica.

    alias gbs='echo "git bisect start master oldest" && git bisect start master oldest'
    alias gbb='echo "git bisect before" && git bisect good'
    alias gba='echo "git bisect after" && git bisect bad'
    alias skip='while (git clean -f -X && git bisect skip && ! (SAL_USE_VCLPLUGIN=gen instdir/program/soffice)); do : ; done'
    alias gen='SAL_USE_VCLPLUGIN=gen'
    alias skia='SAL_ENABLESKIA=1 SAL_USE_VCLPLUGIN=gen'
    alias loexit='OOO_EXIT_POST_STARTUP=1'
    alias buildc='lynx https://git.libreoffice.org/core/+log/`instdir/program/soffice   --version |  awk '"'"'{print $(NF)}'"'"'`  '
    build() { lynx https://git.libreoffice.org/core/+log/"$1"; }
    log() { git log --all --grep="$1"; }

    Alias "buildc" apre la pagina web con il commit corrente, mostrando l'ora e l'autore. La funzione "build" apre master , mentre "build d376297c643785564e7bda1a74b573c35ade6cb8" controlla il commit specifico. La funzione "log 3678e0efcb8bedc58dd329a430da0ac3b1572df8" trova il commit bisect del commit di origine nel repository corrente.

    Ad esempio, con quei comandi è possibile modificare in bibisect in fileopen time, incluse le vecchie versioni, come:

    gbs && time loexit gen sof file.ext.

    Automazione con script

    È possibile automatizzare la bisecazione con l'aiuto di script. Il comando per eseguire bibisect è sempre lo stesso, avviamo bibisect e contrassegniamo il vecchio commit come buono e il nuovo come cattivo. Funziona per trovare una regressione e se dobbiamo trovare una soluzione, dobbiamo compensare in uno script. Il comando git bisect run viene eseguito con uno script. In un caso semplice, lo script viene eseguito dalla directory corrente e i file sono già presenti con nomi contigui. Ma lo script può essere più complesso, avere parametri ed essere predefinito per la cartella di download dei file di bug dell'utente in cui vengono utilizzati i nomi dei file originali. Ulteriori sono esempi. Lo script deve essere eseguibile.

    cd ~/linux-64-6.3 && git bisect start master oldest && git bisect run ~/lo-script.sh "param 1" param2 ...

    The automation also works with PowerShell scripts. The important thing with them is to always have #!/usr/bin/env pwsh as the first line of the script. Without the line the execution will fail in this context.

    In the examples below, the Bash version is followed by the PowerShell version.

    Checking file size after conversion

    Ecco an example con valori fissi, trovando se convert è corretto guardando la dimensione del PDF.

    #!/usr/bin/env bash
    # lo-pdf-size.sh  Called with "/path/to/file.ext"
    doc=$1
    ./instdir/program/soffice --headless --convert-to pdf --outdir "$(dirname "${doc}")" "$doc"
    file="${doc%.*}.pdf"
    minsize=40000
    size=$(wc -c <"$file")
    if (( size >= minsize )); then
        exit 0
    else
        exit 1
    fi

    #!/usr/bin/env pwsh
    # lo-pdf-size.ps1  Called with "c:/path/to/file.ext"
    param (
        [Parameter(Mandatory=$true)][string]$doc
    )
    $outputDir = Split-Path -Path $doc -Parent
    & "instdir/program/soffice" --headless --convert-to pdf --outdir $outputDir $doc
    $file = [System.IO.Path]::ChangeExtension($doc, ".pdf")
    $minsize = 40000
    $size = (Get-Item $file).Length
    if ($size -ge $minsize) {
        exit 0
    } else {
        exit 1
    }

    Crashes upon file opening

    The following script can be used to bisect crashes that happen when opening a file. To find a fix for a crash, use the optional second parameter, "fix".

    #!/usr/bin/env bash
    # lo-fileopen-crash.sh  Called with 1+1 parameters: "/path/to/file.ext" [fix]
    doc=$1 ; regfix=$2
    if [[ $regfix = "fix" ]]; then before=1; after=0; else before=0; after=1; fi
    OOO_EXIT_POST_STARTUP=1 SAL_USE_VCLPLUGIN=gen ./instdir/program/soffice --norestore "$doc"
    status=$? ; echo "$status"
    # Above status code 128 there are various fatal error signals and "Application Error" might have a negative status code
    if (( status > 128 || status < 0 )) ; then
        echo "crashed" ; exit $after
    # OOO_EXIT_POST_STARTUP=1 causes status code 42
    elif (( status == 42 )) ; then
        echo "opened successfully" ; exit $before
    else echo "other exit code"
    git reset --hard
    fi

    #!/usr/bin/env pwsh
    # lo-fileopen-crash.ps1 Called with 1+1 parameters: "c:/path/to/file.ext" [fix]
    param (
        [Parameter(Mandatory=$true)][string]$doc,
        [string]$regfix
    )
    
    $before = if ($regfix -eq "fix") { 1 } else { 0 }
    $after = if ($regfix -eq "fix") { 0 } else { 1 }
    
    $env:OOO_EXIT_POST_STARTUP='1'
    # have to pipe command output, so PowerShell will wait for LibreOffice to exit
    & "instdir/program/soffice" --norestore "$doc" 2>&1 | Out-String
    $status = $LASTEXITCODE
    
    Write-Host "$status"
    
    git reset --hard
    Remove-Item Env:\OOO_EXIT_POST_STARTUP
    
    # above status code 128 there are various fatal error signals and "Application Error" might have a negative status code
    if ($status -gt 128 -or $status -lt 0) {
        Write-Host "crashed"
        exit $after
    # OOO_EXIT_POST_STARTUP=1 causes status code 42
    } elseif ($status -eq 42) {
        Write-Host "opened successfully"
        exit $before
    } else {
        Write-Host "other exit code"
    }

    File opening crashes are quite rare these days thanks to our automated crash testing system. To use the script for crashes happening due to UI actions, remove OOO_EXIT_POST_STARTUP=1 and use 0 instead of 42 for the good status code.

    If you are dealing with a hang happening due to a UI action, kill the soffice process from another terminal or a task manager. Do not use Ctrl + C in the terminal that executes the bisect as it will stop the script. On Windows you have to add a -or $status -eq 1 to the crash condition as killing a process in Windows always gives 1 as the status code.

    When automatically bibisecting crashes, it is a good idea to disable locking to avoid the dialog asking about a locked document. Open the instdir/user/registrymodifications.xcu file. Add the following line among the item elements in the beginning of the file:

    <item oor:path="/org.openoffice.Office.Common/Misc"><prop oor:name="UseLocking" oor:op="fuse"><value>false</value></prop></item>

    Measuring file opening time

    This example is for investigating file opening performance regressions. The script takes a full path to a file, the upper limit for a good opening time in seconds, a timeout time in seconds and an optional "fix" parameter for finding a fixing commit.

    #!/usr/bin/env bash
    # lo-bisect-perf.sh  Called with 3+1 parameters: "/path/to/file.ext" good-time timeout-time [fix]
    fileext=$1 ;   goodtime=$2 ; timeouttime=$3 ; regfix=$4
    if [[ $regfix = "fix" ]]; then before=1; after=0; else before=0; after=1; fi
    timeout "$timeouttime" bash -c 'OOO_EXIT_POST_STARTUP=1 SAL_USE_VCLPLUGIN=gen ./instdir/program/soffice --norestore "$@"' bash "$fileext"
    status=$? ; echo "$status"
    exptime=$SECONDS
    if (( status == 124 )) ; then
        echo "timeout in $timeouttime, done in $exptime sec" ; exit $before
    elif (( status == 134 )) ; then
        echo "done in $exptime sec" ; exit $after
    elif (( status == 42 )) ; then
        if (( exptime < goodtime )) ; then
            echo "opens fast in $exptime sec" ; exit $before
        elif (( exptime > goodtime )) ; then
            echo "opens slow in $exptime sec" ; exit $after
        else echo "error"
        fi
    else echo "other exit code"
    git reset --hard
    fi

    #!/usr/bin/env pwsh
    # lo-bisect-perf.ps1 Called with 3+1 parameters: "c:/path/to/file.ext" good-time timeout-time [fix]
    param (
        [Parameter(Mandatory=$true)][string]$fileext,
        [Parameter(Mandatory=$true)][int]$goodtime,
        [Parameter(Mandatory=$true)][int]$timeouttime,
        [string]$regfix
    )
    
    $before = if ($regfix -eq "fix") { 1 } else { 0 }
    $after = if ($regfix -eq "fix") { 0 } else { 1 }
    
    $env:OOO_EXIT_POST_STARTUP='1'
    $process = Start-Process -FilePath "instdir/program/soffice" -ArgumentList "--norestore", "$fileext" -NoNewWindow -PassThru -Wait
    $process | Wait-Process -Timeout $timeouttime -ErrorAction SilentlyContinue
    $status = $process.ExitCode
    $exptime = (Get-Date) - $process.StartTime
    $roundedtime = $([math]::Round($exptime.TotalSeconds))
    git reset --hard
    Remove-Item Env:\OOO_EXIT_POST_STARTUP
    
    if ($status -eq 124) {
        Write-Host "timeout in $timeouttime, done in $roundedtime sec"
        exit $before
    } elseif ($status -eq 134) {
        Write-Host "done in $roundedtime sec"
        exit $after
    } elseif ($status -eq 42) {
        if ($exptime.TotalSeconds -lt $goodtime) {
            Write-Host "opens fast in $roundedtime sec"
            exit $before
        } elseif ($exptime.TotalSeconds -gt $goodtime) {
            Write-Host "opens slow in $roundedtime sec"
            exit $after
        } else {
            Write-Host "error"
        }
    } else {
        Write-Host "other exit code"
    }

    Measuring conversion time

    Ecco lo script per controllare il tempo di esportazione per qualsiasi estensione originale ed esportata, confrontandolo con un buon tempo determinato dall'utente quando si guarda ai tempi più vecchi e principali. Lo script può essere utilizzato anche per trovare una correzione, se l'ultimo parametro opzionale è una parola "correzione".

    #!/usr/bin/env bash
    # lo-exptime.sh. Called with 3+1 parameters: "/path/to/file" filter good-time [fix]
    file=$1 ; filter=$2 ; goodtime=$3 ; regfix=$4
    if [[ $regfix = "fix" ]]; then before=1; after=0; else before=0; after=1; fi
    ./instdir/program/soffice --headless --convert-to "$filter" --outdir "$(dirname "${file}")" "$file"
    exptime=$SECONDS
    if (( exptime < goodtime )) ; then echo "exports fast in $exptime sec" ; exit $before
    elif (( exptime > goodtime )) ; then echo "exports slow in $exptime sec" ; exit $after
    else echo "error"
    fi

    #!/usr/bin/env pwsh
    # lo-exptime.ps1. Called with 3+1 parameters: "c:/path/to/file" filter good-time [fix]
    param (
        [Parameter(Mandatory=$true)][string]$file,
        [Parameter(Mandatory=$true)][string]$filter,
        [Parameter(Mandatory=$true)][int]$goodtime,
        [string]$regfix
    )
    
    $before = if ($regfix -eq "fix") { 1 } else { 0 }
    $after = if ($regfix -eq "fix") { 0 } else { 1 }
    
    $outputDir = Split-Path -Path $file -Parent
    $inputFile = "$file"
    $startTime = Get-Date
    
    & "instdir/program/soffice" --headless --convert-to $filter --outdir $outputDir $inputFile
    
    $exptime = (Get-Date) - $startTime
    $exptimeSec = [math]::Round($exptime.TotalSeconds)
    
    if ($exptimeSec -lt $goodtime) {
        Write-Host "exports fast in $exptimeSec sec"
        exit $before
    } elseif ($exptimeSec -gt $goodtime) {
        Write-Host "exports slow in $exptimeSec sec"
        exit $after
    } else {
        Write-Host "error"
    }

    Measuring macro execution time

    Ecco lo script per utilizzare la macro e uscire, misurando il tempo di esecuzione e confrontandolo con un buon tempo. Il vantaggio è che il file può essere modificato dall'interno. Questo script utilizza anche il controllo del tempo di timeout in caso di blocco o arresto anomalo. Il comando è più complesso in quanto consente qualsiasi nome di file. Gli stati esatti vengono trovati con i test più vecchi e i commit principali e lo script possono essere modificati di conseguenza.

    #!/usr/bin/env bash
    # lo-openmacro.sh  Called with 4+1 parameters: "/path/to/file.ext" good-time timeout-time macro-name [fix]
    fileext=$1 ; goodtime=$2 ; timeouttime=$3 ; macroname=$4 ; regfix=$5
    if [[ $regfix = "fix" ]]; then before=1; after=0; else before=0; after=1; fi
    timeout "$timeouttime" bash -c 'OOO_EXIT_POST_STARTUP=1 SAL_USE_VCLPLUGIN=gen ./instdir/program/soffice --norestore "$@"' bash "$fileext" macro://./Standard.Module1."$macroname"
    status=$? ; echo "$status"
    exptime=$SECONDS
    if [ $status = 124 ] ; then
        echo "timeout in $timeouttime, done in $exptime sec" ; exit $before
    elif (( status == 134 )) ; then
        echo "done in $exptime sec" ; exit $after
    elif (( status == 42 )) ; then
        if (( exptime < goodtime ))  ; then
            echo "opens fast in $exptime sec" ; exit $before
        elif (( exptime > goodtime ))  ; then
            echo "opens slow in $exptime sec" ; exit $after
        else echo "error"
        fi
    else echo "other exit code"
    git reset --hard
    fi

    #!/usr/bin/env pwsh
    # lo-openmacro.ps1  Called with 4+1 parameters: "c:/path/to/file.ext" good-time timeout-time macro-name [fix]
    param (
        [Parameter(Mandatory=$true)][string]$fileext,
        [Parameter(Mandatory=$true)][int]$goodtime,
        [Parameter(Mandatory=$true)][int]$timeouttime,
        [Parameter(Mandatory=$true)][string]$macroname,
        [string]$regfix
    )
    
    $before = if ($regfix -eq "fix") { 1 } else { 0 }
    $after = if ($regfix -eq "fix") { 0 } else { 1 }
    
    $env:OOO_EXIT_POST_STARTUP='1'
    $process = Start-Process -FilePath "instdir/program/soffice" -ArgumentList "--norestore", "$fileext", macro://./Standard.Module1."$macroname" -NoNewWindow -PassThru -Wait
    $process | Wait-Process -Timeout $timeouttime -ErrorAction SilentlyContinue
    $status = $process.ExitCode
    $exptime = (Get-Date) - $process.StartTime
    $roundedtime = $([math]::Round($exptime.TotalSeconds))
    
    git reset --hard
    Remove-Item Env:\OOO_EXIT_POST_STARTUP
    
    if ($status -eq 124) {
        Write-Host "timeout in $timeouttime, done in $roundedtime sec"
        exit $before
    } elseif ($status -eq 134) {
        Write-Host "done in $roundedtime sec"
        exit $after
    } elseif ($status -eq 42) {
        if ($exptime.TotalSeconds -lt $goodtime) {
            Write-Host "opens fast in $roundedtime sec"
            exit $before
        } elseif ($exptime.TotalSeconds -gt $goodtime) {
            Write-Host "opens slow in $roundedtime sec"
            exit $after
        } else {
            Write-Host "error"
        }
    } else {
        Write-Host "other exit code"
    }