/vendor/phpunit/phpunit/src/Util/PHP/Default.php

https://gitlab.com/miltonkhondokar/grading_system_laravel · PHP · 215 lines · 134 code · 26 blank · 55 comment · 26 complexity · c4abb318c64fce10fcef7b7ae10dd502 MD5 · raw file

  1. <?php
  2. /*
  3. * This file is part of PHPUnit.
  4. *
  5. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. /**
  11. * Default utility for PHP sub-processes.
  12. *
  13. * @since Class available since Release 3.5.12
  14. */
  15. class PHPUnit_Util_PHP_Default extends PHPUnit_Util_PHP
  16. {
  17. /**
  18. * @var string
  19. */
  20. protected $tempFile;
  21. /**
  22. * @var bool
  23. */
  24. protected $useTempFile = false;
  25. /**
  26. * Runs a single job (PHP code) using a separate PHP process.
  27. *
  28. * @param string $job
  29. * @param array $settings
  30. *
  31. * @return array
  32. *
  33. * @throws PHPUnit_Framework_Exception
  34. */
  35. public function runJob($job, array $settings = [])
  36. {
  37. if ($this->useTempFile || $this->stdin) {
  38. if (!($this->tempFile = tempnam(sys_get_temp_dir(), 'PHPUnit')) ||
  39. file_put_contents($this->tempFile, $job) === false) {
  40. throw new PHPUnit_Framework_Exception(
  41. 'Unable to write temporary file'
  42. );
  43. }
  44. $job = $this->stdin;
  45. }
  46. return $this->runProcess($job, $settings);
  47. }
  48. /**
  49. * Returns an array of file handles to be used in place of pipes
  50. *
  51. * @return array
  52. */
  53. protected function getHandles()
  54. {
  55. return [];
  56. }
  57. /**
  58. * Handles creating the child process and returning the STDOUT and STDERR
  59. *
  60. * @param string $job
  61. * @param array $settings
  62. *
  63. * @return array
  64. *
  65. * @throws PHPUnit_Framework_Exception
  66. */
  67. protected function runProcess($job, $settings)
  68. {
  69. $handles = $this->getHandles();
  70. $env = null;
  71. if ($this->env) {
  72. $env = isset($_SERVER) ? $_SERVER : [];
  73. unset($env['argv'], $env['argc']);
  74. $env = array_merge($env, $this->env);
  75. foreach ($env as $envKey => $envVar) {
  76. if (is_array($envVar)) {
  77. unset($env[$envKey]);
  78. }
  79. }
  80. }
  81. $pipeSpec = [
  82. 0 => isset($handles[0]) ? $handles[0] : ['pipe', 'r'],
  83. 1 => isset($handles[1]) ? $handles[1] : ['pipe', 'w'],
  84. 2 => isset($handles[2]) ? $handles[2] : ['pipe', 'w'],
  85. ];
  86. $process = proc_open(
  87. $this->getCommand($settings, $this->tempFile),
  88. $pipeSpec,
  89. $pipes,
  90. null,
  91. $env
  92. );
  93. if (!is_resource($process)) {
  94. throw new PHPUnit_Framework_Exception(
  95. 'Unable to spawn worker process'
  96. );
  97. }
  98. if ($job) {
  99. $this->process($pipes[0], $job);
  100. }
  101. fclose($pipes[0]);
  102. if ($this->timeout) {
  103. $stderr = $stdout = '';
  104. unset($pipes[0]);
  105. while (true) {
  106. $r = $pipes;
  107. $w = null;
  108. $e = null;
  109. $n = @stream_select($r, $w, $e, $this->timeout);
  110. if ($n === false) {
  111. break;
  112. } elseif ($n === 0) {
  113. proc_terminate($process, 9);
  114. throw new PHPUnit_Framework_Exception(sprintf('Job execution aborted after %d seconds', $this->timeout));
  115. } elseif ($n > 0) {
  116. foreach ($r as $pipe) {
  117. $pipeOffset = 0;
  118. foreach ($pipes as $i => $origPipe) {
  119. if ($pipe == $origPipe) {
  120. $pipeOffset = $i;
  121. break;
  122. }
  123. }
  124. if (!$pipeOffset) {
  125. break;
  126. }
  127. $line = fread($pipe, 8192);
  128. if (strlen($line) == 0) {
  129. fclose($pipes[$pipeOffset]);
  130. unset($pipes[$pipeOffset]);
  131. } else {
  132. if ($pipeOffset == 1) {
  133. $stdout .= $line;
  134. } else {
  135. $stderr .= $line;
  136. }
  137. }
  138. }
  139. if (empty($pipes)) {
  140. break;
  141. }
  142. }
  143. }
  144. } else {
  145. if (isset($pipes[1])) {
  146. $stdout = stream_get_contents($pipes[1]);
  147. fclose($pipes[1]);
  148. }
  149. if (isset($pipes[2])) {
  150. $stderr = stream_get_contents($pipes[2]);
  151. fclose($pipes[2]);
  152. }
  153. }
  154. if (isset($handles[1])) {
  155. rewind($handles[1]);
  156. $stdout = stream_get_contents($handles[1]);
  157. fclose($handles[1]);
  158. }
  159. if (isset($handles[2])) {
  160. rewind($handles[2]);
  161. $stderr = stream_get_contents($handles[2]);
  162. fclose($handles[2]);
  163. }
  164. proc_close($process);
  165. $this->cleanup();
  166. return ['stdout' => $stdout, 'stderr' => $stderr];
  167. }
  168. /**
  169. * @param resource $pipe
  170. * @param string $job
  171. *
  172. * @throws PHPUnit_Framework_Exception
  173. *
  174. * @since Method available since Release 3.5.12
  175. */
  176. protected function process($pipe, $job)
  177. {
  178. fwrite($pipe, $job);
  179. }
  180. /**
  181. * @since Method available since Release 3.5.12
  182. */
  183. protected function cleanup()
  184. {
  185. if ($this->tempFile) {
  186. unlink($this->tempFile);
  187. }
  188. }
  189. }