diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..233e6128 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,39 @@ +# editorconfig.org + +# top-most EditorConfig file +root = true + +## Default settings ## +[*] +insert_final_newline = true +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true + +## Formatting rule ## +# https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0055 +dotnet_diagnostic.IDE0055.severity = error + +# 'Using' directive preferences +dotnet_sort_system_directives_first = false + +# New line preferences +dotnet_diagnostic.IDE2002.severity = error +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false +dotnet_diagnostic.IDE2004.severity = error +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false +dotnet_diagnostic.IDE2005.severity = error +csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = false +dotnet_diagnostic.IDE2006.severity = error +csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = false +dotnet_diagnostic.IDE2000.severity = error +dotnet_style_allow_multiple_blank_lines_experimental = false +dotnet_diagnostic.IDE2003.severity = error +dotnet_style_allow_statement_immediately_after_block_experimental = false + +[*.csproj] +indent_size = 2 +charset = utf-8 + +[*.json] +indent_size = 2 \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 00000000..e1220a8d --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,7 @@ + + + + True + + + \ No newline at end of file diff --git a/examples/ConfigStoreDemo/ConfigStoreDemo.csproj b/examples/ConfigStoreDemo/ConfigStoreDemo.csproj index caab5885..a4845d9f 100644 --- a/examples/ConfigStoreDemo/ConfigStoreDemo.csproj +++ b/examples/ConfigStoreDemo/ConfigStoreDemo.csproj @@ -1,17 +1,22 @@ - + + false net8.0 + + + Always + diff --git a/examples/ConfigStoreDemo/Pages/About.cshtml.cs b/examples/ConfigStoreDemo/Pages/About.cshtml.cs index dbbdbbf1..ab5a5b85 100644 --- a/examples/ConfigStoreDemo/Pages/About.cshtml.cs +++ b/examples/ConfigStoreDemo/Pages/About.cshtml.cs @@ -1,10 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. // -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.RazorPages; namespace Microsoft.Extensions.Configuration.AzureAppConfiguration.Examples.ConfigStoreDemo.Pages diff --git a/examples/ConfigStoreDemo/Pages/Contact.cshtml.cs b/examples/ConfigStoreDemo/Pages/Contact.cshtml.cs index 846a4cbc..64453907 100644 --- a/examples/ConfigStoreDemo/Pages/Contact.cshtml.cs +++ b/examples/ConfigStoreDemo/Pages/Contact.cshtml.cs @@ -1,10 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. // -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.RazorPages; namespace Microsoft.Extensions.Configuration.AzureAppConfiguration.Examples.ConfigStoreDemo.Pages diff --git a/examples/ConfigStoreDemo/Pages/Error.cshtml.cs b/examples/ConfigStoreDemo/Pages/Error.cshtml.cs index a75e869d..61725493 100644 --- a/examples/ConfigStoreDemo/Pages/Error.cshtml.cs +++ b/examples/ConfigStoreDemo/Pages/Error.cshtml.cs @@ -1,12 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. // -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.RazorPages; +using System.Diagnostics; namespace Microsoft.Extensions.Configuration.AzureAppConfiguration.Examples.ConfigStoreDemo.Pages { diff --git a/examples/ConsoleApplication/ConsoleApplication.csproj b/examples/ConsoleApplication/ConsoleApplication.csproj index bd4756fa..0b63a9e4 100644 --- a/examples/ConsoleApplication/ConsoleApplication.csproj +++ b/examples/ConsoleApplication/ConsoleApplication.csproj @@ -1,4 +1,4 @@ - + false diff --git a/src/Microsoft.Azure.AppConfiguration.AspNetCore/Microsoft.Azure.AppConfiguration.AspNetCore.csproj b/src/Microsoft.Azure.AppConfiguration.AspNetCore/Microsoft.Azure.AppConfiguration.AspNetCore.csproj index 5c33c144..f11142cc 100644 --- a/src/Microsoft.Azure.AppConfiguration.AspNetCore/Microsoft.Azure.AppConfiguration.AspNetCore.csproj +++ b/src/Microsoft.Azure.AppConfiguration.AspNetCore/Microsoft.Azure.AppConfiguration.AspNetCore.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/Microsoft.Azure.AppConfiguration.Functions.Worker/Microsoft.Azure.AppConfiguration.Functions.Worker.csproj b/src/Microsoft.Azure.AppConfiguration.Functions.Worker/Microsoft.Azure.AppConfiguration.Functions.Worker.csproj index 43d8d181..6ae5ccb4 100644 --- a/src/Microsoft.Azure.AppConfiguration.Functions.Worker/Microsoft.Azure.AppConfiguration.Functions.Worker.csproj +++ b/src/Microsoft.Azure.AppConfiguration.Functions.Worker/Microsoft.Azure.AppConfiguration.Functions.Worker.csproj @@ -1,4 +1,4 @@ - + diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AssemblyInfo.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AssemblyInfo.cs index ded5fff4..f9522baf 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AssemblyInfo.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AssemblyInfo.cs @@ -30,4 +30,4 @@ "c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654" + "753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46" + "ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484c" + -"f7045cc7")] \ No newline at end of file +"f7045cc7")] diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationProvider.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationProvider.cs index 0868ea14..d6613246 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationProvider.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationProvider.cs @@ -125,6 +125,7 @@ public AzureAppConfigurationProvider(IConfigurationClientManager configClientMan requestTracingDisabled = Environment.GetEnvironmentVariable(RequestTracingConstants.RequestTracingDisabledEnvironmentVariable); } catch (SecurityException) { } + _requestTracingEnabled = bool.TryParse(requestTracingDisabled, out bool tracingDisabled) ? !tracingDisabled : true; if (_requestTracingEnabled) @@ -208,7 +209,7 @@ public async Task RefreshAsync(CancellationToken cancellationToken) // // Filter clients based on their backoff status - clients = clients.Where(client => + clients = clients.Where(client => { Uri endpoint = _configClientManager.GetEndpointForClient(client); @@ -320,7 +321,8 @@ await CallWithRequestTracing( refreshAll = true; break; } - } else + } + else { logDebugBuilder.AppendLine(LogHelper.BuildKeyValueReadMessage(change.ChangeType, change.Key, change.Label, endpoint.ToString())); } @@ -697,7 +699,7 @@ private async Task TryInitializeAsync(IEnumerable cli return false; } - + throw; } diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationRefreshOptions.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationRefreshOptions.cs index 5297507c..7522896e 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationRefreshOptions.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationRefreshOptions.cs @@ -14,7 +14,7 @@ public class AzureAppConfigurationRefreshOptions { internal TimeSpan CacheExpirationInterval { get; private set; } = RefreshConstants.DefaultCacheExpirationInterval; internal ISet RefreshRegistrations = new HashSet(); - + /// /// Register the specified individual key-value to be refreshed when the configuration provider's triggers a refresh. /// The instance can be obtained by calling . diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationSource.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationSource.cs index 71a5f480..09544029 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationSource.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureAppConfigurationSource.cs @@ -12,7 +12,8 @@ internal class AzureAppConfigurationSource : IConfigurationSource public AzureAppConfigurationSource(Action optionsInitializer, bool optional = false) { - _optionsProvider = () => { + _optionsProvider = () => + { var options = new AzureAppConfigurationOptions(); optionsInitializer(options); return options; diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureKeyVaultReference/AzureKeyVaultKeyValueAdapter.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureKeyVaultReference/AzureKeyVaultKeyValueAdapter.cs index dd5cddbc..9580a1cc 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureKeyVaultReference/AzureKeyVaultKeyValueAdapter.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/AzureKeyVaultReference/AzureKeyVaultKeyValueAdapter.cs @@ -138,4 +138,4 @@ private string ParseSecretReferenceUri(ConfigurationSetting setting) return secretRefUri; } } -} \ No newline at end of file +} diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/ConfigurationClientManager.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/ConfigurationClientManager.cs index 9ae71d2a..06f916b0 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/ConfigurationClientManager.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/ConfigurationClientManager.cs @@ -146,7 +146,7 @@ public void RefreshClients() { DateTimeOffset now = DateTimeOffset.UtcNow; - if (_replicaDiscoveryEnabled && + if (_replicaDiscoveryEnabled && now >= _lastFallbackClientRefreshAttempt + MinimalClientRefreshInterval) { _lastFallbackClientRefreshAttempt = now; @@ -262,9 +262,9 @@ private async Task RefreshFallbackClients(CancellationToken cancellationToken) // Honor with the DNS based service discovery protocol, but shuffle the results first to ensure hosts can be picked randomly, // Srv lookup does retrieve trailing dot in the host name, just trim it. - IEnumerable OrderedHosts = srvTargetHosts.Any() ? - srvTargetHosts.ToList().Shuffle().SortSrvRecords().Select(r => $"{r.Target.Value.TrimEnd('.')}") : - Enumerable.Empty(); + IEnumerable OrderedHosts = srvTargetHosts.Any() + ? srvTargetHosts.ToList().Shuffle().SortSrvRecords().Select(r => $"{r.Target.Value.TrimEnd('.')}") + : Enumerable.Empty(); foreach (string host in OrderedHosts) { @@ -274,9 +274,9 @@ private async Task RefreshFallbackClients(CancellationToken cancellationToken) { var targetEndpoint = new Uri($"https://{host}"); - var configClient = _credential == null ? - new ConfigurationClient(ConnectionStringUtils.Build(targetEndpoint, _id, _secret), _clientOptions) : - new ConfigurationClient(targetEndpoint, _credential, _clientOptions); + var configClient = _credential == null + ? new ConfigurationClient(ConnectionStringUtils.Build(targetEndpoint, _id, _secret), _clientOptions) + : new ConfigurationClient(targetEndpoint, _credential, _clientOptions); newDynamicClients.Add(new ConfigurationClientWrapper(targetEndpoint, configClient)); } @@ -320,7 +320,7 @@ internal bool IsValidEndpoint(string hostName) public void Dispose() { - if (!_isDisposed) + if (!_isDisposed) { _cancellationTokenSource.Cancel(); diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Constants/HttpStatusCodes.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Constants/HttpStatusCodes.cs index 76de0b48..823895bd 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Constants/HttpStatusCodes.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Constants/HttpStatusCodes.cs @@ -9,4 +9,4 @@ internal class HttpStatusCodes // This constant is necessary because System.Net.HttpStatusCode.TooManyRequests is only available in netstandard2.1 and higher. public static readonly int TooManyRequests = 429; } -} \ No newline at end of file +} diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Constants/RequestTracingConstants.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Constants/RequestTracingConstants.cs index f1da875b..6ff59fa1 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Constants/RequestTracingConstants.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Constants/RequestTracingConstants.cs @@ -10,7 +10,7 @@ internal class RequestTracingConstants public const string AzureWebAppEnvironmentVariable = "WEBSITE_SITE_NAME"; public const string ContainerAppEnvironmentVariable = "CONTAINER_APP_NAME"; public const string KubernetesEnvironmentVariable = "KUBERNETES_PORT"; - + public const string AspNetCoreEnvironmentVariable = "ASPNETCORE_ENVIRONMENT"; public const string DotNetCoreEnvironmentVariable = "DOTNET_ENVIRONMENT"; public const string DevelopmentEnvironmentName = "Development"; diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Exceptions/KeyVaultReferenceException.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Exceptions/KeyVaultReferenceException.cs index 58046c93..7d549a06 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Exceptions/KeyVaultReferenceException.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Exceptions/KeyVaultReferenceException.cs @@ -20,7 +20,7 @@ public class KeyVaultReferenceException : Exception /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. /// public KeyVaultReferenceException(string message, Exception inner) - :base(string.Empty, inner) + : base(string.Empty, inner) { _message = message; } @@ -29,7 +29,7 @@ public KeyVaultReferenceException(string message, ///Gets a message that describes the current exception. ///Returns The error message that explains the reason for the exception, or an empty string(""). /// - public override string Message => $"{_message} ErrorCode:'{ErrorCode}' Key:'{Key}' Label:'{Label}' Etag:'{Etag}' SecretIdentifier:'{SecretIdentifier}'"; + public override string Message => $"{_message} ErrorCode:'{ErrorCode}' Key:'{Key}' Label:'{Label}' Etag:'{Etag}' SecretIdentifier:'{SecretIdentifier}'"; /// /// The key of the Key Vault reference that caused the exception. @@ -56,5 +56,4 @@ public KeyVaultReferenceException(string message, /// public string ErrorCode { get; set; } } - } diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Extensions/ConfigurationClientExtensions.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Extensions/ConfigurationClientExtensions.cs index 0e378f44..18c03178 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Extensions/ConfigurationClientExtensions.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Extensions/ConfigurationClientExtensions.cs @@ -116,7 +116,7 @@ public static async Task> GetKeyValueChangeCollectio await TracingUtils.CallWithRequestTracing(options.RequestTracingEnabled, RequestType.Watch, options.RequestTracingOptions, async () => { - await foreach(ConfigurationSetting setting in client.GetConfigurationSettingsAsync(selector, cancellationToken).ConfigureAwait(false)) + await foreach (ConfigurationSetting setting in client.GetConfigurationSettingsAsync(selector, cancellationToken).ConfigureAwait(false)) { if (!eTagMap.TryGetValue(setting.Key, out ETag etag) || !etag.Equals(setting.ETag)) { diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Extensions/EventGridEventExtensions.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Extensions/EventGridEventExtensions.cs index 7ac04ca9..ee904324 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Extensions/EventGridEventExtensions.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Extensions/EventGridEventExtensions.cs @@ -89,4 +89,4 @@ public static bool TryCreatePushNotification(this EventGridEvent eventGridEvent, return false; } } -} \ No newline at end of file +} diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Extensions/ListExtensions.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Extensions/ListExtensions.cs index 9be9b55a..99024c3c 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Extensions/ListExtensions.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Extensions/ListExtensions.cs @@ -65,4 +65,4 @@ public static void AppendUnique(this List items, T item) items.Add(item); } } -} \ No newline at end of file +} diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/ClientFilter.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/ClientFilter.cs index 80aed990..12145cd7 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/ClientFilter.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/ClientFilter.cs @@ -11,4 +11,4 @@ internal class ClientFilter public JsonElement Parameters { get; set; } } -} \ No newline at end of file +} diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureConditions.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureConditions.cs index ec29c199..d1c23003 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureConditions.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureConditions.cs @@ -11,4 +11,4 @@ internal class FeatureConditions public string RequirementType { get; set; } } -} \ No newline at end of file +} diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFilterTracing.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFilterTracing.cs index 27b59205..deb6db49 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFilterTracing.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFilterTracing.cs @@ -29,7 +29,7 @@ internal class FeatureFilterTracing public bool UsesPercentageFilter { get; set; } = false; public bool UsesTimeWindowFilter { get; set; } = false; public bool UsesTargetingFilter { get; set; } = false; - + public bool UsesAnyFeatureFilter() { return UsesCustomFilter || UsesPercentageFilter || UsesTimeWindowFilter || UsesTargetingFilter; diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFlag.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFlag.cs index a26fb6cc..aaf38540 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFlag.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFlag.cs @@ -12,4 +12,4 @@ internal class FeatureFlag public FeatureConditions Conditions { get; set; } } -} \ No newline at end of file +} diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFlagOptions.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFlagOptions.cs index 202f4055..c63fddc1 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFlagOptions.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureFlagOptions.cs @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. // -using Microsoft.Extensions.Configuration.AzureAppConfiguration.Models; using Microsoft.Extensions.Configuration.AzureAppConfiguration.Extensions; +using Microsoft.Extensions.Configuration.AzureAppConfiguration.Models; using System; using System.Collections.Generic; using System.Linq; diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureManagementKeyValueAdapter.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureManagementKeyValueAdapter.cs index 5b0a6a96..058f353c 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureManagementKeyValueAdapter.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/FeatureManagementKeyValueAdapter.cs @@ -264,7 +264,7 @@ private FeatureConditions ParseFeatureConditions(ref Utf8JsonReader reader, stri default: reader.Skip(); - + break; } } diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/JsonFlattener.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/JsonFlattener.cs index 9974a933..fa5983c1 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/JsonFlattener.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/FeatureManagement/JsonFlattener.cs @@ -36,6 +36,7 @@ private void VisitJsonElement(JsonElement element) { VisitJsonProperty(property); } + break; case JsonValueKind.Array: @@ -45,6 +46,7 @@ private void VisitJsonElement(JsonElement element) VisitJsonElement(element[index]); ExitContext(); } + break; case JsonValueKind.String: diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/JsonKeyValueAdapter.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/JsonKeyValueAdapter.cs index 2c11d423..979811d7 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/JsonKeyValueAdapter.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/JsonKeyValueAdapter.cs @@ -16,7 +16,7 @@ namespace Microsoft.Extensions.Configuration.AzureAppConfiguration { internal class JsonKeyValueAdapter : IKeyValueAdapter { - private static readonly IEnumerable ExcludedJsonContentTypes = new[] + private static readonly IEnumerable ExcludedJsonContentTypes = new[] { FeatureManagementConstants.ContentType, KeyVaultConstants.ContentType diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Microsoft.Extensions.Configuration.AzureAppConfiguration.csproj b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Microsoft.Extensions.Configuration.AzureAppConfiguration.csproj index da78f0e9..a2cfca3c 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Microsoft.Extensions.Configuration.AzureAppConfiguration.csproj +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/Microsoft.Extensions.Configuration.AzureAppConfiguration.csproj @@ -1,4 +1,5 @@ - + + @@ -50,5 +51,5 @@ true true - + diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/PushNotification.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/PushNotification.cs index e23d8bb4..1690645d 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/PushNotification.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/PushNotification.cs @@ -24,6 +24,5 @@ public class PushNotification /// The Type of Event which triggered the . /// public string EventType { get; set; } - - } -} \ No newline at end of file + } +} diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/SrvLookupClient.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/SrvLookupClient.cs index bcbdff75..74bad0b5 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/SrvLookupClient.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/SrvLookupClient.cs @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. // +using DnsClient; +using DnsClient.Protocol; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; -using DnsClient; -using DnsClient.Protocol; namespace Microsoft.Extensions.Configuration.AzureAppConfiguration { @@ -26,7 +26,7 @@ public SrvLookupClient() public async Task> QueryAsync(string host, CancellationToken cancellationToken) { string originSrvDns = $"{TcpOrigin}.{host}"; - + IEnumerable originRecords = await InternalQueryAsync(originSrvDns, cancellationToken).ConfigureAwait(false); if (originRecords == null || originRecords.Count() == 0) diff --git a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/TracingUtils.cs b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/TracingUtils.cs index bbf8511c..2c8d9869 100644 --- a/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/TracingUtils.cs +++ b/src/Microsoft.Extensions.Configuration.AzureAppConfiguration/TracingUtils.cs @@ -117,7 +117,7 @@ private static string CreateCorrelationContextHeader(RequestType requestType, Re { IList> correlationContextKeyValues = new List>(); IList correlationContextTags = new List(); - + correlationContextKeyValues.Add(new KeyValuePair(RequestTracingConstants.RequestTypeKey, Enum.GetName(typeof(RequestType), requestType))); if (requestTracingOptions.ReplicaCount > 0) @@ -167,7 +167,7 @@ private static string CreateCorrelationContextHeader(RequestType requestType, Re var sb = new StringBuilder(); - foreach (KeyValuePair kvp in correlationContextKeyValues) + foreach (KeyValuePair kvp in correlationContextKeyValues) { if (sb.Length > 0) { diff --git a/tests/Tests.AzureAppConfiguration.AspNetCore/AzureAppConfigurationExtensionsTests.cs b/tests/Tests.AzureAppConfiguration.AspNetCore/AzureAppConfigurationExtensionsTests.cs index 5c093d1a..2d4870f2 100644 --- a/tests/Tests.AzureAppConfiguration.AspNetCore/AzureAppConfigurationExtensionsTests.cs +++ b/tests/Tests.AzureAppConfiguration.AspNetCore/AzureAppConfigurationExtensionsTests.cs @@ -1,4 +1,7 @@ -using Microsoft.AspNetCore.Builder; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// +using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Moq; using System; diff --git a/tests/Tests.AzureAppConfiguration.AspNetCore/RefreshMiddlewareTests.cs b/tests/Tests.AzureAppConfiguration.AspNetCore/RefreshMiddlewareTests.cs index 934cd997..de752f03 100644 --- a/tests/Tests.AzureAppConfiguration.AspNetCore/RefreshMiddlewareTests.cs +++ b/tests/Tests.AzureAppConfiguration.AspNetCore/RefreshMiddlewareTests.cs @@ -9,9 +9,7 @@ using Moq; using System.Collections.Generic; using System.Linq; -using System.Threading; using Xunit; -using static Tests.AzureAppConfiguration.AspNetCore.TestHelper; namespace Tests.AzureAppConfiguration.AspNetCore { diff --git a/tests/Tests.AzureAppConfiguration.AspNetCore/TestHelper.cs b/tests/Tests.AzureAppConfiguration.AspNetCore/TestHelper.cs index a67e8127..500f3aa9 100644 --- a/tests/Tests.AzureAppConfiguration.AspNetCore/TestHelper.cs +++ b/tests/Tests.AzureAppConfiguration.AspNetCore/TestHelper.cs @@ -1,4 +1,7 @@ -using Azure; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// +using Azure; using Azure.Data.AppConfiguration; using Moq; using System; diff --git a/tests/Tests.AzureAppConfiguration.AspNetCore/Tests.AzureAppConfiguration.AspNetCore.csproj b/tests/Tests.AzureAppConfiguration.AspNetCore/Tests.AzureAppConfiguration.AspNetCore.csproj index a8cd3b51..f15c5eb7 100644 --- a/tests/Tests.AzureAppConfiguration.AspNetCore/Tests.AzureAppConfiguration.AspNetCore.csproj +++ b/tests/Tests.AzureAppConfiguration.AspNetCore/Tests.AzureAppConfiguration.AspNetCore.csproj @@ -1,4 +1,4 @@ - + net6.0;net7.0;net8.0 @@ -24,4 +24,5 @@ + diff --git a/tests/Tests.AzureAppConfiguration.Functions.Worker/Tests.AzureAppConfiguration.Functions.Worker.csproj b/tests/Tests.AzureAppConfiguration.Functions.Worker/Tests.AzureAppConfiguration.Functions.Worker.csproj index f5af5a3f..02f3f7e2 100644 --- a/tests/Tests.AzureAppConfiguration.Functions.Worker/Tests.AzureAppConfiguration.Functions.Worker.csproj +++ b/tests/Tests.AzureAppConfiguration.Functions.Worker/Tests.AzureAppConfiguration.Functions.Worker.csproj @@ -1,4 +1,4 @@ - + net6.0;net7.0;net8.0 diff --git a/tests/Tests.AzureAppConfiguration/Azure.Core.Testing/MockRequest.cs b/tests/Tests.AzureAppConfiguration/Azure.Core.Testing/MockRequest.cs index 443c8acb..d5ad0815 100644 --- a/tests/Tests.AzureAppConfiguration/Azure.Core.Testing/MockRequest.cs +++ b/tests/Tests.AzureAppConfiguration/Azure.Core.Testing/MockRequest.cs @@ -32,6 +32,7 @@ public override RequestContent Content { _headers.Remove("Content-Length"); } + base.Content = value; } } diff --git a/tests/Tests.AzureAppConfiguration/Azure.Core.Testing/TaskExtensions.cs b/tests/Tests.AzureAppConfiguration/Azure.Core.Testing/TaskExtensions.cs index 37d5d55f..ace8ebe2 100644 --- a/tests/Tests.AzureAppConfiguration/Azure.Core.Testing/TaskExtensions.cs +++ b/tests/Tests.AzureAppConfiguration/Azure.Core.Testing/TaskExtensions.cs @@ -27,7 +27,6 @@ public static Task TimeoutAfterDefault(this Task task, return task.TimeoutAfter(DefaultTimeout, filePath, lineNumber); } - public static async Task TimeoutAfter(this Task task, TimeSpan timeout, [CallerFilePath] string filePath = null, [CallerLineNumber] int lineNumber = default) diff --git a/tests/Tests.AzureAppConfiguration/ConnectTests.cs b/tests/Tests.AzureAppConfiguration/ConnectTests.cs index 22a1507a..6a8ddc8d 100644 --- a/tests/Tests.AzureAppConfiguration/ConnectTests.cs +++ b/tests/Tests.AzureAppConfiguration/ConnectTests.cs @@ -7,7 +7,6 @@ using Moq; using System; using System.Collections.Generic; -using System.Linq; using System.Threading; using System.Threading.Tasks; using Xunit; @@ -48,7 +47,6 @@ public void ConnectTests_ThrowsIfConnectNotInvoked() Assert.Throws(action); } - [Fact] public void ConnectTests_UsesParametersFromLatestConnectCall() { diff --git a/tests/Tests.AzureAppConfiguration/FailoverTests.cs b/tests/Tests.AzureAppConfiguration/FailoverTests.cs index e9a7a12a..25a1d6bf 100644 --- a/tests/Tests.AzureAppConfiguration/FailoverTests.cs +++ b/tests/Tests.AzureAppConfiguration/FailoverTests.cs @@ -72,7 +72,7 @@ public async Task FailOverTests_ReturnsAllClientsIfAllBackedOff() }); options.ReplicaDiscoveryEnabled = false; - + refresher = options.GetRefresher(); }); @@ -210,7 +210,7 @@ public async Task FailOverTests_BackoffStateIsUpdatedOnSuccessfulRequest() // Wait for client 1 backoff to end Thread.Sleep(2500); - + await refresher.RefreshAsync(); // The first client should have been called now with refresh after the backoff time ends diff --git a/tests/Tests.AzureAppConfiguration/FeatureManagementTests.cs b/tests/Tests.AzureAppConfiguration/FeatureManagementTests.cs index abcb7595..2b6a70a2 100644 --- a/tests/Tests.AzureAppConfiguration/FeatureManagementTests.cs +++ b/tests/Tests.AzureAppConfiguration/FeatureManagementTests.cs @@ -316,7 +316,7 @@ public class FeatureManagementTests eTag: new ETag("c3c231fd-39a0-4cb6-3237-4614474b92c1")) }; - List _featureFlagCollection = new List + List _featureFlagCollection = new List { ConfigurationModelFactory.ConfigurationSetting( key: FeatureManagementConstants.FeatureFlagMarker + "App1_Feature1", @@ -521,7 +521,6 @@ public async Task WatchesFeatureFlags() Assert.Equal("SuperUsers", config["FeatureManagement:MyFeature2:EnabledFor:0:Name"]); } - [Fact] public async Task SkipRefreshIfCacheNotExpired() { @@ -950,7 +949,7 @@ public void MultipleCallsToUseFeatureFlags() .Returns(() => { return new MockAsyncPageable(_featureFlagCollection.Where(s => - (s.Key.StartsWith(FeatureManagementConstants.FeatureFlagMarker + prefix1) && s.Label == label1) || + (s.Key.StartsWith(FeatureManagementConstants.FeatureFlagMarker + prefix1) && s.Label == label1) || (s.Key.StartsWith(FeatureManagementConstants.FeatureFlagMarker + prefix2) && s.Label == label2)).ToList()); }); @@ -1285,6 +1284,7 @@ public async Task ValidateCorrectFeatureFlagLoggedIfModifiedOrRemovedDuringRefre { informationalInvocation += s; } + if (args.Level == EventLevel.Verbose) { verboseInvocation += s; @@ -1467,6 +1467,7 @@ public async Task MapTransformFeatureFlagWithRefresh() } "; } + return new ValueTask(setting); }); refresher = options.GetRefresher(); diff --git a/tests/Tests.AzureAppConfiguration/KeyVaultReferenceTests.cs b/tests/Tests.AzureAppConfiguration/KeyVaultReferenceTests.cs index 9d4ce1e5..d8c832bf 100644 --- a/tests/Tests.AzureAppConfiguration/KeyVaultReferenceTests.cs +++ b/tests/Tests.AzureAppConfiguration/KeyVaultReferenceTests.cs @@ -186,7 +186,7 @@ public void NotSecretIdentifierURI() { configuration = builder.AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => kv.Register(mockSecretClient.Object)); }).Build(); }); @@ -212,7 +212,7 @@ public void UseSecret() var configuration = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => kv.Register(mockSecretClient.Object)); }) .Build(); @@ -237,7 +237,7 @@ public void UseCertificate() var configuration = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => kv.Register(mockSecretClient.Object)); }) .Build(); @@ -262,7 +262,7 @@ public void ThrowsWhenSecretNotFound() { new ConfigurationBuilder().AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => kv.Register(mockSecretClient.Object)); }).Build(); }); @@ -287,7 +287,7 @@ public void DisabledSecretIdentifier() { new ConfigurationBuilder().AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => kv.Register(mockSecretClient.Object)); }).Build(); }); @@ -309,7 +309,7 @@ public void WrongContentType() var configuration = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => kv.Register(mockSecretClient.Object)); }) .Build(); @@ -364,14 +364,13 @@ public void CancellationToken() { startupOptions.Timeout = TimeSpan.FromSeconds(5); }); - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => kv.Register(mockSecretClient.Object)); }) .Build(); }); } - [Fact] public void HasNoAccessToKeyVault() { @@ -389,7 +388,7 @@ public void HasNoAccessToKeyVault() { new ConfigurationBuilder().AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => kv.Register(mockSecretClient.Object)); }) .Build(); @@ -418,7 +417,7 @@ public void RegisterMultipleClients() var configuration = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => kv.Register(mockSecretClient1.Object) .Register(mockSecretClient2.Object)); }) @@ -441,7 +440,7 @@ public void ServerRequestIsMadeWhenDefaultCredentialIsSet() { new ConfigurationBuilder().AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => kv.SetCredential(new DefaultAzureCredential())); }) .Build(); @@ -469,7 +468,7 @@ public void ThrowsWhenNoMatchingSecretClientIsFound() new ConfigurationBuilder() .AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => kv.Register(mockSecretClient1.Object).Register(mockSecretClient2.Object)); }) .Build(); @@ -492,7 +491,7 @@ public void ThrowsWhenConfigureKeyVaultIsMissing() new ConfigurationBuilder() .AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); }) .Build(); }); @@ -515,7 +514,7 @@ public void DoesNotThrowKeyVaultExceptionWhenProviderIsOptional() new ConfigurationBuilder() .AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.Adapters = new List { mockKeyValueAdapter.Object }; }, optional: true) .Build(); @@ -532,7 +531,7 @@ public void CallsSecretResolverCallbackWhenNoMatchingSecretClientIsFound() IConfiguration config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => { kv.SetSecretResolver((secretUri) => @@ -558,7 +557,7 @@ public void ThrowsWhenBothDefaultCredentialAndSecretResolverCallbackAreSet() { new ConfigurationBuilder().AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => { kv.SetSecretResolver((secretUri) => @@ -588,7 +587,7 @@ public void ThrowsWhenSecretResolverIsNull() { new ConfigurationBuilder().AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => { kv.SetSecretResolver(null); @@ -609,7 +608,7 @@ public void LastKeyVaultOptionsWinWithMultipleConfigureKeyVaultCalls() IConfiguration config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => { kv.SetCredential(new DefaultAzureCredential()); @@ -644,7 +643,7 @@ public void DontUseSecretResolverCallbackWhenMatchingSecretClientIsPresent() var configuration = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => { kv.SetSecretResolver((secretUri) => @@ -672,7 +671,7 @@ public void ThrowsWhenSecretRefreshIntervalIsTooShort() { new ConfigurationBuilder().AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => { kv.SetSecretRefreshInterval(_kv.Key, TimeSpan.FromMilliseconds(10)); @@ -721,7 +720,7 @@ Response GetIfChanged(ConfigurationSetting setting, bool o var config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => { @@ -794,7 +793,7 @@ Response GetIfChanged(ConfigurationSetting setting, bool o var config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => { kv.Register(mockSecretClient.Object); @@ -847,7 +846,7 @@ public async Task SecretIsReloadedFromKeyVaultWhenCacheExpires() var config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => { kv.Register(mockSecretClient.Object); @@ -890,7 +889,7 @@ public async Task SecretsWithDefaultRefreshInterval() var config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => { kv.Register(mockSecretClient.Object); @@ -936,7 +935,7 @@ public async Task SecretsWithDifferentRefreshIntervals() var config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); options.ConfigureKeyVault(kv => { kv.Register(mockSecretClient.Object); @@ -962,7 +961,6 @@ public async Task SecretsWithDifferentRefreshIntervals() mockSecretClient.Verify(client => client.GetSecretAsync(It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(3)); } - [Fact] public void ThrowsWhenInvalidKeyVaultSecretReferenceJson() { diff --git a/tests/Tests.AzureAppConfiguration/LoggingTests.cs b/tests/Tests.AzureAppConfiguration/LoggingTests.cs index 489bb78e..04ddf3d9 100644 --- a/tests/Tests.AzureAppConfiguration/LoggingTests.cs +++ b/tests/Tests.AzureAppConfiguration/LoggingTests.cs @@ -9,7 +9,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration.AzureAppConfiguration; using Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureKeyVault; -using Microsoft.Extensions.Configuration.AzureAppConfiguration.Extensions; using Moq; using System; using System.Collections.Generic; @@ -132,7 +131,7 @@ public async Task ValidateUnauthorizedExceptionLoggedDuringRefresh() Assert.Equal("TestValue1", config["TestKey1"]); FirstKeyValue.Value = "newValue1"; - + Thread.Sleep(CacheExpirationTime); await refresher.TryRefreshAsync(); @@ -505,6 +504,7 @@ public async Task ValidateCorrectKeyValueLoggedDuringRefresh() { informationalInvocation += s; } + if (args.Level == EventLevel.Verbose) { verboseInvocation += s; @@ -558,6 +558,7 @@ public async Task ValidateCorrectKeyVaultSecretLoggedDuringRefresh() { informationalInvocation += s; } + if (args.Level == EventLevel.Verbose) { verboseInvocation += s; diff --git a/tests/Tests.AzureAppConfiguration/MapTests.cs b/tests/Tests.AzureAppConfiguration/MapTests.cs index ea5b45ca..88fdaa6e 100644 --- a/tests/Tests.AzureAppConfiguration/MapTests.cs +++ b/tests/Tests.AzureAppConfiguration/MapTests.cs @@ -1,19 +1,22 @@ -using Microsoft.Extensions.Configuration.AzureAppConfiguration; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// +using Azure; +using Azure.Core.Diagnostics; +using Azure.Core.Testing; +using Azure.Data.AppConfiguration; +using Azure.Security.KeyVault.Secrets; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration.AzureAppConfiguration; +using Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureKeyVault; +using Moq; using System; using System.Collections.Generic; -using Xunit; -using Azure.Data.AppConfiguration; -using Azure; -using Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureKeyVault; +using System.Diagnostics.Tracing; using System.Linq; -using Azure.Core.Testing; -using Moq; using System.Threading; using System.Threading.Tasks; -using Azure.Security.KeyVault.Secrets; -using Azure.Core.Diagnostics; -using System.Diagnostics.Tracing; +using Xunit; namespace Tests.AzureAppConfiguration { @@ -71,6 +74,7 @@ public void MapTransformKeyValue() { setting.Value += " mapped"; } + return new ValueTask(setting); }).Map((setting) => { @@ -82,6 +86,7 @@ public void MapTransformKeyValue() { setting.Value += " second"; } + return new ValueTask(setting); }); }) @@ -113,16 +118,17 @@ public void MapTransformKeyVaultValueBeforeAdapters() options.ConfigureKeyVault(kv => kv.Register(mockSecretClient.Object)); options.Map((setting) => { - if (setting.ContentType != KeyVaultConstants.ContentType + "; charset=utf-8") - { - setting.Value = @" + if (setting.ContentType != KeyVaultConstants.ContentType + "; charset=utf-8") + { + setting.Value = @" { ""uri"":""https://keyvault-theclassics.vault.azure.net/certificates/TestCertificate"" }"; - setting.ContentType = KeyVaultConstants.ContentType + "; charset=utf-8"; - } - return new ValueTask(setting); - }); + setting.ContentType = KeyVaultConstants.ContentType + "; charset=utf-8"; + } + + return new ValueTask(setting); + }); }) .Build(); @@ -152,6 +158,7 @@ public async Task MapTransformWithRefresh() { setting.Value += " mapped"; } + return new ValueTask(setting); }).Map((setting) => { @@ -163,6 +170,7 @@ public async Task MapTransformWithRefresh() { setting.Value += " second"; } + return new ValueTask(setting); }); @@ -205,6 +213,7 @@ public async Task MapTransformSettingKeyWithRefresh() { setting.Key = "newTestKey1"; } + return new ValueTask(setting); }).Map((setting) => { @@ -212,6 +221,7 @@ public async Task MapTransformSettingKeyWithRefresh() { setting.Value += " changed"; } + return new ValueTask(setting); }); refresher = options.GetRefresher(); @@ -255,6 +265,7 @@ public async Task MapTransformSettingLabelWithRefresh() { setting.Label = "newLabel"; } + return new ValueTask(setting); }).Map((setting) => { @@ -262,6 +273,7 @@ public async Task MapTransformSettingLabelWithRefresh() { setting.Value += " changed"; } + return new ValueTask(setting); }); refresher = options.GetRefresher(); @@ -303,6 +315,7 @@ public async Task MapTransformSettingCreateDuplicateKeyWithRefresh() { setting.Key = "TestKey2"; } + return new ValueTask(setting); }).Map((setting) => { @@ -310,6 +323,7 @@ public async Task MapTransformSettingCreateDuplicateKeyWithRefresh() { setting.Value += " changed"; } + return new ValueTask(setting); }); refresher = options.GetRefresher(); @@ -356,6 +370,7 @@ public async Task MapCreateNewSettingWithRefresh() eTag: new ETag("changed"), contentType: "text"); } + return new ValueTask(setting); }); refresher = options.GetRefresher(); @@ -402,6 +417,7 @@ public void MapResolveKeyVaultReferenceThrowsExceptionInAdapter() { setting.Value = _secretValue; } + return new ValueTask(setting); }); refresher = options.GetRefresher(); @@ -426,7 +442,6 @@ public void MapAsyncResolveKeyVaultReference() .Returns((string name, string version, CancellationToken cancellationToken) => Task.FromResult((Response)new MockResponse(new KeyVaultSecret(name, _secretValue)))); - var config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { @@ -440,6 +455,7 @@ public void MapAsyncResolveKeyVaultReference() setting.Value = secret.Value; setting.ContentType = "text"; } + return setting; }); refresher = options.GetRefresher(); @@ -466,6 +482,7 @@ public async Task MapTransformSettingKeyWithLogAndRefresh() { informationalInvocation += s; } + if (args.Level == EventLevel.Verbose) { verboseInvocation += s; @@ -487,6 +504,7 @@ public async Task MapTransformSettingKeyWithLogAndRefresh() { setting.Key = "newTestKey1"; } + return new ValueTask(setting); }).Map((setting) => { @@ -494,6 +512,7 @@ public async Task MapTransformSettingKeyWithLogAndRefresh() { setting.Value += " changed"; } + return new ValueTask(setting); }); refresher = options.GetRefresher(); diff --git a/tests/Tests.AzureAppConfiguration/MockedConfigurationClientManager.cs b/tests/Tests.AzureAppConfiguration/MockedConfigurationClientManager.cs index 7e6c03e1..0216d1be 100644 --- a/tests/Tests.AzureAppConfiguration/MockedConfigurationClientManager.cs +++ b/tests/Tests.AzureAppConfiguration/MockedConfigurationClientManager.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. // - using Azure.Data.AppConfiguration; using Microsoft.Extensions.Configuration.AzureAppConfiguration; using System; @@ -63,7 +62,8 @@ public IEnumerable GetClients() { var result = new List(); - foreach (var client in _clients) { + foreach (var client in _clients) + { result.Add(client.Client); } diff --git a/tests/Tests.AzureAppConfiguration/PushRefreshTests.cs b/tests/Tests.AzureAppConfiguration/PushRefreshTests.cs index 304a7e02..38b8c70f 100644 --- a/tests/Tests.AzureAppConfiguration/PushRefreshTests.cs +++ b/tests/Tests.AzureAppConfiguration/PushRefreshTests.cs @@ -19,58 +19,58 @@ namespace Tests.AzureAppConfiguration { public class PushRefreshTests - { + { static readonly Uri PrimaryResourceUri = new Uri(TestHelpers.PrimaryConfigStoreEndpoint.ToString() + "/kv/searchQuery1"); static readonly Uri SecondaryResourceUri = new Uri(TestHelpers.SecondaryConfigStoreEndpoint.ToString() + "/kv/searchQuery2"); List _kvCollection = new List - { - ConfigurationModelFactory.ConfigurationSetting( - key: "TestKey1", - label: "label", - value: "TestValue1", - eTag: new ETag("0a76e3d7-7ec1-4e37-883c-9ea6d0d89e63"), - contentType: "text"), - - ConfigurationModelFactory.ConfigurationSetting( - key: "TestKey2", - label: "label", - value: "TestValue2", - eTag: new ETag("31c38369-831f-4bf1-b9ad-79db56c8b989"), - contentType: "text"), - - ConfigurationModelFactory.ConfigurationSetting( - key: "TestKey3", - label: "label", - value: "TestValue3", - eTag: new ETag("bb203f2b-c113-44fc-995d-b933c2143339"), - contentType: "text"), - - ConfigurationModelFactory.ConfigurationSetting( - key: "TestKeyWithMultipleLabels", - label: "label1", - value: "TestValueForLabel1", - eTag: new ETag("bb203f2b-c113-44fc-995d-b933c2143339"), - contentType: "text"), - - ConfigurationModelFactory.ConfigurationSetting( - key: "TestKeyWithMultipleLabels", - label: "label2", - value: "TestValueForLabel2", - eTag: new ETag("bb203f2b-c113-44fc-995d-b933c2143339"), - contentType: "text") - }; + { + ConfigurationModelFactory.ConfigurationSetting( + key: "TestKey1", + label: "label", + value: "TestValue1", + eTag: new ETag("0a76e3d7-7ec1-4e37-883c-9ea6d0d89e63"), + contentType: "text"), + + ConfigurationModelFactory.ConfigurationSetting( + key: "TestKey2", + label: "label", + value: "TestValue2", + eTag: new ETag("31c38369-831f-4bf1-b9ad-79db56c8b989"), + contentType: "text"), + + ConfigurationModelFactory.ConfigurationSetting( + key: "TestKey3", + label: "label", + value: "TestValue3", + eTag: new ETag("bb203f2b-c113-44fc-995d-b933c2143339"), + contentType: "text"), + + ConfigurationModelFactory.ConfigurationSetting( + key: "TestKeyWithMultipleLabels", + label: "label1", + value: "TestValueForLabel1", + eTag: new ETag("bb203f2b-c113-44fc-995d-b933c2143339"), + contentType: "text"), + + ConfigurationModelFactory.ConfigurationSetting( + key: "TestKeyWithMultipleLabels", + label: "label2", + value: "TestValueForLabel2", + eTag: new ETag("bb203f2b-c113-44fc-995d-b933c2143339"), + contentType: "text") + }; List _pushNotificationList = new List { new PushNotification { ResourceUri = PrimaryResourceUri, - EventType = "eventType.KeyValueModified", + EventType = "eventType.KeyValueModified", SyncToken = "SyncToken1;sn=001", }, new PushNotification { ResourceUri = PrimaryResourceUri, - EventType = "eventType.KeyValueModified", + EventType = "eventType.KeyValueModified", SyncToken = "SyncToken2", }, new PushNotification { @@ -114,12 +114,12 @@ public class PushRefreshTests }, new PushNotification { ResourceUri = SecondaryResourceUri, - EventType = null, + EventType = null, SyncToken = "SyncToken2" }, new PushNotification { ResourceUri = PrimaryResourceUri, - EventType = "eventType.KeyValueDeleted", + EventType = "eventType.KeyValueDeleted", SyncToken = null }, new PushNotification { @@ -134,13 +134,13 @@ public class PushRefreshTests } }; - Dictionary _eventGridEvents = new Dictionary - { + Dictionary _eventGridEvents = new Dictionary + { { "sn;Vxujfidne", new EventGridEvent( "https://store1.resource.io/kv/searchQuery1", - "Microsoft.AppConfiguration.KeyValueModified", "2", + "Microsoft.AppConfiguration.KeyValueModified", "2", BinaryData.FromString("{\"key\":\"searchQuery1\",\"etag\":\"etagValue1\",\"syncToken\":\"sn;Vxujfidne\"}") ) }, @@ -158,7 +158,7 @@ public class PushRefreshTests "sn;Ttylmable", new EventGridEvent( "https://store1.resource.io/kv/searchQuery2", - "Microsoft.AppConfiguration.KeyValueDeleted", "2", + "Microsoft.AppConfiguration.KeyValueDeleted", "2", BinaryData.FromString("{\"key\":\"searchQuery1\",\"etag\":\"etagValue1\",\"syncToken\":\"sn;Ttylmable\"}") ) }, @@ -167,7 +167,7 @@ public class PushRefreshTests "sn;CRAle3342", new EventGridEvent( "https://store2.resource.io/kv/searchQuery2", - "Microsoft.AppConfiguration.KeyValueModified", "2", + "Microsoft.AppConfiguration.KeyValueModified", "2", BinaryData.FromString("{\"key\":\"searchQuery1\",\"etag\":\"etagValue1\",\"syncToken\":\"sn;CRAle3342\"}") ) }, @@ -185,25 +185,25 @@ public class PushRefreshTests Dictionary _invalidFormatEventGridEvents = new Dictionary { - { - "sn;Vxujfidne", - new EventGridEvent( - "https://store1.resource.io/kv/searchQuery1", - "Microsoft.AppConfiguration.KeyValueModified", "2", - BinaryData.FromString("\"key\":\"searchQuery1\",\"etag\":\"etagValue1\",\"syncToken\":\"sn;Vxujfidne\"}") - ) - }, - - { - "sn;AxRty78B", - new EventGridEvent( - "https://store1.resource.io/kv/searchQuery1", - "Microsoft.AppConfiguration.KeyValueModified", "2", - BinaryData.FromString("{\"key\":\"searchQuery1\",\"etag\":\"etagValue1\",\"syncToken\":\"sn;Vxujfidne\"") - ) - }, - - { + { + "sn;Vxujfidne", + new EventGridEvent( + "https://store1.resource.io/kv/searchQuery1", + "Microsoft.AppConfiguration.KeyValueModified", "2", + BinaryData.FromString("\"key\":\"searchQuery1\",\"etag\":\"etagValue1\",\"syncToken\":\"sn;Vxujfidne\"}") + ) + }, + + { + "sn;AxRty78B", + new EventGridEvent( + "https://store1.resource.io/kv/searchQuery1", + "Microsoft.AppConfiguration.KeyValueModified", "2", + BinaryData.FromString("{\"key\":\"searchQuery1\",\"etag\":\"etagValue1\",\"syncToken\":\"sn;Vxujfidne\"") + ) + }, + + { "sn;Ttylmable", new EventGridEvent( "https://store1.resource.io/kv/searchQuery2", @@ -227,18 +227,18 @@ public class PushRefreshTests [Fact] public void ValidatePushNotificationCreation() { - foreach (KeyValuePair eventGridAndSync in _eventGridEvents) + foreach (KeyValuePair eventGridAndSync in _eventGridEvents) { - string syncToken = eventGridAndSync.Key; - EventGridEvent eventGridEvent = eventGridAndSync.Value; + string syncToken = eventGridAndSync.Key; + EventGridEvent eventGridEvent = eventGridAndSync.Value; - Assert.True(eventGridEvent.TryCreatePushNotification(out PushNotification pushNotification)); + Assert.True(eventGridEvent.TryCreatePushNotification(out PushNotification pushNotification)); Assert.NotNull(pushNotification); Assert.Equal(eventGridEvent.EventType, pushNotification.EventType); Assert.Equal(eventGridEvent.Subject, pushNotification.ResourceUri.OriginalString); Assert.Equal(syncToken, pushNotification.SyncToken); } - } + } [Fact] public void InvalidPushNotificationCreation() @@ -252,145 +252,143 @@ public void InvalidPushNotificationCreation() } [Fact] - public void ProcessPushNotificationThrowsArgumentExceptions() + public void ProcessPushNotificationThrowsArgumentExceptions() { - var mockResponse = new Mock(); - var mockClient = GetMockConfigurationClient(); - - IConfigurationRefresher refresher = null; - - var config = new ConfigurationBuilder() - .AddAzureAppConfiguration(options => - { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); - options.Select("*"); - options.ConfigureRefresh(refreshOptions => - { - refreshOptions.Register("TestKey1", "label") - .SetCacheExpiration(TimeSpan.FromDays(30)); - }); - refresher = options.GetRefresher(); - }) - .Build(); - - foreach (PushNotification invalidPushNotification in _invalidPushNotificationList) + var mockResponse = new Mock(); + var mockClient = GetMockConfigurationClient(); + + IConfigurationRefresher refresher = null; + + var config = new ConfigurationBuilder() + .AddAzureAppConfiguration(options => + { + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); + options.Select("*"); + options.ConfigureRefresh(refreshOptions => + { + refreshOptions.Register("TestKey1", "label") + .SetCacheExpiration(TimeSpan.FromDays(30)); + }); + refresher = options.GetRefresher(); + }) + .Build(); + + foreach (PushNotification invalidPushNotification in _invalidPushNotificationList) { - Action action = () => refresher.ProcessPushNotification(invalidPushNotification); - Assert.Throws(action); - } - - PushNotification nullPushNotification = null; - - Action nullAction = () => refresher.ProcessPushNotification(nullPushNotification); - Assert.Throws(nullAction); - } - - [Fact] - public async Task SyncTokenUpdatesCorrectNumberOfTimes() - { - // Arrange - var mockResponse = new Mock(); - var mockClient = GetMockConfigurationClient(); - - IConfigurationRefresher refresher = null; - var clientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); - - var config = new ConfigurationBuilder() - .AddAzureAppConfiguration(options => - { - options.ClientManager = clientManager; - options.Select("*"); - options.ConfigureRefresh(refreshOptions => - { - refreshOptions.Register("TestKey1", "label") - .SetCacheExpiration(TimeSpan.FromDays(30)); - }); - refresher = options.GetRefresher(); - }) - .Build(); - - foreach (PushNotification pushNotification in _pushNotificationList) - { - refresher.ProcessPushNotification(pushNotification, TimeSpan.FromSeconds(0)); - await refresher.RefreshAsync(); - } - - var validNotificationKVWatcherCount = 8; - var validEndpointCount = 4; - - mockClient.Verify(c => c.GetConfigurationSettingAsync(It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(validNotificationKVWatcherCount)); - Assert.Equal(_pushNotificationList.Count, clientManager.UpdateSyncTokenCalled); - mockClient.Verify(c => c.UpdateSyncToken(It.IsAny()), Times.Exactly(validEndpointCount)); - } - - [Fact] - public async Task RefreshAsyncUpdatesConfig() - { - // Arrange - var mockResponse = new Mock(); - var mockClient = GetMockConfigurationClient(); - - IConfigurationRefresher refresher = null; - - var config = new ConfigurationBuilder() - .AddAzureAppConfiguration(options => - { - options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object);; - options.Select("*"); - options.ConfigureRefresh(refreshOptions => - { - refreshOptions.Register("TestKey1", "label") - .SetCacheExpiration(TimeSpan.FromDays(30)); - }); - refresher = options.GetRefresher(); - }) - .Build(); - - - Assert.Equal("TestValue1", config["TestKey1"]); - FirstKeyValue.Value = "newValue1"; - - refresher.ProcessPushNotification(_pushNotificationList.First(), TimeSpan.FromSeconds(0)); - await refresher.RefreshAsync(); - - Assert.Equal("newValue1", config["TestKey1"]); - } - - private Mock GetMockConfigurationClient() - { - var mockResponse = new Mock(); - var mockClient = new Mock(MockBehavior.Strict); - - Response GetTestKey(string key, string label, CancellationToken cancellationToken) - { - return Response.FromValue(TestHelpers.CloneSetting(_kvCollection.FirstOrDefault(s => s.Key == key && s.Label == label)), mockResponse.Object); - } - - Response GetIfChanged(ConfigurationSetting setting, bool onlyIfChanged, CancellationToken cancellationToken) - { - var newSetting = _kvCollection.FirstOrDefault(s => (s.Key == setting.Key && s.Label == setting.Label)); - var unchanged = (newSetting.Key == setting.Key && newSetting.Label == setting.Label && newSetting.Value == setting.Value); - var response = new MockResponse(unchanged ? 304 : 200); - return Response.FromValue(newSetting, response); - } - - // We don't actually select KV based on SettingSelector, we just return a deep copy of _kvCollection - mockClient.Setup(c => c.GetConfigurationSettingsAsync(It.IsAny(), It.IsAny())) - .Returns(() => - { - return new MockAsyncPageable(_kvCollection.Select(setting => TestHelpers.CloneSetting(setting)).ToList()); - }); - - mockClient.Setup(c => c.GetConfigurationSettingAsync(It.IsAny(), It.IsAny(), It.IsAny())) - .ReturnsAsync((Func>)GetTestKey); - - mockClient.Setup(c => c.GetConfigurationSettingAsync(It.IsAny(), It.IsAny(), It.IsAny())) - .ReturnsAsync((Func>)GetIfChanged); - - mockClient.Setup(c => c.UpdateSyncToken(It.IsAny())); - - return mockClient; - } - } + Action action = () => refresher.ProcessPushNotification(invalidPushNotification); + Assert.Throws(action); + } + + PushNotification nullPushNotification = null; + + Action nullAction = () => refresher.ProcessPushNotification(nullPushNotification); + Assert.Throws(nullAction); + } + [Fact] + public async Task SyncTokenUpdatesCorrectNumberOfTimes() + { + // Arrange + var mockResponse = new Mock(); + var mockClient = GetMockConfigurationClient(); + + IConfigurationRefresher refresher = null; + var clientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); + + var config = new ConfigurationBuilder() + .AddAzureAppConfiguration(options => + { + options.ClientManager = clientManager; + options.Select("*"); + options.ConfigureRefresh(refreshOptions => + { + refreshOptions.Register("TestKey1", "label") + .SetCacheExpiration(TimeSpan.FromDays(30)); + }); + refresher = options.GetRefresher(); + }) + .Build(); + + foreach (PushNotification pushNotification in _pushNotificationList) + { + refresher.ProcessPushNotification(pushNotification, TimeSpan.FromSeconds(0)); + await refresher.RefreshAsync(); + } + + var validNotificationKVWatcherCount = 8; + var validEndpointCount = 4; + + mockClient.Verify(c => c.GetConfigurationSettingAsync(It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(validNotificationKVWatcherCount)); + Assert.Equal(_pushNotificationList.Count, clientManager.UpdateSyncTokenCalled); + mockClient.Verify(c => c.UpdateSyncToken(It.IsAny()), Times.Exactly(validEndpointCount)); + } + + [Fact] + public async Task RefreshAsyncUpdatesConfig() + { + // Arrange + var mockResponse = new Mock(); + var mockClient = GetMockConfigurationClient(); + + IConfigurationRefresher refresher = null; + + var config = new ConfigurationBuilder() + .AddAzureAppConfiguration(options => + { + options.ClientManager = TestHelpers.CreateMockedConfigurationClientManager(mockClient.Object); + options.Select("*"); + options.ConfigureRefresh(refreshOptions => + { + refreshOptions.Register("TestKey1", "label") + .SetCacheExpiration(TimeSpan.FromDays(30)); + }); + refresher = options.GetRefresher(); + }) + .Build(); + + Assert.Equal("TestValue1", config["TestKey1"]); + FirstKeyValue.Value = "newValue1"; + + refresher.ProcessPushNotification(_pushNotificationList.First(), TimeSpan.FromSeconds(0)); + await refresher.RefreshAsync(); + + Assert.Equal("newValue1", config["TestKey1"]); + } + + private Mock GetMockConfigurationClient() + { + var mockResponse = new Mock(); + var mockClient = new Mock(MockBehavior.Strict); + + Response GetTestKey(string key, string label, CancellationToken cancellationToken) + { + return Response.FromValue(TestHelpers.CloneSetting(_kvCollection.FirstOrDefault(s => s.Key == key && s.Label == label)), mockResponse.Object); + } + + Response GetIfChanged(ConfigurationSetting setting, bool onlyIfChanged, CancellationToken cancellationToken) + { + var newSetting = _kvCollection.FirstOrDefault(s => (s.Key == setting.Key && s.Label == setting.Label)); + var unchanged = (newSetting.Key == setting.Key && newSetting.Label == setting.Label && newSetting.Value == setting.Value); + var response = new MockResponse(unchanged ? 304 : 200); + return Response.FromValue(newSetting, response); + } + + // We don't actually select KV based on SettingSelector, we just return a deep copy of _kvCollection + mockClient.Setup(c => c.GetConfigurationSettingsAsync(It.IsAny(), It.IsAny())) + .Returns(() => + { + return new MockAsyncPageable(_kvCollection.Select(setting => TestHelpers.CloneSetting(setting)).ToList()); + }); + + mockClient.Setup(c => c.GetConfigurationSettingAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync((Func>)GetTestKey); + + mockClient.Setup(c => c.GetConfigurationSettingAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync((Func>)GetIfChanged); + + mockClient.Setup(c => c.UpdateSyncToken(It.IsAny())); + + return mockClient; + } + } } diff --git a/tests/Tests.AzureAppConfiguration/RefreshTests.cs b/tests/Tests.AzureAppConfiguration/RefreshTests.cs index 298fa4b8..25c88f99 100644 --- a/tests/Tests.AzureAppConfiguration/RefreshTests.cs +++ b/tests/Tests.AzureAppConfiguration/RefreshTests.cs @@ -83,10 +83,10 @@ Response GetIfChanged(ConfigurationSetting setting, bool o // Load all settings except the one registered for refresh - this test is to ensure that it will be loaded later mockClient.Setup(c => c.GetConfigurationSettingsAsync(It.IsAny(), It.IsAny())) .Returns(new MockAsyncPageable(keyValueCollection.Where(s => s.Key != "TestKey1" && s.Label != "label").ToList())); - + mockClient.Setup(c => c.GetConfigurationSettingAsync(It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync((Func>)GetTestKey); - + mockClient.Setup(c => c.GetConfigurationSettingAsync(It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync((Func>)GetIfChanged); @@ -101,7 +101,7 @@ Response GetIfChanged(ConfigurationSetting setting, bool o }); }) .Build(); - + Assert.Equal("TestValue1", config["TestKey1"]); } @@ -1049,9 +1049,9 @@ public void RefreshTests_RefreshIsCancelled() Thread.Sleep(1500); using var cancellationSource = new CancellationTokenSource(); - cancellationSource.Cancel(); + cancellationSource.Cancel(); Action action = () => refresher.RefreshAsync(cancellationSource.Token).Wait(); - var exception = Assert.Throws(action); + var exception = Assert.Throws(action); Assert.IsType(exception.InnerException); Assert.Equal("TestValue1", config["TestKey1"]); } @@ -1133,7 +1133,7 @@ Response GetIfChanged(ConfigurationSetting setting, bool o mockClient.Setup(c => c.GetConfigurationSettingAsync(It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync((Func>)GetTestKey); - + mockClient.Setup(c => c.GetConfigurationSettingAsync(It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync((Func>)GetIfChanged); @@ -1169,10 +1169,10 @@ Response GetIfChanged(ConfigurationSetting setting, bool o mockClient.Setup(c => c.GetConfigurationSettingsAsync(It.IsAny(), It.IsAny())) .Returns((Func)GetTestKeys); - + mockClient.Setup(c => c.GetConfigurationSettingAsync(It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync((Func>)GetTestKey); - + mockClient.Setup(c => c.GetConfigurationSettingAsync(It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync((Func>)GetIfChanged); diff --git a/tests/Tests.AzureAppConfiguration/TestHelper.cs b/tests/Tests.AzureAppConfiguration/TestHelper.cs index 477b4429..bc7989b2 100644 --- a/tests/Tests.AzureAppConfiguration/TestHelper.cs +++ b/tests/Tests.AzureAppConfiguration/TestHelper.cs @@ -84,8 +84,10 @@ static public void SerializeSetting(ref Utf8JsonWriter json, ConfigurationSettin { json.WriteString(tag.Key, tag.Value); } + json.WriteEndObject(); } + if (setting.ETag != default) json.WriteString("etag", setting.ETag.ToString()); if (setting.LastModified.HasValue) @@ -103,6 +105,7 @@ static public void SerializeBatch(ref Utf8JsonWriter json, ConfigurationSetting[ { SerializeSetting(ref json, item); } + json.WriteEndArray(); json.WriteEndObject(); } diff --git a/tests/Tests.AzureAppConfiguration/Tests.AzureAppConfiguration.csproj b/tests/Tests.AzureAppConfiguration/Tests.AzureAppConfiguration.csproj index 9b0f17c0..8849645f 100644 --- a/tests/Tests.AzureAppConfiguration/Tests.AzureAppConfiguration.csproj +++ b/tests/Tests.AzureAppConfiguration/Tests.AzureAppConfiguration.csproj @@ -1,4 +1,4 @@ - + net48;net6.0;net7.0;net8.0 @@ -39,4 +39,5 @@ Always + diff --git a/tests/Tests.AzureAppConfiguration/Tests.cs b/tests/Tests.AzureAppConfiguration/Tests.cs index c3b27124..30010f7d 100644 --- a/tests/Tests.AzureAppConfiguration/Tests.cs +++ b/tests/Tests.AzureAppConfiguration/Tests.cs @@ -240,7 +240,7 @@ public void TestUserAgentHeader() // 5. Contains the runtime information (target framework, OS description etc.) in the format set by the SDK // 6. Does not contain any additional components string userAgentRegex = @"^Microsoft\.Extensions\.Configuration\.AzureAppConfiguration/\d+\.\d+\.\d+(\+[a-z0-9]+)?(-preview(\.\d+)?)?,azsdk-net-Data.AppConfiguration/[.+\w-]+ \([.;\w\s]+\)$"; - + var response = new MockResponse(200); response.SetContent(SerializationHelpers.Serialize(_kvCollectionPageOne.ToArray(), TestHelpers.SerializeBatch));