1111from unittest .mock import Mock , patch
1212
1313import pytest
14- import requests
14+ from urllib .error import HTTPError , URLError
15+
1516from botocore .exceptions import ConnectionError # type: ignore
1617
1718from aws_durable_execution_sdk_python_testing .cli import CliApp , CliConfig , main
@@ -604,14 +605,16 @@ def test_invoke_command_makes_http_request_to_start_execution_endpoint() -> None
604605 """Test that invoke command makes HTTP request to start-durable-execution endpoint."""
605606 app = CliApp ()
606607
607- with patch ("requests.post" ) as mock_post :
608- # Mock successful response
609- mock_response = mock_post .return_value
610- mock_response .status_code = 201
611- mock_response .json .return_value = {
612- "ExecutionArn" : "arn:aws:lambda:us-west-2:123456789012:function:test-function:execution:test-execution"
613- }
608+ response_body = json .dumps ({
609+ "ExecutionArn" : "arn:aws:lambda:us-west-2:123456789012:function:test-function:execution:test-execution"
610+ }).encode ("utf-8" )
614611
612+ mock_response = Mock ()
613+ mock_response .read .return_value = response_body
614+ mock_response .__enter__ = Mock (return_value = mock_response )
615+ mock_response .__exit__ = Mock (return_value = False )
616+
617+ with patch ("aws_durable_execution_sdk_python_testing.cli.urlopen" , return_value = mock_response ) as mock_urlopen :
615618 with patch ("sys.stdout" , new_callable = StringIO ) as mock_stdout :
616619 exit_code = app .invoke_command (
617620 argparse .Namespace (
@@ -622,16 +625,17 @@ def test_invoke_command_makes_http_request_to_start_execution_endpoint() -> None
622625 )
623626
624627 assert exit_code == 0
625- mock_post .assert_called_once ()
628+ mock_urlopen .assert_called_once ()
626629
627630 # Verify the request details
628- call_args = mock_post .call_args
629- assert call_args [0 ][0 ].endswith ("/start-durable-execution" )
630- assert call_args [1 ]["headers" ]["Content-Type" ] == "application/json"
631+ call_args = mock_urlopen .call_args
632+ req = call_args [0 ][0 ]
633+ assert req .full_url .endswith ("/start-durable-execution" )
634+ assert req .get_header ("Content-type" ) == "application/json"
631635 assert call_args [1 ]["timeout" ] == 30
632636
633637 # Verify payload structure
634- payload = call_args [ 1 ][ " json" ]
638+ payload = json . loads ( req . data . decode ( "utf-8" ))
635639 assert payload ["FunctionName" ] == "test-function"
636640 assert payload ["Input" ] == '{"key": "value"}'
637641 assert payload ["ExecutionName" ] == "test-execution"
@@ -645,11 +649,13 @@ def test_invoke_command_uses_default_execution_name_when_not_provided() -> None:
645649 """Test that invoke command generates default execution name when not provided."""
646650 app = CliApp ()
647651
648- with patch ("requests.post" ) as mock_post :
649- mock_response = mock_post .return_value
650- mock_response .status_code = 201
651- mock_response .json .return_value = {"ExecutionArn" : "test-arn" }
652+ response_body = json .dumps ({"ExecutionArn" : "test-arn" }).encode ("utf-8" )
653+ mock_response = Mock ()
654+ mock_response .read .return_value = response_body
655+ mock_response .__enter__ = Mock (return_value = mock_response )
656+ mock_response .__exit__ = Mock (return_value = False )
652657
658+ with patch ("aws_durable_execution_sdk_python_testing.cli.urlopen" , return_value = mock_response ) as mock_urlopen :
653659 app .invoke_command (
654660 argparse .Namespace (
655661 function_name = "my-function" ,
@@ -659,18 +665,17 @@ def test_invoke_command_uses_default_execution_name_when_not_provided() -> None:
659665 )
660666
661667 # Verify default execution name is generated
662- payload = mock_post .call_args [1 ]["json" ]
668+ req = mock_urlopen .call_args [0 ][0 ]
669+ payload = json .loads (req .data .decode ("utf-8" ))
663670 assert payload ["ExecutionName" ] == "my-function-execution"
664671
665672
666673def test_invoke_command_handles_connection_error () -> None :
667674 """Test that invoke command handles connection errors gracefully."""
668675 app = CliApp ()
669676
670- with patch ("requests.post" ) as mock_post :
671- mock_post .side_effect = requests .exceptions .ConnectionError (
672- "Connection refused"
673- )
677+ with patch ("aws_durable_execution_sdk_python_testing.cli.urlopen" ) as mock_urlopen :
678+ mock_urlopen .side_effect = URLError ("Connection refused" )
674679
675680 exit_code = app .invoke_command (
676681 argparse .Namespace (
@@ -687,8 +692,8 @@ def test_invoke_command_handles_timeout_error() -> None:
687692 """Test that invoke command handles timeout errors gracefully."""
688693 app = CliApp ()
689694
690- with patch ("requests.post " ) as mock_post :
691- mock_post .side_effect = requests . exceptions . Timeout ("Request timed out" )
695+ with patch ("aws_durable_execution_sdk_python_testing.cli.urlopen " ) as mock_urlopen :
696+ mock_urlopen .side_effect = TimeoutError ("Request timed out" )
692697
693698 exit_code = app .invoke_command (
694699 argparse .Namespace (
@@ -705,13 +710,19 @@ def test_invoke_command_handles_http_error_response() -> None:
705710 """Test that invoke command handles HTTP error responses."""
706711 app = CliApp ()
707712
708- with patch ("requests.post" ) as mock_post :
709- mock_response = mock_post .return_value
710- mock_response .status_code = 400
711- mock_response .json .return_value = {
712- "ErrorMessage" : "Invalid parameter value" ,
713- "ErrorType" : "InvalidParameterValueException" ,
714- }
713+ error_body = json .dumps ({
714+ "ErrorMessage" : "Invalid parameter value" ,
715+ "ErrorType" : "InvalidParameterValueException" ,
716+ }).encode ("utf-8" )
717+
718+ with patch ("aws_durable_execution_sdk_python_testing.cli.urlopen" ) as mock_urlopen :
719+ mock_urlopen .side_effect = HTTPError (
720+ url = "http://0.0.0.0:5000/start-durable-execution" ,
721+ code = 400 ,
722+ msg = "Bad Request" ,
723+ hdrs = None ,
724+ fp = __import__ ("io" ).BytesIO (error_body ),
725+ )
715726
716727 with patch ("sys.stderr" , new_callable = StringIO ) as mock_stderr :
717728 exit_code = app .invoke_command (
@@ -730,11 +741,14 @@ def test_invoke_command_handles_non_json_error_response() -> None:
730741 """Test that invoke command handles non-JSON error responses."""
731742 app = CliApp ()
732743
733- with patch ("requests.post" ) as mock_post :
734- mock_response = mock_post .return_value
735- mock_response .status_code = 500
736- mock_response .json .side_effect = json .JSONDecodeError ("Invalid JSON" , "" , 0 )
737- mock_response .text = "Internal Server Error"
744+ with patch ("aws_durable_execution_sdk_python_testing.cli.urlopen" ) as mock_urlopen :
745+ mock_urlopen .side_effect = HTTPError (
746+ url = "http://0.0.0.0:5000/start-durable-execution" ,
747+ code = 500 ,
748+ msg = "Internal Server Error" ,
749+ hdrs = None ,
750+ fp = __import__ ("io" ).BytesIO (b"Internal Server Error" ),
751+ )
738752
739753 exit_code = app .invoke_command (
740754 argparse .Namespace (
@@ -1050,8 +1064,8 @@ def test_invoke_command_handles_general_exception() -> None:
10501064 """Test that invoke command handles general exceptions."""
10511065 app = CliApp ()
10521066
1053- with patch ("requests.post " ) as mock_post :
1054- mock_post .side_effect = ValueError ("Some unexpected error" )
1067+ with patch ("aws_durable_execution_sdk_python_testing.cli.urlopen " ) as mock_urlopen :
1068+ mock_urlopen .side_effect = ValueError ("Some unexpected error" )
10551069
10561070 exit_code = app .invoke_command (
10571071 argparse .Namespace (
0 commit comments