def compile(self): # If any files are missing then return failure of compilation. Appropriate program result is created. if self.fileExist(): return False # If the language of the section/assignment needs compilation, then go ahead and compile. Set program result attributes accordingly. # If compilation is not needed then proceed. if compile_required(self.language): compilation_command = self.compiler_command self.compileResult = self.commandExecutor.executeCommand( command=compilation_command) attrs = { 'missing_file_names': "\n".join(self.missingFiles), 'compiler_errors': "".join(self.compileResult.stderr), 'compiler_output': "\n".join(self.compileResult.get_stdout()), 'compiler_return_code': int(self.compileResult.returnCode) } else: attrs = { 'missing_file_names': "\n".join(self.missingFiles), 'compiler_errors': "", 'compiler_output': "", 'compiler_return_code': 0 } filter_attrs = { 'assignment_result': self.assignment_result, 'program': self.program } # Create or update program result object with the result of compilation process for the section. The attributes of the program result object # are the same as the result of the compilation process. try: # create_or_update equivalent. obj = ProgramResults.objects.filter(**filter_attrs) obj.update(**attrs) self.programResult = obj[0:1].get() except ProgramResults.DoesNotExist: attrs.update(filter_attrs) self.programResult = ProgramResults.objects.create(**attrs) # If compilation is successful or if compilation is not needed then return true. Else return false. if compile_required( self.language) == False or self.compileResult.returnCode == 0: return True else: return False
def compile(self): # If any files are missing then return failure of compilation. Appropriate program result is created. if self.fileExist(): return False # If the language of the section/assignment needs compilation, then go ahead and compile. Set program result attributes accordingly. # If compilation is not needed then proceed. if compile_required(self.language): compilation_command = self.compiler_command self.compileResult = self.commandExecutor.executeCommand(command=compilation_command) attrs = {'missing_file_names': "\n".join(self.missingFiles), 'compiler_errors': "".join(self.compileResult.stderr), 'compiler_output': "\n".join(self.compileResult.get_stdout()), 'compiler_return_code': int(self.compileResult.returnCode)} else: attrs = {'missing_file_names': "\n".join(self.missingFiles), 'compiler_errors': "", 'compiler_output': "", 'compiler_return_code': 0} filter_attrs = {'assignment_result': self.assignment_result, 'program': self.program} # Create or update program result object with the result of compilation process for the section. The attributes of the program result object # are the same as the result of the compilation process. try: # create_or_update equivalent. obj = ProgramResults.objects.filter(**filter_attrs) obj.update(**attrs) self.programResult = obj[0:1].get() except ProgramResults.DoesNotExist: attrs.update(filter_attrs) self.programResult = ProgramResults.objects.create(**attrs) # If compilation is successful or if compilation is not needed then return true. Else return false. if compile_required(self.language) == False or self.compileResult.returnCode == 0: return True else: return False
def run(self): # Compile the solution. If there are errors then write it to the error file and return if compile_required(self.program.language): compiler_command = get_compilation_command(self.program) print "Compiling model solution. Compilation Command - " + compiler_command self.command_output = self.commandExecutor.safe_execute( command=compiler_command, limits=self.get_resource_limit() ) if self.command_output.getReturnCode(): # There was some error. Write it in database. print "Compilation of model solution failed." self.failed = True _, self.error_file = tempfile.mkstemp(prefix="error", dir=self.temp_input_d) f = open(self.error_file, 'w') for a_line in self.command_output.get_stderr(): f.write(a_line) f.close() return # No errors and thus can continue. Run the solution execution_command = get_execution_command(self.program) print "Creating Output. Running following execution command - " + execution_command #if self.testcase.command_line_args: # execution_command = execution_command + self.testcase.command_line_args if self.testcase.std_in_file_name: execution_command = execution_command + " < " + self.testcase.std_in_file_name self.command_output = self.commandExecutor.safe_execute( command=execution_command, limits=self.get_resource_limit() ) self.success = bool(self.command_output.getReturnCode()) self.command_output.printResult() # Delete input files from current directory. And the program files dir_content = os.listdir('./') for a_file in dir_content: if self.is_program_file(a_file): os.remove(a_file) if self.input: for a_file in get_file_name_list(name=self.input): # delete extracted files if os.path.isfile(a_file): os.remove(a_file) # Write standard output to a file and save it in database. directory_content = os.listdir('./') _, self.std_out_file = tempfile.mkstemp(prefix='output', dir="./") out_file = open(self.std_out_file, 'w') for a_line in ["\n".join(self.command_output.get_stdout())]: out_file.write(a_line) out_file.close() # There was some error. Write it in database. if self.command_output.getReturnCode(): self.failed = True _, self.error_file = tempfile.mkstemp(prefix="error", dir=self.temp_input_d) f = open(self.error_file, 'w') for a_line in self.command_output.get_stderr(): f.write(a_line) f.close() # If directory has any content left then make a tar, else set the outfile to the output file. if directory_content: # make a tar self.out_file = self.make_tar(directory_content + [self.std_out_file], self.std_out_file) else: # there are no other files standard output only. self.out_file = self.std_out_file
def run(self): # Compile the solution. If there are errors then write it to the error file and return if compile_required(self.program.language): compiler_command = get_compilation_command(self.program) print "Compiling model solution. Compilation Command - " + compiler_command self.command_output = self.commandExecutor.safe_execute( command=compiler_command, limits=self.get_resource_limit()) if self.command_output.getReturnCode(): # There was some error. Write it in database. print "Compilation of model solution failed." self.failed = True _, self.error_file = tempfile.mkstemp(prefix="error", dir=self.temp_input_d) f = open(self.error_file, 'w') for a_line in self.command_output.get_stderr(): f.write(a_line) f.close() return # No errors and thus can continue. Run the solution execution_command = get_execution_command(self.program) print "Creating Output. Running following execution command - " + execution_command #if self.testcase.command_line_args: # execution_command = execution_command + self.testcase.command_line_args if self.testcase.std_in_file_name: execution_command = execution_command + " < " + self.testcase.std_in_file_name self.command_output = self.commandExecutor.safe_execute( command=execution_command, limits=self.get_resource_limit()) self.success = bool(self.command_output.getReturnCode()) self.command_output.printResult() # Delete input files from current directory. And the program files dir_content = os.listdir('./') for a_file in dir_content: if self.is_program_file(a_file): os.remove(a_file) if self.input: for a_file in get_file_name_list( name=self.input): # delete extracted files if os.path.isfile(a_file): os.remove(a_file) # Write standard output to a file and save it in database. directory_content = os.listdir('./') _, self.std_out_file = tempfile.mkstemp(prefix='output', dir="./") out_file = open(self.std_out_file, 'w') for a_line in ["\n".join(self.command_output.get_stdout())]: out_file.write(a_line) out_file.close() # There was some error. Write it in database. if self.command_output.getReturnCode(): self.failed = True _, self.error_file = tempfile.mkstemp(prefix="error", dir=self.temp_input_d) f = open(self.error_file, 'w') for a_line in self.command_output.get_stderr(): f.write(a_line) f.close() # If directory has any content left then make a tar, else set the outfile to the output file. if directory_content: # make a tar self.out_file = self.make_tar( directory_content + [self.std_out_file], self.std_out_file) else: # there are no other files standard output only. self.out_file = self.std_out_file
def compile_solution(sender, instance, **kwargs): # If the program language is an interpreted language, then we dont do anything if not compile_required(instance.assignment.program_language) and not getattr(instance, 'execute_now', False): instance.set_sane() instance.delete_error_message() return if not compile_required(instance.assignment.program_language) : old_pwd = os.getcwd() instance.set_sane() instance.UpdateOutput() instance.delete_error_message() os.chdir(old_pwd) return # instance.id would indicate that record was not created. if not getattr(instance, 'compile_now', False) or instance.id is None: return # If solution is given then set the path, else do nothing programFilePath = instance.program_files.name if hasattr(instance.assignment.model_solution, 'file'): ModelSolutionPath = instance.assignment.model_solution.file.name else: instance.set_sane() instance.delete_error_message() return # Model Solution was not provided hence do nothing. if not os.path.isfile(ModelSolutionPath): return # Copying module solution to a temp directory for compilation tmp_dir = tempfile.mkdtemp(prefix='grader') old_pwd = os.getcwd() os.chdir(tmp_dir) currentDir = os.getcwd() try: # Copy model solution to temp directory. with Archive(fileobj=instance.assignment.model_solution.file) as archive: if archive.is_archive(): archive.extract(dest=currentDir) else: shutil.copy(src=os.path.join(MEDIA_ROOT, ModelSolutionPath), dst=currentDir) # Change directory if solution tar contains a directory. directories = [a for a in os.listdir('./') if os.path.isdir(a)] if directories: os.chdir(directories[0]) currentDir = os.getcwd() # Copying the program files to the current directory if instance.program_files: with Archive(name=instance.program_files.file.name) as archive: if archive.is_archive(): archive.extract(dest=currentDir) else: shutil.copy(src=os.path.join(MEDIA_ROOT, programFilePath), dst=currentDir) # Setting up compilation process and calling the CommandExecutor with appropriate command executor = CommandExecutor(timeout=100) compiler_command = get_compilation_command(instance) compileResult = executor.executeCommand(command=compiler_command) # Compilation successful => Set the program to sane and delete errors, else report the errors. if compileResult.returnCode == 0: # save exe file on success. instance.is_sane = True instance.UpdateOutput() instance.delete_error_message() else: message = "Compilation failed.\nReturn code = {0}.\nError message={1}".format(compileResult.returnCode, "".join(compileResult.stderr)) print "Instructor solution not sane - " + message instance.save_error(message) shutil.rmtree(tmp_dir) finally: os.chdir(old_pwd)