sl@0: /*********************************************************************************** sl@0: TestController.h sl@0: sl@0: SUMMARY: An "faux-singleton" object to encapsulate a hodgepodge of state and sl@0: functionality relating to the test suite. Probably should be broken sl@0: into smaller pieces. sl@0: sl@0: * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. sl@0: * sl@0: * Copyright (c) 1997 sl@0: * Mark of the Unicorn, Inc. sl@0: * sl@0: * Permission to use, copy, modify, distribute and sell this software sl@0: * and its documentation for any purpose is hereby granted without fee, sl@0: * provided that the above copyright notice appear in all copies and sl@0: * that both that copyright notice and this permission notice appear sl@0: * in supporting documentation. Mark of the Unicorn makes no sl@0: * representations about the suitability of this software for any sl@0: * purpose. It is provided "as is" without express or implied warranty. sl@0: sl@0: ***********************************************************************************/ sl@0: #if !INCLUDED_MOTU_nc_alloc sl@0: #define INCLUDED_MOTU_nc_alloc 1 sl@0: sl@0: #include "Prefix.h" sl@0: sl@0: #if defined (EH_NEW_HEADERS) sl@0: # include <utility> sl@0: #else sl@0: # include <pair.h> sl@0: #endif sl@0: sl@0: extern long alloc_count; sl@0: extern long object_count; sl@0: sl@0: //struct sl@0: class TestController { sl@0: public: sl@0: // Report that the current test has succeeded. sl@0: static void ReportSuccess(int); sl@0: sl@0: // sl@0: // Leak detection sl@0: // sl@0: sl@0: // Turn the recording of the addresses of individual allocated sl@0: // blocks on or off. If not called, allocations will only be sl@0: // counted, but deallocations won't be checked for validity. sl@0: static void TrackAllocations( bool ); sl@0: static bool TrackingEnabled(); sl@0: sl@0: // Call this to begin a new leak-detection cycle. Resets all sl@0: // allocation counts, etc. sl@0: static void BeginLeakDetection(); sl@0: sl@0: // Returns true iff leak detection is currently in effect sl@0: static bool LeakDetectionEnabled(); sl@0: sl@0: // Ends leak detection and reports any resource leaks. sl@0: // Returns true if any occurred. sl@0: static bool ReportLeaked(); sl@0: sl@0: // sl@0: // Exception-safety sl@0: // sl@0: sl@0: // Don't test for exception-safety sl@0: static void TurnOffExceptions(); sl@0: sl@0: // Set operator new to fail on the nth invocation sl@0: static void SetFailureCountdown( long n ); sl@0: sl@0: // Set operator new to never fail. sl@0: static void CancelFailureCountdown(); sl@0: sl@0: // Throws an exception if the count has been reached. Call this sl@0: // before every operation that might fail in the real world. sl@0: static void maybe_fail(long); sl@0: sl@0: // sl@0: // Managing verbose feedback. sl@0: // sl@0: sl@0: // Call to begin a strong, weak, or const test. If verbose sl@0: // reporting is enabled, prints the test category. sl@0: static void SetCurrentTestCategory( const char* str ); sl@0: sl@0: // Call to set the name of the container being tested. sl@0: static void SetCurrentContainer( const char* str ); sl@0: sl@0: // Sets the name of the current test. sl@0: static void SetCurrentTestName(const char* str); sl@0: sl@0: // Turn verbose reporting on or off. sl@0: static void SetVerbose(bool val); sl@0: sl@0: private: sl@0: enum { kNotInExceptionTest = -1 }; sl@0: sl@0: static void ClearAllocationSet(); sl@0: static void EndLeakDetection(); sl@0: static void PrintTestName( bool err=false ); sl@0: sl@0: static long& Failure_threshold(); sl@0: static long possible_failure_count; sl@0: static const char* current_test; sl@0: static const char* current_test_category; sl@0: static const char* current_container; sl@0: static bool nc_verbose; sl@0: static bool never_fail; sl@0: static bool track_allocations; sl@0: static bool leak_detection_enabled; sl@0: }; sl@0: sl@0: extern TestController gTestController; sl@0: sl@0: sl@0: // sl@0: // inline implementations sl@0: // sl@0: inline void simulate_possible_failure() { sl@0: gTestController.maybe_fail(0); sl@0: } sl@0: sl@0: inline void simulate_constructor() { sl@0: gTestController.maybe_fail(0); sl@0: ++object_count; sl@0: } sl@0: sl@0: inline void simulate_destructor() { sl@0: --object_count; sl@0: } sl@0: #if 1 //enable/disable inline functions sl@0: inline void TestController::TrackAllocations(bool track) { sl@0: track_allocations = track; sl@0: } sl@0: sl@0: inline bool TestController::TrackingEnabled() { sl@0: return track_allocations; sl@0: } sl@0: sl@0: inline void TestController::SetFailureCountdown(long count) { sl@0: Failure_threshold() = count; sl@0: possible_failure_count = 0; sl@0: } sl@0: sl@0: inline void TestController::CancelFailureCountdown() { sl@0: Failure_threshold() = kNotInExceptionTest; sl@0: } sl@0: sl@0: inline void TestController::BeginLeakDetection() { sl@0: alloc_count = 0; sl@0: object_count = 0; sl@0: ClearAllocationSet(); sl@0: leak_detection_enabled = true; sl@0: } sl@0: sl@0: inline bool TestController::LeakDetectionEnabled() { sl@0: return leak_detection_enabled; sl@0: } sl@0: sl@0: inline void TestController::EndLeakDetection() { sl@0: leak_detection_enabled = false; sl@0: } sl@0: sl@0: inline void TestController::SetCurrentTestCategory(const char* str) { sl@0: current_test_category = str; sl@0: if (nc_verbose) sl@0: PrintTestName(); sl@0: } sl@0: sl@0: inline void TestController::SetCurrentContainer(const char* str) { sl@0: current_container=str; sl@0: } sl@0: sl@0: inline void TestController::SetCurrentTestName(const char* str) { sl@0: current_test = str; sl@0: } sl@0: sl@0: inline void TestController::SetVerbose(bool val) { sl@0: nc_verbose = val; sl@0: } sl@0: sl@0: inline void TestController::TurnOffExceptions() { sl@0: never_fail = true; sl@0: } sl@0: #endif sl@0: #endif // INCLUDED_MOTU_nc_alloc