diff options
Diffstat (limited to 'ext/openssl/tests/ServerClientProxyTestCase.inc')
-rw-r--r-- | ext/openssl/tests/ServerClientProxyTestCase.inc | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/ext/openssl/tests/ServerClientProxyTestCase.inc b/ext/openssl/tests/ServerClientProxyTestCase.inc new file mode 100644 index 0000000000..c55159f52a --- /dev/null +++ b/ext/openssl/tests/ServerClientProxyTestCase.inc @@ -0,0 +1,117 @@ +<?php + +const WORKER_ARGV_VALUE = 'RUN_WORKER'; + +function phpt_notify($worker = null) +{ + ServerClientProxyTestCase::getInstance()->notify($worker); +} + +function phpt_wait($worker = null) +{ + ServerClientProxyTestCase::getInstance()->wait($worker); +} + +/** + * This is a singleton to let the wait/notify functions work + * I know it's horrible, but it's a means to an end + */ +class ServerClientProxyTestCase +{ + private $isWorker = false; + + private $workerHandles = []; + + private $workerStdIn = []; + + private $workerStdOut = []; + + private static $instance; + + public static function getInstance($isWorker = false) + { + if (!isset(self::$instance)) { + self::$instance = new self($isWorker); + } + + return self::$instance; + } + + public function __construct($isWorker = false) + { + if (!isset(self::$instance)) { + self::$instance = $this; + } + + $this->isWorker = $isWorker; + } + + private function spawnWorkerProcess($worker, $code) + { + if (defined("PHP_WINDOWS_VERSION_MAJOR")) { + $ini = php_ini_loaded_file(); + $cmd = sprintf('%s %s "%s" %s', PHP_BINARY, $ini ? "-n -c $ini" : "", __FILE__, WORKER_ARGV_VALUE); + } else { + $cmd = sprintf('%s "%s" %s %s', PHP_BINARY, __FILE__, WORKER_ARGV_VALUE, $worker); + } + $this->workerHandle[$worker] = proc_open($cmd, [['pipe', 'r'], ['pipe', 'w'], STDERR], $pipes); + $this->workerStdIn[$worker] = $pipes[0]; + $this->workerStdOut[$worker] = $pipes[1]; + + fwrite($this->workerStdIn[$worker], $code . "\n---\n"); + } + + private function cleanupWorkerProcess($worker) + { + fclose($this->workerStdIn[$worker]); + fclose($this->workerStdOut[$worker]); + proc_close($this->workerHandle[$worker]); + } + + private function stripPhpTagsFromCode($code) + { + return preg_replace('/^\s*<\?(?:php)?|\?>\s*$/i', '', $code); + } + + public function runWorker() + { + $code = ''; + + while (1) { + $line = fgets(STDIN); + + if (trim($line) === "---") { + break; + } + + $code .= $line; + } + + eval($code); + } + + public function run($testCode, array $workerCodes) + { + foreach ($workerCodes as $worker => $code) { + $this->spawnWorkerProcess($worker, $this->stripPhpTagsFromCode($code)); + } + eval($this->stripPhpTagsFromCode($testCode)); + foreach ($workerCodes as $worker => $code) { + $this->cleanupWorkerProcess($worker); + } + } + + public function wait($worker) + { + fgets($this->isWorker ? STDIN : $this->workerStdOut[$worker]); + } + + public function notify($worker) + { + fwrite($this->isWorker ? STDOUT : $this->workerStdIn[$worker], "\n"); + } +} + +if (isset($argv[1]) && $argv[1] === WORKER_ARGV_VALUE) { + ServerClientProxyTestCase::getInstance(true)->runWorker(); +} |