Home | History | Annotate | Download | only in eh
      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