def setUp(self): super().setUp() self.maxDiff = None self.project = obj_build.make_project( # Future closing_time closing_time=timezone.now() + datetime.timedelta(days=1)) self.course = self.project.course self.ag_test_suite = obj_build.make_ag_test_suite(self.project) self.ag_test_case = obj_build.make_ag_test_case(self.ag_test_suite) self.ag_test_cmd = obj_build.make_full_ag_test_command( self.ag_test_case) self.student_test_suite = obj_build.make_student_test_suite( self.project) self.client = APIClient() self.base_url = reverse('all-ultimate-submission-results', kwargs={'project_pk': self.project.pk}) # For use by self._make_group_with_submissions only self._num_groups = 0 # This is to make sure we use the right group queryset other_project = obj_build.make_project() other_group = obj_build.make_group(project=other_project) other_submission = obj_build.make_finished_submission(other_group)
def test_copy_course(self): proj1 = obj_build.make_project() course = proj1.course proj2 = obj_build.make_project(course) admins = obj_build.make_admin_users(course, 4) staff = obj_build.make_staff_users(course, 3) students = obj_build.make_student_users(course, 5) handgraders = obj_build.make_handgrader_users(course, 2) self.assertNotEqual(0, course.staff.count()) self.assertNotEqual(0, course.students.count()) self.assertNotEqual(0, course.handgraders.count()) name = 'stove' new_course = copy_course(course, name, Semester.summer, 2019) self.assertEqual(name, new_course.name) self.assertEqual(Semester.summer, new_course.semester) self.assertEqual(2019, new_course.year) self.assertCountEqual(admins, new_course.admins.all()) self.assertSequenceEqual([], new_course.staff.all()) self.assertSequenceEqual([], new_course.students.all()) self.assertSequenceEqual([], new_course.handgraders.all()) old_project_pks = {proj.pk for proj in course.projects.all()} new_project_pks = {proj.pk for proj in new_course.projects.all()} self.assertTrue(old_project_pks.isdisjoint(new_project_pks)) self.assertSetEqual({proj.name for proj in course.projects.all()}, {proj.name for proj in new_course.projects.all()})
def setUp(self): super().setUp() self.maxDiff = None self.client = APIClient() self.project = obj_build.make_project( ultimate_submission_policy=ag_models.UltimateSubmissionPolicy. most_recent, ) self.url = reverse('project-ultimate-submission-scores', kwargs={'pk': self.project.pk}) self.admin = obj_build.make_admin_user(self.project.course) self.ag_test_suite = obj_build.make_ag_test_suite(project=self.project) self.ag_test_case = obj_build.make_ag_test_case( ag_test_suite=self.ag_test_suite) self.ag_test_cmd = obj_build.make_full_ag_test_command( ag_test_case=self.ag_test_case) self.student_group = obj_build.make_group(project=self.project, num_members=2) self.student_submission = obj_build.make_finished_submission( self.student_group) self.student_result = obj_build.make_incorrect_ag_test_command_result( ag_test_command=self.ag_test_cmd, submission=self.student_submission) self.student_submission = update_denormalized_ag_test_results( self.student_submission.pk) self.student_result_fdbk = SubmissionResultFeedback( self.student_submission, ag_models.FeedbackCategory.max, AGTestPreLoader(self.project)) self.assertEqual(0, self.student_result_fdbk.total_points) self.assertNotEqual(0, self.student_result_fdbk.total_points_possible) self.staff_group = obj_build.make_group( project=self.project, members_role=obj_build.UserRole.admin) self.staff_submission = obj_build.make_finished_submission( self.staff_group) self.staff_result = obj_build.make_correct_ag_test_command_result( ag_test_command=self.ag_test_cmd, submission=self.staff_submission) self.staff_submission = update_denormalized_ag_test_results( self.staff_submission.pk) self.staff_result_fdbk = SubmissionResultFeedback( self.staff_submission, ag_models.FeedbackCategory.max, AGTestPreLoader(self.project)) self.assertNotEqual(0, self.staff_result_fdbk.total_points) self.assertNotEqual(0, self.staff_result_fdbk.total_points_possible) # Make sure we use the right queryset other_project = obj_build.make_project(course=self.project.course) other_group = obj_build.make_group(project=other_project) other_submission = obj_build.make_finished_submission(other_group)
def setUp(self): super().setUp() self.project = obj_build.make_project() # Make sure we use the right group queryset other_project = obj_build.make_project(course=self.project.course) other_group = obj_build.make_group(project=other_project) other_subimssion = obj_build.make_finished_submission(other_group)
def setUp(self): super().setUp() self.hidden_project = obj_build.make_project() self.course = self.hidden_project.course self.visible_project = obj_build.make_project(course=self.course, visible_to_students=True) self.all_projects = [self.hidden_project, self.visible_project] self.client = APIClient() self.url = reverse('projects', kwargs={'pk': self.course.pk})
def test_get_num_queued_submissions(self): client = APIClient() course = obj_build.make_course() admin = obj_build.make_admin_user(course) proj_kwargs = {'visible_to_students': True, 'guests_can_submit': True} no_submits = obj_build.make_project(course, **proj_kwargs) with_submits1 = obj_build.make_project(course, **proj_kwargs) with_submits2 = obj_build.make_project(course, **proj_kwargs) group_with_submits1 = obj_build.make_group(project=with_submits1) group_with_submits2 = obj_build.make_group(project=with_submits2) g1_statuses = [ ag_models.Submission.GradingStatus.queued, ag_models.Submission.GradingStatus.finished_grading, ag_models.Submission.GradingStatus.removed_from_queue, ag_models.Submission.GradingStatus.received, ag_models.Submission.GradingStatus.being_graded, ag_models.Submission.GradingStatus.error ] for grading_status in g1_statuses: obj_build.make_submission(status=grading_status, group=group_with_submits1) for i in range(3): obj_build.make_submission( status=ag_models.Submission.GradingStatus.queued, group=group_with_submits2) client.force_authenticate(admin) response = client.get( reverse('project-num-queued-submissions', kwargs={'pk': no_submits.pk})) self.assertEqual(status.HTTP_200_OK, response.status_code) self.assertEqual(0, response.data) response = client.get( reverse('project-num-queued-submissions', kwargs={'pk': with_submits1.pk})) self.assertEqual(status.HTTP_200_OK, response.status_code) self.assertEqual(1, response.data) response = client.get( reverse('project-num-queued-submissions', kwargs={'pk': with_submits2.pk})) self.assertEqual(status.HTTP_200_OK, response.status_code) self.assertEqual(3, response.data)
def test_get_ultimate_submission_most_recent_submission_doesnt_count_for_user( self): project = obj_build.make_project(visible_to_students=True, hide_ultimate_submission_fdbk=False, ultimate_submission_policy=ag_models. UltimateSubmissionPolicy.most_recent) course = project.course counts_for_user = obj_build.make_student_user(course) does_not_count_for_user = obj_build.make_student_user(course) group = obj_build.make_group( members=[counts_for_user, does_not_count_for_user], project=project) second_most_recent_submission = obj_build.make_finished_submission( group=group) most_recent_submission = obj_build.make_finished_submission( group=group, does_not_count_for=[does_not_count_for_user.username]) self.client.force_authenticate(counts_for_user) response = self.client.get(self.ultimate_submission_url(group)) self.assertEqual(status.HTTP_200_OK, response.status_code) self.assertEqual(most_recent_submission.to_dict(), response.data) self.client.force_authenticate(does_not_count_for_user) response = self.client.get(self.ultimate_submission_url(group)) self.assertEqual(status.HTTP_200_OK, response.status_code) self.assertEqual(second_most_recent_submission.to_dict(), response.data)
def test_non_admin_create_permission_denied(self): project = obj_build.make_project() [staff] = obj_build.make_staff_users(project.course, 1) self.do_permission_denied_create_test( ag_models.RerunSubmissionsTask.objects, APIClient(), staff, reverse('rerun_submissions_tasks', kwargs={'project_pk': project.pk}), {})
def test_copy_project_new_name_same_course(self): project = obj_build.make_project() name = 'steve' new_project = copy_project(project, project.course, name) self.assertEqual(new_project.course, project.course) self.assertNotEqual(project, new_project) self.assertEqual(name, new_project.name)
def test_groups_sorted_by_least_alphabetical_username(self): self.maxDiff = None project = obj_build.make_project(max_group_size=3, guests_can_submit=True) [admin] = obj_build.make_admin_users(project.course, 1) group1_user1 = User.objects.create(username='******') group1 = ag_models.Group.objects.validate_and_create( members=[group1_user1], project=project) group2_user1 = User.objects.create(username='******') group2_user2 = User.objects.create(username='******') group2 = ag_models.Group.objects.validate_and_create( members=[group2_user1, group2_user2], project=project) group3_user1 = User.objects.create(username='******') group3_user2 = User.objects.create(username='******') group3_user3 = User.objects.create(username='******') group3 = ag_models.Group.objects.validate_and_create( members=[group3_user1, group3_user2, group3_user3], project=project) expected = [group2.to_dict(), group3.to_dict(), group1.to_dict()] # type: List[dict] for group_dict in expected: group_dict['member_names'] = list( sorted(group_dict['member_names'])) self.client.force_authenticate(admin) response = self.client.get( reverse('groups', kwargs={'project_pk': project.pk})) self.assertEqual(expected, response.data)
def setUp(self): super().setUp() self.project = obj_build.make_project() self.client = APIClient() self.url = reverse('ag_test_suites', kwargs={'project_pk': self.project.pk}) self.create_data = {'name': 'adslkfjals;dkjfa;lsdkjf'}
def setUp(self): super().setUp() self.project = obj_build.make_project() self.client = APIClient() self.url = reverse('student_test_suites', kwargs={'project_pk': self.project.pk}) self.create_data = {'name': 'some suite'}
def setUp(self): super().setUp() self.project = obj_build.make_project(max_group_size=2) self.course = self.project.course self.student_users = unsorted_users(obj_build.make_student_users(self.course, 2)) self.staff_users = unsorted_users(obj_build.make_staff_users(self.course, 2)) self.guest_group = obj_build.make_users(2)
def setUp(self): super().setUp() self.client = APIClient() self.project = obj_build.make_project() self.admin = obj_build.make_admin_user(self.project.course) self.other_course = obj_build.make_course() self.other_course.admins.add(self.admin)
def test_create_criterion_results_on_create(self): [admin] = obj_build.make_admin_users(self.course, 1) self.client.force_authenticate(admin) # Create HandgradingResult submission = obj_build.make_submission( group=obj_build.make_group(project=self.handgrading_rubric.project)) handgrading_result = hg_models.HandgradingResult.objects.validate_and_create( submission=submission, group=submission.group, handgrading_rubric=self.handgrading_rubric) # Create dummy submissions and groups with no submissions. These should not be affected dummy_submission = obj_build.make_submission( group=obj_build.make_group(project=self.handgrading_rubric.project)) dummy_submission = obj_build.make_submission( group=obj_build.make_group(project=self.handgrading_rubric.project)) group_with_no_submission = obj_build.make_group(project=self.handgrading_rubric.project) group_with_no_submission = obj_build.make_group(project=self.handgrading_rubric.project) self.assertEqual(0, handgrading_result.criterion_results.count()) self.assertEqual(1, hg_models.HandgradingResult.objects.count()) # Create dummy project with its own groups and HandgradingResults. # These should not be affected dummy_project = obj_build.make_project(course=self.handgrading_rubric.project.course) dummy_handgrading_rubric = hg_models.HandgradingRubric.objects.validate_and_create( points_style=hg_models.PointsStyle.start_at_max_and_subtract, max_points=0, show_grades_and_rubric_to_students=False, handgraders_can_leave_comments=True, handgraders_can_adjust_points=True, project=dummy_project) dummy_submission = obj_build.make_submission( group=obj_build.make_group(project=self.handgrading_rubric.project)) dummy_handgrading_result = hg_models.HandgradingResult.objects.validate_and_create( submission=dummy_submission, group=dummy_submission.group, handgrading_rubric=dummy_handgrading_rubric) self.assertEqual(0, hg_models.CriterionResult.objects.count()) self.assertEqual(2, hg_models.HandgradingResult.objects.count()) # Create Criterion, which should create a CriterionResult for above HandgradingResult response = self.client.post(self.url, self.data) self.assertEqual(status.HTTP_201_CREATED, response.status_code) handgrading_result.refresh_from_db() self.assertEqual(1, handgrading_result.criterion_results.count()) self.assertEqual(1, hg_models.CriterionResult.objects.count()) criterion_results = handgrading_result.to_dict()["criterion_results"] self.assertFalse(criterion_results[0]["selected"]) self.assertEqual(criterion_results[0]["criterion"], response.data)
def setUp(self): super().setUp() self.project = obj_build.make_project() self.course = self.project.course self.counts_for_user = obj_build.make_student_user(self.course) self.does_not_count_for_user = obj_build.make_student_user(self.course) self.group = obj_build.make_group( members=[self.counts_for_user, self.does_not_count_for_user], project=self.project)
def test_error_student_file_needed_that_belongs_to_other_project(self): other_project = obj_build.make_project(course=self.project.course) other_student_file = obj_build.make_expected_student_file( other_project) with self.assertRaises(exceptions.ValidationError) as cm: ag_models.StudentTestSuite.objects.validate_and_create( name=self.name, project=self.project, student_files_needed=[other_student_file.pk]) self.assertIn('student_files_needed', cm.exception.message_dict)
def setUp(self): super().setUp() self.initial_num_bonus_submissions = 10 self.project = obj_build.make_project( num_bonus_submissions=self.initial_num_bonus_submissions) self.groups = [ obj_build.make_group(project=self.project) for i in range(5) ] # Make sure bonus submissions are only changed for self.project self.other_project = obj_build.make_project(course=self.project.course, num_bonus_submissions=3) self.other_groups = [ obj_build.make_group(project=self.other_project) for i in range(5) ] self.admin = obj_build.make_admin_user(self.project.course) self.url = reverse('edit-bonus-submissions', kwargs={'project_pk': self.project.pk}) self.client = APIClient()
def setUp(self): super().setUp() self.project = obj_build.make_project() [self.creator] = obj_build.make_admin_users(self.project.course, 1) self.ag_test_suite = obj_build.make_ag_test_suite(self.project) self.ag_test_case = obj_build.make_ag_test_case(self.ag_test_suite) self.student_test_suite = obj_build.make_student_test_suite( self.project) self.submission = obj_build.make_submission(group=obj_build.make_group( project=self.project))
def test_error_stdin_instructor_file_belongs_to_other_project(self): other_project = obj_build.make_project(course=self.project.course) other_instructor_file = obj_build.make_instructor_file( project=other_project) with self.assertRaises(exceptions.ValidationError) as cm: ag_models.AGTestCommand.objects.validate_and_create( name=self.name, ag_test_case=self.ag_test, cmd='true', stdin_source=ag_models.StdinSource.instructor_file, stdin_instructor_file=other_instructor_file) self.assertIn('stdin_instructor_file', cm.exception.message_dict)
def test_view_calls_copy_project(self): dummy_project = obj_build.make_project(self.other_course) mock_copy_project = mock.Mock(return_value=dummy_project) with mock.patch( 'autograder.rest_api.views.project_views.project_views.copy_project', new=mock_copy_project): self.client.force_authenticate(self.admin) response = self.client.post( self.get_url(self.project, self.other_course)) mock_copy_project.assert_called_once_with( project=self.project, target_course=self.other_course, new_project_name=None)
def test_user_passed_to_get_ultimate_submission_func(self): project = obj_build.make_project(visible_to_students=True, hide_ultimate_submission_fdbk=False) group = obj_build.make_group(project=project) mocked_get_ultimate_submission = mock.Mock(return_value=None) with mock.patch( 'autograder.rest_api.views.group_views.get_ultimate_submission', new=mocked_get_ultimate_submission): self.client.force_authenticate(group.members.first()) response = self.client.get(self.ultimate_submission_url(group)) self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code) mocked_get_ultimate_submission.assert_called_once_with( group, user=group.members.first())
def test_no_stdin_specified_redirects_devnull(self): # If no stdin is redirected, this command will time out. # If /dev/null is redirected it should terminate normally. # This behavior is handled by the autograder_sandbox library. cmd = 'python3 -c "import sys; sys.stdin.read(); print(\'done\')"' # Run command from args with AutograderSandbox() as sandbox: result = tasks.run_command_from_args(cmd, sandbox, max_num_processes=10, max_stack_size=10000000, max_virtual_memory=500000000, timeout=2) self.assertFalse(result.timed_out) self.assertEqual(0, result.return_code) self.assertEqual('done\n', result.stdout.read().decode()) # Run ag command with AutograderSandbox() as sandbox: ag_command = ag_models.AGCommand.objects.validate_and_create( cmd=cmd, process_spawn_limit=10, time_limit=2) result = tasks.run_ag_command(ag_command, sandbox) self.assertFalse(result.timed_out) self.assertEqual(0, result.return_code) self.assertEqual('done\n', result.stdout.read().decode()) project = obj_build.make_project() ag_test_suite = ag_models.AGTestSuite.objects.validate_and_create( name='Suite', project=project) ag_test_case = ag_models.AGTestCase.objects.validate_and_create( name='Case', ag_test_suite=ag_test_suite) # Run ag test command with AutograderSandbox() as sandbox: ag_test_command = ag_models.AGTestCommand.objects.validate_and_create( ag_test_case=ag_test_case, name='Read stdin', cmd=cmd, stdin_source=ag_models.StdinSource.none, time_limit=2, process_spawn_limit=10) result = tasks.run_ag_test_command(ag_test_command, sandbox, ag_test_suite) self.assertFalse(result.timed_out) self.assertEqual(0, result.return_code) self.assertEqual('done\n', result.stdout.read().decode())
def setUp(self): super().setUp() self.maxDiff = None self.client = APIClient() self.course = obj_build.make_course() self.project = obj_build.make_project(course=self.course) self.assertEqual(ag_models.UltimateSubmissionPolicy.most_recent, self.project.ultimate_submission_policy) self.rubric = hg_models.HandgradingRubric.objects.validate_and_create( project=self.project, points_style=hg_models.PointsStyle.start_at_max_and_subtract, max_points=43) [self.staff] = obj_build.make_staff_users(self.course, 1) [self.handgrader] = obj_build.make_handgrader_users(self.course, 1)
def setUp(self): super().setUp() self.client = APIClient() # This submission that belongs to another project shouldn't # prevent us from downloading files for our project. obj_build.make_submission( status=ag_models.Submission.GradingStatus.being_graded) self.files = [ SimpleUploadedFile('file1.txt', b'adsfadslkfajsdkfj'), SimpleUploadedFile('file2.txt', b'asdqeirueinfaksdnfaadf'), SimpleUploadedFile('file3.txt', b'cmxcnajsddhadf') ] self.files_by_name = dict( zip([file_.name for file_ in self.files], self.files)) max_group_size = 3 self.project = obj_build.make_project(visible_to_students=True, max_group_size=max_group_size) ag_models.ExpectedStudentFile.objects.validate_and_create( project=self.project, pattern='*', max_num_matches=3) self.student_group1 = obj_build.make_group(project=self.project) self.group1_submission1 = obj_build.make_finished_submission( submitted_files=self.files[:1], group=self.student_group1) self.group1_submission2 = obj_build.make_finished_submission( submitted_files=self.files[:2], group=self.student_group1) self.student_group2 = obj_build.make_group(num_members=max_group_size, project=self.project) self.group2_submission1 = obj_build.make_finished_submission( submitted_files=self.files[-1:], group=self.student_group2) self.staff_group = obj_build.make_group( project=self.project, members_role=obj_build.UserRole.staff) self.staff_submission1 = obj_build.make_finished_submission( submitted_files=self.files, group=self.staff_group) self.no_submissions_group = obj_build.make_group(project=self.project) [self.admin] = obj_build.make_admin_users(self.project.course, 1)
def setUp(self): super().setUp() self.maxDiff = None self.project = obj_build.make_project( # Future closing_time closing_time=timezone.now() + datetime.timedelta(days=1)) self.course = self.project.course self.ag_test_suite = obj_build.make_ag_test_suite(self.project) self.ag_test_case = obj_build.make_ag_test_case(self.ag_test_suite) self.ag_test_cmd = obj_build.make_full_ag_test_command( self.ag_test_case) self.student_test_suite = obj_build.make_student_test_suite( self.project) self.ag_test_preloader = AGTestPreLoader(self.project)
def setUp(self): super().setUp() self.project = obj_build.make_project() [self.admin] = obj_build.make_admin_users(self.project.course, 1) self.task1 = ag_models.RerunSubmissionsTask.objects.validate_and_create( creator=self.admin, project=self.project, ) # type: ag_models.RerunSubmissionsTask self.task2 = ag_models.RerunSubmissionsTask.objects.validate_and_create( creator=self.admin, project=self.project, ) # type: ag_models.RerunSubmissionsTask self.client = APIClient() self.url = reverse('rerun_submissions_tasks', kwargs={'project_pk': self.project.pk})
def setUp(self): super().setUp() self.project = obj_build.make_project() [self.admin] = obj_build.make_admin_users(self.project.course, 1) self.submission = obj_build.make_submission( group=obj_build.make_group()) # Create a rerun task using the api so that it gets run and we have a # real celery task ID to look up. create_client = APIClient() create_client.force_authenticate(self.admin) create_url = reverse('rerun_submissions_tasks', kwargs={'project_pk': self.project.pk}) create_response = create_client.post(create_url, {}) self.rerun_task = ag_models.RerunSubmissionsTask.objects.get( pk=create_response.data['pk']) self.client = APIClient() self.url = reverse('rerun-submissions-task-detail', kwargs={'pk': self.rerun_task.pk})
def test_error_non_unique_name(self): project = obj_build.make_project() with self.assertRaises(exceptions.ValidationError): copy_project(project, project.course, project.name)
def test_copy_project(self): # In new project, hide_ultimate_submission_fdbk should be set to True, # visible_to_students should be set to False, # and guests_can_submit should be set to False project = obj_build.make_project(hide_ultimate_submission_fdbk=False, visible_to_students=True) instructor_file1 = obj_build.make_instructor_file(project) instructor_file2 = obj_build.make_instructor_file(project) student_file1 = obj_build.make_expected_student_file(project) student_file2 = obj_build.make_expected_student_file(project) suite1 = obj_build.make_ag_test_suite( project, instructor_files_needed=[instructor_file1], student_files_needed=[student_file1]) case1 = obj_build.make_ag_test_case(suite1) cmd1 = obj_build.make_full_ag_test_command( case1, expected_stderr_source=ag_models.ExpectedOutputSource. instructor_file, expected_stderr_instructor_file=instructor_file2) cmd2 = obj_build.make_full_ag_test_command( case1, set_arbitrary_points=False, expected_stdout_source=ag_models.ExpectedOutputSource. instructor_file, expected_stdout_instructor_file=instructor_file1) suite2 = obj_build.make_ag_test_suite( project, instructor_files_needed=[instructor_file1, instructor_file2], student_files_needed=[student_file2]) case2 = obj_build.make_ag_test_case(suite2) cmd3 = obj_build.make_full_ag_test_command( case2, set_arbitrary_expected_vals=False, stdin_source=ag_models.StdinSource.instructor_file, stdin_instructor_file=instructor_file2) case3 = obj_build.make_ag_test_case(suite2) suite3 = obj_build.make_ag_test_suite(project) student_suite1 = obj_build.make_student_test_suite( project, instructor_files_needed=[instructor_file1, instructor_file2], student_files_needed=[student_file1], setup_command={ 'name': 'stave', 'cmd': 'yorp' }) student_suite2 = obj_build.make_student_test_suite( project, instructor_files_needed=[instructor_file1], student_files_needed=[student_file1, student_file2]) student_suite3 = obj_build.make_student_test_suite(project) other_course = obj_build.make_course() new_project = copy_project(project, other_course) self.assertTrue(new_project.hide_ultimate_submission_fdbk) self.assertFalse(new_project.visible_to_students) self.assertEqual(project.name, new_project.name) self.assertEqual(other_course, new_project.course) self.assertNotEqual(project.course, other_course) ignore_fields = [ 'pk', 'course', 'last_modified', 'instructor_files', 'expected_student_files' ] expected_ag_tests = _pop_many(project.to_dict(), ignore_fields) expected_ag_tests.update({ 'visible_to_students': False, 'hide_ultimate_submission_fdbk': True }) self.assertEqual(expected_ag_tests, _pop_many(new_project.to_dict(), ignore_fields)) self.assertEqual(project.instructor_files.count(), new_project.instructor_files.count()) for old_file, new_file in itertools.zip_longest( sorted(project.instructor_files.all(), key=lambda obj: obj.name), sorted(new_project.instructor_files.all(), key=lambda obj: obj.name)): self.assertNotEqual(new_file.pk, old_file.pk) self.assertNotEqual(new_file.abspath, old_file.abspath) self.assertEqual(old_file.name, new_file.name) with old_file.open() as old_f, new_file.open() as new_f: self.assertEqual(old_f.read(), new_f.read()) self.assertEqual(project.expected_student_files.count(), new_project.expected_student_files.count()) for old_expected_file, new_expected_file in itertools.zip_longest( project.expected_student_files.order_by('pattern'), new_project.expected_student_files.order_by('pattern')): self.assertNotEqual(old_expected_file.pk, new_expected_file.pk) self.assertEqual( _pop_many(old_expected_file.to_dict(), ['pk', 'project']), _pop_many(new_expected_file.to_dict(), ['pk', 'project'])) old_suite_pks = {suite.pk for suite in project.ag_test_suites.all()} new_suite_pks = { suite.pk for suite in new_project.ag_test_suites.all() } self.assertTrue(old_suite_pks.isdisjoint(new_suite_pks)) old_case_pks = { case.pk for case in ag_models.AGTestCase.objects.filter( ag_test_suite__project=project) }