ubertest.php 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. <?php
  2. //
  3. // $Id$
  4. //
  5. $sd_managed_searchd = false;
  6. $sd_skip_indexer = false;
  7. $g_ignore_weights = false;
  8. $g_pick_query = -1;
  9. require_once ( "settings.inc" );
  10. //////////////////////
  11. // parse command line
  12. //////////////////////
  13. $args = $_SERVER["argv"];
  14. array_shift ( $args );
  15. if ( !is_array($args) || empty($args) )
  16. {
  17. print ( "Usage: php -f ubertest.php <MODE> [OPTIONS] [TESTDIRS ...]\n" );
  18. print ( "\nModes are:\n" );
  19. print ( "g, gen\t\t\tgenerate reference ('model') test results\n" );
  20. print ( "t, test\t\t\trun tests and compare results to reference\n" );
  21. print ( "qt\t\t\tsame as test, but skips user-configured slow tests\n" );
  22. print ( "\nOptions are:\n" );
  23. print ( "-u, --user <USER>\tuse 'USER' as MySQL user\n" );
  24. print ( "-p, --password <PASS>\tuse 'PASS' as MySQL password\n" );
  25. print ( "-i, --indexer <PATH>\tpath to indexer\n" );
  26. print ( "-s, --searchd <PATH>\tpath to searchd\n" );
  27. print ( "--strict\t\tterminate on the first failure (for automatic runs)\n" );
  28. print ( "--strict-verbose\tterminate on the first failure and copy the last report to report.txt (for automatic runs)\n" );
  29. print ( "--managed\t\tdon't run searchd during test (for debugging)\n" );
  30. print ( "--skip-indexer\t\tskip DB creation and indexer stages and go directly to queries/custom tests\n");
  31. print ( "--rt\t\t\ttest RT backend (auto-convert all local indexes)\n" );
  32. print ( "--no-drop-db\t\tKeep test db tables after the test (for debugging)\n");
  33. print ( "--no-demo\t\tJust skip all tests without models. Else - run them, but never fail (for debugging)\n");
  34. print ( "--no-marks\t\tDon't mark the output of every test in the logs.\n");
  35. print ( "--ignore-weights\tIgnore differences in weights. (Useful for testing that reference database changes are ok.)\n" );
  36. print ( "--cwd\t\t\tchange directory to ubertest.php location (for git bisect)\n" );
  37. print ( "\nEnvironment variables are:\n" );
  38. print ( "DBUSER\t\t\tuse 'USER' as MySQL user\n" );
  39. print ( "DBPASS\t\t\tuse 'PASS' as MySQL password\n" );
  40. print ( "\nTests can be specified by full name, or list of IDs, or range of IDs.\n" );
  41. print ( "\nUsage examples:\n" );
  42. print ( "php ubertest.php gen\n" );
  43. print ( "php ubertest.php t --user test --password test\n" );
  44. print ( "php ubertest.php t test_015\n" );
  45. print ( "php ubertest.php t 31 37 41 53-64\n" );
  46. print ( "DBPASS=test make check\n" );
  47. exit ( 0 );
  48. }
  49. $locals = array();
  50. $locals['rt_mode'] = false;
  51. if ( array_key_exists ( "DBUSER", $_ENV ) && $_ENV["DBUSER"] )
  52. $locals['db-user'] = $_ENV["DBUSER"];
  53. if ( array_key_exists ( "DBPASS", $_ENV ) && $_ENV["DBPASS"] )
  54. $locals['db-password'] = $_ENV["DBPASS"];
  55. $run = false;
  56. $test_dirs = array();
  57. $test_range = array();
  58. $user_skip = false;
  59. for ( $i=0; $i<count($args); $i++ )
  60. {
  61. $arg = $args[$i];
  62. if ( false );
  63. else if ( $arg=="g" || $arg=="gen" ) { $g_model = true; $run = true; }
  64. else if ( $arg=="t" || $arg=="test" ) { $g_model = false; $run = true; }
  65. else if ( $arg=="qt" ) { $g_model = false; $run = true; $user_skip = true; }
  66. else if ( $arg=="--managed" ) $sd_managed_searchd = true;
  67. else if ( $arg=="--skip-indexer") $sd_skip_indexer = true;
  68. else if ( $arg=="-u" || $arg=="--user" ) $locals['db-user'] = $args[++$i];
  69. else if ( $arg=="-p" || $arg=="--password" ) $locals['db-password'] = $args[++$i];
  70. else if ( $arg=="-i" || $arg=="--indexer" ) $locals['indexer'] = $args[++$i];
  71. else if ( $arg=="-s" || $arg=="--searchd" ) $locals['searchd'] = $args[++$i];
  72. else if ( $arg=="--rt" ) $locals['rt_mode'] = true;
  73. else if ( $arg=="--strict" ) $g_strict = true;
  74. else if ( $arg=="--strict-verbose" ) { $g_strict = true; $g_strictverbose = true; }
  75. else if ( $arg=="--ignore-weights" ) $g_ignore_weights = true;
  76. else if ( $arg=="--no-drop-db" ) $locals['no_drop_db'] = true;
  77. else if ( $arg=="--no-demo" ) $g_skipdemo = true;
  78. else if ( $arg=="--no-marks" ) $g_usemarks = false;
  79. else if ( $arg=="--cwd" ) chdir ( DIRNAME ( __FILE__ ) );
  80. else if ( is_dir($arg) ) $test_dirs[] = $arg;
  81. else if ( preg_match ( "/^(\\d+)-(\\d+)$/", $arg, $range ) )
  82. {
  83. $test_range = array ( $range[1], $range[2] ); // from, to
  84. } else if ( preg_match ( "/^(\\d+):(\\d+)$/", $arg, $range ) )
  85. {
  86. // FIXME! lockdown gen model, only keep test mode
  87. // FIXME! lockdown $test_dirs from here, and check it for emptiness
  88. // ie. make sure there are NO other test arguments when this syntax is in use
  89. $test_dirs = array ( sprintf ( "test_%03d", $range[1] ) );
  90. $g_pick_query = (int)$range[2];
  91. } else if ( is_dir(sprintf("test_%03d", $arg)))
  92. {
  93. $test_dirs[] = sprintf("test_%03d", $arg);
  94. } else
  95. {
  96. print ( "ERROR: unknown option '$arg'; run with no arguments for help screen.\n" );
  97. exit ( 1 );
  98. }
  99. }
  100. if ( !$run )
  101. {
  102. print ( "ERROR: no run mode defined; run with no arguments for help screen.\n" );
  103. exit ( 1 );
  104. }
  105. PublishLocals ( $locals, false );
  106. GuessIdSize();
  107. GuessRE2();
  108. GuessRLP();
  109. GuessODBC();
  110. if ( $g_locals["malloc-scribble"] )
  111. {
  112. print ( "Malloc scribbling enabled.\n" );
  113. putenv ( "MallocLogFile=/dev/null" );
  114. putenv ( "MallocScribble=1" );
  115. putenv ( "MallocPreScribble=1" );
  116. putenv ( "MallocGuardEdges=1" );
  117. }
  118. require_once ( "helpers.inc" );
  119. /////////////
  120. // run tests
  121. /////////////
  122. if ( IsModelGenMode () )
  123. print ( "GENERATING REFERENCE TEST RESULTS\n\n" );
  124. else
  125. print ( "PERFORMING AUTOMATED TESTING\n\n" );
  126. $testconn = ConnectDB();
  127. if ( !$testconn )
  128. {
  129. print ( "ERROR: failed to connect to MySQL: " . mysql_error() . "\n" );
  130. exit ( 1 );
  131. } else
  132. {
  133. mysql_close ( $testconn );
  134. }
  135. $t = MyMicrotime ();
  136. // build test lists
  137. $tests = array ();
  138. $dh = opendir ( "." );
  139. $user_skipped = 0;
  140. while ( $entry=readdir($dh) )
  141. {
  142. if ( substr ( $entry, 0, 5 )!="test_" )
  143. continue;
  144. $test_id = (int) substr ( $entry, 5 );
  145. if ( $user_skip
  146. && isset ( $g_locals["skip-tests"] )
  147. && in_array ( $test_id, $g_locals["skip-tests"] ) )
  148. {
  149. $user_skipped++;
  150. continue;
  151. }
  152. if ( ( empty($test_dirs) && empty($test_range) )
  153. || in_array ( $entry, $test_dirs )
  154. || ( $test_range && $test_id>=$test_range[0] && $test_id<=$test_range[1] ) )
  155. {
  156. $tests[] = $entry;
  157. }
  158. }
  159. sort ( $tests );
  160. // full name to short alias
  161. function ShortTestName ( $full )
  162. {
  163. if ( substr ( $full,0,5 )=="test_" )
  164. return substr ( $full, 5 );
  165. return $full;
  166. }
  167. // run tests
  168. $total_tests = 0;
  169. $total_tests_failed = 0;
  170. $total_subtests = 0;
  171. $total_subtests_failed = 0;
  172. $total_skipped = $user_skipped;
  173. $failed_tests = array();
  174. foreach ( $tests as $test )
  175. {
  176. if ( $windows && !$sd_managed_searchd )
  177. {
  178. // avoid an issue with daemons stuck in exit(0) for some seconds
  179. $sd_port += 10;
  180. $agent_port += 10;
  181. $agent_port_sql += 10;
  182. $agents = array (
  183. array ( "address" => $sd_address, "port" => $sd_port, "sqlport" => $sd_sphinxql_port ),
  184. array ( "address" => $agent_address, "port" => $agent_port, "sqlport" => $agent_port_sql ),
  185. array ( "address" => $agent_address, "port" => $agent_port+1, "sqlport" => $agent_port_sql+1 )
  186. );
  187. }
  188. if ( file_exists ( $test."/test.xml" ) )
  189. {
  190. $total_tests++;
  191. $res = RunTest ( $test, $g_skipdemo, $g_usemarks );
  192. if ( !is_array($res) )
  193. {
  194. // failed to run that test at all
  195. $total_tests_failed++;
  196. $failed_tests[] = ShortTestName ( $test );
  197. continue;
  198. }
  199. $total_subtests += $res["tests_total"];
  200. $total_skipped += $res["tests_skipped"];
  201. if ( $res["tests_failed"] )
  202. {
  203. $total_tests_failed++;
  204. $total_subtests_failed += $res["tests_failed"];
  205. $failed_tests[] = ShortTestName ( $test );
  206. if ( $g_strict )
  207. {
  208. if ( $g_strictverbose )
  209. {
  210. $report = file_get_contents ( "$test/report.txt" );
  211. $report.= "\n Test $test failed\n";
  212. file_put_contents("report.txt",$report);
  213. $report = "";
  214. }
  215. break;
  216. }
  217. }
  218. }
  219. elseif ( file_exists ( $test."/test.inc" ) )
  220. {
  221. $run_func = create_function ( '$test_path', file_get_contents ( $test."/test.inc" ) );
  222. $total_tests++;
  223. $total_subtests++;
  224. if ( !$run_func ( $test ) )
  225. {
  226. $total_tests_failed++;
  227. $total_subtests_failed++;
  228. $failed_tests[] = ShortTestName ( $test );
  229. }
  230. }
  231. }
  232. // cleanup
  233. @unlink ( "config.conf" );
  234. @unlink ( "error.txt" );
  235. $nfile = 1;
  236. while ( file_exists ( "config_$nfile.conf" ) )
  237. {
  238. @unlink ( "config_$nfile.conf" );
  239. $nfile++;
  240. }
  241. $nfile = 1;
  242. while ( file_exists ( "error_$nfile.txt" ) )
  243. {
  244. // FIXME? not when there were actual errors?
  245. @unlink ( "error_$nfile.txt" );
  246. $nfile++;
  247. }
  248. // summarize
  249. if ( $total_tests_failed )
  250. {
  251. printf ( "\nTo re-run failed tests only:\nphp ubertest.php t %s\n", join ( " ", $failed_tests ) );
  252. printf ( "\n%d of %d tests and %d of %d subtests failed, %d tests skipped, %.2f sec elapsed\nTHERE WERE FAILURES!\n",
  253. $total_tests_failed, $total_tests,
  254. $total_subtests_failed, $total_subtests,$total_skipped,
  255. MyMicrotime()-$t );
  256. exit ( 1 );
  257. } else
  258. {
  259. printf ( "\n%d tests and %d subtests succesful, %d tests skipped, %.2f sec elapsed\nALL OK\n",
  260. $total_tests, $total_subtests, $total_skipped,
  261. MyMicrotime()-$t );
  262. exit ( 0 );
  263. }
  264. //
  265. // $Id$
  266. //
  267. ?>