1+ import threading
12from unittest .mock import Mock
23
34import pytest
45
5- from openfeature .exception import GeneralError
6+ from openfeature .exception import GeneralError , ProviderFatalError
67from openfeature .provider import ProviderStatus
78from openfeature .provider ._registry import ProviderRegistry
89from openfeature .provider .no_op_provider import NoOpProvider
@@ -67,8 +68,8 @@ def test_registering_provider_for_first_time_initializes_it():
6768 registry = ProviderRegistry ()
6869 provider = Mock ()
6970
70- registry .set_provider ("domain1" , provider )
71- registry .set_provider ("domain2" , provider )
71+ registry .set_provider ("domain1" , provider , wait_for_init = True )
72+ registry .set_provider ("domain2" , provider , wait_for_init = True )
7273
7374 provider .initialize .assert_called_once ()
7475
@@ -103,7 +104,7 @@ def test_setting_default_provider_initializes_it():
103104 registry = ProviderRegistry ()
104105 provider = Mock ()
105106
106- registry .set_default_provider (provider )
107+ registry .set_default_provider (provider , wait_for_init = True )
107108
108109 provider .initialize .assert_called_once ()
109110
@@ -114,8 +115,8 @@ def test_registering_provider_as_default_then_domain_only_initializes_once():
114115 registry = ProviderRegistry ()
115116 provider = Mock ()
116117
117- registry .set_default_provider (provider )
118- registry .set_provider ("domain" , provider )
118+ registry .set_default_provider (provider , wait_for_init = True )
119+ registry .set_provider ("domain" , provider , wait_for_init = True )
119120
120121 provider .initialize .assert_called_once ()
121122
@@ -126,8 +127,8 @@ def test_registering_provider_as_domain_then_default_only_initializes_once():
126127 registry = ProviderRegistry ()
127128 provider = Mock ()
128129
129- registry .set_provider ("domain" , provider )
130- registry .set_default_provider (provider )
130+ registry .set_provider ("domain" , provider , wait_for_init = True )
131+ registry .set_default_provider (provider , wait_for_init = True )
131132
132133 provider .initialize .assert_called_once ()
133134
@@ -191,7 +192,7 @@ def test_initializing_provider_sets_status_ready():
191192
192193 assert registry .get_provider_status (provider ) == ProviderStatus .NOT_READY
193194
194- registry .set_provider ("domain" , provider )
195+ registry .set_provider ("domain" , provider , wait_for_init = True )
195196
196197 provider .initialize .assert_called_once ()
197198 assert registry .get_provider_status (provider ) == ProviderStatus .READY
@@ -203,7 +204,7 @@ def test_shutting_down_provider_sets_status_not_ready():
203204 registry = ProviderRegistry ()
204205 provider = Mock ()
205206
206- registry .set_provider ("domain" , provider )
207+ registry .set_provider ("domain" , provider , wait_for_init = True )
207208 assert registry .get_provider_status (provider ) == ProviderStatus .READY
208209
209210 registry .shutdown ()
@@ -216,8 +217,8 @@ def test_clearing_registry_resets_providers_and_default():
216217 registry = ProviderRegistry ()
217218 provider = Mock ()
218219
219- registry .set_provider ("domain" , provider )
220- registry .set_default_provider (provider )
220+ registry .set_provider ("domain" , provider , wait_for_init = True )
221+ registry .set_default_provider (provider , wait_for_init = True )
221222
222223 registry .clear_providers ()
223224
@@ -228,3 +229,53 @@ def test_clearing_registry_resets_providers_and_default():
228229
229230 provider .initialize .assert_called_once ()
230231 provider .shutdown .assert_called_once ()
232+
233+
234+ def test_set_provider_returns_before_initialization_completes ():
235+ """Test that set_provider (non-blocking) returns before initialize finishes."""
236+
237+ registry = ProviderRegistry ()
238+ init_started = threading .Event ()
239+ init_may_proceed = threading .Event ()
240+ provider = Mock ()
241+
242+ def slow_initialize (ctx ):
243+ init_started .set ()
244+ init_may_proceed .wait ()
245+
246+ provider .initialize .side_effect = slow_initialize
247+
248+ registry .set_provider ("domain" , provider )
249+
250+ assert init_started .wait (timeout = 2 ), "initialize was never called in background"
251+ assert registry .get_provider_status (provider ) == ProviderStatus .NOT_READY
252+
253+ init_may_proceed .set () # unblock the background thread
254+
255+
256+ def test_set_provider_and_wait_blocks_until_ready ():
257+ """Test that set_provider with wait_for_init=True blocks until READY."""
258+
259+ registry = ProviderRegistry ()
260+ initialized = threading .Event ()
261+ provider = Mock ()
262+
263+ def tracking_initialize (ctx ):
264+ initialized .set ()
265+
266+ provider .initialize .side_effect = tracking_initialize
267+
268+ registry .set_provider ("domain" , provider , wait_for_init = True )
269+
270+ assert initialized .is_set ()
271+ assert registry .get_provider_status (provider ) == ProviderStatus .READY
272+
273+
274+ def test_set_provider_and_wait_reraises_on_error ():
275+ """Test that set_provider with wait_for_init=True re-raises initialization errors."""
276+ registry = ProviderRegistry ()
277+ provider = Mock ()
278+ provider .initialize .side_effect = ProviderFatalError ()
279+
280+ with pytest .raises (ProviderFatalError ):
281+ registry .set_provider ("domain" , provider , wait_for_init = True )
0 commit comments