1010use PhpSchool \PhpWorkshop \Exercise \ExerciseInterface ;
1111use PhpSchool \PhpWorkshop \Exercise \ExerciseType ;
1212use PhpSchool \PhpWorkshop \Exercise \Scenario \CliScenario ;
13- use PhpSchool \PhpWorkshop \ExerciseDispatcher ;
1413use PhpSchool \PhpWorkshop \Output \OutputInterface ;
1514use PhpSchool \PhpWorkshop \Result \ComparisonFailure ;
1615use PhpSchool \PhpWorkshop \Result \Failure ;
@@ -31,48 +30,59 @@ public function getDescription(): string
3130
3231 public function defineListeners (EventDispatcher $ eventDispatcher ): void
3332 {
34- $ appendArgsListener = function (CliExecuteEvent $ event ) {
35- $ event ->appendArg ('127.0.0.1 ' );
36- $ event ->appendArg ($ this ->getRandomPort ());
37- };
38-
39- $ eventDispatcher ->listen ('cli.verify.reference-execute.pre ' , $ appendArgsListener );
40- $ eventDispatcher ->listen ('cli.verify.student-execute.pre ' , $ appendArgsListener );
41- $ eventDispatcher ->listen ('cli.run.student-execute.pre ' , $ appendArgsListener );
42-
43- $ eventDispatcher ->listen ('cli.verify.reference.executing ' , function (CliExecuteEvent $ event ) {
44- $ args = $ event ->getArgs ()->getArrayCopy ();
33+ $ referencePort = $ this ->getRandomPort ();
34+ $ studentPort = $ this ->getRandomPort ();
35+
36+ $ eventDispatcher ->listen ('cli.verify.reference-execute.pre ' ,
37+ function (CliExecuteEvent $ event ) use ($ referencePort ) {
38+ $ event ->appendArg ('0.0.0.0 ' );
39+ $ event ->appendArg ($ referencePort );
40+ $ event ->getScenario ()->exposePort ($ referencePort );
41+ }
42+ );
43+ $ eventDispatcher ->listen (
44+ ['cli.verify.student-execute.pre ' , 'cli.run.student-execute.pre ' ],
45+ function (CliExecuteEvent $ event ) use ($ studentPort ) {
46+ $ event ->appendArg ('0.0.0.0 ' );
47+ $ event ->appendArg ($ studentPort );
48+ $ event ->getScenario ()->exposePort ($ studentPort );
49+ }
50+ );
4551
52+ $ eventDispatcher ->listen ('cli.verify.reference.executing ' , function (CliExecuteEvent $ event ) use ($ referencePort ) {
4653 //wait for server to boot
47- usleep ( 100000 );
54+ sleep ( 1 );
4855
4956 $ socket = $ this ->createSocket ();
50- socket_connect ($ socket , $ args [0 ], (int ) $ args [1 ]);
51- socket_read ($ socket , 2048 , PHP_NORMAL_READ );
57+ @socket_connect ($ socket , '0.0.0.0 ' , $ referencePort );
58+ @socket_read ($ socket , 2048 , PHP_NORMAL_READ );
59+
60+ socket_close ($ socket );
5261
5362 //wait for shutdown
5463 usleep (100000 );
5564 });
5665
57- $ eventDispatcher ->insertVerifier ('cli.verify.student.executing ' , function (CliExecuteEvent $ event ) {
58- $ args = $ event ->getArgs ()->getArrayCopy ();
59-
66+ $ eventDispatcher ->insertVerifier ('cli.verify.student.executing ' , function (CliExecuteEvent $ event ) use ($ studentPort ) {
6067 //wait for server to boot
61- usleep ( 100000 );
68+ sleep ( 1 );
6269
6370 $ socket = $ this ->createSocket ();
64- $ connectResult = @socket_connect ($ socket , $ args [0 ], (int ) $ args [1 ]);
6571
66- if (!$ connectResult ) {
72+ $ result = @socket_connect ($ socket , '0.0.0.0 ' , $ studentPort );
73+
74+ if (!$ result ) {
6775 return Failure::fromNameAndReason ($ this ->getName (), sprintf (
68- "Client returns an error (number %d): Connection refused while trying to join tcp://127 .0.0.1 :%d. " ,
76+ "Client returns an error (number %d): Connection refused while trying to join tcp://0 .0.0.0 :%d. " ,
6977 socket_last_error ($ socket ),
70- $ args [ 1 ]
78+ $ studentPort
7179 ));
7280 }
7381
7482 $ out = (string ) socket_read ($ socket , 2048 , PHP_NORMAL_READ );
7583
84+ socket_close ($ socket );
85+
7686 //wait for shutdown
7787 usleep (100000 );
7888
@@ -86,16 +96,25 @@ public function defineListeners(EventDispatcher $eventDispatcher): void
8696 return new Success ($ this ->getName ());
8797 });
8898
89- $ eventDispatcher ->listen ('cli.run.student.executing ' , function (CliExecuteEvent $ event ) {
99+ $ eventDispatcher ->listen ('cli.run.student.executing ' , function (CliExecuteEvent $ event ) use ( $ studentPort ) {
90100 /** @var OutputInterface $output */
91101 $ output = $ event ->getParameter ('output ' );
92- $ args = $ event ->getArgs ()->getArrayCopy ();
93102
94103 //wait for server to boot
95- usleep ( 100000 );
104+ sleep ( 1 );
96105
97106 $ socket = $ this ->createSocket ();
98- socket_connect ($ socket , $ args [0 ], (int ) $ args [1 ]);
107+ try {
108+ $ connectResult = @socket_connect ($ socket , '0.0.0.0 ' , $ studentPort );
109+ } catch (\ErrorException $ e ) {
110+ $ output ->write ('Cannot connect ' );
111+ return ;
112+ }
113+
114+ if (false === $ connectResult ) {
115+ $ output ->write ('Cannot connect ' );
116+ return ;
117+ }
99118 $ out = (string ) socket_read ($ socket , 2048 , PHP_NORMAL_READ );
100119
101120 //wait for shutdown
@@ -107,7 +126,7 @@ public function defineListeners(EventDispatcher $eventDispatcher): void
107126
108127 private function getRandomPort (): string
109128 {
110- return ( string ) mt_rand (1025 , 65535 );
129+ return mt_rand (8001 , 10000 );
111130 }
112131
113132 public function getType (): ExerciseType
@@ -117,7 +136,8 @@ public function getType(): ExerciseType
117136
118137 public function defineTestScenario (): CliScenario
119138 {
120- return (new CliScenario ())->withExecution ();
139+ return (new CliScenario ())
140+ ->withExecution ();
121141 }
122142
123143 private function createSocket (): Socket
@@ -128,6 +148,8 @@ private function createSocket(): Socket
128148 throw new RuntimeException ('Cannot create socket ' );
129149 }
130150
151+ socket_set_option ($ socket , SOL_SOCKET , SO_RCVTIMEO , ["sec " => 5 , "usec " => 0 ]);
152+
131153 return $ socket ;
132154 }
133155}
0 commit comments