@@ -155,7 +155,76 @@ def test_execute_code_recreates_sandbox_when_get_returns_none(
155155 mock_json_output = MagicMock ()
156156 mock_json_output .mime_type = "application/json"
157157 mock_json_output .data = json .dumps (
158- {"stdout" : "recreated sandbox run" , "stderr" : "" }
158+ {"msg_out" : "recreated sandbox run" , "msg_err" : "" }
159+ ).encode ("utf-8" )
160+ mock_json_output .metadata = None
161+ mock_response .outputs = [mock_json_output ]
162+ mock_api_client .agent_engines .sandboxes .execute_code .return_value = (
163+ mock_response
164+ )
165+
166+ # Execute using agent_engine_resource_name so a sandbox can be created
167+ executor = AgentEngineSandboxCodeExecutor (
168+ agent_engine_resource_name = (
169+ "projects/123/locations/us-central1/reasoningEngines/456"
170+ )
171+ )
172+ code_input = CodeExecutionInput (code = 'print("hello world")' )
173+ result = executor .execute_code (mock_invocation_context , code_input )
174+
175+ # Assert get was called for the existing sandbox
176+ mock_api_client .agent_engines .sandboxes .get .assert_called_once_with (
177+ name = existing_sandbox_name
178+ )
179+
180+ # Assert create was called and session updated with new sandbox
181+ mock_api_client .agent_engines .sandboxes .create .assert_called_once ()
182+ assert (
183+ mock_invocation_context .session .state ["sandbox_name" ]
184+ == created_sandbox_name
185+ )
186+
187+ # Assert execute_code used the created sandbox name
188+ mock_api_client .agent_engines .sandboxes .execute_code .assert_called_once_with (
189+ name = created_sandbox_name ,
190+ input_data = {"code" : 'print("hello world")' },
191+ )
192+
193+ @patch ("vertexai.Client" )
194+ def test_execute_code_recreates_sandbox_when_get_raises_client_error (
195+ self ,
196+ mock_vertexai_client ,
197+ mock_invocation_context ,
198+ ):
199+ # Setup Mocks
200+ mock_api_client = MagicMock ()
201+ mock_vertexai_client .return_value = mock_api_client
202+
203+ # Existing sandbox name stored in session
204+ existing_sandbox_name = "projects/123/locations/us-central1/reasoningEngines/456/sandboxEnvironments/old"
205+ mock_invocation_context .session .state = {
206+ "sandbox_name" : existing_sandbox_name
207+ }
208+
209+ # Mock get to raise ClientError with code 404
210+ from google .genai .errors import ClientError
211+
212+ mock_api_client .agent_engines .sandboxes .get .side_effect = ClientError (
213+ code = 404 , response_json = {"message" : "Not Found" }
214+ )
215+
216+ # Mock create operation to return a new sandbox resource name
217+ operation_mock = MagicMock ()
218+ created_sandbox_name = "projects/123/locations/us-central1/reasoningEngines/456/sandboxEnvironments/789"
219+ operation_mock .response .name = created_sandbox_name
220+ mock_api_client .agent_engines .sandboxes .create .return_value = operation_mock
221+
222+ # Mock execute_code response
223+ mock_response = MagicMock ()
224+ mock_json_output = MagicMock ()
225+ mock_json_output .mime_type = "application/json"
226+ mock_json_output .data = json .dumps (
227+ {"msg_out" : "recreated sandbox run" , "msg_err" : "" }
159228 ).encode ("utf-8" )
160229 mock_json_output .metadata = None
161230 mock_response .outputs = [mock_json_output ]
0 commit comments