1<?php 2require_once(dirname(dirname(__FILE__)) . '/config.test.php'); 3require_once(dirname(__FILE__) . '/simpletest/unit_tester.php'); 4require_once(dirname(__FILE__) . '/simpletest/mock_objects.php'); 5require_once(dirname(__FILE__) . '/simpletest/web_tester.php'); 6require_once(dirname(__FILE__) . '/kw_db.php'); 7require_once(dirname(__FILE__) . '/kw_unlink.php'); 8 9 10/** 11 * The test manager interface kw tests with simpletest test. 12 * 13 * @package kwtests 14 */ 15class TestManager 16{ 17 var $testDir = null; 18 var $database = null; 19 20 function setDatabase($db){ 21 $this->database = $db; 22 } 23 24 /** 25 * set the tests directory where the test files are placed 26 * @param string $dir 27 */ 28 function setTestDirectory($dir){ 29 $this->testDir = $dir; 30 } 31 32 /** Delete the log file */ 33 function removeLogAndBackupFiles($logfilename) 34 { 35 if(file_exists($logfilename)) 36 { 37 global $CDASH_TESTING_RENAME_LOGS; 38 if ($CDASH_TESTING_RENAME_LOGS) 39 { 40 // Rename to a random name to keep for later inspection: 41 // 42 global $CDASH_LOG_FILE; 43 rename($logfilename, $CDASH_LOG_FILE . "." . mt_rand() . ".txt"); 44 } 45 else 46 { 47 // Delete file: 48 cdash_testsuite_unlink($logfilename); 49 } 50 } 51 52 $filenames = glob(dirname($logfilename)."/*.xml"); 53 foreach($filenames as $filename) 54 { 55 cdash_testsuite_unlink($filename); 56 } 57 } 58 function runFileTest(&$reporter, $file) 59 { 60 $test = &new TestSuite('All Tests'); 61 if($this->testDir !== null) 62 { 63 $path = $this->testDir. "/" . $file; 64 } 65 else 66 { 67 $path = $file; 68 } 69 print "$path\n"; 70 $test->addFile($path); 71 return $test->run($reporter); 72 } 73 /** 74 * run all the tests 75 * @return the result the test running 76 * @param object $reporter 77 */ 78 function runAllTests(&$reporter) { 79 $testsFile = $this->getTestCaseList(); 80 $test = &new TestSuite('All Tests'); 81 foreach($testsFile as $path=>$file) 82 { 83 $test->addFile($path); 84 } 85 return $test->run($reporter); 86 } 87 88 /** 89 * Match all the test files inside the test directory 90 * @return an array of the test files 91 */ 92 function getTestCaseList() { 93 if(!$this->testDir) 94 { 95 die ("please, set the test directory\n"); 96 } 97 $testsFile = array(); 98 foreach(glob($this->testDir.'/test_*.php') as $file) 99 { 100 $fileinfo = pathinfo($file); 101 if(strcmp($fileinfo['basename'],'test_install.php') != 0 && 102 strcmp($fileinfo['basename'],'test_uninstall.php') != 0) 103 { 104 $testsFile[$fileinfo['dirname'].'/'.$fileinfo['basename']] = $fileinfo['basename']; 105 } 106 } 107 return $testsFile; 108 } 109 110 111 /** 112 * perform a connection to the database 113 * @return the result of the connection 114 * @param string $host 115 * @param string $user 116 * @param string $password 117 * @param string $dbname 118 * @param string $dbtype 119 * @access protected 120 */ 121 function _connectToDb($host,$port,$user,$password,$dbname,$dbtype) 122 { 123 $database = new database($dbtype); 124 $database->setHost($host); 125 $database->setPort($port); 126 $database->setUser($user); 127 $database->setPassword($password); 128 $database->setDb($dbname); 129 return $database->connectedToDb(); 130 } 131 132 /** 133 * drop the old test database 134 * @return success/failure depending of the database dropping 135 * @param string $host 136 * @param int $port 137 * @param string $user 138 * @param string $password 139 * @param string $dbname 140 * @param string $dbtype 141 * @access protected 142 */ 143 function _uninstalldb4test($host,$port,$user,$password,$dbname,$dbtype) 144 { 145 if(!strcmp($dbname,'cdash4simpletest')) 146 { 147 $database = new database($dbtype); 148 $database->setHost($host); 149 $database->setPort($port); 150 $database->setUser($user); 151 $database->setPassword($password); 152 return $database->drop($dbname); 153 } 154 else 155 { 156 die("We cannot test cdash because test database is not cdash4simpletest\n"); 157 } 158 } 159 160 161 /** 162 * create the new test database 163 * @return success/failure depending of the database creating 164 * @param string $host 165 * @param string $user 166 * @param string $password 167 * @param string $dbname 168 * @param string $dbtype 169 * @access protected 170 */ 171 function _installdb4test($host,$port,$user,$password,$dbname,$dbtype) 172 { 173 if(!strcmp($dbname,'cdash4simpletest')) 174 { 175 $database = new database($dbtype); 176 $database->setHost($host); 177 $database->setPort($port); 178 $database->setUser($user); 179 $database->setPassword($password); 180 $dbcreated = true; 181 if(!$database->create($dbname)) 182 { 183 $dbcreated = false; 184 $msg = 'error query(CREATE DATABASE)'; 185 die("Error" . " File: " . __FILE__ . " on line: " . __LINE__.": $msg"); 186 return false; 187 } 188 if($dbcreated) 189 { 190 $dirname = str_replace('\\','/',dirname(__FILE__)); 191 $sqlfile = str_replace("/tests/kwtest","", $dirname)."/sql/".$dbtype."/cdash.sql"; 192 $database->fillDb($sqlfile); 193 } 194 return true; 195 } 196 else 197 { 198 die("We cannot test cdash because test database is not cdash4simpletest\n"); 199 } 200 } 201} 202 203 204 205/** 206 * The cdash test manager interface cdash test with simpletest 207 * 208 * @package kwtests 209 */ 210class CDashTestManager extends TestManager 211{ 212 var $_urlToCdash = null; 213 214 /** 215 * run all the tests in the current directory 216 * @return the result of the test 217 * @param object $reporter 218 */ 219 function runAllTests(&$reporter) 220 { 221 $reporter->paintTestCaseList($this->getTestCaseList()); 222 parent::runAllTests($reporter); 223 } 224 225 226 /** 227 * Set the url of the CDash server 228 * @param string $url url via we make the curl to send the report 229 */ 230 function setCDashServer($servername){ 231 if(!empty($servername)) 232 { 233 $this->_urlToCdash = $servername; 234 } 235 } 236 237 /** 238 * update the svn repository 239 * @param object $reporter 240 * @param string $svnroot 241 */ 242 243 function updateSVN($reporter,$svnroot,$type){ 244 if(!empty($svnroot)) 245 { 246 $reporter->paintUpdateStart(); 247 $execution_time = $this->__performSvnUpdate($reporter,$svnroot,$type); 248 // The project is up to date and the type is Continuous 249 if(!$execution_time) 250 { 251 echo "error: updateSVN: false execution_time, no paintUpdateEnd\n"; 252 return false; 253 } 254 // We put in minute the execution time of the svn update 255 if(is_numeric($execution_time)) 256 { 257 $execution_time = round($execution_time / 60 , 3); 258 } 259 $reporter->paintUpdateEnd($execution_time); 260 return true; 261 } 262 263 echo "error: updateSVN: empty svnroot\n"; 264 return false; 265 } 266 267 268 /** 269 * perform an update of a revision in the svn 270 * @return the time execution of the svn update 271 * @param object $reporter 272 * @param string $svnroot 273 * @access private 274 */ 275 function __performSvnUpdate($reporter,$svnroot,$type){ 276 $time_start = (float) array_sum(explode(' ',microtime())); 277 $grepCmd = 'grep'; 278 global $isWindows; 279 if ($isWindows) 280 { 281 $grepCmd = 'findstr'; 282 } 283 $raw_output = $this->__performSvnCommand(`svn info "$svnroot" 2>&1 | $grepCmd Revision`); 284 // We catch the current revision of the repository 285 $currentRevision = str_replace('Revision: ','',$raw_output[0]); 286 $raw_output = $this->__performSvnCommand(`svn update "$svnroot" 2>&1 | $grepCmd revision`); 287 if(strpos($raw_output[0],'revision') === false) 288 { 289 $execution_time = "Svn Error:\nsvn update did not return the right standard output.\n"; 290 $execution_time .= "svn update did not work on your repository\n"; 291 echo "error: __performSvnUpdate: svn update failed\n"; 292 return $execution_time; 293 } 294 if(strpos($raw_output[0],'At revision') !== false) 295 { 296 if(!strcmp($type,'Continuous')) 297 { 298 echo "__performSvnUpdate: type=[$type], returning false\n"; 299 return false; 300 } 301 $time_end = (float) array_sum(explode(' ',microtime())); 302 $execution_time = $time_end - $time_start; 303 echo "Old revision of repository is: $currentRevision\nCurrent revision of repository is: $currentRevision\n"; 304 echo "Project is up to date\n"; 305 return $execution_time; 306 } 307 $newRevision = str_replace('Updated to revision ','',$raw_output[0]); 308 $newRevision = strtok($newRevision,'.'); 309 $raw_output = `svn log "$svnroot" -r $currentRevision:$newRevision -v --xml 2>&1`; 310 $reporter->paintUpdateFile($raw_output); 311 $time_end = (float) array_sum(explode(' ',microtime())); 312 $execution_time = $time_end - $time_start; 313 echo "Your Repository has just been updated from revision $currentRevision to revision $newRevision\n"; 314 echo "\tRepository concerned: [$svnroot]\n"; 315 echo "\tUse SVN repository type\n"; 316 echo "Project is up to date\n"; 317 return $execution_time; 318 } 319 320 321 /** 322 * perform a command line 323 * @return an array of the output result of the commandline 324 * @param command $commandline 325 */ 326 function __performSvnCommand($commandline) 327 { 328 return explode("\n", $commandline); 329 } 330 331 332 /** 333 * configure the database for the test by droping the old 334 * test database and creating a new one 335 * @param object $reporter 336 * @param array $db 337 */ 338 function configure($reporter, $logfilename) 339 { 340 if(!$this->database) 341 { 342 echo "Please, set the database to the test manager before configure the test\n"; 343 return false; 344 } 345 $reporter->paintConfigureStart(); 346 $time_start = (float) array_sum(explode(' ',microtime())); 347 $result = $this->_uninstalldb4test($this->database['host'], 348 $this->database['port'], 349 $this->database['login'], 350 $this->database['pwd'], 351 $this->database['name'], 352 $this->database['type']); 353 $time_end = (float) array_sum(explode(' ',microtime())); 354 $execution_time = $time_end - $time_start; 355 $time_start = $time_end; 356 $reporter->paintConfigureUninstallResult($result); 357 $result = $this->_connectToDb($this->database['host'], 358 $this->database['port'], 359 $this->database['login'], 360 $this->database['pwd'], 361 $this->database['name'], 362 $this->database['type']); 363 $reporter->paintConfigureConnection($result); 364 365 if (file_exists($logfilename)) 366 { 367 // delete the log file -- result is success/failure 368 $result = cdash_testsuite_unlink($logfilename); 369 } 370 else 371 { 372 // file is already not there -- equivalent to successfully deleting it 373 $result = true; 374 } 375 $reporter->paintConfigureDeleteLogResult($result, $logfilename); 376 377 $result = $this->_installdb4test($this->database['host'], 378 $this->database['port'], 379 $this->database['login'], 380 $this->database['pwd'], 381 $this->database['name'], 382 $this->database['type']); 383 $time_end = (float) array_sum(explode(' ',microtime())); 384 $execution_time += ($time_end - $time_start); 385 $execution_time = round($execution_time / 60 , 3); 386 $reporter->paintConfigureInstallResult($result); 387 $result = $this->_connectToDb($this->database['host'], 388 $this->database['port'], 389 $this->database['login'], 390 $this->database['pwd'], 391 $this->database['name'], 392 $this->database['type']); 393 $reporter->paintConfigureConnection($result); 394 $reporter->paintConfigureEnd($execution_time); 395 return $result; 396 } 397 398 399 /** 400 * Check the log file of the application testing 401 * @return false if there is no log file or no error into the log file 402 * true if it caught some errors from the log file 403 * @param object $application 404 * @param object $reporter 405 */ 406 function getErrorFromServer($filename, $reporter) 407 { 408 if(!file_exists($filename)) 409 { 410 return false; 411 } 412 $content = file_get_contents($filename); 413 if(empty($content)) 414 { 415 return false; 416 } 417 // For midas cake: the log time looks like this: if it is not 418 // a cake midas application that you're testing, comment the following line 419 // and implement your own regex 420 //$regex = "([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})"; 421 422 // the regex to catch the date for cdash: model: [2009-02-25T18:24:56] 423 $regex = "([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})T([0-9]{2}):([0-9]{2}):([0-9]{2})\]"; 424 $fp = fopen($filename,'r'); 425 $content = fread($fp,filesize($filename)); 426 fclose($fp); 427 unset($fp); 428 $output = split($regex,$content); 429 foreach($output as $message) 430 { 431 $reporter->paintServerFail($message); 432 } 433 return true; 434 } 435 436 /** 437 * Send via a curl to the CDash server the xml reports 438 * @return true on success / false on failure 439 */ 440 function sendToCdash($reporter,$directory){ 441 if(!$this->_urlToCdash) 442 { 443 echo "please set the url to the cdash server before calling sendToCdash method\n"; 444 return false; 445 } 446 $reporter->close(); 447 $msg = "Submit files (using http)\n\tUsing HTTP submit method\n\t"; 448 $msg .= "Drop site: ".$this->_urlToCdash."?project=CDash\n"; 449 echo $msg; 450 $filename = $directory.'/Build.xml'; 451 $this->__uploadViaCurl($filename); 452 echo "\tUploaded: $filename\n"; 453 $filename = $directory.'/Configure.xml'; 454 $this->__uploadViaCurl($filename); 455 echo "\tUploaded: $filename\n"; 456 $filename = $directory.'/Test.xml'; 457 $this->__uploadViaCurl($filename); 458 echo "\tUploaded: $filename\n"; 459 $filename = $directory.'/Update.xml'; 460 $this->__uploadViaCurl($filename); 461 echo "\tUploaded: $filename\n"; 462 echo "\tSubmission successful\n"; 463 return true; 464 } 465 466 /** 467 * Perform a curl to upload the filename to the CDash Server 468 * @param object $filename 469 */ 470 function __uploadViaCurl($filename){ 471 $fp = fopen($filename, 'r'); 472 $ch = curl_init($this->_urlToCdash.'/submit.php?project=CDash'); 473 curl_setopt($ch, CURLOPT_TIMEOUT, 60); 474 curl_setopt($ch, CURLOPT_UPLOAD, 1); 475 curl_setopt($ch, CURLOPT_INFILE, $fp); 476 curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filename)); 477 curl_exec($ch); 478 curl_close($ch); 479 fclose($fp); 480 unset($fp); 481 } 482} 483 484 485class HtmlTestManager extends TestManager 486{ 487 function runAllTests(&$reporter) 488 { 489 $this->_uninstalldb4test($this->database['host'], 490 $this->database['port'], 491 $this->database['login'], 492 $this->database['pwd'], 493 $this->database['name'], 494 $this->database['type']); 495 $this->_installdb4test($this->database['host'], 496 $this->database['port'], 497 $this->database['login'], 498 $this->database['pwd'], 499 $this->database['name'], 500 $this->database['type']); 501 parent::runAllTests($reporter); 502 } 503} 504?> 505