Interfaz de Pruebas Estándar

Descubrimiento Estándar, Puesta en Escena e Invocación a Pruebas de Integración.

Versión: 2.0.0

Resumen

Definamos una delimitación clara entre un conjunto de pruebas (incluida la estructura) y el sistema de Integración Continua que ejecuta el conjunto de pruebas. Esto es la interfaz estándar. Lo que sigue es una manera estándar de descubrir, empaquetar e invocar las pruebas de integración para un paquete almacenado en un repositorio dist-git de Fedora.

Muchos paquetes Fedora tienen pruebas unitarias. Estas pruebas se ejecutan normalmente durante un paso de compilación RPM %check y se ejecutan en una raíz de compilación. Por otro lado, las pruebas de integración deberían ejecutarse en un sistema compuesto. Los proyectos upstream tienen pruebas de integración tanto Fedora QA como el equipo Atomic Host les gustaría crear más pruebas de integración, a Red Hat le gustaría llevar las pruebas de integración upstream.

Beneficio para Fedora

Los desarrolladores se benefician de tener un objetivo consistente para como describir las pruebas, a la vez de poder ejecutarlas localmente mientras se depuran problemas y se iteran las pruebas.

Al organizar e invocar pruebas de manera consistente en Fedora creamos un ecosistema consistente para las pruebas que permite que interoperen diversas estructuras de prueba así como la infraestructura del sistema de Integración Continua. Las pruebas de integración duran más que los detalles de implementación de las estructuras en los que están escritos o de los sistemas de Integración Continua que las ejecutan.

Definiciones

Terminología

Sujeto de Prueba

Los elementos que van a ser probados. Ejemplos: RPMs, imagen OCI, ISO, QCow2, repositorio de Módulos …

Prueba

Una pieza de código a la que llamar/ejecutar y los correspondientes datos y maqueta de prueba en la que ejercitar y evaluar un sujeto de prueba.

Entorno de Prueba

Entorno donde la ejecución de las pruebas actuales tienen lugar. Las pruebas tienen impacto directo en el entorno de prueba.

Conjunto de Prueba

La colección de todas las pruebas que se aplican a un sujeto de pruebas.

Marco de pruebas

Una librería o componente que el conjunto de pruebas y las_ pruebas_ usan para cumplir su trabajo. Ejemplos: Avocado, Pruebas Instaladas GNOME, Familia de Pruebas Meta, Pruebas Ansible en Atomic Host, pruebas Tunir, imágenes de prueba docker…

Resultado de Pruebas

Una salida booleana pass/fail de un conjunto de pruebas. Los resultados de prueba_ son para consumo por los aspectos automatizados de los sistemas de pruebas.

Artefacto de Prueba

Cualquier salida adicional de un conjunto de pruebas como la salida stdout/stderr, archivos de registro, pantallazos, volcados de memoria o flujos TAP/Junit/subunit. Los artefactos de prueba son para consumo de los humanos, archivo o análisis de grandes datos.

Sistema de Prueba

Un CI u otro sistema de prueba que le gustaría para descubrir, preparar e invocar pruebas para un sujeto de prueba. Ejemplo: Jenkins, Taskotron, ZUUL, CentOS CI, Papr, Travis, Semaphore, Openshift CI/CD, Ubuntu CI

Corredor de Pruebas

El sistema de prueba delega la ejecución de las pruebas en el corredor de pruebas que puede ser diferente del entorno de pruebas. Por ejemplo, ansible se ejecuta sobre el corredor de pruebas y las pruebas se ejecutan en el host administrado. Normalmente por parte del corredor de pruebas se utiliza una versión estable del sistema operativo.

Formato de los Resultados

Se debe utilizar el siguiente formato para reportar los resultados de las pruebas individuales en el archivo results.yml:

results:
- {result: pass, test: test1, logs: [test1.log]}
- {result: fail, test: test2, logs: [test2.log, debug.log]}
- {result: error, test: test3, logs: [test3.log, debug.log, error.log]}
resultado

Resultado de la prueba. Uno de pass, fail o error. Obligatorio.

test

Nombre de la prueba. Un identificador único. Obligatorio.

logs

Uno o más registros con salidas detalladas de las pruebas. Opcional. La ruta debe ser relativa al directorio artifacts. Algunas interfaces de usuario pueden mostrar solo un único registro de forma predeterminada. En este caso el primer registro de la lista se debe presentar al usuario.

El campo result puede contener los siguiente valores:

pass

La prueba ha finalizado con éxito y ha pasado.

fail

La prueba ha finalizado con éxito y ha fallado.

error

Ha habido un problema con al ejecución de la prueba.

Responsabilidades

El Sistema de Prueba es responsable de:

  • Construir o de lo contrario adquirir el sujeto de prueba, como un paquete, contenedor de imagen, árbol…

  • Decidir que conjunto de pruebas ejecutar, a menudo mediante el uso de la interfaz estándar para descubrir las pruebas apropiadas para el repositorio dist-git en el que se originó un sujeto de prueba.

  • Programar, aprovisionar u organizar para ejecutar el conjunto de pruebas en la computación y el almacenamiento adecuado…

  • Organizar el conjunto de pruebas como se describe en la interfaz estándar.

  • Llamar al conjunto de pruebas como se describe por la interfaz estándar.

  • Recopilar los resultados de las pruebas y los artefactos de pruebas como se describe por la interfaz estándar.

  • Anunciar y transmitir los resultados de pruebas y los_ artefactos de pruebas_ para su control y archivo…

La Interfaz Estándar describe como:

  • Descubrir un conjunto de pruebas para un repositorio dist-git dado.

  • Identificar de forma única un conjunto de pruebas.

  • Preparar un conjunto de pruebas y sus dependencias como marco de pruebas.

  • Proporcionar el sujeto de pruebas al conjunto de pruebas.

  • Invocar un conjunto de pruebas de forma consistente.

  • Recopilar resultados de pruebas y artefactos de prueba desde el conjunto de pruebas invocado.

El Conjunto de Pruebas es responsable de:

  • Declarar sus dependencias como marco de pruebas por medio de la interfaz estándar.

  • Ejecutar el marco de pruebas según sea necesario.

  • Proporcionar (localmente) cualquier contenedor o máquina virtual necesaria para probar el sujeto de pruebas.

  • Proporcionar los resultados de pruebas y los sujetos de prueba de acuerdo con el estándar

El formato de los registros textuales y los artefactos de prueba que surgen de un conjunto de pruebas no están prescritos en este documento. Tampoco se prevé que se estandarice en todos los conjuntos de prueba posibles.

Requisitos

  • El conjunto de pruebas y el marco de pruebas NO DEBERÍAN filtrar sus detalles de implementación en el sistema de prueba de manera que distinta a la interfaz estándar.

  • El conjunto de pruebas y el marco de pruebas NO DEBERÍAN depender del comportamiento del sistema de pruebas distinto a la interfaz estándar.

  • La interfaz estándar DEBE habilitar un empaquetador dist-git para ejecutar un conjunto de pruebas localmente.

    • Los conjuntos de prueba o los marcos de prueba PUEDEN llamar a la red para determinadas pruebas.

  • DEBE ser posible organizar un conjunto de pruebas upstream usando la interfaz estándar.

  • Tanto las pruebas in situ como las más rigurosas pruebas externas DEBEN ser posibles con la interfaz estándar.

    • Para las pruebas in situ el conjunto de pruebas está en el mismo árbol del sistema de archivos y del espacio de procesamiento que el sujeto de prueba.

    • Para las pruebas externas el conjunto de pruebas está fuera del árbol del sistema de archivos y del espacio de procesamiento del sujeto de prueba.

  • El conjunto de pruebas y el marco de prueba DEBEN ser capaces de aprovisionar los contenedores y máquinas virtuales necesarias para sus pruebas sin solicitarlas al sistema de prueba.

  • La interfaz estándar DEBERÍA describir como identificar inequívocamente un conjunto de pruebas.

Descripción Detallada

Esta interfaz estándar describe como descubrir, organizar e invocar pruebas. Es importante separar limpiamente los detalles de implementación del sistema de prueba de los del conjunto de pruebas y su marco. También es importante permitir a los empaquetadores de Fedora para invocar local y manualmente un conjunto de pruebas.

Vea primero la Terminlogía, división de Responsabilidades y Requisitos.

Puesta en escena

Los archivos de pruebas serán añadidos en la carpeta tests/ de una rama del repositorio dist-git. La estructura de los archivos y carpetas se deja a la libertad de los empaquetadores pero hay uno o más manuales en la carpeta t`tests/` que se pueden invocar para ejecutar el conjunto de pruebas.

  1. El sistema de prueba DEBERÍA realizar las pruebas en el sistema operativo de destino (por ejemplo: Fedora) apropiado para el nombre de la rama del repositorio dist-git que contiene las pruebas.

  2. El sistema de prueba DEBERÍA organizar un corredor de pruebas limpio para cada conjunto de pruebas que realice.

  3. El sistema de prueba DEBE presentar el siguiente paquete en el corredor de pruebas:

    1. standard-test-roles

  4. El sistema de prueba DEBE clonar el repositorio dist-git para la prueba en el corredor de pruebas y verificar la rama apropiada.

  5. Los contenidos de`/etc/yum.repos.d` en el sistema preparado DEBERÍAN ser reemplazados con información del repositorio que refleje los paquetes Fedora bien conocidos correspondientes a la rama del repositorio dist-git.

    1. El sistema de pruebas PUEDE usar múltiples repositorios, incluyendo updates o updates-testing para asegurar esto.

Invocación

El sistema de pruebas DEBE ejecutar cada libro de jugadas que coincida con el glob tests/tests*.yml en el repositorio dist-git. Cada uno de estos archivos constituye un conjunto de pruebas. Cada conjunto de pruebas es invocado por el sistema de prueba independientemente y ejecutado en un entorno de prueba claro como sigue.

Los sujetos de pruebas se pasan al libro de jugadas y al inventario como entorno del sistema operativo y entorno ansible. A menudo solo se aprueba un sujeto de prueba. Sin embargo se pueden concatenar varios sujetos en una cadena de escape de shell. Los libros de jugadas y/o el script de inventario dividen la cadena. Las extensiones que siguen se usan para determinar el tipo de sujeto:

*.rpm

Ruta absoluta a un archivo RPM

*.repo

Nombres de archivos de repositorios apropiados para /etc/yum.repos.d

*.qcow2, *.qcow2c

Ruta absoluta a una imagen de disco de máquina virtual para arrancar con cloud-init

*.oci

Ruta absoluta a un paquete de sistema de archivos de imágenes de contenedor OCI

docker:*

Ruta de acceso completa a una imagen acoplable en un registro

…​

Otros identificadores de s_ujeto de prueba_ se pueden añadir más tarde.

Varias prueba_s en un manual constituyen un _conjunto de pruebas. Algunas partes de estos conjuntos de prueba se ejecutarán en ciertos contextos, contra ciertos artefactos entregables. Ciertas pruebas se ejecutarán contra entregables Atomic Host, otros no lo serán. Ciertas pruebas correrán contra entregables Docker, otras no. Esto está relacionado con los identificadores de _sujetos de prueba_s, pero no se superpone exactamente con ellos. Las etiquetas ansible se usan para indicar estos contextos.

atomic

Atomic Host

contenedor

Un contendor Docker u OCI

classic

Probado contra un sistema clásico instalado con YUM/DNF.

…​

Otros identificadores de s_ujeto de prueba_ se pueden añadir más tarde.

Para invocar las pruebas, el sistema de prueba debe llevar a cabo las siguientes tareas por cada manual del conjunto de pruebas:

  1. DEBE ejecutar el manual con las siguientes variables de entorno del sistema operativo:

    1. TEST_SUBJECTS: La cadena sujetos de prueba como se describe arriba

    2. TEST_ARTIFACTS: La ruta completa de una carpeta vacía para los artefactos de prueba

  2. DEBERÍA ejecutar el manual con todas las etiquetas Ansible que mejor representen el contexto de pruebas pretendido.

    1. La elección de las etiquetas de contexto de prueba está relacionada con el sujeto de prueba que están siendo probado

  3. DEBE ejecutar Ansible con el inventario configurado en la ruta completa del archivo o directorio tests/inventory si existe.

    1. Si el archivo tests/inventory no existe DEBERÍA ser usado como predeterminado /usr/share/ansible/inventory.

  4. DEBE ejecutar el manual como root.

  5. DEBE ejecutar el manual pasando como variable ansible git_branch.

    1. La rama usada para clonar tests*.yml

  6. DEBE examinar el código de salida del manual. Un código de salida cero significa que la prueba se ha completado con éxito, si no es cero significa un problema ejecutando las pruebas.

  7. DEBE examinar el archivo results.yml en la carpeta artifacts para detectar si las pruebas pasaron o fallaron.

  8. DEBE tratar el archivo test.log en la carpeta artifacts como la principal salida legible de la prueba.

  9. DEBERÍA situar la stdout/stderr textual del comando ansible-playbook en el archivo ansible.log en la carpeta artifacts.

  10. DEBERÍA tratar los contenidos de la carpeta artifacts como los artefactos de prueba.

Cada manual de conjunto de pruebas o cada marco de prueba contenido en el mismo:

  1. DEBERÍA eliminar los privilegios de forma adecuada si el conjunto de pruebas debe ejecutarse como no root.

  2. DEBE instalar cualquier requisito de su conjunto de pruebas o marco de pruebas y DEBE fallar si esto no es posible.

  3. DEBE aprovisionar el sujeto de pruebas listado en la variable subjects apropiadamente para su nombre de manual (descrito arriba) y DEBE fallar si no es posible.

  4. DEBE colocar la principal salida legible del conjunto de pruebas en un archivo test.log en la carpeta de la variable artifacts. Esto DEBE suceder aún si alguna de las pruebas falla.

  5. DEBERÍA colocar artefactos de prueba adicionales en la carpeta definida en la variable artifacts.

  6. DEBE devolver un código de salida cero del manual si las pruebas se han ejecutado con éxito o un código de salida distinto de cero si falló al ejecutar cualquier prueba (por ejemplo, a causa de un error de infraestructura).

  7. DEBE crear un archivo results.yml en el directorio artifacts con los resultados de las pruebas en el formato de resultados definido arriba.

Si existe un archivo o script de inventario, este:

  1. DEBE describir donde invocar el manual y como conectar a ese objetivo.

  2. DEBERÍA lanzar o instalar cualquier $TEST_SUBJECTS` soportado de manera que el manual pueda ser invocado contra ellos.

  3. DEBERÍA poner los registros relevantes en el directorio $TEST_ARTIFACTS.

Descubrimiento

El descubrimiento de pruebas se hace por medio de dist-git. Tanto los paquetes como los módulos deben tener pruebas en este formato. Para listar que contexto de prueba es relevante para un directorio o manual dist-git dado, use un comando como el siguiente:

ansible-playbook --list-tags tests.yml

Alcance

Puesto que las pruebas se añaden en una subcarpeta del repositorio dist-git, no se requieren cambios en la infraestructura de Fedora y no tendrán impacto sobre el flujo de trabajo y las herramientas de los empaquetadores.

Solo será necesario enseñar al sistema de pruebas a instalar los requisitos y ejecutar los manuales.

Experiencia del Usuario

Una manera estándar para empaquetar, almacenar y ejecutar las pruebas beneficia la estabilidad de Fedora y hace a Fedora mejor para los usuarios.

  • Esta estructura facilita la ejecución local, por lo que potencialmente reproduce un error desencadenado en el sistema de pruebas.

  • Ansible está siendo cada vez más popular, lo que facilita que las personas contribuyan con nuevas pruebas

  • Usado por muchos administradores de sistemas, ansible podría ayudar a los administradores de sistemas a llevar casos de prueba a los empaquetadores y desarrolladores sobre la situación en que algo les ha fallado.

Diagrama

sti diagram

Impacto de actualización/compatibilidad

No hay un impacto real de actualización o compatibilidad. Las pruebas se ramifican por versión según están ramificados ahora los archivos de especificaciones en dist-git.

Propuestas y Evaluación

Durante el proceso de selección de una invocación estándar de pruebas y formato de esquema para Fedora, fueron examinadas diversas propuestas .

Contacto