private function run_tests_singly($code, $testcases, $files, $sandboxparams) { $maxMark = $this->maximum_possible_mark($testcases); $templateparams = array('STUDENT_ANSWER' => $code, 'ESCAPED_STUDENT_ANSWER' => python_escaper(null, $code, null), 'MATLAB_ESCAPED_STUDENT_ANSWER' => matlab_escaper(null, $code, null), 'QUESTION' => $this); $outcome = new qtype_coderunner_testing_outcome($maxMark); $template = $this->pertesttemplate; foreach ($testcases as $testcase) { $templateparams['TEST'] = $testcase; try { $testprog = $this->twig->render($template, $templateparams); } catch (Exception $e) { $outcome = new qtype_coderunner_testing_outcome($maxMark, qtype_coderunner_testing_outcome::STATUS_SYNTAX_ERROR, 'TEMPLATE ERROR: ' . $e->getMessage()); break; } $input = isset($testcase->stdin) ? $testcase->stdin : ''; $this->allruns[] = $testprog; $run = $this->sandboxinstance->execute($testprog, $this->language, $input, $files, $sandboxparams); if ($run->error !== qtype_coderunner_sandbox::OK) { $outcome = new qtype_coderunner_testing_outcome($maxMark, qtype_coderunner_testing_outcome::STATUS_SANDBOX_ERROR, qtype_coderunner_sandbox::error_string($run->error)); break; } else { if ($run->result === qtype_coderunner_sandbox::RESULT_COMPILATION_ERROR) { $outcome = new qtype_coderunner_testing_outcome($maxMark, qtype_coderunner_testing_outcome::STATUS_SYNTAX_ERROR, $run->cmpinfo); break; } else { if ($run->result != qtype_coderunner_sandbox::RESULT_SUCCESS) { $errormessage = $this->make_error_message($run); $iserror = true; $outcome->add_test_result($this->grade($errormessage, $testcase, $iserror)); break; } else { // Successful run. Merge stdout and stderr for grading. // [Rarely if ever do we get both stderr output and a // RESULT_SUCCESS result but it has been known to happen in the // past, possibly with a now-defunct sandbox.] $output = $run->stderr ? $run->output + '\\n' + $run->stderr : $run->output; $outcome->add_test_result($this->grade($output, $testcase)); } } } } return $outcome; }