Пример #1
0
def submit_assignment(assignment_config):
    """Submits config file for evaluation.

    This function creates a zip archive, stores it in
    $VMCHECKER_ROOT/unchecked/ directory and calls submit
    script.

    The archive contains:
        config - assignment config (eg. name, time of submission etc)
        global - global assignments config (eg. deadlines)
        archive.zip - a zip containing the homework
        callback - a script executed by the tester to send results back

    """
    assignment_config = abspath(assignment_config)

    # reads user, assignment and course
    aconfig = ConfigParser.RawConfigParser()
    with open(assignment_config) as handler:
        aconfig.readfp(handler)

    user = aconfig.get('Assignment', 'User')
    assignment = aconfig.get('Assignment', 'Assignment')
    course = config.get(assignment, 'Course')

    # location of student's homework
    archive = join(dirname(assignment_config), 'archive.zip')
    assert isfile(archive), "Missing archive `%s'" % archive

    # location of tests
    tests = join(vmcheckerpaths.dir_tests(), assignment + '.zip')
    assert isfile(tests), "Missing tests `%s'" % tests

    # builds archive with configuration
    with _Locker(assignment):
        # creates the zip archive with an unique name
        fd = mkstemp(
                suffix='.zip',
                prefix='%s_%s_%s_' % (course, assignment, user),
                dir=vmcheckerpaths.dir_unchecked())
        _logger.info("Creating zip package at `%s'", fd[1])

        # populates the archive
        # Includes at least these files:
        #   config -> homework config (see above)
        #   archive.zip -> homework files (student's sources)
        #   tests.zip -> assignment tests
        try:
            with os.fdopen(fd[0], 'w+b') as handler:
                zip = ZipFile(handler, 'w')
                zip.write(assignment_config, 'config')   # assignment config
                zip.write(archive, 'archive.zip')        # assignment archive
                zip.write(tests, 'tests.zip')            # the archive containing tests

                # includes extra required files
                for f in config.get(assignment):
                    if not f.startswith('include '):
                        continue

                    dst, src = f[8:], config.get(assignment, f)
                    src = vmcheckerpaths.abspath(src)
                    assert isfile(src), "`%s' is missing" % src

                    zip.write(src, dst)
                    _logger.debug("Included `%s' as `%s'.", src, dst)

                zip.close()
        except:
            _logger.error("Failed to create archive `%s'", fd[1])
            os.unlink(fd[1])
            raise

        # sends homework to tester
        submit = vmcheckerpaths.abspath(config.get(assignment, 'Submit'))
        _logger.info('Calling submission script %s', submit)
        try:
            check_call((submit, fd[1]))
        except:
            _logger.fatal("Cannot submit homework. Archive `%s' not deleted.", fd[1])
            raise
Пример #2
0
def submit_homework(location):
    """Submits homework at location for evaluation

    This function creates a zip archive in the ./unchecked/
    directory and calls the submit script.

    The archive contains:
        config - assignment config (eg. name, time of submission etc)
        archive.zip - a zip containing the homework
        tests.zip - a zip containing the tests
        callback - a script executed by the tester to send results back
        ... - assignment's extra files (see assignments.Assignments.include())

    """
    # reads user, assignment and course
    # hrc = homework resource configuration
    hrc = ConfigParser.RawConfigParser()
    with open(os.path.join(location, "config")) as handler:
        hrc.readfp(handler)

    assignment = hrc.get("Assignment", "Assignment")
    user = hrc.get("Assignment", "User")
    course = config.assignments.course(assignment)

    # location of student's homework
    # XXX should create a clean zip from the repository
    archive = os.path.join(location, "archive.zip")
    assert os.path.isfile(archive), "Missing archive %s" % archive

    # location of tests
    tests = config.assignments.tests(assignment)
    assert os.path.isfile(tests), "Missing tests %s" % tests

    # builds archive with configuration
    with config.assignments.lock(assignment):
        # creates the zip archive with an unique name
        fd = tempfile.mkstemp(
            suffix=".zip", prefix="%s_%s_%s_" % (course, assignment, user), dir=vmcheckerpaths.dir_unchecked()
        )  # FIXME not here
        _logger.info("Creating zip package %s", fd[1])

        # populates the archive (see the function's docstring)
        try:
            with os.fdopen(fd[0], "w+b") as handler:
                zip_ = zipfile.ZipFile(handler, "w")
                zip_.write(os.path.join(location, "config"), "config")
                zip_.write(archive, "archive.zip")
                zip_.write(tests, "tests.zip")

                # includes extra required files
                for dest, src in config.assignments.include(assignment):
                    src = vmcheckerpaths.abspath(src)

                    # XXX do not assert, but raise
                    assert os.path.isfile(src), "File %s is missing" % src

                    zip_.write(src, dest)
                    _logger.debug("Included %s as %s", src, dest)

                zip_.close()
        except:
            _logger.error("Failed to create zip archive %s", fd[1])
            os.unlink(fd[1])
            raise

    # package created, sends homework to tester by invoking submission script
    submit = config.assignments.get(assignment, "Submit")
    submit = vmcheckerpaths.abspath(submit)
    _logger.info("Invoking submission script %s", submit)
    try:
        subprocess.check_call((submit, fd[1]))
    except:
        _logger.fatal("Cannot submit homework %s, %s", assignment, user)
        os.unlink(fd[1])
        raise