diff options
author | Thomas Benisch <tbe@openoffice.org> | 2010-03-01 12:22:02 +0100 |
---|---|---|
committer | Thomas Benisch <tbe@openoffice.org> | 2010-03-01 12:22:02 +0100 |
commit | 4f4ce41e44919b7e201f854e52cc004c3858856d (patch) | |
tree | 14b7a6003953848bae2c065e32b16fd7106ea504 /testshl2/source/cppunit/result | |
parent | 247c018e0c1fae644f52fae087f4f3906e1f529a (diff) | |
parent | bbfe7e2867795f697920d2d7055037e202d2169d (diff) |
chartshapes: merge with DEV300_m72
Diffstat (limited to 'testshl2/source/cppunit/result')
-rw-r--r-- | testshl2/source/cppunit/result/SynchronizedObject.cpp | 38 | ||||
-rw-r--r-- | testshl2/source/cppunit/result/TestResult.cpp | 264 | ||||
-rw-r--r-- | testshl2/source/cppunit/result/TestResultCollector.cpp | 150 | ||||
-rw-r--r-- | testshl2/source/cppunit/result/TestSucessListener.cpp | 50 | ||||
-rw-r--r-- | testshl2/source/cppunit/result/TextTestResult.cpp | 194 | ||||
-rw-r--r-- | testshl2/source/cppunit/result/emacsTestResult.cxx | 190 | ||||
-rw-r--r-- | testshl2/source/cppunit/result/log.cxx | 122 | ||||
-rw-r--r-- | testshl2/source/cppunit/result/makefile.mk | 79 | ||||
-rw-r--r-- | testshl2/source/cppunit/result/optionhelper.cxx | 314 | ||||
-rw-r--r-- | testshl2/source/cppunit/result/outputter.cxx | 103 | ||||
-rw-r--r-- | testshl2/source/cppunit/result/signal.cxx | 996 | ||||
-rw-r--r-- | testshl2/source/cppunit/result/signal.hxx | 39 | ||||
-rw-r--r-- | testshl2/source/cppunit/result/testshlTestResult.cxx | 425 | ||||
-rw-r--r-- | testshl2/source/cppunit/result/treswrapper.cxx | 259 |
14 files changed, 3223 insertions, 0 deletions
diff --git a/testshl2/source/cppunit/result/SynchronizedObject.cpp b/testshl2/source/cppunit/result/SynchronizedObject.cpp new file mode 100644 index 000000000000..73de43b8c543 --- /dev/null +++ b/testshl2/source/cppunit/result/SynchronizedObject.cpp @@ -0,0 +1,38 @@ +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_testshl2.hxx" + +#include <cppunit/SynchronizedObject.h> + + +namespace CppUnit +{ + + + + +SynchronizedObject::SynchronizedObject( SynchronizationObject *syncObject ) + : m_syncObject( syncObject == 0 ? new SynchronizationObject() : + syncObject ) +{ +} + + +SynchronizedObject::~SynchronizedObject() +{ + delete m_syncObject; +} + + +/** Accept a new synchronization object for protection of this instance + * TestResult assumes ownership of the object + */ +void +SynchronizedObject::setSynchronizationObject( SynchronizationObject *syncObject ) +{ + delete m_syncObject; + m_syncObject = syncObject; +} + + +} // namespace CppUnit + diff --git a/testshl2/source/cppunit/result/TestResult.cpp b/testshl2/source/cppunit/result/TestResult.cpp new file mode 100644 index 000000000000..5fa5e444e540 --- /dev/null +++ b/testshl2/source/cppunit/result/TestResult.cpp @@ -0,0 +1,264 @@ +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_testshl2.hxx" + +#include <cppunit/TestFailure.h> +#include <testshl/result/TestListener.h> +#include "testshl/getopt.hxx" +#include <testshl/result/TestResult.h> +#include <algorithm> +#include "testshl/result/outputter.hxx" +#include <cppunit/Test.h> +#include <testshl/cmdlinebits.hxx> + +namespace CppUnit { + +/// Construct a TestResult +TestResult::TestResult( GetOpt &_pOptions, SynchronizationObject *syncObject ) + : SynchronizedObject( syncObject ), + m_aOptionHelper(_pOptions), + m_nExitValue(0) +{ + reset(); +} + + +/// Destroys a test result +TestResult::~TestResult() +{ +} + + +/** Resets the result for a new run. + * + * Clear the previous run result. + */ +void +TestResult::reset() +{ + ExclusiveZone zone( m_syncObject ); + m_stop = false; +} + + +/** Adds an error to the list of errors. + * The passed in exception + * caused the error + */ +void +TestResult::addError( Test *test, + Exception *e, ErrorType::num _eType ) +{ + TestFailure aTestFailure( test, e, _eType ); + addFailure( aTestFailure ); +} + + +/** Adds a failure to the list of failures. The passed in exception + * caused the failure. + */ +void +TestResult::addFailure( Test *test, Exception *e ) +{ + TestFailure aTestFailure( test, e, ErrorType::ET_FAILURE ); + addFailure( aTestFailure ); +} + + +/** Called to add a failure to the list of failures. + */ +void +TestResult::addFailure( const TestFailure &failure ) +{ + ExclusiveZone zone( m_syncObject ); + + // LLA: + // this set the global returnvalue, due to the fact, there occurs a failure, we have to return a non zero value + // at the moment this seams to be a good place. + setExitValue(1); + + for ( TestListeners::iterator it = m_listeners.begin(); + it != m_listeners.end(); + ++it ) + { + TestListener *pListener = *it; + pListener->addFailure( failure ); + } +} + + +/// Informs the result that a test will be started. +void +TestResult::startTest( Test *test ) +{ + ExclusiveZone zone( m_syncObject ); + if (m_aOptionHelper.isVerbose()) + { + std::string aStr; + if (test) + { + aStr = getNodeName(); + aStr += "."; + aStr += test->getName(); + } + // fprintf(stderr, "Start test: %s\n", aStr.c_str()); + t_print( T_VERBOSE, "Start test: %s\n", aStr.c_str()); + } + + for ( TestListeners::iterator it = m_listeners.begin(); + it != m_listeners.end(); + ++it ) + { + TestListener *pListener = *it; + pListener->startTest( test ); + } +} + + +/// Informs the result that a test was completed. +void +TestResult::endTest( Test *test ) +{ + ExclusiveZone zone( m_syncObject ); + for ( TestListeners::iterator it = m_listeners.begin(); + it != m_listeners.end(); + ++it ) + { + TestListener *pListener = *it; + pListener->endTest( test ); + } +} + + +/// Returns whether testing should be stopped +bool +TestResult::shouldStop() const +{ + ExclusiveZone zone( m_syncObject ); + return m_stop; +} + + +/// Stop testing +void +TestResult::stop() +{ + ExclusiveZone zone( m_syncObject ); + m_stop = true; +} + + +void +TestResult::addListener( TestListener *listener ) +{ + ExclusiveZone zone( m_syncObject ); + m_listeners.push_back( listener ); +} + + +void +TestResult::removeListener ( TestListener *listener ) +{ + ExclusiveZone zone( m_syncObject ); +#if defined(_MSC_VER) && (_MSC_VER >=1400) + m_listeners.erase( remove( m_listeners.begin(), +#else + m_listeners.erase( std::remove( m_listeners.begin(), +#endif + m_listeners.end(), + listener ), + m_listeners.end()); +} + +void +TestResult::addInfo(Test *test, const char* _aStr) +{ + ExclusiveZone zone( m_syncObject ); + for ( TestListeners::iterator it = m_listeners.begin(); + it != m_listeners.end(); + ++it ) + { + TestListener *pListener = *it; + pListener->addInfo( test, _aStr ); + } +} + +// old: void +// old: TestResult::enterNode(const char* _aStr) +// old: { +// old: ExclusiveZone zone( m_syncObject ); +// old: for ( TestListeners::iterator it = m_listeners.begin(); +// old: it != m_listeners.end(); +// old: ++it ) +// old: { +// old: TestListener *pListener = *it; +// old: pListener->enterNode( _aStr ); +// old: } +// old: } +// old: +// old: void +// old: TestResult::leaveNode(const char* _aStr) +// old: { +// old: ExclusiveZone zone( m_syncObject ); +// old: +// old: for ( TestListeners::iterator it = m_listeners.begin(); +// old: it != m_listeners.end(); +// old: ++it ) +// old: { +// old: TestListener *pListener = *it; +// old: pListener->leaveNode( _aStr ); +// old: } +// old: } + +void TestResult::enterNode(const char* _sNode) +{ + ExclusiveZone zone( m_syncObject ); + m_aCurrentNodeNames.push_back(std::string(_sNode)); +} + +void TestResult::leaveNode(const char* /*_sNode*/) +{ + ExclusiveZone zone( m_syncObject ); + std::string sBack = m_aCurrentNodeNames.back(); + m_aCurrentNodeNames.pop_back(); + + // due to a -Wall warning, comment out. + // if (sBack != std::string(_sNode)) + // { + // volatile int dummy = 0; + // // problem?! + // } +} + +std::string TestResult::getNodeName() +{ + std::string sName; + for (std::vector<std::string>::const_iterator it = m_aCurrentNodeNames.begin(); + it != m_aCurrentNodeNames.end(); + ++it) + { + if (sName.size() != 0) + { + sName += "."; + } + sName += *it; + } + return sName; +} + +// ----------------------------------------------------------------------------- +bool TestResult::isAllowedToExecute(std::string const& _sName) +{ + return m_aOptionHelper.isAllowedToExecute(getNodeName(), _sName); +} +// ----------------------------------------------------------------------------- +bool TestResult::isOptionWhereAmI() +{ + return m_aOptionHelper.isOptionWhereAmI(); +} + +// ----------------------------------------------------------------------------- +void TestResult::print(Outputter&) +{ +} + +} // namespace CppUnit diff --git a/testshl2/source/cppunit/result/TestResultCollector.cpp b/testshl2/source/cppunit/result/TestResultCollector.cpp new file mode 100644 index 000000000000..e3913219b541 --- /dev/null +++ b/testshl2/source/cppunit/result/TestResultCollector.cpp @@ -0,0 +1,150 @@ +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_testshl2.hxx" + +#include <cppunit/TestFailure.h> +#include <testshl/result/TestResultCollector.h> + + +namespace CppUnit +{ + + +TestResultCollector::TestResultCollector( TestResult* _pResult, SynchronizationObject *syncObject ) + : TestSucessListener( syncObject ), + m_pResult(_pResult), + m_testErrors(0) +{ + reset(); +} + + +TestResultCollector::~TestResultCollector() +{ + TestFailures::iterator itFailure = m_failures.begin(); + while ( itFailure != m_failures.end() ) + { + TestFailureEnvelope *pEnvelope = *itFailure++; + TestFailure *pFailure = pEnvelope->getTestFailure(); + delete pFailure; + } +} + + +void +TestResultCollector::reset() +{ + TestSucessListener::reset(); + + ExclusiveZone zone( m_syncObject ); + m_testErrors = 0; + m_tests.clear(); + m_failures.clear(); +} + + +void +TestResultCollector::startTest( Test *test ) +{ + ExclusiveZone zone (m_syncObject); + + m_tests.push_back( new TestEnvelope(test, m_pResult->getNodeName()) ); +} + +void +TestResultCollector::endTest( Test * ) +{ + // ExclusiveZone zone (m_syncObject); + // Nothing! +} + + +void +TestResultCollector::addFailure( const TestFailure &failure ) +{ + TestSucessListener::addFailure( failure ); + + ExclusiveZone zone( m_syncObject ); + if ( failure.isError() ) + ++m_testErrors; + m_failures.push_back( new TestFailureEnvelope(failure.clone(), m_pResult->getNodeName()) ); +} + + +/// Gets the number of run tests. +int +TestResultCollector::runTests() const +{ + ExclusiveZone zone( m_syncObject ); + return m_tests.size(); +} + + +/// Gets the number of detected errors (uncaught exception). +int +TestResultCollector::testErrors() const +{ + ExclusiveZone zone( m_syncObject ); + return m_testErrors; +} + + +/// Gets the number of detected failures (failed assertion). +int +TestResultCollector::testFailures() const +{ + ExclusiveZone zone( m_syncObject ); + return m_failures.size() - m_testErrors; +} + + +/// Gets the total number of detected failures. +int +TestResultCollector::testFailuresTotal() const +{ + ExclusiveZone zone( m_syncObject ); + return m_failures.size(); +} + + +/// Returns a the list failures (random access collection). +const TestResultCollector::TestFailures & +TestResultCollector::failures() const +{ + ExclusiveZone zone( m_syncObject ); + return m_failures; +} + + +const TestResultCollector::Tests & +TestResultCollector::tests() const +{ + ExclusiveZone zone( m_syncObject ); + return m_tests; +} + +void TestResultCollector::addInfo(Test *_pTest, const char* _sInfo) +{ + ExclusiveZone zone( m_syncObject ); + m_aInfos.push_back(new TestInfo(_pTest, _sInfo)); +} + +std::string TestResultCollector::getInfo(Test *_pTest) +{ + for (TestInfos::const_iterator it = m_aInfos.begin(); + it != m_aInfos.end(); + ++it) + { + TestInfo *pInfo = *it; + Test *pTest = pInfo->getTest(); + if (pTest == _pTest) + { + std::string sInfo = pInfo->getString(); + return sInfo; + } + } + return std::string(); +} + + +} // namespace CppUnit + diff --git a/testshl2/source/cppunit/result/TestSucessListener.cpp b/testshl2/source/cppunit/result/TestSucessListener.cpp new file mode 100644 index 000000000000..d8f8268f09aa --- /dev/null +++ b/testshl2/source/cppunit/result/TestSucessListener.cpp @@ -0,0 +1,50 @@ +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_testshl2.hxx" + + +#include <testshl/result/TestSucessListener.h> + + + +namespace CppUnit +{ + + +TestSucessListener::TestSucessListener( SynchronizationObject *syncObject ) + : SynchronizedObject( syncObject ) + , m_sucess( true ) +{ +} + + +TestSucessListener::~TestSucessListener() +{ +} + + +void +TestSucessListener::reset() +{ + ExclusiveZone zone( m_syncObject ); + m_sucess = true; +} + + +void +TestSucessListener::addFailure( const TestFailure & ) +{ + ExclusiveZone zone( m_syncObject ); + m_sucess = false; +} + + +bool +TestSucessListener::wasSuccessful() const +{ + ExclusiveZone zone( m_syncObject ); + return m_sucess; +} + + +} // namespace CppUnit + diff --git a/testshl2/source/cppunit/result/TextTestResult.cpp b/testshl2/source/cppunit/result/TextTestResult.cpp new file mode 100644 index 000000000000..2ad271ded7de --- /dev/null +++ b/testshl2/source/cppunit/result/TextTestResult.cpp @@ -0,0 +1,194 @@ +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_testshl2.hxx" + +#include <cppunit/Exception.h> +#include <cppunit/NotEqualException.h> +#include <cppunit/Test.h> +#include <cppunit/TestFailure.h> +#include <testshl/result/TextTestResult.h> +// #include <TextTestResult.h> +//!io #include <iostream> + +namespace CppUnit { + + +TextTestResult::TextTestResult(GetOpt& _aOptions) + :TestResult(_aOptions), + m_aResulter(this) +{ + addListener( &m_aResulter ); +} + + +void +TextTestResult::addFailure( const TestFailure &failure ) +{ + TestResult::addFailure( failure ); + // std::cerr << ( failure.isError() ? "E" : "F" ); + if (failure.isError()) + fprintf(stderr, "E"); + else + fprintf(stderr, "F"); +} + + +void +TextTestResult::startTest( Test *test ) +{ + TestResult::startTest (test); + // std::cerr << "."; + fprintf(stderr, "."); +} + +void TextTestResult::endTest( Test *test ) +{ + TestResult::endTest (test); +} + + +void +TextTestResult::printFailures( std::ostream &stream ) +{ + TestResultCollector::TestFailures::const_iterator itFailure = m_aResulter.failures().begin(); + int failureNumber = 1; + while ( itFailure != m_aResulter.failures().end() ) + { + stream << std::endl; + TestFailure *pFailure= (*itFailure++)->getTestFailure(); + printFailure( pFailure, failureNumber++, stream ); + } +} + + +void +TextTestResult::printFailure( TestFailure *failure, + int failureNumber, + std::ostream &stream ) +{ + printFailureListMark( failureNumber, stream ); + stream << ' '; + printFailureTestName( failure, stream ); + stream << ' '; + printFailureType( failure, stream ); + stream << ' '; + printFailureLocation( failure->sourceLine(), stream ); + stream << std::endl; + printFailureDetail( failure->thrownException(), stream ); + stream << std::endl; +} + + +void +TextTestResult::printFailureListMark( int failureNumber, + std::ostream &stream ) +{ + stream << failureNumber << ")"; +} + + +void +TextTestResult::printFailureTestName( TestFailure *failure, + std::ostream &stream ) +{ + Test* pTest = failure->failedTest(); + stream << "test: " << pTest->getName(); +} + + +void +TextTestResult::printFailureType( TestFailure *failure, + std::ostream &stream ) +{ + stream << "(" + << (failure->isError() ? "E" : "F") + << ")"; +} + + +void +TextTestResult::printFailureLocation( SourceLine sourceLine, + std::ostream &stream ) +{ + if ( !sourceLine.isValid() ) + return; + + stream << "line: " << sourceLine.lineNumber() + << ' ' << sourceLine.fileName(); +} + + +void +TextTestResult::printFailureDetail( Exception *thrownException, + std::ostream &stream ) +{ + if ( thrownException->isInstanceOf( NotEqualException::type() ) ) + { + NotEqualException *e = (NotEqualException*)thrownException; + stream << "expected: " << e->expectedValue() << std::endl + << "but was: " << e->actualValue(); + if ( !e->additionalMessage().empty() ) + { + stream << std::endl; + stream << "additional message:" << std::endl + << e->additionalMessage(); + } + } + else + { + stream << " \"" << thrownException->what() << "\""; + } +} + + +void +TextTestResult::print( std::ostream& stream ) +{ + printHeader( stream ); + stream << std::endl; + printFailures( stream ); +} + + +void +TextTestResult::printHeader( std::ostream &stream ) +{ + if (m_aResulter.wasSuccessful ()) + stream << std::endl << "OK (" << m_aResulter.runTests () << " tests)" + << std::endl; + else + { + stream << std::endl; + printFailureWarning( stream ); + printStatistics( stream ); + } +} + + +void +TextTestResult::printFailureWarning( std::ostream &stream ) +{ + stream << "!!!FAILURES!!!" << std::endl; +} + + +void +TextTestResult::printStatistics( std::ostream &stream ) +{ + stream << "Test Results:" << std::endl; + + stream << "Run: " << m_aResulter.runTests() + << " Failures: " << m_aResulter.testFailures() + << " Errors: " << m_aResulter.testErrors() + << std::endl; +} + + +std::ostream & +operator <<( std::ostream &stream, + TextTestResult &result ) +{ + result.print (stream); return stream; +} + + +} // namespace CppUnit diff --git a/testshl2/source/cppunit/result/emacsTestResult.cxx b/testshl2/source/cppunit/result/emacsTestResult.cxx new file mode 100644 index 000000000000..4a4d57b6cee6 --- /dev/null +++ b/testshl2/source/cppunit/result/emacsTestResult.cxx @@ -0,0 +1,190 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_testshl2.hxx" + +#include <stdlib.h> + +#include <map> +#include <cppunit/Exception.h> +#include <cppunit/NotEqualException.h> +#include <cppunit/Test.h> +#include <cppunit/TestFailure.h> +#include <testshl/result/emacsTestResult.hxx> +// #include <TextTestResult.h> +//!io #include <iostream> +#include <string> + +#include <rtl/string.hxx> +#include "testshl/result/outputter.hxx" + +namespace CppUnit { + + emacsTestResult::emacsTestResult(GetOpt & _aOptions) + :TestResult(_aOptions), + m_aOptions(_aOptions), + m_aResulter(this) + { + addListener( &m_aResulter ); + } + + //# struct ltstr + //# { + //# bool operator()(const CppUnit::Test* p1, const CppUnit::Test* p2) const + //# { + //# return p1 < p2; + //# } + //# }; + //# typedef std::map<CppUnit::Test*, bool, ltstr> TestPtrList; + + void + emacsTestResult::print( Outputter& stream ) + { + printHeader( stream ); + // stream << std::endl; + // printFailures( stream ); + + // TestPtrList aFailedTests; + + for (TestResultCollector::TestFailures::const_iterator it2 = m_aResulter.failures().begin(); + it2 != m_aResulter.failures().end(); + ++it2) + { + TestFailureEnvelope *pEnvelop = *it2; + TestFailure *pFailure = pEnvelop->getTestFailure(); + std::string sNodeName = pEnvelop->getString(); + + // aFailedTests[ pFailure->failedTest() ] = true; + + printFailureLine(stream, pFailure, sNodeName); + } + + // only errors are from interest here + //# for (TestResultCollector::Tests::const_iterator it = m_aResulter.tests().begin(); + //# it != m_aResulter.tests().end(); + //# ++it) + //# { + //# TestEnvelope *pEnvelop = *it; + //# Test* pTest = pEnvelop->getTest(); + //# std::string sNodeName = pEnvelop->getString(); + //# + //# if (aFailedTests.find(pTest) == aFailedTests.end()) + //# { + //# std::string sInfo = m_aResulter.getInfo(pTest); + //# printTestLine(stream, pTest, sNodeName, sInfo); + //# } + //# } + stream << "Test #PASSED#" << Outputter::endl(); + } + + + void + emacsTestResult::printHeader( Outputter &stream ) + { + std::string sDate(m_aOptionHelper.createDateTag()); + stream << sDate << Outputter::endl(); + } + + void + emacsTestResult::printFailureLine( Outputter &stream, TestFailure *_pFailure, std::string const& _sNodeName) + { + std::string aName; + aName += _sNodeName; + aName += "."; + aName += _pFailure->failedTestName(); + + SourceLine aLine = _pFailure->sourceLine(); + sal_Int32 nLine = -1; + std::string sFilename; + if (aLine.isValid()) + { + nLine = aLine.lineNumber(); + sFilename = aLine.fileName(); + } + + Exception *pExp = _pFailure->thrownException(); + std::string sWhat; + if (pExp) + { + sWhat = pExp->what(); + } + + stream << sFilename; + stream << ":"; + stream << nLine; + stream << ":"; + + stream << aName; + stream << ";#FAILED#"; + // ErrorType::num eErr = _pFailure->getErrorType(); + //# if (isErr) + //# stream << "FAILED#;"; + //# else + //# stream << "ERROR#;"; + + stream << sWhat; + stream << Outputter::endl(); + } + + //# void + //# emacsTestResult::printTestLine( Outputter &stream, Test* _pTest, std::string const& _sNodeName, std::string const& _sInfo) + //# { + //# std::string aName; + //# aName += _sNodeName; + //# aName += "."; + //# aName += _pTest->getName(); + //# + //# stream << aName; + //# stream << ";"; + //# stream << _sInfo << "#"; + //# stream << "OK#"; + //# stream << std::endl; + //# } + + +//# void +//# emacsTestResult::printStatistics( Outputter &stream ) +//# { +//# stream << "Test Results:" << std::endl; +//# +//# stream << "Run: " << runTests() +//# << " Failures: " << testFailures() +//# << " Errors: " << testErrors() +//# << std::endl; +//# } + + + Outputter & + operator <<( Outputter &stream, + emacsTestResult &result ) + { + result.print (stream); return stream; + } + + +} // namespace CppUnit diff --git a/testshl2/source/cppunit/result/log.cxx b/testshl2/source/cppunit/result/log.cxx new file mode 100644 index 000000000000..3279d1b2091e --- /dev/null +++ b/testshl2/source/cppunit/result/log.cxx @@ -0,0 +1,122 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_testshl2.hxx" + +#include "testshl/log.hxx" + +// #include <hash_map> +// #include <list> +// #include <set> + +using namespace std; + +::osl::FileBase::RC Log::open( sal_Bool append ) { + + ::osl::FileBase::RC ret; + + if ( ! append ) { + ret = ::osl::File::remove( m_logurl ); + } + + if( m_logfile->open( OpenFlag_Write ) == ::osl::FileBase::E_NOENT ) { + ret = m_logfile->open( OpenFlag_Write | OpenFlag_Create ); + } + else { + ret = m_logfile->setPos( Pos_End, 0 ); + } + return ret; +} + +::osl::FileBase::RC Log::write( const sal_Char* buf, sal_Bool v ) { + sal_uInt64 uBytes=0; + sal_uInt32 len = 0; + const sal_Char* ptr = buf; + + if( ptr ) { + while( *ptr++ ) len++; + } + + if ( v ) { + // cout << buf << flush; + printf("%s", buf); + } + return m_logfile->write( buf, len , uBytes ); +} + +::osl::FileBase::RC Log::write( const rtl::OString& buf, sal_Bool v ) { + sal_uInt64 uBytes=0; + if ( v ) { + // cout << buf.getStr() << flush; + printf("%s", buf.getStr()); + } + return m_logfile->write( buf.getStr(), buf.getLength(), uBytes ); +} +/* +// LLA: due to a problem with sal/OUStingBuffer getLength() which isn't const, this +// is so not compilable. +::osl::FileBase::RC Log::write( rtl::OStringBuffer const& buf, sal_Bool v ) { + sal_uInt64 uBytes=0; + if ( v ) { + cout << buf.getStr() << flush; + } + return m_logfile->write( buf.getStr(), buf.getLength(), uBytes ); +} +*/ +::osl::FileBase::RC Log::write( const rtl::OUString& buf, + rtl_TextEncoding tenc, sal_Bool v ) { + sal_uInt64 uBytes=0; + if ( ! tenc ) { + tenc = RTL_TEXTENCODING_ASCII_US; + } + rtl::OStringBuffer osbuf( + rtl::OUStringToOString( buf, tenc ).getStr() ); + + if ( v ) { + // cout << osbuf.getStr() << flush; + printf("%s", osbuf.getStr()); + } + return m_logfile->write( osbuf.getStr(), osbuf.getLength(), uBytes ); +} + +Log &operator <<( Log &_aLog, const sal_Char * _sValue ) +{ + _aLog.write(_sValue); return _aLog; +} +Log &operator <<( Log &_aLog, rtl::OString const& _sValue ) +{ + _aLog.write(_sValue); return _aLog; +} +Log &operator <<( Log &_aLog, rtl::OUString const& _sValue ) +{ + _aLog.write(_sValue); return _aLog; +} +//! Log &operator <<( Log &_aLog, rtl::OStringBuffer const& _sValue ) +//! { +//! _aLog.write(_sValue); return _aLog; +//! } diff --git a/testshl2/source/cppunit/result/makefile.mk b/testshl2/source/cppunit/result/makefile.mk new file mode 100644 index 000000000000..59ff333726db --- /dev/null +++ b/testshl2/source/cppunit/result/makefile.mk @@ -0,0 +1,79 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=testshl2 +TARGET=c5t_testresult +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE +# ENABLE_RTTI=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +# CXXFILES = \ +# querytemplate.cxx \ +# stringhelper.cxx + +# ENVCFLAGSCXX+=-DCPPUNIT_BUILD_DLL +SLOFILES = \ + $(SLO)$/SynchronizedObject.obj \ + $(SLO)$/TestResult.obj \ + $(SLO)$/TestResultCollector.obj \ + $(SLO)$/TestSucessListener.obj \ + $(SLO)$/emacsTestResult.obj \ + $(SLO)$/log.obj \ + $(SLO)$/optionhelper.obj \ + $(SLO)$/outputter.obj \ + $(SLO)$/signal.obj \ + $(SLO)$/testshlTestResult.obj \ + $(SLO)$/treswrapper.obj + +# currently unused +# $(SLO)$/TextTestResult.obj + +LIB1TARGET= $(LB)$/$(TARGET).lib +LIB1OBJFILES= $(SLOFILES) + +.IF "$(GUI)"=="WNT" +.IF "$(COM)"=="GCC" +LIB1ARCHIV=$(LB)$/lib$(TARGET)$(DLLPOSTFIX).a +.ENDIF +.ENDIF + +.IF "$(GUI)" == "UNX" +LIB1ARCHIV=$(LB)$/lib$(TARGET)$(DLLPOSTFIX).a +.ENDIF + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/testshl2/source/cppunit/result/optionhelper.cxx b/testshl2/source/cppunit/result/optionhelper.cxx new file mode 100644 index 000000000000..90096c8957e7 --- /dev/null +++ b/testshl2/source/cppunit/result/optionhelper.cxx @@ -0,0 +1,314 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_testshl2.hxx" + +#include "testshl/result/optionhelper.hxx" +// #include <sstream> +// #include <string> +#include <osl/time.h> +#include "testshl/cmdlinebits.hxx" + +// ----------------------------------------------------------------------------- + +namespace +{ + void split( const rtl::OString& opt, + const rtl::OString& _sSeparator, + OStringList& optLine ) + { + optLine.clear(); + // const sal_Int32 cSetLen = cSet.getLength(); + sal_Int32 index = 0; + sal_Int32 oldIndex = 0; + + // sal_Int32 i; + // sal_Int32 j = 0; + while ( opt.getLength() > 0) + { + // for ( i = 0; i < cSetLen; i++ ) + // { + index = opt.indexOf( _sSeparator, oldIndex); + if( index != -1 ) + { + optLine.push_back( opt.copy( oldIndex, index - oldIndex ) ); + oldIndex = index + _sSeparator.getLength(); + } + // } + else // if (index == -1) + { + optLine.push_back( opt.copy( oldIndex ) ); + break; + } + } + } ///< split + + bool match(OStringList const& _aFilter, OStringList const& _aName) + { + OStringList::const_iterator aFilterIter = _aFilter.begin(); + OStringList::const_iterator aValueIter = _aName.begin(); + + bool bMatch = false; + + while (aFilterIter != _aFilter.end() && aValueIter != _aName.end()) + { + rtl::OString sFilter = *aFilterIter; + rtl::OString sName = *aValueIter; + + if (sFilter == sName) + { + bMatch = true; + ++aFilterIter; + ++aValueIter; + } + else if (sFilter == "*") + { + bMatch = true; + break; + } + else + { + // Filter does not match + bMatch = false; + break; + } + } + return bMatch; + } +} + +/* static */ +std::string OptionHelper::integerToAscii(sal_Int32 nValue) +{ + sal_Char cBuf[30]; + sal_Char *pBuf = cBuf; + sprintf(pBuf, "%d", static_cast<int>(nValue)); +//# std::ostringstream sBuf; +//# sBuf << nValue; +// rtl::OString sStr; +// sStr = rtl::OString::valueOf(nValue); + return std::string(pBuf); +} + +/* static */ +// if a given String is less then 2 char, add a "0" in front. +std::string OptionHelper::twoDigits(std::string const& _sValue) +{ + std::string sBack; + if (_sValue.length() == 0) + { + sBack = "00"; + } + else if (_sValue.length() == 1) + { + sBack = "0"; + sBack += _sValue; + } + else + { + sBack = _sValue; + } + return sBack; +} + + +std::string OptionHelper::createDateTag(std::string const& _sProjectId, std::string const& _sBuildId) +{ + TimeValue tmv_system; + TimeValue tmv_local; + oslDateTime dt; + osl_getSystemTime( &tmv_system ); + osl_getLocalTimeFromSystemTime(&tmv_system, &tmv_local); + osl_getDateTimeFromTimeValue( &tmv_local, &dt ); + + sal_Int32 nYear = dt.Year; + sal_Int32 nMonth = dt.Month; + sal_Int32 nDay = dt.Day; + + std::string sDate; + sDate = "# Current Time: "; + sDate += std::string(twoDigits(integerToAscii(dt.Hours))); + sDate += ":"; + sDate += std::string(twoDigits(integerToAscii(dt.Minutes))); + sDate += ":"; + sDate += std::string(twoDigits(integerToAscii(dt.Seconds))); + sDate += "\n"; + + sDate += "["; + + // sDate += rtl::OString::valueOf(nYear); + sDate.append(integerToAscii(nYear)); + sDate += "."; + if (nMonth < 10) + sDate += "0"; + // sDate += rtl::OString::valueOf(nMonth); + sDate.append(integerToAscii(nMonth)); + sDate += "."; + if (nDay < 10) + sDate += "0"; + // sDate += rtl::OString::valueOf(nDay); + sDate += std::string(integerToAscii(nDay)); + sDate += "/"; + sDate += _sProjectId; + sDate += "/"; + sDate += _sBuildId; + sDate += "]"; + + return sDate; +} + +//# rtl::OString createDateTag() +//# { +//# TimeValue tmv; +//# oslDateTime dt; +//# osl_getSystemTime( &tmv ); +//# osl_getDateTimeFromTimeValue( &tmv, &dt ); +//# +//# sal_Int32 nYear = dt.Year; +//# sal_Int32 nMonth = dt.Month; +//# sal_Int32 nDay = dt.Day; +//# +//# rtl::OString sDate("["); +//# sDate += rtl::OString::valueOf(nYear); +//# sDate += "."; +//# if (nMonth < 10) +//# sDate += "0"; +//# sDate += rtl::OString::valueOf(nMonth); +//# sDate += "."; +//# if (nDay < 10) +//# sDate += "0"; +//# sDate += rtl::OString::valueOf(nDay); +//# sDate += "//]"; +//# +//# return sDate; +//# } + +std::string OptionHelper::createDateTag() +{ + return createDateTag(m_sProjectId, m_sBuildId); +} + +bool OptionHelper::showErrors() +{ + bool bRetValue = true; // default, show all + if (m_aOption.hasOpt("-noerrors")) + { + bRetValue = false; + } + return bRetValue; +} + +bool OptionHelper::showTests() +{ + bool bRetValue = true; // default, show all + if (m_aOption.hasOpt("-onlyerrors")) + { + bRetValue = false; + } + return bRetValue; +} + +// Check which parameter is given for handle the jobs. +// If no parameter is given, all jobs (tests) will run through +void OptionHelper::handleJobs() +{ + // load job file, the file contains the functions which we only want to test. + if (m_aOption.hasOpt("-jobexclude")) + { + rtl::OString sJobFile = m_aOption.getOpt("-jobexclude"); + m_aJobExcludeList.readfile(sJobFile.getStr(), JOB_EXCLUDE_LIST); + } + + if (m_aOption.hasOpt("-jobonly")) + { + rtl::OString sJobFile = m_aOption.getOpt("-jobonly"); + m_aJobOnlyList.readfile(sJobFile.getStr(), JOB_ONLY_LIST); + } + + // + if (m_aOption.hasOpt("-jobfilter")) + { + rtl::OString sJobFilter = m_aOption.getOpt("-jobfilter"); + split(sJobFilter, ".", m_aJobFilter); + } +} + +// ----------------------------------------------------------------------------- +// Here will be decide, if a job/test will execute or not. +// therefore exist some lists, in which stay all jobs (positive list) or a list (negative list) which jobs should not execute +// or if only specific jobs should execute by a given filter + +bool OptionHelper::isAllowedToExecute(std::string const& _sNodeName, std::string const& _sName) +{ + std::string sJobName = _sNodeName + "." + _sName; + // t_print(T_VERBOSE, "Jobname %s\n", sJobName.c_str()); + if (isOnlyShowJobs()) // true, if parameter -onlyshowjob + { + m_aJobOnlyList.setJobListEntry(sJobName, JOB_ACCESS); + return false; + } + + if (m_aJobOnlyList.size()) // >0 if parameter -jobonly + { + if (m_aJobOnlyList.getJobListEntry(sJobName) != JOB_NOT_FOUND) + { + // job entry found, mark as accessed + m_aJobOnlyList.setJobListEntry(sJobName, JOB_ACCESS); + return true; + } + return false; + } + else if (m_aJobFilter.size() > 0) // >0 if parameter -jobfilter + { + OStringList aSplitName; + split(sJobName.c_str(), ".", aSplitName); + if (! match(m_aJobFilter, aSplitName)) + { + t_print(T_VERBOSE, "job: '%s' filtered by [-jobfilter]\n", sJobName.c_str()); + return false; + } + } + else if (m_aJobExcludeList.size() > 0) // >0 if parameter -jobexclude + { + if (m_aJobExcludeList.getJobListEntry(sJobName) != JOB_NOT_FOUND) + { + // job entry found, this job should not executed, so return false + t_print(T_VERBOSE, "job: '%s' filtered by [-jobexclude]\n", sJobName.c_str()); + return false; + } + // m_aJobOnlyList.setJobListEntry(sJobName, JOB_ACCESS); + return true; + } + else + { + //! not handled yet + } + + return true; +} + diff --git a/testshl2/source/cppunit/result/outputter.cxx b/testshl2/source/cppunit/result/outputter.cxx new file mode 100644 index 000000000000..182b9db683e9 --- /dev/null +++ b/testshl2/source/cppunit/result/outputter.cxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_testshl2.hxx" + +// +#include <string> +#include <sal/types.h> +#include "testshl/result/outputter.hxx" + +// ----------------------------------------------------------------------------- + +Outputter::~Outputter() +{ + // delete m_pLog; +} + +void Outputter::writeToAll(const sal_Char* _sCharStr) +{ + // std::cout << _sCharStr; + if (m_pStream) + { + *m_pStream << _sCharStr; + } + if (m_pLog.get()) + { + m_pLog->write(_sCharStr); + } +} + +void Outputter::write(const sal_Char* _sCharStr) +{ + writeToAll(_sCharStr); +} + +void Outputter::write(std::string const& _sStr) +{ + writeToAll(_sStr.c_str()); +} + +void Outputter::write(sal_Int32 _nValue) +{ + sal_Char cBuf[20]; + sal_Char* pBuf = cBuf; + sprintf(pBuf, "%d", SAL_STATIC_CAST(int, _nValue)); + writeToAll(pBuf); +} + +// ----------------------------------------------------------------------------- + +Outputter& operator <<( Outputter &_aStreamWrapper, const sal_Char* _sValue) +{ + _aStreamWrapper.write(_sValue); + return _aStreamWrapper; +} + +Outputter& operator <<( Outputter &_aStreamWrapper, std::string const& _sValue) +{ + _aStreamWrapper.write(_sValue); + return _aStreamWrapper; +} + +Outputter& operator <<( Outputter &_aStreamWrapper, sal_Int32 _nValue) +{ + _aStreamWrapper.write(_nValue); + return _aStreamWrapper; +} + +//# Outputter& operator <<( Outputter &_aStreamWrapper, double ) +//# { +//# return _aStreamWrapper; +//# } + +Outputter& operator <<( Outputter &_aStreamWrapper, Outputter::endl const&) +{ + _aStreamWrapper.write("\n"); + return _aStreamWrapper; +} diff --git a/testshl2/source/cppunit/result/signal.cxx b/testshl2/source/cppunit/result/signal.cxx new file mode 100644 index 000000000000..7c96dcfe7589 --- /dev/null +++ b/testshl2/source/cppunit/result/signal.cxx @@ -0,0 +1,996 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_testshl2.hxx" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#if (defined UNX) || (defined OS2) +#include <signal.h> +#include <errno.h> +#endif + +#include <fstream> +#include <vector> +#include <hash_map> + +#include <rtl/tres.h> +#include <rtl/string.hxx> + +#include "testshl/autoregisterhelper.hxx" +#include "testshl/getopt.hxx" +#include "signal.hxx" +#include <cppunit/tagvalues.hxx> +#include <testshl/taghelper.hxx> +#include <unistd.h> +#include "testshl/filehelper.hxx" +#include <testshl/result/TestResult.h> +#include "testshl/signaltest.h" +#include "cppunit/Exception.h" + +#ifdef WNT +#include "testshl/winstuff.hxx" +#endif + +// typedef std::vector<std::string> StringList; +// StringList sCurrentNodeName; +CppUnit::TestResult *pTestResult = NULL; +std::string sSignalFile; + +typedef std::hash_map< std::string, int > HashMap; +HashMap m_aSignalHash; +bool bSignalsCached = false; +bool bDoNotTouchSignalFile = false; + +// ----------------------------------------------------------------------------- + +// return 'true' if signalfile doesn't exist. +// else 'false' +bool existsSignalFile(std::string const& _sSignalFilename) +{ + FILE* pFile = fopen(_sSignalFilename.c_str(), "r"); + if (!pFile) + { + return false; + } + fprintf(stderr, "'%s' exists.\n", _sSignalFilename.c_str()); + fclose(pFile); + return true; +} + +// ----------------------------------------------------------------------------- +void createEmptySignalFile(std::string const& _sSignalFilename) +{ + FILE* pFile = fopen(_sSignalFilename.c_str(), "w"); + if (!pFile) + { + fprintf(stderr, "error: Could not create signal helper file %s for signal info.\n", _sSignalFilename.c_str()); + } + else + { + fprintf(pFile, "# This is an auto generated helper file for signal handling.\n"); + fprintf(pFile, "# An entry start by '#' is a comment.\n"); + fprintf(pFile, "# All other are test functions which have abort, before this line is removed.\n"); + fprintf(pFile, "# So you have to check this functions by hand.\n"); + + fclose(pFile); + } +} + +// ----------------------------------------------------------------------------- +/** get Current PID. +*/ +inline ::rtl::OUString getCurrentPID( ) +{ + //~ Get current PID and turn it into OUString; + sal_uInt32 nPID = 0; +#ifdef WNT + nPID = WinGetCurrentProcessId(); +#else + nPID = getpid(); +#endif + return ( ::rtl::OUString::valueOf( static_cast<long>(nPID ) ) ); +} +// ----------------------------------------------------------------------------- +static std::string integerToAscii(sal_uInt32 nValue) +{ + sal_Char cBuf[30]; + sal_Char *pBuf = cBuf; + sprintf(pBuf, "%d", static_cast<unsigned int>(nValue)); + return std::string(pBuf); +} +void my_sleep(int sec); + +// ----------------------------------------------------------------------------- +void setSignalFilename(GetOpt & opt) +{ + if (opt.hasOpt("-dntsf") || opt.hasOpt("-donottouchsignalfile")) + { + // special feature, for debugging, so the signal file will not manipulate. + // but create, if no one exist. + bDoNotTouchSignalFile = true; + } + + if (opt.hasOpt("-sf") || opt.hasOpt("-signalfile")) + { + if (opt.hasOpt("-sf")) + { + sSignalFile = opt.getOpt("-sf"); + } + else if (opt.hasOpt("-signalfile")) + { + sSignalFile = opt.getOpt("-signalfile"); + } + } + else + { + std::string sPath; + // std::string sPath(FileHelper::getTempPath()); + std::string sFilename("signalfile"); + std::string sFilenameExt(".txt"); + bool bCanQuitLoop = true; + do + { + +// #ifdef WNT +// sPath += "\\"; +// #endif +// #ifdef UNX +// sPath += "/"; +// #endif + sPath = sFilename; + // BUG: i72675 + // add "_12345" where 12345 is the current process ID + + TimeValue aTimeValue; + osl_getSystemTime(&aTimeValue); + + sPath += "_"; + sPath += integerToAscii(aTimeValue.Seconds); + // rtl::OUString suPID = getCurrentPID(); + // rtl::OString sPID = rtl::OUStringToOString(suPID, RTL_TEXTENCODING_ASCII_US); + // sPath += sPID.getStr(); + sPath += sFilenameExt; + bCanQuitLoop = true; + if (existsSignalFile(sPath)) + { + // there is already a signal file, wait a second, choose an other one. + my_sleep(1); + bCanQuitLoop = false; + } + } + while (!(bCanQuitLoop)); + + sSignalFile = sPath; + fprintf(stderr, "Use default signal file name '%s'\n", sSignalFile.c_str()); + } + + if (opt.hasOpt("-dnrmsf")) + { + fprintf(stderr, "'Don't remove signal file' (-dnrmsf) is set.\n"); + } + else + { + if (bDoNotTouchSignalFile == true) + { + fprintf(stderr, "warning: 'Don't touch signal file' parameter (-dntsf) is set, will not remove existing signal file.\n"); + } + else + { + // remove signalfile + createEmptySignalFile(sSignalFile); + } + } +} + +// ----------------------------------------------------------------------------- +bool doNotTouchSignalFile() { return bDoNotTouchSignalFile; } + +// ----------------------------------------------------------------------------- +std::string buildTestFunctionName(std::string const& _sName) +{ + std::string sName; + if (pTestResult) + { + sName = pTestResult->getNodeName(); + sName += "."; + } + +/* + for (StringList::const_iterator it = sCurrentNodeName.begin(); + it != sCurrentNodeName.end(); + ++it) + { + sName += *it; + sName += "."; + } +*/ + sName += _sName; + + return sName; +} +// ----------------------------------------------------------------------------- +// old: void executionPushName(std::string const& _sName) +// old: { +// old: sCurrentNodeName.push_back(_sName); +// old: } +// old: void executionPopName() +// old: { +// old: sCurrentNodeName.pop_back(); +// old: } +// old: + +// ----------------------------------------------------------------------------- +// ------------------------------ Signal Handling ------------------------------ +// ----------------------------------------------------------------------------- + +// std::string sLastTestFunctionName; + +std::string getSignalName(sal_Int32 nSignalNo); +// ----------------------------------------------------------------------------- + +std::string getSignalFilename() +{ + return sSignalFile; +} + +// ----------------------------------------------------------------------------- +// void storeNoSignal(std::string const& _sTestName) +// { + // sLastTestFunctionName = buildTestFunctionName(_sTestName); + // std::ofstream out(getSignalFilename().c_str(), std::ios::out); + // out << NO_SIGNAL << std::endl; // no signal! +// } + +void markSignalAsAlreadyDone(sal_Int32 _nSignalNo) +{ + // std::ofstream out(getSignalFilename().c_str(), std::ios::out | std::ios::app); + FILE *out = fopen(getSignalFilename().c_str(), "a"); + if (out != NULL) + { +//# out << "# the previous test function creates signal: " +//# << getSignalName(_nSignalNo) +//# << " (" +//# << _nSignalNo +//# << ")" << std::endl; +//# // out << sLastTestFunctionName << std::endl; // SIGNAL! + + fprintf(out, "# the previous test function creates signal: %s(%d)\n", getSignalName(_nSignalNo).c_str(), SAL_STATIC_CAST(int, _nSignalNo)); + // fprintf(out, "%s\n", sLastTestFunctionName ); + fclose(out); + } + else + { + fprintf(stderr, "error: Can't write signal info to file %s \n", getSignalFilename().c_str()); + } +} + +// ----------------------------------------------------------------------------- + +Signal hasSignaled(std::string const& _sTestName) +{ + // BACK: true: signal + // false: nothing + + if (bSignalsCached == true) + { + + if (m_aSignalHash.find(buildTestFunctionName(_sTestName)) != m_aSignalHash.end()) + { + return HAS_SIGNAL; + } + return NO_SIGNAL; + } + + std::ifstream in(getSignalFilename().c_str(), std::ios::in); + + // std::cout << "Check for signal" << std::endl; + std::string sLine, sLastLine; + while (std::getline(in, sLine)) + { + // std::cout << sTest << std::endl; + char ch = sLine[0]; + if (isspace(ch) == 0 && + sLine.size() > 0) + { + if (ch == '#') + { + if (sLastLine.size() > 0) + { + rtl::OString aStrLine(sLine.c_str()); + sal_Int32 nIdx = aStrLine.indexOf("(") + 1; + sal_Int32 nIdx2 = aStrLine.indexOf(")"); + sal_Int32 nSignalNo = 0; + if (nIdx > 0 && nIdx2 > 0) + { + rtl::OString sSignalNo = aStrLine.copy(nIdx, nIdx2 - nIdx); + nSignalNo = sSignalNo.toInt32(); + m_aSignalHash[sLastLine] = nSignalNo; + } + sLastLine.clear(); + } + } + else + { + // if (sTest == buildTestFunctionName(_sTestName)) + m_aSignalHash[sLine] = 1; + sLastLine = sLine; + // return HAS_SIGNAL; + } + } + } + + bSignalsCached = true; + return hasSignaled(_sTestName); + // return NO_SIGNAL; +} + +#ifdef UNX + +// ----------------------------------------------------------------------------- + +void release_signal_Handling(); + +//# void signalFunction(int value) +//# { +//# std::cout << "Signal caught: (" << value << "), please restart." << std::endl; +//# markSignalAsAlreadyDone(); +//# +//# release_signal_Handling(); +//# std::cout.flush(); +//# abort(); +//# } + +// ----------------------------------------------------------------------------- +extern "C" void SignalHandlerFunction(int _nSignalNo, siginfo_t *, void*) +{ + // std::cout << "Signal caught: " << getSignalName(_nSignalNo) << " (" << _nSignalNo << "), please restart." << std::endl; + fprintf(stderr, "Signal caught %s(%d)\n", getSignalName(_nSignalNo).c_str(), _nSignalNo); + markSignalAsAlreadyDone(_nSignalNo); + + release_signal_Handling(); + // std::cout.flush(); + abort(); +} + +// ----------------------------------------------------------------------------- +// This is a copy of the osl/signal.c code +#define ACT_IGNORE 1 +#define ACT_ABORT 2 +#define ACT_EXIT 3 +#define ACT_SYSTEM 4 +#define ACT_HIDE 5 + +extern "C" { +static struct SignalAction +{ + int Signal; + int Action; + void (*Handler)(int); +} Signals[] = +{ + { SIGHUP, ACT_IGNORE, NULL }, /* hangup */ + { SIGINT, ACT_EXIT, NULL }, /* interrupt (rubout) */ + { SIGQUIT, ACT_ABORT, NULL }, /* quit (ASCII FS) */ + { SIGILL, ACT_SYSTEM, NULL }, /* illegal instruction (not reset when caught) */ +/* changed from ACT_ABOUT to ACT_SYSTEM to try and get collector to run*/ + { SIGTRAP, ACT_ABORT, NULL }, /* trace trap (not reset when caught) */ +#if ( SIGIOT != SIGABRT ) + { SIGIOT, ACT_ABORT, NULL }, /* IOT instruction */ +#endif +// { SIGABRT, ACT_ABORT, NULL }, /* used by abort, replace SIGIOT in the future */ +#ifdef SIGEMT + { SIGEMT, ACT_SYSTEM, NULL }, /* EMT instruction */ +/* changed from ACT_ABORT to ACT_SYSTEM to remove handler*/ +/* SIGEMT may also be used by the profiler - so it is probably not a good + plan to have the new handler use this signal*/ +#endif + { SIGFPE, ACT_ABORT, NULL }, /* floating point exception */ + { SIGKILL, ACT_SYSTEM, NULL }, /* kill (cannot be caught or ignored) */ + { SIGBUS, ACT_ABORT, NULL }, /* bus error */ + { SIGSEGV, ACT_ABORT, NULL }, /* segmentation violation */ +#ifdef SIGSYS + { SIGSYS, ACT_ABORT, NULL }, /* bad argument to system call */ +#endif + { SIGPIPE, ACT_HIDE, NULL }, /* write on a pipe with no one to read it */ + { SIGALRM, ACT_EXIT, NULL }, /* alarm clock */ + { SIGTERM, ACT_EXIT, NULL }, /* software termination signal from kill */ + { SIGUSR1, ACT_SYSTEM, NULL }, /* user defined signal 1 */ + { SIGUSR2, ACT_SYSTEM, NULL }, /* user defined signal 2 */ + { SIGCHLD, ACT_SYSTEM, NULL }, /* child status change */ +#ifdef SIGPWR + { SIGPWR, ACT_IGNORE, NULL }, /* power-fail restart */ +#endif + { SIGWINCH, ACT_IGNORE, NULL }, /* window size change */ + { SIGURG, ACT_EXIT, NULL }, /* urgent socket condition */ +#ifdef SIGPOLL + { SIGPOLL, ACT_EXIT, NULL }, /* pollable event occured */ +#endif + { SIGSTOP, ACT_SYSTEM, NULL }, /* stop (cannot be caught or ignored) */ + { SIGTSTP, ACT_SYSTEM, NULL }, /* user stop requested from tty */ + { SIGCONT, ACT_SYSTEM, NULL }, /* stopped process has been continued */ + { SIGTTIN, ACT_SYSTEM, NULL }, /* background tty read attempted */ + { SIGTTOU, ACT_SYSTEM, NULL }, /* background tty write attempted */ + { SIGVTALRM, ACT_EXIT, NULL }, /* virtual timer expired */ + { SIGPROF, ACT_SYSTEM, NULL }, /* profiling timer expired */ +/*Change from ACT_EXIT to ACT_SYSTEM for SIGPROF is so that profiling signals do + not get taken by the new handler - the new handler does not pass on context + information which causes 'collect' to crash. This is a way of avoiding + what looks like a bug in the new handler*/ + { SIGXCPU, ACT_ABORT, NULL }, /* exceeded cpu limit */ + { SIGXFSZ, ACT_ABORT, NULL } /* exceeded file size limit */ +}; +} + +const int NoSignals = sizeof(Signals) / sizeof(struct SignalAction); + +#endif /* UNX */ + +// ----------------------------------------------------------------------------- +void init_signal_Handling(CppUnit::TestResult *_pResult) +{ + pTestResult = _pResult; +#ifdef UNX + +// signal(SIGSEGV, signalFunction); + // signal(SIGSEGV, signalFunction); + // signal(SIGFPE, signalFunction); + +// signal(1, signalFunction); + // struct sigaction action, oldaction; + // action.sa_sigaction = signalFunction2; + // action.sa_flags = SA_ONESHOT /* | SA_SIGINFO */; + + struct sigaction act; + struct sigaction oact; + + // act.sa_handler = SignalHandlerFunction; + act.sa_flags = SA_RESTART; + // act.sa_flags = SA_ONESHOT /* | SA_SIGINFO */; + act.sa_sigaction = SignalHandlerFunction; + + sigfillset(&(act.sa_mask)); + + /* Initialize the rest of the signals */ + for (int i = 0; i < NoSignals; i++) + { + if (Signals[i].Action != ACT_SYSTEM) + { + if (Signals[i].Action == ACT_HIDE) + { + struct sigaction ign; + + ign.sa_handler = SIG_IGN; + ign.sa_flags = 0; + sigemptyset(&ign.sa_mask); + + if (sigaction(Signals[i].Signal, &ign, &oact) == 0) + Signals[i].Handler = oact.sa_handler; + else + Signals[i].Handler = SIG_DFL; + } + else + if (sigaction(Signals[i].Signal, &act, &oact) == 0) + Signals[i].Handler = oact.sa_handler; + else + Signals[i].Handler = SIG_DFL; + } + } +#endif + + // ------------ signal helper file must exist ----------------- + FILE* pFile = fopen(getSignalFilename().c_str(), "r"); + if (!pFile) + { + createEmptySignalFile( getSignalFilename() ); + } + else + { + fclose(pFile); + } +} + +// ----------------------------------------------------------------------------- +void release_signal_Handling() +{ + // frees all signals +#ifdef UNX + int i; + struct sigaction act; + + act.sa_flags = 0; + sigemptyset(&(act.sa_mask)); + + /* Initialize the rest of the signals */ + for (i = NoSignals - 1; i >= 0; i--) + { + if (Signals[i].Action != ACT_SYSTEM) + { + act.sa_handler = Signals[i].Handler; + + sigaction(Signals[i].Signal, &act, NULL); + } + } +#endif +} + +// ----------------------------------------------------------------------------- +Signal signalCheck(CppUnit::TestResult* _pResult, std::string const& _sTestName) +{ + // BACK: HAS_SIGNAL: the test has already done and signaled + if (hasSignaled(_sTestName) == HAS_SIGNAL) + { + // std::cout << "The Test '" << buildTestFunctionName(_sTestName) << "' is marked as signaled." << std::endl; + std::string sTestFunctionName = buildTestFunctionName(_sTestName); + fprintf(stderr, "The Test '%s' is marked as signaled.\n", sTestFunctionName.c_str()); + if (_pResult) + { + CppUnit::SignalTest *pTest = new CppUnit::SignalTest(_sTestName); + + std::string sErrorText = "Function is marked as signaled: "; + sal_Int32 nSignalNo = m_aSignalHash[sTestFunctionName]; + sErrorText += getSignalName(nSignalNo); + sErrorText += " ("; + sErrorText += OptionHelper::integerToAscii(nSignalNo); + sErrorText += ")"; + + _pResult->addError(pTest, new CppUnit::SignalException(sErrorText), ErrorType::ET_SIGNAL); + } + return HAS_SIGNAL; + } + + // storeNoSignal(_sTestName); + return NO_SIGNAL; +} + +// ----------------------------------------------------------------------------- +bool copyFile(std::string const& _sFrom, std::string const& _sTo) +{ + bool bRetValue = false; + const int MAXBUFSIZE = 1024; + char buff[MAXBUFSIZE]; + FILE *in = fopen(_sFrom.c_str(), "r"); + if (in == NULL) + { + fprintf(stderr, "error: Can't open file %s for read to copy.\n", _sFrom.c_str()); + bRetValue = false; + } + else + { + FILE *out = fopen(_sTo.c_str(), "w"); + if (out == NULL) + { + fclose(in); + fprintf(stderr, "error: Can't open file %s for write to copy.\n", _sTo.c_str()); + bRetValue = false; + } + else + { + int nRealGot = 0; + while(!feof(in)) + { + nRealGot = fread(buff, sizeof(char), MAXBUFSIZE, in); + if (nRealGot > 0) + { + fwrite(buff, sizeof(char), nRealGot, out); + } + } + bRetValue = true; + fclose(out); + fclose(in); + } + } + return bRetValue; +} + +// ----------------------------------------------------------------------------- +void signalStartTest(std::string const& _sName) +{ + if (doNotTouchSignalFile()) return; + + // fprintf(stderr, "### signalStartTest!\n"); + // due to the fact, that functions are vicious, we write the name first. + // if it isn't vivious, than we removed it. + std::string sNewName = getSignalFilename(); + sNewName += ".bak"; + if (copyFile(getSignalFilename(), sNewName)) + { + // std::ofstream out(getSignalFilename().c_str(), std::ios::out | std::ios::app); + FILE *out = fopen(getSignalFilename().c_str(), "a"); + if (out != NULL) + { + // out << buildTestFunctionName(_sName) << std::endl; + fprintf(out, "%s\n", buildTestFunctionName(_sName).c_str()); + fclose(out); + } + else + { + fprintf(stderr, "error: Can't open file %s for append.\n", getSignalFilename().c_str()); + } + } + else + { + fprintf(stderr, "error: Can't copy signal helper from file %s to file %s, %d\n", getSignalFilename().c_str(), sNewName.c_str(), errno); + } +} + +// ----------------------------------------------------------------------------- +void signalEndTest() +{ + if (doNotTouchSignalFile()) return; + + // fprintf(stderr, "### signalEndTest!\n"); + if (0 != remove(getSignalFilename().c_str())) + { + fprintf(stderr, "error: Can't delete file %s\n", getSignalFilename().c_str()); + } + else + { + std::string sNewName = getSignalFilename(); + sNewName += ".bak"; + if (0 != rename(sNewName.c_str(), getSignalFilename().c_str())) + { + fprintf(stderr, "error: Can't rename file %s to file %s errno: %d\n", sNewName.c_str(), getSignalFilename().c_str(), errno); + } + } +} + +// ----------------------------------------------------------------------------- +void removeSignalFile(GetOpt & opt) +{ + // fprintf(stderr, "### remove signal file: '%s'\n", sSignalFile.c_str()); + if (opt.hasOpt("-dnrmsf")) + { + return; + } + if (bDoNotTouchSignalFile == true) + { + return; + } + remove(getSignalFilename().c_str()); +} + +// ----------------------------------------------------------------------------- + +sal_Int32 SignalHandlerA( TagHelper const& _aTagItems ) +{ + sal_Int32 nRetValue = 0; + TagData nTagType = _aTagItems.GetTagData(TAG_TYPE, 0); +// LLA: unused +// hTestResult hResult = (hTestResult) _aTagItems.GetTagData(TAG_RESULT_PTR, 0 /* NULL */ ); +// CppUnit::TestResult* pResult = (CppUnit::TestResult*)hResult; + + try + { + switch(nTagType) + { + // old: case SIGNAL_PUSH_NAME: + // old: { + // old: const char* sName = (const char*) _aTagItems.GetTagData(TAG_NODENAME); + // old: if (sName != NULL) + // old: signalPushName(sName); + // old: break; + // old: } + // old: + // old: case SIGNAL_POP_NAME: + // old: signalPopName(); + // old: break; + + // old: case SIGNAL_CHECK: + // old: { + // old: const char* sName = (const char*) _aTagItems.GetTagData(TAG_NODENAME); + // old: if (sName != NULL) + // old: { + // old: nRetValue = signalCheck(sName); + // old: } + // old: break; + // old: } + + // old: case INIT_SIGNAL_HANDLING: + // old: init_signal_Handling(); + // old: break; + // old: + // old: case RELEASE_SIGNAL_HANDLING: + // old: release_signal_Handling(); + // old: break; + + case SIGNAL_START_TEST: + { + // fprintf(stderr, "### SIGNAL_START_TEST!\n"); + const char* sName = (const char*) _aTagItems.GetTagData(TAG_NODENAME); + if (sName != NULL) + { + signalStartTest(sName); + } + break; + } + + case SIGNAL_END_TEST: + { + // fprintf(stderr, "### SIGNAL_END_TEST!\n"); + const char* sName = (const char*) _aTagItems.GetTagData(TAG_NODENAME); + if (sName != NULL) + { + signalEndTest(); + } + break; + } + + default: + fprintf(stderr, "error: SignalHandlerA: Can't handle the tag type %d\n", SAL_STATIC_CAST(int, nTagType)); + fflush(stderr); + // throw std::exception(/*std::string("Unknown TYPE_TAG Exception.")*/); + } + } + catch (std::exception &e) + { + fprintf(stderr, "error: SignalHandlerA: Exception caught: %s\n", e.what()); + fflush(stderr); + // throw e; + } + + return nRetValue; +} +// ----------------------------------------------------------------------------- +// This a little bit more abstract code, could be easier to modify or expand. + +sal_Int32 CheckExecution(CppUnit::TestResult* _pResult, std::string const& _sName) +{ + // more checks in the corresponding job lists + if (_pResult) + { + if (! _pResult->isAllowedToExecute(_sName)) + { + return DO_NOT_EXECUTE; + } + } + + // Check if the given test should be executed. + if (signalCheck(_pResult, _sName) == HAS_SIGNAL) + { + return DO_NOT_EXECUTE; + } + + return GO_EXECUTE; +} + +// ----------------------------------------------------------------------------- +sal_Int32 ExecutionA( TagHelper const& _aTagItems ) +{ + sal_Int32 nRetValue = 0; + TagData nTagType = _aTagItems.GetTagData(TAG_TYPE, 0); + hTestResult hResult = (hTestResult) _aTagItems.GetTagData(TAG_RESULT_PTR, 0 /* NULL */ ); + CppUnit::TestResult* pResult = (CppUnit::TestResult*)hResult; + + try + { + switch(nTagType) + { + case EXECUTION_CHECK: + { + const char* sName = (const char*) _aTagItems.GetTagData(TAG_NODENAME); + if (sName) + { + nRetValue = CheckExecution(pResult, sName); + if (nRetValue == GO_EXECUTE) + { + if (pResult && pResult->isOptionWhereAmI()) + { + printf("# This is: %s\n", buildTestFunctionName(sName).c_str()); + } + } + } + + break; + } + + // old: case EXECUTION_PUSH_NAME: + // old: { + // old: const char* sName = (const char*) _aTagItems.GetTagData(TAG_NODENAME); + // old: if (sName != NULL) + // old: executionPushName(sName); + // old: break; + // old: } + // old: + // old: case EXECUTION_POP_NAME: + // old: executionPopName(); + // old: break; + + case INIT_TEST: + init_signal_Handling(pResult); + break; + + case RELEASE_TEST: + release_signal_Handling(); + break; + + default: + fprintf(stderr, "ExceptionA: Can't handle the tag type %d\n", SAL_STATIC_CAST(int, nTagType)); + break; + } + } + catch (std::exception &e) + { + fprintf(stderr, "ExecutionA: exception caught: %s\n", e.what()); + fflush(stderr); + // throw e; + } + return nRetValue; +} + +// ----------------------------------------------------------------------------- +std::string getSignalName(sal_Int32 nSignalNo) +{ + std::string sValue; +#ifdef UNX + switch(nSignalNo) + { + case SIGHUP: + sValue = "SIGHUP"; + break; + + case SIGINT: + sValue = "SIGINT"; + break; + + case SIGQUIT: + sValue = "SIGQUIT"; + break; + + case SIGILL: + sValue = "SIGILL"; + break; + + case SIGTRAP: + sValue = "SIGTRAP"; + break; + +#if ( SIGIOT != SIGABRT ) + case SIGIOT: + sValue = "SIGIOT"; + break; +#endif +// case SIGABRT: +#ifdef SIGEMT + case SIGEMT: + sValue = "SIGEMT"; + break; +#endif + case SIGFPE: + sValue = "SIGFPE"; + break; + + case SIGKILL: + sValue = "SIGKILL"; + break; + + case SIGBUS: + sValue = "SIGBUS"; + break; + + case SIGSEGV: + sValue = "SIGSEGV"; + break; + +#ifdef SIGSYS + case SIGSYS: + sValue = "SIGSYS"; + break; +#endif + case SIGPIPE: + sValue = "SIGPIPE"; + break; + + case SIGALRM: + sValue = "SIGALRM"; + break; + + case SIGTERM: + sValue = "SIGTERM"; + break; + + case SIGUSR1: + sValue = "SIGUSR1"; + break; + + case SIGUSR2: + sValue = "SIGUSR2"; + break; + + case SIGCHLD: + sValue = "SIGCHLD"; + break; + +#ifdef SIGPWR + case SIGPWR: + sValue = "SIGPWR"; + break; +#endif + case SIGWINCH: + sValue = "SIGWINCH"; + break; + + case SIGURG: + sValue = "SIGURG"; + break; + +#ifdef SIGPOLL + case SIGPOLL: + sValue = "SIGPOLL"; + break; +#endif + case SIGSTOP: + sValue = "SIGSTOP"; + break; + + case SIGTSTP: + sValue = "SIGTSTP"; + break; + + case SIGCONT: + sValue = "SIGCONT"; + break; + + case SIGTTIN: + sValue = "SIGTTIN"; + break; + + case SIGTTOU: + sValue = "SIGTTOU"; + break; + + case SIGVTALRM: + sValue = "SIGVTALRM"; + break; + + case SIGPROF: + sValue = "SIGPROF"; + break; + + case SIGXCPU: + sValue = "SIGXCPU"; + break; + + case SIGXFSZ: + sValue = "SIGXFSZ"; + break; + + default: + sValue = "Unhandled Signal."; + } +#else + (void) nSignalNo; // unused +#endif + return sValue; +} + +// The following sets variables for GNU EMACS +// Local Variables: +// tab-width:4 +// End: diff --git a/testshl2/source/cppunit/result/signal.hxx b/testshl2/source/cppunit/result/signal.hxx new file mode 100644 index 000000000000..e3f448535014 --- /dev/null +++ b/testshl2/source/cppunit/result/signal.hxx @@ -0,0 +1,39 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SIGNAL_HXX +#define SIGNAL_HXX + +#include <sal/types.h> + +#define HAS_SIGNAL 1 +#define NO_SIGNAL 0 + +typedef sal_Int32 Signal; + +#endif + diff --git a/testshl2/source/cppunit/result/testshlTestResult.cxx b/testshl2/source/cppunit/result/testshlTestResult.cxx new file mode 100644 index 000000000000..f80b999416ed --- /dev/null +++ b/testshl2/source/cppunit/result/testshlTestResult.cxx @@ -0,0 +1,425 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_testshl2.hxx" + +#include <stdlib.h> + +#include <map> +#include <cppunit/Exception.h> +#include <cppunit/NotEqualException.h> +#include <cppunit/Test.h> +#include <cppunit/TestFailure.h> +#include <testshl/result/testshlTestResult.h> +// #include <TextTestResult.h> +//!io #include <iostream> +#include <string> + +#include <rtl/string.hxx> +#include "testshl/result/outputter.hxx" + +namespace CppUnit { + + testshlTestResult::testshlTestResult(GetOpt & _aOptions) + :TestResult(_aOptions), + m_aOptions(_aOptions), + // m_aOptionHelper(_aOptions), + m_aResulter(this) + { + addListener( &m_aResulter ); + } + + testshlTestResult::~testshlTestResult() + { + } + +//# void +//# testshlTestResult::addFailure( const TestFailure &failure ) +//# { +//# // TestResultCollector::addFailure( failure ); +//# // std::cerr << ( failure.isError() ? "E" : "F" ); +//# m_aResulter.addFailure(failure); +//# } +//# +//# +//# void +//# testshlTestResult::startTest( Test *test ) +//# { +//# // TestResultCollector::startTest (test); +//# m_aResulter.startTest(test); +//# // std::cerr << "."; +//# } +//# +//# void testshlTestResult::endTest( Test *test ) +//# { +//# } + +// ----------------------------------------------------------------------------- + +//# void +//# testshlTestResult::printFailures( Outputter &stream ) +//# { +//# TestFailures::const_iterator itFailure = failures().begin(); +//# int failureNumber = 1; +//# while ( itFailure != failures().end() ) +//# { +//# stream << std::endl; +//# printFailure( *itFailure++, failureNumber++, stream ); +//# } +//# } +//# +//# +//# void +//# testshlTestResult::printFailure( TestFailure *failure, +//# int failureNumber, +//# std::ostream &stream ) +//# { +//# printFailureListMark( failureNumber, stream ); +//# stream << ' '; +//# printFailureTestName( failure, stream ); +//# stream << ' '; +//# printFailureType( failure, stream ); +//# stream << ' '; +//# printFailureLocation( failure->sourceLine(), stream ); +//# stream << std::endl; +//# printFailureDetail( failure->thrownException(), stream ); +//# stream << std::endl; +//# } +//# +//# +//# void +//# testshlTestResult::printFailureListMark( int failureNumber, +//# std::ostream &stream ) +//# { +//# stream << failureNumber << ")"; +//# } +//# +//# +//# void +//# testshlTestResult::printFailureTestName( TestFailure *failure, +//# std::ostream &stream ) +//# { +//# Test* pTest = failure->failedTest(); +//# stream << "test: " << pTest->getName(); +//# } +//# +//# +//# void +//# testshlTestResult::printFailureType( TestFailure *failure, +//# std::ostream &stream ) +//# { +//# stream << "(" +//# << (failure->isError() ? "E" : "F") +//# << ")"; +//# } +//# +//# +//# void +//# testshlTestResult::printFailureLocation( SourceLine sourceLine, +//# std::ostream &stream ) +//# { +//# if ( !sourceLine.isValid() ) +//# return; +//# +//# stream << "line: " << sourceLine.lineNumber() +//# << ' ' << sourceLine.fileName(); +//# } +//# +//# +//# void +//# testshlTestResult::printFailureDetail( Exception *thrownException, +//# std::ostream &stream ) +//# { +//# if ( thrownException->isInstanceOf( NotEqualException::type() ) ) +//# { +//# NotEqualException *e = (NotEqualException*)thrownException; +//# stream << "expected: " << e->expectedValue() << std::endl +//# << "but was: " << e->actualValue(); +//# if ( !e->additionalMessage().empty() ) +//# { +//# stream << std::endl; +//# stream << "additional message:" << std::endl +//# << e->additionalMessage(); +//# } +//# } +//# else +//# { +//# stream << " \"" << thrownException->what() << "\""; +//# } +//# } + + +// LLA: output format: +// Header +// # -- BEGIN +// Error lines +// No error lines +// unknown lines +// # -- END +// Text 'Test #PASSED#' or 'Errors only' + +void +testshlTestResult::print( Outputter& stream ) +{ + printHeader( stream ); + // stream << std::endl; + // printFailures( stream ); + + bool bPassed = false; + if (isOnlyShowJobs()) + { + JobList jl(m_aOptionHelper.getJobOnlyList()); + HashMap aJobList = jl.getHashMap(); + printLines(stream, aJobList); + } + else + { + stream << "# -- BEGIN:" << Outputter::endl(); + + TestPtrList aFailedTests; + + // List of failures + printFailedTests(stream, aFailedTests); + + if (! m_aOptionHelper.getOptions().hasOpt("-onlyerrors")) + { + // List of well done tests + printTestLines(stream, aFailedTests); + + // List of unknown Tests + JobList jl(m_aOptionHelper.getJobOnlyList()); + HashMap aJobList = jl.getHashMap(); + printUnknownLines(stream, aJobList); + + bPassed = true; + } + stream << "# -- END:" << Outputter::endl(); + + if (bPassed) + { + stream << "Test #PASSED#" << Outputter::endl(); + } + + if (m_aOptionHelper.getOptions().hasOpt("-onlyerrors")) + { + stream << "Errors only." << Outputter::endl(); + } + } +} + +// ----------------------------------------------------------------------------- +void +testshlTestResult::printLines(Outputter &stream, HashMap & _aJobList) +{ + int nCount = _aJobList.size(); + if (nCount != 0) + { + for (HashMap::const_iterator it = _aJobList.begin(); + it != _aJobList.end(); + ++it) + { + std::string aKey = (*it).first; + if (_aJobList[aKey] == JOB_ACCESS) + { + stream << aKey; + stream << Outputter::endl(); + } + } + } +} + +void +testshlTestResult::printFailedTests(Outputter &stream, TestPtrList &aFailedTests) +{ + for (TestResultCollector::TestFailures::const_iterator it2 = m_aResulter.failures().begin(); + it2 != m_aResulter.failures().end(); + ++it2) + { + TestFailureEnvelope *pEnvelop = *it2; + TestFailure *pFailure = pEnvelop->getTestFailure(); + std::string sNodeName = pEnvelop->getString(); + + aFailedTests[ pFailure->failedTest() ] = true; + + printFailureLine(stream, pFailure, sNodeName); + } +} + +void +testshlTestResult::printTestLines(Outputter &stream, TestPtrList &aFailedTests) +{ + for (TestResultCollector::Tests::const_iterator it = m_aResulter.tests().begin(); + it != m_aResulter.tests().end(); + ++it) + { + TestEnvelope *pEnvelop = *it; + Test* pTest = pEnvelop->getTest(); + std::string sNodeName = pEnvelop->getString(); + + if (aFailedTests.find(pTest) == aFailedTests.end()) + { + std::string sInfo = m_aResulter.getInfo(pTest); + printTestLine(stream, pTest, sNodeName, sInfo); + } + } +} + +void +testshlTestResult::printUnknownLines(Outputter &stream, HashMap & _aJobList) +{ + int nCount = _aJobList.size(); + if (nCount != 0) + { + for (HashMap::const_iterator it = _aJobList.begin(); + it != _aJobList.end(); + ++it) + { + std::string aKey = (*it).first; + if (_aJobList[aKey] == JOB_UNKNOWN) + { + printUnknownLine(stream, aKey); + } + } + } +} + +void +testshlTestResult::printHeader( Outputter &stream ) +{ + std::string sDate(m_aOptionHelper.createDateTag()); + if (isOnlyShowJobs()) + { + stream << "# This is an automatically generated job file." << Outputter::endl(); + stream << "# "; + } + else + { + stream << sDate << Outputter::endl(); + } +} + +void +testshlTestResult::printFailureLine( Outputter &stream, TestFailure *_pFailure, std::string const& _sNodeName) +{ + std::string aName; + aName += _sNodeName; + aName += "."; + aName += _pFailure->failedTestName(); + + SourceLine aLine = _pFailure->sourceLine(); + sal_Int32 nLine = -1; + std::string sFilename; + if (aLine.isValid()) + { + nLine = aLine.lineNumber(); + sFilename = aLine.fileName(); + } + + Exception *pExp = _pFailure->thrownException(); + std::string sWhat; + if (pExp) + { + sWhat = pExp->what(); + } + + ErrorType::num eErr = _pFailure->getErrorType(); + + stream << aName; + stream << ";"; + + if (eErr == ErrorType::ET_FAILURE) + stream << "FAILED"; + + else if (eErr == ErrorType::ET_ERROR) + stream << "ERROR"; + + else if (eErr == ErrorType::ET_SIGNAL) + stream << "SIGNAL"; + + else + stream << "UNKNOWN"; + + stream << "#FAILED#"; + + stream << sWhat; + stream << Outputter::endl(); +} + +void +testshlTestResult::printTestLine( Outputter &stream, Test* _pTest, std::string const& _sNodeName, std::string const& _sInfo) +{ + std::string aName; + aName += _sNodeName; + aName += "."; + aName += _pTest->getName(); + + stream << aName; + stream << ";"; + stream << _sInfo << "#"; + if (_sInfo == "PASSED") + { + stream << "OK#"; + } + else + { + stream << "FAILED#"; + } + stream << Outputter::endl(); +} + +void +testshlTestResult::printUnknownLine( Outputter &stream, std::string const& _sTestName) +{ + stream << _sTestName; + stream << ";"; + stream << "UNKNOWN#"; + stream << "FAILED#"; + stream << Outputter::endl(); +} + +//# void +//# testshlTestResult::printStatistics( Outputter &stream ) +//# { +//# stream << "Test Results:" << std::endl; +//# +//# stream << "Run: " << runTests() +//# << " Failures: " << testFailures() +//# << " Errors: " << testErrors() +//# << std::endl; +//# } + + +Outputter & +operator <<( Outputter &stream, + testshlTestResult &result ) +{ + result.print (stream); return stream; +} + + +} // namespace CppUnit diff --git a/testshl2/source/cppunit/result/treswrapper.cxx b/testshl2/source/cppunit/result/treswrapper.cxx new file mode 100644 index 000000000000..50d0b7f8ebfe --- /dev/null +++ b/testshl2/source/cppunit/result/treswrapper.cxx @@ -0,0 +1,259 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_testshl2.hxx" + +#include <cstdarg> +#include <stdlib.h> +#include <stdio.h> + +#include <sal/types.h> +#include <cppunit/Test.h> +#include "testshl/autoregister/htestresult.h" +#include "cppunit/callbackfunc_fktptr.h" +#include "testshl/result/callbackfunc.h" +#include "testshl/result/TestResult.h" +#include <testshl/taghelper.hxx> + +#include <cppunit/tagvalues.hxx> + +namespace +{ + void TestResult_startTest(hTestResult _pResult, hTest _pTest) + { + CppUnit::TestResult* pResult = (CppUnit::TestResult*)_pResult; + CppUnit::Test* pTest = (CppUnit::Test*)_pTest; + + std::string sName = pTest->getName(); + CallbackDispatch(0 /* NULL */, TAG_TYPE, SIGNAL_START_TEST, TAG_RESULT_PTR, _pResult, TAG_NODENAME, sName.c_str(), TAG_DONE); + + pResult->startTest(pTest); + } + + void TestResult_endTest( hTestResult _pResult, hTest _pTest ) + { + CppUnit::TestResult* pResult = (CppUnit::TestResult*)_pResult; + CppUnit::Test* pTest = (CppUnit::Test*)_pTest; + pResult->endTest(pTest); + + std::string sName = pTest->getName(); + CallbackDispatch(0 /* NULL */, TAG_TYPE, SIGNAL_END_TEST, TAG_RESULT_PTR, _pResult, TAG_NODENAME, sName.c_str(), TAG_DONE); + } + +// ----------------------------------------------------------------------------- + + void TestResult_addFailure( hTestResult _pResult, hTest _pTest, hException _pException ) + { + CppUnit::TestResult* pResult = (CppUnit::TestResult*)_pResult; + CppUnit::Test* pTest = (CppUnit::Test*)_pTest; + CppUnit::Exception* pException = (CppUnit::Exception*)_pException; + pResult->addFailure(pTest, pException); + } + + void TestResult_addError( hTestResult _pResult, hTest _pTest, hException _pException ) + { + CppUnit::TestResult* pResult = (CppUnit::TestResult*)_pResult; + CppUnit::Test* pTest = (CppUnit::Test*)_pTest; + CppUnit::Exception* pException = (CppUnit::Exception*)_pException; + pResult->addError(pTest, pException); + } + + sal_Int32 TestResult_shouldStop(hTestResult _pResult) + { + CppUnit::TestResult* pResult = (CppUnit::TestResult*)_pResult; + return pResult->shouldStop() == true ? 1 : 0; + } + +// ----------------------------------------------------------------------------- + void TestResult_addInfo( hTestResult _pResult, hTest _pTest, const char* _sInfo ) + { + CppUnit::TestResult* pResult = (CppUnit::TestResult*)_pResult; + CppUnit::Test* pTest = (CppUnit::Test*)_pTest; + // CppUnit::Exception* pException = (CppUnit::Exception*)_pException; + pResult->addInfo(pTest, _sInfo); + } +// ----------------------------------------------------------------------------- + void TestResult_enterNode( hTestResult _pResult, const char* _sNode ) + { + // signalPushName(getName()); + // CallbackDispatch(NULL, TAG_TYPE, EXECUTION_PUSH_NAME, TAG_RESULT_PTR, _pResult, TAG_NODENAME, _sNode, TAG_DONE); + + CppUnit::TestResult* pResult = (CppUnit::TestResult*)_pResult; + // CppUnit::Test* pTest = (CppUnit::Test*)_pTest; + // CppUnit::Exception* pException = (CppUnit::Exception*)_pException; + pResult->enterNode(_sNode); + } + void TestResult_leaveNode( hTestResult _pResult, const char* _sNode ) + { + CppUnit::TestResult* pResult = (CppUnit::TestResult*)_pResult; + // CppUnit::Test* pTest = (CppUnit::Test*)_pTest; + // CppUnit::Exception* pException = (CppUnit::Exception*)_pException; + pResult->leaveNode(_sNode); + + // CallbackDispatch(NULL, TAG_TYPE, EXECUTION_POP_NAME, TAG_RESULT_PTR, _pResult, TAG_DONE); + } + +// ----------------------------------------------------------------------------- + sal_Int32 TestResult_StarterA(TagHelper const& _aTagItems) + { + sal_Int32 nRetValue = 0; + TagData nTagType = _aTagItems.GetTagData(TAG_TYPE, 0); + hTestResult pResult = (hTestResult) _aTagItems.GetTagData(TAG_RESULT_PTR, 0 /* NULL */); + CppUnit::Test* pTest = (CppUnit::Test*) _aTagItems.GetTagData(TAG_TEST_PTR, 0 /* NULL */); + + try + { + switch(nTagType) + { + case RESULT_START: + TestResult_startTest(pResult, pTest); + break; + + case RESULT_END: + TestResult_endTest(pResult, pTest); + break; + + case RESULT_ADD_FAILURE: + { + hException pException = (hException) _aTagItems.GetTagData(TAG_EXCEPTION, 0); + TestResult_addFailure(pResult, pTest, pException); + break; + } + + case RESULT_ADD_ERROR: + { + hException pException = (hException) _aTagItems.GetTagData(TAG_EXCEPTION, 0); + TestResult_addError(pResult, pTest, pException); + break; + } + + case RESULT_ADD_INFO: + { + const char* pInfo = (const char* ) _aTagItems.GetTagData(TAG_INFO, 0); + TestResult_addInfo(pResult, pTest, pInfo); + break; + } + + case RESULT_ENTER_NODE: + { + const char* pNode = (const char* )_aTagItems.GetTagData(TAG_NODENAME, 0); + TestResult_enterNode(pResult, pNode); + break; + } + + case RESULT_LEAVE_NODE: + { + const char* pNode = (const char* ) _aTagItems.GetTagData(TAG_NODENAME, 0); + TestResult_leaveNode(pResult, pNode); + break; + } + + case RESULT_SHOULD_STOP: + nRetValue = TestResult_shouldStop(pResult); + break; + + default: + fprintf(stderr, "TestResult_StarterA: Can't handle the tag type %8x\n", SAL_STATIC_CAST(int, nTagType)); + fflush(stderr); + // throw std::exception(/*std::string("Unknown TYPE_TAG Exception.")*/); + } + } + catch (std::exception &e) + { + fprintf(stderr, "TestResult_StarterA: Exception caught: %s\n", e.what()); + // throw e; + } + + return nRetValue; + } +} // namespace anonymous + +// --------------------------------- Prototypes --------------------------------- + +sal_Int32 SignalHandlerA( TagHelper const& _aTagItems ); +sal_Int32 ExecutionA( TagHelper const& _aTagItems ); + +// ----------------------------------------------------------------------------- +long CallbackDispatch(int x, ...) +{ + (void) x; // avoid warning + + // The idea behind TagItems are from the Amiga OS. + // Due to the fact that the following code does not find my ok + // I decide to wrote a simple helper + // + // struct TagItem *tags = (struct TagItem *)&x + 1; + + TagHelper aTagItems; + + // the following code could also be in a #define, so other functions could + // use this, but at the moment this function a the only one. + + // FILL_TAGS(aTagItems, x); + std::va_list args; + va_start( args, x ); + Tag nTag; + do + { + nTag = va_arg(args, Tag); + if (nTag != TAG_DONE) + { + TagData nValue = va_arg(args, TagData); + // printf("Tag: %8x Value:%8x\n", nTag, nValue); + aTagItems.insert(nTag, nValue); + } + } while (nTag != TAG_DONE); + + va_end ( args ); + + // FILL_TAGS:END + + // printf(".\n"); + + long nRetValue = 0; + Tag nPreTag = aTagItems.GetTagData(TAG_TYPE); + if ( (nPreTag & TAG_RESULT) == TAG_RESULT) + { + nRetValue = TestResult_StarterA( aTagItems ); + } + else if ((nPreTag & TAG_SIGNAL) == TAG_SIGNAL) + { + nRetValue = SignalHandlerA(aTagItems); + } + else if (( nPreTag & TAG_EXECUTION) == TAG_EXECUTION) + { + nRetValue = ExecutionA(aTagItems); + } + else + { + fprintf(stderr, "CallbackDispatch: First tag is unknown %8x\n", SAL_STATIC_CAST(int, nPreTag)); + // unknown TAG_TYPE + } + return nRetValue; +} + |