Spaces:
Sleeping
Sleeping
File size: 3,184 Bytes
54a19c9 | 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 | import subprocess
import time
import os
import tempfile
import ast
from .models import ExecutionResult
def run_code_with_tests(code: str, test_code: str, timeout: float = 5.0) -> ExecutionResult:
# Syntax check
try:
ast.parse(code)
except SyntaxError as e:
return ExecutionResult(
compile_success=False,
runtime_errors=str(e),
test_passed=0,
test_total=0,
execution_time_seconds=0.0,
success=False
)
# Combine code and test definitions
full_code = f"""
import sys
import unittest
import time
import io
{code}
{test_code}
if __name__ == '__main__':
stream = io.StringIO()
runner = unittest.TextTestRunner(stream=stream, verbosity=2)
start_time = time.time()
result = runner.run(unittest.defaultTestLoader.loadTestsFromModule(sys.modules[__name__]))
end_time = time.time()
output = stream.getvalue()
print(f"|CODEARENA_STATS|{{result.wasSuccessful()}}|{{result.testsRun - len(result.failures) - len(result.errors)}}|{{result.testsRun}}|{{end_time - start_time}}|")
if not result.wasSuccessful():
print(output)
"""
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
f.write(full_code)
temp_file = f.name
start_wall = time.time()
try:
process = subprocess.run(
['python', temp_file],
capture_output=True,
text=True,
timeout=timeout
)
wall_time = time.time() - start_wall
stdout = process.stdout
stderr = process.stderr
stats_line = None
for line in stdout.split('\n'):
if line.startswith('|CODEARENA_STATS|'):
stats_line = line
break
if stats_line:
parts = stats_line.split('|')
success_str = parts[2]
passed = int(parts[3])
total = int(parts[4])
exec_time = float(parts[5])
return ExecutionResult(
compile_success=True,
runtime_errors=stderr if stderr else "",
test_passed=passed,
test_total=total,
execution_time_seconds=exec_time,
success=(success_str == 'True')
)
else:
return ExecutionResult(
compile_success=True,
runtime_errors="Tests did not complete successfully or output was malformed. Stderr: " + stderr + "\nStdout: " + stdout,
test_passed=0,
test_total=1, # Assume at least 1 failed
execution_time_seconds=wall_time,
success=False
)
except subprocess.TimeoutExpired as e:
return ExecutionResult(
compile_success=True,
runtime_errors="Execution timed out.",
test_passed=0,
test_total=1,
execution_time_seconds=timeout,
success=False
)
finally:
if os.path.exists(temp_file):
os.remove(temp_file)
|