Skip to content

Commit

Permalink
MDL-66273 qtype_random: Fix question deletion during course restore
Browse files Browse the repository at this point in the history
  • Loading branch information
golenkovm committed Sep 12, 2022
1 parent 54b614c commit 8684cd6
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
17 changes: 17 additions & 0 deletions question/type/random/classes/task/remove_unused_questions.php
Expand Up @@ -25,6 +25,8 @@

namespace qtype_random\task;

use core\task\manager;

defined('MOODLE_INTERNAL') || die();


Expand All @@ -44,6 +46,21 @@ public function execute() {
global $DB, $CFG;
require_once($CFG->libdir . '/questionlib.php');

// Confirm, that there is no restore in progress to make sure we do not
// clean up questions that have their quiz slots not restored yet.
$restoretasks = [
'\core\task\asynchronous_copy_task',
'\core\task\asynchronous_restore_task',
];

$running = manager::get_running_tasks();
foreach ($running as $task) {
if (in_array($task->classname, $restoretasks)) {
mtrace('Detected running async restore. Aborting the task.');
return;
}
}

// Find potentially unused random questions (up to 10000).
// Note, because we call question_delete_question below,
// the question will not actually be deleted if something else
Expand Down
33 changes: 33 additions & 0 deletions question/type/random/tests/cleanup_task_test.php
Expand Up @@ -67,4 +67,37 @@ public function test_cleanup_task_removes_unused_question() {
$this->assertTrue($DB->record_exists('question', ['id' => $quizslots[1]->questionid]));
$this->assertFalse($DB->record_exists('question', ['id' => $quizslots[2]->questionid]));
}

/**
* Test that remove_unused_questions aborts when there is a course restore in progress.
*/
public function test_cleanup_task_checks_for_active_restores() {
$this->resetAfterTest();

// Get ready the tasks.
$cleanuptask = new \qtype_random\task\remove_unused_questions();
$restoretask = new \core\task\asynchronous_restore_task();
\core\task\manager::queue_adhoc_task($restoretask);
$copytask = new \core\task\asynchronous_copy_task();
\core\task\manager::queue_adhoc_task($copytask);

// Start the first adhoc task. This might be either restore or copy adhoc task.
$task1 = \core\task\manager::get_next_adhoc_task(time());
\core\task\manager::adhoc_task_starting($task1);
$cleanuptask->execute();

// Complete the first task and start the second one.
\core\task\manager::adhoc_task_complete($task1);
$task2 = \core\task\manager::get_next_adhoc_task(time());
\core\task\manager::adhoc_task_starting($task2);
$cleanuptask->execute();

// Complete the second adhoc task.
\core\task\manager::adhoc_task_complete($task2);
$cleanuptask->execute();

$aborted = 'Detected running async restore. Aborting the task.';
$completed = 'Cleaned up 0 unused random questions.';
$this->expectOutputRegex("/.*$aborted.*\s.*$aborted.*\s.*$completed.*/");
}
}

0 comments on commit 8684cd6

Please sign in to comment.