/core/src/test/php/net/xp_framework/unittest/core/ProcessTest.class.php

https://github.com/treuter/xp-framework · PHP · 255 lines · 121 code · 22 blank · 112 comment · 3 complexity · a86d5791e0b191bf6e0003f958087d78 MD5 · raw file

  1. <?php
  2. /* This class is part of the XP framework
  3. *
  4. * $Id$
  5. */
  6. uses(
  7. 'unittest.TestCase',
  8. 'lang.Runtime',
  9. 'lang.System',
  10. 'lang.Process',
  11. 'io.streams.Streams',
  12. 'io.streams.MemoryOutputStream'
  13. );
  14. /**
  15. * TestCase for Process class
  16. *
  17. * @see xp://lang.Process
  18. */
  19. class ProcessTest extends TestCase {
  20. /**
  21. * Skips tests if process execution has been disabled.
  22. */
  23. #[@beforeClass]
  24. public static function verifyProcessExecutionEnabled() {
  25. if (Process::$DISABLED) {
  26. throw new PrerequisitesNotMetError('Process execution disabled', NULL, array('enabled'));
  27. }
  28. }
  29. /**
  30. * Return executable name
  31. *
  32. * @return string
  33. */
  34. protected function executable() {
  35. return Runtime::getInstance()->getExecutable()->getFilename();
  36. }
  37. /**
  38. * Test process status information methods
  39. *
  40. * @see xp://lang.Process#getProcessId
  41. * @see xp://lang.Process#getFilename
  42. * @see xp://lang.Process#getCommandLine
  43. * @see xp://lang.Process#exitValue
  44. */
  45. #[@test]
  46. public function information() {
  47. $p= new Process($this->executable(), array('-v'));
  48. try {
  49. $this->assertEquals(-1, $p->exitValue(), 'Process should not have exited yet');
  50. $this->assertNotEquals(0, $p->getProcessId());
  51. $this->assertNotEquals('', $p->getFilename());
  52. $this->assertTrue(create(new String($p->getCommandLine()))->contains('-v'));
  53. $p->close();
  54. } catch (AssertionFailedError $e) {
  55. $p->close(); // Ensure process is closed
  56. throw $e;
  57. }
  58. }
  59. /**
  60. * Tests Process::newInstance()
  61. *
  62. */
  63. #[@test]
  64. public function newInstance() {
  65. $p= Runtime::getInstance()->getExecutable()->newInstance(array('-v'));
  66. $version= 'PHP '.phpversion();
  67. $this->assertEquals($version, $p->out->read(strlen($version)));
  68. $p->close();
  69. }
  70. /**
  71. * Test exit value
  72. *
  73. */
  74. #[@test]
  75. public function exitValueReturnedFromClose() {
  76. $p= new Process($this->executable(), array('-r', 'exit(0);'));
  77. $this->assertEquals(0, $p->close());
  78. }
  79. /**
  80. * Test non-zero exit value
  81. *
  82. */
  83. #[@test]
  84. public function nonZeroExitValueReturnedFromClose() {
  85. $p= new Process($this->executable(), array('-r', 'exit(2);'));
  86. $this->assertEquals(2, $p->close());
  87. }
  88. /**
  89. * Test exit value
  90. *
  91. */
  92. #[@test]
  93. public function exitValue() {
  94. $p= new Process($this->executable(), array('-r', 'exit(0);'));
  95. $p->close();
  96. $this->assertEquals(0, $p->exitValue());
  97. }
  98. /**
  99. * Test non-zero exit value
  100. *
  101. */
  102. #[@test]
  103. public function nonZeroExitValue() {
  104. $p= new Process($this->executable(), array('-r', 'exit(2);'));
  105. $p->close();
  106. $this->assertEquals(2, $p->exitValue());
  107. }
  108. /**
  109. * Test standard input
  110. *
  111. */
  112. #[@test]
  113. public function stdIn() {
  114. $p= new Process($this->executable(), array('-r', 'fprintf(STDOUT, fread(STDIN, 0xFF));'));
  115. $p->in->write('IN');
  116. $p->in->close();
  117. $out= $p->out->read();
  118. $p->close();
  119. $this->assertEquals('IN', $out);
  120. }
  121. /**
  122. * Test standard output
  123. *
  124. */
  125. #[@test]
  126. public function stdOut() {
  127. $p= new Process($this->executable(), array('-r', 'fprintf(STDOUT, "OUT");'));
  128. $out= $p->out->read();
  129. $p->close();
  130. $this->assertEquals('OUT', $out);
  131. }
  132. /**
  133. * Test standard error
  134. *
  135. */
  136. #[@test]
  137. public function stdErr() {
  138. $p= new Process($this->executable(), array('-r', 'fprintf(STDERR, "ERR");'));
  139. $err= $p->err->read();
  140. $p->close();
  141. $this->assertEquals('ERR', $err);
  142. }
  143. /**
  144. * Test running a non-existant file
  145. *
  146. */
  147. #[@test, @expect('io.IOException')]
  148. public function runningNonExistantFile() {
  149. new Process(':FILE_DOES_NOT_EXIST:');
  150. }
  151. /**
  152. * Test running a directory (System::tempDir() used as argument)
  153. *
  154. */
  155. #[@test, @expect('io.IOException')]
  156. public function runningDirectory() {
  157. new Process(System::tempDir());
  158. }
  159. /**
  160. * Test running an empty command ("")
  161. *
  162. */
  163. #[@test, @expect('io.IOException')]
  164. public function runningEmpty() {
  165. new Process('');
  166. }
  167. /**
  168. * Test getProcessById() method
  169. *
  170. */
  171. #[@test, @expect('lang.IllegalStateException')]
  172. public function nonExistantProcessId() {
  173. Process::getProcessById(-1);
  174. }
  175. /**
  176. * Test getProcessById() method
  177. *
  178. */
  179. #[@test]
  180. public function getByProcessId() {
  181. $pid= getmypid();
  182. $p= Process::getProcessById($pid);
  183. $this->assertInstanceOf('lang.Process', $p);
  184. $this->assertEquals($pid, $p->getProcessId());
  185. }
  186. /**
  187. * Test invoking close() method twice
  188. *
  189. */
  190. #[@test]
  191. public function doubleClose() {
  192. $p= new Process($this->executable(), array('-r', 'exit(222);'));
  193. $this->assertEquals(222, $p->close());
  194. $this->assertEquals(222, $p->close());
  195. }
  196. /**
  197. * Test close() method on a process retrieved by getProcessById()
  198. *
  199. */
  200. #[@test, @expect(class= 'lang.IllegalStateException', withMessage= '/Cannot close not-owned/')]
  201. public function closingProcessByProcessId() {
  202. Process::getProcessById(getmypid())->close();
  203. }
  204. /**
  205. * Test huge STDOUT output
  206. *
  207. */
  208. #[@test]
  209. public function hugeStdout() {
  210. $p= new Process($this->executable(), array('-r', 'fputs(STDOUT, str_repeat("*", 65536));'));
  211. $out= '';
  212. while (!$p->out->eof()) {
  213. $out.= $p->out->read();
  214. }
  215. $p->close();
  216. $this->assertEquals(65536, strlen($out));
  217. }
  218. /**
  219. * Test huge STDERR output
  220. *
  221. */
  222. #[@test]
  223. public function hugeStderr() {
  224. $p= new Process($this->executable(), array('-r', 'fputs(STDERR, str_repeat("*", 65536));'));
  225. $err= '';
  226. while (!$p->err->eof()) {
  227. $err.= $p->err->read();
  228. }
  229. $p->close();
  230. $this->assertEquals(65536, strlen($err));
  231. }
  232. }
  233. ?>