diff --git a/src/Exercise/TimeServer.php b/src/Exercise/TimeServer.php index ae1dada..b5ec382 100644 --- a/src/Exercise/TimeServer.php +++ b/src/Exercise/TimeServer.php @@ -10,7 +10,6 @@ use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface; use PhpSchool\PhpWorkshop\Exercise\ExerciseType; use PhpSchool\PhpWorkshop\Exercise\Scenario\CliScenario; -use PhpSchool\PhpWorkshop\ExerciseDispatcher; use PhpSchool\PhpWorkshop\Output\OutputInterface; use PhpSchool\PhpWorkshop\Result\ComparisonFailure; use PhpSchool\PhpWorkshop\Result\Failure; @@ -31,43 +30,50 @@ public function getDescription(): string public function defineListeners(EventDispatcher $eventDispatcher): void { - $appendArgsListener = function (CliExecuteEvent $event) { - $event->appendArg('127.0.0.1'); - $event->appendArg($this->getRandomPort()); - }; - - $eventDispatcher->listen('cli.verify.reference-execute.pre', $appendArgsListener); - $eventDispatcher->listen('cli.verify.student-execute.pre', $appendArgsListener); - $eventDispatcher->listen('cli.run.student-execute.pre', $appendArgsListener); - - $eventDispatcher->listen('cli.verify.reference.executing', function (CliExecuteEvent $event) { - $args = $event->getArgs()->getArrayCopy(); + $referencePort = $this->getRandomPort(); + $studentPort = $this->getRandomPort(); + + $eventDispatcher->listen('cli.verify.reference-execute.pre', + function (CliExecuteEvent $event) use ($referencePort) { + $event->appendArg('127.0.0.1'); + $event->appendArg($referencePort); + $event->getScenario()->exposePort($referencePort); + } + ); + $eventDispatcher->listen( + ['cli.verify.student-execute.pre', 'cli.run.student-execute.pre'], + function (CliExecuteEvent $event) use ($studentPort) { + $event->appendArg('127.0.0.1'); + $event->appendArg($studentPort); + $event->getScenario()->exposePort($studentPort); + } + ); + $eventDispatcher->listen('cli.verify.reference.executing', function (CliExecuteEvent $event) use ($referencePort) { //wait for server to boot usleep(100000); $socket = $this->createSocket(); - socket_connect($socket, $args[0], (int) $args[1]); + + $connectResult = @socket_connect($socket, '127.0.0.1', $referencePort); socket_read($socket, 2048, PHP_NORMAL_READ); //wait for shutdown usleep(100000); }); - $eventDispatcher->insertVerifier('cli.verify.student.executing', function (CliExecuteEvent $event) { - $args = $event->getArgs()->getArrayCopy(); - + $eventDispatcher->insertVerifier('cli.verify.student.executing', function (CliExecuteEvent $event) use ($studentPort) { //wait for server to boot usleep(100000); $socket = $this->createSocket(); - $connectResult = @socket_connect($socket, $args[0], (int) $args[1]); + $connectResult = @socket_connect($socket, '127.0.0.1', $studentPort); if (!$connectResult) { return Failure::fromNameAndReason($this->getName(), sprintf( "Client returns an error (number %d): Connection refused while trying to join tcp://127.0.0.1:%d.", socket_last_error($socket), - $args[1] + $studentPort )); } @@ -86,16 +92,25 @@ public function defineListeners(EventDispatcher $eventDispatcher): void return new Success($this->getName()); }); - $eventDispatcher->listen('cli.run.student.executing', function (CliExecuteEvent $event) { + $eventDispatcher->listen('cli.run.student.executing', function (CliExecuteEvent $event) use ($studentPort) { /** @var OutputInterface $output */ $output = $event->getParameter('output'); - $args = $event->getArgs()->getArrayCopy(); //wait for server to boot usleep(100000); $socket = $this->createSocket(); - socket_connect($socket, $args[0], (int) $args[1]); + try { + $connectResult = @socket_connect($socket, '127.0.0.1', $studentPort); + } catch (\ErrorException $e) { + $output->write('Cannot connect'); + return; + } + + if (false === $connectResult) { + $output->write('Cannot connect'); + return; + } $out = (string) socket_read($socket, 2048, PHP_NORMAL_READ); //wait for shutdown @@ -107,7 +122,7 @@ public function defineListeners(EventDispatcher $eventDispatcher): void private function getRandomPort(): string { - return (string) mt_rand(1025, 65535); + return mt_rand(8001, 10000); } public function getType(): ExerciseType @@ -117,7 +132,8 @@ public function getType(): ExerciseType public function defineTestScenario(): CliScenario { - return (new CliScenario())->withExecution(); + return (new CliScenario()) + ->withExecution(); } private function createSocket(): Socket