Skip to content

Commit 4a67689

Browse files
committed
Updates to bulktester and related utility scripts. Also, grade cache now includes jobe_host in job spec.
Updated bulktester to offer the option of clearing the grade cache for the course first. The bulktester now displays the current jobe_host value. Changed utility scripts to use namespaces.
1 parent 62ae9a4 commit 4a67689

10 files changed

+127
-33
lines changed

bulktest.php

+8-4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
2626
*/
2727

28+
namespace qtype_coderunner;
29+
2830
define('NO_OUTPUT_BUFFERING', true);
2931

3032
require_once(__DIR__ . '/../../../config.php');
@@ -37,15 +39,16 @@
3739
$repeatrandomonly = optional_param('repeatrandomonly', 1, PARAM_INT);
3840
$nruns = optional_param('nruns', 1, PARAM_INT);
3941
$questionids = optional_param('questionids', '', PARAM_RAW); // A list of specific questions to check, eg, for rechecking failed tests.
42+
$clearcachefirst = optional_param('clearcachefirst', 0, PARAM_INT);
4043

4144

4245
// Login and check permissions.
4346
require_login();
44-
$context = context::instance_by_id($contextid);
47+
$context = \context::instance_by_id($contextid);
4548
require_capability('moodle/question:editall', $context);
4649

4750
$urlparams = ['contextid' => $context->id, 'categoryid' => $categoryid, 'randomseed' => $randomseed,
48-
'repeatrandomonly' => $repeatrandomonly, 'nruns' => $nruns, 'questionids' => $questionids];
51+
'repeatrandomonly' => $repeatrandomonly, 'nruns' => $nruns, 'clearcachefirst' => $clearcachefirst, 'questionids' => $questionids];
4952
$PAGE->set_url('/question/type/coderunner/bulktest.php', $urlparams);
5053
$PAGE->set_context($context);
5154
$title = get_string('bulktesttitle', 'qtype_coderunner', $context->get_context_name());
@@ -66,12 +69,13 @@
6669

6770

6871
// Create the helper class.
69-
$bulktester = new qtype_coderunner_bulk_tester(
72+
$bulktester = new bulk_tester(
7073
$context,
7174
$categoryid,
7275
$randomseed,
7376
$repeatrandomonly,
74-
$nruns
77+
$nruns,
78+
$clearcachefirst
7579
);
7680

7781
// Was: Release the session, so the user can do other things while this runs.

bulktestall.php

+11-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@
2323
* @copyright 2016 Richard Lobb, The University of Canterbury
2424
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
2525
*/
26+
namespace qtype_coderunner;
27+
28+
use context;
29+
use context_system;
30+
use context_course;
31+
use html_writer;
32+
use moodle_url;
2633

2734
define('NO_OUTPUT_BUFFERING', true);
2835

@@ -60,7 +67,7 @@
6067

6168
// Run the tests.
6269
ini_set('memory_limit', '2048M'); // For big question banks - TODO: make this a setting?
63-
$contextdata = qtype_coderunner_bulk_tester::get_num_coderunner_questions_by_context();
70+
$contextdata = bulk_tester::get_num_coderunner_questions_by_context();
6471
foreach ($contextdata as $contextid => $numcoderunnerquestions) {
6572
if ($skipping && $contextid != $startfromcontextid) {
6673
continue;
@@ -69,8 +76,9 @@
6976
$testcontext = context::instance_by_id($contextid);
7077
if (has_capability('moodle/question:editall', $context)) {
7178
$PAGE->set_context($testcontext); // Helps grading cache pickup right course id.
72-
$bulktester = new qtype_coderunner_bulk_tester($testcontext);
79+
$bulktester = new bulk_tester($testcontext);
7380
echo $OUTPUT->heading(get_string('bulktesttitle', 'qtype_coderunner', $testcontext->get_context_name()));
81+
echo html_writer::tag('p', 'Note: Grading cache not cleared -- do it from admin-plugins-cache if you really want to clear the cache for all course!');
7482
echo html_writer::tag('p', html_writer::link(
7583
new moodle_url(
7684
'/question/type/coderunner/bulktestall.php',
@@ -87,5 +95,5 @@
8795
}
8896

8997
// Display the final summary.
90-
qtype_coderunner_bulk_tester::print_summary_after_bulktestall($numpasses, $allfailingtests, $allmissinganswers);
98+
bulk_tester::print_summary_after_bulktestall($numpasses, $allfailingtests, $allmissinganswers);
9199
echo $OUTPUT->footer();

bulktestindex.php

+39-11
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313
//
1414
// You should have received a copy of the GNU General Public License
1515
// along with Stack. If not, see <http://www.gnu.org/licenses/>.
16+
namespace qtype_coderunner;
17+
18+
use context_system;
19+
use context;
20+
use html_writer;
21+
use moodle_url;
1622

1723
require_once(__DIR__ . '/../../../config.php');
1824
require_once($CFG->libdir . '/questionlib.php');
@@ -32,7 +38,7 @@
3238
}
3339

3440
// Find in which contexts the user can edit questions.
35-
$questionsbycontext = qtype_coderunner_bulk_tester::get_num_coderunner_questions_by_context();
41+
$questionsbycontext = bulk_tester::get_num_coderunner_questions_by_context();
3642
$availablequestionsbycontext = [];
3743
foreach ($questionsbycontext as $contextid => $numcoderunnerquestions) {
3844
$context = context::instance_by_id($contextid);
@@ -56,7 +62,7 @@
5662
echo <<<HTML
5763
<div class="bulk-test-config" style="margin-bottom: 20px; padding: 10px; background-color: #f5f5f5; border: 1px solid #ddd;">
5864
<h3>Test Configuration</h3>
59-
<div style="margin-bottom: 10px; display: grid; grid-template-columns: auto 80px; gap: 10px; align-items: center; max-width: 240px;">
65+
<div style="margin-bottom: 10px; display: grid; grid-template-columns: auto 80px; gap: 10px; align-items: center; max-width:400px;">
6066
<label for="nruns">Number of runs:</label>
6167
<input type="number" id="nruns" value="{$nruns}" min="1" style="width: 80px;">
6268
@@ -67,6 +73,10 @@
6773
<div>
6874
<input type="checkbox" id="repeatrandomonly" checked>
6975
</div>
76+
<label for="clearcachefirst">Clear course grading cache first (be careful):</label>
77+
<div>
78+
<input type="checkbox" id="clearcachefirst" onchange="confirmCheckboxChange(this)">
79+
</div>
7080
</div>
7181
</div>
7282
HTML;
@@ -77,7 +87,8 @@
7787
} else {
7888
echo get_string('bulktestinfo', 'qtype_coderunner');
7989
echo $OUTPUT->heading(get_string('coderunnercontexts', 'qtype_coderunner'));
80-
90+
$jobehost = get_config('qtype_coderunner', 'jobe_host');
91+
echo html_writer::tag('p', '<b>jobe_host:</b> ' . $jobehost);
8192
echo html_writer::start_tag('ul');
8293
$buttonstyle = 'background-color: #FFFFD0; padding: 2px 2px 0px 2px;border: 4px solid white';
8394
foreach ($availablequestionsbycontext as $name => $info) {
@@ -87,7 +98,8 @@
8798
$testallstr = get_string('bulktestallincontext', 'qtype_coderunner');
8899
$testalltitledetails = ['title' => get_string('testalltitle', 'qtype_coderunner'), 'style' => $buttonstyle];
89100
$testallspan = html_writer::tag(
90-
'span', $testallstr,
101+
'span',
102+
$testallstr,
91103
['class' => 'test-link',
92104
'data-contextid' => $contextid,
93105
'style' => $buttonstyle . ';cursor:pointer;']
@@ -106,14 +118,16 @@
106118
echo html_writer::start_tag('li', ['class' => $class]);
107119
echo $litext;
108120

109-
$categories = qtype_coderunner_bulk_tester::get_categories_for_context($contextid);
121+
$categories = bulk_tester::get_categories_for_context($contextid);
110122
echo html_writer::start_tag('ul', ['class' => 'expandable']);
111123

112124
$titledetails = ['title' => get_string('testallincategory', 'qtype_coderunner')];
113125
foreach ($categories as $cat) {
114126
if ($cat->count > 0) {
115127
$linktext = $cat->name . ' (' . $cat->count . ')';
116-
$span = html_writer::tag('span', $linktext,
128+
$span = html_writer::tag(
129+
'span',
130+
$linktext,
117131
['class' => 'test-link',
118132
'data-contextid' => $contextid,
119133
'data-categoryid' => $cat->id,
@@ -127,7 +141,9 @@
127141
}
128142

129143
echo html_writer::end_tag('ul');
130-
144+
echo html_writer::empty_tag('br');
145+
echo html_writer::tag('hr', '');
146+
echo html_writer::empty_tag('br');
131147
if (has_capability('moodle/site:config', context_system::instance())) {
132148
echo html_writer::tag('p', html_writer::link(
133149
new moodle_url('/question/type/coderunner/bulktestall.php'),
@@ -138,6 +154,17 @@
138154

139155
echo <<<SCRIPT_END
140156
<script>
157+
function confirmCheckboxChange(checkbox) {
158+
if (checkbox.checked) {
159+
var prompt = "Are you sure you want to clear the cache for the selected course?";
160+
prompt = prompt + " This will clear the cache for all attempts on all questions!";
161+
const confirmed = confirm(prompt);
162+
if (!confirmed) {
163+
checkbox.checked = false;
164+
}
165+
}
166+
}
167+
141168
document.addEventListener("DOMContentLoaded", function(event) {
142169
// Handle expandable sections
143170
var expandables = document.getElementsByClassName('expandable');
@@ -169,18 +196,19 @@
169196
var nruns = document.getElementById('nruns').value;
170197
var randomseed = document.getElementById('randomseed').value;
171198
var repeatrandomonly = document.getElementById('repeatrandomonly').checked ? 1 : 0;
199+
var clearcachefirst = document.getElementById('clearcachefirst').checked ? 1 : 0;
172200
173201
// Build URL parameters
174202
var params = new URLSearchParams();
175203
params.append('contextid', link.dataset.contextid);
176-
params.append('randomseed', randomseed);
177-
params.append('repeatrandomonly', repeatrandomonly);
178-
params.append('nruns', nruns);
179-
180204
// Add category ID if present
181205
if (link.dataset.categoryid) {
182206
params.append('categoryid', link.dataset.categoryid);
183207
}
208+
params.append('nruns', nruns);
209+
params.append('randomseed', randomseed);
210+
params.append('repeatrandomonly', repeatrandomonly);
211+
params.append('clearcachefirst', clearcachefirst);
184212
185213
// Construct and navigate to URL
186214
var url = M.cfg.wwwroot + '/question/type/coderunner/bulktest.php?' + params.toString();

classes/bulk_tester.php

+27-6
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,15 @@
2626
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
2727
*/
2828

29-
class qtype_coderunner_bulk_tester {
29+
namespace qtype_coderunner;
30+
31+
use moodle_url;
32+
use html_writer;
33+
use question_bank;
34+
use core_php_time_limit;
35+
use question_state;
36+
37+
class bulk_tester {
3038
/** @var context Context to run bulktester for. */
3139
public $context;
3240

@@ -42,6 +50,9 @@ class qtype_coderunner_bulk_tester {
4250
/** @var int How many runs to do for each question. */
4351
public $nruns;
4452

53+
/** @var int Whether or not to clear the grading cache for this context first Default: 0 . */
54+
public $clearcachefirst;
55+
4556
/** @var int The number of questions that passed tests. */
4657
public $numpasses;
4758

@@ -78,23 +89,26 @@ class qtype_coderunner_bulk_tester {
7889
* @param int $repeatrandomonly when true(or 1), only repeats tests for questions with random in the name.
7990
* Default = true (or really 1).
8091
* @param int $nruns the number times to test each question. Default to 1.
92+
* @param int $clearcachefirst If 1 then clears the grading cache (ignoring ttl) for the given context before running the tests. Default is 0.
8193
*/
8294
public function __construct(
8395
$context = null,
8496
$categoryid = null,
8597
$randomseed = -1,
8698
$repeatrandomonly = 1,
87-
$nruns = 1
99+
$nruns = 1,
100+
$clearcachefirst = 0
88101
) {
89102
if ($context === null) {
90103
$site = get_site(); // Get front page course.
91-
$context = context_course::instance($site->id);
104+
$context = \context_course::instance($site->id);
92105
}
93106
$this->context = $context;
94107
$this->categoryid = $categoryid;
95108
$this->randomseed = $randomseed;
96109
$this->repeatrandomonly = $repeatrandomonly;
97110
$this->nruns = $nruns;
111+
$this->clearcachefirst = $clearcachefirst;
98112
$this->numpasses = 0;
99113
$this->numfails = 0;
100114
$this->failedquestionids = [];
@@ -316,6 +330,13 @@ public function run_all_tests_for_context($questionidstoinclude = []) {
316330
$questiontestsurl = new moodle_url('/question/type/coderunner/questiontestrun.php');
317331
$questiontestsurl->params($qparams);
318332

333+
// Clear grading cache if requested. usettl is set to false here.
334+
if ($this->clearcachefirst) {
335+
$purger = new cache_purger($this->context->id, false);
336+
$purger->purge_cache_for_context();
337+
}
338+
$jobehost = get_config('qtype_coderunner', 'jobe_host');
339+
echo html_writer::tag('p', '<b>jobe_host:</b> ' . $jobehost);
319340
$this->numpasses = 0;
320341
foreach ($categories as $currentcategoryid => $nameandcount) {
321342
$categoryname = $nameandcount->name;
@@ -431,7 +452,7 @@ private function load_and_test_question($questionid) {
431452
$status = self::FAIL;
432453
}
433454
}
434-
} catch (qtype_coderunner_exception $e) {
455+
} catch (exception $e) {
435456
if (isset($question)) {
436457
$questionname = ' ' . format_string($question->name);
437458
} else {
@@ -462,7 +483,7 @@ private function test_question($question) {
462483
if (!empty($params['answer_language'])) {
463484
$response['language'] = $params['answer_language'];
464485
} else if (!empty($question->acelang) && strpos($question->acelang, ',') !== false) {
465-
[$languages, $defaultlang] = qtype_coderunner_util::extract_languages($question->acelang);
486+
[$languages, $defaultlang] = util::extract_languages($question->acelang);
466487
if ($defaultlang === '') {
467488
$defaultlang = $languages[0];
468489
}
@@ -471,7 +492,7 @@ private function test_question($question) {
471492
try {
472493
[$fraction, $state] = $question->grade_response($response, false);
473494
$ok = $state == question_state::$gradedright;
474-
} catch (qtype_coderunner_exception $e) {
495+
} catch (exception $e) {
475496
$ok = false; // If user clicks link to see why, they'll get the same exception.
476497
}
477498
return $ok;

classes/jobesandbox.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,8 @@ public function execute($sourcecode, $language, $input, $files = null, $params =
229229
}
230230
}
231231

232-
232+
// Add jobserver name(s) to runspec so jobs with different jobeservers are treated as different.
233+
$runspec['jobeserver'] = $this->jobeserver;
233234
$cache = cache::make('qtype_coderunner', 'coderunner_grading_cache');
234235
$runresult = null;
235236
if (get_config('qtype_coderunner', 'enablegradecache') && $usecache) {

downloadquizattempts.php

+10-4
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,21 @@
2727
* @copyright 2017 Richard Lobb, The University of Canterbury
2828
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
2929
*/
30+
namespace qtype_coderunner;
31+
32+
use context_system;
33+
use context_course;
34+
use html_writer;
35+
use moodle_url;
36+
37+
require_once(__DIR__ . '/../../../config.php');
38+
require_once($CFG->libdir . '/questionlib.php');
3039

3140
define('NO_OUTPUT_BUFFERING', true);
3241
if (!defined('ANONYMISE')) {
3342
define('ANONYMISE', 0);
3443
}
3544

36-
require_once(__DIR__ . '/../../../config.php');
37-
require_once($CFG->libdir . '/questionlib.php');
38-
3945
// Login and check permissions.
4046
$context = context_system::instance();
4147
require_login();
@@ -47,7 +53,7 @@
4753
$PAGE->requires->jquery_plugin('ui');
4854
$PAGE->requires->jquery_plugin('ui-css');
4955

50-
$courses = qtype_coderunner_bulk_tester::get_all_courses();
56+
$courses = bulk_tester::get_all_courses();
5157

5258
// Start display.
5359
echo $OUTPUT->header();

findduplicates.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
* @copyright 2018 and beyond Richard Lobb, The University of Canterbury
2626
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
2727
*/
28+
namespace qtype_coderunner;
29+
30+
use context;
2831

2932
define('NO_OUTPUT_BUFFERING', true);
3033

@@ -57,7 +60,7 @@
5760
echo "<table class='table table-bordered table-striped'>\n";
5861
echo "<tr><th>Q1 name</th><th>Q1 Category</th><th>Q2 name</th><th>Q2 category</th></tr>\n";
5962
// Find all the duplicates.
60-
$allquestionsmap = qtype_coderunner_bulk_tester::get_all_coderunner_questions_in_context($contextid);
63+
$allquestionsmap = bulk_tester::get_all_coderunner_questions_in_context($contextid);
6164
$allquestions = array_values($allquestionsmap);
6265
$numduplicates = 0;
6366
for ($i = 0; $i < count($allquestions); $i++) {

0 commit comments

Comments
 (0)