Overview

Namespaces

  • Budovy
  • Kdyby
    • BootstrapFormRenderer
      • DI
      • Latte
  • Nette
    • Application
      • Diagnostics
      • Responses
      • Routers
      • UI
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Diagnostics
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Diagnostics
      • Extensions
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
      • Diagnostics
    • Iterators
    • Latte
      • Macros
    • Loaders
    • Localization
    • Mail
    • PhpGenerator
    • Reflection
    • Security
      • Diagnostics
    • Templating
    • Utils
  • NetteModule
  • Nextras
    • Datagrid
  • None
  • PHP
  • Tester
    • CodeCoverage
    • Runner
      • Output
  • Vodacek
    • Forms
      • Controls
  • WebLoader
    • Filter
    • Nette

Classes

  • CommandLine
  • Job
  • PhpExecutable
  • Runner
  • TestHandler

Interfaces

  • OutputHandler
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Tester.
  5:  * Copyright (c) 2009 David Grudl (http://davidgrudl.com)
  6:  */
  7: 
  8: namespace Tester\Runner;
  9: 
 10: use Tester\Environment;
 11: 
 12: 
 13: /**
 14:  * Single test job.
 15:  *
 16:  * @author     David Grudl
 17:  */
 18: class Job
 19: {
 20:     const
 21:         CODE_NONE = -1,
 22:         CODE_OK = 0,
 23:         CODE_SKIP = 177,
 24:         CODE_FAIL = 178,
 25:         CODE_ERROR = 255;
 26: 
 27:     /** waiting time between process activity check in microseconds */
 28:     const RUN_USLEEP = 10000;
 29: 
 30:     /** @var string  test file */
 31:     private $file;
 32: 
 33:     /** @var string  test arguments */
 34:     private $args;
 35: 
 36:     /** @var string  test output */
 37:     private $output;
 38: 
 39:     /** @var string  output headers in raw format */
 40:     private $headers;
 41: 
 42:     /** @var PhpExecutable */
 43:     private $php;
 44: 
 45:     /** @var resource */
 46:     private $proc;
 47: 
 48:     /** @var resource */
 49:     private $stdout;
 50: 
 51:     /** @var int */
 52:     private $exitCode = self::CODE_NONE;
 53: 
 54: 
 55:     /**
 56:      * @param  string  test file name
 57:      * @return void
 58:      */
 59:     public function __construct($testFile, PhpExecutable $php, $args = NULL)
 60:     {
 61:         $this->file = (string) $testFile;
 62:         $this->php = $php;
 63:         $this->args = $args;
 64:     }
 65: 
 66: 
 67:     /**
 68:      * Runs single test.
 69:      * @param  bool  wait till process ends
 70:      * @return void
 71:      */
 72:     public function run($blocking = TRUE)
 73:     {
 74:         putenv(Environment::RUNNER . '=1');
 75:         putenv(Environment::COLORS . '=' . (int) Environment::$useColors);
 76:         $this->proc = proc_open(
 77:             $this->php->getCommandLine() . ' -d register_argc_argv=on ' . \Tester\Helpers::escapeArg($this->file) . ' ' . $this->args,
 78:             array(
 79:                 array('pipe', 'r'),
 80:                 array('pipe', 'w'),
 81:                 array('pipe', 'w'),
 82:             ),
 83:             $pipes,
 84:             dirname($this->file),
 85:             NULL,
 86:             array('bypass_shell' => TRUE)
 87:         );
 88:         list($stdin, $this->stdout, $stderr) = $pipes;
 89:         fclose($stdin);
 90:         fclose($stderr);
 91:         if ($blocking) {
 92:             while ($this->isRunning()) {
 93:                 usleep(self::RUN_USLEEP); // stream_select() doesn't work with proc_open()
 94:             }
 95:         } else {
 96:             stream_set_blocking($this->stdout, 0);
 97:         }
 98:     }
 99: 
100: 
101:     /**
102:      * Checks if the test is still running.
103:      * @return bool
104:      */
105:     public function isRunning()
106:     {
107:         if (!is_resource($this->stdout)) {
108:             return FALSE;
109:         }
110: 
111:         $this->output .= stream_get_contents($this->stdout);
112:         $status = proc_get_status($this->proc);
113:         if ($status['running']) {
114:             return TRUE;
115:         }
116: 
117:         fclose($this->stdout);
118:         $code = proc_close($this->proc);
119:         $this->exitCode = $code === self::CODE_NONE ? $status['exitcode'] : $code;
120: 
121:         if ($this->php->isCgi() && count($tmp = explode("\r\n\r\n", $this->output, 2)) >= 2) {
122:             list($headers, $this->output) = $tmp;
123:             foreach (explode("\r\n", $headers) as $header) {
124:                 $a = strpos($header, ':');
125:                 if ($a !== FALSE) {
126:                     $this->headers[trim(substr($header, 0, $a))] = (string) trim(substr($header, $a + 1));
127:                 }
128:             }
129:         }
130:         return FALSE;
131:     }
132: 
133: 
134:     /**
135:      * Returns test file path.
136:      * @return string
137:      */
138:     public function getFile()
139:     {
140:         return $this->file;
141:     }
142: 
143: 
144:     /**
145:      * Returns script arguments.
146:      * @return string
147:      */
148:     public function getArguments()
149:     {
150:         return $this->args;
151:     }
152: 
153: 
154:     /**
155:      * Returns exit code.
156:      * @return int
157:      */
158:     public function getExitCode()
159:     {
160:         return $this->exitCode;
161:     }
162: 
163: 
164:     /**
165:      * Returns test output.
166:      * @return string
167:      */
168:     public function getOutput()
169:     {
170:         return $this->output;
171:     }
172: 
173: 
174:     /**
175:      * Returns output headers.
176:      * @return string
177:      */
178:     public function getHeaders()
179:     {
180:         return $this->headers;
181:     }
182: 
183: }
184: 
API documentation generated by ApiGen 2.8.0