Test

Abilitazione di $0

I test possono essere scritti in modi diversi, ma vengono esposti e invocati in un modo standard definito dalla Standard Test Interface direttamente nel [repository git](https://src.fedoraproject.org/projects/rpms/%2A) del pacchetto. È anche possibile abilitare la pipeline per il namespace dei test, vedi Testing Tests per i dettagli. Per iniziare a lavorare sui test, puoi clonare direttamente il repo di un pacchetto:

git clone https://src.fedoraproject.org/rpms/qrencode.git

Usa fedpkg per clonare il repository git del pacchetto. Vedi la Guida alla Manutenzione dei Pacchetti per maggiori informazioni sullo strumento.

fedpkg clone -a qrencode

I test vengono abilitati includendo il file tests.yml all’interno della directory tests:

cd qrencode/tests
cat tests.yml

I test sono racchiusi o scritti come playbook Ansible. Ecco un esempio di un semplice playbook che abilita un singolo smoke test per il pacchetto qrencode:

- hosts: localhost
  roles:
  - role: standard-test-beakerlib
    tags:
    - classic
    - container
    - atomic
    tests:
    - smoke
    required_packages:
    - qrencode
    - file

Diamo ora un breve sguardo al playbook per vedere quali variabili sono definite al fine di abilitare lo smoke test:

ruoli

Questo test utilizza il ruolo standard-test-beakerlib proveniente da Standard Test Roles per eseguire un test BeakerLib

tag

tutti e tre i soggetti del test (rpm [classic](https://www.google.com/search?q=xref:standard-test-roles.adoc%23_classic), ">container(https://www.google.com/search?q=xref:standard-test-roles.adoc%23_container) docker e host ">atomic(https://www.google.com/search?q=xref:standard-test-roles.adoc%23_atomic)) sono rilevanti per questo test

Test

elenco dei test da eseguire (in questo caso abbiamo un singolo smoke test)

Pacchetti richiesti

elenco dei pacchetti rpm richiesti per l’esecuzione del test

È possibile suddividere i test in più playbook, ognuno dei quali può rappresentare un test o una parte di un test. Il sistema di testing eseguirà separatamente ciascun playbook che corrisponde al pattern globale tests/tests*.yml in un ambiente pulito. Opzionalmente, è possibile avere più playbook senza il prefisso tests e collegarli dal file tests.yml. Diamo un’occhiata all’esempio di gzip:

> fedpkg clone -a gzip
Cloning into 'gzip'...
> cd gzip/tests/
> ls
test-simple  test_simple.yml  tests.yml
> cat tests.yml
- include: test_simple.yml

Eseguendo (

Prima di eseguire i test, assicurati di avere le seguenti dipendenze installate sul tuo sistema:

dnf install ansible python2-dnf libselinux-python standard-test-roles

Sebbene alcuni playbook possano funzionare senza sudo, i test vengono sempre invocati come root. Il test stesso può configurare utenti e/o revocare i permessi se fa parte del test. Ma in generale, assicurati di essere root quando invochi i test.

I test potrebbero modificare o distruggere il tuo ambiente
Si raccomanda di utilizzare una macchina virtuale per i test, al fine di prevenire qualsiasi modifica indesiderata effettuata dal test sul tuo sistema.

Eseguire un test direttamente sul sistema corrente è semplice:

ansible-playbook tests.yml

Per eseguire solo i test adatti ai sistemi classici installati tramite yum o dnf, usa l’argomento --tags:

ansible-playbook --tags=classic tests.yml

See Standard Test Roles documentation for detailed instructions how to run tests for a specific Rpm Package, Docker Container or Atomic Host.

Scrittura in corso

Il codice del test stesso può essere memorizzato direttamente nel dist-git (raccomandato come impostazione predefinita) o recuperato da un altro repository ospitato nell’infrastruttura di Fedora, come il [Test Namespace](https://www.google.com/search?q=xref:share-test-code.adoc). Il modo più semplice per aggiungere un nuovo test è utilizzare uno dei " class="xref unresolved">Standard Test Roles(https://www.google.com/search?q=xref:standard-test-roles.adoc) esistenti, che si occupano di molti dettagli di implementazione. Se desideri creare un test personalizzato, segui le istruzioni riportate di seguito.

Una volta identificato un repository dist-git in cui aggiungere i nuovi test (vedi sopra), puoi iniziare a scrivere un nuovo test Ansible. Crea un [playbook Ansible](http://docs.ansible.com/ansible/latest/playbooks.html) con un nuovo nome. Assicurati che l’estensione sia .yml. Inseriamo il seguente esempio nel file test_pid_1.yml.

---
- hosts: localhost
  vars:
  - artifacts: "{{ lookup('env', 'TEST_ARTIFACTS')|default('./artifacts', true) }}"
  tags:
  - atomic
  - classic
  - container
  tasks:
  - name: Test block
    block:
      - name: Test that /proc/1 exists
        shell: |
            ls /proc > /tmp/test.log || exit 1
            grep -qw 1 /tmp/test.log && result=pass || result=fail
            echo -e "results:\n- {result: $result, test: proc}" > /tmp/results.yml

    always:
      - name: Pull out the artifacts
        fetch:
          dest: "{{ artifacts }}/"
          src: "{{ item }}"
          flat: yes
        with_items:
          - /tmp/test.log
          - /tmp/results.yml

Tutti i test hanno una directory degli artefatti (artifacts) in cui inseriscono i propri output. Il sistema di testing o di CI che invoca il test valorizzerà questa variabile con una directory che provvederà poi ad archiviare. All’interno del test ci assicuriamo che questa directory esista.

Tramite l’uso dei tags indichiamo su quale tipo di sistemi questo test è adatto a essere eseguito. Quando si includono task aggiuntivi come i pre_tasks, assicurati di impostare anche il tag appropriato. In aggiunta ai tag sopra elencati, è possibile utilizzare anche always per indicare che il task deve essere eseguito in tutti gli ambienti. Per esempio:

- hosts: localhost
  pre_tasks:
  - name: Set up a test user
    tags: always
    user:
      name: test
      groups:
        - wheel
        - adm

La sezione block è quella che esegue il test vero e proprio. In questo esempio, utilizziamo un modo piuttosto articolato per verificare che il PID 1 esista. Tuttavia, così facendo, inseriamo un artefatto di test aggiuntivo nella directory degli artefatti.

Infine, scarichiamo gli artefatti. Ricorda che il test non sempre viene eseguito sullo stesso sistema sul quale è stato invocato. Prova a eseguire questo test di esempio su un [Atomic Host](https://www.google.com/search?q=xref:standard-test-roles.adoc%23_atomic) o su un ">container Docker(https://www.google.com/search?q=xref:standard-test-roles.adoc%23_container). Dovrebbe andare a buon fine. Prova a cambiare l’argomento /proc/1 con un altro valore e il test dovrebbe fallire.

Puoi utilizzare la maggior parte delle tecniche Ansible nei tuoi playbook. Dai un’occhiata a [Standard Test Roles](https://www.google.com/search?q=xref:standard-test-roles.adoc) per trovare i ruoli Ansible che ti semplificheranno la scrittura dei test.

Contrassegnare il test per l’esecuzione

Il solo fatto di avere un file .yml nella directory corretta non significa che verrà invocato. Assicurati di fare riferimento ad esso o di aggiungerlo all’interno di un playbook tests.yml. Questo è il punto di ingresso che il sistema di testing o di CI utilizzerà per invocare tutti i test di un determinato pacchetto.

Se il file tests.yml non esiste ancora, crealo. Continuiamo con il nostro esempio precedente e creiamo un file tests.yml con il seguente contenuto:

- import_playbook: test_pid_1.yml

Ora puoi eseguire questo test con i comandi standard sopra indicati.

Consulta la Guida rapida per ricevere raccomandazioni su come contribuire con nuovi test.

In conclusione

Diciamo che tu abbia uno script che esegue un test. I suoi stdout e stderr sono l’output del test, e uno stato di uscita pari a zero indica il successo. Ecco come racchiuderemmo quel test per essere invocato. Diciamo di avere uno script semplice come in un file chiamato test-simple

#!/bin/sh
set -ex
# exercise installed gzip/gunzip programs
echo "Bla" > bla.file
cp bla.file bla.file.orig
gzip bla.file
gunzip bla.file.gz
cmp bla.file bla.file.orig
rm bla.file bla.file.orig

Possiamo scrivere un wrapper Ansible per questo script in questo modo, nel file test_simple.yml:

---
- hosts: localhost
  vars:
  - artifacts: "{{ lookup('env', 'TEST_ARTIFACTS')|default('./artifacts', true) }}"
  tags:
  - atomic
  - classic
  - container
  remote_user: root
  tasks:
  - name: Install the test files
    copy: src={{ item.file }} dest=/usr/local/bin/{{ item.dest }} mode=0755
    with_items:
    - {file: test-simple, dest: test-simple }

  - name: Test block
    block:
      - name: Execute the tests
        shell: |
          /usr/local/bin/test-simple &> /tmp/test.log && result=pass || result=fail
          echo -e "results:\n- {result: $result, test: simple}" > /tmp/results.yml

    always:
      - name: Pull out the logs
        fetch:
          dest: "{{ artifacts }}/"
          src: "{{ item }}"
          flat: yes
        with_items:
          - /tmp/test.log
          - /tmp/results.yml

Tutti i test hanno una directory degli artefatti in cui inseriscono il proprio output. Il sistema di testing o di CI che invoca il test popolerà questa variabile con una directory che provvederà poi ad archiviare. All’interno del test ci assicuriamo che questa directory esista.

Il block è la sezione che esegue il test vero e proprio.

Infine, scarichiamo gli artefatti. Ricorda che il test non sempre viene eseguito sullo stesso sistema sul quale è stato invocato.

Se il file tests.yml non esiste ancora, crealo. Continuiamo con il nostro esempio precedente e creiamo un file tests.yml con il seguente contenuto:

- import_playbook: test_simple.yml

Prova a eseguire questo test di esempio su un Atomic Host o su un Docker Container. Dovrebbe andare a buon fine.

Vedi la documentazione Standard Test Roles per istruzioni su come racchiudere i test BeakerLib e RHTS.

Consulta la Guida rapida per ricevere raccomandazioni su come contribuire con nuovi test.

Preparazione in corso

Se hai bisogno di apportare modifiche al sistema prima del test, includi un task Ansible extra prima della sezione di test. Ad esempio, questo aggiornerà tutti i pacchetti del sistema all’ultima versione:

- hosts: localhost
  tags:
    - classic
  tasks:
    - dnf:
        name: "*"
        state: latest

- hosts: localhost
  roles:
  - role: standard-test-basic
    tags:
    - classic
    tests:
    - smoke38:
        dir: smoke
        run: VERSION=3.8 METHOD=virtualenv ./venv.sh