1e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott/*********************************************************************************** 2e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott TestController.h 3e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 4e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott SUMMARY: An "faux-singleton" object to encapsulate a hodgepodge of state and 5e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott functionality relating to the test suite. Probably should be broken 6e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott into smaller pieces. 7e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 8e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Copyright (c) 1997 9e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Mark of the Unicorn, Inc. 10e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * 11e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * Permission to use, copy, modify, distribute and sell this software 12e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * and its documentation for any purpose is hereby granted without fee, 13e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * provided that the above copyright notice appear in all copies and 14e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * that both that copyright notice and this permission notice appear 15e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * in supporting documentation. Mark of the Unicorn makes no 16e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * representations about the suitability of this software for any 17e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott * purpose. It is provided "as is" without express or implied warranty. 18e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 19e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott***********************************************************************************/ 20e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if !INCLUDED_MOTU_nc_alloc 21e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#define INCLUDED_MOTU_nc_alloc 1 22e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 23e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include "Prefix.h" 24e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 25e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#if defined (EH_NEW_HEADERS) 26e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# include <utility> 27e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#else 28e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott# include <pair.h> 29e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif 30e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 31e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottextern long alloc_count; 32e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottextern long object_count; 33e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 34e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstruct TestController { 35e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Report that the current test has succeeded. 36e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static void ReportSuccess(int); 37e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 38e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // 39e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Leak detection 40e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // 41e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 42e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Turn the recording of the addresses of individual allocated 43e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // blocks on or off. If not called, allocations will only be 44e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // counted, but deallocations won't be checked for validity. 45e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static void TrackAllocations( bool ); 46e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static bool TrackingEnabled(); 47e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 48e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Call this to begin a new leak-detection cycle. Resets all 49e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // allocation counts, etc. 50e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static void BeginLeakDetection(); 51e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 52e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Returns true iff leak detection is currently in effect 53e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static bool LeakDetectionEnabled(); 54e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 55e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Ends leak detection and reports any resource leaks. 56e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Returns true if any occurred. 57e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static bool ReportLeaked(); 58e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 59e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // 60e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Exception-safety 61e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // 62e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 63e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Don't test for exception-safety 64e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static void TurnOffExceptions(); 65e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 66e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Set operator new to fail on the nth invocation 67e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static void SetFailureCountdown( long n ); 68e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 69e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Set operator new to never fail. 70e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static void CancelFailureCountdown(); 71e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 72e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Throws an exception if the count has been reached. Call this 73e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // before every operation that might fail in the real world. 74e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static void maybe_fail(long); 75e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 76e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // 77e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Managing verbose feedback. 78e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // 79e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 80e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Call to begin a strong, weak, or const test. If verbose 81e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // reporting is enabled, prints the test category. 82e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static void SetCurrentTestCategory( const char* str ); 83e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 84e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Call to set the name of the container being tested. 85e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static void SetCurrentContainer( const char* str ); 86e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 87e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Sets the name of the current test. 88e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static void SetCurrentTestName(const char* str); 89e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 90e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott // Turn verbose reporting on or off. 91e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static void SetVerbose(bool val); 92e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 93e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottprivate: 94e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott enum { kNotInExceptionTest = -1 }; 95e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 96e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static void ClearAllocationSet(); 97e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static void EndLeakDetection(); 98e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static void PrintTestName( bool err=false ); 99e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 100e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static long& Failure_threshold(); 101e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static long possible_failure_count; 102e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static const char* current_test; 103e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static const char* current_test_category; 104e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static const char* current_container; 105e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static bool nc_verbose; 106e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static bool never_fail; 107e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static bool track_allocations; 108e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott static bool leak_detection_enabled; 109e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}; 110e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 111e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottextern TestController gTestController; 112e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 113e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// 114e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// inline implementations 115e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// 116e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 117e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottinline void simulate_possible_failure() { 118e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott gTestController.maybe_fail(0); 119e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 120e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 121e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottinline void simulate_constructor() { 122e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott gTestController.maybe_fail(0); 123e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott ++object_count; 124e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 125e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 126e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottinline void simulate_destructor() { 127e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott --object_count; 128e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 129e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 130e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottinline void TestController::TrackAllocations(bool track) { 131e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott track_allocations = track; 132e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 133e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 134e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottinline bool TestController::TrackingEnabled() { 135e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return track_allocations; 136e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 137e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 138e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottinline void TestController::SetFailureCountdown(long count) { 139e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott Failure_threshold() = count; 140e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott possible_failure_count = 0; 141e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 142e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 143e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottinline void TestController::CancelFailureCountdown() { 144e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott Failure_threshold() = kNotInExceptionTest; 145e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 146e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 147e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottinline void TestController::BeginLeakDetection() { 148e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott alloc_count = 0; 149e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott object_count = 0; 150e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott ClearAllocationSet(); 151e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott leak_detection_enabled = true; 152e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 153e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 154e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottinline bool TestController::LeakDetectionEnabled() { 155e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott return leak_detection_enabled; 156e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 157e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 158e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottinline void TestController::EndLeakDetection() { 159e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott leak_detection_enabled = false; 160e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 161e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 162e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottinline void TestController::SetCurrentTestCategory(const char* str) { 163e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott current_test_category = str; 164e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott if (nc_verbose) 165e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott PrintTestName(); 166e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 167e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 168e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottinline void TestController::SetCurrentContainer(const char* str) { 169e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott current_container=str; 170e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 171e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 172e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottinline void TestController::SetCurrentTestName(const char* str) { 173e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott current_test = str; 174e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 175e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 176e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottinline void TestController::SetVerbose(bool val) { 177e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott nc_verbose = val; 178e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 179e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 180e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottinline void TestController::TurnOffExceptions() { 181e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott never_fail = true; 182e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} 183e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott 184e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#endif // INCLUDED_MOTU_nc_alloc 185