es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Las pruebas unitarias bifurcadas de allegro se bloquean cuando se ejecutan.

Estoy usando un sistema de pruebas unitarias personalizado para C que bifurca cada prueba en un nuevo proceso para que, si una falla, las otras puedan ejecutarse sin interrupciones. En este momento, estoy intentando usar esto para probar código que utiliza Allegro. Cuando ejecuto al_init() en main (mostrado a continuación), mi programa de pruebas termina después de la primera prueba con el mensaje de error:

Conexión X con :1 interrumpida (apagado intencional o cierre del servidor).
Conexión X con :1 interrumpida (apagado intencional o cierre del servidor).
make: *** [Makefile:39: tests/results/collision.result] Error 1

Código erróneo que causa problemas:

void MakeCollisionCircleInWorldTest()
{
    Testing_Unimplemented();
}

/*
 * otras pruebas no implementadas aquí, recortadas por brevedad
 */

int main(int argc, char **argv)
{
    al_init();
    Testing_Init(argc, argv);

    TESTING_RUN(MakeCollisionCircleInWorldTest);
    TESTING_RUN(DuplicateCollisionCircleTest);
    TESTING_RUN(AddCollisionCircleTest);
    TESTING_RUN(RemoveCollisionCircleTest);
    TESTING_RUN(MoveTest);
    TESTING_RUN(CheckCollisionsTest);

    return 0;
}

Nota: es TESTING_RUN lo que realiza la bifurcación mencionada anteriormente. Asumo que esto está relacionado con el fallo (quizás la conexión se interrumpe después de que el primer hijo termina), pero no estoy seguro de cómo exactamente ni de cómo solucionarlo.

Cuando en cambio coloco la llamada a al_init() en cada prueba por separado (mostrado a continuación), no hay terminación prematura ni mensaje de error, pero parece ser algo lento (no insoportablemente lento, pero hay una pausa perceptible que realmente no debería estar presente para pruebas que fallan inmediatamente porque no están implementadas). Además, parece un poco incómodo reinicializar Allegro para cada prueba por separado.

void MakeCollisionCircleInWorldTest()
{
    al_init();
    Testing_Unimplemented();
}

/*
 * otras pruebas no implementadas aquí, recortadas por brevedad
 */

int main(int argc, char **argv)
{
    Testing_Init(argc, argv);

    TESTING_RUN(MakeCollisionCircleInWorldTest);
    TESTING_RUN(DuplicateCollisionCircleTest);
    TESTING_RUN(AddCollisionCircleTest);
    TESTING_RUN(RemoveCollisionCircleTest);
    TESTING_RUN(MoveTest);
    TESTING_RUN(CheckCollisionsTest);

    return 0;
}

¿Qué está causando el fallo? ¿Hay alguna manera de inicializar Allegro en main sin romper mis pruebas?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El accidente parece estar relacionado con la conexión del servidor X utilizada por Allegro, la cual se cierra cuando el primer proceso hijo finaliza. Una posible solución sería inicializar Allegro en main antes de bifurcar los procesos hijos, y luego cerrarlo después de que se hayan completado todas las pruebas. Esto se puede hacer agregando un manejador de señal para SIGCHLD en main, el cual se llamará cuando cualquier proceso hijo finalice, y luego cerrando la conexión de Allegro en ese manejador. Algo como esto:

    #include <signal.h>
    
    static ALLEGRO_DISPLAY *display;
    
    void SigChildHandler(int sig)
    {
        /* Cerrar la conexión de Allegro. */
        al_destroy_display(display);
    
        /* Llamar al manejador de señal original, si existe. */
        signal(sig, SIG_DFL);
        raise(sig);
    }
    
    int main(int argc, char **argv)
    {
        /* Inicializar Allegro. */
        al_init();
        display = al_create_display(640, 480);
    
        /* Configurar el manejador de señal para los procesos hijos. */
        signal(SIGCHLD, SigChildHandler);
    
        /* Inicializar el marco de pruebas. */
        Testing_Init(argc, argv);
    
        /* Ejecutar pruebas. */
        TESTING_RUN(MakeCollisionCircleInWorldTest);
        TESTING_RUN(DuplicateCollisionCircleTest);
        TESTING_RUN(AddCollisionCircleTest);
        TESTING_RUN(RemoveCollisionCircleTest);
        TESTING_RUN(MoveTest);
        TESTING_RUN(CheckCollisionsTest);
    
        /* Cerrar Allegro. */
        al_destroy_display(display);
    
        return 0;
    }
    

    Ten en cuenta que esto asume que solo necesitas una pantalla de Allegro para todas las pruebas. Si diferentes pruebas requieren pantallas diferentes, es posible que debas modificar este enfoque en consecuencia. Además, es posible que necesites agregar manejo de errores para la inicialización de Allegro y la creación de la pantalla.</signal.h>

Comments are closed.