def HandleFile(Job, InputFileName, CorrectOutputFileName, ProblemDict): #FileNameToRun, SystemSuppliedFileList=None):
    '''
    Process one student's submission on one set of input data.
    Parameters:
        Job: The named tuple containing, among other things, the files submitted by the student and their contents. 
        InputFileName: The name (including path if needed) of the ONE file with sample input for this test.
        CorrectOutputFileName: The name (including path if needed) of the ONE file with correct output for
            the specified input.
        FileNameToRun: The name (excluding path) of the ONE file that is to run 
          to test the student's code. This must be present in Job or 
          SystemSuppliedFileList.
        SystemSuppliedFileList: The (possibly empty or missing) list of other   
          files (including paths) which are needed to run this problem's code 
          (class files, driver programs, etc)
    Returns:
        tuple of strings (Res, Err). Res is a brief description ('Correct', 
          'Runtime exceeded', etc), and Err is an error message (possibly empty 
          string).
    ''' 
    # set up some labels for later (exit codes)
    ExitMsg = {1:'Translation Error', 2:'Time Limit Exceeded', 3:'Windows Error', \
               4:'Excessive Output', 5:'Submission Error'}

    # Make sure we've got everything we're expecting; if we don't, skip all this. 
    ExpectedFiles = [Filename for (Filename, contents) in Job.Files] 
    try:
        ExpectedFiles += ProblemDict['Extras'] # SystemSuppliedFileList
    except (TypeError, KeyError):  # if there was no list of other needed files. 
        pass
    Expected = [os.path.basename(name).lower().strip() for name in ExpectedFiles]
    if os.path.basename(ProblemDict['Run']).lower().strip() not in Expected:
        Res = "File " + ProblemDict['Run'] + " was expected, but not found."
        Err = ExitMsg[5]
        return Err, Res  
    # even if we're going ahead, we can free up some memory
    del(ExpectedFiles)
    del(Expected)
        
    # Create working (temporary) directory, copy files into it
    ProblemDict['WritePath'] = os.path.dirname(ProblemDict['FileToRun']) #FileNameToRun)

    try: 
        for f in Job.Files:
            Fname = f[0]
            Code = f[1]
            open(ProblemDict['WritePath']+'/'+os.path.basename(Fname),'w').write(Code)
  
        if ProblemDict['Extras']: # SystemSuppliedFileList:
            for f in ProblemDict['Extras']:
                Code = open(f).read()
                open(ProblemDict['WritePath']+'/'+os.path.basename(f),'w').write(Code)
                
    except IOError:
        return ('SystemError', 'Contact Administrator or Instructor')
        
    # Setup I/O for program we're testing. 
    Input = open(InputFileName).read()
    os.chdir(ProblemDict['WritePath'])
    open(os.path.join(ProblemDict['WritePath'], 'input.txt'),'w').write(Input)
    
    In = open('input.txt')
    Out = open('output.txt', 'w')
    Err = open('error.txt', 'w')

    # Run that sucker!
    try:
        ExitCode = winprocess.run('python %s' % ProblemDict['Run'], stdin=In, \
                                  stdout=Out, stderr=Err, mSec=5000, desktop='')
    except WindowsError, msg:
        if 'timeout exceeded' in str(msg):
            ExitCode = 2 # time out
        else:
            ExitCode = 3  # some other Windows error
Beispiel #2
0
def HandleFile(CodeFileNameList, InputFileName, CorrectOutputFileName, FileNameToRun, SystemSuppliedFileList=None):
    '''
    Process one student's submission on one set of input data.
    Parameters:
        CodeFileNameList: The non-empty list of files submitted by the student.
        InputFileName: The name (including path if needed) of the ONE file with sample input for this test.
        CorrectOutputFileName: The name (including path if needed) of the ONE file with correct output for
            the specified input.
        FileNameToRun: The name (excluding path) of the ONE file that is to run to test the student's code.
            This must be present in CodeFileNameList or SystemSuppliedFileList.
        SystemSuppliedFileList: The (possibly empty or missing) list of other files (including paths) which
            are needed to run this problem's code (class files, driver programs, etc)
    Returns:
        tuple of strings (Res, Err). Res is a brief description ('Correct', 'Runtime exceeded', etc), and
            Err is an error message (possibly empty string).
    ''' 
    # set up some labels for later (exit codes)
    ExitMsg = {1:'Translation Error', 2:'Time Limit Exceeded', 3:'Windows Error', \
               4:'Excessive Output', 5:'Submission Error'}

    # Make sure we've got everything we're expecting; if we don't, skip all this. 
    ExpectedFiles = CodeFileNameList[:]
    try:
        ExpectedFiles += SystemSuppliedFileList
    except TypeError:  # if there was no list of other needed files. 
        pass
    Expected = [os.path.basename(name).lower() for name in ExpectedFiles]
    if os.path.basename(FileNameToRun).lower().strip() not in Expected:
        Res = "File " + FileNameToRun + " was expected, but not found."
        Err = ExitMsg[5]
        return Res, Err
    # even if we're going ahead, we can free up some memory
    del(ExpectedFiles)
    del(Expected)
    
    # Goose the random number generator just a bit, to be sure every process
    # generates different temporary names.
    #random.jumpahead(os.getpid())
        
    # Create working (temporary) directory, copy files into it
    StartPath = os.getcwd()
    #TmpDir = autograde_utilities.TempName()
    #os.mkdir(TmpDir)

    ReadPath = StartPath
    WritePath = os.path.dirname(FileNameToRun)

    try: 
        for f in CodeFileNameList:
            Code = open(f).read()
            open(WritePath+'/'+os.path.basename(f),'w').write(Code)
  
        if SystemSuppliedFileList:
            for f in SystemSuppliedFileList:
                Code = open(f).read()
                open(WritePath+'/'+os.path.basename(f),'w').write(Code)
                
    except IOError:
        #print "System Error. Can't copy necessary file. Contact administrator"
        # try to clean up 
        autograde_utilities.Cleanup(WritePath)
        os.chdir(StartPath)
        #os.rmdir(WritePath)
        return ('SystemError', 'Contact Administrator or Instructor')
        
    # Setup I/O for program we're testing. 
    Input = open(InputFileName).read()
    os.chdir(WritePath)
    open('input.txt','w').write(Input)

##    TODO: Pipes are more efficient, as they spare the disk operations. Therefore pipes to
##    connect to stdout and stderr of the child process would be more efficient. Given that we're
##    waiting 5 seconds for the process to run, this isn't a huge deal, but may become a factor if
##    we need to scale this up to higher capacity.
    
    In = open('input.txt')
    Out = open('output.txt', 'w')
    Err = open('error.txt', 'w')

    # Run that sucker!
    try:
        ExitCode = winprocess.run('notepad.exe',login='******', desktop='')
        #ExitCode = winprocess.run('python %s' % FileNameToRun, stdin=In, stdout=Out, stderr=Err, mSec=5000,login='******', desktop='')
    except WindowsError, msg:
        if 'timeout exceeded' in str(msg):
            ExitCode = 2 # time out
        else:
            ExitCode = 3  # some other Windows error