Pruebas

Habilitación

Las pruebas pueden escribirse de diferentes maneras, pero se exponen e invocan de forma estándar, según lo definido en Interfaz de Prueba Estándar directamente en el paquete repositorio Git. También es posible habilitar la canalización para el espacio de nombres de pruebas; consulte Pruebas de Prueba para obtener más información. Para empezar a trabajar en las pruebas, puede clonar directamente un repositorio de paquetes:

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

También puede usar fedpkg para clonar el repositorio. Consulte la Guía de Mantenimiento de Paquetes) para obtener más información sobre la herramienta:

fedpkg clone -a qrencode

Las pruebas se habilitan incluyendo el archivo tests.yml en el directorio tests:

cd qrencode/tests
cat tests.yml

Las pruebas se encapsulan o escriben como Ansible playbooks. A continuación, se muestra un ejemplo de un playbook simple que permite una única prueba de humo del paquete qrencode:

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

Ahora veamos brevemente el libro de jugadas para ver qué variables están definidas para habilitar la prueba de humo:

rol

esta prueba utiliza el rol standard-test-beakerlib de Standard Test Roles para ejecutar una prueba BeakerLib

etiquetas

Los tres sujetos de prueba (classic rpm, docker container y atomic host) son relevantes para esta prueba

tests

lista de pruebas a ejecutar (aquí solo tenemos una prueba de humo)

required_packages

lista de paquetes rpm necesarios para la ejecución de pruebas

Es posible separar las pruebas en varios playbooks, cada uno de los cuales puede representar una prueba o parte de ella. El sistema de pruebas ejecutará cada playbook que coincida con el archivo glob tests/tests*.yml por separado en un entorno limpio. Opcionalmente, puede tener varios playbooks sin el prefijo tests y vincularlos desde el archivo tests.yml. Veamos el ejemplo gzip:

 > fedpkg clone -a gzip
Clonación en 'gzip'...
> cd gzip/tests/
> ls
test-simple  test_simple.yml  tests.yml
> cat tests.yml
- include: test_simple.yml

Ejecutar

Antes de ejecutar pruebas, asegúrese de tener las siguientes dependencias instaladas en su sistema:

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

Aunque algunos playbooks pueden funcionar sin sudo, las pruebas siempre se invocan como root. La prueba en sí puede configurar usuarios o eliminar permisos si forma parte de ella. Pero, en general, asegúrese de ser root al invocar las pruebas.

Las pruebas pueden modificar o destruir su entorno
Se recomienda utilizar una máquina virtual para realizar pruebas a fin de evitar cambios no deseados en su sistema.

Ejecutar una prueba directamente en el sistema actual es fácil:

ansible-playbook tests.yml

Para ejecutar únicamente pruebas adecuadas para sistemas clásicos instalados por yum o dnf, utilice el argumento --tags:

ansible-playbook --tags=classic tests.yml

Consulte la documentación de Roles de prueba estándar para obtener instrucciones detalladas sobre cómo ejecutar pruebas para un Paquete Rpm, Contenedor Docker o Host atómico específico.

Escribir

El código de prueba puede almacenarse directamente en dist-git (recomendado por defecto) o extraerse de otro repositorio alojado en la infraestructura de Fedora, como Test Namespace. La forma más sencilla de agregar una nueva prueba es usar uno de los Standard Test Roles existentes, que se encargan de muchos detalles de implementación. Si desea crear una prueba personalizada, siga las instrucciones a continuación.

Una vez que hayas identificado un repositorio dist-git al que añadirás nuevas pruebas (ver arriba), puedes empezar a escribir una nueva prueba de Ansible. Crea un playbook de Ansible (http://docs.ansible.com/ansible/latest/playbooks.html) con un nuevo nombre. Asegúrate de que la extensión sea .yml. Colocaremos el siguiente ejemplo en el archivo 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

Todas las pruebas tienen un directorio de artefactos donde almacenan su salida. El sistema de pruebas o CI que invoca la prueba rellenará esta variable con un directorio que archivará. Nos aseguramos de que este directorio exista en la prueba.

Mediante el uso de etiquetas, indicamos en qué tipo de sistemas es adecuada esta prueba. Al incluir tareas adicionales como pre_tasks, asegúrese de configurar también la etiqueta adecuada. Además de las etiquetas mencionadas anteriormente, también es posible usar always para indicar que la tarea debe ejecutarse en todos los entornos. Por ejemplo:

- hosts: localhost
  pre_tasks:
  - name: Configurar una prueba de usuario
    tags: always
    user:
      name: test
      groups:
        - wheel
        - adm

El bloque es la sección que ejecuta la prueba. En este ejemplo, utilizamos un método bastante complejo para comprobar la existencia del PID 1. Sin embargo, al hacerlo, colocamos un artefacto de prueba adicional en el directorio de artefactos.

Por último, descargamos los artefactos. Recuerde que la prueba no siempre se ejecuta en el mismo sistema en el que se invocó. Intente ejecutar esta prueba de ejemplo en un Host Atomic o Contenedor Docker. Debería funcionar correctamente. Intente cambiar el argumento /proc/1 a otro valor; la prueba debería fallar.

Puedes utilizar más de las técnicas de Ansible en tus libros de jugadas. Mira en los Roles de Pruebas Estándar para los roles de Ansible para escribir tus pruebas más fáciles.

Marcar la prueba a ejecutar

Tener un archivo .yml en el directorio correcto no significa que se invoque. Asegúrese de referenciarlo o agregarlo desde un playbook tests.yml. Este es el punto de entrada que el sistema de pruebas o CI usará para invocar todas las pruebas de un paquete determinado.

Si el archivo tests.yml aún no existe, créalo. Continuamos con el ejemplo anterior y creamos un tests.yml con el siguiente contenido:

- import_playbook: test_pid_1.yml

Ahora puedes ejecutar esta prueba con los comandos estándares de arriba.

Consulte las Quick Start Guide para obtener recomendaciones para contribuir pruebas nuevas.

Cobertura

Suponemos que tienes un script que ejecuta una prueba. Su salida estándar (stdout) y su salida estándar (stderr) son la salida de la prueba, y un estado de salida de cero indica logro. Así es como encapsularíamos esa prueba para que se invoque. Suponemos que tenemos un script simple, como un archivo que se llama test-simple

#!/bin/sh
set -ex
# ejercicio instalado de programas gzip/gunzip
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

Podemos escribir un contenedor Ansible para este script como este en 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

Todas las pruebas tienen un directorio de artefactos donde sitúan su salida. El sistema de pruebas o CI que invoca la prueba rellenará esta variable con un directorio que archivará. Nos aseguramos de que este directorio exista en la prueba.

El “bloque” es la sección que ejecuta la prueba real.

Por último, descargamos los artefactos. Recuerde que la prueba no siempre se ejecuta en el mismo sistema en el que se invocó.

Si el archivo tests.yml aún no existe, créalo. Continuamos con el ejemplo anterior y creamos un tests.yml con el siguiente contenido:

- import_playbook: test_simple.yml

Intenta ejecutar esta prueba de ejemplo contra un Atomic Host o Docker Container. Debería pasar.

Consulte la documentación de Roles de Pruebas Estándar para obtener instrucciones sobre cómo encapsular pruebas BeakerLib y RHTS.

Consulte las Quick Start Guide para obtener recomendaciones para contribuir pruebas nuevas.

Preparación

Si necesita realizar algún ajuste en el sistema antes de realizar pruebas, incluya una tarea adicional de Ansible antes de la sección de pruebas. Por ejemplo, esto actualizará todos los paquetes del sistema a la última versión:

- 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