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
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