3737from apache_beam .portability .api import beam_fn_api_pb2_grpc
3838from apache_beam .portability .api import beam_runner_api_pb2
3939from apache_beam .portability .api import metrics_pb2
40+ from apache_beam .runners .worker import data_plane
4041from apache_beam .runners .worker import sdk_worker
4142from apache_beam .runners .worker import statecache
4243from apache_beam .runners .worker .sdk_worker import BundleProcessorCache
@@ -126,7 +127,10 @@ def test_fn_registration(self):
126127
127128 def test_inactive_bundle_processor_returns_empty_progress_response (self ):
128129 bundle_processor = mock .MagicMock ()
129- bundle_processor_cache = BundleProcessorCache (None , None , None , {})
130+ data_channel_factory = mock .create_autospec (
131+ data_plane .GrpcClientDataChannelFactory )
132+ bundle_processor_cache = BundleProcessorCache (
133+ None , None , data_channel_factory , {})
130134 bundle_processor_cache .activate ('instruction_id' )
131135 worker = SdkWorker (bundle_processor_cache )
132136 split_request = beam_fn_api_pb2 .InstructionRequest (
@@ -153,7 +157,8 @@ def test_inactive_bundle_processor_returns_empty_progress_response(self):
153157
154158 def test_failed_bundle_processor_returns_failed_progress_response (self ):
155159 bundle_processor = mock .MagicMock ()
156- data_channel_factory = mock .MagicMock ()
160+ data_channel_factory = mock .create_autospec (
161+ data_plane .GrpcClientDataChannelFactory )
157162 bundle_processor_cache = BundleProcessorCache (
158163 None , None , data_channel_factory , {})
159164 bundle_processor_cache .activate ('instruction_id' )
@@ -178,7 +183,10 @@ def test_failed_bundle_processor_returns_failed_progress_response(self):
178183
179184 def test_inactive_bundle_processor_returns_empty_split_response (self ):
180185 bundle_processor = mock .MagicMock ()
181- bundle_processor_cache = BundleProcessorCache (None , None , None , {})
186+ data_channel_factory = mock .create_autospec (
187+ data_plane .GrpcClientDataChannelFactory )
188+ bundle_processor_cache = BundleProcessorCache (
189+ None , None , data_channel_factory , {})
182190 bundle_processor_cache .activate ('instruction_id' )
183191 worker = SdkWorker (bundle_processor_cache )
184192 split_request = beam_fn_api_pb2 .InstructionRequest (
@@ -264,7 +272,8 @@ def test_harness_monitoring_infos_and_metadata(self):
264272
265273 def test_failed_bundle_processor_returns_failed_split_response (self ):
266274 bundle_processor = mock .MagicMock ()
267- data_channel_factory = mock .MagicMock ()
275+ data_channel_factory = mock .create_autospec (
276+ data_plane .GrpcClientDataChannelFactory )
268277 bundle_processor_cache = BundleProcessorCache (
269278 None , None , data_channel_factory , {})
270279 bundle_processor_cache .activate ('instruction_id' )
@@ -342,6 +351,29 @@ def stop(self):
342351
343352 self .assertEqual (response , expected_response )
344353
354+ def test_bundle_processor_creation_failure_cleans_up_grpc_data_channel (self ):
355+ data_channel_factory = data_plane .GrpcClientDataChannelFactory ()
356+ channel = data_channel_factory .create_data_channel_from_url ('some_url' )
357+ state_handler_factory = mock .create_autospec (
358+ sdk_worker .GrpcStateHandlerFactory )
359+ bundle_processor_cache = BundleProcessorCache (
360+ frozenset (), state_handler_factory , data_channel_factory , {})
361+ if bundle_processor_cache .periodic_shutdown :
362+ bundle_processor_cache .periodic_shutdown .cancel ()
363+
364+ bundle_processor_cache .get = mock .MagicMock (
365+ side_effect = RuntimeError ('test error' ))
366+
367+ worker = SdkWorker (bundle_processor_cache )
368+ instruction_id = 'instruction_id'
369+ request = beam_fn_api_pb2 .ProcessBundleRequest (
370+ process_bundle_descriptor_id = 'descriptor_id' )
371+
372+ with self .assertRaises (RuntimeError ):
373+ worker .process_bundle (request , instruction_id )
374+
375+ self .assertIn (instruction_id , channel ._cleaned_instruction_ids )
376+
345377
346378class CachingStateHandlerTest (unittest .TestCase ):
347379 def test_caching (self ):
0 commit comments