Skip to content

Commit 9e08b2c

Browse files
factor out into execution context
1 parent ff535a0 commit 9e08b2c

File tree

3 files changed

+56
-76
lines changed

3 files changed

+56
-76
lines changed

commit0/harness/execution_context.py

Lines changed: 36 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
""" Remote code execution contexts
1+
"""Remote code execution contexts
22
33
Implements the interface for local docker containers, remote modal sandboxes,
44
and HTTP servers.
55
"""
66

7-
87
from abc import ABC
98
import docker
109
import logging
@@ -15,7 +14,6 @@
1514
from commit0.harness.spec import Spec
1615
from commit0.harness.docker_build import (
1716
close_logger,
18-
setup_logger,
1917
)
2018
from commit0.harness.docker_utils import (
2119
cleanup_container,
@@ -26,15 +24,14 @@
2624
delete_file_from_container,
2725
exec_run_with_timeout,
2826
)
29-
from commit0.harness.utils import (
30-
EvaluationError,
31-
extract_test_output,
32-
get_hash_string,
33-
get_ip,
34-
get_user,
35-
)
3627

3728

29+
def read_stream(stream: modal.io_streams.StreamReader) -> str:
30+
strings = []
31+
for line in stream:
32+
strings.append(line)
33+
return "\n".join(strings)
34+
3835
class ExecutionContext(ABC):
3936
def __init__(
4037
self,
@@ -44,29 +41,29 @@ def __init__(
4441
timeout: int,
4542
log_dir: Path,
4643
):
47-
""" Create the remote execution context
44+
"""Create the remote execution context
4845
4946
The execution context will persist for the lifetime of this object.
5047
The execution context can be a Docker container or Modal sandbox.
5148
"""
5249
raise NotImplementedError
5350

54-
def copy_ssh_pubkey_from_remote(self):
51+
def copy_ssh_pubkey_from_remote(self) -> None:
5552
raise NotImplementedError
5653

57-
def copy_to_remote(self, local_path, remote_path):
54+
def copy_to_remote(self, local_path: Path, remote_path: Path) -> None:
5855
raise NotImplementedError
5956

60-
def exec_run_with_timeout(self, command, timeout):
57+
def exec_run_with_timeout(self, command: str, timeout: int) -> None:
6158
raise NotImplementedError
6259

63-
def exec_run(self, command):
60+
def exec_run(self, command: str) -> None:
6461
raise NotImplementedError
6562

66-
def copy_from_remote(self, remote_path, local_path):
63+
def copy_from_remote(self, remote_path, local_path) -> None:
6764
raise NotImplementedError
6865

69-
def delete_file_from_remote(self, remote_path):
66+
def delete_file_from_remote(self, remote_path) -> None:
7067
raise NotImplementedError
7168

7269
def __enter__(self):
@@ -85,10 +82,10 @@ def __init__(
8582
timeout: int,
8683
log_dir: Path,
8784
):
88-
client = docker.from_env()
85+
self.client = docker.from_env()
8986
self.logger = logger
9087
self.container = create_container(
91-
client=client,
88+
client=self.client,
9289
image_name=spec.repo_image_key,
9390
container_name=spec.get_container_name(),
9491
logger=logger,
@@ -103,9 +100,7 @@ def copy_to_remote(self, local_file: Path, remote_path: Path) -> None:
103100
copy_to_container(self.container, local_file, remote_path)
104101

105102
def exec_run_with_timeout(self, command: str, timeout: int) -> ():
106-
return exec_run_with_timeout(
107-
self.container, command, timeout
108-
)
103+
return exec_run_with_timeout(self.container, command, timeout)
109104

110105
def exec_run(self, command: str) -> None:
111106
return self.container.exec_run(command, demux=True)
@@ -147,6 +142,8 @@ def __init__(
147142
network_file_systems={
148143
"/vol": self.nfs,
149144
},
145+
cpu=8.0,
146+
timeout=30,
150147
)
151148

152149
self.copy_ssh_pubkey_from_remote()
@@ -174,32 +171,30 @@ def copy_ssh_pubkey_from_remote(self):
174171
authorized_keys_file.write(public_key + "\n")
175172

176173
def copy_to_remote(self, local_path: Path, remote_path: Path) -> None:
174+
tempname = "tmpfile"
177175
with local_path.open("rb") as f:
178-
self.nfs.write_file(str(local_path), f)
179-
self.sandbox.exec("bash", "-c", f"cp /vol/{str(local_path)} {str(remote_path)}")
176+
self.nfs.write_file(tempname, f)
177+
self.sandbox.exec("bash", "-c", f"cp /vol/{tempname} {str(remote_path)}")
180178

181179
def exec_run_with_timeout(self, command: str, timeout: int) -> None:
182180
"""Execute command on modal sandbox"""
181+
print("Executing:", command)
183182
process = self.sandbox.exec("bash", "-c", command)
184-
stdout = []
185-
for line in process.stdout:
186-
stdout.append(line)
187-
stderr = []
188-
for line in process.stderr:
189-
stderr.append(line)
190-
return "\n".join(stdout), False, 1
191-
return "\n".join(stdout), "\n".join(stderr)
183+
print("stdout")
184+
stdout = read_stream(process.stdout)
185+
print("stderr")
186+
stderr = read_stream(process.stderr)
187+
print(stderr)
188+
return stdout, False, 1
189+
return stdout, stderr
192190

193191
def exec_run(self, command: str) -> None:
194192
"""Execute command on modal sandbox"""
195193
process = self.sandbox.exec("bash", "-c", command)
196-
stdout = []
197-
for line in process.stdout:
198-
stdout.append(line)
199-
stderr = []
200-
for line in process.stderr:
201-
stderr.append(line)
202-
return 1, "\n".join(stdout)
194+
stdout = read_stream(process.stdout)
195+
stderr = read_stream(process.stderr)
196+
print(stderr)
197+
return 1, stdout
203198

204199
def copy_from_remote(self, remote_path: Path, local_path: Path) -> None:
205200
"""Copy file from modal sandbox"""
@@ -215,4 +210,5 @@ def __enter__(self):
215210
return self
216211

217212
def __exit__(self, exc_type, exc_value, exc_traceback):
218-
self.nfs.__exit__()
213+
# self.nfs.__exit__()
214+
pass

commit0/harness/modal_utils.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ def create_sandbox(image: modal.Image, nfs: modal.NetworkFileSystem) -> modal.Sa
1717
network_file_systems={
1818
"/vol": nfs,
1919
},
20+
timeout=60,
2021
)
2122

2223

@@ -38,9 +39,10 @@ def copy_file_to_sandbox(
3839
sandbox: modal.Sandbox, nfs: modal.NetworkFileSystem, src: Path, dst: Path
3940
) -> None:
4041
"""Copy file to modal sandbox"""
42+
path = "tmpfile"
4143
with src.open("rb") as f:
42-
nfs.write_file(str(src), f)
43-
sandbox.exec("bash", "-c", f"cp /vol/{str(src)} {str(dst)}")
44+
nfs.write_file(path, f)
45+
sandbox.exec("bash", "-c", f"cp /vol/{path} {str(dst)}")
4446

4547

4648
def copy_from_sandbox(sandbox: modal.Sandbox, src: Path, dst: Path) -> None:

commit0/harness/run_pytest_ids.py

Lines changed: 16 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
)
3636

3737

38-
3938
class ExecutionBackend(StrEnum):
4039
LOCAL = auto()
4140
MODAL = auto()
@@ -149,40 +148,15 @@ def run_modal(
149148
copy_file_to_sandbox(sandbox, nfs, eval_file, Path("/eval.sh"))
150149

151150
# DBG: check if eval file properly copied
151+
print("checking for eval.sh")
152152
print(execute_command(sandbox, "ls /")[0])
153153

154154
# execute tests
155155
output, error = execute_command(sandbox, "/bin/bash /eval.sh")
156156
# TODO: add timeout
157-
#print(output)
158-
#print(error)
159-
160-
timed_out = False
161-
test_output = extract_test_output(
162-
output, "--json-report --json-report-file=report.json"
163-
)
164-
165-
# stdout might be more straightforward
166-
print(test_output)
167-
test_output_path = log_dir / "test_output.txt"
168-
with open(test_output_path, "w") as f:
169-
f.write(test_output)
170-
if timed_out:
171-
f.write(f"\n\nTimeout error: {timeout} seconds exceeded.")
172-
raise EvaluationError(
173-
spec.repo,
174-
f"Test timed out after {timeout} seconds.",
175-
logger,
176-
)
177-
178-
# copy back report.json if there is any
179-
report_file = Path(spec.repo_directory) / "report.json"
180-
# Run the test command inside the container to check if the file exists
181-
exit_code, output = container.exec_run(f"test -e {report_file}", demux=True)
182-
# Check the exit code of the command
183-
if exit_code == 0:
184-
copy_from_sandbox(container, report_file, Path(log_dir / "report.json"))
185-
delete_file_from_sandbox(container, str(report_file))
157+
print(output)
158+
print(error)
159+
return
186160

187161

188162
def main(
@@ -235,6 +209,11 @@ def main(
235209
eval_file = Path(log_dir / "eval.sh")
236210
eval_file.write_text(eval_script)
237211

212+
#run_docker(spec, logger, eval_file, timeout, log_dir)
213+
run_modal(spec, logger, eval_file, timeout, log_dir)
214+
return
215+
216+
#backend = "local"
238217
backend = "modal"
239218
execution_context = None
240219
if ExecutionBackend(backend) == ExecutionBackend.MODAL:
@@ -244,7 +223,12 @@ def main(
244223
print(backend, execution_context)
245224

246225
with execution_context(spec, logger, eval_file, timeout, log_dir) as context:
247-
context.copy_to_remote(eval_file, "/eval.sh")
226+
context.copy_to_remote(eval_file, Path("/eval.sh"))
227+
print(context.exec_run("ls /vol")[1])
228+
print(context.exec_run("ls /")[1])
229+
230+
print(context.exec_run("cat /eval.sh")[1])
231+
248232
output, timed_out, total_runtime = context.exec_run_with_timeout(
249233
"/bin/bash /eval.sh", timeout
250234
)
@@ -269,19 +253,17 @@ def main(
269253
# copy back report.json if there is any
270254
report_file = Path(spec.repo_directory) / "report.json"
271255
# Run the test command inside the container to check if the file exists
272-
#exit_code, output = container.exec_run(f"test -e {report_file}", demux=True)
256+
# exit_code, output = container.exec_run(f"test -e {report_file}", demux=True)
273257
exit_code, output = context.exec_run(f"test -e {report_file}")
274258
# Check the exit code of the command
275259
if exit_code == 0:
276260
context.copy_from_remote(report_file, Path(log_dir / "report.json"))
277261
context.delete_file_from_remote(report_file)
278262

279-
280263
"""
281264
if ExecutionBackend(backend) == ExecutionBackend.LOCAL:
282265
run_docker(spec, logger, eval_file, timeout, log_dir)
283266
elif ExecutionBackend(backend) == ExecutionBackend.MODAL:
284-
run_modal(spec, logger, eval_file, timeout, log_dir)
285267
"""
286268

287269

0 commit comments

Comments
 (0)