diff --git a/Core/Code/Testing/mitkLogTest.cpp b/Core/Code/Testing/mitkLogTest.cpp index 65fe886844..0a93be0cc2 100644 --- a/Core/Code/Testing/mitkLogTest.cpp +++ b/Core/Code/Testing/mitkLogTest.cpp @@ -1,286 +1,286 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkCommon.h" #include "mitkTestingMacros.h" #include #include #include #include #include /** Documentation * * @brief Objects of this class can start an internal thread by calling the Start() method. * The thread is then logging messages until the method Stop() is called. The class * can be used to test if logging is thread-save by using multiple objects and let * them log simuntanously. */ class mitkTestLoggingThread : public itk::Object { public: mitkClassMacro(mitkTestLoggingThread,itk::Object); mitkNewMacro1Param(mitkTestLoggingThread,itk::MultiThreader::Pointer); int NumberOfMessages; protected: mitkTestLoggingThread(itk::MultiThreader::Pointer MultiThreader) { ThreadID = -1; NumberOfMessages = 0; m_MultiThreader = MultiThreader; } bool LoggingRunning; int ThreadID; itk::MultiThreader::Pointer m_MultiThreader; void LogMessages() { while(LoggingRunning) { MITK_INFO << "Test info stream in thread" << ThreadID << "\n even with newlines"; MITK_WARN << "Test warning stream in thread " << ThreadID <<". " << "Even with a very long text, even without meaning or implied meaning or content, just a long sentence to see whether something has problems with long sentences or output in files or into windows or commandlines or whatever."; MITK_DEBUG << "Test debugging stream in thread " << ThreadID; MITK_ERROR << "Test error stream in thread " << ThreadID; MITK_FATAL << "Test fatal stream in thread " << ThreadID; NumberOfMessages += 5; } } static ITK_THREAD_RETURN_TYPE ThreadStartTracking(void* pInfoStruct) { /* extract this pointer from Thread Info structure */ struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct; if (pInfo == NULL) { return ITK_THREAD_RETURN_VALUE; } if (pInfo->UserData == NULL) { return ITK_THREAD_RETURN_VALUE; } mitkTestLoggingThread *thisthread = (mitkTestLoggingThread*)pInfo->UserData; if (thisthread != NULL) thisthread->LogMessages(); return ITK_THREAD_RETURN_VALUE; } public: int Start() { LoggingRunning = true; this->ThreadID = m_MultiThreader->SpawnThread(this->ThreadStartTracking, this); return ThreadID; } void Stop() { LoggingRunning = false; } }; /** Documentation * * @brief This class holds static test methods to sturcture the test of the mitk logging mechanism. */ class mitkLogTestClass { public: static void TestSimpleLog() { bool testSucceded = true; try { MITK_INFO << "Test info stream."; MITK_WARN << "Test warning stream."; MITK_DEBUG << "Test debugging stream."; //only activated if cmake variable is on! //so no worries if you see no output for this line MITK_ERROR << "Test error stream."; MITK_FATAL << "Test fatal stream."; } catch(mitk::Exception e) { testSucceded = false; } MITK_TEST_CONDITION_REQUIRED(testSucceded,"Test logging streams."); } static void TestObjectInfoLogging() { bool testSucceded = true; try { int i = 123; float f = .32234; double d = 123123; std::string testString = "testString"; std::stringstream testStringStream; testStringStream << "test" << "String" << "Stream"; mitk::Point3D testMitkPoint; testMitkPoint.Fill(2); MITK_INFO << i; MITK_INFO << f; MITK_INFO << d; MITK_INFO << testString; - MITK_INFO << testStringStream; + MITK_INFO << testStringStream.str(); MITK_INFO << testMitkPoint; } catch(mitk::Exception e) { testSucceded = false; } MITK_TEST_CONDITION_REQUIRED(testSucceded,"Test logging of object information."); } static void TestThreadSaveLog(bool toFile) { bool testSucceded = true; try { if (toFile) { std::string filename = mitk::StandardFileLocations::GetInstance()->GetOptionDirectory() + "/testthreadlog.log"; itksys::SystemTools::RemoveFile(filename.c_str()); // remove old file, we do not want to append to large files mitk::LoggingBackend::SetLogFile(filename.c_str()); } unsigned int numberOfThreads = 20; unsigned int threadRuntimeInMilliseconds = 2000; std::vector threadIDs; std::vector threads; itk::MultiThreader::Pointer multiThreader = itk::MultiThreader::New(); for (unsigned int threadIdx = 0; threadIdx < numberOfThreads; ++threadIdx) { //initialize threads... mitkTestLoggingThread::Pointer newThread = mitkTestLoggingThread::New(multiThreader); threads.push_back(newThread); std::cout << "Created " << threadIdx << ". thread." << std::endl; } for (unsigned int threadIdx = 0; threadIdx < numberOfThreads; ++threadIdx) { //start them std::cout << "Start " << threadIdx << ". thread." << std::endl; threadIDs.push_back( threads[threadIdx]->Start() ); std::cout << threadIdx << ". thread has ID " << threadIDs[threadIdx] << std::endl; } //wait for some time (milliseconds) itksys::SystemTools::Delay( threadRuntimeInMilliseconds ); for (unsigned int threadIdx = 0; threadIdx < numberOfThreads; ++threadIdx) { //stop them std::cout << "Stop " << threadIdx << ". thread." << std::endl; threads[threadIdx]->Stop(); } for (unsigned int threadIdx = 0; threadIdx < numberOfThreads; ++threadIdx) { //Wait for all threads to end multiThreader->TerminateThread(threadIDs[threadIdx]); std::cout << "Terminated " << threadIdx << ". thread (" << threads[threadIdx]->NumberOfMessages << " messages)." << std::endl; } } catch(std::exception e) { MITK_ERROR << "exception during 'TestThreadSaveLog': "<GetOptionDirectory() + "/testlog.log"; mitk::LoggingBackend::SetLogFile(filename.c_str()); MITK_INFO << "Test logging to default filename: " << mitk::LoggingBackend::GetLogFile(); MITK_TEST_CONDITION_REQUIRED(itksys::SystemTools::FileExists(filename.c_str()),"Testing if log file exists."); //TODO delete log file? } static void TestAddAndRemoveBackends() { mbilog::BackendCout myBackend = mbilog::BackendCout(); mbilog::RegisterBackend(&myBackend); MITK_INFO << "Test logging"; mbilog::UnregisterBackend(&myBackend); //if no error occured until now, everything is ok MITK_TEST_CONDITION_REQUIRED(true,"Test add/remove logging backend."); } static void TestDefaultBackend() { //not possible now, because we cannot unregister the mitk logging backend in the moment. If such a method is added to mbilog utility one may add this test. } }; int mitkLogTest(int /* argc */, char* /*argv*/[]) { // always start with this! MITK_TEST_BEGIN("Log") MITK_TEST_OUTPUT(<<"TESTING ALL LOGGING OUTPUTS, ERROR MESSAGES ARE ALSO TESTED AND NOT MEANING AN ERROR OCCURED!") mitkLogTestClass::TestSimpleLog(); mitkLogTestClass::TestObjectInfoLogging(); mitkLogTestClass::TestLoggingToFile(); mitkLogTestClass::TestAddAndRemoveBackends(); mitkLogTestClass::TestThreadSaveLog( false ); // false = to console mitkLogTestClass::TestThreadSaveLog( true ); // true = to file // TODO actually test file somehow? // always end with this! MITK_TEST_END() }