18
18
use PhpSchool \PhpWorkshop \Exception \SolutionExecutionException ;
19
19
use PhpSchool \PhpWorkshop \Exercise \CgiExercise ;
20
20
use PhpSchool \PhpWorkshop \Exercise \ExerciseInterface ;
21
+ use PhpSchool \PhpWorkshop \ExerciseRunner \Context \ExecutionContext ;
21
22
use PhpSchool \PhpWorkshop \Input \Input ;
22
23
use PhpSchool \PhpWorkshop \Output \OutputInterface ;
23
24
use PhpSchool \PhpWorkshop \Process \ProcessFactory ;
@@ -63,7 +64,8 @@ class CgiRunner implements ExerciseRunnerInterface
63
64
public function __construct (
64
65
private CgiExercise $ exercise ,
65
66
private EventDispatcher $ eventDispatcher ,
66
- private ProcessFactory $ processFactory
67
+ private ProcessFactory $ processFactory ,
68
+ private EnvironmentManager $ environmentManager
67
69
) {
68
70
}
69
71
@@ -99,36 +101,43 @@ public function getRequiredChecks(): array
99
101
* * cgi.verify.student.executing
100
102
* * cgi.verify.student-execute.fail (if the student's solution fails to execute)
101
103
*
102
- * @param Input $input The command line arguments passed to the command .
104
+ * @param ExecutionContext $context The current execution context, containing the exercise, input and working directories .
103
105
* @return CgiResult The result of the check.
104
106
*/
105
- public function verify (Input $ input ): ResultInterface
107
+ public function verify (ExecutionContext $ context ): ResultInterface
106
108
{
107
109
$ scenario = $ this ->exercise ->defineTestScenario ();
108
110
109
- $ this ->eventDispatcher ->dispatch (new CgiExerciseRunnerEvent ('cgi.verify.start ' , $ this ->exercise , $ input ));
111
+ $ this ->eventDispatcher ->dispatch (new CgiExerciseRunnerEvent ('cgi.verify.start ' , $ this ->exercise , $ context ->getInput ()));
112
+
113
+ $ this ->environmentManager ->prepareStudent ($ context , $ scenario );
114
+ $ this ->environmentManager ->prepareReference ($ context , $ scenario );
110
115
111
116
$ result = new CgiResult (
112
117
array_map (
113
- function (RequestInterface $ request ) use ($ input ) {
114
- return $ this ->doVerify ($ request , $ input );
118
+ function (RequestInterface $ request ) use ($ context ) {
119
+ return $ this ->doVerify ($ request , $ context );
115
120
},
116
121
$ scenario ->getExecutions ()
117
122
)
118
123
);
119
- $ this ->eventDispatcher ->dispatch (new CgiExerciseRunnerEvent ('cgi.verify.finish ' , $ this ->exercise , $ input ));
124
+
125
+ $ this ->environmentManager ->cleanup ($ context , $ scenario );
126
+
127
+ $ this ->eventDispatcher ->dispatch (new CgiExerciseRunnerEvent ('cgi.verify.finish ' , $ this ->exercise , $ context ->getInput ()));
120
128
return $ result ;
121
129
}
122
130
123
- private function doVerify (RequestInterface $ request , Input $ input ): CgiResultInterface
131
+ private function doVerify (RequestInterface $ request , ExecutionContext $ context ): CgiResultInterface
124
132
{
125
133
try {
126
134
/** @var CgiExecuteEvent $event */
127
135
$ event = $ this ->eventDispatcher ->dispatch (
128
- new CgiExecuteEvent ('cgi.verify.reference-execute.pre ' , $ this ->exercise , $ input , $ request )
136
+ new CgiExecuteEvent ('cgi.verify.reference-execute.pre ' , $ this ->exercise , $ context -> getInput () , $ request )
129
137
);
130
138
$ solutionResponse = $ this ->executePhpFile (
131
- $ input ,
139
+ $ context ,
140
+ $ context ->getReferenceExecutionDirectory (),
132
141
$ this ->exercise ->getSolution ()->getEntryPoint ()->getAbsolutePath (),
133
142
$ event ->getRequest (),
134
143
'reference '
@@ -138,7 +147,7 @@ private function doVerify(RequestInterface $request, Input $input): CgiResultInt
138
147
new CgiExecuteEvent (
139
148
'cgi.verify.reference-execute.fail ' ,
140
149
$ this ->exercise ,
141
- $ input ,
150
+ $ context -> getInput () ,
142
151
$ request ,
143
152
['exception ' => $ e ]
144
153
)
@@ -149,11 +158,12 @@ private function doVerify(RequestInterface $request, Input $input): CgiResultInt
149
158
try {
150
159
/** @var CgiExecuteEvent $event */
151
160
$ event = $ this ->eventDispatcher ->dispatch (
152
- new CgiExecuteEvent ('cgi.verify.student-execute.pre ' , $ this ->exercise , $ input , $ request )
161
+ new CgiExecuteEvent ('cgi.verify.student-execute.pre ' , $ this ->exercise , $ context -> getInput () , $ request )
153
162
);
154
163
$ userResponse = $ this ->executePhpFile (
155
- $ input ,
156
- $ input ->getRequiredArgument ('program ' ),
164
+ $ context ,
165
+ $ context ->getStudentExecutionDirectory (),
166
+ $ context ->getEntryPoint (),
157
167
$ event ->getRequest (),
158
168
'student '
159
169
);
@@ -162,7 +172,7 @@ private function doVerify(RequestInterface $request, Input $input): CgiResultInt
162
172
new CgiExecuteEvent (
163
173
'cgi.verify.student-execute.fail ' ,
164
174
$ this ->exercise ,
165
- $ input ,
175
+ $ context -> getInput () ,
166
176
$ request ,
167
177
['exception ' => $ e ]
168
178
)
@@ -202,16 +212,17 @@ private function getHeaders(ResponseInterface $response): array
202
212
* @return ResponseInterface
203
213
*/
204
214
private function executePhpFile (
205
- Input $ input ,
215
+ ExecutionContext $ context ,
216
+ string $ workingDirectory ,
206
217
string $ fileName ,
207
218
RequestInterface $ request ,
208
219
string $ type
209
220
): ResponseInterface {
210
- $ process = $ this ->getPhpProcess (dirname ( $ fileName ), basename ( $ fileName) , $ request );
221
+ $ process = $ this ->getPhpProcess ($ workingDirectory , $ fileName , $ request );
211
222
212
223
$ process ->start ();
213
224
$ this ->eventDispatcher ->dispatch (
214
- new CgiExecuteEvent (sprintf ('cgi.verify.%s.executing ' , $ type ), $ this ->exercise , $ input , $ request )
225
+ new CgiExecuteEvent (sprintf ('cgi.verify.%s.executing ' , $ type ), $ this ->exercise , $ context -> getInput () , $ request )
215
226
);
216
227
$ process ->wait ();
217
228
@@ -280,25 +291,27 @@ private function getPhpProcess(string $workingDirectory, string $fileName, Reque
280
291
* * cgi.run.student-execute.pre
281
292
* * cgi.run.student.executing
282
293
*
283
- * @param Input $input The command line arguments passed to the command .
294
+ * @param ExecutionContext $context The current execution context, containing the exercise, input and working directories .
284
295
* @param OutputInterface $output A wrapper around STDOUT.
285
296
* @return bool If the solution was successfully executed, eg. exit code was 0.
286
297
*/
287
- public function run (Input $ input , OutputInterface $ output ): bool
298
+ public function run (ExecutionContext $ context , OutputInterface $ output ): bool
288
299
{
289
300
$ scenario = $ this ->exercise ->defineTestScenario ();
290
301
291
- $ this ->eventDispatcher ->dispatch (new CgiExerciseRunnerEvent ('cgi.run.start ' , $ this ->exercise , $ input ));
302
+ $ this ->eventDispatcher ->dispatch (new CgiExerciseRunnerEvent ('cgi.run.start ' , $ this ->exercise , $ context ->getInput ()));
303
+
304
+ $ this ->environmentManager ->prepareStudent ($ context , $ scenario );
292
305
293
306
$ success = true ;
294
307
foreach ($ scenario ->getExecutions () as $ i => $ request ) {
295
308
/** @var CgiExecuteEvent $event */
296
309
$ event = $ this ->eventDispatcher ->dispatch (
297
- new CgiExecuteEvent ('cgi.run.student-execute.pre ' , $ this ->exercise , $ input , $ request )
310
+ new CgiExecuteEvent ('cgi.run.student-execute.pre ' , $ this ->exercise , $ context -> getInput () , $ request )
298
311
);
299
312
$ process = $ this ->getPhpProcess (
300
- dirname ( $ input -> getRequiredArgument ( ' program ' ) ),
301
- $ input -> getRequiredArgument ( ' program ' ),
313
+ $ context -> getStudentExecutionDirectory ( ),
314
+ $ context -> getEntryPoint ( ),
302
315
$ event ->getRequest ()
303
316
);
304
317
@@ -307,7 +320,7 @@ public function run(Input $input, OutputInterface $output): bool
307
320
new CgiExecuteEvent (
308
321
'cgi.run.student.executing ' ,
309
322
$ this ->exercise ,
310
- $ input ,
323
+ $ context -> getInput () ,
311
324
$ request ,
312
325
['output ' => $ output ]
313
326
)
@@ -324,10 +337,13 @@ public function run(Input $input, OutputInterface $output): bool
324
337
$ output ->lineBreak ();
325
338
326
339
$ this ->eventDispatcher ->dispatch (
327
- new CgiExecuteEvent ('cgi.run.student-execute.post ' , $ this ->exercise , $ input , $ request )
340
+ new CgiExecuteEvent ('cgi.run.student-execute.post ' , $ this ->exercise , $ context -> getInput () , $ request )
328
341
);
329
342
}
330
- $ this ->eventDispatcher ->dispatch (new CgiExerciseRunnerEvent ('cgi.run.finish ' , $ this ->exercise , $ input ));
343
+
344
+ $ this ->environmentManager ->cleanup ($ context , $ scenario );
345
+
346
+ $ this ->eventDispatcher ->dispatch (new CgiExerciseRunnerEvent ('cgi.run.finish ' , $ this ->exercise , $ context ->getInput ()));
331
347
return $ success ;
332
348
}
333
349
}
0 commit comments