11"""Common test functions used in many autograders."""
22
3- from datetime import datetime , timedelta , timezone
43import inspect
5- import json
64import os
75import pytest
86import subprocess
@@ -22,23 +20,6 @@ def chdir_test():
2220 break
2321
2422
25- def get_username (default = "username" ):
26- """Get the student's username from the submission metadata.
27-
28- Args:
29- default (str): Value to return if metadata not found.
30-
31- Returns:
32- str: The student's email address up to the @ symbol.
33- """
34- try :
35- with open ("/autograder/submission_metadata.json" ) as file :
36- metadata = json .load (file )
37- return metadata ["users" ][0 ]["email" ].split ("@" )[0 ]
38- except FileNotFoundError :
39- return default
40-
41-
4223def _get_cfg (filename ):
4324 """Get the path of an optional configuration file.
4425
@@ -133,87 +114,3 @@ def run_module(filename, input=None):
133114 str: Captured output from the child process.
134115 """
135116 return run_command (["python" , filename ], input )
136-
137-
138- def submission_open (before = 5 , after = 5 ):
139- """Check if the current time is within the user's submission window.
140-
141- The window starts at the release date and ends at the due date (or late
142- due date, if set). This function applies a tolerance by including times:
143- * `before` minutes prior to the release date
144- * `after` minutes beyond the due/late date
145-
146- Args:
147- before (int): Minutes to extend the window before the release date.
148- after (int): Minutes to extend the window after the due/late date.
149-
150- Returns:
151- bool: True if the current time is within the submission window.
152- """
153-
154- # Get the submission metadata
155- try :
156- with open ("/autograder/submission_metadata.json" ) as file :
157- metadata = json .load (file )
158- except FileNotFoundError :
159- return False
160-
161- # Get the assignment's dates specific to the user
162- assignment = metadata ["users" ][0 ]["assignment" ]
163- beg = datetime .fromisoformat (assignment ["release_date" ])
164- end = datetime .fromisoformat (assignment ["due_date" ])
165- late = assignment .get ("late_due_date" )
166- if late is not None :
167- end = datetime .fromisoformat (late )
168-
169- # Extend the submission window
170- beg -= timedelta (minutes = before )
171- end += timedelta (minutes = after )
172-
173- # Compare with current time
174- now = datetime .now (timezone .utc )
175- return beg <= now <= end
176-
177-
178- def submission_closed ():
179- """Check if the current time is outside the user's submission window.
180-
181- See submission_open() for more details. This function returns the opposite.
182- """
183- return not submission_open ()
184-
185-
186- def postpone_tests (
187- title = "Ready to grade" ,
188- message = "Your submission has been received and will be graded manually." ,
189- ):
190- """Replace all tests in the calling test module with a single placeholder.
191-
192- This function is used to hide autograder feedback during an assignment or
193- exam. It deletes all existing test functions and defines a new function
194- named `test_postpone` that carries the given title and message.
195-
196- Args:
197- title (str): Docstring for the new test (rendered as the test's name).
198- message (str): Message assigned to the new test's `output` attribute.
199- """
200-
201- # Get the test module
202- for frameinfo in inspect .stack ():
203- module = inspect .getmodule (frameinfo .frame )
204- if module and module .__name__ .startswith ("test_" ):
205- test_module = module
206- break
207-
208- # Delete all test functions
209- g = test_module .__dict__
210- for name in list (g .keys ()):
211- if name .startswith ("test_" ):
212- del g [name ]
213-
214- # Define the fallback test
215- def test_postpone ():
216- test_postpone .__doc__ = title
217- test_postpone .output = message
218-
219- g ["test_postpone" ] = test_postpone
0 commit comments