| [ Index ] |
PHP Cross Reference of Akelos Framework |
[Summary view] [Print] [Text view]
1 <?php 2 defined('DS') ? null : define('DS',DIRECTORY_SEPARATOR); 3 defined('AK_BASE_DIR') ? null : define('AK_BASE_DIR',preg_replace('@\\'.DS.'(test|script)($|\\'.DS.'.*)@','',getcwd())); 4 if (!@include_once(AK_BASE_DIR.DS.'config'.DS.'config.php')) { 5 require_once(AK_BASE_DIR.DS.'config'.DS.'DEFAULT-config.php'); 6 } 7 define('AK_CI_CONFIG_FILE',AK_BASE_DIR.DS.'config'.DS.'ci-config.yaml'); 8 9 class CI_Tests 10 { 11 var $options = array( 12 'break_on_errors'=>false, 13 'test_mode' =>false, 14 'repeat' =>1 15 ); 16 17 var $settings = array('executables'=>array(),'environments'=>array(),'default_executables'=>array()); 18 var $configured = array('ci-config.yaml'=>false,'environments'=>false); 19 var $target_files; 20 var $target_executables; 21 var $target_environments; 22 var $debug=false; 23 var $report_environments = array(); 24 25 function main($args=array()) 26 { 27 if (empty($args)){ 28 $args = $_SERVER['argv']; 29 } 30 $self = new CI_Tests($args); 31 $self->run(); 32 $self->hadError() ? exit(1) : exit(0); 33 } 34 35 function CI_Tests($args) 36 { 37 38 39 40 $this->args = $args; 41 if (in_array('-d',$this->args)) { 42 $this->debug = true; 43 } 44 if (!$this->_isConfigured()) { 45 46 $this->setup(); 47 48 } 49 50 $this->setDefaults(); 51 $this->info('Ci-Tests configured properly.'); 52 53 } 54 55 function setup() 56 { 57 foreach ($this->configured as $type=>$ok) { 58 switch($type) { 59 case 'environments': 60 if (!is_array($ok)) { 61 $ok = array('mysql'=>false,'postgres'=>false,'sqlite'=>false); 62 } 63 foreach ($ok as $env=>$res) { 64 if (!$res) { 65 $this->_createDbConfig($env); 66 } 67 } 68 break; 69 case 'ci-config.yaml': 70 break; 71 case 'ci-config.php': 72 if (!$ok) { 73 $this->_createCiPhpConfigFile(); 74 $this->loadSettings(); 75 } 76 break; 77 } 78 } 79 } 80 function _promptForDbConfig($env) 81 { 82 83 $env=='sqlite'?$host='':$host = $this->promptUserVar('['.$env.'] Host', array('default'=>'localhost')); 84 $env=='sqlite'?$dbname='':$dbname = $this->promptUserVar('['.$env.'] Database name', array('default'=>'akelos')); 85 $dbfile = ($env=='sqlite'?$this->promptUserVar('['.$env.'] Database file:', array('default'=>'/tmp/akelos.sqlite')):null); 86 $env=='sqlite'?$username='':$username = $this->promptUserVar('['.$env.'] Username'); 87 $env=='sqlite'?$password='':$password = $this->promptUserVar('['.$env.'] Password',array('optional'=>true)); 88 $env=='sqlite'?$options='':$options = $this->promptUserVar('['.$env.'] Options',array('optional'=>true)); 89 90 return array('type'=>$env,'host'=>$host,'database_file'=>$dbfile,'database_name'=>$dbname,'user'=>$username,'password'=>$password,'options'=>$options); 91 } 92 function _createDbConfig($env) 93 { 94 $file = AK_BASE_DIR.DS.'config'.DS.$env.'.yml'; 95 $templateFile = AK_BASE_DIR.DS.'script'.DS.'extras'.DS.'TPL-database.yml'; 96 if (in_array($env,array('postgres','postgresql','postgressql'))) { 97 $env = 'pgsql'; 98 } 99 $this->info('Creating environment configuration for:'.$env); 100 $dbConfig = $this->_promptForDbConfig($env); 101 while (!($res = $this->_checkDbConfig($env,$dbConfig))) { 102 103 $this->info('Try again:'); 104 $dbConfig = $this->_promptForDbConfig($env); 105 } 106 $replacements = array(); 107 foreach($dbConfig as $key=>$val) { 108 $replacements['${'.$key.'}'] = $val; 109 } 110 return file_put_contents($file,str_replace(array_keys($replacements),array_values($replacements),file_get_contents($templateFile)))>0; 111 112 } 113 /** 114 * Promts for a variable on console scripts 115 */ 116 function promptUserVar($message, $options = array()) 117 { 118 $f = fopen("php://stdin","r"); 119 $default_options = array( 120 'default' => null, 121 'optional' => false, 122 ); 123 124 $options = array_merge($default_options, $options); 125 126 echo "\n".$message.(empty($options['default'])?'': ' ['.$options['default'].']').': '; 127 $user_input = fgets($f, 25600); 128 $value = trim($user_input,"\n\r\t "); 129 $value = empty($value) ? $options['default'] : $value; 130 if(empty($value) && empty($options['optional'])){ 131 echo "\n\nThis setting is not optional."; 132 fclose($f); 133 return $this->promptUserVar($message, $options); 134 } 135 fclose($f); 136 return empty($value) ? $options['default'] : $value; 137 } 138 function _isConfigured() 139 { 140 $returnVal = true; 141 // check if AK_CI_CONFIG_FILE exists 142 if(file_exists(AK_CI_CONFIG_FILE)) { 143 $this->debug('File '.AK_CI_CONFIG_FILE.' exists'); 144 $this->loadSettings(); 145 // check if the ci-test installation is there 146 if (!$this->_checkTestInstallation()) { 147 $this->error('Check of test installation failed'); 148 return false; 149 } 150 if (isset($this->settings['test-installation'])) { 151 $this->_createTestInstallation($this->settings['test-installation']); 152 } 153 // check if php executables are runnable and if they are really php4 and php5 154 if (!$this->_checkExecutables()) { 155 $this->error('Check of executables failed'); 156 return false; 157 } 158 159 if (!$this->_checkMemcacheInstallation()) { 160 $this->error('Check of memcached installation failed'); 161 return false; 162 } 163 164 } else { 165 $this->debug('File '.AK_CI_CONFIG_FILE.' does not exist'); 166 $res = $this->_createCiConfigFile(); 167 if (!$res) { 168 $this->error('Could not create: '.AK_CI_CONFIG_FILE,true); 169 } 170 $this->loadSettings(); 171 $this->_setupMemcache(); 172 } 173 174 $this->_fixTestInstallationPermissions(); 175 $this->configured['ci-config.yaml'] = true; 176 $this->configured['environments'] = array(); 177 foreach ($this->settings['environments'] as $type) { 178 $this->debug('Checking environment: '.$type); 179 $this->configured['environments'][$type] = false; 180 if (file_exists(AK_BASE_DIR.DS.'config'.DS.$type.'.yml')) { 181 // check environment database configs - access database to verify it works 182 $res = $this->_checkDbConfig($type); 183 $this->configured['environments'][$type] = $res; 184 $returnVal = $res && $returnVal; 185 } else { 186 $this->info('Environment config for '.$type.' does not exist'); 187 $this->_createDbConfig($type); 188 } 189 } 190 copy(AK_BASE_DIR.DS.'config'.DS.'sqlite.yml',AK_CI_TEST_DIR.DS.'config'.DS.'database.yml'); 191 if (file_exists(AK_BASE_DIR.DS.'config'.DS.'ci-config.php')) { 192 /**$ciConfigContents = file_get_contents(AK_BASE_DIR.DS.'config'.DS.'ci-config.php'); 193 // check the config.php file (needs the webroot), check if the webserver is reachable 194 preg_match("/define\('AK_TESTING_URL', '(.*?)'\);/",$ciConfigContents,$matches); 195 $testing_url = ''; 196 if(isset($matches[1])) { 197 $testing_url = $matches[1]; 198 }*/ 199 $testing_url = $this->settings['test-url']; 200 $res = $this->_checkWebServer($testing_url); 201 $this->configured['ci-config.php'] = $res; 202 $returnVal = $res && $returnVal; 203 } else { 204 $this->_createCiPhpConfigFile(); 205 } 206 207 return $returnVal; 208 // if all passes return true 209 } 210 function _checkTestInstallation() 211 { 212 $this->info('Checking test-installation'); 213 $command = $this->settings['test-installation'].'/akelos -v'; 214 $this->debug('Checking test-installation:'.$command); 215 $out = array(); 216 exec($command,$out,$ret); 217 $version = isset($out[0])? $out[0]:0; 218 if (version_compare($version,0,'>')) { 219 $this->info('Test installation ok, running version:'.$version); 220 } else { 221 $this->error('Test installation not ok:'.var_export($out,true), true); 222 } 223 return true; 224 } 225 function _checkWebserver2($url) 226 { 227 $return = true; 228 $testIndexPage = @file_get_contents($url.'/'); 229 if ($testIndexPage!='Test::page::index') { 230 $this->error('Webserver Configuration problems:'."\n" .$testIndexPage."\n\n"); 231 $return = false; 232 } else { 233 $this->info('Web Server is configured correctly'); 234 } 235 return $return; 236 } 237 238 function _checkWebServer($url, $test_installation = null) 239 { 240 $return = true; 241 if ($test_installation == null && defined('AK_CI_TEST_DIR')) { 242 $test_installation = AK_CI_TEST_DIR; 243 } 244 $parts = parse_url($url); 245 if (!isset($parts['host'])) { 246 $this->error('No host found in: '.$url); 247 return false; 248 } 249 $rewritebase = isset($parts['path'])?$parts['path']:'/'; 250 $htaccessTemplateFile = AK_BASE_DIR.DS.'script'.DS.'extras'.DS.'TPL-htaccess'; 251 $htaccessFile = $test_installation.DS.'test'.DS.'fixtures'.DS.'public'.DS.'.htaccess'; 252 $htaccessRes = file_put_contents($htaccessFile,str_replace('$rewrite-base}',$rewritebase,file_get_contents($htaccessTemplateFile)))>0; 253 254 $this->debug('Copying '.$htaccessTemplateFile.' template to '.$htaccessFile.':'.(($htaccessRes)?'Success':'failure')); 255 256 //$htaccess = AK_CI_TEST_DIR.DS.'test'.DS.'fixtures'.DS.'public'.DS.'.htaccess'; 257 //$htaccess_backup =AK_CI_TEST_DIR.DS.'test'.DS.'fixtures'.DS.'public'.DS.'.htaccess.backup'; 258 $test_htaccess = $test_installation.DS.'test'.DS.'.htaccess'; 259 $test_htaccess_backup =$test_installation.DS.'test'.DS.'.htaccess.backup'; 260 //copy($htaccess,$htaccess_backup); 261 //unlink($htaccess); 262 copy($test_htaccess,$test_htaccess_backup); 263 $this->debug('Copying '.$test_htaccess.' to '.$test_htaccess_backup); 264 unlink($test_htaccess); 265 $this->debug('Unlinking '.$test_htaccess); 266 $this->debug('Checking if webserver is reachable at: '.$url.'/ci-setup-test.html'); 267 $content = time().' - '.rand(0,10000); 268 $file = $test_installation.DS.'test'.DS.'fixtures'.DS.'public'.DS.'ci-setup-test.html'; 269 file_put_contents($file,$content); 270 $res = @file_get_contents($url.'/ci-setup-test.html'); 271 if ($res!=$content) { 272 if (strlen($res)>0) { 273 $this->error('Web Server is not pointing to the test-installation at '.dirname($file)); 274 } else { 275 $this->error('Web Server is not reachable at '.$url); 276 } 277 $return = false; 278 } 279 $this->info('Web Server is reachable at '.$url); 280 281 282 283 return $return; 284 } 285 286 function _checkDbConfig($type, $settings = array()) 287 { 288 $this->debug('Checking if database config for "'.$type.'" is available'); 289 require_once(AK_BASE_DIR.DS.'lib'.DS.'AkActiveRecord'.DS.'AkDbAdapter.php'); 290 require_once (AK_LIB_DIR.DS.'Ak.php'); 291 292 if (empty($settings)) { 293 require_once(AK_BASE_DIR.DS.'lib'.DS.'AkConfig.php'); 294 $config = new AkConfig(); 295 $settings = $config->get($type,'testing'); 296 } 297 $db = new AkDbAdapter($settings); 298 $db->connect(false); 299 if (!($res=$db->connected())) { 300 $this->error("[$type] ".'Cannot connect to DB'); 301 } else { 302 $this->info("[$type] ".'Successfully connected to database '.($settings['type'] == 'sqlite'?$settings['database_file']:$settings['database_name'])); 303 $createRes = $db->execute('CREATE table ci_test_dummy(id integer)'); 304 if (!$createRes) { 305 $res = false; 306 $this->error("[$type] ".'Could not create test table: ci_test_dummy'); 307 } else { 308 $res = true; 309 $this->info("[$type] ".'Successfully created test table: ci_test_dummy'); 310 $db->execute('DROP table ci_test_dummy'); 311 } 312 } 313 return $res; 314 } 315 function debug($message) 316 { 317 if ($this->debug) { 318 echo "[DEBUG]\t$message\n"; 319 } 320 } 321 function error($message, $fatal = false) 322 { 323 echo "[ERROR]\t$message\n"; 324 if ($fatal) { 325 die("[FATAL-ERROR]\texiting.\n"); 326 } 327 } 328 function _checkExecutables($executables = array()) 329 { 330 331 $executables = empty($executables)?$this->settings['executables']:$executables; 332 if (count($executables)>1) { 333 $this->debug('Checking executables:'); 334 } 335 foreach ($executables as $executable) { 336 $command = $executable.' -r "echo 1;"'; 337 $this->debug('Checking executable "'.$executable.'" with: '.$command); 338 $return=array(); 339 exec($command,$return,$returnVal); 340 $this->debug('Return :'.var_export($return,true)); 341 if ($return[0] !== "1") { 342 $this->error("$executable should have echoed '1' but did echo '" . var_export($return,true)); 343 return false; 344 } 345 } 346 return true; 347 } 348 function _createCiPhpConfigFile() 349 { 350 $this->info('Creating ci-config.php'); 351 $templateFile = AK_BASE_DIR.DS.'script'.DS.'extras'.DS.'TPL-ci-config.php'; 352 $file = AK_BASE_DIR.DS.'config'.DS.'ci-config.php'; 353 $settings = array(); 354 $settings['$testing-url}'] = $this->settings['test-url']; 355 return file_put_contents($file,str_replace(array_keys($settings),array_values($settings),file_get_contents($templateFile)))>0; 356 } 357 function _createCiConfigFile() 358 { 359 $this->info('Creating ci-configuration'); 360 $templateFile = AK_BASE_DIR.DS.'script'.DS.'extras'.DS.'TPL-ci-config.yaml'; 361 $file = AK_BASE_DIR.DS.'config'.DS.'ci-config.yaml'; 362 $settings = array(); 363 $settings['$test-installation}'] = $this->_createTestInstallation(); 364 $settings['$php4}'] = $this->_promptForPhp('php4'); 365 $settings['$php5}'] = $this->_promptForPhp('php5'); 366 $settings['$test-url}'] = $this->_promptForTestingUrl($settings['$test-installation}']); 367 $settings['$memcached-socket}'] = ''; 368 return file_put_contents($file,str_replace(array_keys($settings),array_values($settings),file_get_contents($templateFile)))>0; 369 } 370 371 function _promptForPhp($php) 372 { 373 while ((($executable = $this->promptUserVar('Please provide the path to a valid '.$php.' executable')) && !$this->_checkExecutables(array($executable)))) { 374 $this->error('Could not verify that '.$executable.' is a valid php executable'); 375 } 376 return $executable; 377 } 378 function _promptForTestingUrl($test_installation) 379 { 380 while ((($testingUrl = $this->promptUserVar("Please provide the testing url of the webserver. 381 382 Example: 383 384 In case you are running apache on localhost you can add the following in the apache conf: 385 386 Alias /akelos-ci-tests \"$test_installation\" 387 388 <Directory \"$test_installation\"> 389 Options Indexes FollowSymLinks 390 AllowOverride All 391 Order allow,deny 392 Allow from all 393 </Directory> 394 395 If you are running apache on localhost, the testing url would be: 396 397 http://localhost/akelos-ci-tests/test/fixtures/public 398 399 You need to restart your webserver after making the change and before confirming 400 the testing url. 401 ")) && !$this->_checkWebServer($testingUrl,$test_installation))) { 402 $this->error('Could not verify the testing url. Please make sure a webserver is running and handling that request.'); 403 } 404 return $testingUrl; 405 } 406 function info($message) 407 { 408 echo "[INFO]\t$message \n"; 409 } 410 function _createTestInstallation($testDir = null) 411 { 412 if ($testDir == null) { 413 while ((($testDir = $this->promptUserVar('Please insert the path for installing the CI tests for Akelos')) && ((file_exists($testDir) && !is_writable($testDir)) || (!is_writable(dirname(dirname($testDir))))))) { 414 $this->error('Directory '.$testDir.' is not writable'); 415 } 416 } 417 $testDir = rtrim($testDir,DS).DS; 418 $this->debug('Chosen directory '.$testDir); 419 $out = array(); 420 $command = AK_BASE_DIR.DS.'akelos -d '.$testDir.' -deps --force'; 421 $this->debug('Installing akelos testing app: '.$command); 422 if ($this->debug) { 423 passthru($command, $ret); 424 } else { 425 exec($command,$out,$ret); 426 } 427 428 $routing = copy(AK_BASE_DIR.DS.'config'.DS.'DEFAULT-routes.php',$testDir.DS.'config'.DS.'routes.php'); 429 430 if (!$routing) { 431 $this->error('Could not copy routing file to '.$testDir.DS.'config'.DS.'routes.php',true); 432 } 433 434 if ($ret!=0) { 435 $this->error('Could not install akelos testing app in: '.$testDir,true); 436 } 437 return $testDir; 438 } 439 function _fixTestInstallationPermissions() 440 { 441 $dirs = array('/test/tmp','/config/cache','/log'); 442 foreach ($dirs as $dir) { 443 exec('chmod -Rf 777 '.AK_CI_TEST_DIR.$dir); 444 } 445 } 446 447 function _setupMemcache() 448 { 449 $memcachedInstalled = $this->promptUserVar('Certain tests need a memcached running. Do you have a memcached installation?',array('default'=>'No')); 450 451 if (!in_array(strtolower($memcachedInstalled),array('y','yes','si','ja','1'))) { 452 $installation = $this->settings['test-installation']; 453 $memcacheTestConfigFile = $installation.DS.'test'.DS.'unit'.DS.'config'.DS.'memcached'; 454 file_put_contents($memcacheTestConfigFile,'0'); 455 return; 456 } else { 457 $socket = $this->_configureMemcache(); 458 if ($socket !== false) { 459 $res = $this->_createMemcachedConfig($socket); 460 if (!$res) { 461 $this->error('Could not create caching.yml. Disabling memcached support.'); 462 $installation = $this->settings['test-installation']; 463 $memcacheTestConfigFile = $installation.DS.'test'.DS.'unit'.DS.'config'.DS.'memcached'; 464 file_put_contents($memcacheTestConfigFile,'0'); 465 return; 466 } else { 467 468 } 469 } 470 } 471 } 472 473 function _createMemcachedConfig($socket) 474 { 475 $file1 = AK_CI_TEST_DIR.DS.'test'.DS.'fixtures'.DS.'config'.DS.'caching.yml'; 476 $file2 = AK_CI_TEST_DIR.DS.'config'.DS.'caching.yml'; 477 $templateFile = AK_BASE_DIR.DS.'script'.DS.'extras'.DS.'TPL-caching.yml'; 478 $this->info('Creating caching configuration: ' .$file1); 479 $res1 = file_put_contents($file1,str_replace('$memcached_server}',$socket,file_get_contents($templateFile)))>0; 480 $this->info('Creating caching configuration: ' .$file2); 481 $res2 = file_put_contents($file1,str_replace('$memcached_server}',$socket,file_get_contents($templateFile)))>0; 482 $res3 = file_put_contents(AK_CI_CONFIG_FILE,str_replace('memcached-socket: ','memcached-socket: '.$socket,file_get_contents(AK_CI_CONFIG_FILE))); 483 return $res1 && $res2 && $res3; 484 } 485 486 function _checkMemcacheInstallation($socket = null) 487 { 488 if ($socket == null) { 489 $socket = $this->settings['memcached-socket']; 490 if (empty($socket)) return true; 491 } 492 require_once(AK_BASE_DIR.DS.'lib'.DS.'AkCache'.DS.'AkMemcache.php'); 493 $memcache = new AkMemcache(); 494 return @$memcache->init(array('servers'=>array($socket))); 495 } 496 function _configureMemcache() 497 { 498 require_once(AK_BASE_DIR.DS.'lib'.DS.'AkCache'.DS.'AkMemcache.php'); 499 $memcache = new AkMemcache(); 500 while ((($socket = $this->promptUserVar('Please provide the socket memcached is running on',array('default'=>'localhost:11211'))) && !$this->_checkMemcacheInstallation($socket))) { 501 $this->error('Could not connect to memcached at socket: '.$socket); 502 $tryAgain = $this->promptUserVar('Want to try again configuring memcached support?',array('default'=>'Yes')); 503 if (!in_array(strtolower($tryAgain),array('y','yes','si','ja','1'))) { 504 return false; 505 } 506 } 507 return $socket; 508 } 509 function loadSettings($filename=AK_CI_CONFIG_FILE) 510 { 511 require_once dirname(__FILE__).DS.'..'.DS.'..'.DS.'..'.DS.'vendor'.DS.'TextParsers'.DS.'spyc.php'; 512 $this->debug('Trying to load settings from: '.$filename); 513 if (!is_file($filename)){ 514 die ('Could not find ci configuration file in '.AK_CI_CONFIG_FILE.'.'); 515 } 516 $yaml = file_get_contents($filename); 517 $this->settings = Spyc::YAMLLoad($yaml); 518 defined('AK_CI_TEST_DIR')?null:define('AK_CI_TEST_DIR',$this->settings['test-installation']); 519 $this->parseArgs(); 520 } 521 522 function parseArgs($args = null) 523 { 524 if ($args == null) { 525 $args = $this->args; 526 } 527 array_shift($args); 528 while (count($args) > 0){ 529 $arg = array_shift($args); 530 $arg = strtolower($arg); 531 if (in_array($arg,array('postgresql','postgressql','pgsql','pg','postgres'))) { 532 $arg = 'pgsql'; 533 } 534 if (array_key_exists(strtolower($arg),$this->settings['executables'])){ 535 $this->target_executables[] = $arg; 536 }elseif (in_array(strtolower($arg),$this->settings['environments'])){ 537 $this->target_environments[] = $arg; 538 }elseif ($filename = $this->constructTestFilename($arg)){ 539 $this->target_files[] = $filename; 540 }else{ 541 switch ($arg){ 542 case '-b': 543 $this->options['break_on_errors'] = true; 544 break; 545 case '-t': 546 $this->options['test_mode'] = true; 547 break; 548 case '-d': 549 $this->debug=true; 550 break; 551 case '-?': 552 case '?': 553 $this->drawHelp(); 554 break; 555 case '-n': 556 $timesToRepeat = array_shift($args); 557 $this->options['repeat'] = $timesToRepeat; 558 break; 559 } 560 } 561 } 562 563 } 564 565 function setDefaults() 566 { 567 if (!$this->target_executables) $this->target_executables = $this->settings['default_executables']; 568 if (!$this->target_files) $this->target_files[] = AK_CI_TEST_DIR.DS.'test'.DS.'ci-unit.php'; 569 if (!$this->target_environments) $this->target_environments = $this->settings['environments']; 570 } 571 572 function constructTestFilename($filename) 573 { 574 if (is_file($filename)) return $filename; 575 576 $target_file = getcwd().DIRECTORY_SEPARATOR.$filename; 577 if (is_file($target_file)) return $target_file; 578 579 return false; 580 } 581 582 583 function config_file() 584 { 585 return AK_CI_TEST_DIR.DS.'config'.DS.'config.php'; 586 } 587 function fix_htaccess_file() 588 { 589 return AK_CI_TEST_DIR.DS.'config'.DS.'fix_htaccess.php'; 590 } 591 function ci_fix_htaccess_file() 592 { 593 return AK_BASE_DIR.DS.'script'.DS.'extras'.DS.'fix_htaccess.php'; 594 } 595 function ci_config_file() 596 { 597 return AK_BASE_DIR.DS.'config'.DS.'ci-config.php'; 598 } 599 600 function environment_file() 601 { 602 return AK_CI_TEST_DIR.DS.'config'.DS.'database.yml'; 603 } 604 function config_backup_file() 605 { 606 return AK_CI_TEST_DIR.DS.'config'.DS.'config-backup.php'; 607 } 608 609 function config_file_for($environment) 610 { 611 return AK_BASE_DIR.DS.'config'.DS.$this->settings['environments'][$environment].'.php'; 612 } 613 function environment_file_for($environment) 614 { 615 return AK_BASE_DIR.DS.'config'.DS.$environment.'.yml'; 616 } 617 function run() 618 { 619 $this->drawHeader(); 620 621 $this->beforeRun(); 622 for ($i=1; $i <= $this->timesToRun(); $i++){ 623 $this->drawRepeatIndicator($i); 624 foreach ($this->filesToRun() as $file){ 625 $this->info('Running test file: '.$file); 626 foreach ($this->executablesToRun() as $php_version){ 627 $this->info('Running tests for: '.$php_version); 628 foreach ($this->environmentsToRun() as $environment){ 629 if ($this->isValidCombination($environment,$php_version)){ 630 $return_value = $this->runCommand($php_version,$file,$environment); 631 if ($return_value !== 0) { 632 $this->markError(); 633 if ($this->options['break_on_errors']) break 4; 634 } else { 635 636 } 637 } 638 } 639 } 640 } 641 } 642 $this->_generateSummary(); 643 $this->afterRun(); 644 645 $this->drawFooter(); 646 } 647 648 function markError() 649 { 650 $this->errors = true; 651 } 652 653 function hadError() 654 { 655 return isset($this->errors); 656 } 657 658 function filesToRun() 659 { 660 return $this->target_files; 661 } 662 663 function executablesToRun() 664 { 665 return $this->target_executables; 666 } 667 668 function environmentsToRun() 669 { 670 return $this->target_environments; 671 } 672 673 function timesToRun() 674 { 675 return $this->options['repeat']; 676 } 677 678 function isValidCombination($environment,$php_version) 679 { 680 return in_array($environment,$this->settings['valid_combinations'][$php_version]); 681 } 682 683 function beforeRun() 684 { 685 $res = copy($this->config_file(),$this->config_backup_file()); 686 $res = copy($this->ci_config_file(),$this->config_file()) && $res; 687 return $res; 688 } 689 690 function afterRun() 691 { 692 if (copy($this->config_backup_file(),$this->config_file())){ 693 return unlink($this->config_backup_file()); 694 } 695 return false; 696 } 697 698 function prepareEnvironment($environment) 699 { 700 if (!is_file($this->environment_file_for($environment))){ 701 echo "Can't find environment settings for $environment. Skipping...\n\r"; 702 return false; 703 } 704 return copy($this->environment_file_for($environment),$this->environment_file()); 705 } 706 function _generateSummary() 707 { 708 $summaryFile = AK_BASE_DIR.DS.'test'.DS.'report'.DS.'index.html'; 709 $environments = $this->report_environments; 710 ob_start(); 711 include_once(AK_BASE_DIR.DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.'summary.php'); 712 $contents = ob_get_clean(); 713 714 $res = file_put_contents($summaryFile, $contents) > 0; 715 if ($res) { 716 $this->info('Summary Report available at: '.$summaryFile); 717 } else { 718 $this->error('Could not generate Summary Report: '.$summaryFile); 719 } 720 } 721 function _generateReport($xmlFile,$php,$env) 722 { 723 if (version_compare(PHP_VERSION,'5','>=')&&extension_loaded('xsl')) { 724 $this->debug('Including php5 xslt wrapper'); 725 require_once(AK_BASE_DIR.DS.'vendor'.DS.'xslt-php4-php5'.DS.'xslt-php4-php5.php'); 726 } 727 728 // Fail if XSLT extension is not available 729 if( ! function_exists( 'xslt_create' ) ) { 730 $this->error('Cannot generate report: xslt extension missing'); 731 return FALSE; 732 } 733 $currentDir = getcwd(); 734 chdir(AK_BASE_DIR . DIRECTORY_SEPARATOR . 'resources'.DIRECTORY_SEPARATOR . 'xsl'); 735 $xsl_file = AK_BASE_DIR . DIRECTORY_SEPARATOR . 'resources'.DIRECTORY_SEPARATOR . 'xsl' .DIRECTORY_SEPARATOR . 'phpunit2-noframes.xsl'; 736 737 // look for xsl 738 if( !is_readable( $xsl_file ) ) { 739 $this->error('Cannot generate report: '.$xsl_file.' missing'); 740 chdir($currentDir); 741 return FALSE; 742 } 743 if (!is_readable($xmlFile)) { 744 return false; 745 } 746 747 748 $schema = file_get_contents( $xmlFile ); 749 750 $xml = new SimpleXMLElement($schema); 751 $suites=$xml->xpath("/testsuites/testsuite"); 752 $tests=0; 753 $failures=0; 754 $errors=0; 755 $time=0; 756 757 foreach($suites as $suite){ 758 $attributes = $suite->attributes(); 759 $tests += (int)$attributes->tests; 760 $failures += (int)$attributes->failures; 761 $errors += (int)$attributes->errors; 762 $time += (float)$attributes->time; 763 } 764 $environment = array(); 765 $environment['php']=$php; 766 $environment['class']=$failures>0?'failure':$errors>0?'error':''; 767 $environment['backend']=$env; 768 $environment['tests']=$tests; 769 $environment['failures']=$failures; 770 $environment['errors']=$errors; 771 $environment['time']=round($time,3); 772 $link = AK_BASE_DIR.DS.'test'.DS.'report'.DS.$php.DS.$env.DS.'index.html'; 773 $environment['details']='file://'.$link; 774 $this->report_environments[]=$environment; 775 $arguments = array ( 776 '/_xml' => $schema, 777 '/_xsl' => file_get_contents( $xsl_file ) 778 ); 779 780 // create an XSLT processor 781 $xh = xslt_create (); 782 783 // set error handler 784 xslt_set_error_handler ($xh, array (&$this, 'xslt_error_handler')); 785 786 // process the schema 787 $result = xslt_process ($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments); 788 789 xslt_free ($xh); 790 791 $targetFile = AK_BASE_DIR.DS.'test'.DS.'report'.DS.$php.DS.$env.DS.'index.html'; 792 if (!file_exists(dirname($targetFile))) { 793 mkdir(dirname($targetFile),0777,true); 794 } 795 file_put_contents($targetFile,$result); 796 chdir($currentDir); 797 } 798 function runCommand($php,$filename,$environment) 799 { 800 $this->drawBox(array($filename,strtoupper($environment),$php)); 801 $returnVal = $this->_checkWebserver2($this->settings['test-url']); 802 if (!$returnVal) { 803 $this->error('Webserver is not configured properly. Exiting',true); 804 } 805 if ($this->prepareEnvironment($environment)){ 806 $xmlFile = getcwd().DIRECTORY_SEPARATOR.'test-results-'.$php.'-'.str_replace(' ','-',$environment).'.xml'; 807 $command = $this->settings['executables'][$php].' '.$filename.' --xml '.$xmlFile.' "'.$php.'" "'.$environment.'"'; 808 if ($this->options['test_mode']){ 809 echo "Executing: ".$command."\n\r"; 810 $return_value = 0; 811 }else{ 812 echo "Executing: ".$command."\n\r"; 813 passthru($command,$return_value); 814 } 815 $this->_generateReport($xmlFile,$php,$environment); 816 return $return_value; 817 } 818 } 819 820 function drawBox($message) 821 { 822 $this->drawNewline(); 823 $this->drawLine(); 824 $this->drawNewline(); 825 echo " TARGET: ".join(', ',$message)."\n\r"; 826 $this->drawLine(); 827 $this->drawNewline(); 828 } 829 830 function drawHeader() 831 { 832 #$this->drawLine('+'); 833 } 834 835 function drawFooter() 836 { 837 $this->drawNewline(); 838 $this->drawLine('+'); 839 $this->drawNewline(); 840 echo "FINISHED. "; 841 $this->drawNewline(); 842 if (!$this->hadError()) echo " All fine."; 843 } 844 845 function drawRepeatIndicator($actual) 846 { 847 if ($this->timesToRun() == 1) return; 848 849 $this->drawNewline(2); 850 echo str_pad('# '.$actual.'. ',80,'#'); 851 } 852 853 function drawLine($char='-',$num=80) 854 { 855 echo str_pad('',$num,$char); 856 } 857 858 function drawNewline($multiplier=1) 859 { 860 echo str_repeat("\n\r",$multiplier); 861 } 862 863 function drawHelp() 864 { 865 echo <<<BANNER 866 Usage: 867 868 ci_tests [php4|php5] [mysql|postgres|sqlite] [-b] [test-files] 869 -b break on first error 870 -t test-mode, don't run the commands actually 871 -n x repeat tests x times 872 -? this help 873 874 Examples: 875 > ci_tests 876 run all unit tests in any combination. 877 878 > ci_tests php5 postgres mysql AkHasMany AkBelongsTo 879 run AkHasMany and AkBelongsTo on PHP5 using the postgres and mysql-db. 880 881 Setup: 882 1. Copy DEFAULT-ci-config.yaml to config/ci-config.yaml and set it up 883 884 2. Copy config/config.php to config/mysql-testing.php, config/postgres-testing.php [...] and modify the database settings at least for the testing environment. You can configure the filename for these config-files in the script directly if you must. 885 886 3. Expects to be run from inside the test folder structure. So to speak your current directory must be */test or a subdir. The script itself can be placed whereever you want. You can define a (shell-)macro and quickly swap between different installations and test again. ;-) 887 888 This script backups config/config.php to config-backup.php (and restores it after run). 889 890 BANNER; 891 exit; 892 } 893 } 894 $test_args = array( 895 'Myself_will_be_thrown_away', 896 "all", 897 #"-b", 898 #"-?", 899 "-t", 900 #"-n","2", 901 #'AkHasMany.php', 902 #'postgres' 903 ); 904 #CI_Tests::main($test_args); 905 CI_Tests::main(); 906 907 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Oct 27 12:43:49 2008 | Cross-referenced by PHPXref 0.6 |