1212See the License for the specific language governing permissions and
1313limitations under the License.
1414"""
15+
1516import asyncio
1617import time
1718import unittest
18- from unittest .mock import patch , MagicMock
19+ from unittest .mock import AsyncMock , MagicMock , patch
1920
2021from dapr .aio .clients .health import DaprHealth
2122from dapr .conf import settings
2425
2526class DaprHealthCheckAsyncTests (unittest .IsolatedAsyncioTestCase ):
2627 @patch .object (settings , 'DAPR_HTTP_ENDPOINT' , 'http://domain.com:3500' )
27- @patch ('urllib.request.urlopen' )
28- async def test_wait_until_ready_success (self , mock_urlopen ):
29- mock_urlopen .return_value .__enter__ .return_value = MagicMock (status = 200 )
28+ @patch ('aiohttp.ClientSession.get' )
29+ async def test_wait_for_sidecar_success (self , mock_get ):
30+ # Create mock response
31+ mock_response = MagicMock ()
32+ mock_response .status = 200
33+ mock_response .__aenter__ = AsyncMock (return_value = mock_response )
34+ mock_response .__aexit__ = AsyncMock (return_value = None )
35+ mock_get .return_value = mock_response
3036
3137 try :
32- await DaprHealth .wait_until_ready ()
38+ await DaprHealth .wait_for_sidecar ()
3339 except Exception as e :
34- self .fail (f'wait_until_ready () raised an exception unexpectedly: { e } ' )
40+ self .fail (f'wait_for_sidecar () raised an exception unexpectedly: { e } ' )
3541
36- mock_urlopen .assert_called_once ()
42+ mock_get .assert_called_once ()
3743
38- called_url = mock_urlopen .call_args [0 ][0 ].full_url
44+ # Check URL
45+ called_url = mock_get .call_args [0 ][0 ]
3946 self .assertEqual (called_url , 'http://domain.com:3500/v1.0/healthz/outbound' )
4047
4148 # Check headers are properly set
42- headers = mock_urlopen .call_args [0 ][ 0 ]. headers
43- self .assertIn ('User-agent ' , headers )
44- self .assertEqual (headers ['User-agent ' ], f'dapr-sdk-python/{ __version__ } ' )
49+ headers = mock_get .call_args [1 ][ ' headers' ]
50+ self .assertIn ('User-Agent ' , headers )
51+ self .assertEqual (headers ['User-Agent ' ], f'dapr-sdk-python/{ __version__ } ' )
4552
4653 @patch .object (settings , 'DAPR_HTTP_ENDPOINT' , 'http://domain.com:3500' )
4754 @patch .object (settings , 'DAPR_API_TOKEN' , 'mytoken' )
48- @patch ('urllib.request.urlopen' )
49- async def test_wait_until_ready_success_with_api_token (self , mock_urlopen ):
50- mock_urlopen .return_value .__enter__ .return_value = MagicMock (status = 200 )
55+ @patch ('aiohttp.ClientSession.get' )
56+ async def test_wait_for_sidecar_success_with_api_token (self , mock_get ):
57+ # Create mock response
58+ mock_response = MagicMock ()
59+ mock_response .status = 200
60+ mock_response .__aenter__ = AsyncMock (return_value = mock_response )
61+ mock_response .__aexit__ = AsyncMock (return_value = None )
62+ mock_get .return_value = mock_response
5163
5264 try :
53- await DaprHealth .wait_until_ready ()
65+ await DaprHealth .wait_for_sidecar ()
5466 except Exception as e :
55- self .fail (f'wait_until_ready () raised an exception unexpectedly: { e } ' )
67+ self .fail (f'wait_for_sidecar () raised an exception unexpectedly: { e } ' )
5668
57- mock_urlopen .assert_called_once ()
69+ mock_get .assert_called_once ()
5870
5971 # Check headers are properly set
60- headers = mock_urlopen .call_args [0 ][ 0 ]. headers
61- self .assertIn ('User-agent ' , headers )
62- self .assertEqual (headers ['User-agent ' ], f'dapr-sdk-python/{ __version__ } ' )
63- self .assertIn ('Dapr -api-token' , headers )
64- self .assertEqual (headers ['Dapr -api-token' ], 'mytoken' )
72+ headers = mock_get .call_args [1 ][ ' headers' ]
73+ self .assertIn ('User-Agent ' , headers )
74+ self .assertEqual (headers ['User-Agent ' ], f'dapr-sdk-python/{ __version__ } ' )
75+ self .assertIn ('dapr -api-token' , headers )
76+ self .assertEqual (headers ['dapr -api-token' ], 'mytoken' )
6577
6678 @patch .object (settings , 'DAPR_HEALTH_TIMEOUT' , '2.5' )
67- @patch ('urllib.request.urlopen' )
68- async def test_wait_until_ready_timeout (self , mock_urlopen ):
69- mock_urlopen .return_value .__enter__ .return_value = MagicMock (status = 500 )
79+ @patch ('aiohttp.ClientSession.get' )
80+ async def test_wait_for_sidecar_timeout (self , mock_get ):
81+ # Create mock response that always returns 500
82+ mock_response = MagicMock ()
83+ mock_response .status = 500
84+ mock_response .__aenter__ = AsyncMock (return_value = mock_response )
85+ mock_response .__aexit__ = AsyncMock (return_value = None )
86+ mock_get .return_value = mock_response
7087
7188 start = time .time ()
7289
7390 with self .assertRaises (TimeoutError ):
74- await DaprHealth .wait_until_ready ()
91+ await DaprHealth .wait_for_sidecar ()
7592
7693 self .assertGreaterEqual (time .time () - start , 2.5 )
77- self .assertGreater (mock_urlopen .call_count , 1 )
94+ self .assertGreater (mock_get .call_count , 1 )
7895
7996 @patch .object (settings , 'DAPR_HTTP_ENDPOINT' , 'http://domain.com:3500' )
8097 @patch .object (settings , 'DAPR_HEALTH_TIMEOUT' , '5.0' )
81- @patch ('urllib.request.urlopen ' )
82- async def test_health_check_does_not_block (self , mock_urlopen ):
98+ @patch ('aiohttp.ClientSession.get ' )
99+ async def test_health_check_does_not_block (self , mock_get ):
83100 """Test that health check doesn't block other async tasks from running"""
84101 # Mock health check to retry several times before succeeding
85102 call_count = [0 ] # Use list to allow modification in nested function
86103
87- class MockResponse :
88- def __init__ (self , status ):
89- self .status = status
90-
91- def __enter__ (self ):
92- return self
93-
94- def __exit__ (self , exc_type , exc_val , exc_tb ):
95- return None
96-
97104 def side_effect (* args , ** kwargs ):
98105 call_count [0 ] += 1
99- # First 2 calls fail with URLError , then succeed
106+ # First 2 calls fail with ClientError , then succeed
100107 # This will cause ~2 seconds of retries (1 second sleep after each failure)
101108 if call_count [0 ] <= 2 :
102- import urllib . error
109+ import aiohttp
103110
104- raise urllib . error . URLError ('Connection refused' )
111+ raise aiohttp . ClientError ('Connection refused' )
105112 else :
106- return MockResponse (status = 200 )
113+ mock_response = MagicMock ()
114+ mock_response .status = 200
115+ mock_response .__aenter__ = AsyncMock (return_value = mock_response )
116+ mock_response .__aexit__ = AsyncMock (return_value = None )
117+ return mock_response
107118
108- mock_urlopen .side_effect = side_effect
119+ mock_get .side_effect = side_effect
109120
110121 # Counter that will be incremented by background task
111122 counter = [0 ] # Use list to allow modification in nested function
@@ -122,7 +133,7 @@ async def increment_counter():
122133
123134 try :
124135 # Run health check (will take ~2 seconds with retries)
125- await DaprHealth .wait_until_ready ()
136+ await DaprHealth .wait_for_sidecar ()
126137
127138 # Stop the background task
128139 is_running [0 ] = False
@@ -150,17 +161,22 @@ async def increment_counter():
150161 pass
151162
152163 @patch .object (settings , 'DAPR_HTTP_ENDPOINT' , 'http://domain.com:3500' )
153- @patch ('urllib.request.urlopen ' )
154- async def test_multiple_health_checks_concurrent (self , mock_urlopen ):
164+ @patch ('aiohttp.ClientSession.get ' )
165+ async def test_multiple_health_checks_concurrent (self , mock_get ):
155166 """Test that multiple health check calls can run concurrently"""
156- mock_urlopen .return_value .__enter__ .return_value = MagicMock (status = 200 )
167+ # Create mock response
168+ mock_response = MagicMock ()
169+ mock_response .status = 200
170+ mock_response .__aenter__ = AsyncMock (return_value = mock_response )
171+ mock_response .__aexit__ = AsyncMock (return_value = None )
172+ mock_get .return_value = mock_response
157173
158174 # Run multiple health checks concurrently
159175 start_time = time .time ()
160176 results = await asyncio .gather (
161- DaprHealth .wait_until_ready (),
162- DaprHealth .wait_until_ready (),
163- DaprHealth .wait_until_ready (),
177+ DaprHealth .wait_for_sidecar (),
178+ DaprHealth .wait_for_sidecar (),
179+ DaprHealth .wait_for_sidecar (),
164180 )
165181 elapsed = time .time () - start_time
166182
@@ -174,7 +190,7 @@ async def test_multiple_health_checks_concurrent(self, mock_urlopen):
174190 self .assertLess (elapsed , 1.0 )
175191
176192 # Verify multiple calls were made
177- self .assertGreaterEqual (mock_urlopen .call_count , 3 )
193+ self .assertGreaterEqual (mock_get .call_count , 3 )
178194
179195
180196if __name__ == '__main__' :
0 commit comments