@@ -268,3 +268,87 @@ def test_init_chat_ollama_format():
268268 "dummy_input" , ["output" ], node_config = node_config_with_schema
269269 )
270270 assert node2 .llm_model .format == "dummy_schema_json"
271+
272+ import time
273+ import json
274+ from requests .exceptions import Timeout
275+
276+ # New dummy chain classes and dummy llms for testing invoke_with_timeout and ChatBedrock behavior.
277+ class DummySlowChain :
278+ """A dummy chain that simulates a slow response by returning quickly but using patched time."""
279+ def invoke (self , inputs ):
280+ return "response"
281+
282+ class DummyChainException :
283+ """A dummy chain that simulates an exception during invoke."""
284+ def invoke (self , inputs ):
285+ raise Exception ("dummy error" )
286+
287+ class DummyChatBedrock :
288+ """A dummy ChatBedrock chain that returns a predefined answer. It should be used when output_parser is None."""
289+ def __call__ (self , * args , ** kwargs ):
290+ return {"content" : "bedrock answer" }
291+
292+ def __or__ (self , other ):
293+ return self
294+
295+ # New tests to increase test coverage.
296+ def test_invoke_with_timeout_exceeded (dummy_node ):
297+ """
298+ Test that invoke_with_timeout raises a Timeout exception when the chain.invoke
299+ takes longer than the specified timeout.
300+ """
301+ # Set dummy_node.timeout to a known value (from dummy_node, timeout=1 is used)
302+ original_time = time .time
303+ # Create a list of times such that the first call returns start_time,
304+ # and the next call returns start_time + timeout + 1.
305+ call_times = [100 , 100 + dummy_node .timeout + 1 ]
306+ def fake_time ():
307+ return call_times .pop (0 ) if call_times else original_time ()
308+ time_time_backup = time .time
309+ time .time = fake_time
310+ try :
311+ with pytest .raises (Timeout ):
312+ dummy_node .invoke_with_timeout (DummySlowChain (), {"key" : "value" }, dummy_node .timeout )
313+ finally :
314+ time .time = time_time_backup
315+
316+ def test_invoke_with_timeout_exception_propagates (dummy_node ):
317+ """
318+ Test that invoke_with_timeout properly propagates exceptions raised by the chain.invoke call.
319+ """
320+ with pytest .raises (Exception ) as excinfo :
321+ dummy_node .invoke_with_timeout (DummyChainException (), {"key" : "value" }, dummy_node .timeout )
322+ assert "dummy error" in str (excinfo .value )
323+
324+ @pytest .mark .parametrize ("content_key" , ["relevant_chunks" , "parsed_doc" , "doc" , "content" ])
325+ def test_process_with_alternative_content_keys (dummy_node_for_process , content_key ):
326+ """
327+ Test that process() successfully uses alternative content keys.
328+ """
329+ state = {"user_prompt" : "What is the answer?" , content_key : "Alternative content" }
330+ dummy_node_for_process .chain = DummyChain ()
331+ dummy_node_for_process .invoke_with_timeout = lambda chain , inputs , timeout : chain .invoke (inputs )
332+ result_state = dummy_node_for_process .process (state )
333+ assert result_state ["output" ] == {"content" : "successful answer" }
334+
335+ def test_execute_single_chunk_with_bedrock ():
336+ """
337+ Test execute() for the single chunk branch using a DummyChatBedrock instance.
338+ This verifies that if the llm_model is a ChatBedrock, no output_parser is applied.
339+ """
340+ node_config = {"llm_model" : DummyChatBedrock (), "verbose" : False , "timeout" : 480 }
341+ node = GenerateAnswerNode ("dummy_input & doc" , ["output" ], node_config = node_config )
342+ node .logger = DummyLogger ()
343+ node .get_input_keys = lambda state : ["dummy_input" , "doc" ]
344+ state = {"dummy_input" : "What is the answer?" , "doc" : ["Only one chunk bedrock" ]}
345+
346+ # simulate a simple chain invocation (in the single-chunk branch)
347+ def fake_invoke_with_timeout (chain , inputs , timeout ):
348+ if "question" in inputs :
349+ return {"content" : "bedrock answer" }
350+ return {"content" : "unexpected response" }
351+
352+ node .invoke_with_timeout = fake_invoke_with_timeout
353+ output_state = node .execute (state )
354+ assert output_state ["output" ] == {"content" : "bedrock answer" }
0 commit comments