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