[ Index ]

PHP Cross Reference of Akelos Framework

title

Body

[close]

/utils/scripts/ -> ci-test.php (source)

   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  ?>


Generated: Mon Oct 27 12:43:49 2008 Cross-referenced by PHPXref 0.6