@@ -24,17 +24,24 @@ impl ConfigWorld {
2424
2525 fn clear ( & mut self ) {
2626 // SAFETY: Removing environment variables is safe here because:
27- // 1. We're only removing variables that were set during this specific test scenario
28- // 2. The test is protected by #[serial_test::serial]
29- // 3. This prevents test pollution between scenarios
30- // 4. All variables being removed are tracked in world.env_vars
27+ // 1. The test is protected by #[serial_test::serial]
28+ // 2. This prevents test pollution between scenarios
29+ // 3. We clear env vars that were set in previous scenarios
30+
31+ // Clear env vars that were set in the previous scenario
3132 for key in self . env_vars . keys ( ) {
3233 unsafe {
3334 std:: env:: remove_var ( key) ;
3435 }
3536 }
36- self . env_vars . clear ( ) ;
3737
38+ // Also explicitly clear FLAGD_OFFLINE_FLAG_SOURCE_PATH because it can affect resolver type
39+ // via FlagdOptions::default() logic, even if not tracked in world.env_vars
40+ unsafe {
41+ std:: env:: remove_var ( "FLAGD_OFFLINE_FLAG_SOURCE_PATH" ) ;
42+ }
43+
44+ self . env_vars . clear ( ) ;
3845 self . options = FlagdOptions :: default ( ) ;
3946 self . provider = None ;
4047 self . option_values . clear ( ) ;
@@ -106,43 +113,60 @@ async fn env_with_value(world: &mut ConfigWorld, env: String, value: String) {
106113
107114#[ when( expr = "a config was initialized" ) ]
108115async fn initialize_config ( world : & mut ConfigWorld ) {
116+ // Start with defaults (which reads from environment variables)
109117 let mut options = FlagdOptions :: default ( ) ;
118+ let mut resolver_explicitly_set = false ;
110119
111- // Handle resolver type first
112- if let Some ( resolver) = world. option_values . get ( "resolver" ) {
120+ // Apply env vars from world.env_vars to ensure they take precedence
121+ // This handles cases where env vars were set in test steps but timing issues
122+ // prevent FlagdOptions::default() from reading them correctly
123+ if let Some ( resolver) = world. env_vars . get ( "FLAGD_RESOLVER" ) {
113124 options. resolver_type = match resolver. to_uppercase ( ) . as_str ( ) {
114125 "RPC" => ResolverType :: Rpc ,
115126 "REST" => ResolverType :: Rest ,
116127 "IN-PROCESS" | "INPROCESS" => ResolverType :: InProcess ,
117128 "FILE" | "OFFLINE" => ResolverType :: File ,
118129 _ => ResolverType :: Rpc ,
119130 } ;
120- } else if let Ok ( resolver) = std:: env:: var ( "FLAGD_RESOLVER" ) {
131+ resolver_explicitly_set = true ;
132+ // Update port based on resolver type when set via env var
133+ options. port = match options. resolver_type {
134+ ResolverType :: Rpc => 8013 ,
135+ ResolverType :: InProcess => 8015 ,
136+ _ => options. port ,
137+ } ;
138+ }
139+
140+ // Handle explicit options - these override env vars
141+ if let Some ( resolver) = world. option_values . get ( "resolver" ) {
121142 options. resolver_type = match resolver. to_uppercase ( ) . as_str ( ) {
122143 "RPC" => ResolverType :: Rpc ,
123144 "REST" => ResolverType :: Rest ,
124145 "IN-PROCESS" | "INPROCESS" => ResolverType :: InProcess ,
125146 "FILE" | "OFFLINE" => ResolverType :: File ,
126147 _ => ResolverType :: Rpc ,
127148 } ;
149+ resolver_explicitly_set = true ;
150+ // Update port based on resolver type when explicitly set
151+ options. port = match options. resolver_type {
152+ ResolverType :: Rpc => 8013 ,
153+ ResolverType :: InProcess => 8015 ,
154+ _ => options. port ,
155+ } ;
128156 }
129157
130- // Set default port based on resolver type
131- options. port = match options. resolver_type {
132- ResolverType :: Rpc => 8013 ,
133- ResolverType :: InProcess => 8015 ,
134- _ => options. port ,
135- } ;
136-
137- // Handle source configuration after resolver type
158+ // Handle source configuration - may override resolver type for backwards compatibility
159+ // BUT only if resolver wasn't explicitly set to "rpc"
138160 if let Some ( source) = world. option_values . get ( "offlineFlagSourcePath" ) {
139161 options. source_configuration = Some ( source. clone ( ) ) ;
140- if options. resolver_type != ResolverType :: Rpc {
162+ // For backwards compatibility: if offline path is set, switch to File resolver
163+ // UNLESS resolver was explicitly set to "rpc" (in which case keep it as "rpc")
164+ if !resolver_explicitly_set || options. resolver_type != ResolverType :: Rpc {
141165 options. resolver_type = ResolverType :: File ;
142166 }
143167 }
144168
145- // Handle remaining explicit options
169+ // Handle remaining explicit options (these override env vars)
146170 if let Some ( host) = world. option_values . get ( "host" ) {
147171 options. host = host. clone ( ) ;
148172 }
@@ -217,6 +241,9 @@ async fn initialize_config(world: &mut ConfigWorld) {
217241 if let Some ( selector) = world. option_values . get ( "selector" ) {
218242 options. selector = Some ( selector. clone ( ) ) ;
219243 }
244+ if let Some ( provider_id) = world. option_values . get ( "providerId" ) {
245+ options. provider_id = Some ( provider_id. clone ( ) ) ;
246+ }
220247 if let Some ( max_size) = world
221248 . option_values
222249 . get ( "maxCacheSize" )
@@ -269,12 +296,30 @@ async fn check_option_value(
269296 "retryBackoffMaxMs" => Some ( world. options . retry_backoff_max_ms . to_string ( ) ) ,
270297 "retryGracePeriod" => Some ( world. options . retry_grace_period . to_string ( ) ) ,
271298 "selector" => world. options . selector . clone ( ) ,
299+ "providerId" => world. options . provider_id . clone ( ) ,
272300 "socketPath" => world. options . socket_path . clone ( ) ,
273301 "streamDeadlineMs" => Some ( world. options . stream_deadline_ms . to_string ( ) ) ,
274302 _ => None ,
275303 } ;
276304 let expected = convert_type ( & option_type, & value) ;
277- assert_eq ! ( actual, expected, "Option '{}' value mismatch" , option) ;
305+
306+ // For resolver type, do case-insensitive comparison since enum normalizes to lowercase
307+ let actual_normalized = if option == "resolver" {
308+ actual. as_ref ( ) . map ( |v| v. to_lowercase ( ) )
309+ } else {
310+ actual. clone ( )
311+ } ;
312+ let expected_normalized = if option == "resolver" {
313+ expected. as_ref ( ) . map ( |v| v. to_lowercase ( ) )
314+ } else {
315+ expected. clone ( )
316+ } ;
317+
318+ assert_eq ! (
319+ actual_normalized, expected_normalized,
320+ "Option '{}' value mismatch" ,
321+ option
322+ ) ;
278323}
279324
280325#[ test( tokio:: test) ]
0 commit comments