Skip to content

Commit ff4a8d3

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 ff4a8d3

11 files changed

+128
-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-5
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,16 @@
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+
use qtype_coderunner_util;
37+
38+
class bulk_tester {
3039
/** @var context Context to run bulktester for. */
3140
public $context;
3241

@@ -42,6 +51,9 @@ class qtype_coderunner_bulk_tester {
4251
/** @var int How many runs to do for each question. */
4352
public $nruns;
4453

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

@@ -78,23 +90,26 @@ class qtype_coderunner_bulk_tester {
7890
* @param int $repeatrandomonly when true(or 1), only repeats tests for questions with random in the name.
7991
* Default = true (or really 1).
8092
* @param int $nruns the number times to test each question. Default to 1.
93+
* @param int $clearcachefirst If 1 then clears the grading cache (ignoring ttl) for the given context before running the tests. Default is 0.
8194
*/
8295
public function __construct(
8396
$context = null,
8497
$categoryid = null,
8598
$randomseed = -1,
8699
$repeatrandomonly = 1,
87-
$nruns = 1
100+
$nruns = 1,
101+
$clearcachefirst = 0
88102
) {
89103
if ($context === null) {
90104
$site = get_site(); // Get front page course.
91-
$context = context_course::instance($site->id);
105+
$context = \context_course::instance($site->id);
92106
}
93107
$this->context = $context;
94108
$this->categoryid = $categoryid;
95109
$this->randomseed = $randomseed;
96110
$this->repeatrandomonly = $repeatrandomonly;
97111
$this->nruns = $nruns;
112+
$this->clearcachefirst = $clearcachefirst;
98113
$this->numpasses = 0;
99114
$this->numfails = 0;
100115
$this->failedquestionids = [];
@@ -316,6 +331,13 @@ public function run_all_tests_for_context($questionidstoinclude = []) {
316331
$questiontestsurl = new moodle_url('/question/type/coderunner/questiontestrun.php');
317332
$questiontestsurl->params($qparams);
318333

334+
// Clear grading cache if requested. usettl is set to false here.
335+
if ($this->clearcachefirst) {
336+
$purger = new cache_purger($this->context->id, false);
337+
$purger->purge_cache_for_context();
338+
}
339+
$jobehost = get_config('qtype_coderunner', 'jobe_host');
340+
echo html_writer::tag('p', '<b>jobe_host:</b> ' . $jobehost);
319341
$this->numpasses = 0;
320342
foreach ($categories as $currentcategoryid => $nameandcount) {
321343
$categoryname = $nameandcount->name;
@@ -431,7 +453,7 @@ private function load_and_test_question($questionid) {
431453
$status = self::FAIL;
432454
}
433455
}
434-
} catch (qtype_coderunner_exception $e) {
456+
} catch (exception $e) {
435457
if (isset($question)) {
436458
$questionname = ' ' . format_string($question->name);
437459
} else {
@@ -471,7 +493,7 @@ private function test_question($question) {
471493
try {
472494
[$fraction, $state] = $question->grade_response($response, false);
473495
$ok = $state == question_state::$gradedright;
474-
} catch (qtype_coderunner_exception $e) {
496+
} catch (exception $e) {
475497
$ok = false; // If user clicks link to see why, they'll get the same exception.
476498
}
477499
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++) {

findduplicatesindex.php

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

27+
namespace qtype_coderunner;
28+
29+
use context;
30+
use context_system;
31+
use html_writer;
32+
use moodle_url;
33+
2734
require_once(__DIR__ . '/../../../config.php');
2835
require_once($CFG->libdir . '/questionlib.php');
2936

@@ -40,7 +47,7 @@
4047
echo $OUTPUT->heading('Courses containing CodeRunner questions');
4148

4249
// Find in which contexts the user can edit questions.
43-
$questionsbycontext = qtype_coderunner_bulk_tester::get_num_coderunner_questions_by_context();
50+
$questionsbycontext = bulk_tester::get_num_coderunner_questions_by_context();
4451
$availablequestionsbycontext = [];
4552
foreach ($questionsbycontext as $contextid => $numcoderunnerquestions) {
4653
$context = context::instance_by_id($contextid);

0 commit comments

Comments
 (0)