This repository has been archived by the owner on Oct 25, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Test.py
130 lines (92 loc) · 3.86 KB
/
Test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import sys
import subprocess
import os
import re
import time
class Test(object):
"""
Global database of all of the answers I did/want give students
"""
"""
This is the scaling I use whenever I apply a timeout, i.e. if the student's
solution needs more than TimeoutScalingFactor the time of my simple code,
then I consider the submission to be wrong.
"""
TimeoutScalingFactor = 4
def __init__(self, submitted_file, benchmark_file = ""):
"""
submitted_file: String
File submitted by student
benchmark_file: String
File to benchmark/validate against. Can be empty if no such thing is
available or shall be provided.
"""
self.submitted_file = submitted_file
self.benchmark_file = benchmark_file
self.compilation_success = True
self.yields_correct_result = True
self.last_output = ""
self.timeout = 4000
self.runtime = 0
pass
def ignore_wrong_output(self):
if self.compilation_success:
self.yields_correct_result = True
def __get_submitted_executable_name(self):
return "submitted.out"
def __get_benchmark_executable_name(self):
return "benchmark.out"
def compile(self,compiler_call="g++ -O3"):
"""
Compiles the code (and also compiles the solution). The routine needs the
report file to write errors to, and it wants to know what the solution file
is called. That's the file submitted by the student.
Returns 1 if successful. Otherwise 0
"""
success = True
try:
invocation = compiler_call + " -o " + self.__get_submitted_executable_name() + " " + self.submitted_file
returnCode = subprocess.run(invocation, shell=True)
if returnCode.returncode!=0:
self.last_output = "ERROR: tried to translate with " + invocation + " and got " + str(returnCode.stderr)
return 0
else:
return 1
except Exception as e:
self.last_output = "ERROR: wanted to translate but got an exception " + str(e)
return 0
def run(self,arguments="",environment_variables={}):
"""
Compiles the code (and also compiles the solution). The routine needs the
report file to write errors to, and it wants to know what the solution file
is called. That's the file submitted by the student.
Returns 1 if successful. Otherwise 0
"""
success = True
encoding = 'utf-8'
try:
invocation = "./" + self.__get_submitted_executable_name() + " " + arguments
my_environment = os.environ
for i in environment_variables:
my_environment[ i[0] ] = i[1]
start_solution = time.time()
returnCode = subprocess.run(invocation, timeout=self.timeout, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, env=my_environment )
if returnCode.returncode!=0:
self.last_output = "ERROR: tried to run code with " + arguments + " and got " + str(returnCode.stderr)
return 0
else:
self.last_output = returnCode.stdout.decode(encoding).splitlines()[-1]
self.runtime = time.time() - start_solution
return 1
except Exception as e:
self.last_output = "ERROR: wanted to run code but got an exception " + str(e)
return 0
def search_for_pattern_in_output(self,search_pattern):
result = ""
m = re.findall( search_pattern, self.last_output )
if m:
result = str(m[-1])
return result
# if self.benchmark_file!="":
# invocation = compiler_call + " -o " + self.__get_benchmark_executable_name() + " " + self.benchmark_file
# returnCode = subprocess.run(invocation, shell=True)