Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-72743

Make question restore more fault tolerant of missing user data in course backups

XMLWordPrintable

    • MOODLE_310_STABLE, MOODLE_311_STABLE, MOODLE_400_STABLE
    • MOODLE_310_STABLE, MOODLE_311_STABLE
    • Hide

      Setup

      Tail your webserver logs prior to manual test (using whatever method is most appropriate), e.g. for a Docker container:

      $ docker logs docker_webserver_1 -f
      

      Or for apache error logs:

      $ tail -f /var/log/apache/error_log (or similar)
      

      Test

      1. Login as admin
      2. Navigate to Courses > Restore course in site administration
      3. Upload  question_attempts_missing_users.mbz and press Restore
      4. Press Continue
      5. Select a category under Restore as new course, press Continue
      6. Press Next
      7. Press Next again
      8. Press Perform restore
      9. Confirm restore completes successfully without exceptions
      10. Confirm you see the following in your webserver logs:

        Mapped user ID not found for user 4, quiz 1, attempt 1. Skipping quiz attempt, referer: http://localhost:8000/backup/restore.php
        Mapped user ID not found for user 5, quiz 1, attempt 1. Skipping quiz attempt, referer: http://localhost:8000/backup/restore.php
        

      11. Press Continue
      12. In restored course, open Quiz 01
      13. Press Attempts: 2
      14. Confirm question attempts were restored:
        • User 01 has a red cross & 0.00 for Q.1
        • User 04 has a green cross & 10.00 for Q.1

      Automated test

      $ vendor/bin/phpunit mod/quiz/tests/restore_attempt_test.php
      

      Show
      Setup Tail your webserver logs prior to manual test (using whatever method is most appropriate), e.g. for a Docker container: $ docker logs docker_webserver_1 -f Or for apache error logs: $ tail -f /var/log/apache/error_log (or similar) Test Login as admin Navigate to Courses > Restore course in site administration Upload  question_attempts_missing_users.mbz and press Restore Press Continue Select a category under Restore as new course , press Continue Press Next Press Next again Press Perform restore Confirm restore completes successfully without exceptions Confirm you see the following in your webserver logs: Mapped user ID not found for user 4, quiz 1, attempt 1. Skipping quiz attempt, referer: http://localhost:8000/backup/restore.php Mapped user ID not found for user 5, quiz 1, attempt 1. Skipping quiz attempt, referer: http://localhost:8000/backup/restore.php Press Continue In restored course, open Quiz 01 Press Attempts: 2 Confirm question attempts were restored: User 01 has a red cross & 0.00 for Q.1 User 04 has a green cross & 10.00 for Q.1 Automated test $ vendor/bin/phpunit mod/quiz/tests/restore_attempt_test.php

      While working with a partner on a backup/restore issue, and after consulting with stronk7, we might try to make the question attempt restoration process a little more forgiving when restoring question attempts that appear to lack matching users:

      [Tue Oct 05 11:58:44.273132 2021] [php7:notice] [pid 20] [client 172.19.0.1:47948] Default exception handler: Error writing to database Debug: Duplicate entry '1-0-1' for key 'm_quizatte_quiuseatt_uix'
      INSERT INTO m_quiz_attempts (userid,uniqueid,layout,currentpage,preview,state,timestart,timefinish,timemodified,timemodifiedoffline,timecheckstate,sumgrades,quiz,attempt) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)
      [array (
        0 => 0,
        1 => 8,
        2 => '1,0,2,0,3,0,4,0,5,0,6,0,7,0,8,0,9,0,10,0,11,0,12,0,13,0',
        3 => '12',
        4 => '0',
        5 => 'finished',
        6 => '1519300587',
        7 => '1519300989',
        8 => '1519300989',
        9 => '0',
        10 => 0,
        11 => '12.33333',
        12 => 1,
        13 => '1',
      )]
      Error code: dmlwriteexception
      * line 489 of /lib/dml/moodle_database.php: dml_write_exception thrown
      * line 1357 of /lib/dml/mysqli_native_moodle_database.php: call to moodle_database->query_end()
      * line 1403 of /lib/dml/mysqli_native_moodle_database.php: call to mysqli_native_moodle_database->insert_record_raw()
      * line 495 of /mod/quiz/backup/moodle2/restore_quiz_stepslib.php: call to mysqli_native_moodle_database->insert_record()
      * line 5649 of /backup/moodle2/restore_stepslib.php: call to restore_quiz_activity_structure_step->inform_new_usage_id()
      * line 5611 of /backup/moodle2/restore_stepslib.php: call to restore_questions_activity_structure_step->restore_question_usage_worker()
      * line 137 of /backup/util/plan/restore_structure_step.class.php: call to restore_questions_activity_structure_step->process_question_usage()
      * line 121 of /backup/util/helper/restore_structure_parser_processor.class.php: call to restore_structure_step->process()
      * line 178 of /backup/util/xml/parser/processors/grouped_parser_processor.class.php: call to restore_structure_parser_processor->dispatch_chunk()
      * line 109 of /backup/util/helper/restore_structure_parser_processor.class.php: call to grouped_parser_processor->postprocess_chunk()
      * line 148 of /backup/util/xml/parser/processors/simplified_parser_processor.class.php: call to restore_structure_parser_processor->postprocess_chunk()
      * line 92 of /backup/util/xml/parser/processors/progressive_parser_processor.class.php: call to simplified_parser_processor->process_chunk()
      * line 190 of /backup/util/xml/parser/progressive_parser.class.php: call to progressive_parser_processor->receive_chunk()
      * line 237 of /backup/util/xml/parser/progressive_parser.class.php: call to progressive_parser->publish()
      * line ? of unknownfile: call to progressive_parser->start_tag()
      * line 179 of /backup/util/xml/parser/progressive_parser.class.php: call to xml_parse()
      * line 158 of /backup/util/xml/parser/progressive_parser.class.php: call to progressive_parser->parse()
      * line 110 of /backup/util/plan/restore_structure_step.class.php: call to progressive_parser->process()
      * line 181 of /backup/util/plan/base_task.class.php: call to restore_structure_step->execute()
      * line 219 of /backup/moodle2/restore_activity_task.class.php: call to base_task->execute()
      * line 191 of /backup/util/plan/base_plan.class.php: call to restore_activity_task->execute()
      * line 168 of /backup/util/plan/restore_plan.class.php: call to base_plan->execute()
      * line 394 of /backup/controller/restore_controller.class.php: call to restore_plan->execute()
      * line 219 of /backup/util/ui/restore_ui.class.php: call to restore_controller->execute_plan()
      * line 143 of /backup/restore.php: call to restore_ui->execute()
      , referer: http://localhost:8000/backup/restore.php
      

      This appears to be attempting to insert an attempt for user with ID=0, and when it tries to do that a second time, it hits the unique index constraint on the table

        1. coverage.png
          coverage.png
          121 kB
        2. MDL-72743_master_Step 10.png
          MDL-72743_master_Step 10.png
          96 kB
        3. MDL-72743_master_Step 14.png
          MDL-72743_master_Step 14.png
          138 kB
        4. MDL-72743_master_Step 9.png
          MDL-72743_master_Step 9.png
          89 kB
        5. MDL-72743_v310_Step 10.png
          MDL-72743_v310_Step 10.png
          88 kB
        6. MDL-72743_v310_Step 14.png
          MDL-72743_v310_Step 14.png
          117 kB
        7. MDL-72743_v310_Step 9.png
          MDL-72743_v310_Step 9.png
          76 kB
        8. MDL-72743_v311_Step 10.png
          MDL-72743_v311_Step 10.png
          129 kB
        9. MDL-72743_v311_Step 14.png
          MDL-72743_v311_Step 14.png
          126 kB
        10. MDL-72743_v311_Step 9.png
          MDL-72743_v311_Step 9.png
          76 kB
        11. question_attempts_missing_users.mbz
          12 kB
        12. Screenshot_2021-10-05 Docker Restore.png
          Screenshot_2021-10-05 Docker Restore.png
          70 kB

            pholden Paul Holden
            pholden Paul Holden
            Tim Hunt Tim Hunt
            Eloy Lafuente (stronk7) Eloy Lafuente (stronk7)
            Angelia Dela Cruz Angelia Dela Cruz
            Votes:
            2 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved:

                Estimated:
                Original Estimate - 0 minutes
                0m
                Remaining:
                Remaining Estimate - 0 minutes
                0m
                Logged:
                Time Spent - 1 day, 35 minutes
                1d 35m

                  Error rendering 'clockify-timesheets-time-tracking-reports:timer-sidebar'. Please contact your Jira administrators.