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