55
66import dataclasses
77import pathlib
8+ from datetime import timedelta
89from unittest import mock
910
1011import pytest
1314
1415from frequenz .client .base .channel import (
1516 ChannelOptions ,
17+ KeepAliveOptions ,
1618 SslOptions ,
1719 _to_bool ,
1820 parse_grpc_uri ,
@@ -136,6 +138,70 @@ class _ValidUrlTestCase:
136138 ),
137139 ),
138140 ),
141+ _ValidUrlTestCase (
142+ title = "Keep-alive no defaults" ,
143+ uri = "grpc://localhost:1234" ,
144+ defaults = ChannelOptions (
145+ keep_alive = KeepAliveOptions (
146+ enabled = True ,
147+ interval = timedelta (minutes = 5 ),
148+ timeout = timedelta (minutes = 1 ),
149+ ),
150+ ),
151+ expected_host = "localhost" ,
152+ expected_port = 1234 ,
153+ expected_options = ChannelOptions (
154+ keep_alive = KeepAliveOptions (
155+ enabled = True ,
156+ interval = timedelta (minutes = 5 ),
157+ timeout = timedelta (minutes = 1 ),
158+ ),
159+ ),
160+ ),
161+ _ValidUrlTestCase (
162+ title = "Keep-alive default timeout" ,
163+ uri = "grpc://localhost:1234" ,
164+ defaults = ChannelOptions (
165+ keep_alive = KeepAliveOptions (
166+ enabled = False , interval = timedelta (minutes = 5 )
167+ ),
168+ ),
169+ expected_host = "localhost" ,
170+ expected_port = 1234 ,
171+ expected_options = ChannelOptions (
172+ keep_alive = KeepAliveOptions (
173+ enabled = False , interval = timedelta (minutes = 5 )
174+ ),
175+ ),
176+ ),
177+ _ValidUrlTestCase (
178+ title = "Keep-alive default interval" ,
179+ uri = "grpc://localhost:1234" ,
180+ defaults = ChannelOptions (
181+ keep_alive = KeepAliveOptions (enabled = True , timeout = timedelta (minutes = 1 )),
182+ ),
183+ expected_host = "localhost" ,
184+ expected_port = 1234 ,
185+ expected_options = ChannelOptions (
186+ keep_alive = KeepAliveOptions (enabled = True , timeout = timedelta (minutes = 1 )),
187+ ),
188+ ),
189+ _ValidUrlTestCase (
190+ title = "keep-alive no defaults" ,
191+ uri = "grpc://localhost:1234" ,
192+ defaults = ChannelOptions (
193+ keep_alive = KeepAliveOptions (
194+ enabled = False , interval = None , timeout = timedelta (minutes = 1 )
195+ ),
196+ ),
197+ expected_host = "localhost" ,
198+ expected_port = 1234 ,
199+ expected_options = ChannelOptions (
200+ keep_alive = KeepAliveOptions (
201+ enabled = False , interval = None , timeout = timedelta (minutes = 1 )
202+ ),
203+ ),
204+ ),
139205 ],
140206 ids = lambda case : case .title ,
141207)
@@ -198,6 +264,22 @@ def test_parse_uri_ok( # pylint: disable=too-many-locals
198264
199265 assert channel == expected_channel
200266 expected_target = f"{ expected_host } :{ expected_port } "
267+ expected_channel_options = (
268+ [
269+ ("grpc.http2.max_pings_without_data" , 0 ),
270+ ("grpc.keepalive_permit_without_calls" , 1 ),
271+ (
272+ "grpc.keepalive_time_ms" ,
273+ (defaults .keep_alive .interval .total_seconds () * 1000 ),
274+ ),
275+ (
276+ "grpc.keepalive_timeout_ms" ,
277+ defaults .keep_alive .timeout .total_seconds () * 1000 ,
278+ ),
279+ ]
280+ if defaults .keep_alive .enabled and defaults .keep_alive .interval
281+ else None
282+ )
201283 if expected_ssl :
202284 if isinstance (expected_root_certificates , pathlib .Path ):
203285 get_contents_mock .assert_any_call (
@@ -223,10 +305,12 @@ def test_parse_uri_ok( # pylint: disable=too-many-locals
223305 certificate_chain = expected_certificate_chain ,
224306 )
225307 secure_channel_mock .assert_called_once_with (
226- expected_target , expected_credentials
308+ expected_target , expected_credentials , expected_channel_options
227309 )
228310 else :
229- insecure_channel_mock .assert_called_once_with (expected_target )
311+ insecure_channel_mock .assert_called_once_with (
312+ expected_target , expected_channel_options
313+ )
230314
231315
232316@pytest .mark .parametrize ("value" , ["true" , "on" , "1" , "TrUe" , "On" , "ON" , "TRUE" ])
0 commit comments