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?
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.