def add_files_to_sandbox(sandbox: AutograderSandbox, suite: Union[ag_models.AGTestSuite, ag_models.StudentTestSuite], submission: ag_models.Submission): student_files_to_add = [] for student_file in suite.student_files_needed.all(): matching_files = fnmatch.filter(submission.submitted_filenames, student_file.pattern) student_files_to_add += [ os.path.join(core_ut.get_submission_dir(submission), filename) for filename in matching_files ] if student_files_to_add: sandbox.add_files(*student_files_to_add) project_files_to_add = [ file_.abspath for file_ in suite.instructor_files_needed.all() ] if project_files_to_add: owner_and_read_only = { 'owner': 'root' if suite.read_only_instructor_files else SANDBOX_USERNAME, 'read_only': suite.read_only_instructor_files } sandbox.add_files(*project_files_to_add, **owner_and_read_only)
def test_extra_files_discarded(self): files = [ SimpleUploadedFile('spam.cpp', b'blah'), SimpleUploadedFile('eggs.cpp', b'merp'), SimpleUploadedFile('test_spam.cpp', b'cheeese'), ] extra_files = [ SimpleUploadedFile('extra.cpp', b'merp'), SimpleUploadedFile('extra_extra.cpp', b'spam') ] submission = self._do_files_discarded_test(files, extra_files) with utils.ChangeDirectory(core_ut.get_submission_dir(submission)): for file_ in extra_files: self.assertFalse(os.path.exists(file_.name))
def _merge_group_files(self, group1, group2, merged_group): tempdir_path = tempfile.mkdtemp() for submission in itertools.chain(group1.submissions.all(), group2.submissions.all()): shutil.copytree( core_ut.get_submission_dir(submission), os.path.join(tempdir_path, core_ut.get_submission_dir_basename(submission))) submission.group = merged_group submission.save() merged_group_dir = core_ut.get_student_group_dir(merged_group) shutil.rmtree(merged_group_dir) shutil.move(tempdir_path, merged_group_dir)
def test_get_submission_dir(self): submission = ag_models.Submission.objects.validate_and_create( group=self.group, submitted_files=[]) submission_dir_basename = 'submission{}'.format(submission.pk) expected_relative = "{0}/{1}/{2}/{3}/{4}/{5}".format( constants.FILESYSTEM_ROOT_COURSES_DIRNAME, self.course_dirname, self.project_dirname, constants.PROJECT_SUBMISSIONS_DIRNAME, self.group_dir_basename, submission_dir_basename) actual_relative = core_ut.get_submission_relative_dir(submission) self.assertEqual(expected_relative, actual_relative) expected_absolute = os.path.join(settings.MEDIA_ROOT, expected_relative) actual_absolute = core_ut.get_submission_dir(submission) self.assertEqual(expected_absolute, actual_absolute)
def _make_submission_archive( task: ag_models.DownloadTask, submission_fdbks: Iterator[SubmissionResultFeedback], num_submissions, dest_filename): with open(dest_filename, 'wb') as archive: with zipfile.ZipFile(archive, 'w') as z: for index, fdbk in enumerate(submission_fdbks): submission = fdbk.submission archive_dirname = ('_'.join(submission.group.member_names) + '-' + submission.timestamp.isoformat()) with utils.ChangeDirectory( core_ut.get_submission_dir(submission)): for filename in submission.submitted_filenames: target_name = os.path.join( '{}_{}'.format(task.project.course.name, task.project.name), archive_dirname, filename) z.write(filename, arcname=target_name) if index % _PROGRESS_UPDATE_FREQUENCY == 0: task.progress = (index / num_submissions) * 100 task.save() print('Updated task {} progress: {}'.format( task.pk, task.progress))
def test_valid_init(self): SimpleFileTuple = namedtuple('SimpleFileTuple', ['name', 'content']) files_to_submit = sorted([ SimpleFileTuple('spam.cpp', b'blah'), SimpleFileTuple('eggs.cpp', b'merp'), SimpleFileTuple('test_spam.cpp', b'cheeese') ]) now = timezone.now() submitter = 'steve' submission: ag_models.Submission = ag_models.Submission.objects.validate_and_create( group=self.group, submitted_files=[ SimpleUploadedFile(name, content) for name, content in files_to_submit ], submitter=submitter) submission.refresh_from_db() self.assertEqual(submitter, submission.submitter) self.assertEqual(submission.status, ag_models.Submission.GradingStatus.received) self.assertEqual(submission.error_msg, '') self.assertCountEqual(submission.missing_files, []) self.assertCountEqual((file_.name for file_ in files_to_submit), submission.submitted_filenames) self.assertTrue(submission.count_towards_daily_limit) self.assertFalse(submission.is_past_daily_limit) self.assertTrue(submission.count_towards_total_limit) self.assertFalse(submission.is_bonus_submission) self.assertEqual([], submission.does_not_count_for) self.assertLess(submission.timestamp - now, timezone.timedelta(seconds=2)) # Check file contents in the filesystem self.assertTrue(os.path.isdir(core_ut.get_submission_dir(submission))) with utils.ChangeDirectory(core_ut.get_submission_dir(submission)): self.assertTrue( os.path.isdir(constants.FILESYSTEM_RESULT_OUTPUT_DIRNAME)) for name, content in files_to_submit: self.assertEqual(name, submission.get_file(name).name) self.assertEqual(content, submission.get_file(name).read()) self.assertTrue(os.path.isfile(os.path.basename(name))) with open(name, 'rb') as f: self.assertEqual(content, f.read()) # Check submitted files using member accessors expected = sorted(files_to_submit) actual = sorted(submission.submitted_files, key=lambda file_: file_.name) for expected_file, loaded_file in zip(expected, actual): self.assertEqual(expected_file.name, os.path.basename(loaded_file.name)) self.assertEqual(expected_file.content, loaded_file.read())
def _get_submitted_file_dir(self, filename): return os.path.join(core_ut.get_submission_dir(self), filename)
def _get_submission_file_upload_to_dir(submission, filename): value = os.path.join(core_ut.get_submission_dir(submission), filename) return value