Esempio n. 1
0
def grade(reference_solution, student_solution, translate_line, websheet, student):

    if not re.match(r"^\w+$", websheet.classname):
      return ("Internal Error (Compiling)", "Invalid overridden classname <tt>" + websheet.classname + " </tt>")
    
    dump = {
        "reference." + websheet.classname : reference_solution,
        "student." + websheet.classname : student_solution[1],
        "tester." + websheet.classname : websheet.make_tester()    
        }

#    print(student_solution[1])
#    print(reference_solution)
#    print(websheet.make_tester())
    
    for clazz in ["Grader", "Options", "Utils"]:
      dump["websheets."+clazz] = "".join(open("grade_java_files/"+clazz+".java"))

    for dep in websheet.dependencies:
      depws = Websheet.Websheet.from_name(dep)
      if depws == None:
          return ("Internal Error", "Dependent websheet " + dep + " does not exist");
      submission = config.load_submission(student, dep, True)
      if submission == False:
        return("Dependency Error",
               "<div class='dependency-error'><i>Dependency error</i>: " + 
               "You need to successfully complete the <a href='javascript:websheets.load(\""+dep+"\")'><tt>"+dep+"</tt></a> websheet first (while logged in).</div>") # error text
      submission = [{'code': x, 'from': {'line': 0, 'ch':0}, 'to': {'line': 0, 'ch': 0}} for x in submission]
      dump["student."+dep] = depws.combine_with_template(submission, "student")[1]
      
      dump["reference."+dep] = depws.get_reference_solution("reference")


    compileRun = config.run_java(["traceprinter/ramtools/CompileToBytes"], json.dumps(dump))
    compileResult = compileRun.stdout
    if (compileResult==""):
      return ("Internal Error (Compiling)", "<pre>\n" + 
              cgi.escape(compileRun.stderr) +
              "</pre>"+"<!--"+compileRun._toString()+"-->")
    
    compileObj = json.loads(compileResult)

#    print(compileObj['status'])

    if compileObj['status'] == 'Internal Error':
      return ("Internal Error (Compiling)", "<pre>\n" + 
              cgi.escape(compileObj["errmsg"]) +
              "</pre>")
    elif compileObj['status'] == 'Compile-time Error':
        errorObj = compileObj['error']
        if errorObj['filename'] == ("student." + websheet.classname + ".java"):
            result = "Syntax error (could not compile):"
            result += "<br>"
            result += '<tt>'+errorObj['filename'].split('.')[-2]+'.java</tt>, line '
            result += str(translate_line(errorObj['row'])) + ':'
            #result += str(errorObj['row']) + ':'
            result += "<pre>\n"
            #remove the safeexec bits
            result += cgi.escape(errorObj["errmsg"]
                                 .replace("stdlibpack.", "")
                                 .replace("student.", "")
                                 )
            result += "</pre>"
            return ("Syntax Error", result)
        else:
            return("Internal Error (Compiling reference solution and testing suite)",
                   '<b>File: </b><tt>'+errorObj['filename']+'</tt><br><b>Line number: '
                   +str(errorObj['row'])+"</b><pre>"
                   +errorObj['errmsg']+":\n"+dump[errorObj['filename'][:-5]].split("\n")[errorObj['row']-1]+"</pre>")
                    

    #print(compileResult)

    # prefetch all urls, pass them to the grader on stdin
    compileObj["stdin"] = json.dumps({
      "fetched_urls":websheet.prefetch_urls(True)
      })

    compileResult = json.dumps(compileObj)
    
    runUser = config.run_java(["traceprinter/ramtools/RAMRun", "tester." + websheet.classname], compileResult)
    #runUser = config.run_java("tester." + websheet.classname + " " + student)

    #print(runUser.stdout)
    RAMRunError = runUser.stdout.startswith("Error")
    RAMRunErrmsg = runUser.stdout[:runUser.stdout.index('\n')]

    runUser.stdout = runUser.stdout[runUser.stdout.index('\n')+1:]

    #print(runUser.stdout)
    #print(runUser.stderr)

    if runUser.returncode != 0 or runUser.stdout.startswith("Time Limit Exceeded"):
        errmsg = runUser.stderr.split('\n')[0]
        result = runUser.stdout
        result += "<div class='safeexec'>Crashed! The grader reported "
        result += "<code>"
        result += cgi.escape(errmsg)
        result += "</code>"
        result += "</div>"
        result += "<!--" + runUser.stderr + "-->"
        return ("Sandbox Limit", result)

    if RAMRunError:
        result += "<div class='safeexec'>Could not execute! "
        result += "<code>"
        result += cgi.escape(RAMRunErrmsg)
        result += "</code>"
        result += "</div>"
        return ("Internal Error (RAMRun)", result)
      
    runtimeOutput = re.sub(
        re.compile("(at|from) line (\d+) "),
        lambda match: match.group(1)+" line " + translate_line(match.group(2)) + " ",
        runUser.stdout)

    #print(runtimeOutput)

    def ssf(s, t, u): # substring from of s from after t to before u
      if t not in s: raise ValueError("Can't ssf("+s+","+t+","+u+")") 
      s = s[s.index(t)+len(t) : ]
      return s[ : s.index(u)]
    
    if "<div class='error'>Runtime error:" in runtimeOutput:
      category = "Runtime Error"
      errmsg = ssf(runtimeOutput[runtimeOutput.index("<div class='error'>Runtime error:"):], "<pre >", "\n")
    elif "<div class='all-passed'>" in runtimeOutput:
      category = "Passed"
      epilogue = websheet.epilogue
    else:
      category = "Failed Tests"
      if "<div class='error'>" in runtimeOutput:
        errmsg = ssf(runtimeOutput, "<div class='error'>", '</div>')
      else:
        return ("Internal Error", "<b>stderr</b><pre>" + runUser.stderr + "</pre><b>stdout</b><br>" + runUser.stdout)
        
    return (category, runtimeOutput)
Esempio n. 2
0
    def compile_and_run():
        nonlocal errmsg, epilogue

        user_poschunks = client_request["snippets"]

        # this is the pre-syntax check
        student_solution = websheet.make_student_solution(user_poschunks, "student")
        if student_solution[0] == False:
            if student_solution[1] == "Internal error! Wrong number of inputs":
                return ("Internal Error (Wrong number of snippets)", "Error: wrong number of snippets")
            errmsg = student_solution[1].split("\n")[1]
            return (
                "Pre-syntax Error",
                "<div class='pre-syntax-error'>Syntax error:"
                + "<pre>\n"
                + cgi.escape(student_solution[1])
                + "</pre></div>",
            )  # error text
        ss_to_ui_linemap = student_solution[2]

        def translate_line(ss_lineno):
            ss_lineno = int(ss_lineno)
            if ss_lineno in ss_to_ui_linemap:
                return str(ss_to_ui_linemap[ss_lineno])
            else:
                return "???(" + str(ss_lineno) + ")" + "<!--" + json.dumps(ss_to_ui_linemap) + "-->"

        reference_solution = websheet.get_reference_solution("reference")

        with open("GenericTester.java") as file:
            GTjava = "".join(file)

        dump = {
            "reference." + classname: reference_solution,
            "student." + classname: student_solution[1],
            "tester." + classname: websheet.make_tester(),
            "framework.GenericTester": GTjava,
        }

        # print(student_solution[1])

        for dep in websheet.dependencies:
            depws = Websheet.Websheet.from_filesystem(dep)
            submission = config.load_submission(student, dep, True)
            if submission == False:
                return (
                    "Dependency Error",
                    "<div class='dependency-error'><i>Dependency error</i>: "
                    + "You need to successfully complete the <a href='javascript:loadProblem(\""
                    + dep
                    + "\")'><tt>"
                    + dep
                    + "</tt></a> websheet first (while logged in).</div>",
                )  # error text
            submission = [{"code": x, "from": {"line": 0, "ch": 0}, "to": {"line": 0, "ch": 0}} for x in submission]
            dump["student." + dep] = depws.make_student_solution(submission, "student")[1]

            dump["reference." + dep] = depws.get_reference_solution("reference")

        compileRun = run_java("traceprinter/ramtools/CompileToBytes", json.dumps(dump))
        compileResult = compileRun.stdout
        if compileResult == "":
            return ("Internal Error (Compiling)", "<pre>\n" + cgi.escape(compileRun.stderr) + "</pre>")

        compileObj = json.loads(compileResult)

        #    print(compileObj['status'])

        if compileObj["status"] == "Internal Error":
            return ("Internal Error (Compiling)", "<pre>\n" + cgi.escape(compileObj["errmsg"]) + "</pre>")
        elif compileObj["status"] == "Compile-time Error":
            result = "Syntax error (could not compile):"
            result += "<br>"
            errorObj = compileObj["error"]
            result += "<tt>" + errorObj["filename"].split(".")[-2] + ".java</tt>, line "
            result += str(translate_line(errorObj["row"])) + ":"
            # result += str(errorObj['row']) + ':'
            result += "<pre>\n"
            # remove the safeexec bits
            result += cgi.escape(errorObj["errmsg"].replace("stdlibpack.", "").replace("student.", ""))
            result += "</pre>"
            return ("Syntax Error", result)

        #    print(compileResult)

        runUser = run_java("traceprinter/ramtools/RAMRun tester." + classname + " " + student, compileResult)
        # runUser = run_java("tester." + classname + " " + student)

        # print(runUser.stdout)
        RAMRunError = runUser.stdout.startswith("Error")
        RAMRunErrmsg = runUser.stdout[: runUser.stdout.index("\n")]

        runUser.stdout = runUser.stdout[runUser.stdout.index("\n") + 1 :]

        # print(runUser.stdout)
        # print(runUser.stderr)

        if runUser.returncode != 0 or runUser.stdout.startswith("Time Limit Exceeded"):
            errmsg = runUser.stderr.split("\n")[0]
            result = runUser.stdout
            result += "<div class='safeexec'>Crashed! The grader reported "
            result += "<code>"
            result += cgi.escape(errmsg)
            result += "</code>"
            result += "</div>"
            result += "<!--" + runUser.stderr + "-->"
            return ("Sandbox Limit", result)

        if RAMRunError:
            result += "<div class='safeexec'>Could not execute! "
            result += "<code>"
            result += cgi.escape(RAMRunErrmsg)
            result += "</code>"
            result += "</div>"
            return ("Internal Error (RAMRun)", result)

        runtimeOutput = re.sub(
            re.compile("at line (\d+) "),
            lambda match: "at line " + translate_line(match.group(1)) + " ",
            runUser.stdout,
        )

        # print(runtimeOutput)

        def ssf(s, t, u):  # substring from of s from after t to before u
            if t not in s:
                raise ValueError("Can't ssf(" + s + "," + t + "," + u + ")")
            s = s[s.index(t) + len(t) :]
            return s[: s.index(u)]

        if "<div class='error'>Runtime error:" in runtimeOutput:
            category = "Runtime Error"
            errmsg = ssf(runtimeOutput[runtimeOutput.index("<div class='error'>Runtime error:") :], "<pre >", "\n")
        elif "<div class='all-passed'>" in runtimeOutput:
            category = "Passed"
            epilogue = websheet.epilogue
        else:
            category = "Failed Tests"
            if "<div class='error'>" in runtimeOutput:
                errmsg = ssf(runtimeOutput, "<div class='error'>", "</div>")
            else:
                return (
                    "Internal Error",
                    "<b>stderr</b><pre>" + runUser.stderr + "</pre><b>stdout</b><br>" + runUser.stdout,
                )

        return (category, runtimeOutput)
Esempio n. 3
0
def grade(reference_solution, student_solution, translate_line, websheet,
          student):

    if not re.match(r"^\w+$", websheet.classname):
        return ("Internal Error (Compiling)",
                "Invalid overridden classname <tt>" + websheet.classname +
                " </tt>")

    dump = {
        "reference." + websheet.classname: reference_solution,
        "student." + websheet.classname: student_solution[1],
        "tester." + websheet.classname: websheet.make_tester()
    }

    #    print(student_solution[1])
    #    print(reference_solution)
    #    print(websheet.make_tester())

    for clazz in ["Grader", "Options", "Utils"]:
        dump["websheets." + clazz] = "".join(
            open("grade_java_files/" + clazz + ".java"))

    for dep in websheet.dependencies:
        depws = Websheet.Websheet.from_name(dep)
        if depws == None:
            return ("Internal Error",
                    "Dependent websheet " + dep + " does not exist")
        submission = config.load_submission(student, dep, True)
        if submission == False:
            return (
                "Dependency Error",
                "<div class='dependency-error'><i>Dependency error</i>: " +
                "You need to successfully complete the <a href='javascript:websheets.load(\""
                + dep + "\")'><tt>" + dep +
                "</tt></a> websheet first (while logged in).</div>"
            )  # error text
        submission = [{
            'code': x,
            'from': {
                'line': 0,
                'ch': 0
            },
            'to': {
                'line': 0,
                'ch': 0
            }
        } for x in submission]
        dump["student." + dep] = depws.combine_with_template(
            submission, "student")[1]

        dump["reference." + dep] = depws.get_reference_solution("reference")

    compileRun = config.run_java(["traceprinter/ramtools/CompileToBytes"],
                                 json.dumps(dump))
    compileResult = compileRun.stdout
    if (compileResult == ""):
        return ("Internal Error (Compiling)",
                "<pre>\n" + cgi.escape(compileRun.stderr) + "</pre>" + "<!--" +
                compileRun._toString() + "-->")

    compileObj = json.loads(compileResult)

    #    print(compileObj['status'])

    if compileObj['status'] == 'Internal Error':
        return ("Internal Error (Compiling)",
                "<pre>\n" + cgi.escape(compileObj["errmsg"]) + "</pre>")
    elif compileObj['status'] == 'Compile-time Error':
        errorObj = compileObj['error']
        if errorObj['filename'] == ("student." + websheet.classname + ".java"):
            result = "Syntax error (could not compile):"
            result += "<br>"
            result += '<tt>' + errorObj['filename'].split(
                '.')[-2] + '.java</tt>, line '
            result += str(translate_line(errorObj['row'])) + ':'
            #result += str(errorObj['row']) + ':'
            result += "<pre>\n"
            #remove the safeexec bits
            result += cgi.escape(errorObj["errmsg"].replace(
                "stdlibpack.", "").replace("student.", ""))
            result += "</pre>"
            return ("Syntax Error", result)
        else:
            return (
                "Internal Error (Compiling reference solution and testing suite)",
                '<b>File: </b><tt>' + errorObj['filename'] +
                '</tt><br><b>Line number: ' + str(errorObj['row']) +
                "</b><pre>" + errorObj['errmsg'] + ":\n" +
                dump[errorObj['filename'][:-5]].split("\n")[errorObj['row'] -
                                                            1] + "</pre>")

    #print(compileResult)

    # prefetch all urls, pass them to the grader on stdin
    compileObj["stdin"] = json.dumps(
        {"fetched_urls": websheet.prefetch_urls(True)})

    compileResult = json.dumps(compileObj)

    runUser = config.run_java(
        ["traceprinter/ramtools/RAMRun", "tester." + websheet.classname],
        compileResult)
    #runUser = config.run_java("tester." + websheet.classname + " " + student)

    #print(runUser.stdout)
    RAMRunError = runUser.stdout.startswith("Error")
    RAMRunErrmsg = runUser.stdout[:runUser.stdout.index('\n')]

    runUser.stdout = runUser.stdout[runUser.stdout.index('\n') + 1:]

    #print(runUser.stdout)
    #print(runUser.stderr)

    if runUser.returncode != 0 or runUser.stdout.startswith(
            "Time Limit Exceeded"):
        errmsg = runUser.stderr.split('\n')[0]
        result = runUser.stdout
        result += "<div class='safeexec'>Crashed! The grader reported "
        result += "<code>"
        result += cgi.escape(errmsg)
        result += "</code>"
        result += "</div>"
        result += "<!--" + runUser.stderr + "-->"
        return ("Sandbox Limit", result)

    if RAMRunError:
        result += "<div class='safeexec'>Could not execute! "
        result += "<code>"
        result += cgi.escape(RAMRunErrmsg)
        result += "</code>"
        result += "</div>"
        return ("Internal Error (RAMRun)", result)

    runtimeOutput = re.sub(
        re.compile("(at|from) line (\d+) "), lambda match: match.group(1) +
        " line " + translate_line(match.group(2)) + " ", runUser.stdout)

    #print(runtimeOutput)

    def ssf(s, t, u):  # substring from of s from after t to before u
        if t not in s:
            raise ValueError("Can't ssf(" + s + "," + t + "," + u + ")")
        s = s[s.index(t) + len(t):]
        return s[:s.index(u)]

    if "<div class='error'>Runtime error:" in runtimeOutput:
        category = "Runtime Error"
        errmsg = ssf(
            runtimeOutput[runtimeOutput.
                          index("<div class='error'>Runtime error:"):],
            "<pre >", "\n")
    elif "<div class='all-passed'>" in runtimeOutput:
        category = "Passed"
        epilogue = websheet.epilogue
    else:
        category = "Failed Tests"
        if "<div class='error'>" in runtimeOutput:
            errmsg = ssf(runtimeOutput, "<div class='error'>", '</div>')
        else:
            return ("Internal Error", "<b>stderr</b><pre>" + runUser.stderr +
                    "</pre><b>stdout</b><br>" + runUser.stdout)

    return (category, runtimeOutput)