mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-16 10:08:36 +03:00
0023586: The test execution process should correctly stop on user demand
Possibility to break DRAW commands by user break (Control-C) is implemented as follows: - Treatment of Control-C (SIGINT signal) on UNIX in OSD::SetSignal() is made coherent with Windows implementation: instead of attempt to raise exception (simulated by longjump, does not work anyway), signal handler just sets a flag which can be later checked by OSD::ControlBreak() - Call to OSD::ControlBreak() is added to common entry point for OCCT DRAW commands; this causes command interruption if Control-C has been pressed before its start. - Command "dbreak" added allowing to check Control-Break status from Tcl script (raises Tcl exception if break was signaled) - Command "dversion" added printing information on OCCT version, used build options, compiler, etc. - Test system modified to properly handle and report user breaks and add version info in the summary log Fix compiler error on Linux
This commit is contained in:
parent
3994ec417f
commit
8a262fa13d
@ -18,10 +18,10 @@
|
|||||||
// purpose or non-infringement. Please see the License for the specific terms
|
// purpose or non-infringement. Please see the License for the specific terms
|
||||||
// and conditions governing the rights and limitations under the License.
|
// and conditions governing the rights and limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
#include <Standard_Macro.hxx>
|
#include <Standard_Macro.hxx>
|
||||||
#include <Standard_Stream.hxx>
|
#include <Standard_Stream.hxx>
|
||||||
#include <Standard_SStream.hxx>
|
#include <Standard_SStream.hxx>
|
||||||
|
#include <Standard_Version.hxx>
|
||||||
|
|
||||||
#include <Draw.ixx>
|
#include <Draw.ixx>
|
||||||
#include <Draw_Appli.hxx>
|
#include <Draw_Appli.hxx>
|
||||||
@ -30,6 +30,8 @@
|
|||||||
#include <Message.hxx>
|
#include <Message.hxx>
|
||||||
#include <Message_Messenger.hxx>
|
#include <Message_Messenger.hxx>
|
||||||
#include <OSD_MemInfo.hxx>
|
#include <OSD_MemInfo.hxx>
|
||||||
|
#include <OSD.hxx>
|
||||||
|
#include <OSD_Exception_CTRL_BREAK.hxx>
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
@ -272,6 +274,113 @@ static Standard_Integer decho(Draw_Interpretor& di, Standard_Integer n, const ch
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Standard_Integer dbreak(Draw_Interpretor& di, Standard_Integer, const char**)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
OSD::ControlBreak();
|
||||||
|
}
|
||||||
|
catch (OSD_Exception_CTRL_BREAK) {
|
||||||
|
di << "User pressed Control-Break";
|
||||||
|
return 1; // Tcl exception
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Standard_Integer dversion(Draw_Interpretor& di, Standard_Integer, const char**)
|
||||||
|
{
|
||||||
|
// print OCCT version and OCCTY-specific macros used
|
||||||
|
di << "Open CASCADE Technology " << OCC_VERSION_STRING_EXT << "\n";
|
||||||
|
#if defined(DEB) || defined(_DEBUG)
|
||||||
|
di << "Debug mode\n";
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_TBB
|
||||||
|
di << "TBB enabled (HAVE_TBB)\n";
|
||||||
|
#else
|
||||||
|
di << "TBB disabled\n";
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_GL2PS
|
||||||
|
di << "GL2PS enabled (HAVE_GL2PS)\n";
|
||||||
|
#else
|
||||||
|
di << "GL2PS disabled\n";
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_FREEIMAGE
|
||||||
|
di << "FreeImage enabled (HAVE_FREEIMAGE)\n";
|
||||||
|
#else
|
||||||
|
di << "FreeImage disabled\n";
|
||||||
|
#endif
|
||||||
|
#ifdef No_Exception
|
||||||
|
di << "Exceptions disabled (No_Exception)\n";
|
||||||
|
#else
|
||||||
|
di << "Exceptions enabled\n";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// check compiler, OS, etc. using pre-processor macros provided by compiler
|
||||||
|
// see "Pre-defined C/C++ Compiler Macros" http://sourceforge.net/p/predef/wiki/
|
||||||
|
// note that only modern compilers that are known to be used for OCCT are recognized
|
||||||
|
|
||||||
|
// compiler; note that GCC and MSVC are last as other compilers (e.g. Intel) can also define __GNUC__ and _MSC_VER
|
||||||
|
#if defined(__INTEL_COMPILER)
|
||||||
|
di << "Compiler: Intel " << __INTEL_COMPILER << "\n";
|
||||||
|
#elif defined(__BORLANDC__)
|
||||||
|
di << "Compiler: Borland C++ (__BORLANDC__ = " << __BORLANDC__ << ")\n";
|
||||||
|
#elif defined(__clang__)
|
||||||
|
di << "Compiler: Clang " << __clang_major__ << "." << __clang_minor__ << "." << __clang_patchlevel__ << "\n";
|
||||||
|
#elif defined(__SUNPRO_C)
|
||||||
|
di << "Compiler: Sun Studio (__SUNPRO_C = " << __SUNPROC_C << ")\n";
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
di << "Compiler: MS Visual C++ " << (int)(_MSC_VER/100-6) << "." << (int)((_MSC_VER/10)-60-10*(int)(_MSC_VER/100-6)) << " (_MSC_FULL_VER = " << _MSC_FULL_VER << ")\n";
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
di << "Compiler: GCC " << __GNUC__ << "." << __GNUC_MINOR__ << "." << __GNUC_PATCHLEVEL__ << "\n";
|
||||||
|
#else
|
||||||
|
di << "Compiler: unrecognized\n";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Cygwin and MinGW specifics
|
||||||
|
#if defined(__CYGWIN__)
|
||||||
|
di << "Cygwin\n";
|
||||||
|
#endif
|
||||||
|
#if defined(__MINGW64__)
|
||||||
|
di << "MinGW 64 " << __MINGW64_MAJOR_VERSION << "." << __MINGW64_MINOR_VERSION << "\n";
|
||||||
|
#elif defined(__MINGW32__)
|
||||||
|
di << "MinGW 32 " << __MINGW32_MAJOR_VERSION << "." << __MINGW32_MINOR_VERSION << "\n";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// architecture
|
||||||
|
#if defined(__amd64) || defined(__x86_64) || defined(_M_AMD64)
|
||||||
|
di << "Architecture: AMD64\n";
|
||||||
|
#elif defined(__i386) || defined(_M_IX86) || defined(__X86__)|| defined(_X86_)
|
||||||
|
di << "Architecture: Intel x86\n";
|
||||||
|
#elif defined(_M_IA64) || defined(__ia64__)
|
||||||
|
di << "Architecture: Intel Itanium (IA 64)\n";
|
||||||
|
#elif defined(__sparc__) || defined(__sparc)
|
||||||
|
di << "Architecture: SPARC\n";
|
||||||
|
#else
|
||||||
|
di << "Architecture: unrecognized\n";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// OS
|
||||||
|
#if defined(_WIN32) || defined(__WINDOWS__) || defined(__WIN32__)
|
||||||
|
di << "OS: Windows\n";
|
||||||
|
#elif defined(__APPLE__) || defined(__MACH__)
|
||||||
|
di << "OS: Mac OS X\n";
|
||||||
|
#elif defined(__sun)
|
||||||
|
di << "OS: SUN Solaris\n";
|
||||||
|
#elif defined(__ANDROID__) /* must be before Linux */
|
||||||
|
#include <android/api-level.h>
|
||||||
|
di << "OS: Android (__ANDROID_API__ = " << __ANDROID_API__ << ")\n";
|
||||||
|
#elif defined(__linux__)
|
||||||
|
di << "OS: Linux\n";
|
||||||
|
#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
|
||||||
|
#include <sys/param.h>
|
||||||
|
di << "OS: BSD (BSD = " << BSD << ")\n";
|
||||||
|
#else
|
||||||
|
di << "OS: unrecognized\n";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : wait
|
//function : wait
|
||||||
//purpose :
|
//purpose :
|
||||||
@ -570,4 +679,9 @@ void Draw::BasicCommands(Draw_Interpretor& theCommands)
|
|||||||
__FILE__,dlog,g);
|
__FILE__,dlog,g);
|
||||||
theCommands.Add("decho", "switch on / off echo of commands to cout; run without args to get help",
|
theCommands.Add("decho", "switch on / off echo of commands to cout; run without args to get help",
|
||||||
__FILE__,decho,g);
|
__FILE__,decho,g);
|
||||||
|
|
||||||
|
theCommands.Add("dbreak", "raises Tcl exception if user has pressed Control-Break key",
|
||||||
|
__FILE__,dbreak,g);
|
||||||
|
theCommands.Add("dversion", "provides information on OCCT build configuration (version, compiler, OS, C library, etc.)",
|
||||||
|
__FILE__,dversion,g);
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <TCollection_AsciiString.hxx>
|
#include <TCollection_AsciiString.hxx>
|
||||||
#include <TCollection_ExtendedString.hxx>
|
#include <TCollection_ExtendedString.hxx>
|
||||||
#include <OSD_Path.hxx>
|
#include <OSD_Path.hxx>
|
||||||
|
#include <OSD.hxx>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <tcl.h>
|
#include <tcl.h>
|
||||||
@ -206,6 +207,9 @@ static Standard_Integer CommandCmd
|
|||||||
try {
|
try {
|
||||||
OCC_CATCH_SIGNALS
|
OCC_CATCH_SIGNALS
|
||||||
|
|
||||||
|
// get exception if control-break has been pressed
|
||||||
|
OSD::ControlBreak();
|
||||||
|
|
||||||
// OCC63: Convert strings from UTF-8 to local encoding, normally expected by OCC commands
|
// OCC63: Convert strings from UTF-8 to local encoding, normally expected by OCC commands
|
||||||
TclUTFToLocalStringSentry anArgs ( argc, (const char**)argv );
|
TclUTFToLocalStringSentry anArgs ( argc, (const char**)argv );
|
||||||
|
|
||||||
|
@ -296,8 +296,9 @@ proc testgrid {args} {
|
|||||||
|
|
||||||
# log command arguments and environment
|
# log command arguments and environment
|
||||||
set log "Command: testgrid $args\nHost: [info hostname]\nStarted on: [clock format [clock seconds] -format {%Y-%m-%d %H:%M:%S}]\n"
|
set log "Command: testgrid $args\nHost: [info hostname]\nStarted on: [clock format [clock seconds] -format {%Y-%m-%d %H:%M:%S}]\n"
|
||||||
|
catch {set log "$log\nDRAW build:\n[dversion]\n" }
|
||||||
set log "$log\nEnvironment:\n"
|
set log "$log\nEnvironment:\n"
|
||||||
foreach envar [array names env] {
|
foreach envar [lsort [array names env]] {
|
||||||
set log "$log$envar=\"$env($envar)\"\n"
|
set log "$log$envar=\"$env($envar)\"\n"
|
||||||
}
|
}
|
||||||
set log "$log\n"
|
set log "$log\n"
|
||||||
@ -321,7 +322,14 @@ proc testgrid {args} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# start test cases
|
# start test cases
|
||||||
|
set userbreak 0
|
||||||
foreach test_def $tests_list {
|
foreach test_def $tests_list {
|
||||||
|
# check for user break
|
||||||
|
if { "[info commands dbreak]" == "dbreak" && [catch dbreak] } {
|
||||||
|
set userbreak 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
set dir [lindex $test_def 0]
|
set dir [lindex $test_def 0]
|
||||||
set group [lindex $test_def 1]
|
set group [lindex $test_def 1]
|
||||||
set grid [lindex $test_def 2]
|
set grid [lindex $test_def 2]
|
||||||
@ -387,12 +395,17 @@ proc testgrid {args} {
|
|||||||
# get results of started threads
|
# get results of started threads
|
||||||
if { $parallel > 0 } {
|
if { $parallel > 0 } {
|
||||||
catch {tpool::resume $worker}
|
catch {tpool::resume $worker}
|
||||||
while { [llength [array names job_def]] > 0 } {
|
while { ! $userbreak && [llength [array names job_def]] > 0 } {
|
||||||
foreach job [tpool::wait $worker [array names job_def]] {
|
foreach job [tpool::wait $worker [array names job_def]] {
|
||||||
eval _log_test_case \[tpool::get $worker $job\] $job_def($job) log
|
eval _log_test_case \[tpool::get $worker $job\] $job_def($job) log
|
||||||
unset job_def($job)
|
unset job_def($job)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# check for user break
|
||||||
|
if { "[info commands dbreak]" == "dbreak" && [catch dbreak] } {
|
||||||
|
set userbreak 1
|
||||||
|
}
|
||||||
|
|
||||||
# update summary log with requested period
|
# update summary log with requested period
|
||||||
if { $logdir != "" && $refresh > 0 && [clock seconds] > $refresh_timer + $refresh } {
|
if { $logdir != "" && $refresh > 0 && [clock seconds] > $refresh_timer + $refresh } {
|
||||||
_log_summarize $logdir $log
|
_log_summarize $logdir $log
|
||||||
@ -400,12 +413,18 @@ proc testgrid {args} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
# release thread pool
|
# release thread pool
|
||||||
|
tpool::cancel $worker [array names job_def]
|
||||||
tpool::release $worker
|
tpool::release $worker
|
||||||
}
|
}
|
||||||
|
|
||||||
uplevel dchrono _timer stop
|
uplevel dchrono _timer stop
|
||||||
set time [lindex [split [uplevel dchrono _timer show] "\n"] 0]
|
set time [lindex [split [uplevel dchrono _timer show] "\n"] 0]
|
||||||
|
|
||||||
|
if { $userbreak } {
|
||||||
|
puts "*********** Stopped by user break ***********"
|
||||||
|
set time "${time} \nNote: the process is not finished, stopped by user break!"
|
||||||
|
}
|
||||||
|
|
||||||
######################################################
|
######################################################
|
||||||
# output summary logs and exit
|
# output summary logs and exit
|
||||||
######################################################
|
######################################################
|
||||||
@ -1243,7 +1262,8 @@ proc _log_html_summary {logdir log totals regressions improvements total_time} {
|
|||||||
|
|
||||||
# time stamp and elapsed time info
|
# time stamp and elapsed time info
|
||||||
if { $total_time != "" } {
|
if { $total_time != "" } {
|
||||||
puts $fd "<p>Generated on [clock format [clock seconds] -format {%Y-%m-%d %H:%M:%S}] on [info hostname] <p> $total_time"
|
puts $fd "<p>Generated on [clock format [clock seconds] -format {%Y-%m-%d %H:%M:%S}] on [info hostname]\n<p>"
|
||||||
|
puts $fd [join [split $total_time "\n"] "<p>"]
|
||||||
} else {
|
} else {
|
||||||
puts $fd "<p>NOTE: This is intermediate summary; the tests are still running! This page will refresh automatically until tests are finished."
|
puts $fd "<p>NOTE: This is intermediate summary; the tests are still running! This page will refresh automatically until tests are finished."
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <OSD_SIGBUS.hxx>
|
#include <OSD_SIGBUS.hxx>
|
||||||
#include <OSD_SIGSEGV.hxx>
|
#include <OSD_SIGSEGV.hxx>
|
||||||
#include <OSD_SIGSYS.hxx>
|
#include <OSD_SIGSYS.hxx>
|
||||||
|
#include <OSD_Exception_CTRL_BREAK.hxx>
|
||||||
#include <Standard_NumericError.hxx>
|
#include <Standard_NumericError.hxx>
|
||||||
#include <Standard_NullObject.hxx>
|
#include <Standard_NullObject.hxx>
|
||||||
#include <Standard_DivideByZero.hxx>
|
#include <Standard_DivideByZero.hxx>
|
||||||
@ -62,6 +63,9 @@ static pthread_t getOCCThread () {
|
|||||||
static Standard_Boolean fFltExceptions = Standard_False;
|
static Standard_Boolean fFltExceptions = Standard_False;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// variable signalling that Control-C has been pressed (SIGINT signal)
|
||||||
|
static Standard_Boolean fCtrlBrk;
|
||||||
|
|
||||||
//const OSD_WhoAmI Iam = OSD_WPackage;
|
//const OSD_WhoAmI Iam = OSD_WPackage;
|
||||||
|
|
||||||
typedef void (ACT_SIGIO_HANDLER)(void) ;
|
typedef void (ACT_SIGIO_HANDLER)(void) ;
|
||||||
@ -486,8 +490,11 @@ void OSD::Handler(const OSD_Signals theSignal,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
OSD_SIGINT::NewInstance("SIGINT 'interrupt' detected.")->Jump();
|
// For safe handling of Control-C as stop event, arm a variable but do not
|
||||||
exit(SIGINT);
|
// generate longjump (we are out of context anyway)
|
||||||
|
fCtrlBrk = Standard_True;
|
||||||
|
// OSD_SIGINT::NewInstance("SIGINT 'interrupt' detected.")->Jump();
|
||||||
|
// exit(SIGINT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIGQUIT:
|
case SIGQUIT:
|
||||||
@ -578,6 +585,18 @@ void OSD::Handler(const OSD_Signals theSignal,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//==== ControlBreak
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
void OSD :: ControlBreak ()
|
||||||
|
{
|
||||||
|
if ( fCtrlBrk ) {
|
||||||
|
fCtrlBrk = Standard_False;
|
||||||
|
OSD_Exception_CTRL_BREAK::Raise ("*** INTERRUPT ***");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//==== SegvHandler
|
//==== SegvHandler
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
Loading…
x
Reference in New Issue
Block a user