def run(self, env): thys = map (lambda (name,_): ('%s' % os.path.splitext(name)[0]), env.sources()) additional_thys = ['%s' % name for name in re.split(" |,",self.additional_theories) if name] user_thys = filter (lambda name: name not in additional_thys, thys) platform = execute_arglist([settings.ISABELLE_BINARY, "getenv", "ML_PLATFORM"], env.tmpdir(), timeout=10, error_to_output=False)[0] args = [settings.ISABELLE_BINARY,"process"] # Depending on the underlying polyml platform (32/64 bit) we use 2 or 1 threads, resp. # This is due to the default memory limit (1gb) of safe-docker and the # default initial heap sizes of 500m and 1000m for 32 bit and 64 bit, resp. if "x86_64-linux" in platform: args += ["-o", "threads=1"] else: args += ["-o", "threads=2"] for t in additional_thys + user_thys: args += ["-T", t] args += ["-l", self.logic] (output, error, exitcode, timed_out, oom_ed) = execute_arglist(args, env.tmpdir(),timeout=settings.TEST_TIMEOUT, error_to_output=False) if timed_out: output += "\n\n---- check aborted after %d seconds ----\n" % settings.TEST_TIMEOUT if oom_ed: output += "\n\n---- check aborted, out of memory ----\n" result = self.create_result(env) result.set_log('<pre>' + escape(output) + '</pre>') result.set_passed(not timed_out and not oom_ed and self.output_ok(output)) return result
def compile_make(self, env): # compile CMakeLists.txt if os.path.exists(env.tmpdir() + '/CMakeLists.txt'): logger.debug('cmakefile found, execute cmake') # cmake . # cmake --build . [output, error, exitcode, timed_out, oom_ed] = execute_arglist(['cmake', '.'], env.tmpdir(), unsafe=True) if exitcode != 0: return self.handle_compile_error(env, output, error, timed_out, oom_ed) [output, error, exitcode, timed_out, oom_ed] = execute_arglist(['cmake', '--build', '.'], env.tmpdir(), unsafe=True) if exitcode != 0: return self.handle_compile_error(env, output, error, timed_out, oom_ed) else: # run make logger.debug('make') [output, error, exitcode, timed_out, oom_ed] = execute_arglist(['make'], env.tmpdir(), unsafe=True) if exitcode != 0: # suppress as much information as possible # call make twice in order to get only errors in student code [output, error, exitcode, timed_out, oom_ed] = execute_arglist(['make'], env.tmpdir(), unsafe=True) if error != None: # delete output when error text exists because output contains a lot of irrelevant information # for student # logger.error(error) output = error error = '' return self.handle_compile_error(env, output, error, timed_out, oom_ed) return True
def run(self, env): # Find out the path to isabaelle-process args = [settings.ISABELLE_BINARY, "getenv", "-b", "ISABELLE_PROCESS"] (output, error, exitcode, _) = execute_arglist(args, env.tmpdir()) isabelle_process = output.rstrip() thys = map (lambda (name,_): ('"%s"' % os.path.splitext(name)[0]), env.sources()) ml_cmd = 'Secure.set_secure (); use_thys [%s]' % ','.join(thys) args = [isabelle_process, "-r", "-q", "-e", ml_cmd, self.logic] (output, error, exitcode, timed_out, oom_ed) = execute_arglist(args, env.tmpdir(),timeout=settings.TEST_TIMEOUT) if timed_out: output += "\n\n---- check aborted after %d seconds ----\n" % settings.TEST_TIMEOUT if oom_ed: output += "\n\n---- check aborted, out of memory ----\n" result = self.create_result(env) result.set_log('<pre>' + escape(output) + '</pre>') result.set_passed(not timed_out and not oom_ed and not self.output_ok(output)) return result
def run(self, env): # Save save check configuration config_path = os.path.join(env.tmpdir(), "checks.xml") copy_file(self.configuration.path, config_path) # Run the tests args = [settings.JVM, "-cp", settings.CHECKSTYLEALLJAR, "-Dbasedir=.", "com.puppycrawl.tools.checkstyle.Main", "-c", "checks.xml"] + [name for (name,content) in env.sources()] [output, error, exitcode,timed_out, oom_ed] = execute_arglist(args, env.tmpdir()) # Remove Praktomat-Path-Prefixes from result: output = re.sub(r"^"+re.escape(env.tmpdir())+"/+","",output,flags=re.MULTILINE) result = self.create_result(env) log = '<pre>' + escape(output) + '</pre>' if timed_out: log = log + '<div class="error">Timeout occured!</div>' if oom_ed: log = log + '<div class="error">Out of memory!</div>' result.set_log(log) result.set_passed(not timed_out and not oom_ed and not exitcode and (not re.match('Starting audit...\nAudit done.', output) == None)) return result
def main_module(self, env): """ find the first class file containing a main method """ main_method = re.compile( r"^public static void main\(java.lang.String\[\]\)$", re.MULTILINE) main_method = "public static void main(java.lang.String[])" class_name = re.compile( r"^(public )?(abstract )?(final )?class ([^ ]*) extends .*$", re.MULTILINE) class_files = [] for dirpath, dirs, files in os.walk(env.tmpdir()): for filename in files: if filename.endswith(".class"): class_files.append(filename) [classinfo, _, _, _, _] = execute_arglist([ settings.JCLASSINFO, "--methods", "--general-info", os.path.join(dirpath, filename) ], env.tmpdir(), self.environment(), unsafe=True) if string.find(classinfo, main_method) >= 0: main_class_name = class_name.search( classinfo, re.MULTILINE).group(4) return main_class_name raise self.NotFoundError( "A class containing the main method ('public static void main(String[] args)') could not be found in the files %s" % ", ".join(class_files))
def run(self, env): # Save save check configuration config_path = os.path.join(env.tmpdir(), "checks.xml") copy_file(self.configuration.path, config_path) # Run the tests args = [ settings.JVM, "-cp", settings.CHECKSTYLEALLJAR, "-Dbasedir=.", "com.puppycrawl.tools.checkstyle.Main", "-c", "checks.xml" ] + [name for (name, content) in env.sources()] [output, error, exitcode, timed_out, oom_ed] = execute_arglist(args, env.tmpdir()) # Remove Praktomat-Path-Prefixes from result: output = re.sub(r"^" + re.escape(env.tmpdir()) + "/+", "", output, flags=re.MULTILINE) result = self.create_result(env) log = '<pre>' + escape(output) + '</pre>' if timed_out: log = log + '<div class="error">Timeout occured!</div>' if oom_ed: log = log + '<div class="error">Out of memory!</div>' result.set_log(log) result.set_passed( not timed_out and not oom_ed and not exitcode and (not re.match('Starting audit...\nAudit done.', output) == None)) return result
def run(self, env): """ Build it. """ result = self.create_result(env) filenames = [name for name in self.get_file_names(env)] args = [self.compiler()] + self.flags(env) + filenames + self.libs() [output,_,_,_,_] = execute_arglist(args, env.tmpdir(),self.environment()) has_main = re.search(r"^Linking ([^ ]*) ...$",output,re.MULTILINE) if has_main: self._detected_main = has_main.group(1) output = escape(output) output = self.enhance_output(env, output) # We mustn't have any warnings. passed = not self.has_warnings(output) log = self.build_log(output,args,set(filenames).intersection([solutionfile.path() for solutionfile in env.solution().solutionfile_set.all()])) # Now that submission was successfully built, try to find the main modules name again try: if passed : env.set_program(self.main_module(env)) except self.NotFoundError as e: passed = not self._main_required log += "<pre>" + str(e) + "</pre>" result.set_passed(passed) result.set_log(log) return result
def run(self, env): """ Build it. """ result = self.create_result(env) filenames = [name for name in self.get_file_names(env)] args = [self.compiler()] + self.flags(env) + filenames + self.libs() [output, _, _, _, _] = execute_arglist(args, env.tmpdir(), self.environment()) has_main = re.search(r"^Linking ([^ ]*) ...$", output, re.MULTILINE) if has_main: self._detected_main = has_main.group(1) output = escape(output) output = self.enhance_output(env, output) # We mustn't have any warnings. passed = not self.has_warnings(output) log = self.build_log( output, args, set(filenames).intersection([ solutionfile.path() for solutionfile in env.solution().solutionfile_set.all() ])) # Now that submission was successfully built, try to find the main modules name again try: if passed: env.set_program(self.main_module(env)) except self.NotFoundError as e: passed = not self._main_required log += "<pre>" + str(e) + "</pre>" result.set_passed(passed) result.set_log(log) return result
def run(self, env): java_builder = IgnoringJavaBuilder(_flags="", _libs=self.junit_version, _file_pattern=r"^.*\.[jJ][aA][vV][aA]$", _output_flags="", _main_required=False) java_builder._ignore = self.ignore.split(" ") build_result = java_builder.run(env) if not build_result.passed: result = self.create_result(env) result.set_passed(False) result.set_log('<pre>' + escape(self.test_description) + '\n\n======== Test Results ======\n\n</pre><br/>\n'+build_result.log) return result environ = {} environ['UPLOAD_ROOT'] = settings.UPLOAD_ROOT environ['JAVA'] = settings.JVM script_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'scripts') environ['POLICY'] = os.path.join(script_dir, "junit.policy") cmd = [settings.JVM_SECURE, "-cp", settings.JAVA_LIBS[self.junit_version]+":.", self.runner(), self.class_name] [output, error, exitcode, timed_out, oom_ed] = execute_arglist(cmd, env.tmpdir(), environment_variables=environ, timeout=settings.TEST_TIMEOUT, fileseeklimit=settings.TEST_MAXFILESIZE, extradirs=[script_dir]) result = self.create_result(env) (output, truncated) = truncated_log(output) output = '<pre>' + escape(self.test_description) + '\n\n======== Test Results ======\n\n</pre><br/><pre>' + escape(output) + '</pre>' result.set_log(output, timed_out=timed_out or oom_ed, truncated=truncated, oom_ed=oom_ed) result.set_passed(not exitcode and not timed_out and not oom_ed and self.output_ok(output) and not truncated) return result
def show_info(request): # read disk usage for sandbox response = HttpResponse() response.write("Praktomat: " + VERSION.version + "<br>\r\n") sandboxdir = settings.SANDBOX_DIR if not os.path.exists(sandboxdir): # sandbox folder does not exist response.write("Sandbox folder not found<br>\r\n") else: command = ['du', '-s', '-h'] result = execute_arglist(args=command, working_directory=sandboxdir, timeout=60, unsafe=True) resultout = result[0] resulterr = result[1] # print(resultout) # print(resulterr) response.write("Sandbox disk usage: " + resultout + "<br>\r\n") # get number of tasks # now = django.utils.timezone.now() counter = 0 for e in Task.objects.all(): counter = counter + 1 response.write("Tasks: " + str(counter) + "<br>\r\n") # get number of solutions counter = 0 for e in Solution.objects.all(): counter = counter + 1 response.write("Solution: " + str(counter) + "<br>\r\n") # prefer Json? return HttpResponse(response)
def run(self, env): """ Build it. """ result = self.create_result(env) # Try to find out the main modules name with only the source files present try: env.set_program(self.main_module(env)) except self.NotFoundError: pass filenames = [name for name in self.get_file_names(env)] args = [self.compiler()] + self.output_flags(env) + self.flags(env) + filenames + self.libs() script_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)),'scripts') [output,_,_,_,_] = execute_arglist(args, env.tmpdir(),self.environment(), extradirs=[script_dir]) output = escape(output) output = self.enhance_output(env, output) # We mustn't have any warnings. passed = not self.has_warnings(output) log = self.build_log(output,args,set(filenames).intersection([solutionfile.path() for solutionfile in env.solution().solutionfile_set.all()])) # Now that submission was successfully built, try to find the main modules name again try: if passed : env.set_program(self.main_module(env)) except self.NotFoundError as e: # But only complain if the main method is required if self._main_required: log += "<pre>" + str(e) + "</pre>" passed = False result.set_passed(passed) result.set_log(log) return result
def run(self, env): """ Build it. """ result = self.create_result(env) # Try to find out the main modules name with only the source files present if self._main_required: try: env.set_program(self.main_module(env)) except self.NotFoundError: pass filenames = [name for name in self.get_file_names(env)] args = [self.compiler()] + self.output_flags(env) + self.flags(env) + filenames + self.libs() script_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'scripts') [output, _, _, _, _] = execute_arglist(args, env.tmpdir(), self.environment(), extradirs=[script_dir]) output = escape(output) output = self.enhance_output(env, output) # We mustn't have any warnings. passed = not self.has_warnings(output) log = self.build_log(output, args, set(filenames).intersection([solutionfile.path() for solutionfile in env.solution().solutionfile_set.all()])) # Now that submission was successfully built, try to find the main modules name again if self._main_required and passed: try: env.set_program(self.main_module(env)) except self.NotFoundError as e: log += "<pre>" + str(e) + "</pre>" passed = False result.set_passed(passed) result.set_log(log) return result
def run_command(self, cmd, env): [output, error, exitcode, timed_out, oom_ed] = \ execute_arglist(cmd, env.tmpdir(), timeout=settings.TEST_TIMEOUT, fileseeklimit=settings.TEST_MAXFILESIZE) logger.debug("output: " + output) logger.debug("exitcode: " + str(exitcode)) if error != None and len(error) > 0: logger.debug("error: " + error) output = output + error result = self.create_result(env) if timed_out or oom_ed: # ERROR: Execution timed out logger.error('Execution timeout') # clear log for timeout # because truncating log will result in invalid XML. truncated = False output = '\Execution timed out... (Check for infinite loop in your code)\r\n' + output (output, truncated) = truncated_log(output) # Do not set timout flag in order to handle timeout only as failed testcase. # Student shall be motivated to look for error in his or her code and not in testcode. result.set_log(output, timed_out=timed_out, truncated=truncated, oom_ed=oom_ed, log_format=CheckerResult.TEXT_LOG) result.set_passed(False) return result, output if exitcode != 0: (output, truncated) = truncated_log(output) if exitcode < 0: # append signal message output = output + '\r\nSignal:\r\n' + signal.strsignal(- exitcode) result.set_log(output, timed_out=False, truncated=truncated, oom_ed=False, log_format=CheckerResult.TEXT_LOG) result.set_passed(False) return result, output result.set_passed(True) return result, output
def run(self, env): thys = map(lambda (name, _): ('%s' % os.path.splitext(name)[0]), env.sources()) additional_thys = [ '%s' % name for name in re.split(" |,", self.additional_theories) if name ] user_thys = filter(lambda name: name not in additional_thys, thys) platform = execute_arglist( [settings.ISABELLE_BINARY, "getenv", "ML_PLATFORM"], env.tmpdir(), timeout=10, error_to_output=False)[0] args = [settings.ISABELLE_BINARY, "process"] # Depending on the underlying polyml platform (32/64 bit) we use 2 or 1 threads, resp. # This is due to the default memory limit (1gb) of safe-docker and the # default initial heap sizes of 500m and 1000m for 32 bit and 64 bit, resp. if "x86_64-linux" in platform: args += ["-o", "threads=1"] else: args += ["-o", "threads=2"] for t in additional_thys + user_thys: args += ["-T", t] args += ["-l", self.logic] (output, error, exitcode, timed_out, oom_ed) = execute_arglist(args, env.tmpdir(), timeout=settings.TEST_TIMEOUT, error_to_output=False) if timed_out: output += "\n\n---- check aborted after %d seconds ----\n" % settings.TEST_TIMEOUT if oom_ed: output += "\n\n---- check aborted, out of memory ----\n" result = self.create_result(env) result.set_log('<pre>' + escape(output) + '</pre>') result.set_passed(not timed_out and not oom_ed and self.output_ok(output)) return result
def run(self, env): # Find out the path to isabaelle-process args = [settings.ISABELLE_BINARY, "getenv", "-b", "ISABELLE_PROCESS"] (output, error, exitcode, timed_out, oom_ed) = execute_arglist(args, env.tmpdir(), error_to_output=False) isabelle_process = output.rstrip() if not isabelle_process: output = "isabelle gentenv -b ISABELLE_PROCESS failed\n" output += "error: " + error + "\n" output += "timed_out: " + timed_out + "\n" output += "oom_ed: " + oom_ed + "\n" result = self.create_result(env) result.set_log('<pre>' + escape(output) + '</pre>') result.set_passed(False) return result thys = map(lambda (name, _): ('"%s"' % os.path.splitext(name)[0]), env.sources()) trusted_thys = [ '"%s"' % name for name in re.split(" |,", self.trusted_theories) if name ] untrusted_thys = filter(lambda name: name not in trusted_thys, thys) ml_cmd = 'use_thys [%s]; Secure.set_secure (); use_thys [%s]' % \ (','.join(trusted_thys), ','.join(untrusted_thys)) args = [isabelle_process, "-r", "-q", "-e", ml_cmd, self.logic] (output, error, exitcode, timed_out, oom_ed) = execute_arglist(args, env.tmpdir(), timeout=settings.TEST_TIMEOUT, error_to_output=False) if timed_out: output += "\n\n---- check aborted after %d seconds ----\n" % settings.TEST_TIMEOUT if oom_ed: output += "\n\n---- check aborted, out of memory ----\n" result = self.create_result(env) result.set_log('<pre>' + escape(output) + '</pre>') result.set_passed(not timed_out and not oom_ed and self.output_ok(output)) return result
def run(self, env): # Save public test cases in `tests.exp' tests_exp = os.path.join(self.tests_dir(env), "tests.exp") test_cases = string.replace( encoding.get_unicode(self.test_case.read()), u"PROGRAM", env.program()) create_file(tests_exp, test_cases) testsuite = self.testsuite_dir(env) program_name = env.program() if " " in program_name: result = self.create_result(env) result.set_log( "<pre><b class=\"fail\">Error</b>: Path to the main() - source file contains spaces.\n\nFor Java .zip submittions, the directory hierarchy of the .zip file must excactly match the package structure.\nThe default package must correspond to the .zip root directory.</pre>" ) result.set_passed(False) return result cmd = [settings.DEJAGNU_RUNTEST, "--tool", program_name, "tests.exp"] environ = {} environ['JAVA'] = settings.JVM script_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'scripts') environ['POLICY'] = join(script_dir, "praktomat.policy") environ['USER'] = env.user().get_full_name().encode( sys.getdefaultencoding(), 'ignore') environ['HOME'] = testsuite environ['UPLOAD_ROOT'] = settings.UPLOAD_ROOT [output, error, exitcode, timed_out, oom_ed] = \ execute_arglist( cmd, testsuite, environment_variables=environ, timeout=settings.TEST_TIMEOUT, fileseeklimit=settings.TEST_MAXFILESIZE, extradirs=[env.tmpdir(), script_dir] ) output = encoding.get_unicode(output) try: summary = encoding.get_unicode( open(os.path.join(testsuite, program_name + ".sum")).read()) log = encoding.get_unicode( open(os.path.join(testsuite, program_name + ".log")).read()) except: summary = "" log = "" complete_output = self.htmlize_output(output + log) result = self.create_result(env) result.set_log(complete_output, timed_out=timed_out or oom_ed) result.set_passed(not exitcode and not timed_out and not oom_ed and self.output_ok(complete_output)) return result
def run(self, env): """ Runs tests in a special environment. Here's the actual work. This runs the check in the environment ENV, returning a CheckerResult. """ # Setup filename = self.filename if self.filename else self.shell_script.path path = os.path.join(env.tmpdir(), os.path.basename(filename)) copy_file(self.shell_script.path, path) os.chmod(path, 0750) # Run the tests -- execute dumped shell script 'script.sh' filenames = [name for (name, content) in env.sources()] args = [path] + filenames environ = {} environ['USER'] = str(env.user().id) environ['USER_MATR'] = str(env.user().mat_number) environ['SOLUTION_ID'] = str(env.solution().id) environ['HOME'] = env.tmpdir() environ['JAVA'] = settings.JVM environ['JAVA_SECURE'] = settings.JVM_SECURE environ['SCALA'] = settings.SCALA environ['POLICY'] = settings.JVM_POLICY environ['PROGRAM'] = env.program() or '' script_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'scripts') [output, error, exitcode, timed_out, oom_ed] = execute_arglist( args, working_directory=env.tmpdir(), environment_variables=environ, timeout=settings.TEST_TIMEOUT, maxmem=settings.TEST_MAXMEM, fileseeklimit=settings.TEST_MAXFILESIZE, extradirs=[script_dir], ) output = force_unicode(output, errors='replace') result = self.create_result(env) (output, truncated) = truncated_log(output) if self.remove: output = re.sub(self.remove, "", output) if not self.returns_html or truncated or timed_out or oom_ed: output = '<pre>' + escape(output) + '</pre>' result.set_log(output, timed_out=timed_out, truncated=truncated, oom_ed=oom_ed) result.set_passed(not exitcode and not timed_out and not oom_ed and not truncated) return result
def run(self, env): java_builder = IgnoringJavaBuilder( _flags="", _libs=self.junit_version, _file_pattern=r"^.*\.[jJ][aA][vV][aA]$", _output_flags="") java_builder._ignore = self.ignore.split(" ") build_result = java_builder.run(env) if not build_result.passed: result = self.create_result(env) result.set_passed(False) result.set_log( '<pre>' + escape(self.test_description) + '\n\n======== Test Results ======\n\n</pre><br/>\n' + build_result.log) return result environ = {} environ['UPLOAD_ROOT'] = settings.UPLOAD_ROOT environ['JAVA'] = settings.JVM script_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'scripts') environ['POLICY'] = os.path.join(script_dir, "junit.policy") cmd = [ settings.JVM_SECURE, "-cp", settings.JAVA_LIBS[self.junit_version] + ":.", self.runner(), self.class_name ] [output, error, exitcode, timed_out, oom_ed] = execute_arglist(cmd, working_directory=env.tmpdir(), environment_variables=environ, timeout=settings.TEST_TIMEOUT, fileseeklimit=settings.TEST_MAXFILESIZE, extradirs=[script_dir]) result = self.create_result(env) (output, truncated) = truncated_log(output) output = '<pre>' + escape( self.test_description ) + '\n\n======== Test Results ======\n\n</pre><br/><pre>' + escape( output) + '</pre>' result.set_log(output, timed_out=timed_out or oom_ed, truncated=truncated, oom_ed=oom_ed) result.set_passed(not exitcode and not timed_out and not oom_ed and self.output_ok(output) and not truncated) return result
def solution_list(request, task_id, user_id=None): if (user_id and not request.user.is_trainer and not request.user.is_superuser): return access_denied(request) task = get_object_or_404(Task, pk=task_id) author = get_object_or_404(User, pk=user_id) if user_id else request.user solutions = task.solution_set.filter(author = author).order_by('-id') final_solution = task.final_solution(author) if task.publication_date >= datetime.now() and not request.user.is_trainer: raise Http404 if request.method == "POST": if task.expired() and not request.user.is_trainer: return access_denied(request) solution = Solution(task = task, author=author) formset = SolutionFormSet(request.POST, request.FILES, instance=solution) if formset.is_valid(): solution.save() formset.save() run_all_checker = bool(User.objects.filter(id=user_id, tutorial__tutors__pk=request.user.id) or request.user.is_trainer) solution.check_solution(run_all_checker) if solution.accepted: # Send submission confirmation email t = loader.get_template('solutions/submission_confirmation_email.html') c = { 'protocol': request.is_secure() and "https" or "http", 'domain': RequestSite(request).domain, 'site_name': settings.SITE_NAME, 'solution': solution, } with tempfile.NamedTemporaryFile(mode='w+') as tmp: tmp.write(t.render(c)) tmp.seek(0) [signed_mail, __, __, __, __] = execute_arglist(["openssl", "smime", "-sign", "-signer", settings.CERTIFICATE, "-inkey", settings.PRIVATE_KEY, "-in", tmp.name], ".", unsafe=True) connection = get_connection() message = ConfirmationMessage(_("%s submission confirmation") % settings.SITE_NAME, signed_mail, None, [solution.author.email], connection=connection) if solution.author.email: message.send() if solution.accepted or get_settings().accept_all_solutions: solution.final = True solution.save() return HttpResponseRedirect(reverse('solution_detail', args=[solution.id])) else: formset = SolutionFormSet() attestations = Attestation.objects.filter(solution__task=task, author__tutored_tutorials=request.user.tutorial) attestationsPublished = attestations[0].published if attestations else False return render(request, "solutions/solution_list.html", {"formset": formset, "task":task, "solutions": solutions, "final_solution":final_solution, "attestationsPublished":attestationsPublished, "author":author, "invisible_attestor":get_settings().invisible_attestor})
def remove_source_files(self, env, extensions): logger.debug('remove source files') # remove all files with extension c files_in_directory = os.listdir(env.tmpdir()) for root, dirs, files in os.walk(env.tmpdir()): for file in files: if file.lower().endswith(extensions): # logger.debug('remove ' + file) cmd = ['rm', file] [output, error, exitcode, timed_out, oom_ed] = \ execute_arglist(cmd, env.tmpdir(), unsafe=True)
def run_jplag(self, lang): # sanity check if not hasattr(settings, 'JPLAGJAR'): raise RuntimeError("Setting JPLAGJAR not set") if not os.path.exists(settings.JPLAGJAR): raise RuntimeError("Setting JPLAGJAR points to non-existing file %s" % settings.JPLAGJAR) if not lang in self.jplag_languages(): raise RuntimeError("Unknown jplag settings %s" % lang) # Remember jplag setting configuration = get_settings() configuration.jplag_setting = lang configuration.save() jplag_settings = self.jplag_languages()[lang] path = self.jplag_dir_path() tmp = os.path.join(path, "tmp") # clean out previous run if self.did_jplag_run(): shutil.rmtree(path) # create output directory os.makedirs(path) # extract all final solutions os.mkdir(tmp) final_solutions = self.solution_set.filter(final=True) from solutions.models import path_for_user for solution in final_solutions: subpath = os.path.join(tmp, path_for_user(solution.author)) os.mkdir(subpath) solution.copySolutionFiles(subpath) # run jplag args = [settings.JVM, "-jar", settings.JPLAGJAR, "-s", "-l", jplag_settings['param'], "-p", jplag_settings['files'], "-r", path, tmp] [output, error, exitcode, timed_out, oom_ed] = \ execute_arglist(args, path, unsafe=True) # remove solution copies shutil.rmtree(tmp) # write log file with open(os.path.join(path, "jplag.txt"), 'w') as fd: fd.write(output) # mark jplag as up-to-date self.jplag_up_to_date = True self.save()
def run(self, env): self.copy_files(env) # Save save check configuration config_path = os.path.join(env.tmpdir(), "checks.xml") copy_file(self.configuration.path, config_path) # Run the tests # tests are run unsafe because checkstyle fails when network is missing args = [settings.JVM, "-cp", settings.CHECKSTYLE_VER[self.check_version], "-Dbasedir=.", "com.puppycrawl.tools.checkstyle.Main", "-c", "checks.xml"] + \ [name for (name, content) in env.sources()] # + [" > ", env.tmpdir() + "/output.txt"] [output, error, exitcode, timed_out, oom_ed] = execute_arglist(args, env.tmpdir(), unsafe=True) # Remove Praktomat-Path-Prefixes from result: output = re.sub(r"" + re.escape(env.tmpdir() + "/") + "+", "", output, flags=re.MULTILINE) warnings = str.count(output, '[WARN]') errors = str.count(output, '[ERROR]') result = self.create_result(env) (output, truncated) = truncated_log(output) # logger.debug('Exitcode is ' + str(exitcode)) if ProFormAChecker.retrieve_subtest_results: # simply use plaintext result.set_log(output, timed_out=timed_out, truncated=False, oom_ed=oom_ed, log_format=CheckerResult.TEXT_LOG) regexp = '\[(?<msgtype>[A-Z]+)\]\s(?<filename>\/?(.+\/)*(.+)\.([^\s:]+)):(?<line>[0-9]+)(:(?<column>[0-9]+))?:\s(?<text>.+\.)\s\[(?<short>\w+)\]' result.set_regexp(regexp) else: # old handling (e.g. for LON-CAPA) log = '<pre>' + '\n\n======== Test Results ======\n\n</pre><br/><pre>' + \ escape(output) + '</pre>' # log = '<pre>' + escape(output) + '</pre>' if timed_out: log = log + '<div class="error">Timeout occured!</div>' if oom_ed: log = log + '<div class="error">Out of memory!</div>' result.set_log(log) result.set_passed(not timed_out and not oom_ed and not exitcode and warnings <= self.allowedWarnings and errors <= self.allowedErrors and not truncated) # result.set_passed(not timed_out and not oom_ed and not exitcode and (not re.match('Starting audit...\nAudit done.', output) == None)) return result
def get_submission_files_from_svn(submission_uri, NAMESPACES): from utilities.safeexec import execute_arglist from django.conf import settings folder = tempfile.mkdtemp() tmp_dir = os.path.join(folder, "submission") cmd = [ 'svn', 'export', '--username', os.environ['SVNUSER'], '--password', os.environ['SVNPASS'], submission_uri, tmp_dir ] # logger.debug(cmd) # fileseeklimit: do not limit here! [output, error, exitcode, timed_out, oom_ed] = \ execute_arglist(cmd, folder, environment_variables={}, timeout=settings.TEST_TIMEOUT, fileseeklimit=None, # settings.TEST_MAXFILESIZE, extradirs=[], unsafe=True) if exitcode != 0: message = '' if error != None: logger.debug('error: ' + str(error)) message += error + ' ' if output != None: logger.debug('output: ' + str(output)) message += output raise ExternalSubmissionException(message) if timed_out: raise ExternalSubmissionException( 'timeout when getting svn submission') # logger.debug('SVN-output: ' + output) # find revision m = re.search(r"(Exported revision )(?P<revision>.+)\.", output) revision = 'unknown revision' if m: if m.group('revision') is not None: revision = m.group('revision') logger.debug("SVN revision is: " + revision) versioncontrolinfo = VersionControlSystem(revision, submission_uri) # create filename dictionary submission_files_dict = dict() import glob for file_name in glob.iglob(tmp_dir + '/**/*', recursive=True): if not os.path.isfile(file_name): # ignore directories continue shortname = file_name[len(tmp_dir) + 1:] # logger.debug('add ' + str(shortname)) submission_files_dict[shortname] = PhysicalFile(file_name) return submission_files_dict, versioncontrolinfo
def run_jplag(self, lang): # sanity check if not hasattr(settings,'JPLAGJAR'): raise RuntimeError("Setting JPLAGJAR not set") if not os.path.exists(settings.JPLAGJAR): raise RuntimeError("Setting JPLAGJAR points to non-existing file %s" % settings.JPLAGJAR) if not lang in self.jplag_languages(): raise RuntimeError("Unknown jplag settings %s" % lang) # Remember jplag setting configuration = get_settings() configuration.jplag_setting = lang configuration.save() jplag_settings = self.jplag_languages()[lang] path = self.jplag_dir_path() tmp = os.path.join(path,"tmp") # clean out previous run if self.did_jplag_run(): shutil.rmtree(path) # create output directory os.makedirs(path) # extract all final solutions os.mkdir(tmp) final_solutions = self.solution_set.filter(final=True) from solutions.models import path_for_user for solution in final_solutions: subpath = os.path.join(tmp, path_for_user(solution.author)) os.mkdir(subpath) solution.copySolutionFiles(subpath) # run jplag args = [settings.JVM, "-jar", settings.JPLAGJAR, "-l", jplag_settings['param'], "-p", jplag_settings['files'], "-r", path, tmp] [output, error, exitcode,timed_out, oom_ed] = \ execute_arglist(args, path, unsafe=True) # remove solution copies shutil.rmtree(tmp) # write log file file(os.path.join(path,"jplag.txt"),'w').write(output) # mark jplag as up-to-date self.jplag_up_to_date = True self.save()
def run(self, env): """ Runs tests in a special environment. Here's the actual work. This runs the check in the environment ENV, returning a CheckerResult. """ # Setup filename = self.filename if self.filename else self.shell_script.path path = os.path.join(env.tmpdir(),os.path.basename(filename)) copy_file(self.shell_script.path, path) os.chmod(path,0750) # Run the tests -- execute dumped shell script 'script.sh' filenames = [name for (name,content) in env.sources()] args = [path] + filenames environ = {} environ['USER'] = str(env.user().id) environ['USER_MATR'] = str(env.user().mat_number) environ['SOLUTION_ID'] = str(env.solution().id) environ['HOME'] = env.tmpdir() environ['JAVA'] = settings.JVM environ['JAVA_SECURE'] = settings.JVM_SECURE environ['SCALA'] = settings.SCALA environ['POLICY'] = settings.JVM_POLICY environ['PROGRAM'] = env.program() or '' script_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)),'scripts') [output, error, exitcode,timed_out, oom_ed] = execute_arglist( args, working_directory=env.tmpdir(), environment_variables=environ, timeout=settings.TEST_TIMEOUT, maxmem=settings.TEST_MAXMEM, fileseeklimit=settings.TEST_MAXFILESIZE, extradirs = [script_dir], ) output = force_unicode(output, errors='replace') result = self.create_result(env) (output,truncated) = truncated_log(output) if self.remove: output = re.sub(self.remove, "", output) if not self.returns_html or truncated or timed_out or oom_ed: output = '<pre>' + escape(output) + '</pre>' result.set_log(output,timed_out=timed_out,truncated=truncated,oom_ed=oom_ed) result.set_passed(not exitcode and not timed_out and not oom_ed and not truncated) return result
def run(self, env): # Save public test cases in `tests.exp' tests_exp = os.path.join(self.tests_dir(env), "tests.exp") test_cases = string.replace(encoding.get_unicode(self.test_case.read()), u"PROGRAM", env.program()) create_file(tests_exp,test_cases) testsuite = self.testsuite_dir(env) program_name = env.program() if " " in program_name: result = self.create_result(env) result.set_log("<pre><b class=\"fail\">Error</b>: Path to the main() - source file contains spaces.\n\nFor Java .zip submittions, the directory hierarchy of the .zip file must excactly match the package structure.\nThe default package must correspond to the .zip root directory.</pre>") result.set_passed(False) return result cmd = [settings.DEJAGNU_RUNTEST, "--tool", program_name, "tests.exp"] environ = {} environ['JAVA'] = settings.JVM script_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)),'scripts') environ['POLICY'] = join(script_dir,"praktomat.policy") environ['USER'] = env.user().get_full_name().encode(sys.getdefaultencoding(), 'ignore') environ['HOME'] = testsuite environ['UPLOAD_ROOT'] = settings.UPLOAD_ROOT [output, error, exitcode, timed_out, oom_ed] = \ execute_arglist( cmd, testsuite, environment_variables=environ, timeout=settings.TEST_TIMEOUT, fileseeklimit=settings.TEST_MAXFILESIZE, extradirs=[env.tmpdir(), script_dir] ) output = encoding.get_unicode(output) try: summary = encoding.get_unicode(open(os.path.join(testsuite, program_name + ".sum")).read()) log = encoding.get_unicode(open(os.path.join(testsuite, program_name + ".log")).read()) except: summary = "" log = "" complete_output = self.htmlize_output(output + log) result = self.create_result(env) result.set_log(complete_output,timed_out=timed_out or oom_ed) result.set_passed(not exitcode and not timed_out and not oom_ed and self.output_ok(complete_output)) return result
def run(self, env): # Find out the path to isabaelle-process args = [settings.ISABELLE_BINARY, "getenv", "-b", "ISABELLE_PROCESS"] (output, error, exitcode, timed_out, oom_ed) = execute_arglist(args, env.tmpdir(), error_to_output=False) isabelle_process = output.rstrip() if not isabelle_process: output = "isabelle gentenv -b ISABELLE_PROCESS failed\n" output += "error: " + error + "\n" output += "timed_out: " + timed_out + "\n" output += "oom_ed: " + oom_ed + "\n" result = self.create_result(env) result.set_log('<pre>' + escape(output) + '</pre>') result.set_passed(False) return result thys = map (lambda (name,_): ('"%s"' % os.path.splitext(name)[0]), env.sources()) trusted_thys = ['"%s"' % name for name in re.split(" |,",self.trusted_theories) if name] untrusted_thys = filter (lambda name: name not in trusted_thys, thys) ml_cmd = 'use_thys [%s]; Secure.set_secure (); use_thys [%s]' % \ (','.join(trusted_thys), ','.join(untrusted_thys)) args = [isabelle_process, "-r", "-q", "-e", ml_cmd, self.logic] (output, error, exitcode, timed_out, oom_ed) = execute_arglist(args, env.tmpdir(),timeout=settings.TEST_TIMEOUT, error_to_output=False) if timed_out: output += "\n\n---- check aborted after %d seconds ----\n" % settings.TEST_TIMEOUT if oom_ed: output += "\n\n---- check aborted, out of memory ----\n" result = self.create_result(env) result.set_log('<pre>' + escape(output) + '</pre>') result.set_passed(not timed_out and not oom_ed and self.output_ok(output)) return result
def main_module(self, env): """ find the first class file containing a main method """ main_method = "public static void main(java.lang.String[])" class_name = re.compile(r"^(public )?(abstract )?(final )?class ([^ ]*)( extends .*)? \{$", re.MULTILINE) class_files = [] for dirpath, dirs, files in os.walk(env.tmpdir()): for filename in files: if filename.endswith(".class"): class_files.append(filename) [classinfo,_,_,_,_] = execute_arglist([settings.JAVAP, os.path.join(dirpath,filename)], env.tmpdir(), self.environment(), unsafe=True) if string.find(classinfo,main_method) >= 0: main_class_name = class_name.search(classinfo, re.MULTILINE).group(4) return main_class_name raise self.NotFoundError("A class containing the main method ('public static void main(String[] args)') could not be found in the files %s" % ", ".join(class_files))
def main_module(self, env): """ find the first class file containing a main method """ main_method = "public static void main(java.lang.String[])" main_method_varargs = "public static void main(java.lang.String...)" class_name = re.compile(r"^(public )?(abstract )?(final )?(class|interface) ([^ ]*)( extends .*)?( implements .*)? \{$", re.MULTILINE) class_files = [] for dirpath, dirs, files in os.walk(env.tmpdir()): for filename in files: if filename.endswith(".class"): class_files.append(filename) [classinfo, _, _, _, _] = execute_arglist([settings.JAVAP, os.path.join(dirpath, filename)], env.tmpdir(), self.environment(), unsafe=True) if classinfo.find(main_method) >= 0 or classinfo.find(main_method_varargs) >= 0: main_class_name = class_name.search(classinfo, re.MULTILINE).group(5) return main_class_name raise self.NotFoundError("A class containing the main method ('public static void main(String[] args)') could not be found in the files %s" % ", ".join(class_files))
def run(self, env): filecopy_result = self.run_file(env) if not filecopy_result.passed: return filecopy_result if self.require_safe: safe_builder = IgnoringHaskellBuilder(_flags="-XSafe", _file_pattern = r"^.*\.[hH][sS]$", _main_required=False) safe_builder._ignore=self.ignore.split(" ") + [self.path_relative_to_sandbox()] safe_build_result = safe_builder.run(env) if not safe_build_result.passed: result = self.create_result(env) result.set_passed(False) result.set_log('<pre>' + escape(self.test_description) + '\n\n======== Test Results (Safe) ======\n\n</pre><br/>\n'+safe_build_result.log) return result test_builder = TestOnlyBuildingBuilder(_flags="-main-is "+self.module_name(), _libs="test-framework test-framework-quickcheck2 test-framework-hunit") test_builder._testsuite_filename=self.path_relative_to_sandbox() test_build_result = test_builder.run(env) if not test_build_result.passed: result = self.create_result(env) result.set_passed(False) result.set_log('<pre>' + escape(self.test_description) + '\n\n======== Test Results (Building all) ======\n\n</pre><br/>\n'+test_build_result.log) return result environ = {} environ['UPLOAD_ROOT'] = settings.UPLOAD_ROOT cmd = ["./"+self.module_binary_name(), "--maximum-generated-tests=5000"] [output, error, exitcode,timed_out, oom_ed] = execute_arglist(cmd, env.tmpdir(),environment_variables=environ,timeout=settings.TEST_TIMEOUT,fileseeklimit=settings.TEST_MAXFILESIZE) result = self.create_result(env) (output,truncated) = truncated_log(output) output = '<pre>' + escape(self.test_description) + '\n\n======== Test Results ======\n\n</pre><br/><pre>' + escape(output) + '</pre>' if self.include_testcase_in_report in ["FULL","DL"]: testsuit_template = get_template('checker/checker/haskell_test_framework_report.html') output += testsuit_template.render(Context({'showSource' : (self.include_testcase_in_report=="FULL"), 'testfile' : self.file, 'testfilename' : self.path_relative_to_sandbox(), 'testfileContent': encoding.get_unicode(self.file.read())})) result.set_log(output,timed_out=timed_out or oom_ed,truncated=truncated) result.set_passed(not exitcode and not timed_out and not oom_ed and self.output_ok(output) and not truncated) return result
def run(self, env): filecopy_result = self.run_file(env) if not filecopy_result.passed: return filecopy_result if self.require_safe: safe_builder = IgnoringHaskellBuilder(_flags="-XSafe", _file_pattern = r"^.*\.[hH][sS]$", _main_required=False) safe_builder._ignore=self.ignore.split(" ") + [self.path_relative_to_sandbox()] safe_build_result = safe_builder.run(env) if not safe_build_result.passed: result = self.create_result(env) result.set_passed(False) result.set_log('<pre>' + escape(self.test_description) + '\n\n======== Test Results (Safe) ======\n\n</pre><br/>\n'+safe_build_result.log) return result test_builder = TestOnlyBuildingBuilder(_flags="-main-is "+self.module_name(), _libs="test-framework test-framework-quickcheck2 test-framework-hunit") test_builder._testsuite_filename=self.path_relative_to_sandbox() test_build_result = test_builder.run(env) if not test_build_result.passed: result = self.create_result(env) result.set_passed(False) result.set_log('<pre>' + escape(self.test_description) + '\n\n======== Test Results (Building all) ======\n\n</pre><br/>\n'+test_build_result.log) return result environ = {} environ['UPLOAD_ROOT'] = settings.UPLOAD_ROOT cmd = ["./"+self.module_binary_name(), "--maximum-generated-tests=1000"] [output, error, exitcode,timed_out, oom_ed] = execute_arglist(cmd, env.tmpdir(),environment_variables=environ,timeout=settings.TEST_TIMEOUT,fileseeklimit=settings.TEST_MAXFILESIZE) result = self.create_result(env) (output,truncated) = truncated_log(output) output = '<pre>' + escape(self.test_description) + '\n\n======== Test Results ======\n\n</pre><br/><pre>' + escape(output) + '</pre>' if self.include_testcase_in_report in ["FULL","DL"]: testsuit_template = get_template('checker/checker/haskell_test_framework_report.html') output += testsuit_template.render(Context({'showSource' : (self.include_testcase_in_report=="FULL"), 'testfile' : self.file, 'testfilename' : self.path_relative_to_sandbox(), 'testfileContent': encoding.get_unicode(self.file.read())})) result.set_log(output,timed_out=timed_out or oom_ed,truncated=truncated) result.set_passed(not exitcode and not timed_out and not oom_ed and self.output_ok(output) and not truncated) return result
def run(self, env): # copy files and unzip zip file if submission consists of just a zip file. self.prepare_run(env) test_dir = env.tmpdir() # compile python code in order to prevent leaking testcode to student (part 1) logger.debug('compile python') [output, error, exitcode, timed_out, oom_ed] = execute_arglist(['python3', '-m', 'compileall'], env.tmpdir(), unsafe=True) if exitcode != 0: # could not compile. # TODO: run without compilation in order to generate better output??? regexp = '(?<filename>\/?(\w+\/)*(\w+)\.([^:]+)),(?<line>[0-9]+)' # regexp = '(?<filename>\/?(\w+\/)*(\w+)\.([^:]+)):(?<line>[0-9]+)(:(?<column>[0-9]+))?: (?<msgtype>[a-z]+): (?<text>.+)(?<code>\s+.+)?(?<position>\s+\^)?(\s+symbol:\s*(?<symbol>\s+.+))?' return self.handle_compile_error(env, output, error, timed_out, oom_ed, regexp) pythonbin = os.readlink('/usr/bin/python3') # create run script: with open(test_dir + '/run_suite.py', 'w') as file: file.write("""# coding=utf-8 import unittest import xmlrunner import os loader = unittest.TestLoader() start_dir = '.' suite = loader.discover(start_dir, "*test*.py") # delete python files in order to prevent leaking testcode to student (part 2) for dirpath, dirs, files in os.walk('.'): for file in files: if file.endswith('.py'): try: os.unlink(os.path.join(dirpath, file)) except: pass with open('unittest_results.xml', 'wb') as output: runner=xmlrunner.XMLTestRunner(output=output, outsuffix='') runner.run(suite) """) os.chmod(test_dir + '/run_suite.py', 0o770) # TODO # RXSECURE = re.compile(r"(exit|test_detail\.xml)", re.MULTILINE) # if not self.submission_ok(env, RXSECURE): # result = self.create_result(env) # result.set_passed(False) # result.set_log("Invalid keyword found in submission (e.g. exit)", log_format=CheckerResult.TEXT_LOG) # return result pythonbin = self.prepare_sandbox(env) # run command cmd = ['./' + pythonbin, 'run_suite.py'] logger.debug('run ' + str(cmd)) # get result (result, output) = self.run_command(cmd, env) # XSLT if os.path.exists(test_dir + "/unittest_results.xml") and \ os.path.isfile(test_dir + "/unittest_results.xml"): try: # f = open(test_dir + "/unittest_results.xml", "r") # logger.debug(f.read()) xmloutput = self.convert_xml(test_dir + "/unittest_results.xml") result.set_log(xmloutput, timed_out=False, truncated=False, oom_ed=False, log_format=CheckerResult.PROFORMA_SUBTESTS) result.set_extralog(output) return result except: logger.error('Error in XML transformation') traceback.print_exc() # logger.error(inst) # fallback: use default output return result # logger.error('could not convert to XML format') # raise Exception('Inconclusive test result (1)') else: if result.passed: # Test is passed but there is no XML file. # (exit in submission?) result.set_passed(False) result.set_log("Inconclusive test result", log_format=CheckerResult.TEXT_LOG) return result # raise Exception('Inconclusive test result (2)') return result
def run(self, env): thys = map (lambda (name,_): ('"%s"' % os.path.splitext(name)[0]), env.sources()) R_files = [ name for (name,content) in env.sources() if os.path.splitext(name)[1] == '.R' ] scriptname = None if len(R_files) == 0: output = "<p>No R scripts found in submission</p>" result = self.create_result(env) result.set_log(output) result.set_passed(False) return result if self.r_script: if self.r_script not in R_files: output = "<p>Could not find expected R script %s.</p>" % self.r_script output += "<p>R scripts found: %s</p>" % ", ".join(map(escape, R_files)) result = self.create_result(env) result.set_log(output) result.set_passed(False) return result scriptname = self.r_script else: if len(R_files) > 1: output = "<p>Multiple R scripts found in submission.</p>" output += "<p>R scripts found: %s</p>" % ", ".join(map(escape, R_files)) output +=" <p>Please submit exactly one file ending in <tt>.R</tt></p>" result = self.create_result(env) result.set_log(output) result.set_passed(False) return result else: scriptname = R_files[0] args = ["Rscript", scriptname] (output, error, exitcode, timed_out, oom_ed) = execute_arglist( args, env.tmpdir(), timeout=settings.TEST_TIMEOUT, fileseeklimit=settings.TEST_MAXFILESIZE, maxmem=settings.TEST_MAXMEM, ) if timed_out: output += "\n\n---- script execution aborted, took too long ----\n" if oom_ed: output += "\n\n---- script execution aborted, out of memory ----\n" if exitcode != 0: output += "\n\n---- Rscript finished with exitcode %d ----\n" % exitcode rplots_path = os.path.join(env.tmpdir(), "Rplots.pdf") rplots_exists = os.path.isfile(rplots_path) result = self.create_result(env) if rplots_exists: if self.keep_plots: result.add_artefact("Rplots.pdf", rplots_path) if self.require_plots and not rplots_exists: output += "\n\n---- No Rplots.pdf file was generated, this was required ----\n" % exitcode result.set_log('<pre>' + escape(output) + '</pre>') result.set_passed(exitcode == 0 and not timed_out and not oom_ed and not (self.require_plots and not rplots_exists)) return result
def run(self, env): """ Runs tests in a special environment. Here's the actual work. This runs the check in the environment ENV, returning a CheckerResult. """ # Setup test_dir = env.tmpdir() environ = {} if self.input_file: input_path = os.path.join(test_dir, os.path.basename(self.input_file.path)) environ['INPUTFILE'] = os.path.basename(self.input_file.path) copy_file(self.input_file.path, input_path) if self.output_file: output_path = os.path.join(test_dir, os.path.basename(self.output_file.path)) environ['OUTPUTFILE'] = os.path.basename(self.output_file.path) copy_file(self.output_file.path, output_path) replace = [(u'PROGRAM', env.program())] if env.program() else [] replace += [("JAVA", settings.JVM_SECURE)] #copy_file_to_directory(self.shell_script.path, test_dir, replace=replace) copy_file(self.shell_script.path, test_dir, to_is_directory=True) #some time after 2013 Praktomat losts copy_file_to_directory with replace parameter to_path = os.path.join(test_dir, os.path.basename(self.shell_script.path)) with open(to_path) as fd: content = encoding.get_unicode(fd.read()) for (old, new) in replace: content = content.replace(old, new) with open(to_path, 'w') as fd: fd.write(encoding.get_utf8(content)) args = ["sh", os.path.basename(self.shell_script.name)] #environ['USER'] = unicode(env.user().get_full_name()).encode('utf-8') environ['USER'] = env.user( ).username # gets overwritten with praktomat-test-user's name, therefore: environ['AUTHOR'] = env.solution( ).author.username # will not be overwritten! environ['HOME'] = test_dir script_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'scripts') #[output, error, exitcode,_] = execute_arglist(args, working_directory=test_dir, environment_variables=environ) [output, error, exitcode, timed_out, oom_ed] = execute_arglist( args, working_directory=test_dir, environment_variables=environ, timeout=settings.TEST_TIMEOUT, maxmem=settings.TEST_MAXMEM, fileseeklimit=settings.TEST_MAXFILESIZE, extradirs=[script_dir], ) output = force_unicode(output, errors='replace') result = CheckerResult(checker=self, solution=env.solution()) result.set_log('<pre>' + escape(output) + '</pre>') result.set_passed(not exitcode) return result
def run(self, env): """ Runs tests in a special environment. Here's the actual work. This runs the check in the environment ENV, returning a CheckerResult. """ # Setup # copy files and unzip zip file if submission consists of just a zip file. self.prepare_run(env) test_dir = env.tmpdir() replace = [(u'PROGRAM', env.program())] if env.program() else [] copy_file(self.doctest.path, os.path.join(test_dir, os.path.basename(self.doctest.path))) script_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'scripts') # copy python interpreter with all its shared libraries into sandbox # since it is not available because of chroot in restrict # todo: make properly copy_file('/usr/bin/python3', test_dir + '/python3') self.copy_shared_objects(env) # todo: make properly # python3 instead of 3.8 and prepare outside checker createpathonlib = "(cd / && tar -cf - usr/lib/python3.8) | (cd " + test_dir + " && tar -xf -)" os.system(createpathonlib) # Run the tests -- execute dumped shell script 'script.sh' cmd = ["./python3", os.path.basename(self.doctest.name), "-v"] environ = dict() environ['USER'] = env.user().get_full_name() environ['HOME'] = test_dir for (name, content) in env.sources(): if self.checkSubmission(content): result = CheckerResult(checker=self) result.set_passed(False) result.set_log( "Bitte überarbeiten Sie Ihren Programmcode: " "Betriebssystem kritische Befehle sind verboten") return result # (output, error, exitcode) = execute(args, working_directory=test_dir, environment_variables=environ) [output, error, exitcode, timed_out, oom_ed] = execute_arglist( cmd, env.tmpdir(), environment_variables=environ, # use_default_user_configuration=True, timeout=settings.TEST_TIMEOUT, fileseeklimit=settings.TEST_MAXFILESIZE, # extradirs=[script_dir] ) # cleanup sandbox # todo: make properly shutil... try: os.system('rm -rf ' + test_dir + '/lib') os.system('rm -rf ' + test_dir + '/lib64') os.system('rm -rf ' + test_dir + '/usr/lib') os.system('rm -rf ' + test_dir + '/__pycache__') os.system('rm ' + test_dir + '/python3') except: logger.error('error while cleaning up python sandbox') logger.debug(output) logger.debug(error) result = self.create_result(env) (output, truncated) = truncated_log(output) if self.remove: output = re.sub(self.remove, "", output) # Remove Praktomat-Path-Prefixes from result: output = re.sub(r"^" + re.escape(env.tmpdir()) + "/+", "", output, flags=re.MULTILINE) if ProFormAChecker.retrieve_subtest_results: # plain text output result.set_log(output, timed_out=timed_out, truncated=truncated, log_format=CheckerResult.TEXT_LOG) else: if not self.returns_html: output = '<pre>' + output + '</pre>' output = '<pre>' + '\n\n======== Test Results ======\n\n</pre><br/><pre>' + \ escape(output) + '</pre>' result.set_log(output, timed_out=timed_out, truncated=truncated) result.set_passed(not exitcode and not timed_out and self.output_ok_positiv(output) and not truncated) return result
def run(self, env): self.copy_files(env) # compile test logger.debug('JUNIT Checker build') java_builder = IgnoringJavaBuilder( _flags="", _libs=self.junit_version, _file_pattern=r"^.*\.[jJ][aA][vV][aA]$", _output_flags="", _main_required=False) # add JAR files from test task for file in self.files.all(): if file.file.path.lower().endswith('.jar'): java_builder.add_custom_lib(file) java_builder._ignore = self.ignore.split(" ") build_result = java_builder.run(env) if not build_result.passed: logger.info('could not compile JUNIT test') # logger.debug("log: " + build_result.log) result = self.create_result(env) result.set_passed(False) result.set_log(build_result.log, log_format=(CheckerResult.FEEDBACK_LIST_LOG if ProFormAChecker.retrieve_subtest_results else CheckerResult.NORMAL_LOG)) # result.set_log('<pre>' + escape(self.test_description) + '\n\n======== Test Results ======\n\n</pre><br/>\n'+build_result.log) return result # delete all java files in the sandbox in order to avoid the student getting the test source code :-) [output, error, exitcode, timed_out, oom_ed] = \ execute_arglist(['find', '.' , '-name', '*.java', '-delete'], env.tmpdir(), unsafe=True) if exitcode != 0: logger.error('exitcode for java files deletion :' + str(exitcode)) logger.error(output) logger.error(error) # run test logger.debug('JUNIT Checker run') environ = {} environ['UPLOAD_ROOT'] = settings.UPLOAD_ROOT environ['JAVA'] = settings.JVM script_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'scripts') environ['POLICY'] = os.path.join(script_dir, "junit.policy") if self.junit_version == 'junit5': # JUNIT5 [cmd, use_run_listener ] = self.get_run_command_junit5(java_builder.libs()[1]) else: # JUNIT4 [cmd, use_run_listener ] = self.get_run_command_junit4(java_builder.libs()[1]) # use Java security manager instead of restrict application [output, error, exitcode, timed_out, oom_ed] = \ execute_arglist(cmd, env.tmpdir(), environment_variables=environ, timeout=settings.TEST_TIMEOUT, fileseeklimit=settings.TEST_MAXFILESIZE, extradirs=[script_dir], unsafe=True) # Remove deprecated warning for Java 17 and security manager output = JUnitChecker.remove_depricated_warning(output) # logger.debug('JUNIT output:' + str(output)) logger.debug('JUNIT error:' + str(error)) logger.debug('JUNIT exitcode:' + str(exitcode)) result = self.create_result(env) truncated = False # show normal console output in case of: # - timeout (created by Checker) # - not using RunListener # - exitcode <> 0 with RunListener (means internal error) if timed_out or oom_ed: # ERROR: Execution timed out logger.error('Execution timeout') if use_run_listener: # clear log for timeout with Run Listener # because truncating log will result in invalid XML. output = '' truncated = False output = '\Execution timed out... (Check for infinite loop in your code)\r\n' + output (output, truncated) = truncated_log(output) # Do not set timout flag in order to handle timeout only as failed testcase. # Student shall be motivated to look for error in his or her code and not in testcode. result.set_log(output, timed_out=False, truncated=truncated, oom_ed=oom_ed, log_format=CheckerResult.TEXT_LOG) result.set_passed(False) return result #import chardet #encoding = chardet.detect(output) #logger.debug('JUNIT output encoding:' + encoding['encoding']) if use_run_listener: # RUN LISTENER if exitcode == 0: # normal detailed results # todo: Unterscheiden zwischen Textlistener (altes Log-Format) und Proforma-Listener (neues Format) result.set_log(output, timed_out=timed_out, truncated=False, oom_ed=oom_ed, log_format=CheckerResult.PROFORMA_SUBTESTS) else: result.set_internal_error(True) # no XML output => truncate (output, truncated) = truncated_log(output) result.set_log("RunListener Error: " + output, timed_out=timed_out, truncated=truncated, oom_ed=oom_ed, log_format=CheckerResult.TEXT_LOG) else: # show standard log output (output, truncated) = truncated_log(output) output = '<pre>' + escape(self.test_description) + '\n\n======== Test Results ======\n\n</pre><br/><pre>' + \ escape(output) + '</pre>' result.set_log(output, timed_out=timed_out or oom_ed, truncated=truncated, oom_ed=oom_ed) result.set_passed(not exitcode and self.output_ok(output) and not truncated) return result
def run(self, env): # Setup self.copy_files(env) test_dir = env.tmpdir() replace = [(u'PROGRAM', env.program())] if env.program() else [] copy_file(self.testFile.path, os.path.join(test_dir, os.path.basename(self.testFile.path))) script_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'scripts') # check: only one submission file allowed result = self.create_result(env) if len(env.sources()) > 1: result.set_log("Sie dürfen nur eine Datei angegeben!") result.set_passed(False) return result # check submission for (name, content) in env.sources(): if not (self.secureSubmission(content)): result.set_passed(False) result.set_log("Bitte keine IO-Befehle verwenden") return result else: #concat test #try: self.conCat(test_dir, content, self.testFile) #except UnicodeEncodeError: # result.set_passed(False) # result.set_log("Special characters can pose a problem. Vermeiden Sie Umlaute im Source Code " # "und verwenden Sie kein <, > oder & in XML Dokumenten.") # return result # complete test cmd = [ settings.JVM, '-cp', settings.SETLXJAR, "org.randoom.setlx.pc.ui.SetlX", "concat.stlx" ] # (output, error, exitcode) = execute(args, env.tmpdir()) environ = {} environ['UPLOAD_ROOT'] = settings.UPLOAD_ROOT [output, error, exitcode, timed_out, oom_ed] = execute_arglist(cmd, env.tmpdir(), environment_variables=environ, timeout=settings.TEST_TIMEOUT, fileseeklimit=settings.TEST_MAXFILESIZE, extradirs=[script_dir], unsafe=True) # [output, error, exitcode, timed_out] = execute_arglist(cmd, env.tmpdir(), # use_default_user_configuration=True, # timeout=settings.TEST_TIMEOUT, # fileseeklimit=settings.TEST_MAXFILESIZE, # extradirs=[script_dir]) extradirs=[script_dir]) (output, truncated) = truncated_log(output) # Remove Praktomat-Path-Prefixes from result: # output = re.sub(r"^"+re.escape(env.tmpdir())+"/+", "", output, flags=re.MULTILINE) output = re.sub(r"" + re.escape(env.tmpdir() + "/") + "+", "", output, flags=re.MULTILINE) passed = True if len(output.strip()) == 0: output = "no output" passed = False if ProFormAChecker.retrieve_subtest_results: # plain text output if passed and (RXFAIL.search(output) is not None or exitcode): # add regular expression in case of an error regexp = 'line\ (?<line>[0-9]+)(:(?<column>[0-9]+))?\s(?<text>.+)' result.set_regexp(regexp) result.set_log(output, timed_out=timed_out, truncated=truncated, log_format=CheckerResult.TEXT_LOG) else: output = '<pre>' + '\n\n======== Test Results ======\n\n</pre><br/><pre>' + \ escape(output) + '</pre>' result.set_log(output, timed_out=timed_out, truncated=truncated) result.set_passed(passed and not exitcode and not timed_out and (RXFAIL.search(output) is None) and not truncated) return result