Example #1
0
    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
Example #2
0
    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
Example #3
0
    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
Example #4
0
    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
Example #5
0
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)