33"""
44import json
55import uuid
6+ from datetime import timedelta
67from unittest .mock import patch
78
89from django .contrib .auth import get_user_model
910from django .core .files .base import ContentFile
1011from django .db import DatabaseError
1112from django .test import override_settings
1213from django .urls import reverse
14+ from django .utils import timezone
1315from rest_framework import status
1416from rest_framework .permissions import AllowAny , IsAuthenticated
1517from rest_framework .test import APITestCase
@@ -35,7 +37,7 @@ def setUp(self):
3537 password = 'testpass'
3638 )
3739 self .submission = SubmissionFactory ()
38- self .queue_record = ExternalGraderDetailFactory (
40+ self .external_grader_detail = ExternalGraderDetailFactory (
3941 submission = self .submission ,
4042 pullkey = 'test_pull_key' ,
4143 status = 'pending' ,
@@ -145,7 +147,7 @@ def test_get_submission_invalid_transition(self, mock_update_status):
145147 self .assertEqual (response .status_code , status .HTTP_200_OK )
146148
147149 new_submission = SubmissionFactory ()
148- queue_record = ExternalGraderDetailFactory (
150+ external_grader_detail = ExternalGraderDetailFactory (
149151 submission = new_submission ,
150152 queue_name = queue_name ,
151153 status = 'pending'
@@ -160,8 +162,8 @@ def test_get_submission_invalid_transition(self, mock_update_status):
160162 self .viewset .compose_reply (False , "Error processing submission: Invalid transition" )
161163 )
162164
163- queue_record .refresh_from_db ()
164- self .assertEqual (queue_record .status , 'pending' )
165+ external_grader_detail .refresh_from_db ()
166+ self .assertEqual (external_grader_detail .status , 'pending' )
165167
166168 def test_put_result_invalid_submission_id (self ):
167169 """Test put_result with non-existent submission ID."""
@@ -253,9 +255,9 @@ def test_put_result_set_score_failure(self):
253255
254256 self .assertEqual (response .status_code , status .HTTP_200_OK )
255257
256- self .queue_record .refresh_from_db ()
257- self .assertEqual (self .queue_record .num_failures , 1 )
258- self .assertEqual (self .queue_record .status , 'pending' )
258+ self .external_grader_detail .refresh_from_db ()
259+ self .assertEqual (self .external_grader_detail .num_failures , 1 )
260+ self .assertEqual (self .external_grader_detail .status , 'pending' )
259261
260262 def test_put_result_set_score_fail_30_times (self ):
261263 """
@@ -279,10 +281,10 @@ def test_put_result_set_score_fail_30_times(self):
279281
280282 self .assertEqual (response .status_code , status .HTTP_200_OK )
281283
282- self .queue_record .refresh_from_db ()
283- self .assertEqual (self .queue_record .num_failures , each + 1 )
284+ self .external_grader_detail .refresh_from_db ()
285+ self .assertEqual (self .external_grader_detail .num_failures , each + 1 )
284286
285- self .assertEqual (self .queue_record .status , 'failed' )
287+ self .assertEqual (self .external_grader_detail .status , 'failed' )
286288
287289 def test_put_result_auto_retire (self ):
288290 """
@@ -292,8 +294,8 @@ def test_put_result_auto_retire(self):
292294 response = self .client .post (self .url_status )
293295 self .assertEqual (response .status_code , status .HTTP_200_OK )
294296 initial_failures = 29
295- self .queue_record .num_failures = initial_failures
296- self .queue_record .save ()
297+ self .external_grader_detail .num_failures = initial_failures
298+ self .external_grader_detail .save ()
297299
298300 payload = {
299301 'xqueue_header' : json .dumps ({
@@ -307,19 +309,19 @@ def test_put_result_auto_retire(self):
307309 with patch ('submissions.api.set_score' ) as mock_set_score :
308310 mock_set_score .side_effect = Exception ('Test error' )
309311 _ = self .client .post (self .url , payload , format = 'json' )
310- self .queue_record .refresh_from_db ()
312+ self .external_grader_detail .refresh_from_db ()
311313
312- self .queue_record .refresh_from_db ()
314+ self .external_grader_detail .refresh_from_db ()
313315
314316 @patch ('submissions.views.xqueue.log' )
315317 def test_put_result_logging (self , mock_log ):
316318 """
317319 Test that appropriate logging occurs in various escenarios.
318320 """
319- self .submission .queue_record .status = 'pulled'
320- self .submission .queue_record .save ()
321- self .submission .queue_record .refresh_from_db ()
322- self .assertEqual (self .submission .queue_record .status , 'pulled' )
321+ self .submission .external_grader_detail .status = 'pulled'
322+ self .submission .external_grader_detail .save ()
323+ self .submission .external_grader_detail .refresh_from_db ()
324+ self .assertEqual (self .submission .external_grader_detail .status , 'pulled' )
323325
324326 payload = {
325327 'xqueue_header' : json .dumps ({
@@ -344,10 +346,10 @@ def test_put_result_success(self, mock_log):
344346 """
345347 Test that appropriate logging occurs in various scenarios.
346348 """
347- self .submission .queue_record .status = 'pulled'
348- self .submission .queue_record .save ()
349- self .submission .queue_record .refresh_from_db ()
350- self .assertEqual (self .submission .queue_record .status , 'pulled' )
349+ self .submission .external_grader_detail .status = 'pulled'
350+ self .submission .external_grader_detail .save ()
351+ self .submission .external_grader_detail .refresh_from_db ()
352+ self .assertEqual (self .submission .external_grader_detail .status , 'pulled' )
351353
352354 payload = {
353355 'xqueue_header' : json .dumps ({
@@ -498,7 +500,7 @@ def test_get_submission_with_files(self):
498500
499501 file_content = b'Test file content'
500502 submission_file = SubmissionFile .objects .create (
501- submission_queue = self .queue_record ,
503+ submission_queue = self .external_grader_detail ,
502504 file = ContentFile (file_content , name = 'test.txt' ),
503505 original_filename = 'test.txt'
504506 )
@@ -525,7 +527,7 @@ def test_get_submission_with_multiple_files(self):
525527 created_files = []
526528 for filename , content in files_data :
527529 submission_file = SubmissionFile .objects .create (
528- submission_queue = self .queue_record ,
530+ submission_queue = self .external_grader_detail ,
529531 file = ContentFile (content , name = filename ),
530532 original_filename = filename
531533 )
@@ -548,7 +550,7 @@ def test_get_submission_file_urls_format(self):
548550
549551 test_uuid = uuid .uuid4 ()
550552 _ = SubmissionFile .objects .create (
551- submission_queue = self .queue_record ,
553+ submission_queue = self .external_grader_detail ,
552554 file = ContentFile (b'content' , name = 'test.txt' ),
553555 original_filename = 'test.txt' ,
554556 uid = test_uuid
@@ -561,3 +563,29 @@ def test_get_submission_file_urls_format(self):
561563
562564 expected_url = f'/test_queue/{ test_uuid } '
563565 self .assertEqual (xqueue_files ['test.txt' ], expected_url )
566+
567+ def test_get_submission_already_pulled_status (self ):
568+ """Test get_submission when the status is already 'pulled'."""
569+ self .client .login (username = 'testuser' , password = 'testpass' )
570+
571+ queue_name = 'test_already_pulled'
572+ submission = SubmissionFactory ()
573+ old_time = timezone .now () - timedelta (minutes = 10 )
574+
575+ external_grader_detail = ExternalGraderDetailFactory (
576+ submission = submission ,
577+ queue_name = queue_name ,
578+ status = 'pulled' ,
579+ status_time = old_time ,
580+ pullkey = 'original_key'
581+ )
582+
583+ response = self .client .get (self .get_submission_url , {'queue_name' : queue_name })
584+
585+ self .assertEqual (response .status_code , status .HTTP_200_OK )
586+
587+ external_grader_detail .refresh_from_db ()
588+
589+ self .assertEqual (external_grader_detail .pullkey , 'original_key' )
590+ self .assertEqual (external_grader_detail .status , 'pulled' )
591+ self .assertEqual (external_grader_detail .status_time , old_time )
0 commit comments