Skip to content

Commit b6ce69e

Browse files
committed
Merge branch 'development' of github.com:trampgeek/moodle-qtype_coderunner into development
2 parents 2a29fa4 + 157bca2 commit b6ce69e

10 files changed

+76
-61
lines changed

bulktest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
// Get the parameters from the URL.
3434
$contextid = required_param('contextid', PARAM_INT); // Set to 0 if providing a list of question IDs to check.
3535
$categoryid = optional_param('categoryid', null, PARAM_INT);
36-
$randomseed = optional_param('randomseed', 0, PARAM_INT);
36+
$randomseed = optional_param('randomseed', -1, PARAM_INT);
3737
$repeatrandomonly = optional_param('repeatrandomonly', 1, PARAM_INT);
3838
$nruns = optional_param('nruns', 1, PARAM_INT);
3939
$questionids = optional_param('questionids', '', PARAM_RAW); // A list of specific questions to check, eg, for rechecking failed tests.

bulktestall.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@
4545
$title = get_string('bulktesttitle', 'qtype_coderunner', $context->get_context_name());
4646
$PAGE->set_title($title);
4747

48-
// Create the helper class.
49-
$bulktester = new qtype_coderunner_bulk_tester();
48+
5049
$numpasses = 0;
5150
$allfailingtests = [];
5251
$allmissinganswers = [];
@@ -60,14 +59,16 @@
6059
echo $OUTPUT->heading($title, 1);
6160

6261
// Run the tests.
63-
foreach ($bulktester->get_num_coderunner_questions_by_context() as $contextid => $numcoderunnerquestions) {
62+
$contextdata = qtype_coderunner_bulk_tester::get_num_coderunner_questions_by_context();
63+
foreach ($contextdata as $contextid => $numcoderunnerquestions) {
6464
if ($skipping && $contextid != $startfromcontextid) {
6565
continue;
6666
}
6767
$skipping = false;
68-
6968
$testcontext = context::instance_by_id($contextid);
7069
if (has_capability('moodle/question:editall', $context)) {
70+
$PAGE->set_context($testcontext); // Helps grading cache pickup right course id.
71+
$bulktester = new qtype_coderunner_bulk_tester($testcontext);
7172
echo $OUTPUT->heading(get_string('bulktesttitle', 'qtype_coderunner', $testcontext->get_context_name()));
7273
echo html_writer::tag('p', html_writer::link(
7374
new moodle_url(
@@ -77,13 +78,13 @@
7778
get_string('bulktestcontinuefromhere', 'qtype_coderunner')
7879
));
7980

80-
[$passes, $failingtests, $missinganswers] = $bulktester->run_all_tests_for_context($testcontext);
81+
[$passes, $failingtests, $missinganswers] = $bulktester->run_all_tests_for_context();
8182
$numpasses += $passes;
8283
$allfailingtests = array_merge($allfailingtests, $failingtests);
8384
$allmissinganswers = array_merge($allmissinganswers, $missinganswers);
8485
}
8586
}
8687

8788
// Display the final summary.
88-
$bulktester->print_overall_result($numpasses, $allfailingtests, $allmissinganswers);
89+
qtype_coderunner_bulk_tester::print_summary_after_bulktestall($numpasses, $allfailingtests, $allmissinganswers);
8990
echo $OUTPUT->footer();

bulktestindex.php

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@
5959
<div style="margin-bottom: 10px; display: grid; grid-template-columns: auto 80px; gap: 10px; align-items: center; max-width: 240px;">
6060
<label for="nruns">Number of runs:</label>
6161
<input type="number" id="nruns" value="{$nruns}" min="1" style="width: 80px;">
62-
62+
6363
<label for="randomseed">Random seed:</label>
64-
<input type="number" id="randomseed" value="0" min="0" style="width: 80px;">
65-
64+
<input type="number" id="randomseed" value="" min="0" style="width: 80px;">
65+
6666
<label for="repeatrandomonly">Repeat random only:</label>
6767
<div>
6868
<input type="checkbox" id="repeatrandomonly" checked>
@@ -86,25 +86,23 @@
8686

8787
$testallstr = get_string('bulktestallincontext', 'qtype_coderunner');
8888
$testalltitledetails = ['title' => get_string('testalltitle', 'qtype_coderunner'), 'style' => $buttonstyle];
89-
$testallspan = html_writer::tag('span', $testallstr,
90-
['class' => 'test-link',
89+
$testallspan = html_writer::tag(
90+
'span', $testallstr,
91+
['class' => 'test-link',
9192
'data-contextid' => $contextid,
92-
'style' => $buttonstyle . ';cursor:pointer;']);
93-
93+
'style' => $buttonstyle . ';cursor:pointer;']
94+
);
9495
$expandlink = html_writer::link(
9596
'#expand',
9697
get_string('expand', 'qtype_coderunner'),
9798
['class' => 'expander', 'title' => get_string('expandtitle', 'qtype_coderunner'), 'style' => $buttonstyle]
9899
);
99-
100100
$litext = $name . ' (' . $numcoderunnerquestions . ') ' . $testallspan . ' ' . $expandlink;
101-
102101
if (strpos($name, ": Quiz: ") === false) {
103102
$class = 'bulktest coderunner context normal';
104103
} else {
105104
$class = 'bulktest coderunner context quiz';
106105
}
107-
108106
echo html_writer::start_tag('li', ['class' => $class]);
109107
echo $litext;
110108

@@ -115,11 +113,12 @@
115113
foreach ($categories as $cat) {
116114
if ($cat->count > 0) {
117115
$linktext = $cat->name . ' (' . $cat->count . ')';
118-
$span = html_writer::tag('span', $linktext,
116+
$span = html_writer::tag('span', $linktext,
119117
['class' => 'test-link',
120118
'data-contextid' => $contextid,
121119
'data-categoryid' => $cat->id,
122-
'style' => $buttonstyle . ';cursor:pointer;']);
120+
'style' => $buttonstyle . ';cursor:pointer;']
121+
);
123122
echo html_writer::tag('li', $span, $titledetails);
124123
}
125124
}
@@ -145,7 +144,7 @@
145144
Array.from(expandables).forEach(function (expandable) {
146145
expandable.style.display = 'none';
147146
});
148-
147+
149148
var expanders = document.getElementsByClassName('expander');
150149
Array.from(expanders).forEach(function(expander) {
151150
expander.addEventListener('click', function(event) {
@@ -165,24 +164,24 @@
165164
Array.from(testLinks).forEach(function(link) {
166165
link.addEventListener('click', function(event) {
167166
event.preventDefault();
168-
167+
169168
// Get configuration values
170169
var nruns = document.getElementById('nruns').value;
171170
var randomseed = document.getElementById('randomseed').value;
172171
var repeatrandomonly = document.getElementById('repeatrandomonly').checked ? 1 : 0;
173-
172+
174173
// Build URL parameters
175174
var params = new URLSearchParams();
176175
params.append('contextid', link.dataset.contextid);
177176
params.append('randomseed', randomseed);
178177
params.append('repeatrandomonly', repeatrandomonly);
179178
params.append('nruns', nruns);
180-
179+
181180
// Add category ID if present
182181
if (link.dataset.categoryid) {
183182
params.append('categoryid', link.dataset.categoryid);
184183
}
185-
184+
186185
// Construct and navigate to URL
187186
var url = M.cfg.wwwroot + '/question/type/coderunner/bulktest.php?' + params.toString();
188187
window.location.href = url;

classes/bulk_tester.php

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class qtype_coderunner_bulk_tester {
7171
/**
7272
* @param context $context the context to run the tests for.
7373
* @param int $categoryid test only questions in this category. Default to all.
74-
* @param int $randomseed used to set random seed before runs for each question. Default = 0 --- meaning seed is not set.
74+
* @param int $randomseed used to set random seed before runs for each question. Default = -1 --- meaning seed is not set.
7575
* Use this to have more chance of the series of questions being generated for testing is the same for a new run
7676
* of the tests. This works well with grader caching as you won't keep getting new random variations.
7777
* Also allows you to mix up the space that is being tested.
@@ -80,12 +80,16 @@ class qtype_coderunner_bulk_tester {
8080
* @param int $nruns the number times to test each question. Default to 1.
8181
*/
8282
public function __construct(
83-
$context,
83+
$context = null,
8484
$categoryid = null,
85-
$randomseed = 0,
85+
$randomseed = -1,
8686
$repeatrandomonly = 1,
8787
$nruns = 1
8888
) {
89+
if ($context === null) {
90+
$site = get_site(); // Get front page course.
91+
$context = context_course::instance($site->id);
92+
}
8993
$this->context = $context;
9094
$this->categoryid = $categoryid;
9195
$this->randomseed = $randomseed;
@@ -309,7 +313,7 @@ public function run_all_tests_for_context($questionidstoinclude = []) {
309313
} else {
310314
$qparams['courseid'] = SITEID;
311315
}
312-
$questiontestsurl = new moodle_url('/question/type/coderunner/questiontestrun.php');
316+
$questiontestsurl = new moodle_url('/question/type/coderunner/questiontestrun.php');
313317
$questiontestsurl->params($qparams);
314318

315319
$this->numpasses = 0;
@@ -345,12 +349,9 @@ public function run_all_tests_for_context($questionidstoinclude = []) {
345349
} else {
346350
$nrunsthistime = $this->nruns;
347351
}
348-
if ($this->randomseed > 0) {
352+
if ($this->randomseed >= 0) {
349353
mt_srand($this->randomseed);
350354
}
351-
if ($question->id == 6273) {
352-
echo $question->id;
353-
}
354355
// Now run the test for the required number of times.
355356
for ($i = 0; $i < $nrunsthistime; $i++) {
356357
// Only records last outcome and message.
@@ -403,7 +404,7 @@ public function run_all_tests_for_context($questionidstoinclude = []) {
403404
}
404405
echo "</ul>\n";
405406
}
406-
return;
407+
return [$this->numpasses, $this->failedtestdetails, $this->missinganswerdetails];
407408
}
408409

409410

@@ -496,8 +497,6 @@ public function print_overall_result() {
496497
}
497498
echo html_writer::end_tag('ul');
498499
}
499-
500-
501500
if (count($this->failedtestdetails) > 0) {
502501
echo $OUTPUT->heading(get_string('coderunner_install_testsuite_failures', 'qtype_coderunner'), 5);
503502
echo html_writer::start_tag('ul');
@@ -531,6 +530,36 @@ public function print_overall_result() {
531530
echo html_writer::tag('p', $link);
532531
}
533532

533+
/**
534+
* Print an overall summary of the failed tests.
535+
*/
536+
public static function print_summary_after_bulktestall($numpasses, $allfailingtests, $allmissinganswers) {
537+
global $OUTPUT;
538+
echo $OUTPUT->heading(get_string('bulktestoverallresults', 'qtype_coderunner'), 5);
539+
$spacer = '&nbsp;&nbsp;|&nbsp;&nbsp;';
540+
$passstr = $numpasses . ' ' . get_string('passes', 'qtype_coderunner') . $spacer;
541+
$failstr = count($allfailingtests) . ' ' . get_string('fails', 'qtype_coderunner') . $spacer;
542+
$missingstr = count($allmissinganswers) . ' ' . get_string('missinganswers', 'qtype_coderunner');
543+
echo html_writer::tag('p', $passstr . $failstr . $missingstr);
544+
545+
if (count($allmissinganswers) > 0) {
546+
echo $OUTPUT->heading(get_string('coderunner_install_testsuite_noanswer', 'qtype_coderunner'), 5);
547+
echo html_writer::start_tag('ul');
548+
foreach ($allmissinganswers as $message) {
549+
echo html_writer::tag('li', $message);
550+
}
551+
echo html_writer::end_tag('ul');
552+
}
553+
if (count($allfailingtests) > 0) {
554+
echo $OUTPUT->heading(get_string('coderunner_install_testsuite_failures', 'qtype_coderunner'), 5);
555+
echo html_writer::start_tag('ul');
556+
foreach ($allfailingtests as $message) {
557+
echo html_writer::tag('li', $message);
558+
}
559+
echo html_writer::end_tag('ul');
560+
}
561+
}
562+
534563

535564
/**
536565
* Display the results of scanning all the CodeRunner questions to

classes/jobesandbox.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ public function execute($sourcecode, $language, $input, $files = null, $params =
162162
try {
163163
// Had to use try here as isset($PAGE->context) always seems to fail even if the context has been set.
164164
$context = $PAGE->context;
165-
$courseid = $context->get_course_context(strict: true)->instanceid;
165+
$courseid = $context->get_course_context(true)->instanceid; // raises exception if context is unknown.
166166
} catch (Exception $e) {
167167
$courseid = 1; // Use context of 1 as no $PAGE context is set, eg, could be a websocket UI run.
168168
}

downloadquizattempts.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@
4747
$PAGE->requires->jquery_plugin('ui');
4848
$PAGE->requires->jquery_plugin('ui-css');
4949

50-
// Create the helper class.
51-
$bulktester = new qtype_coderunner_bulk_tester();
52-
$courses = $bulktester->get_all_courses();
50+
$courses = qtype_coderunner_bulk_tester::get_all_courses();
5351

5452
// Start display.
5553
echo $OUTPUT->header();

findduplicates.php

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,14 @@
5050
$PAGE->set_cm($cm, $DB->get_record('course', ['id' => $cm->course], '*', MUST_EXIST));
5151
}
5252

53-
// Create the helper class.
54-
$bulktester = new qtype_coderunner_bulk_tester();
55-
56-
// Release the session, so the user can do other things while this runs.
57-
\core\session\manager::write_close();
58-
5953
// Display.
6054
echo $OUTPUT->header();
6155
echo $OUTPUT->heading($title);
6256

6357
echo "<table class='table table-bordered table-striped'>\n";
6458
echo "<tr><th>Q1 name</th><th>Q1 Category</th><th>Q2 name</th><th>Q2 category</th></tr>\n";
6559
// Find all the duplicates.
66-
$allquestionsmap = $bulktester->get_all_coderunner_questions_in_context($contextid);
60+
$allquestionsmap = qtype_coderunner_bulk_tester::get_all_coderunner_questions_in_context($contextid);
6761
$allquestions = array_values($allquestionsmap);
6862
$numduplicates = 0;
6963
for ($i = 0; $i < count($allquestions); $i++) {

findduplicatesindex.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,12 @@
3535
$PAGE->set_context($context);
3636
$PAGE->set_title('Find duplicate questions');
3737

38-
// Create the helper class.
39-
$bulktester = new qtype_coderunner_bulk_tester();
40-
4138
// Display.
4239
echo $OUTPUT->header();
4340
echo $OUTPUT->heading('Courses containing CodeRunner questions');
4441

4542
// Find in which contexts the user can edit questions.
46-
$questionsbycontext = $bulktester->get_num_coderunner_questions_by_context();
43+
$questionsbycontext = qtype_coderunner_bulk_tester::get_num_coderunner_questions_by_context();
4744
$availablequestionsbycontext = [];
4845
foreach ($questionsbycontext as $contextid => $numcoderunnerquestions) {
4946
$context = context::instance_by_id($contextid);

lang/en/qtype_coderunner.php

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,18 +1374,17 @@ function should be applied, e.g. <code>{{STUDENT_ANSWER | e(\'py\')}}</code> is
13741374

13751375
$string['purgeoldcachekeysbutton'] = 'Purge only OLD keys';
13761376
$string['purgeallcachekeysbutton'] = 'Purge ALL keys';
1377-
$string['bulktestinfo'] = 'By default clicking on test links will test with <b>...&randomseed=0&repeatrandomonly=1&nruns=1</b>. Feel free to change the url as you see fit.<br>
1378-
By default each question with \'random\' in the name will be tested <i>nruns</i> times
1379-
unless <i>repeatrandomonly</i> is 0, in which case all questions are tested that many times.<br>A randomseed of 0 means the seed is not set.
1380-
Setting it to another value (eg, 1) will mean that the php randomseed is set before doing the test(s) for each question with random in its name.<br>
1381-
If you don\'t set the random seed then each time you do a bulk test you will get random sequences of question instances, which may mean the grade
1382-
cache isn\'t so useful and more questions have to actually be run on the Jobe server (depending on how random your questions are).<br>
1377+
$string['bulktestinfo'] = '<ul>
1378+
<li><b>Number of runs:</b> How many times each included question will be tested.</li>
1379+
<li><b>Repeat random only:</b> Limits repeated runs to questions with <emph>random</emph> in their names.</li>
1380+
<li><b>randomseed:</b> If set to a postive integer then the PHP randomseed is set to this value before running the test(s) for each question that has <emph>random</emph> in its name.<br>
1381+
If you don\'t set the random seed then each time you do a bulk test you will get random sequences of question instances, which may mean the grade cache isn\'t so useful and more questions have to actually be run on the Jobe server (depending on how random your questions are).<br>
13831382
For a given seed the sequence of random question instances should be the same (assuming your question template uses the random seed it is given correctly).
13841383
Setting the random seed allows you to recreate a specific sequences of random question instances (eg, you could do 100 runs with 1 being
1385-
the initial seed, then try 100 runs with 200 being the seed, etc, hopefully getting more coverage).';
1384+
the initial seed, then try 100 runs with 200 being the seed, etc, hopefully getting more coverage).</li>';
13861385
$string['cachepurgeindextitle'] = 'Coderunner Cache Purge Index';
13871386
$string['cachepurgepagetitle'] = 'Purging cache for {$a}';
1388-
$string['cachepurgeindexinfo'] = 'Purging OLD keys will only delete cache entries for grading runs that are older than the Coderunner cache Time To Live (TTL) as set in the admin settings. Pruging ALL will delete all cache entries for the given course.';
1387+
$string['cachepurgeindexinfo'] = 'Purging OLD keys will only delete cache entries for grading runs that are older than the Coderunner cache Time To Live (TTL) as set in the admin settings. Purging ALL will delete all cache entries for the given course.';
13891388
$string['currentttlinfo'] = 'Coderunner grading cache Time to Live is currently set to TTL = {$a->seconds} seconds (={$a->days} days)';
13901389
$string['unauthorisedcachepurging'] = 'You do not have suitable access to any CodeRunner questions!';
13911390
$string['contextidnotacourse'] = 'Nothing to do as context_id $contextid is not a course.';

prototypeusageindex.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,7 @@
3737
$PAGE->set_context($context);
3838
$PAGE->set_title(get_string('prototypeusageindex', 'qtype_coderunner'));
3939

40-
// Create the helper class.
41-
$bulktester = new qtype_coderunner_bulk_tester();
42-
$allcourses = $bulktester->get_all_courses();
40+
$allcourses = qtype_coderunner_bulk_tester::get_all_courses();
4341

4442
// Start display.
4543
echo $OUTPUT->header();

0 commit comments

Comments
 (0)