icp/oer/exercise-formats/program/match-regex/controller.py

89 lines
2.4 KiB
Python
Raw Normal View History

2018-05-05 22:18:02 +00:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# program/match-regex
# Standardized types do not require authors to specify any control script as
# it can be generated on import. However when provided it will overwrite the
# default behaivior.
import sys
import subprocess
import re
2018-05-06 10:35:06 +00:00
import time
2018-05-05 22:18:02 +00:00
def build(ctx):
# Add filenames
allArgs = ['/usr/bin/make']
# start subprocess in with work_path as cwd
p = subprocess.Popen(allArgs, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=ctx.work_path)
msgs,errs = p.communicate()
2018-05-06 09:20:32 +00:00
retval = p.wait()
2018-05-05 22:18:02 +00:00
errs = errs.decode("utf-8")
msgs = msgs.decode("utf-8")
return retval, errs, msgs
def execute(ctx):
# if build failed, return early
if ctx.build_result[0] != 0:
return
2018-05-06 12:50:31 +00:00
allArgs = ("/usr/bin/docker run -h oer-worker --user 1001:65534 --rm -v /data/run/jobs/%s/:/data/ --network none kunkel/oer-worker /data/program" % ctx.id).split(" ")
print(" ".join(allArgs), file=sys.stderr)
2018-05-05 22:18:02 +00:00
p = subprocess.Popen(allArgs, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=ctx.work_path)
2019-06-28 16:26:41 +00:00
timeout = 3
2018-05-06 10:35:06 +00:00
poll_period = 0.1
p.poll()
while p.returncode is None and timeout > 0:
time.sleep(poll_period)
timeout -= poll_period
p.poll()
if timeout <= 0:
p.kill() # timed out
2018-05-05 22:18:02 +00:00
msgs,errs = p.communicate()
2018-05-06 09:20:32 +00:00
retval = p.wait()
2018-05-05 22:18:02 +00:00
errs = errs.decode("utf-8")
msgs = msgs.decode("utf-8")
2018-05-07 09:30:15 +00:00
if timeout <= 0:
errs += "\nKilled after timeout!\n"
2018-05-05 22:18:02 +00:00
return retval, errs, msgs
def grade(ctx):
"""A function that governs the grading process when different from default.
Expected is return value that indicates if the task passed or failed."""
# if build failed, return early and set grade to FAIL
if ctx.build_result[0] != 0:
return 'FAIL'
ctx.execute_result = execute(ctx)
2018-05-06 12:11:47 +00:00
#print(ctx.data['data']['regex'], file=sys.stderr)
#print(ctx.execute_result, file=sys.stderr)
2018-05-05 22:18:02 +00:00
if re.match(ctx.data['data']['regex'], ctx.execute_result[2]) != None:
return 'PASS'
else:
return 'FAIL'
def response(ctx):
if ctx.build_result[0] != 0:
output = ctx.build_result[1]
else:
2018-05-06 12:11:47 +00:00
output = ctx.execute_result[2] + "\n" + ctx.execute_result[1]
2018-05-05 22:18:02 +00:00
grade = ctx.grade_result
msg = ""
return {'output': output, 'grade': grade, 'msg': msg, 'data': None}