/** * Runs a student's solution by invoking PHP via the `php-cgi` binary, populating all the super globals with * the information from the request objects returned from the exercise. The exercise can return multiple * requests so the solution will be invoked for however many requests there are. * * Running only runs the student's solution, the reference solution is not run and no verification is performed, * the output of the student's solution is written directly to the output. * * Events dispatched (for each request): * * * cgi.run.student-execute.pre * * cgi.run.student.executing * * @param Input $input The command line arguments passed to the command. * @param OutputInterface $output A wrapper around STDOUT. * @return bool If the solution was successfully executed, eg. exit code was 0. */ public function run(Input $input, OutputInterface $output) { $this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cgi.run.start', $this->exercise, $input)); $success = true; foreach ($this->exercise->getRequests() as $i => $request) { $event = $this->eventDispatcher->dispatch(new CgiExecuteEvent('cgi.run.student-execute.pre', $request)); $process = $this->getProcess($input->getArgument('program'), $event->getRequest()); $output->writeTitle("Request"); $output->emptyLine(); $output->write($this->requestRenderer->renderRequest($request)); $output->writeTitle("Output"); $output->emptyLine(); $process->start(); $this->eventDispatcher->dispatch(new CgiExecuteEvent('cgi.run.student.executing', $request, ['output' => $output])); $process->wait(function ($outputType, $outputBuffer) use($output) { $output->write($outputBuffer); }); $output->emptyLine(); if (!$process->isSuccessful()) { $success = false; } $output->lineBreak(); } $this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cgi.run.finish', $this->exercise, $input)); return $success; }
/** * Render the details of each failed request including the mismatching headers and body. * * @param ResultsRenderer $renderer * @return string */ public function render(ResultsRenderer $renderer) { $results = array_filter($this->result->getResults(), function (ResultInterface $result) { return $result instanceof FailureInterface; }); $output = ''; if (count($results)) { $output .= $renderer->center("Some requests to your solution produced incorrect output!\n"); } foreach ($results as $key => $request) { $output .= $renderer->lineBreak(); $output .= "\n"; $output .= $renderer->style(sprintf('Request %d', $key + 1), ['bold', 'underline', 'blue']); $output .= ' ' . $renderer->style(' FAILED ', ['bg_red', 'bold']) . "\n\n"; $output .= "Request Details:\n\n"; $output .= $this->requestRenderer->renderRequest($request->getRequest()) . "\n"; $output .= $renderer->renderResult($request) . "\n"; } return $output; }