Skip to content

Commit b41069b

Browse files
committed
Correct test failures
LocalAppContextSwitchesHelper was returning the field values, skipping the default values exposed by LocalAppContextSwitches when the AppContext switch had not been set one way or another.
1 parent f6fcc32 commit b41069b

1 file changed

Lines changed: 63 additions & 42 deletions

File tree

src/Microsoft.Data.SqlClient/tests/Common/LocalAppContextSwitchesHelper.cs

Lines changed: 63 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,8 @@ public void Dispose()
204204

205205
#region Switch Value Getters and Setters
206206

207-
// These properties get or set the like-named underlying switch field value.
207+
// These properties get the like-named underlying switch *property* value and set the underlying
208+
// switch *field* value. This allows tests to verify the default switch values.
208209
//
209210
// They all throw if the value cannot be retrieved or set.
210211

@@ -214,7 +215,7 @@ public void Dispose()
214215
/// </summary>
215216
public bool? DisableTnirByDefault
216217
{
217-
get => GetSwitchValue("s_disableTnirByDefault");
218+
get => GetSwitchPropertyValue(nameof(DisableTnirByDefault));
218219
set => SetSwitchValue("s_disableTnirByDefault", value);
219220
}
220221
#endif
@@ -224,7 +225,7 @@ public bool? DisableTnirByDefault
224225
/// </summary>
225226
public bool? EnableMultiSubnetFailoverByDefault
226227
{
227-
get => GetSwitchValue("s_enableMultiSubnetFailoverByDefault");
228+
get => GetSwitchPropertyValue(nameof(EnableMultiSubnetFailoverByDefault));
228229
set => SetSwitchValue("s_enableMultiSubnetFailoverByDefault", value);
229230
}
230231

@@ -234,7 +235,7 @@ public bool? EnableMultiSubnetFailoverByDefault
234235
/// </summary>
235236
public bool? GlobalizationInvariantMode
236237
{
237-
get => GetSwitchValue("s_globalizationInvariantMode");
238+
get => GetSwitchPropertyValue(nameof(GlobalizationInvariantMode));
238239
set => SetSwitchValue("s_globalizationInvariantMode", value);
239240
}
240241
#endif
@@ -244,7 +245,7 @@ public bool? GlobalizationInvariantMode
244245
/// </summary>
245246
public bool? IgnoreServerProvidedFailoverPartner
246247
{
247-
get => GetSwitchValue("s_ignoreServerProvidedFailoverPartner");
248+
get => GetSwitchPropertyValue(nameof(IgnoreServerProvidedFailoverPartner));
248249
set => SetSwitchValue("s_ignoreServerProvidedFailoverPartner", value);
249250
}
250251

@@ -253,7 +254,7 @@ public bool? IgnoreServerProvidedFailoverPartner
253254
/// </summary>
254255
public bool? UseLegacyFailoverAlternationOnLoginSqlErrors
255256
{
256-
get => GetSwitchValue("s_useLegacyFailoverAlternationOnLoginSqlErrors");
257+
get => GetSwitchPropertyValue(nameof(UseLegacyFailoverAlternationOnLoginSqlErrors));
257258
set => SetSwitchValue("s_useLegacyFailoverAlternationOnLoginSqlErrors", value);
258259
}
259260

@@ -262,7 +263,7 @@ public bool? UseLegacyFailoverAlternationOnLoginSqlErrors
262263
/// </summary>
263264
public bool? LegacyRowVersionNullBehavior
264265
{
265-
get => GetSwitchValue("s_legacyRowVersionNullBehavior");
266+
get => GetSwitchPropertyValue(nameof(LegacyRowVersionNullBehavior));
266267
set => SetSwitchValue("s_legacyRowVersionNullBehavior", value);
267268
}
268269

@@ -271,7 +272,7 @@ public bool? LegacyRowVersionNullBehavior
271272
/// </summary>
272273
public bool? LegacyVarTimeZeroScaleBehaviour
273274
{
274-
get => GetSwitchValue("s_legacyVarTimeZeroScaleBehaviour");
275+
get => GetSwitchPropertyValue(nameof(LegacyVarTimeZeroScaleBehaviour));
275276
set => SetSwitchValue("s_legacyVarTimeZeroScaleBehaviour", value);
276277
}
277278

@@ -280,7 +281,7 @@ public bool? LegacyVarTimeZeroScaleBehaviour
280281
/// </summary>
281282
public bool? MakeReadAsyncBlocking
282283
{
283-
get => GetSwitchValue("s_makeReadAsyncBlocking");
284+
get => GetSwitchPropertyValue(nameof(MakeReadAsyncBlocking));
284285
set => SetSwitchValue("s_makeReadAsyncBlocking", value);
285286
}
286287

@@ -289,7 +290,7 @@ public bool? MakeReadAsyncBlocking
289290
/// </summary>
290291
public bool? SuppressInsecureTlsWarning
291292
{
292-
get => GetSwitchValue("s_suppressInsecureTlsWarning");
293+
get => GetSwitchPropertyValue(nameof(SuppressInsecureTlsWarning));
293294
set => SetSwitchValue("s_suppressInsecureTlsWarning", value);
294295
}
295296

@@ -298,7 +299,7 @@ public bool? SuppressInsecureTlsWarning
298299
/// </summary>
299300
public bool? TruncateScaledDecimal
300301
{
301-
get => GetSwitchValue("s_truncateScaledDecimal");
302+
get => GetSwitchPropertyValue(nameof(TruncateScaledDecimal));
302303
set => SetSwitchValue("s_truncateScaledDecimal", value);
303304
}
304305

@@ -307,7 +308,7 @@ public bool? TruncateScaledDecimal
307308
/// </summary>
308309
public bool? UseCompatibilityAsyncBehaviour
309310
{
310-
get => GetSwitchValue("s_useCompatibilityAsyncBehaviour");
311+
get => GetSwitchPropertyValue(nameof(UseCompatibilityAsyncBehaviour));
311312
set => SetSwitchValue("s_useCompatibilityAsyncBehaviour", value);
312313
}
313314

@@ -316,7 +317,7 @@ public bool? UseCompatibilityAsyncBehaviour
316317
/// </summary>
317318
public bool? UseCompatibilityProcessSni
318319
{
319-
get => GetSwitchValue("s_useCompatibilityProcessSni");
320+
get => GetSwitchPropertyValue(nameof(UseCompatibilityProcessSni));
320321
set => SetSwitchValue("s_useCompatibilityProcessSni", value);
321322
}
322323

@@ -325,7 +326,7 @@ public bool? UseCompatibilityProcessSni
325326
/// </summary>
326327
public bool? UseConnectionPoolV2
327328
{
328-
get => GetSwitchValue("s_useConnectionPoolV2");
329+
get => GetSwitchPropertyValue(nameof(UseConnectionPoolV2));
329330
set => SetSwitchValue("s_useConnectionPoolV2", value);
330331
}
331332

@@ -335,7 +336,7 @@ public bool? UseConnectionPoolV2
335336
/// </summary>
336337
public bool? UseManagedNetworking
337338
{
338-
get => GetSwitchValue("s_useManagedNetworking");
339+
get => GetSwitchPropertyValue(nameof(UseManagedNetworking));
339340
set => SetSwitchValue("s_useManagedNetworking", value);
340341
}
341342
#endif
@@ -345,7 +346,7 @@ public bool? UseManagedNetworking
345346
/// </summary>
346347
public bool? UseMinimumLoginTimeout
347348
{
348-
get => GetSwitchValue("s_useMinimumLoginTimeout");
349+
get => GetSwitchPropertyValue(nameof(UseMinimumLoginTimeout));
349350
set => SetSwitchValue("s_useMinimumLoginTimeout", value);
350351
}
351352

@@ -358,19 +359,7 @@ public bool? UseMinimumLoginTimeout
358359
/// </summary>
359360
private static bool? GetSwitchValue(string fieldName)
360361
{
361-
var assembly = Assembly.GetAssembly(typeof(SqlConnection));
362-
if (assembly is null)
363-
{
364-
throw new InvalidOperationException(
365-
"Could not get assembly for Microsoft.Data.SqlClient");
366-
}
367-
368-
var type = assembly.GetType("Microsoft.Data.SqlClient.LocalAppContextSwitches");
369-
if (type is null)
370-
{
371-
throw new InvalidOperationException(
372-
"Could not get type LocalAppContextSwitches");
373-
}
362+
var type = GetLocalAppContextSwitchesType();
374363

375364
var field = type.GetField(
376365
fieldName,
@@ -405,19 +394,7 @@ public bool? UseMinimumLoginTimeout
405394
/// </summary>
406395
private static void SetSwitchValue(string fieldName, bool? value)
407396
{
408-
var assembly = Assembly.GetAssembly(typeof(SqlConnection));
409-
if (assembly is null)
410-
{
411-
throw new InvalidOperationException(
412-
"Could not get assembly for Microsoft.Data.SqlClient");
413-
}
414-
415-
var type = assembly.GetType("Microsoft.Data.SqlClient.LocalAppContextSwitches");
416-
if (type is null)
417-
{
418-
throw new InvalidOperationException(
419-
"Could not get type LocalAppContextSwitches");
420-
}
397+
var type = GetLocalAppContextSwitchesType();
421398

422399
var field = type.GetField(
423400
fieldName,
@@ -442,5 +419,49 @@ private static void SetSwitchValue(string fieldName, bool? value)
442419
field.SetValue(null, Enum.ToObject(field.FieldType, byteValue));
443420
}
444421

422+
/// <summary>
423+
/// Use reflection to get a switch property value from LocalAppContextSwitches.
424+
/// </summary>
425+
/// <remarks>
426+
/// Each property in LocalAppContextSwitchHelper corresponds to a like-named property in
427+
/// LocalAppContextSwitches, which may return a different value when the AppContext switch
428+
/// has not been set.
429+
/// </remarks>
430+
private static bool GetSwitchPropertyValue(string propertyName)
431+
{
432+
var type = GetLocalAppContextSwitchesType();
433+
var property = type.GetProperty(
434+
propertyName,
435+
BindingFlags.Static | BindingFlags.Public);
436+
437+
if (property == null)
438+
{
439+
throw new InvalidOperationException(
440+
$"Property '{propertyName}' not found in LocalAppContextSwitches");
441+
}
442+
443+
object? value = property.GetValue(null);
444+
445+
return value is bool boolValue
446+
? boolValue
447+
: throw new InvalidOperationException($"Property '{propertyName}' is not of type bool.");
448+
}
449+
450+
private static Type GetLocalAppContextSwitchesType()
451+
{
452+
var assembly = Assembly.GetAssembly(typeof(SqlConnection));
453+
if (assembly is null)
454+
{
455+
throw new InvalidOperationException("Could not get assembly for Microsoft.Data.SqlClient");
456+
}
457+
458+
var type = assembly.GetType("Microsoft.Data.SqlClient.LocalAppContextSwitches");
459+
if (type is null)
460+
{
461+
throw new InvalidOperationException("Could not get type LocalAppContextSwitches");
462+
}
463+
return type;
464+
}
465+
445466
#endregion
446467
}

0 commit comments

Comments
 (0)