Commit 1fb6dbf6 authored by Kurzenberger's avatar Kurzenberger
Browse files

Merge branch 'master' into niklas-dev-recommendation

parents cee505a2 07cd8123
1 merge request!1Coding style and recommendations
Pipeline #10969 passed with stage
Showing with 983 additions and 1 deletion
+983 -1
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file contains the backend webservice contact functionality for the DTA plugin
*
* @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright Gero Lueckemeyer and student project teams
*/
/**
* backend webservice contact utility class
*
* @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright Gero Lueckemeyer and student project teams
*/
class DtaBackendUtils {
/**
* Returns the base url of the backend webservice as configured in the administration settings.
* @return string backend host base url
*/
private static function getbackendbaseurl(): string {
$backendaddress = get_config(assign_submission_dta::COMPONENT_NAME, "backendHost");
if (empty($backendaddress)) {
\core\notification::error(get_string("backendHost_not_set", assign_submission_dta::COMPONENT_NAME));
}
return $backendaddress;
}
/**
* Sends the configuration textfile uploaded by prof to the backend.
*
* @param stdClass $assignment assignment this test-config belongs to
* @param stdClass $file uploaded test-config
* @return bool true if no error occurred
*/
public static function sendtestconfigtobackend($assignment, $file): bool {
$backendaddress = self::getbackendbaseurl();
if (empty($backendaddress)) {
return true;
}
// Set endpoint for test upload.
$url = $backendaddress . "/v1/unittest";
// Prepare params.
$params = [
"unitTestFile" => $file,
"assignmentId" => $assignment->get_instance()->id,
];
// If request returned null, return false to indicate failure.
if (is_null(self::post($url, $params))) {
return false;
} else {
return true;
}
}
/**
* Sends submission config or archive to backend to be tested.
*
* @param stdClass $assignment assignment for the submission
* @param int $submissionid submissionid of the current file
* @param stdClass $file submission config file or archive with submission
* @return string json string with testresults or null on error
*/
public static function sendsubmissiontobackend($assignment, $submissionid, $file): ?string {
$backendaddress = self::getbackendbaseurl();
if (empty($backendaddress)) {
return true;
}
// Set endpoint for test upload.
$url = $backendaddress . "/v1/task/" . $submissionid;
// Prepare params.
$params = [
"taskFile" => $file,
"assignmentId" => $assignment->get_instance()->id,
];
return self::post($url, $params);
}
/**
* Posts the given params to the given url and returns the response as a string.
* @param string $url full url to request to
* @param array $params parameters for http-request
*
* @return string received body on success or null on error
*/
private static function post($url, $params): ?string {
if (!isset($url) || !isset($params)) {
return false;
}
$options = ["CURLOPT_RETURNTRANSFER" => true];
$curl = new curl();
$response = $curl->post($url, $params, $options);
// Check state of request, if response code is a 2xx return the answer.
$info = $curl->get_info();
if ($info["http_code"] >= 200 && $info["http_code"] < 300) {
return $response;
}
// Something went wrong, return null and give an error message.
debugging(assign_submission_dta::COMPONENT_NAME . ": Post file to server was not successful: http_code=" .
$info["http_code"]);
if ($info['http_code'] >= 400 && $info['http_code'] < 500) {
\core\notification::error(get_string("http_client_error_msg", assign_submission_dta::COMPONENT_NAME));
return null;
} else if ($info['http_code'] >= 500 && $info['http_code'] < 600) {
\core\notification::error(get_string("http_server_error_msg", assign_submission_dta::COMPONENT_NAME));
return null;
} else {
\core\notification::error(get_string("http_unknown_error_msg", assign_submission_dta::COMPONENT_NAME) .
$info["http_code"] . $response);
return null;
}
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* persistence layer utility class
*
* @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright Gero Lueckemeyer and student project teams
*/
class DbUtils {
/**
* Summary database table name.
*/
private const TABLE_SUMMARY = "assignsubmission_dta_summary";
/**
* Result database table name.
*/
private const TABLE_RESULT = "assignsubmission_dta_result";
/**
* gets summary with all corresponding result entries
*
* @param int $assignmentid assignment id to search for
* @param int $submissionid submission id to search for
* @return DttResultSummary representing given submission
*/
public static function getresultsummaryfromdatabase(
int $assignmentid,
int $submissionid
): DtaResultSummary {
global $DB;
// Fetch data from database.
$summaryrecord = $DB->get_record(self::TABLE_SUMMARY, [
"assignment_id" => $assignmentid,
"submission_id" => $submissionid,
]);
$resultsarray = $DB->get_records(self::TABLE_RESULT, [
"assignment_id" => $assignmentid,
"submission_id" => $submissionid,
]);
// Create a summary instance.
$summary = new DtaResultSummary();
$summary->timestamp = $summaryrecord->timestamp;
$summary->globalstacktrace = $summaryrecord->global_stacktrace;
$summary->successfultestcompetencies = $summaryrecord->successful_competencies;
$summary->overalltestcompetencies = $summaryrecord->tested_competencies;
$summary->results = [];
// Create result instances and add to array of summary instance.
foreach ($resultsarray as $rr) {
$result = new DtaResult();
$result->packagename = $rr->package_name;
$result->classname = $rr->class_name;
$result->name = $rr->name;
$result->state = $rr->state;
$result->failuretype = $rr->failure_type;
$result->failurereason = $rr->failure_reason;
$result->stacktrace = $rr->stacktrace;
$result->columnnumber = $rr->column_number;
$result->linenumber = $rr->line_number;
$result->position = $rr->position;
$summary->results[] = $result;
}
return $summary;
}
/**
* save given result summary and single results to database
* under given assignment and submission id
*
* @param int $assignmentid assigment this is submission is linked to
* @param int $submissionid submission of this result
* @param DtaResultSummary $summary instance to persist
*/
public static function storeresultsummarytodatabase(
int $assignmentid,
int $submissionid,
DtaResultSummary $summary
): void {
global $DB;
// Prepare new database entries.
$summaryrecord = new stdClass();
$summaryrecord->assignment_id = $assignmentid;
$summaryrecord->submission_id = $submissionid;
$summaryrecord->timestamp = $summary->timestamp;
$summaryrecord->global_stacktrace = $summary->globalstacktrace;
$summaryrecord->successful_competencies = $summary->successfultestcompetencies;
$summaryrecord->tested_competencies = $summary->overalltestcompetencies;
// Prepare results to persist to array.
$resultrecords = [];
foreach ($summary->results as $r) {
$record = new stdClass();
$record->assignment_id = $assignmentid;
$record->submission_id = $submissionid;
$record->package_name = $r->packagename;
$record->class_name = $r->classname;
$record->name = $r->name;
$record->state = $r->state;
$record->failure_type = $r->failuretype;
$record->failure_reason = $r->failurereason;
$record->stacktrace = $r->stacktrace;
$record->column_number = $r->columnnumber;
$record->line_number = $r->linenumber;
$record->position = $r->position;
$resultrecords[] = $record;
}
// If results already exist, delete old values beforehand.
$submission = $DB->get_record(self::TABLE_SUMMARY, [
'assignment_id' => $assignmentid,
'submission_id' => $submissionid,
]);
if ($submission) {
$DB->delete_records(self::TABLE_RESULT, [
'assignment_id' => $assignmentid,
'submission_id' => $submissionid,
]);
$DB->delete_records(self::TABLE_SUMMARY, [
'assignment_id' => $assignmentid,
'submission_id' => $submissionid,
]);
}
// Create summary and single result entries.
$DB->insert_record(self::TABLE_SUMMARY, $summaryrecord);
foreach ($resultrecords as $rr) {
$DB->insert_record(self::TABLE_RESULT, $rr);
}
}
/**
* cleans up database if plugin is uninstalled
*/
public static function uninstallplugincleaup(): void {
global $DB;
$DB->delete_records(self::TABLE_RESULT, null);
$DB->delete_records(self::TABLE_SUMMARY, null);
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* utility class for DTA submission plugin result display
*
* @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright Gero Lueckemeyer and student project teams
*/
class view_submission_utils {
/**
* Broadly used in logic, parametrized for easier change.
*/
const COMPONENT_NAME = "assignsubmission_dta";
/**
* generates a short summary html
*
* @param int $assignmentid assignment
* @param int $submissionid submission to create a report for
* @return string html
*/
public static function generatesummaryhtml(
int $assignmentid,
int $submissionid
): string {
// Fetch data.
$summary = DbUtils::getResultSummaryFromDatabase($assignmentid, $submissionid);
$html = "";
// Calculate success rate, if no unknown result states or compilation errors.
$successrate = "?";
if ($summary->unknownCount() == 0 && $summary->compilationErrorCount() == 0) {
$successrate = round(($summary->successfulCount() / $summary->resultCount()) * 100, 2 );
}
// Generate html.
$html .= $summary->successfulCount() . "/";
$html .= ($summary->compilationErrorCount() == 0 && $summary->unknownCount() == 0)
? $summary->resultCount() . " (" . $successrate . "%)"
: "?";
$html .= get_string("tests_successful", self::COMPONENT_NAME) . "<br />";
if ($summary->compilationErrorCount() > 0) {
$html .= $summary->compilationErrorCount() . get_string("compilation_errors", self::COMPONENT_NAME) . "<br />";
}
if ($summary->unknownCount() > 0) {
$html .= $summary->unknownCount() . get_string("unknown_state", self::COMPONENT_NAME) . "<br />";
}
$showncompetencies = explode(";", $summary->successfultestcompetencies);
$overallcompetencies = explode(";", $summary->overalltestcompetencies);
$tmp = "";
for ($index = 0, $size = count($showncompetencies); $index < $size; $index++) {
$shown = $showncompetencies[$index];
$comp = $overallcompetencies[$index];
// If the competency was actually assessed by the assignment and tests, add a summary entry.
if ($shown != "0") {
$tmp .= get_string("comp" . $index, self::COMPONENT_NAME) .
" " . 100 * floatval($shown) / floatval($comp) . "% " . "<br />";
}
}
$html .= get_string("success_competencies", self::COMPONENT_NAME) . "<br />" . $tmp . "<br />";
return html_writer::div($html, "dtaSubmissionSummary");
}
/**
* generates detailed view html
*
* @param int $assignmentid assignment
* @param int $submissionid submission to create a report for
*/
public static function generatedetailhtml(
int $assignmentid,
int $submissionid
): string {
// Fetch data.
$summary = DbUtils::getResultSummaryFromDatabase($assignmentid, $submissionid);
$html = "";
// Define a few css classes and prepare html attribute arrays to beautify the output.
$tableheaderrowattributes = ["class" => "dtaTableHeaderRow"];
$tablerowattributes = ["class" => "dtaTableRow"];
$resultrowattributes = $tablerowattributes;
$unknownattributes = 'dtaResultUnknown';
$successattributes = 'dtaResultSuccess';
$failureattributes = 'dtaResultFailure';
$compilationerrorattributes = 'dtaResultCompilationError';
// Summary table.
$tmp = "";
$tmp .= html_writer::tag("th", get_string("summary", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]);
$tmp .= html_writer::empty_tag("th", ["class" => "dtaTableHeader"]);
$header = html_writer::tag("tr", $tmp, $tableheaderrowattributes);
$header = html_writer::tag("thead", $header);
$body = "";
$tmp = "";
$attributes = ["class" => "dtaTableData"];
$tmp .= html_writer::tag(
"td",
get_string("total_items", self::COMPONENT_NAME),
$attributes);
$tmp .= html_writer::tag(
"td",
$summary->resultCount(),
$attributes);
$resultrowattributes = $tablerowattributes;
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $unknownattributes;
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
$tmp = "";
$tmp .= html_writer::tag("td", get_string("tests_successful", self::COMPONENT_NAME), $attributes);
$tmp .= html_writer::tag( "td", $summary->successfulCount(), $attributes);
$resultrowattributes = $tablerowattributes;
$successrate = "?";
if ($summary->unknownCount() > 0 || $summary->compilationErrorCount() > 0) {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $unknownattributes;
} else {
$successrate = round(($summary->successfulCount() / $summary->resultCount()) * 100, 2 );
if ($successrate < 50) {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $compilationerrorattributes;
} else if ($successrate < 75) {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $failureattributes;
} else {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $successattributes;
}
}
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
$tmp = "";
$tmp .= html_writer::tag("td", get_string("failures", self::COMPONENT_NAME), $attributes);
$tmp .= html_writer::tag("td", $summary->failedCount(), $attributes);
$resultrowattributes = $tablerowattributes;
if ($summary->failedCount() > 0) {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $failureattributes;
} else {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $successattributes;
}
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
$tmp = "";
$tmp .= html_writer::tag("td", get_string("compilation_errors", self::COMPONENT_NAME), $attributes);
$tmp .= html_writer::tag("td", $summary->compilationErrorCount(), $attributes);
$resultrowattributes = $tablerowattributes;
if ($summary->compilationErrorCount() > 0) {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $compilationerrorattributes;
} else {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $successattributes;
}
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
$tmp = "";
$tmp .= html_writer::tag("td", get_string("unknown_state", self::COMPONENT_NAME), $attributes);
$tmp .= html_writer::tag("td", $summary->unknownCount(), $attributes);
$resultrowattributes = $tablerowattributes;
if ($summary->unknownCount() > 0) {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $unknownattributes;
} else {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $successattributes;
}
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
$tmp = "";
$tmp .= html_writer::tag("td", html_writer::tag("b", get_string("success_rate", self::COMPONENT_NAME)), $attributes);
$tmp .= html_writer::tag(
"td",
html_writer::tag("b", $summary->successfulCount()
. "/" . (($summary->compilationErrorCount() == 0 && $summary->unknownCount() == 0) ? $summary->resultCount()
. " (" . $successrate . "%)"
: "?")),
$attributes);
$resultrowattributes = $tablerowattributes;
if ($summary->unknownCount() > 0 || $summary->compilationErrorCount() > 0) {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $unknownattributes;
} else {
if ($successrate < 50) {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $compilationerrorattributes;
} else if ($successrate < 75) {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $failureattributes;
} else {
$resultrowattributes['class'] = $resultrowattributes['class'] . " " . $successattributes;
}
}
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
$body = html_writer::tag("tbody", $body);
$table = html_writer::tag("table", $header . $body, ["class" => "dtaTable"]);
$html .= $table;
// Add empty div for spacing between summary and compentency table.
$html .= html_writer::empty_tag("div", ["class" => "dtaSpacer"]);
// Competency assessment table.
$body = "";
$tmp = "";
$tmp .= html_writer::tag("th", get_string("competencies", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]);
$tmp .= html_writer::empty_tag("th", ["class" => "dtaTableHeader"]);
$header = html_writer::tag("tr", $tmp, $tableheaderrowattributes);
$header = html_writer::tag("thead", $header);
$showncompetencies = explode(";", $summary->successfultestcompetencies);
$overallcompetencies = explode(";", $summary->overalltestcompetencies);
for ($index = 0, $size = count($overallcompetencies); $index < $size; $index++) {
$comp = $overallcompetencies[$index];
$shown = $showncompetencies[$index];
// If the competency was actually assessed by the assignment and tests, add a row in the table.
if ($comp != "0") {
// New copy of base attributes array.
$resultrowattributes = $tablerowattributes;
$tmp = "";
$tmp .= html_writer::tag("td", get_string("comp" . $index, self::COMPONENT_NAME), $resultrowattributes);
$tmp .= html_writer::tag("td", 100 * floatval($shown) / floatval($comp) . "% " .
"(" . $shown . " / " . $comp . ")", $resultrowattributes);
$tmp .= html_writer::tag("td", get_string("comp_expl" . $index, self::COMPONENT_NAME), $resultrowattributes);
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
}
}
$body = html_writer::tag("tbody", $body);
$html .= html_writer::tag("table", $header . $body, ["class" => "dtaTable"]);
// Add empty div for spacing between competency and details table.
$html .= html_writer::empty_tag("div", ["class" => "dtaSpacer"]);
// Details table.
$tmp = "";
$tmp .= html_writer::tag("th", get_string("details", self::COMPONENT_NAME), ["class" => "dtaTableHeader"]);
$tmp .= html_writer::empty_tag("th", ["class" => "dtaTableHeader"]);
$header = html_writer::tag("tr", $tmp, $tableheaderrowattributes);
$header = html_writer::tag("thead", $header);
$body = "";
$spacerrow = null;
foreach ($summary->results as $r) {
// Add spacer first if not null.
if (!is_null($spacerrow)) {
$body .= $spacerrow;
}
// New copy of base attributes array.
$resultrowattributes = $tablerowattributes;
// Check which css class to add for the colored left-border according to resuls state.
if ($r->state == 0) {
$resultrowattributes['class'] = $resultrowattributes['class'] . ' dtaResultUnknown';
} else if ($r->state == 1) {
$resultrowattributes['class'] = $resultrowattributes['class'] . ' dtaResultSuccess';
} else if ($r->state == 2) {
$resultrowattributes['class'] = $resultrowattributes['class'] . ' dtaResultFailure';
} else if ($r->state == 3) {
$resultrowattributes['class'] = $resultrowattributes['class'] . ' dtaResultCompilationError';
}
$tmp = "";
$tmp .= html_writer::tag(
"td",
get_string("package_name", self::COMPONENT_NAME),
$attributes);
$tmp .= html_writer::tag(
"td",
$r->packagename,
$attributes);
$tmp .= html_writer::tag(
"td",
get_string("unit_name", self::COMPONENT_NAME),
$attributes);
$tmp .= html_writer::tag(
"td",
$r->classname,
$attributes);
$tmp .= html_writer::tag(
"td",
get_string("test_name", self::COMPONENT_NAME),
$attributes);
$tmp .= html_writer::tag(
"td",
$r->name,
$attributes);
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
$tmp = "";
$tmp .= html_writer::tag(
"td",
get_string("status", self::COMPONENT_NAME),
$attributes);
$tmp .= html_writer::tag(
"td",
DtaResult::getStateName($r->state),
$attributes);
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
// If state is something different than successful, show additional rows.
if ($r->state != 1) {
$tmp = "";
$tmp .= html_writer::tag(
"td",
get_string("failure_type", self::COMPONENT_NAME),
$attributes);
$tmp .= html_writer::tag(
"td",
$r->failureType,
$attributes);
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
$tmp = "";
$tmp .= html_writer::tag(
"td",
get_string("failure_reason", self::COMPONENT_NAME),
$attributes);
$tmp .= html_writer::tag(
"td",
$r->failureReason,
$attributes);
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
// Only show line, column and position if they have useful values.
if (!is_null($r->lineNumber) && $r->lineNumber > 0) {
$tmp = "";
$tmp .= html_writer::tag(
"td",
get_string("line_no", self::COMPONENT_NAME),
$attributes);
$tmp .= html_writer::tag(
"td",
$r->lineNumber,
$attributes);
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
}
if (!is_null($r->columnNumber) && $r->columnNumber > 0) {
$tmp = "";
$tmp .= html_writer::tag(
"td",
get_string("col_no", self::COMPONENT_NAME),
$attributes);
$tmp .= html_writer::tag(
"td",
$r->columnNumber,
$attributes);
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
}
if (!is_null($r->position) && $r->position > 0) {
$tmp = "";
$tmp .= html_writer::tag(
"td",
get_string("pos", self::COMPONENT_NAME),
$attributes);
$tmp .= html_writer::tag(
"td",
$r->position,
$attributes);
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
}
$tmp = "";
$tmp .= html_writer::tag(
"td",
get_string("stacktrace", self::COMPONENT_NAME),
$attributes);
$tmp .= html_writer::tag(
"td",
html_writer::tag("details", $r->stacktrace, ["class" => "dtaStacktraceDetails"]),
$attributes);
$body .= html_writer::tag("tr", $tmp, $resultrowattributes);
}
// Set spacerrow value if null for next round separation.
if (is_null($spacerrow)) {
$spacerrow = html_writer::empty_tag("tr", ["class" => "dtaTableSpacer"]);
}
}
$html .= html_writer::tag("table", $header . $body, ["class" => "dtaTable"]);
// Wrap generated html into final div.
$html = html_writer::div($html, "dtaSubmissionDetails");
return $html;
}
}
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* entity classes for DTA submission plugin result summary and test results
*
* @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright Gero Lueckemeyer and student project teams
*/
defined('MOODLE_INTERNAL') || die();
/**
* entity class for DTA submission plugin result
*
* @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright Gero Lueckemeyer and student project teams
*/
class DtaResult {
/**
* Broadly used in logic, parametrized for easier change.
*/
const COMPONENT_NAME = "assignsubmission_dta";
/**
* @var $packagename Package name of the test.
*/
public $packagename;
/**
* @var $classname Unit name of the test.
*/
public $classname;
/**
* @var $name Name of the test.
*/
public $name;
/**
* @var $state State is defined like below
*
* 0 UNKNOWN
* 1 SUCCESS
* 2 FAILURE
* 3 COMPILATIONERROR
*/
public $state;
/**
* @var $failuretype Type of test failure if applicable, "" otherwise.
*/
public $failuretype;
/**
* @var $failurereason Reason of test failure if applicable, "" otherwise.
*/
public $failurereason;
/**
* @var $stacktrace Stack trace of test failure if applicable, "" otherwise.
*/
public $stacktrace;
/**
* @var $columnnumber Column number of compile failure if applicable, "" otherwise.
*/
public $columnnumber;
/**
* @var $linenumber Line number of compile failure if applicable, "" otherwise.
*/
public $linenumber;
/**
* @var $position Position of compile failure if applicable, "" otherwise.
*/
public $position;
/**
* Returns the name of a state with the given number of display.
* @param int $state number of the state
* @return string name of state as defined
*/
public static function getstatename(int $state): string {
if ($state == 1) {
return get_string("tests_successful", self::COMPONENT_NAME);
} else if ($state == 2) {
return get_string("failures", self::COMPONENT_NAME);
} else if ($state == 3) {
return get_string("compilation_errors", self::COMPONENT_NAME);
} else {
return get_string("unknown_state", self::COMPONENT_NAME);
}
}
}
/**
* entity class for DTA submission plugin result
*
* @package assignsubmission_dta
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright Gero Lueckemeyer and student project teams
*/
class DtaResultSummary {
/**
* @var $timestamp Result timestamp for chronological ordering and deletion of previous results.
*/
public $timestamp;
/**
* @var $globalstacktrace Global stack trace if applicable, "" otherwise.
*/
public $globalstacktrace;
/**
* @var $successfultestcompetencies Successfully tested competencies according to tests and weights, "" otherwise.
*/
public $successfultestcompetencies;
/**
* @var overalltestcompetencies Overall tested competencies according to tests and weights, "" otherwise.
*/
public $overalltestcompetencies;
/**
* @var results List of detail results.
*/
public $results;
/**
* Decodes the JSON result summary returned by the backend service call into the plugin PHP data structure.
* @param string $jsonstring jsonString containing DtaResultSummary
* @return DtaResultSummary the result summary
*/
public static function decodejson(string $jsonstring): DtaResultSummary {
$response = json_decode($jsonstring);
$summary = new DtaResultSummary();
$summary->timestamp = $response->timestamp;
$summary->globalstacktrace = $response->globalstacktrace;
$summary->successfultestcompetencies = $response->successfulTestCompetencyProfile;
$summary->overalltestcompetencies = $response->overallTestCompetencyProfile;
$summary->results = self::decodejsonresultarray($response->results);
return $summary;
}
/**
* Decodes the array of JSON detail results returned by the backend service call into the plugin PHP data structure.
* @param array $jsonarray decoded json array of results array
* @return array of DtaResult
*/
private static function decodejsonresultarray($jsonarray): array {
$ret = [];
foreach ($jsonarray as $entry) {
$value = new DtaResult();
$value->packagename = $entry->packageName;
$value->classname = $entry->className;
$value->name = $entry->name;
$value->state = $entry->state;
$value->failuretype = $entry->failureType;
$value->failurereason = $entry->failureReason;
$value->stacktrace = $entry->stacktrace;
$value->columnnumber = $entry->columnNumber;
$value->linenumber = $entry->lineNumber;
$value->position = $entry->position;
$ret[] = $value;
}
return $ret;
}
/**
* Returns the number of detail results attached to the summary.
* @return int count of occurences
*/
public function resultcount(): int {
return count($this->results);
}
/**
* Returns the number of detail results with the given state attached to the summary.
* @param int $state state ordinal number
* @return int count of occurences provided state has
*/
public function stateoccurencecount(int $state): int {
$num = 0;
foreach ($this->results as $r) {
if ($r->state == $state) {
$num++;
}
}
return $num;
}
/**
* Returns the number of detail results with compilation errors attached to the summary.
* @return int count of occurences
*/
public function compilationerrorcount(): int {
return $this->stateoccurencecount(3);
}
/**
* Returns the number of detail results with test failures attached to the summary.
* @return int count of occurences
*/
public function failedcount(): int {
return $this->stateoccurencecount(2);
}
/**
* Returns the number of detail results with successful tests attached to the summary.
* @return int count of occurences
*/
public function successfulcount(): int {
return $this->stateoccurencecount(1);
}
/**
* Returns the number of detail results with an unknown result - mostly due to compile errors - attached to the summary.
* @return int count of occurences
*/
public function unknowncount(): int {
return $this->stateoccurencecount(0);
}
}
......@@ -62,7 +62,7 @@ foreach ($list->good as $component) {
foreach ($collection->get_collection() as $item) {
if ($item instanceof \core_privacy\local\metadata\types\user_preference) {
$userprefdescribed = true;
echo " ".$item->assignsubmission_dta_get_name()." : ".get_string($item->get_summary(), $component) . "\n";
echo " ".$item->get_name()." : ".get_string($item->get_summary(), $component) . "\n";
}
}
if (!$userprefdescribed) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment