Skip to content

Commit

Permalink
Try fix timeserver
Browse files Browse the repository at this point in the history
  • Loading branch information
AydinHassan committed Sep 4, 2024
1 parent 2906141 commit 6e14900
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 41 deletions.
8 changes: 4 additions & 4 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

80 changes: 51 additions & 29 deletions src/Exercise/TimeServer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -31,48 +30,59 @@ 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('0.0.0.0');
$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('0.0.0.0');
$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);
sleep(1);

$socket = $this->createSocket();
socket_connect($socket, $args[0], (int) $args[1]);
socket_read($socket, 2048, PHP_NORMAL_READ);
@socket_connect($socket, '0.0.0.0', $referencePort);
@socket_read($socket, 2048, PHP_NORMAL_READ);

socket_close($socket);

//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);
sleep(1);

$socket = $this->createSocket();
$connectResult = @socket_connect($socket, $args[0], (int) $args[1]);

if (!$connectResult) {
$result = @socket_connect($socket, '0.0.0.0', $studentPort);

if (!$result) {
return Failure::fromNameAndReason($this->getName(), sprintf(
"Client returns an error (number %d): Connection refused while trying to join tcp://127.0.0.1:%d.",
"Client returns an error (number %d): Connection refused while trying to join tcp://0.0.0.0:%d.",
socket_last_error($socket),
$args[1]
$studentPort
));
}

$out = (string) socket_read($socket, 2048, PHP_NORMAL_READ);

socket_close($socket);

//wait for shutdown
usleep(100000);

Expand All @@ -86,16 +96,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);
sleep(1);

$socket = $this->createSocket();
socket_connect($socket, $args[0], (int) $args[1]);
try {
$connectResult = @socket_connect($socket, '0.0.0.0', $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
Expand All @@ -107,7 +126,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
Expand All @@ -117,7 +136,8 @@ public function getType(): ExerciseType

public function defineTestScenario(): CliScenario
{
return (new CliScenario())->withExecution();
return (new CliScenario())
->withExecution();
}

private function createSocket(): Socket
Expand All @@ -128,6 +148,8 @@ private function createSocket(): Socket
throw new RuntimeException('Cannot create socket');
}

socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, ["sec" => 5, "usec" => 0]);

return $socket;
}
}
10 changes: 2 additions & 8 deletions test/Exercise/TimeServerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,8 @@ public function testFailureWhenCannotConnect(): void

$this->assertVerifyWasNotSuccessful();

if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
$reason = '/^Client returns an error \(number \d+\): No connection could be made because';
$reason .= ' the target machine actively refused it\.\r\n';
$reason .= ' while trying to join tcp:\/\/127\.0\.0\.1:\d+\.$/';
} else {
$reason = '/^Client returns an error \(number \d+\): Connection refused';
$reason .= ' while trying to join tcp:\/\/127\.0\.0\.1:\d+\.$/';
}
$reason = '/^Client returns an error \(number \d+\): Connection refused';
$reason .= ' while trying to join tcp:\/\/0\.0\.0\.0:\d+\.$/';

$this->assertResultsHasFailureAndMatches(Failure::class, function (Failure $failure) use ($reason) {
$this->assertMatchesRegularExpression($reason, $failure->getReason());
Expand Down

0 comments on commit 6e14900

Please sign in to comment.