Added optional global timeouts for test suite

This commit is contained in:
Lukasz Forynski 2013-12-17 14:46:57 +00:00
parent 0b394ba318
commit 2c1e71b6ad
4 changed files with 125 additions and 45 deletions

View File

@ -1,6 +1,6 @@
![catch logo](catch-logo-small.png) ![catch logo](catch-logo-small.png)
*v1.0 build 23 (master branch)* *v1.0 build 24 (master branch)*
Build status (on Travis CI) [![Build Status](https://travis-ci.org/philsquared/Catch.png)](https://travis-ci.org/philsquared/Catch) Build status (on Travis CI) [![Build Status](https://travis-ci.org/philsquared/Catch.png)](https://travis-ci.org/philsquared/Catch)

View File

@ -10,7 +10,16 @@
#ifndef __OBJC__ #ifndef __OBJC__
#if !defined(DO_NOT_USE_SIGNALS) #ifdef TIMEOUT_FOR_ALL_TESTS_IN_SECONDS
#ifdef __GNUC__
#define USING_TIMEOUTS
#else /*!__GNUC__ = for MSVC pthreads-win32 is needed (
unless this library will go to C++11 and use std::thread, in which case below could be updated accordingly)*/
#pragma message ("\nWARNING: Specified TIMEOUT_FOR_ALL_TESTS_IN_SECONDS, but it's only supported with GCC compilers..\n")
#endif /*__GNUC__*/
#endif /*TIMEOUT_FOR_ALL_TESTS_IN_SECONDS*/
#if defined(USING_TIMEOUTS) || !defined(DO_NOT_USE_SIGNALS)
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
void add_test_info(std::stringstream& s) { void add_test_info(std::stringstream& s) {
@ -29,6 +38,38 @@ void add_test_info(std::stringstream& s) {
} }
#endif #endif
#ifdef USING_TIMEOUTS
#include <pthread.h>
#ifdef CATCH_PLATFORM_WINDOWS
#define SLEEP(x) Sleep(x)
#else
#include <unistd.h>
#define SLEEP(x) sleep(x/1000)
#endif
void* timeout_thread_fcn(void* arg) {
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
unsigned int elapsed_s = 0;
volatile bool& exit_timeout_thread = *static_cast<bool*>(arg);
while(!exit_timeout_thread) {
SLEEP(1000);
elapsed_s++;
if (elapsed_s == TIMEOUT_FOR_ALL_TESTS_IN_SECONDS)
{
std::stringstream info;
info << "\n\n=================\n\n";
info << "Test execution timed out";
info << " (timeout was: " << TIMEOUT_FOR_ALL_TESTS_IN_SECONDS << " seconds)\n";
add_test_info(info);
std::cerr << info.str();
exit(-1);
}
}
return NULL;
}
#endif /*!TIMEOUT_FOR_ALL_TESTS_IN_SECONDS*/
#ifndef DO_NOT_USE_SIGNALS #ifndef DO_NOT_USE_SIGNALS
static bool testing_finished = false; static bool testing_finished = false;
#include <signal.h> #include <signal.h>
@ -66,16 +107,15 @@ void handle_signal(int sig) {
default: default:
break; break;
} }
add_test_info(s); add_test_info(s);
std::cout << s.str(); std::cout << s.str();
exit(-sig); exit(-sig);
} }
#endif /*!DO_NOT_USE_SIGNALS*/ #endif /*!DO_NOT_USE_SIGNALS*/
// Standard C/C++ main entry point // Standard C/C++ main entry point
int main (int argc, char * const argv[]) { int main (int argc, char * const argv[]) {
int ret = 0;
#ifndef DO_NOT_USE_SIGNALS #ifndef DO_NOT_USE_SIGNALS
testing_finished = false; testing_finished = false;
signal(SIGSEGV, handle_signal); signal(SIGSEGV, handle_signal);
@ -86,25 +126,25 @@ int main (int argc, char * const argv[]) {
signal(SIGFPE, handle_signal); signal(SIGFPE, handle_signal);
#endif /*!DO_NOT_USE_SIGNALS*/ #endif /*!DO_NOT_USE_SIGNALS*/
return Catch::Session().run( argc, argv ); #ifdef USING_TIMEOUTS
} pthread_t timeout_thread;
volatile bool exit_timeout_thread = false;
ret = pthread_create(&timeout_thread,
NULL,
timeout_thread_fcn,
(void*)&exit_timeout_thread);
if (ret) {
std::cerr << "Catch failed to start timeout thread (pthread_create failed with %d" << ret << ")\n";
return ret;
}
#endif /*!USING_TIMEOUTS*/
#else // __OBJC__ ret = Catch::Session().run( argc, argv );
// Objective-C entry point #ifndef DO_NOT_USE_SIGNALS
int main (int argc, char * const argv[]) { testing_finished = true;
#if !CATCH_ARC_ENABLED #endif /*!DO_NOT_USE_SIGNALS*/
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; return ret;
#endif
Catch::registerTestMethods();
int result = Catch::Session().run( argc, (char* const*)argv );
#if !CATCH_ARC_ENABLED
[pool drain];
#endif
return result;
} }
#endif // __OBJC__ #endif // __OBJC__

View File

@ -13,7 +13,7 @@
namespace Catch { namespace Catch {
// These numbers are maintained by a script // These numbers are maintained by a script
Version libraryVersion( 1, 0, 23, "master" ); Version libraryVersion( 1, 0, 24, "master" );
} }
#endif // TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED #endif // TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED

View File

@ -1,6 +1,6 @@
/* /*
* CATCH v1.0 build 23 (master branch) * CATCH v1.0 build 24 (master branch)
* Generated: 2013-12-17 13:44:13.801508 * Generated: 2013-12-17 14:45:19.329049
* ---------------------------------------------------------- * ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly * This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
@ -6166,7 +6166,7 @@ namespace Catch {
namespace Catch { namespace Catch {
// These numbers are maintained by a script // These numbers are maintained by a script
Version libraryVersion( 1, 0, 23, "master" ); Version libraryVersion( 1, 0, 24, "master" );
} }
// #included from: catch_text.hpp // #included from: catch_text.hpp
@ -7904,7 +7904,16 @@ namespace Catch {
#ifndef __OBJC__ #ifndef __OBJC__
#if !defined(DO_NOT_USE_SIGNALS) #ifdef TIMEOUT_FOR_ALL_TESTS_IN_SECONDS
#ifdef __GNUC__
#define USING_TIMEOUTS
#else /*!__GNUC__ = for MSVC pthreads-win32 is needed (
unless this library will go to C++11 and use std::thread, in which case below could be updated accordingly)*/
#pragma message ("\nWARNING: Specified TIMEOUT_FOR_ALL_TESTS_IN_SECONDS, but it's only supported with GCC compilers..\n")
#endif /*__GNUC__*/
#endif /*TIMEOUT_FOR_ALL_TESTS_IN_SECONDS*/
#if defined(USING_TIMEOUTS) || !defined(DO_NOT_USE_SIGNALS)
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
void add_test_info(std::stringstream& s) { void add_test_info(std::stringstream& s) {
@ -7923,6 +7932,38 @@ void add_test_info(std::stringstream& s) {
} }
#endif #endif
#ifdef USING_TIMEOUTS
#include <pthread.h>
#ifdef CATCH_PLATFORM_WINDOWS
#define SLEEP(x) Sleep(x)
#else
#include <unistd.h>
#define SLEEP(x) sleep(x/1000)
#endif
void* timeout_thread_fcn(void* arg) {
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
unsigned int elapsed_s = 0;
volatile bool& exit_timeout_thread = *static_cast<bool*>(arg);
while(!exit_timeout_thread) {
SLEEP(1000);
elapsed_s++;
if (elapsed_s == TIMEOUT_FOR_ALL_TESTS_IN_SECONDS)
{
std::stringstream info;
info << "\n\n=================\n\n";
info << "Test execution timed out";
info << " (timeout was: " << TIMEOUT_FOR_ALL_TESTS_IN_SECONDS << " seconds)\n";
add_test_info(info);
std::cerr << info.str();
exit(-1);
}
}
return NULL;
}
#endif /*!TIMEOUT_FOR_ALL_TESTS_IN_SECONDS*/
#ifndef DO_NOT_USE_SIGNALS #ifndef DO_NOT_USE_SIGNALS
static bool testing_finished = false; static bool testing_finished = false;
#include <signal.h> #include <signal.h>
@ -7960,16 +8001,15 @@ void handle_signal(int sig) {
default: default:
break; break;
} }
add_test_info(s); add_test_info(s);
std::cout << s.str(); std::cout << s.str();
exit(-sig); exit(-sig);
} }
#endif /*!DO_NOT_USE_SIGNALS*/ #endif /*!DO_NOT_USE_SIGNALS*/
// Standard C/C++ main entry point // Standard C/C++ main entry point
int main (int argc, char * const argv[]) { int main (int argc, char * const argv[]) {
int ret = 0;
#ifndef DO_NOT_USE_SIGNALS #ifndef DO_NOT_USE_SIGNALS
testing_finished = false; testing_finished = false;
signal(SIGSEGV, handle_signal); signal(SIGSEGV, handle_signal);
@ -7980,25 +8020,25 @@ int main (int argc, char * const argv[]) {
signal(SIGFPE, handle_signal); signal(SIGFPE, handle_signal);
#endif /*!DO_NOT_USE_SIGNALS*/ #endif /*!DO_NOT_USE_SIGNALS*/
return Catch::Session().run( argc, argv ); #ifdef USING_TIMEOUTS
} pthread_t timeout_thread;
volatile bool exit_timeout_thread = false;
ret = pthread_create(&timeout_thread,
NULL,
timeout_thread_fcn,
(void*)&exit_timeout_thread);
if (ret) {
std::cerr << "Catch failed to start timeout thread (pthread_create failed with %d" << ret << ")\n";
return ret;
}
#endif /*!USING_TIMEOUTS*/
#else // __OBJC__ ret = Catch::Session().run( argc, argv );
// Objective-C entry point #ifndef DO_NOT_USE_SIGNALS
int main (int argc, char * const argv[]) { testing_finished = true;
#if !CATCH_ARC_ENABLED #endif /*!DO_NOT_USE_SIGNALS*/
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; return ret;
#endif
Catch::registerTestMethods();
int result = Catch::Session().run( argc, (char* const*)argv );
#if !CATCH_ARC_ENABLED
[pool drain];
#endif
return result;
} }
#endif // __OBJC__ #endif // __OBJC__