Example #1
0
    def create_course(self, admin, course_id, course_name):
        result = admin.run("admin course add", [course_id, course_name])
        self.assertEqual(result.exit_code, 0)

        course = Course.get_by_course_id(course_id)
        self.assertIsNotNone(course)
        self.assertEqual(course.name, course_name)

        result = admin.run("admin course list")
        self.assertEqual(result.exit_code, 0)
        self.assertIn(course_id, result.output)
        self.assertIn(course_name, result.output)

        result = admin.run(
            "admin course set-attribute %s git_usernames custom" % (course_id))
        self.assertEqual(result.exit_code, 0)

        git_server_connstr = self.git_server_connstr
        git_staging_connstr = self.git_staging_connstr

        result = admin.run(
            "admin course set-attribute %s git_server_connstr %s" %
            (course_id, git_server_connstr))
        self.assertEqual(result.exit_code, 0)

        result = admin.run(
            "admin course set-attribute %s git_staging_connstr %s" %
            (course_id, git_staging_connstr))
        self.assertEqual(result.exit_code, 0)

        course = Course.get_by_course_id(course_id)
        self.assertEqual(course.git_server_connstr, git_server_connstr)
        self.assertEqual(course.git_staging_connstr, git_staging_connstr)

        result = admin.run("admin course unsetup-repo %s" % (course_id))
        self.assertEqual(result.exit_code, 0)

        result = admin.run("admin course setup-repo %s" % (course_id))
        self.assertEqual(result.exit_code, 0)

        result = admin.run("admin course unsetup-repo %s --staging" %
                           (course_id))
        self.assertEqual(result.exit_code, 0)

        result = admin.run("admin course setup-repo %s --staging" %
                           (course_id))
        self.assertEqual(result.exit_code, 0)
Example #2
0
    def create_course(self, admin, course_id, course_name):
        result = admin.run("admin course add", [course_id, course_name])
        self.assertEqual(result.exit_code, 0)
        
        course = Course.get_by_course_id(course_id)
        self.assertIsNotNone(course)
        self.assertEqual(course.name, course_name)
        
        result = admin.run("admin course list")
        self.assertEqual(result.exit_code, 0)
        self.assertIn(course_id, result.output)
        self.assertIn(course_name, result.output)

        result = admin.run("admin course set-attribute %s git_usernames custom" % (course_id))
        self.assertEqual(result.exit_code, 0)
        
        git_server_connstr = self.git_server_connstr
        git_staging_connstr = self.git_staging_connstr

        result = admin.run("admin course set-attribute %s git_server_connstr %s" % (course_id, git_server_connstr))
        self.assertEqual(result.exit_code, 0)

        result = admin.run("admin course set-attribute %s git_staging_connstr %s" % (course_id, git_staging_connstr))
        self.assertEqual(result.exit_code, 0)
        
        course = Course.get_by_course_id(course_id)
        self.assertEqual(course.git_server_connstr, git_server_connstr)
        self.assertEqual(course.git_staging_connstr, git_staging_connstr)
        
        result = admin.run("admin course unsetup-repo %s" % (course_id))
        self.assertEqual(result.exit_code, 0)
        
        result = admin.run("admin course setup-repo %s" % (course_id))
        self.assertEqual(result.exit_code, 0)

        result = admin.run("admin course unsetup-repo %s --staging" % (course_id))
        self.assertEqual(result.exit_code, 0)

        result = admin.run("admin course setup-repo %s --staging" % (course_id))
        self.assertEqual(result.exit_code, 0)
Example #3
0
    def test_create_team_with_team_members(self):
        c = self.get_api_client("admintoken")

        course = c.get_course("cmsc40100")
        team = course.create_team(team_id="student2-student3",
                                  extensions=2,
                                  active=False)
        self.assertEqual(team.team_id, "student2-student3")
        self.assertEqual(team.extensions, 2)
        self.assertEqual(team.active, False)

        course_obj = Course.get_by_course_id("cmsc40100")
        self.assertIsNotNone(course_obj)

        team_obj = course_obj.get_team("student2-student3")
        self.assertIsNotNone(team_obj, "Team was not added to database")

        self.assertEqual(team_obj.team_id, "student2-student3")
        self.assertEqual(team_obj.extensions, 2)
        self.assertEqual(team_obj.active, False)

        team_member = team.add_team_member("student2", confirmed=False)
        self.assertEqual(team_member.username, "student2")
        self.assertEqual(team_member.student.user.username, "student2")
        self.assertEqual(team_member.confirmed, False)

        team_member_objs = TeamMember.objects.filter(
            team=team_obj, student__user__username="******")
        self.assertEqual(len(team_member_objs), 1)
        team_member_obj = team_member_objs[0]
        self.assertEqual(team_member_obj.student.user.username, "student2")
        self.assertEqual(team_member_obj.confirmed, False)

        team.add_team_member("student3", confirmed=True)
        team_member_objs = TeamMember.objects.filter(
            team=team_obj, student__user__username="******")
        self.assertEqual(len(team_member_objs), 1)
        team_member_obj = team_member_objs[0]
        self.assertEqual(team_member_obj.student.user.username, "student3")
        self.assertEqual(team_member_obj.confirmed, True)

        team_members = team.get_team_members()

        self.assertEqual(len(team_members), 2)
        self.assertCountEqual([tm.username for tm in team_members],
                              ["student2", "student3"])
        self.assertCountEqual(
            [tm.student.user.username for tm in team_members],
            ["student2", "student3"])
Example #4
0
    def test_create_team_with_team_members(self):
        c = self.get_api_client("admintoken")
        
        course = c.get_course("cmsc40100")
        team = course.create_team(team_id = "student2-student3",
                                  extensions = 2,
                                  active = False)
        self.assertEqual(team.team_id, "student2-student3")
        self.assertEqual(team.extensions, 2)
        self.assertEqual(team.active, False)
        
        course_obj = Course.get_by_course_id("cmsc40100")
        self.assertIsNotNone(course_obj)
        
        team_obj = course_obj.get_team("student2-student3")
        self.assertIsNotNone(team_obj, "Team was not added to database")
            
        self.assertEqual(team_obj.team_id, "student2-student3")
        self.assertEqual(team_obj.extensions, 2)
        self.assertEqual(team_obj.active, False)
              
        team_member = team.add_team_member("student2", confirmed = False)
        self.assertEqual(team_member.username, "student2")
        self.assertEqual(team_member.student.user.username, "student2")
        self.assertEqual(team_member.confirmed, False)
                
        team_member_objs = TeamMember.objects.filter(team = team_obj, student__user__username = "******")
        self.assertEqual(len(team_member_objs), 1)
        team_member_obj = team_member_objs[0]
        self.assertEqual(team_member_obj.student.user.username, "student2")
        self.assertEqual(team_member_obj.confirmed, False)
        
        team.add_team_member("student3", confirmed = True)
        team_member_objs = TeamMember.objects.filter(team = team_obj, student__user__username = "******")
        self.assertEqual(len(team_member_objs), 1)
        team_member_obj = team_member_objs[0]
        self.assertEqual(team_member_obj.student.user.username, "student3")
        self.assertEqual(team_member_obj.confirmed, True)

        team_members = team.get_team_members()
        
        self.assertEqual(len(team_members), 2)
        self.assertCountEqual([tm.username for tm in team_members], ["student2","student3"])
        self.assertCountEqual([tm.student.user.username for tm in team_members], ["student2","student3"])
Example #5
0
    def test_create_team(self):
        c = self.get_api_client("admintoken")

        course = c.get_course("cmsc40100")
        team = course.create_team(team_id="student2-student3",
                                  extensions=2,
                                  active=False)
        self.assertEqual(team.team_id, "student2-student3")
        self.assertEqual(team.extensions, 2)
        self.assertEqual(team.active, False)

        course_obj = Course.get_by_course_id("cmsc40100")
        self.assertIsNotNone(course_obj)

        team_obj = course_obj.get_team("student2-student3")
        self.assertIsNotNone(team_obj, "Team was not added to database")

        self.assertEqual(team_obj.team_id, "student2-student3")
        self.assertEqual(team_obj.extensions, 2)
        self.assertEqual(team_obj.active, False)
Example #6
0
 def test_create_team(self):
     c = self.get_api_client("admintoken")
     
     course = c.get_course("cmsc40100")
     team = course.create_team(team_id = "student2-student3",
                               extensions = 2,
                               active = False)
     self.assertEqual(team.team_id, "student2-student3")
     self.assertEqual(team.extensions, 2)
     self.assertEqual(team.active, False)
     
     course_obj = Course.get_by_course_id("cmsc40100")
     self.assertIsNotNone(course_obj)
     
     team_obj = course_obj.get_team("student2-student3")
     self.assertIsNotNone(team_obj, "Team was not added to database")
         
     self.assertEqual(team_obj.team_id, "student2-student3")
     self.assertEqual(team_obj.extensions, 2)
     self.assertEqual(team_obj.active, False)
 def test_create_assignment(self):
     c = self.get_api_client("admintoken")
     
     course = c.get_course("cmsc40100")
     assignment = course.create_assignment(assignment_id = "pa3",
                                           name = "Programming Assignment 3",
                                           deadline = "2042-02-04 20:00:00+00:00",
                                           min_students = 2,
                                           max_students = 2)
     self.assertEquals(assignment.assignment_id, "pa3")
     self.assertEquals(assignment.name, "Programming Assignment 3")
     
     course_obj = Course.get_by_course_id("cmsc40100")
     self.assertIsNotNone(course_obj)
     
     assignment_obj = course_obj.get_assignment("pa3")
     self.assertIsNotNone(assignment_obj, "Assignment was not added to database")
         
     self.assertEquals(assignment_obj.assignment_id, "pa3")                  
     self.assertEquals(assignment_obj.name, "Programming Assignment 3")                  
     self.assertEquals(assignment_obj.min_students, 2)                  
     self.assertEquals(assignment_obj.max_students, 2)                  
 def test_create_rubric_component(self):
     c = self.get_api_client("admintoken")
     
     course = c.get_course("cmsc40100")
     assignment = course.get_assignment("pa1")
     rc = assignment.create_rubric_component(description = "Third Task",
                                             points = 50,
                                             order = 3)
     
     course_obj = Course.get_by_course_id("cmsc40100")
     self.assertIsNotNone(course_obj)
     
     assignment_obj = course_obj.get_assignment("pa1")
     self.assertIsNotNone(assignment_obj)
     
     rc_obj = assignment_obj.get_rubric_component_by_description("Third Task")
     self.assertIsNotNone(rc_obj, "Rubric Component was not added to database")
         
     self.assertEqual(rc_obj.description, "Third Task")
     self.assertEqual(rc_obj.points, 50)
     self.assertEqual(rc_obj.order, 3)
     
Example #9
0
 def test_create_rubric_component(self):
     c = self.get_api_client("admintoken")
     
     course = c.get_course("cmsc40100")
     assignment = course.get_assignment("pa1")
     rc = assignment.create_rubric_component(description = "Third Task",
                                             points = 50,
                                             order = 3)
     
     course_obj = Course.get_by_course_id("cmsc40100")
     self.assertIsNotNone(course_obj)
     
     assignment_obj = course_obj.get_assignment("pa1")
     self.assertIsNotNone(assignment_obj)
     
     rc_obj = assignment_obj.get_rubric_component_by_description("Third Task")
     self.assertIsNotNone(rc_obj, "Rubric Component was not added to database")
         
     self.assertEquals(rc_obj.description, "Third Task")                  
     self.assertEquals(rc_obj.points, 50)                  
     self.assertEquals(rc_obj.order, 3)                  
     
Example #10
0
    def test_complete_with_extensions_per_student(self, runner):
        course_id = u"cmsc40300"
        course_name = u"Foobarmentals of Foobar II"

        admin_id = u"admin"
        instructor_ids = [u"instructor"]
        grader_ids = [u"grader"]
        student_ids = [u"student1", u"student2", u"student3", u"student4"]

        all_users = instructor_ids + grader_ids + student_ids

        admin, instructors, graders, students = self.create_clients(
            runner,
            admin_id,
            instructor_ids,
            grader_ids,
            student_ids,
            course_id,
            verbose=True)
        self.create_users(admin, all_users)

        self.create_course(admin, course_id, course_name)

        course = Course.get_by_course_id(course_id)
        self.assertIsNotNone(course)
        self.assertEquals(course.name, course_name)

        result = admin.run(
            "admin course set-attribute %s default_extensions 3" % (course_id))
        self.assertEquals(result.exit_code, 0)

        result = admin.run(
            "admin course set-attribute %s extension_policy per-student" %
            (course_id))
        self.assertEquals(result.exit_code, 0)

        self.add_users_to_course(admin, course_id, instructors, graders,
                                 students)

        deadline = get_datetime_now_utc() - timedelta(hours=23)
        deadline = deadline.replace(tzinfo=None).isoformat(sep=" ")

        result = instructors[0].run(
            "instructor assignment add",
            ["pa1", "Programming Assignment 1", deadline])
        self.assertEquals(result.exit_code, 0)

        result = instructors[0].run("instructor assignment set-attribute",
                                    ["pa1", "max_students", "2"])
        self.assertEquals(result.exit_code, 0)

        deadline = get_datetime_now_utc() - timedelta(hours=47)
        deadline = deadline.isoformat(sep=" ")

        result = instructors[0].run(
            "instructor assignment add",
            ["pa2", "Programming Assignment 2", deadline])
        self.assertEquals(result.exit_code, 0)

        result = instructors[0].run("instructor assignment set-attribute",
                                    ["pa2", "max_students", "2"])
        self.assertEquals(result.exit_code, 0)

        deadline = get_datetime_now_utc() - timedelta(hours=47)
        deadline = deadline.isoformat(sep=" ")

        result = instructors[0].run(
            "instructor assignment add",
            ["pa3", "Programming Assignment 3", deadline])
        self.assertEquals(result.exit_code, 0)

        result = instructors[0].run("instructor assignment set-attribute",
                                    ["pa3", "max_students", "2"])
        self.assertEquals(result.exit_code, 0)

        deadline = get_datetime_now_utc() - timedelta(hours=23)
        deadline = deadline.replace(tzinfo=None).isoformat(sep=" ")

        result = instructors[0].run(
            "instructor assignment add",
            ["pa4", "Programming Assignment 4", deadline])
        self.assertEquals(result.exit_code, 0)

        result = instructors[0].run("instructor assignment set-attribute",
                                    ["pa4", "max_students", "2"])
        self.assertEquals(result.exit_code, 0)

        deadline = get_datetime_now_utc() + timedelta(hours=2)
        deadline = deadline.replace(tzinfo=None).isoformat(sep=" ")

        result = instructors[0].run(
            "instructor assignment add",
            ["pa5", "Programming Assignment 5", deadline])
        self.assertEquals(result.exit_code, 0)

        result = instructors[0].run("instructor assignment set-attribute",
                                    ["pa5", "max_students", "2"])
        self.assertEquals(result.exit_code, 0)

        teams = [
            u"student1-student2", u"student3-student4", u"student1-student3",
            u"student2-student4"
        ]

        students_team = [
            (students[0], students[1]), (students[2], students[3]),
            (students[0], students[2]), (students[1], students[3])
        ]

        self.register_team(students_team[0], teams[0], "pa1", course_id)
        self.register_team(students_team[1], teams[1], "pa2", course_id)

        team_git_paths, team_git_repos, team_commits = self.create_team_repos(
            admin, course_id, teams[0:2], students_team[0:2])

        self.register_team(students_team[2], teams[2], "pa3", course_id)
        self.register_team(students_team[2], teams[2], "pa4", course_id)
        self.register_team(students_team[2], teams[2], "pa5", course_id)
        self.register_team(students_team[3], teams[3], "pa3", course_id)
        self.register_team(students_team[3], teams[3], "pa4", course_id)
        self.register_team(students_team[3], teams[3], "pa5", course_id)

        x, y, z = self.create_team_repos(admin, course_id, teams[2:4],
                                         students_team[2:4])

        team_git_paths += x
        team_git_repos += y
        team_commits += z

        for s in students:
            result = s.run("student course show-extensions")
            self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        # Team 0 submits with one extension to pa1
        # Student 0 and 1 now have 2 extensions left each
        result = students_team[0][0].run("student assignment submit",
                                         ["pa1", "--yes"])
        self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        s1 = course.get_student(
            get_user_by_username(students_team[0][0].user_id))
        s2 = course.get_student(
            get_user_by_username(students_team[0][1].user_id))
        t = course.get_team(teams[0])

        self.assertEqual(t.get_extensions_available(), 2)
        self.assertEqual(s1.get_extensions_available(), 2)
        self.assertEqual(s2.get_extensions_available(), 2)

        for s in students:
            result = s.run("student course show-extensions")
            self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        # Team 1 submits with two extensions to pa2
        # Student 2 and 3 now have 1 extension left each
        result = students_team[1][0].run("student assignment submit",
                                         ["pa2", "--yes"])
        self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        s1 = course.get_student(
            get_user_by_username(students_team[1][0].user_id))
        s2 = course.get_student(
            get_user_by_username(students_team[1][1].user_id))
        t = course.get_team(teams[1])

        self.assertEqual(t.get_extensions_available(), 1)
        self.assertEqual(s1.get_extensions_available(), 1)
        self.assertEqual(s2.get_extensions_available(), 1)

        for s in students:
            result = s.run("student course show-extensions")
            self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        result = students_team[0][0].run("student team show", [teams[0]])
        self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        result = students_team[1][0].run("student team show", [teams[1]])
        self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        # Now we have two new teams:
        #
        # Team 2 with Student 0 and 2, with 2 and 1 extensions left respectively.
        # This team can only submit to projects requiring one extension
        #
        # Team 3 with Student 1 and 3, with 2 and 1 extensions left respectively.
        # This team can only submit to projects requiring one extension

        # Team 2 tries to submit to pa3, but they are denied because they would
        # need two extensions to submit.
        result = students_team[2][0].run("student assignment submit",
                                         ["pa3", "--yes"])
        self.assertEquals(result.exit_code, CHISUBMIT_FAIL)

        s1 = course.get_student(
            get_user_by_username(students_team[2][0].user_id))
        s2 = course.get_student(
            get_user_by_username(students_team[2][1].user_id))
        t = course.get_team(teams[2])

        self.assertEqual(t.get_extensions_available(), 1)
        self.assertEqual(s1.get_extensions_available(), 2)
        self.assertEqual(s2.get_extensions_available(), 1)

        # Team 2 tries submitting to pa4 and it goes through because it only
        # requires one extensions
        result = students_team[2][0].run("student assignment submit",
                                         ["pa4", "--yes"])
        self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        s1 = course.get_student(
            get_user_by_username(students_team[2][0].user_id))
        s2 = course.get_student(
            get_user_by_username(students_team[2][1].user_id))
        t = course.get_team(teams[2])

        self.assertEqual(t.get_extensions_available(), 0)
        self.assertEqual(s1.get_extensions_available(), 1)
        self.assertEqual(s2.get_extensions_available(), 0)

        for s in students:
            result = s.run("student course show-extensions")
            self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        # Team 2 tries submitting to pa5 with zero extensions and is accepted
        result = students_team[2][0].run("student assignment submit",
                                         ["pa5", "--yes"])
        self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        s1 = course.get_student(
            get_user_by_username(students_team[2][0].user_id))
        s2 = course.get_student(
            get_user_by_username(students_team[2][1].user_id))
        t = course.get_team(teams[2])

        self.assertEqual(t.get_extensions_available(), 0)
        self.assertEqual(s1.get_extensions_available(), 1)
        self.assertEqual(s2.get_extensions_available(), 0)

        for s in students:
            result = s.run("student course show-extensions")
            self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        # Team 3 tries submitting to pa5 and is accepted (doesn't require extensions)
        result = students_team[3][0].run("student assignment submit",
                                         ["pa5", "--yes"])
        self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        s1 = course.get_student(
            get_user_by_username(students_team[3][0].user_id))
        s2 = course.get_student(
            get_user_by_username(students_team[3][1].user_id))
        t = course.get_team(teams[3])

        self.assertEqual(t.get_extensions_available(), 1)
        self.assertEqual(s1.get_extensions_available(), 2)
        self.assertEqual(s2.get_extensions_available(), 1)

        for team, student_team in zip(teams, students_team):
            result = student_team[0].run("student team show", [team])
            self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        for s in students:
            result = s.run("student course show-extensions")
            self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)
Example #11
0
    def test_complete_with_gradescope(self, runner):
        course_id = u"cmsc40300"
        course_name = u"Foobarmentals of Foobar II"

        admin_id = u"admin"
        instructor_ids = [u"instructor"]
        grader_ids = [u"grader"]
        student_ids = [u"student1", u"student2", u"student3", u"student4"]

        all_users = instructor_ids + grader_ids + student_ids

        admin, instructors, graders, students = self.create_clients(
            runner,
            admin_id,
            instructor_ids,
            grader_ids,
            student_ids,
            course_id,
            gradescope_api_key="gradescope-testing",
            verbose=True)
        self.create_users(admin, all_users)

        self.create_course(admin, course_id, course_name)

        course = Course.get_by_course_id(course_id)
        self.assertIsNotNone(course)
        self.assertEqual(course.name, course_name)

        result = admin.run("admin course set-attribute %s gradescope_id 4242" %
                           (course_id))
        self.assertEqual(result.exit_code, 0)

        self.add_users_to_course(admin, course_id, instructors, graders,
                                 students)

        deadline = get_datetime_now_utc() + timedelta(hours=1)
        deadline = convert_datetime_to_local(deadline)
        deadline = deadline.replace(tzinfo=None).isoformat(sep=" ")

        result = instructors[0].run(
            "instructor assignment add",
            ["pa1", "Programming Assignment 1", deadline])
        self.assertEqual(result.exit_code, 0)

        result = instructors[0].run("instructor assignment set-attribute",
                                    ["pa1", "max_students", "2"])
        self.assertEqual(result.exit_code, 0)

        result = instructors[0].run("instructor assignment set-attribute",
                                    ["pa1", "gradescope_id", "3737"])
        self.assertEqual(result.exit_code, 0)

        result = instructors[0].run("instructor assignment set-attribute",
                                    ["pa1", "expected_files", "foo,b*,qux"])
        self.assertEqual(result.exit_code, 0)

        teams = [u"student1-student2", u"student3-student4"]

        students_team = [(students[0], students[1]),
                         (students[2], students[3])]

        self.register_team(students_team[0], teams[0], "pa1", course_id)
        self.register_team(students_team[1], teams[1], "pa1", course_id)

        _, _, team_commits = self.create_team_repos(admin, course_id,
                                                    teams[0:2],
                                                    students_team[0:2])

        # Team 0 and 1 submit
        result = students_team[0][0].run("student assignment submit",
                                         ["pa1", "--yes"])
        self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)

        result = students_team[1][0].run("student assignment submit",
                                         ["pa1", "--yes"])
        self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)

        for team, student_team in zip(teams, students_team):
            result = student_team[0].run("student team show", [team])
            self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)

        # Let the deadline "pass"
        new_now = get_datetime_now_utc() + timedelta(hours=2)
        set_testing_now(new_now)

        print()
        print("~~~ Time has moved 'forward' by two hours ~~~")
        print()

        # Instructor uploads to Gradescope. Both repos should be skipped
        # because we haven't created the the grading repos yet
        result = instructors[0].run("instructor grading gradescope-upload",
                                    ["--dry-run", "pa1"])
        self.assertEqual(result.exit_code, 0)

        # Instructor creates grading repos
        result = instructors[0].run("instructor grading create-grading-repos",
                                    ["--master", "pa1"])
        self.assertEqual(result.exit_code, 0)

        # Instructor uploads to Gradescope. Both repos should be skipped
        # because they're missing required file "qux"
        result = instructors[0].run("instructor grading gradescope-upload",
                                    ["--dry-run", "pa1"])
        self.assertEqual(result.exit_code, 0)

        # We change the list of expected files
        result = instructors[0].run("instructor assignment set-attribute",
                                    ["pa1", "expected_files", "foo,b*"])
        self.assertEqual(result.exit_code, 0)

        # Instructor uploads to Gradescope. Both repos should be uploaded
        # (but we're running in dry-run mode, so we don't actually contact
        # Gradescope)
        result = instructors[0].run("instructor grading gradescope-upload",
                                    ["--dry-run", "pa1"])
        self.assertEqual(result.exit_code, 0)
Example #12
0
    def test_complete_with_submission_grace_period(self, runner):
        course_id = u"cmsc40300"
        course_name = u"Foobarmentals of Foobar II"

        admin_id = u"admin"
        instructor_ids = [u"instructor"]
        grader_ids= [u"grader"]
        student_ids = [u"student1", u"student2", u"student3", u"student4"]
        
        all_users = instructor_ids + grader_ids + student_ids
        
        admin, instructors, graders, students = self.create_clients(runner, admin_id, instructor_ids, grader_ids, student_ids, course_id, verbose = True)
        self.create_users(admin, all_users)
        
        self.create_course(admin, course_id, course_name)
        
        course = Course.get_by_course_id(course_id)
        self.assertIsNotNone(course)
        self.assertEquals(course.name, course_name)        

        result = admin.run("admin course set-attribute %s default_extensions 2" % (course_id))
        self.assertEquals(result.exit_code, 0)
        
        result = admin.run("admin course set-attribute %s extension_policy per-student" % (course_id))
        self.assertEquals(result.exit_code, 0)
        
        self.add_users_to_course(admin, course_id, instructors, graders, students)
        
        deadline = get_datetime_now_utc() - timedelta(minutes=5)
        deadline = deadline.isoformat(sep=" ")

        result = instructors[0].run("instructor assignment add", 
                                    ["pa1", "Programming Assignment 1", deadline])
        self.assertEquals(result.exit_code, 0)
        
        result = instructors[0].run("instructor assignment set-attribute", 
                                    ["pa1", "max_students", "2"])
        self.assertEquals(result.exit_code, 0)        
        
        result = instructors[0].run("instructor assignment set-attribute", 
                                    ["pa1", "grace_period", "00:15"])
        self.assertEquals(result.exit_code, 0)           
            
        teams = [u"student1-student2", 
                 u"student3-student4"]        

        students_team = [ (students[0], students[1]),
                          (students[2], students[3])]
        

        self.register_team(students_team[0], teams[0], "pa1", course_id)
        self.register_team(students_team[1], teams[1], "pa1", course_id)
        
        _, _, team_commits = self.create_team_repos(admin, course_id, teams[0:2], students_team[0:2])
                
        # Team 0 submits during the grace period, and doesn't have to use an extension. 
        result = students_team[0][0].run("student assignment submit", 
                                         ["pa1", "--yes"])        
        self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)
        
        t = course.get_team(teams[0])
        
        self.assertEqual(t.get_extensions_available(), 2)
        
        
        # Let the grace period "pass"
        new_now = get_datetime_now_utc() + timedelta(minutes=11)
        set_testing_now(new_now)

        print
        print "~~~ Time has moved 'forward' to one minute after the grace period hours ~~~"
        print
        
        # Team 1 submits and has to use an extensions because the grace period is over
        result = students_team[1][0].run("student assignment submit", 
                                         ["pa1", "--yes"])        
        self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        t = course.get_team(teams[1])
        
        self.assertEqual(t.get_extensions_available(), 1)

        for team, student_team in zip(teams, students_team):
            result = student_team[0].run("student team show", [team])
            self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)
Example #13
0
    def test_complete_with_extensions_per_student(self, runner):
        course_id = u"cmsc40300"
        course_name = u"Foobarmentals of Foobar II"

        admin_id = u"admin"
        instructor_ids = [u"instructor"]
        grader_ids= [u"grader"]
        student_ids = [u"student1", u"student2", u"student3", u"student4"]
        
        all_users = instructor_ids + grader_ids + student_ids
        
        admin, instructors, graders, students = self.create_clients(runner, admin_id, instructor_ids, grader_ids, student_ids, course_id, verbose = True)
        self.create_users(admin, all_users)
                
        self.create_course(admin, course_id, course_name)

        course = Course.get_by_course_id(course_id)
        self.assertIsNotNone(course)
        self.assertEquals(course.name, course_name)

        result = admin.run("admin course set-attribute %s default_extensions 3" % (course_id))
        self.assertEquals(result.exit_code, 0)
        
        result = admin.run("admin course set-attribute %s extension_policy per-student" % (course_id))
        self.assertEquals(result.exit_code, 0)
        
        self.add_users_to_course(admin, course_id, instructors, graders, students)
        
        deadline = get_datetime_now_utc() - timedelta(hours=23)
        deadline = deadline.replace(tzinfo=None).isoformat(sep=" ")        

        result = instructors[0].run("instructor assignment add", 
                                    ["pa1", "Programming Assignment 1", deadline])
        self.assertEquals(result.exit_code, 0)

        result = instructors[0].run("instructor assignment set-attribute", 
                                    ["pa1", "max_students", "2"])
        self.assertEquals(result.exit_code, 0)

        deadline = get_datetime_now_utc() - timedelta(hours=47)
        deadline = deadline.isoformat(sep=" ")

        result = instructors[0].run("instructor assignment add", 
                                    ["pa2", "Programming Assignment 2", deadline])
        self.assertEquals(result.exit_code, 0)

        result = instructors[0].run("instructor assignment set-attribute", 
                                    ["pa2", "max_students", "2"])
        self.assertEquals(result.exit_code, 0)

        deadline = get_datetime_now_utc() - timedelta(hours=47)
        deadline = deadline.isoformat(sep=" ")

        result = instructors[0].run("instructor assignment add", 
                                    ["pa3", "Programming Assignment 3", deadline])
        self.assertEquals(result.exit_code, 0)

        result = instructors[0].run("instructor assignment set-attribute", 
                                    ["pa3", "max_students", "2"])
        self.assertEquals(result.exit_code, 0)

        deadline = get_datetime_now_utc() - timedelta(hours=23)
        deadline = deadline.replace(tzinfo=None).isoformat(sep=" ")        

        result = instructors[0].run("instructor assignment add", 
                                    ["pa4", "Programming Assignment 4", deadline])
        self.assertEquals(result.exit_code, 0)

        result = instructors[0].run("instructor assignment set-attribute", 
                                    ["pa4", "max_students", "2"])
        self.assertEquals(result.exit_code, 0)

        deadline = get_datetime_now_utc() + timedelta(hours=2)
        deadline = deadline.replace(tzinfo=None).isoformat(sep=" ")        

        result = instructors[0].run("instructor assignment add", 
                                    ["pa5", "Programming Assignment 5", deadline])
        self.assertEquals(result.exit_code, 0)

        result = instructors[0].run("instructor assignment set-attribute", 
                                    ["pa5", "max_students", "2"])
        self.assertEquals(result.exit_code, 0)
        
        
        teams = [u"student1-student2", 
                 u"student3-student4",
                 u"student1-student3",
                 u"student2-student4"]        

        students_team = [ (students[0], students[1]),
                          (students[2], students[3]),
                          (students[0], students[2]),
                          (students[1], students[3])]
        

        self.register_team(students_team[0], teams[0], "pa1", course_id)
        self.register_team(students_team[1], teams[1], "pa2", course_id)
        
        team_git_paths, team_git_repos, team_commits = self.create_team_repos(admin, course_id, teams[0:2], students_team[0:2])

        self.register_team(students_team[2], teams[2], "pa3", course_id)
        self.register_team(students_team[2], teams[2], "pa4", course_id)
        self.register_team(students_team[2], teams[2], "pa5", course_id)
        self.register_team(students_team[3], teams[3], "pa3", course_id)
        self.register_team(students_team[3], teams[3], "pa4", course_id)
        self.register_team(students_team[3], teams[3], "pa5", course_id)
        
        x, y, z = self.create_team_repos(admin, course_id, teams[2:4], students_team[2:4])
        
        team_git_paths += x
        team_git_repos += y
        team_commits += z
        
        for s in students:
            result = s.run("student course show-extensions")
            self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)        
        
        # Team 0 submits with one extension to pa1
        # Student 0 and 1 now have 2 extensions left each
        result = students_team[0][0].run("student assignment submit", 
                                         ["pa1", "--yes"])        
        self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)
        
        s1 = course.get_student(get_user_by_username(students_team[0][0].user_id))
        s2 = course.get_student(get_user_by_username(students_team[0][1].user_id))
        t = course.get_team(teams[0])
        
        self.assertEqual(t.get_extensions_available(), 2)
        self.assertEqual(s1.get_extensions_available(), 2)
        self.assertEqual(s2.get_extensions_available(), 2)

        for s in students:
            result = s.run("student course show-extensions")
            self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)
        
        # Team 1 submits with two extensions to pa2
        # Student 2 and 3 now have 1 extension left each
        result = students_team[1][0].run("student assignment submit", 
                                         ["pa2", "--yes"])        
        self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        s1 = course.get_student(get_user_by_username(students_team[1][0].user_id))
        s2 = course.get_student(get_user_by_username(students_team[1][1].user_id))
        t = course.get_team(teams[1])
        
        self.assertEqual(t.get_extensions_available(), 1)
        self.assertEqual(s1.get_extensions_available(), 1)
        self.assertEqual(s2.get_extensions_available(), 1)

        for s in students:
            result = s.run("student course show-extensions")
            self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        result = students_team[0][0].run("student team show", [teams[0]])
        self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        result = students_team[1][0].run("student team show", [teams[1]])
        self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)


        # Now we have two new teams:
        #
        # Team 2 with Student 0 and 2, with 2 and 1 extensions left respectively.
        # This team can only submit to projects requiring one extension
        # 
        # Team 3 with Student 1 and 3, with 2 and 1 extensions left respectively.
        # This team can only submit to projects requiring one extension

        # Team 2 tries to submit to pa3, but they are denied because they would 
        # need two extensions to submit.
        result = students_team[2][0].run("student assignment submit", 
                                         ["pa3", "--yes"])        
        self.assertEquals(result.exit_code, CHISUBMIT_FAIL)

        s1 = course.get_student(get_user_by_username(students_team[2][0].user_id))
        s2 = course.get_student(get_user_by_username(students_team[2][1].user_id))
        t = course.get_team(teams[2])
        
        self.assertEqual(t.get_extensions_available(), 1)
        self.assertEqual(s1.get_extensions_available(), 2)
        self.assertEqual(s2.get_extensions_available(), 1)


        # Team 2 tries submitting to pa4 and it goes through because it only
        # requires one extensions
        result = students_team[2][0].run("student assignment submit", 
                                         ["pa4", "--yes"])        
        self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        s1 = course.get_student(get_user_by_username(students_team[2][0].user_id))
        s2 = course.get_student(get_user_by_username(students_team[2][1].user_id))
        t = course.get_team(teams[2])
        
        self.assertEqual(t.get_extensions_available(), 0)
        self.assertEqual(s1.get_extensions_available(), 1)
        self.assertEqual(s2.get_extensions_available(), 0)

        for s in students:
            result = s.run("student course show-extensions")
            self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)                        

        # Team 2 tries submitting to pa5 with zero extensions and is accepted
        result = students_team[2][0].run("student assignment submit", 
                                         ["pa5", "--yes"])        
        self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)
                        
        s1 = course.get_student(get_user_by_username(students_team[2][0].user_id))
        s2 = course.get_student(get_user_by_username(students_team[2][1].user_id))
        t = course.get_team(teams[2])
        
        self.assertEqual(t.get_extensions_available(), 0)
        self.assertEqual(s1.get_extensions_available(), 1)
        self.assertEqual(s2.get_extensions_available(), 0)

        for s in students:
            result = s.run("student course show-extensions")
            self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)                        

        # Team 3 tries submitting to pa5 and is accepted (doesn't require extensions)
        result = students_team[3][0].run("student assignment submit", 
                                         ["pa5", "--yes"])        
        self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        s1 = course.get_student(get_user_by_username(students_team[3][0].user_id))
        s2 = course.get_student(get_user_by_username(students_team[3][1].user_id))
        t = course.get_team(teams[3])
        
        self.assertEqual(t.get_extensions_available(), 1)
        self.assertEqual(s1.get_extensions_available(), 2)
        self.assertEqual(s2.get_extensions_available(), 1)

        for team, student_team in zip(teams, students_team):
            result = student_team[0].run("student team show", [team])
            self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)

        for s in students:
            result = s.run("student course show-extensions")
            self.assertEquals(result.exit_code, CHISUBMIT_SUCCESS)        
Example #14
0
    def test_complete_with_registration_cancellation(self, runner):
        course_id = u"cmsc40300"
        course_name = u"Foobarmentals of Foobar II"

        admin_id = u"admin"
        instructor_ids = [u"instructor"]
        grader_ids= [u"grader"]
        student_ids = [u"student1", u"student2", u"student3", u"student4"]
        
        all_users = instructor_ids + grader_ids + student_ids
        
        admin, instructors, graders, students = self.create_clients(runner, admin_id, instructor_ids, grader_ids, student_ids, course_id, verbose = True)
        self.create_users(admin, all_users)
        
        self.create_course(admin, course_id, course_name)
        
        course = Course.get_by_course_id(course_id)
        self.assertIsNotNone(course)
        self.assertEqual(course.name, course_name)

        result = admin.run("admin course set-attribute %s default_extensions 2" % (course_id))
        self.assertEqual(result.exit_code, 0)
        
        result = admin.run("admin course set-attribute %s extension_policy per-student" % (course_id))
        self.assertEqual(result.exit_code, 0)
        
        self.add_users_to_course(admin, course_id, instructors, graders, students)
        
        deadline = get_datetime_now_utc() - timedelta(minutes=5)
        deadline = deadline.isoformat(sep=" ")

        result = instructors[0].run("instructor assignment add", 
                                    ["pa1", "Programming Assignment 1", deadline])
        self.assertEqual(result.exit_code, 0)
        
        result = instructors[0].run("instructor assignment set-attribute", 
                                    ["pa1", "max_students", "2"])
        self.assertEqual(result.exit_code, 0)
            
        teams = [u"student1-student2", 
                 u"student3-student4"]        

        students_team = [ (students[0], students[1]),
                          (students[2], students[3])]
        

        self.register_team(students_team[0], teams[0], "pa1", course_id)
        self.register_team(students_team[1], teams[1], "pa1", course_id)
        
        _, _, team_commits = self.create_team_repos(admin, course_id, teams[0:2], students_team[0:2])
                
        # Team 0 cancels their registration, which they can do because they haven't submitted yet. 
        result = students_team[0][0].run("student assignment cancel-registration", 
                                         ["pa1", "--yes"])        
        self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)
        
        # Team 0 tries to cancel their registration again, which doesn't work. There's nothing to cancel.
        result = students_team[0][0].run("student assignment cancel-registration", 
                                         ["pa1", "--yes"])        
        self.assertEqual(result.exit_code, CHISUBMIT_FAIL)
        
        # Team 0 registers again     
        result = students_team[0][0].run("student assignment register", 
                                         ["pa1", "--partner", students_team[0][1].user_id])        
        self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)
        
        # Team 1 submits.
        result = students_team[1][0].run("student assignment submit", 
                                         ["pa1", "--yes"])        
        self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)

        # Team 1 tries to cancel their registration, which doesn't work. They have a submission.
        result = students_team[1][0].run("student assignment cancel-registration", 
                                         ["pa1", "--yes"])        
        self.assertEqual(result.exit_code, CHISUBMIT_FAIL)

        # Team 1 cancels their submission
        result = students_team[1][0].run("student assignment cancel-submit", 
                                         ["pa1", "--yes"])        
        self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)

        # Team 1 can now cancel their registration.
        result = students_team[1][0].run("student assignment cancel-registration", 
                                         ["pa1", "--yes"])        
        self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)


        for team, student_team in zip(teams, students_team):
            result = student_team[0].run("student team show", [team])
            self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)
Example #15
0
    def test_complete_with_registration_cancellation(self, runner):
        course_id = u"cmsc40300"
        course_name = u"Foobarmentals of Foobar II"

        admin_id = u"admin"
        instructor_ids = [u"instructor"]
        grader_ids = [u"grader"]
        student_ids = [u"student1", u"student2", u"student3", u"student4"]

        all_users = instructor_ids + grader_ids + student_ids

        admin, instructors, graders, students = self.create_clients(
            runner,
            admin_id,
            instructor_ids,
            grader_ids,
            student_ids,
            course_id,
            verbose=True)
        self.create_users(admin, all_users)

        self.create_course(admin, course_id, course_name)

        course = Course.get_by_course_id(course_id)
        self.assertIsNotNone(course)
        self.assertEqual(course.name, course_name)

        result = admin.run(
            "admin course set-attribute %s default_extensions 2" % (course_id))
        self.assertEqual(result.exit_code, 0)

        result = admin.run(
            "admin course set-attribute %s extension_policy per-student" %
            (course_id))
        self.assertEqual(result.exit_code, 0)

        self.add_users_to_course(admin, course_id, instructors, graders,
                                 students)

        deadline = get_datetime_now_utc() - timedelta(minutes=5)
        deadline = deadline.isoformat(sep=" ")

        result = instructors[0].run(
            "instructor assignment add",
            ["pa1", "Programming Assignment 1", deadline])
        self.assertEqual(result.exit_code, 0)

        result = instructors[0].run("instructor assignment set-attribute",
                                    ["pa1", "max_students", "2"])
        self.assertEqual(result.exit_code, 0)

        teams = [u"student1-student2", u"student3-student4"]

        students_team = [(students[0], students[1]),
                         (students[2], students[3])]

        self.register_team(students_team[0], teams[0], "pa1", course_id)
        self.register_team(students_team[1], teams[1], "pa1", course_id)

        _, _, team_commits = self.create_team_repos(admin, course_id,
                                                    teams[0:2],
                                                    students_team[0:2])

        # Team 0 cancels their registration, which they can do because they haven't submitted yet.
        result = students_team[0][0].run(
            "student assignment cancel-registration", ["pa1", "--yes"])
        self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)

        # Team 0 tries to cancel their registration again, which doesn't work. There's nothing to cancel.
        result = students_team[0][0].run(
            "student assignment cancel-registration", ["pa1", "--yes"])
        self.assertEqual(result.exit_code, CHISUBMIT_FAIL)

        # Team 0 registers again
        result = students_team[0][0].run(
            "student assignment register",
            ["pa1", "--partner", students_team[0][1].user_id])
        self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)

        # Team 1 submits.
        result = students_team[1][0].run("student assignment submit",
                                         ["pa1", "--yes"])
        self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)

        # Team 1 tries to cancel their registration, which doesn't work. They have a submission.
        result = students_team[1][0].run(
            "student assignment cancel-registration", ["pa1", "--yes"])
        self.assertEqual(result.exit_code, CHISUBMIT_FAIL)

        # Team 1 cancels their submission
        result = students_team[1][0].run("student assignment cancel-submit",
                                         ["pa1", "--yes"])
        self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)

        # Team 1 can now cancel their registration.
        result = students_team[1][0].run(
            "student assignment cancel-registration", ["pa1", "--yes"])
        self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)

        for team, student_team in zip(teams, students_team):
            result = student_team[0].run("student team show", [team])
            self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)
Example #16
0
    def test_complete_with_submission_grace_period(self, runner):
        course_id = u"cmsc40300"
        course_name = u"Foobarmentals of Foobar II"

        admin_id = u"admin"
        instructor_ids = [u"instructor"]
        grader_ids = [u"grader"]
        student_ids = [u"student1", u"student2", u"student3", u"student4"]

        all_users = instructor_ids + grader_ids + student_ids

        admin, instructors, graders, students = self.create_clients(
            runner,
            admin_id,
            instructor_ids,
            grader_ids,
            student_ids,
            course_id,
            verbose=True)
        self.create_users(admin, all_users)

        self.create_course(admin, course_id, course_name)

        course = Course.get_by_course_id(course_id)
        self.assertIsNotNone(course)
        self.assertEqual(course.name, course_name)

        result = admin.run(
            "admin course set-attribute %s default_extensions 2" % (course_id))
        self.assertEqual(result.exit_code, 0)

        result = admin.run(
            "admin course set-attribute %s extension_policy per-student" %
            (course_id))
        self.assertEqual(result.exit_code, 0)

        self.add_users_to_course(admin, course_id, instructors, graders,
                                 students)

        deadline = get_datetime_now_utc() - timedelta(minutes=5)
        deadline = deadline.isoformat(sep=" ")

        result = instructors[0].run(
            "instructor assignment add",
            ["pa1", "Programming Assignment 1", deadline])
        self.assertEqual(result.exit_code, 0)

        result = instructors[0].run("instructor assignment set-attribute",
                                    ["pa1", "max_students", "2"])
        self.assertEqual(result.exit_code, 0)

        result = instructors[0].run("instructor assignment set-attribute",
                                    ["pa1", "grace_period", "00:15"])
        self.assertEqual(result.exit_code, 0)

        teams = [u"student1-student2", u"student3-student4"]

        students_team = [(students[0], students[1]),
                         (students[2], students[3])]

        self.register_team(students_team[0], teams[0], "pa1", course_id)
        self.register_team(students_team[1], teams[1], "pa1", course_id)

        _, _, team_commits = self.create_team_repos(admin, course_id,
                                                    teams[0:2],
                                                    students_team[0:2])

        # Team 0 submits during the grace period, and doesn't have to use an extension.
        result = students_team[0][0].run("student assignment submit",
                                         ["pa1", "--yes"])
        self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)

        t = course.get_team(teams[0])

        self.assertEqual(t.get_extensions_available(), 2)

        # Let the grace period "pass"
        new_now = get_datetime_now_utc() + timedelta(minutes=11)
        set_testing_now(new_now)

        print()
        print(
            "~~~ Time has moved 'forward' to one minute after the grace period hours ~~~"
        )
        print()

        # Team 1 submits and has to use an extensions because the grace period is over
        result = students_team[1][0].run("student assignment submit",
                                         ["pa1", "--yes"])
        self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)

        t = course.get_team(teams[1])

        self.assertEqual(t.get_extensions_available(), 1)

        for team, student_team in zip(teams, students_team):
            result = student_team[0].run("student team show", [team])
            self.assertEqual(result.exit_code, CHISUBMIT_SUCCESS)