11import threading
22import time
3+ import typing
34import unittest
45from unittest .mock import MagicMock , Mock , patch
56
@@ -39,10 +40,12 @@ def setUp(self):
3940
4041 flag_store = Mock (spec = FlagStore )
4142 flag_store .update .return_value = None
42- self .emit_provider_ready = Mock ()
4343 emit_provider_error = Mock ()
4444 emit_provider_stale = Mock ()
4545 channel = Mock (spec = Channel )
46+ self .provider_done = False
47+ self .provider_details : typing .Optional [ProviderEventDetails ] = None
48+ self .context : typing .Optional [dict ] = None
4649
4750 with patch (
4851 "openfeature.contrib.provider.flagd.resolvers.process.connector.grpc_watcher.GrpcWatcher._generate_channel" ,
@@ -51,7 +54,7 @@ def setUp(self):
5154 self .grpc_watcher = GrpcWatcher (
5255 config = config ,
5356 flag_store = flag_store ,
54- emit_provider_ready = self .emit_provider_ready ,
57+ emit_provider_ready = self .provider_ready ,
5558 emit_provider_error = emit_provider_error ,
5659 emit_provider_stale = emit_provider_stale ,
5760 )
@@ -61,6 +64,23 @@ def setUp(self):
6164 self .grpc_watcher .stub = self .mock_stub
6265 self .grpc_watcher .active = True
6366
67+ def provider_ready (self , details : ProviderEventDetails , context : dict ):
68+ self .provider_done = True
69+ self .provider_details = details
70+ self .context = context
71+
72+ def run_listen_and_shutdown_after (self ):
73+ listener = threading .Thread (target = self .grpc_watcher .listen )
74+ listener .start ()
75+ for _i in range (0 , 100 ):
76+ if self .provider_done :
77+ break
78+ time .sleep (0.001 )
79+
80+ self .assertTrue (self .provider_done )
81+ self .grpc_watcher .shutdown ()
82+ listener .join (timeout = 0.5 )
83+
6484 def test_listen_with_sync_metadata_and_sync_context (self ):
6585 sync_context = Struct ()
6686 sync_context .update ({"attribute" : "value" })
@@ -74,17 +94,12 @@ def test_listen_with_sync_metadata_and_sync_context(self):
7494 )
7595 self .mock_stub .SyncFlags = Mock (return_value = mock_stream_with_sync_context )
7696
77- listener = threading .Thread (target = self .grpc_watcher .listen )
78- listener .start ()
79-
80- time .sleep (0.5 )
81- self .grpc_watcher .shutdown ()
82- listener .join (timeout = 1 )
97+ self .run_listen_and_shutdown_after ()
8398
84- self .emit_provider_ready .assert_called_once_with (
85- ProviderEventDetails (message = "gRPC sync connection established" ),
86- MessageToDict (sync_context ),
99+ self .assertEqual (
100+ self .provider_details .message , "gRPC sync connection established"
87101 )
102+ self .assertEqual (self .context , MessageToDict (sync_context ))
88103
89104 def test_listen_with_sync_metadata_only (self ):
90105 mock_stream_no_sync_context = iter (
@@ -94,17 +109,12 @@ def test_listen_with_sync_metadata_only(self):
94109 )
95110 self .mock_stub .SyncFlags = Mock (return_value = mock_stream_no_sync_context )
96111
97- listener = threading .Thread (target = self .grpc_watcher .listen )
98- listener .start ()
99-
100- time .sleep (0.5 )
101- self .grpc_watcher .shutdown ()
102- listener .join (timeout = 1 )
112+ self .run_listen_and_shutdown_after ()
103113
104- self .emit_provider_ready .assert_called_once_with (
105- ProviderEventDetails (message = "gRPC sync connection established" ),
106- MessageToDict (self .mock_metadata .metadata ),
114+ self .assertEqual (
115+ self .provider_details .message , "gRPC sync connection established"
107116 )
117+ self .assertEqual (self .context , MessageToDict (self .mock_metadata .metadata ))
108118
109119 def test_listen_with_sync_metadata_disabled_in_config (self ):
110120 self .grpc_watcher .config .sync_metadata_disabled = True
@@ -115,15 +125,11 @@ def test_listen_with_sync_metadata_disabled_in_config(self):
115125 )
116126 self .mock_stub .SyncFlags = Mock (return_value = mock_stream_no_sync_context )
117127
118- listener = threading .Thread (target = self .grpc_watcher .listen )
119- listener .start ()
120-
121- time .sleep (0.5 )
122- self .grpc_watcher .shutdown ()
123- listener .join (timeout = 1 )
128+ self .run_listen_and_shutdown_after ()
124129
125130 self .mock_stub .GetMetadata .assert_not_called ()
126131
127- self .emit_provider_ready . assert_called_once_with (
128- ProviderEventDetails ( message = "gRPC sync connection established" ), {}
132+ self .assertEqual (
133+ self . provider_details . message , "gRPC sync connection established"
129134 )
135+ self .assertEqual (self .context , {})
0 commit comments