cunit-testingforkxorgallegro5

Forked allegro unit tests crash when run


I'm using a custom unit-testing system for c which forks each test into a new process so that if one crashes the others can still be executed uninterrupted. Right now I am trying to use this for testing code that uses Allegro. When I run al_init() in main (shown below), my testing program terminates after the first test with the error message:

X connection to :1 broken (explicit kill or server shutdown).
X connection to :1 broken (explicit kill or server shutdown).
make: *** [Makefile:39: tests/results/collision.result] Error 1

Erroneous code causing problems:

void MakeCollisionCircleInWorldTest()
{
    Testing_Unimplemented();
}

/*
 * other unimplemented tests here, cropped for brevity
 */ 

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;
}

note: it is TESTING_RUN which performs the aforementioned forking. I assume this is related to the crash (perhaps the connection is killed after the first child terminates?), but I'm not certain exactly how, nor how to solve.

When I instead put the call to al_init() in each test separately (shown below), there is no premature termination nor error message, but it seems somewhat slow (not unbearably slow, but there is a noticeable pause which shouldn't really be there for tests that just immediately fail because they're unimplemented). Also, it just seems like a bit of a pain to reinit Allegro for every separate test.

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

/*
 * other unimplemented tests here, cropped for brevity
 */ 

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;
}

What is causing the crash? Is there some way to initialize Allegro in main without breaking my tests?


Solution

  • This problem was caused by al_init() setting al_uninstall_system as an atexit function. The result was that the child performed the system uninstall when it exited. This can be prevented by calling al_install_system(ALLEGRO_VERSION_INT, NULL) instead of al_init(), and then manually calling al_uninstall_system() when the parent process finishes. There are other solutions, but that's what I've gone with for now, since my unit test programs only have one exit point.