test.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:9k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file test.cpp
  3.  * @author Phoenix
  4.  * @date 2005-09-26
  5.  * @brief Entry point for the test app.
  6.  *
  7.  * $LicenseInfo:firstyear=2005&license=viewergpl$
  8.  * 
  9.  * Copyright (c) 2005-2010, Linden Research, Inc.
  10.  * 
  11.  * Second Life Viewer Source Code
  12.  * The source code in this file ("Source Code") is provided by Linden Lab
  13.  * to you under the terms of the GNU General Public License, version 2.0
  14.  * ("GPL"), unless you have obtained a separate licensing agreement
  15.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  16.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  17.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  18.  * 
  19.  * There are special exceptions to the terms and conditions of the GPL as
  20.  * it is applied to this Source Code. View the full text of the exception
  21.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  22.  * online at
  23.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  24.  * 
  25.  * By copying, modifying or distributing this software, you acknowledge
  26.  * that you have read and understood your obligations described above,
  27.  * and agree to abide by those obligations.
  28.  * 
  29.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  30.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  31.  * COMPLETENESS OR PERFORMANCE.
  32.  * $/LicenseInfo$
  33.  */
  34. /** 
  35.  *
  36.  * You can add tests by creating a new cpp file in this directory, and
  37.  * rebuilding. There are at most 50 tests per testgroup without a
  38.  * little bit of template parameter and makefile tweaking.
  39.  *
  40.  */
  41. #include "linden_common.h"
  42. #include "llerrorcontrol.h"
  43. #include "lltut.h"
  44. #include "apr_pools.h"
  45. #include "apr_getopt.h"
  46. // the CTYPE_WORKAROUND is needed for linux dev stations that don't
  47. // have the broken libc6 packages needed by our out-of-date static 
  48. // libs (such as libcrypto and libcurl). -- Leviathan 20060113
  49. #ifdef CTYPE_WORKAROUND
  50. # include "ctype_workaround.h"
  51. #endif
  52. #ifndef LL_WINDOWS
  53. #include <gmock/gmock.h>
  54. #include <gtest/gtest.h>
  55. #endif
  56. namespace tut
  57. {
  58. std::string sSourceDir;
  59.     test_runner_singleton runner;
  60. }
  61. class LLTestCallback : public tut::callback
  62. {
  63. public:
  64. LLTestCallback(bool verbose_mode, std::ostream *stream) :
  65. mVerboseMode(verbose_mode),
  66. mTotalTests(0),
  67. mPassedTests(0),
  68. mFailedTests(0),
  69. mSkippedTests(0),
  70. mStream(stream)
  71. {
  72. }
  73. void run_started()
  74. {
  75. //std::cout << "run_started" << std::endl;
  76. }
  77. void test_completed(const tut::test_result& tr)
  78. {
  79. ++mTotalTests;
  80. std::ostringstream out;
  81. out << "[" << tr.group << ", " << tr.test << "] ";
  82. switch(tr.result)
  83. {
  84. case tut::test_result::ok:
  85. ++mPassedTests;
  86. out << "ok";
  87. break;
  88. case tut::test_result::fail:
  89. ++mFailedTests;
  90. out << "fail";
  91. break;
  92. case tut::test_result::ex:
  93. ++mFailedTests;
  94. out << "exception";
  95. break;
  96. case tut::test_result::warn:
  97. ++mFailedTests;
  98. out << "test destructor throw";
  99. break;
  100. case tut::test_result::term:
  101. ++mFailedTests;
  102. out << "abnormal termination";
  103. break;
  104. case tut::test_result::skip:
  105. ++mSkippedTests;
  106. out << "skipped known failure";
  107. break;
  108. default:
  109. ++mFailedTests;
  110. out << "unknown";
  111. }
  112. if(mVerboseMode || (tr.result != tut::test_result::ok))
  113. {
  114. if(!tr.message.empty())
  115. {
  116. out << ": '" << tr.message << "'";
  117. }
  118. if (mStream)
  119. {
  120. *mStream << out.str() << std::endl;
  121. }
  122. std::cout << out.str() << std::endl;
  123. }
  124. }
  125. void run_completed()
  126. {
  127. if (mStream)
  128. {
  129. run_completed_(*mStream);
  130. }
  131. run_completed_(std::cout);
  132. }
  133. int getFailedTests() const { return mFailedTests; }
  134. private:
  135. void run_completed_(std::ostream &stream)
  136. {
  137. stream << "tTotal Tests:t" << mTotalTests << std::endl;
  138. stream << "tPassed Tests:t" << mPassedTests;
  139. if (mPassedTests == mTotalTests)
  140. {
  141. stream << "tYAY!! \o/";
  142. }
  143. stream << std::endl;
  144. if (mSkippedTests > 0)
  145. {
  146. stream << "tSkipped known failures:t" << mSkippedTests
  147. << std::endl;
  148. }
  149. if(mFailedTests > 0)
  150. {
  151. stream << "*********************************" << std::endl;
  152. stream << "Failed Tests:t" << mFailedTests << std::endl;
  153. stream << "Please report or fix the problem." << std::endl;
  154. stream << "*********************************" << std::endl;
  155. }
  156. }
  157. protected:
  158. bool mVerboseMode;
  159. int mTotalTests;
  160. int mPassedTests;
  161. int mFailedTests;
  162. int mSkippedTests;
  163. std::ostream *mStream;
  164. };
  165. static const apr_getopt_option_t TEST_CL_OPTIONS[] =
  166. {
  167. {"help", 'h', 0, "Print the help message."},
  168. {"list", 'l', 0, "List available test groups."},
  169. {"verbose", 'v', 0, "Verbose output."},
  170. {"group", 'g', 1, "Run test group specified by option argument."},
  171. {"output", 'o', 1, "Write output to the named file."},
  172. {"sourcedir", 's', 1, "Project source file directory from CMake."},
  173. {"touch", 't', 1, "Touch the given file if all tests succeed"},
  174. {"wait", 'w', 0, "Wait for input before exit."},
  175. {"debug", 'd', 0, "Emit full debug logs."},
  176. {0, 0, 0, 0}
  177. };
  178. void stream_usage(std::ostream& s, const char* app)
  179. {
  180. s << "Usage: " << app << " [OPTIONS]" << std::endl
  181.   << std::endl;
  182. s << "This application runs the unit tests." << std::endl << std::endl;
  183. s << "Options: " << std::endl;
  184. const apr_getopt_option_t* option = &TEST_CL_OPTIONS[0];
  185. while(option->name)
  186. {
  187. s << "  ";
  188. s << "  -" << (char)option->optch << ", --" << option->name
  189.   << std::endl;
  190. s << "t" << option->description << std::endl << std::endl;
  191. ++option;
  192. }
  193. s << "Examples:" << std::endl;
  194. s << "  " << app << " --verbose" << std::endl;
  195. s << "tRun all the tests and report all results." << std::endl;
  196. s << "  " << app << " --list" << std::endl;
  197. s << "tList all available test groups." << std::endl;
  198. s << "  " << app << " --group=uuid" << std::endl;
  199. s << "tRun the test group 'uuid'." << std::endl;
  200. }
  201. void stream_groups(std::ostream& s, const char* app)
  202. {
  203. s << "Registered test groups:" << std::endl;
  204. tut::groupnames gl = tut::runner.get().list_groups();
  205. tut::groupnames::const_iterator it = gl.begin();
  206. tut::groupnames::const_iterator end = gl.end();
  207. for(; it != end; ++it)
  208. {
  209. s << "  " << *(it) << std::endl;
  210. }
  211. }
  212. void wouldHaveCrashed(const std::string& message)
  213. {
  214. tut::fail("llerrs message: " + message);
  215. }
  216. int main(int argc, char **argv)
  217. {
  218. // The following line must be executed to initialize Google Mock
  219. // (and Google Test) before running the tests.
  220. #ifndef LL_WINDOWS
  221. ::testing::InitGoogleMock(&argc, argv);
  222. #endif
  223. LLError::initForApplication(".");
  224. LLError::setFatalFunction(wouldHaveCrashed);
  225. LLError::setDefaultLevel(LLError::LEVEL_ERROR);
  226. //< *TODO: should come from error config file. Note that we
  227. // have a command line option that sets this to debug.
  228. #ifdef CTYPE_WORKAROUND
  229. ctype_workaround();
  230. #endif
  231. apr_initialize();
  232. apr_pool_t* pool = NULL;
  233. if(APR_SUCCESS != apr_pool_create(&pool, NULL))
  234. {
  235. std::cerr << "Unable to initialize pool" << std::endl;
  236. return 1;
  237. }
  238. apr_getopt_t* os = NULL;
  239. if(APR_SUCCESS != apr_getopt_init(&os, pool, argc, argv))
  240. {
  241. std::cerr << "Unable to  pool" << std::endl;
  242. return 1;
  243. }
  244. // values used for controlling application
  245. bool verbose_mode = false;
  246. bool wait_at_exit = false;
  247. std::string test_group;
  248. // values use for options parsing
  249. apr_status_t apr_err;
  250. const char* opt_arg = NULL;
  251. int opt_id = 0;
  252. std::ofstream *output = NULL;
  253. const char *touch = NULL;
  254. while(true)
  255. {
  256. apr_err = apr_getopt_long(os, TEST_CL_OPTIONS, &opt_id, &opt_arg);
  257. if(APR_STATUS_IS_EOF(apr_err)) break;
  258. if(apr_err)
  259. {
  260. char buf[255]; /* Flawfinder: ignore */
  261. std::cerr << "Error parsing options: "
  262.   << apr_strerror(apr_err, buf, 255) << std::endl;
  263. return 1;
  264. }
  265. switch (opt_id)
  266. {
  267. case 'g':
  268. test_group.assign(opt_arg);
  269. break;
  270. case 'h':
  271. stream_usage(std::cout, argv[0]);
  272. return 0;
  273. break;
  274. case 'l':
  275. stream_groups(std::cout, argv[0]);
  276. return 0;
  277. case 'v':
  278. verbose_mode = true;
  279. break;
  280. case 'o':
  281. output = new std::ofstream;
  282. output->open(opt_arg);
  283. break;
  284. case 's': // --sourcedir
  285. tut::sSourceDir = opt_arg;
  286. // For convenience, so you can use tut::sSourceDir + "myfile"
  287. tut::sSourceDir += '/';
  288. break;
  289. case 't':
  290. touch = opt_arg;
  291. break;
  292. case 'w':
  293. wait_at_exit = true;
  294. break;
  295. case 'd':
  296. // *TODO: should come from error config file. We set it to
  297. // ERROR by default, so this allows full debug levels.
  298. LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
  299. break;
  300. default:
  301. stream_usage(std::cerr, argv[0]);
  302. return 1;
  303. break;
  304. }
  305. }
  306. // run the tests
  307. LLTestCallback callback(verbose_mode, output);
  308. tut::runner.get().set_callback(&callback);
  309. if(test_group.empty())
  310. {
  311. tut::runner.get().run_tests();
  312. }
  313. else
  314. {
  315. tut::runner.get().run_tests(test_group);
  316. }
  317. bool success = (callback.getFailedTests() == 0);
  318. if (wait_at_exit)
  319. {
  320. std::cerr << "Press return to exit..." << std::endl;
  321. std::cin.get();
  322. }
  323. if (output)
  324. {
  325. output->close();
  326. delete output;
  327. }
  328. if (touch && success)
  329. {
  330. std::ofstream s;
  331. s.open(touch);
  332. s << "ok" << std::endl;
  333. s.close();
  334. }
  335. apr_terminate();
  336. int retval = (success ? 0 : 1);
  337. return retval;
  338. }