1 #ifndef _beos_test_shell_h_ 2 #define _beos_test_shell_h_ 3 4 #include <LockerSyncObject.h> 5 #include <cppunit/Exception.h> 6 #include <cppunit/Test.h> 7 #include <cppunit/TestListener.h> 8 #include <cppunit/TestResult.h> 9 #include <cppunit/TestResultCollector.h> 10 #include <image.h> 11 #include <TestSuite.h> 12 #include <map> 13 #include <set> 14 #include <string> 15 16 class BDirectory; 17 class BLocker; 18 class BPath; 19 20 class ElfSymbolPatchGroup; 21 22 // Defines SuiteFunction to be a pointer to a function that 23 // takes no arguments and returns a pointer to a CppUnit::Test 24 typedef CppUnit::Test* (*SuiteFunction)(void); 25 26 // This is just absurd to have to type... 27 typedef CppUnit::SynchronizedObject::SynchronizationObject SyncObject; 28 29 /*! \brief Executes a statement that is supposed to call debugger(). 30 An exception is thrown if the debugger is not invoked by the 31 statement. 32 */ 33 #define CPPUNIT_ASSERT_DEBUGGER(statement) \ 34 BTestShell::GlobalShell()->ExpectDebuggerCall(); \ 35 statement; \ 36 ::CppUnit::Asserter::failIf( \ 37 !BTestShell::GlobalShell()->WasDebuggerCalled(), \ 38 (#statement), \ 39 CPPUNIT_SOURCELINE() ); 40 41 42 //! BeOS savvy command line interface for the CppUnit testing framework. 43 /*! This class provides a fully functional command-line testing interface 44 built on top of the CppUnit testing library. You add named test suites 45 via AddSuite(), and then call Run(), which does all the dirty work. The 46 user can get a list of each test installed via AddSuite(), and optionally 47 can opt to run only a specified set of them. 48 */ 49 class CPPUNIT_API BTestShell { 50 public: 51 BTestShell(const std::string &description = "", SyncObject *syncObject = 0); 52 virtual ~BTestShell(); 53 54 // This function is used to add the tests for a given kit (as contained 55 // in a BTestSuite object) to the list of available tests. The shell assumes 56 // ownership of the BTestSuite object. Each test in the kit is added to 57 // the list of tests via a call to AddTest(string 58 status_t AddSuite(BTestSuite *kit); 59 60 // This function is used to add test suites to the list of available 61 // tests. A SuiteFunction is just a function that takes no parameters 62 // and returns a pointer to a CppUnit::Test object. Return NULL at 63 // your own risk :-). The name given is the name that will be presented 64 // when the program is run with "--list" as an argument. Usually the 65 // given suite would be a test suite for an entire class, but that's 66 // not a requirement. 67 void AddTest(const std::string &name, CppUnit::Test* test); 68 69 // This function loads all the test addons it finds in the given 70 // directory, returning the number of tests actually loaded. 71 int32 LoadSuitesFrom(BDirectory *libDir); 72 73 // This is the function you call after you've added all your test 74 // suites with calls to AddSuite(). It runs the test, or displays 75 // help, or lists installed tests, or whatever, depending on the 76 // command-line arguments passed in. 77 int Run(int argc, char *argv[]); 78 79 // Verbosity Level enumeration and accessor function 80 enum VerbosityLevel { v0, v1, v2, v3, v4 }; 81 VerbosityLevel Verbosity() const; 82 83 // Returns true if verbosity is high enough that individual tests are 84 // allowed to make noise. 85 bool BeVerbose() const { return Verbosity() >= v2; }; 86 87 static bool GlobalBeVerbose() { return (fGlobalShell ? fGlobalShell->BeVerbose() : true); }; 88 89 // Returns a pointer to a global BTestShell object. This function is 90 // something of a hack, used to give BTestCase and its subclasses 91 // access to verbosity information. Don't rely on it if you don't 92 // have to (and always make sure the pointer it returns isn't NULL 93 // before you try to use it :-). 94 static BTestShell* GlobalShell() { return fGlobalShell; }; 95 96 // Sets the global BTestShell pointer. The BTestShell class does 97 // not assume ownership of the object. 98 static void SetGlobalShell(BTestShell *shell) { fGlobalShell = shell; }; 99 100 const char* TestDir() const; 101 static const char* GlobalTestDir() { return (fGlobalShell ? fGlobalShell->TestDir() : NULL); }; 102 103 void ExpectDebuggerCall(); 104 bool WasDebuggerCalled(); 105 106 protected: 107 typedef std::map<std::string, CppUnit::Test*> TestMap; 108 typedef std::map<std::string, BTestSuite*> SuiteMap; 109 110 VerbosityLevel fVerbosityLevel; 111 std::set<std::string> fTestsToRun; 112 std::set<std::string> fSuitesToRun; 113 TestMap fTests; 114 SuiteMap fSuites; 115 std::set<std::string> fLibDirs; 116 CppUnit::TestResult fTestResults; 117 CppUnit::TestResultCollector fResultsCollector; 118 std::string fDescription; 119 static BTestShell* fGlobalShell; 120 static const char indent[]; 121 bool fListTestsAndExit; 122 BPath *fTestDir; 123 int32 fTLSDebuggerCall; 124 #ifndef NO_ELF_SYMBOL_PATCHING 125 BLocker *fPatchGroupLocker; 126 ElfSymbolPatchGroup *fPatchGroup; 127 void (*fOldDebuggerHook)(const char*); 128 image_id (*fOldLoadAddOnHook)(const char*); 129 status_t (*fOldUnloadAddOnHook)(image_id); 130 #endif // ! NO_ELF_SYMBOL_PATCHING 131 132 //! Prints a brief description of the program. 133 virtual void PrintDescription(int argc, char *argv[]); 134 135 //! Prints out command line argument instructions 136 void PrintHelp(); 137 138 /*! \brief Prints out the list of valid command line arguments. 139 Called by PrintHelp(). 140 */ 141 virtual void PrintValidArguments(); 142 143 //! Prints out a list of all the currently available tests 144 void PrintInstalledTests(); 145 146 /*! \brief Handles command line arguments; returns true if everything goes 147 okay, false if not (or if the program just needs to terminate without 148 running any tests). Modifies settings in "settings" as necessary. 149 */ 150 bool ProcessArguments(int argc, char *argv[]); 151 152 //! Processes a single argument, given by the \c arg parameter. 153 virtual bool ProcessArgument(std::string arg, int argc, char *argv[]); 154 155 //! Makes any necessary pre-test preparations 156 void InitOutput(); 157 158 /*! \brief Prints out the test results in the proper format per 159 the specified verbosity level. 160 */ 161 void PrintResults(); 162 163 /*! \brief Searches all the paths in \c fLibDirs, loading any dynamically 164 loadable suites it finds. 165 */ 166 virtual void LoadDynamicSuites(); 167 168 //! Sets the current test directory. 169 void UpdateTestDir(char *argv[]); 170 171 void InstallPatches(); 172 void UninstallPatches(); 173 174 private: 175 //! Prevents the use of the copy constructor. 176 BTestShell( const BTestShell © ); 177 178 //! Prevents the use of the copy operator. 179 void operator =( const BTestShell © ); 180 181 #ifndef NO_ELF_SYMBOL_PATCHING 182 void _Debugger(const char* message); 183 image_id _LoadAddOn(const char* path); 184 status_t _UnloadAddOn(image_id image); 185 186 static void _DebuggerHook(const char* message); 187 static image_id _LoadAddOnHook(const char* path); 188 static status_t _UnloadAddOnHook(image_id image); 189 #endif // ! NO_ELF_SYMBOL_PATCHING 190 191 }; // class BTestShell 192 193 #endif // _beos_test_shell_h_ 194