10
10
use PhpSchool \PhpWorkshop \Exercise \ExerciseInterface ;
11
11
use PhpSchool \PhpWorkshop \Exercise \ExerciseType ;
12
12
use PhpSchool \PhpWorkshop \Exercise \Scenario \CliScenario ;
13
- use PhpSchool \PhpWorkshop \ExerciseDispatcher ;
14
13
use PhpSchool \PhpWorkshop \Output \OutputInterface ;
15
14
use PhpSchool \PhpWorkshop \Result \ComparisonFailure ;
16
15
use PhpSchool \PhpWorkshop \Result \Failure ;
@@ -31,48 +30,59 @@ public function getDescription(): string
31
30
32
31
public function defineListeners (EventDispatcher $ eventDispatcher ): void
33
32
{
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
+ );
45
51
52
+ $ eventDispatcher ->listen ('cli.verify.reference.executing ' , function (CliExecuteEvent $ event ) use ($ referencePort ) {
46
53
//wait for server to boot
47
- usleep ( 100000 );
54
+ sleep ( 1 );
48
55
49
56
$ 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 );
52
61
53
62
//wait for shutdown
54
63
usleep (100000 );
55
64
});
56
65
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 ) {
60
67
//wait for server to boot
61
- usleep ( 100000 );
68
+ sleep ( 1 );
62
69
63
70
$ socket = $ this ->createSocket ();
64
- $ connectResult = @socket_connect ($ socket , $ args [0 ], (int ) $ args [1 ]);
65
71
66
- if (!$ connectResult ) {
72
+ $ result = @socket_connect ($ socket , '0.0.0.0 ' , $ studentPort );
73
+
74
+ if (!$ result ) {
67
75
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. " ,
69
77
socket_last_error ($ socket ),
70
- $ args [ 1 ]
78
+ $ studentPort
71
79
));
72
80
}
73
81
74
82
$ out = (string ) socket_read ($ socket , 2048 , PHP_NORMAL_READ );
75
83
84
+ socket_close ($ socket );
85
+
76
86
//wait for shutdown
77
87
usleep (100000 );
78
88
@@ -86,16 +96,25 @@ public function defineListeners(EventDispatcher $eventDispatcher): void
86
96
return new Success ($ this ->getName ());
87
97
});
88
98
89
- $ eventDispatcher ->listen ('cli.run.student.executing ' , function (CliExecuteEvent $ event ) {
99
+ $ eventDispatcher ->listen ('cli.run.student.executing ' , function (CliExecuteEvent $ event ) use ( $ studentPort ) {
90
100
/** @var OutputInterface $output */
91
101
$ output = $ event ->getParameter ('output ' );
92
- $ args = $ event ->getArgs ()->getArrayCopy ();
93
102
94
103
//wait for server to boot
95
- usleep ( 100000 );
104
+ sleep ( 1 );
96
105
97
106
$ 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
+ }
99
118
$ out = (string ) socket_read ($ socket , 2048 , PHP_NORMAL_READ );
100
119
101
120
//wait for shutdown
@@ -107,7 +126,7 @@ public function defineListeners(EventDispatcher $eventDispatcher): void
107
126
108
127
private function getRandomPort (): string
109
128
{
110
- return ( string ) mt_rand (1025 , 65535 );
129
+ return mt_rand (8001 , 10000 );
111
130
}
112
131
113
132
public function getType (): ExerciseType
@@ -117,7 +136,8 @@ public function getType(): ExerciseType
117
136
118
137
public function defineTestScenario (): CliScenario
119
138
{
120
- return (new CliScenario ())->withExecution ();
139
+ return (new CliScenario ())
140
+ ->withExecution ();
121
141
}
122
142
123
143
private function createSocket (): Socket
@@ -128,6 +148,8 @@ private function createSocket(): Socket
128
148
throw new RuntimeException ('Cannot create socket ' );
129
149
}
130
150
151
+ socket_set_option ($ socket , SOL_SOCKET , SO_RCVTIMEO , ["sec " => 5 , "usec " => 0 ]);
152
+
131
153
return $ socket ;
132
154
}
133
155
}
0 commit comments