1- import pytest
2- import pytest_asyncio
3- import os
41import asyncio
2+ import os
53
6- from logging import warning
7-
8- from e2b_code_interpreter .code_interpreter_async import AsyncSandbox
9- from e2b_code_interpreter .code_interpreter_sync import Sandbox
4+ import pytest
105
11- timeout = 60
6+ from e2b_code_interpreter import (
7+ AsyncSandbox ,
8+ Sandbox ,
9+ )
10+ import uuid
1211
1312
14- # Override the event loop so it never closes during test execution
15- # This helps with pytest-xdist and prevents "Event loop is closed" errors
1613@pytest .fixture (scope = "session" )
17- def event_loop ():
18- """Create a session-scoped event loop for all async tests."""
19- try :
20- loop = asyncio .get_running_loop ()
21- except RuntimeError :
22- loop = asyncio .new_event_loop ()
23- yield loop
24- loop .close ()
14+ def sandbox_test_id ():
15+ return f"test_{ uuid .uuid4 ()} "
2516
2617
2718@pytest .fixture ()
@@ -30,66 +21,72 @@ def template():
3021
3122
3223@pytest .fixture ()
33- def sandbox (template , debug , network ):
34- sandbox = Sandbox .create (template , timeout = timeout , debug = debug , network = network )
24+ def sandbox_factory (request , template , sandbox_test_id ):
25+ def factory (* , template_name : str = template , ** kwargs ):
26+ kwargs .setdefault ("secure" , False )
27+ kwargs .setdefault ("timeout" , 5 )
28+
29+ metadata = kwargs .setdefault ("metadata" , dict ())
30+ metadata .setdefault ("sandbox_test_id" , sandbox_test_id )
31+
32+ sandbox = Sandbox .create (template_name , ** kwargs )
33+
34+ request .addfinalizer (lambda : sandbox .kill ())
35+
36+ return sandbox
37+
38+ return factory
3539
40+
41+ @pytest .fixture ()
42+ def sandbox (sandbox_factory ):
43+ return sandbox_factory ()
44+
45+
46+ # override the event loop so it never closes
47+ # this helps us with the global-scoped async http transport
48+ @pytest .fixture (scope = "session" )
49+ def event_loop ():
3650 try :
37- yield sandbox
38- finally :
39- try :
40- sandbox .kill ()
41- except : # noqa: E722
42- if not debug :
43- warning (
44- "Failed to kill sandbox — this is expected if the test runs with local envd."
45- )
51+ loop = asyncio .get_running_loop ()
52+ except RuntimeError :
53+ loop = asyncio .new_event_loop ()
54+ yield loop
55+ loop .close ()
4656
4757
4858@pytest .fixture
49- def async_sandbox_factory (request , template , debug , network , event_loop ):
50- """Factory for creating async sandboxes with proper cleanup."""
51-
52- async def factory (template_override = None , ** kwargs ):
53- template_name = template_override or template
54- kwargs .setdefault ("timeout" , timeout )
55- kwargs .setdefault ("debug" , debug )
56- kwargs .setdefault ("network" , network )
59+ def async_sandbox_factory (request , template , sandbox_test_id , event_loop ):
60+ async def factory (* , template_name : str = template , ** kwargs ):
61+ kwargs .setdefault ("timeout" , 5 )
62+
63+ metadata = kwargs .setdefault ("metadata" , dict ())
64+ metadata .setdefault ("sandbox_test_id" , sandbox_test_id )
65+
5766 sandbox = await AsyncSandbox .create (template_name , ** kwargs )
5867
5968 def kill ():
6069 async def _kill ():
61- try :
62- await sandbox .kill ()
63- except : # noqa: E722
64- if not debug :
65- warning (
66- "Failed to kill sandbox — this is expected if the test runs with local envd."
67- )
70+ await sandbox .kill ()
6871
6972 event_loop .run_until_complete (_kill ())
7073
7174 request .addfinalizer (kill )
75+
7276 return sandbox
7377
7478 return factory
7579
7680
7781@pytest .fixture
7882async def async_sandbox (async_sandbox_factory ):
79- """Default async sandbox fixture."""
8083 return await async_sandbox_factory ()
8184
8285
8386@pytest .fixture
8487def debug ():
8588 return os .getenv ("E2B_DEBUG" ) is not None
8689
87-
88- @pytest .fixture
89- def network ():
90- return None
91-
92-
9390@pytest .fixture (autouse = True )
9491def skip_by_debug (request , debug ):
9592 if request .node .get_closest_marker ("skip_debug" ):
0 commit comments