1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Tester\Runner;
9:
10: use Tester\Environment;
11:
12:
13: 14: 15: 16: 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:
28: const RUN_USLEEP = 10000;
29:
30:
31: private $file;
32:
33:
34: private $args;
35:
36:
37: private $output;
38:
39:
40: private ;
41:
42:
43: private $php;
44:
45:
46: private $proc;
47:
48:
49: private $stdout;
50:
51:
52: private $exitCode = self::CODE_NONE;
53:
54:
55: 56: 57: 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: 69: 70: 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);
94: }
95: } else {
96: stream_set_blocking($this->stdout, 0);
97: }
98: }
99:
100:
101: 102: 103: 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: 136: 137:
138: public function getFile()
139: {
140: return $this->file;
141: }
142:
143:
144: 145: 146: 147:
148: public function getArguments()
149: {
150: return $this->args;
151: }
152:
153:
154: 155: 156: 157:
158: public function getExitCode()
159: {
160: return $this->exitCode;
161: }
162:
163:
164: 165: 166: 167:
168: public function getOutput()
169: {
170: return $this->output;
171: }
172:
173:
174: 175: 176: 177:
178: public function ()
179: {
180: return $this->headers;
181: }
182:
183: }
184: