test.cpp

Go to the documentation of this file.
00001 
00042 #include "linden_common.h"
00043 #include "llerrorcontrol.h"
00044 #include "lltut.h"
00045 
00046 #include <apr-1/apr_pools.h>
00047 #include <apr-1/apr_getopt.h>
00048 
00049 // the CTYPE_WORKAROUND is needed for linux dev stations that don't
00050 // have the broken libc6 packages needed by our out-of-date static 
00051 // libs (such as libcrypto and libcurl). -- Leviathan 20060113
00052 #ifdef CTYPE_WORKAROUND
00053 #       include "ctype_workaround.h"
00054 #endif
00055 
00056 
00057 namespace tut
00058 {
00059     test_runner_singleton runner;
00060 }
00061 
00062 class LLTestCallback : public tut::callback
00063 {
00064 public:
00065         LLTestCallback(bool verbose_mode) :
00066                 mVerboseMode(verbose_mode),
00067                 mTotalTests(0),
00068                 mPassedTests(0),
00069                 mFailedTests(0),
00070                 mSkippedTests(0),
00071                 mSkipedFailTests(0)
00072         {
00073         }
00074 
00075         void run_started()
00076         {
00077                 //std::cout << "run_started" << std::endl;
00078         }
00079 
00080         void test_completed(const tut::test_result& tr)
00081         {
00082                 ++mTotalTests;
00083                 std::ostringstream out;
00084                 out << "[" << tr.group << ", " << tr.test << "] ";
00085                 switch(tr.result)
00086                 {
00087                 case tut::test_result::ok:
00088                         ++mPassedTests;
00089                         out << "ok";
00090                         break;
00091                 case tut::test_result::fail:
00092                         ++mFailedTests;
00093                         out << "fail";
00094                         break;
00095                 case tut::test_result::ex:
00096                         ++mFailedTests;
00097                         out << "exception";
00098                         break;
00099                 case tut::test_result::warn:
00100                         ++mFailedTests;
00101                         out << "test destructor throw";
00102                         break;
00103                 case tut::test_result::term:
00104                         ++mFailedTests;
00105                         out << "abnormal termination";
00106                         break;
00107                 case tut::test_result::skip:
00108                         ++mSkippedTests;
00109                         out << "skipped";
00110                         break;
00111                 case tut::test_result::skip_fail:
00112                         ++mSkipedFailTests;
00113                         out << "skipped known failure";
00114                         break;
00115                 default:
00116                         ++mFailedTests;
00117                         out << "unknown";
00118                 }
00119                 if(mVerboseMode || (tr.result != tut::test_result::ok))
00120                 {
00121                         if(!tr.message.empty())
00122                         {
00123                                 out << ": '" << tr.message << "'";
00124                         }
00125                         std::cout << out.str() << std::endl;
00126                 }
00127         }
00128 
00129         void run_completed()
00130         {
00131                 std::cout << std::endl;
00132                 std::cout << "Total Tests:   " << mTotalTests << std::endl;
00133                 std::cout << "Passed Tests: " << mPassedTests << std::endl;
00134                 
00135                 if (mSkippedTests > 0)
00136                 {
00137                         std::cout << "Skipped Tests: " << mSkippedTests << std::endl;
00138                 }
00139 
00140                 if (mSkipedFailTests > 0)
00141                 {
00142                         std::cout << "Skipped known failures: " << mSkipedFailTests
00143                                 << std::endl;
00144                 }
00145 
00146                 if(mFailedTests > 0)
00147                 {
00148                         std::cout << "*********************************" << std::endl;
00149                         std::cout << "Failed Tests:   " << mFailedTests << std::endl;
00150                         std::cout << "Please report or fix the problem." << std::endl;
00151                         std::cout << "*********************************" << std::endl;
00152                         exit(1);
00153                 }
00154         }
00155 
00156 protected:
00157         bool mVerboseMode;
00158         int mTotalTests;
00159         int mPassedTests;
00160         int mFailedTests;
00161         int mSkippedTests;
00162         int mSkipedFailTests;
00163 };
00164 
00165 static const apr_getopt_option_t TEST_CL_OPTIONS[] =
00166 {
00167         {"help", 'h', 0, "Print the help message."},
00168         {"list", 'l', 0, "List available test groups."},
00169         {"verbose", 'v', 0, "Verbose output."},
00170         {"group", 'g', 1, "Run test group specified by option argument."},
00171         {"skip", 's', 1, "Skip test number specified by option argument. Only works when a specific group is being tested"},
00172         {"wait", 'w', 0, "Wait for input before exit."},
00173         {0, 0, 0, 0}
00174 };
00175 
00176 void stream_usage(std::ostream& s, const char* app)
00177 {
00178         s << "Usage: " << app << " [OPTIONS]" << std::endl
00179           << std::endl;
00180 
00181         s << "This application runs the unit tests." << std::endl << std::endl;
00182 
00183         s << "Options: " << std::endl;
00184         const apr_getopt_option_t* option = &TEST_CL_OPTIONS[0];
00185         while(option->name)
00186         {
00187                 s << "  ";
00188                 s << "  -" << (char)option->optch << ", --" << option->name
00189                   << std::endl;
00190                 s << "\t" << option->description << std::endl << std::endl;
00191                 ++option;
00192         }
00193 
00194         s << "Examples:" << std::endl;
00195         s << "  " << app << " --verbose" << std::endl;
00196         s << "\tRun all the tests and report all results." << std::endl;
00197         s << "  " << app << " --list" << std::endl;
00198         s << "\tList all available test groups." << std::endl;
00199         s << "  " << app << " --group=uuid" << std::endl;
00200         s << "\tRun the test group 'uuid'." << std::endl;
00201         s << "  " << app << " --skip=2" << std::endl;
00202         s << "\tSkip test case 2." << std::endl;
00203 }
00204 
00205 void stream_groups(std::ostream& s, const char* app)
00206 {
00207         s << "Registered test groups:" << std::endl;
00208         tut::groupnames gl = tut::runner.get().list_groups();
00209         tut::groupnames::const_iterator it = gl.begin();
00210         tut::groupnames::const_iterator end = gl.end();
00211         for(; it != end; ++it)
00212         {
00213                 s << "  " << *(it) << std::endl;
00214         }
00215 }
00216 
00217 void wouldHaveCrashed(const std::string& message)
00218 {
00219         tut::fail("llerrs message: " + message);
00220 }
00221 
00222 int main(int argc, char **argv)
00223 {
00224         LLError::initForApplication(".");
00225         LLError::setFatalFunction(wouldHaveCrashed);
00226         LLError::setDefaultLevel(LLError::LEVEL_ERROR);
00227                 // *FIX: should come from error config file
00228         
00229 #ifdef CTYPE_WORKAROUND
00230         ctype_workaround();
00231 #endif
00232 
00233         apr_initialize();
00234         apr_pool_t* pool = NULL;
00235         if(APR_SUCCESS != apr_pool_create(&pool, NULL))
00236         {
00237                 std::cerr << "Unable to initialize pool" << std::endl;
00238                 return 1;
00239         }
00240         apr_getopt_t* os = NULL;
00241         if(APR_SUCCESS != apr_getopt_init(&os, pool, argc, argv))
00242         {
00243                 std::cerr << "Unable to  pool" << std::endl;
00244                 return 1;
00245         }
00246 
00247         // values used for controlling application
00248         bool verbose_mode = false;
00249         bool wait_at_exit = false;
00250         int  skip_test_id = 0;
00251         std::string test_group;
00252 
00253         // values use for options parsing
00254         apr_status_t apr_err;
00255         const char* opt_arg = NULL;
00256         int opt_id = 0;
00257         while(true)
00258         {
00259                 apr_err = apr_getopt_long(os, TEST_CL_OPTIONS, &opt_id, &opt_arg);
00260                 if(APR_STATUS_IS_EOF(apr_err)) break;
00261                 if(apr_err)
00262                 {
00263                         char buf[255];          /* Flawfinder: ignore */
00264                         std::cerr << "Error parsing options: "
00265                                           << apr_strerror(apr_err, buf, 255) << std::endl;
00266                         return 1;
00267                 }
00268                 switch (opt_id)
00269                 {
00270                 case 'g':
00271                         test_group.assign(opt_arg);
00272                         break;
00273                 case 's':
00274                         skip_test_id = atoi(opt_arg);
00275                         break;                  
00276                 case 'h':
00277                         stream_usage(std::cout, argv[0]);
00278                         return 0;
00279                         break;
00280                 case 'l':
00281                         stream_groups(std::cout, argv[0]);
00282                         return 0;
00283                 case 'v':
00284                         verbose_mode = true;
00285                         break;
00286                 case 'w':
00287                         wait_at_exit = true;
00288                         break;
00289                 default:
00290                         stream_usage(std::cerr, argv[0]);
00291                         return 1;
00292                         break;
00293                 }
00294         }
00295 
00296         // run the tests
00297         LLTestCallback callback(verbose_mode);
00298         tut::runner.get().set_callback(&callback);
00299         
00300         if(test_group.empty())
00301         {
00302                 tut::runner.get().run_tests();
00303         }
00304         else
00305         {
00306                 tut::runner.get().run_tests(test_group, skip_test_id);
00307         }
00308 
00309         if (wait_at_exit)
00310         {
00311                 std::cerr << "Waiting for input before exiting..." << std::endl;
00312                 std::cin.get();
00313         }
00314         
00315         apr_terminate();
00316         return 0;
00317 }

Generated on Thu Jul 1 06:09:59 2010 for Second Life Viewer by  doxygen 1.4.7