diff --git a/Microsoft.Azure.Cosmos.Encryption.Custom/src/CosmosDataEncryptionKeyProvider.cs b/Microsoft.Azure.Cosmos.Encryption.Custom/src/CosmosDataEncryptionKeyProvider.cs index 773845aa9e..d3bc14dd6b 100644 --- a/Microsoft.Azure.Cosmos.Encryption.Custom/src/CosmosDataEncryptionKeyProvider.cs +++ b/Microsoft.Azure.Cosmos.Encryption.Custom/src/CosmosDataEncryptionKeyProvider.cs @@ -192,8 +192,8 @@ private async Task FetchDekAsync(string id, string encryption cancellationToken: cancellationToken); // supports Encryption with MDE based algorithm using Legacy Encryption Algorithm Configured DEK. - if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized) && - string.Equals(dataEncryptionKeyProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized)) + if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal) && + string.Equals(dataEncryptionKeyProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal)) { return await this.dataEncryptionKeyContainerCore.FetchUnWrappedMdeSupportedLegacyDekAsync( dataEncryptionKeyProperties, @@ -201,8 +201,8 @@ private async Task FetchDekAsync(string id, string encryption } // supports Encryption with Legacy based algorithm using Mde Encryption Algorithm Configured DEK. - if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized) && - string.Equals(dataEncryptionKeyProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized)) + if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal) && + string.Equals(dataEncryptionKeyProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal)) { return await this.dataEncryptionKeyContainerCore.FetchUnWrappedLegacySupportedMdeDekAsync( dataEncryptionKeyProperties, diff --git a/Microsoft.Azure.Cosmos.Encryption.Custom/src/CosmosEncryptionAlgorithm.cs b/Microsoft.Azure.Cosmos.Encryption.Custom/src/CosmosEncryptionAlgorithm.cs index 0bca224438..94a5c3f72d 100644 --- a/Microsoft.Azure.Cosmos.Encryption.Custom/src/CosmosEncryptionAlgorithm.cs +++ b/Microsoft.Azure.Cosmos.Encryption.Custom/src/CosmosEncryptionAlgorithm.cs @@ -31,8 +31,8 @@ public static class CosmosEncryptionAlgorithm /// Returns True if the Algorithm is supported. internal static bool VerifyIfSupportedAlgorithm(string encryptionAlgorithm) { - if (!string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized) && - !string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized)) + if (!string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal) && + !string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal)) { return false; } diff --git a/Microsoft.Azure.Cosmos.Encryption.Custom/src/DataEncryptionKeyContainerCore.cs b/Microsoft.Azure.Cosmos.Encryption.Custom/src/DataEncryptionKeyContainerCore.cs index 68e5414275..2291292509 100644 --- a/Microsoft.Azure.Cosmos.Encryption.Custom/src/DataEncryptionKeyContainerCore.cs +++ b/Microsoft.Azure.Cosmos.Encryption.Custom/src/DataEncryptionKeyContainerCore.cs @@ -78,7 +78,7 @@ public override async Task> CreateData EncryptionKeyWrapMetadata updatedMetadata = null; InMemoryRawDek inMemoryRawDek = null; - if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized)) + if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal)) { (wrappedDek, updatedMetadata, inMemoryRawDek) = await this.GenerateAndWrapRawDekForLegacyEncAlgoAsync( id, @@ -87,7 +87,7 @@ public override async Task> CreateData diagnosticsContext, cancellationToken); } - else if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized)) + else if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal)) { (wrappedDek, updatedMetadata) = this.GenerateAndWrapPdekForMdeEncAlgo(id, encryptionKeyWrapMetadata); } @@ -118,7 +118,7 @@ public override async Task> CreateData this.DekProvider.DekCache.SetDekProperties(id, dekProperties); - if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized)) + if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal)) { this.DekProvider.DekCache.SetRawDek(id, inMemoryRawDek); } @@ -165,7 +165,7 @@ public override async Task> RewrapData byte[] rawkey = null; - if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized)) + if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal)) { InMemoryRawDek inMemoryRawDek = await this.FetchUnwrappedAsync( dekProperties, @@ -174,7 +174,7 @@ public override async Task> RewrapData rawkey = inMemoryRawDek.DataEncryptionKey.RawKey; } - else if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized)) + else if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal)) { EncryptionKeyUnwrapResult encryptionKeyUnwrapResult = await this.DekProvider.MdeKeyWrapProvider.UnwrapKeyAsync( dekProperties.WrappedDataEncryptionKey, @@ -186,8 +186,8 @@ public override async Task> RewrapData if (!string.IsNullOrEmpty(encryptionAlgorithm)) { - if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized) - && string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized)) + if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal) + && string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal)) { throw new InvalidOperationException($"Rewrap operation with EncryptionAlgorithm '{encryptionAlgorithm}' is not supported on Data Encryption Keys" + $" which are configured with '{CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized}'. "); @@ -264,7 +264,7 @@ await this.ReadDataEncryptionKeyAsync( this.DekProvider.DekCache.SetDekProperties(id, dekProperties); - if (string.Equals(newDekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized)) + if (string.Equals(newDekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal)) { this.DekProvider.DekCache.SetRawDek(id, updatedRawDek); } @@ -384,7 +384,7 @@ internal async Task FetchUnwrappedAsync( { try { - if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized)) + if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal)) { DataEncryptionKey dek = this.InitMdeEncryptionAlgorithm(dekProperties, withRawKey); @@ -419,11 +419,11 @@ internal async Task FetchUnwrappedAsync( using (diagnosticsContext.CreateScope("WrapDataEncryptionKey")) { - if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized) && this.DekProvider.EncryptionKeyWrapProvider != null) + if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal) && this.DekProvider.EncryptionKeyWrapProvider != null) { keyWrapResponse = await this.DekProvider.EncryptionKeyWrapProvider.WrapKeyAsync(key, metadata, cancellationToken); } - else if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized) && this.DekProvider.MdeKeyWrapProvider != null) + else if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal) && this.DekProvider.MdeKeyWrapProvider != null) { keyWrapResponse = await this.DekProvider.MdeKeyWrapProvider.WrapKeyAsync(key, metadata, cancellationToken); } @@ -446,12 +446,12 @@ internal async Task FetchUnwrappedAsync( byte[] rawKey = null; InMemoryRawDek roundTripResponse = null; - if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized)) + if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized, StringComparison.Ordinal)) { roundTripResponse = await this.UnwrapAsync(tempDekProperties, diagnosticsContext, cancellationToken); rawKey = roundTripResponse.DataEncryptionKey.RawKey; } - else if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized)) + else if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized, StringComparison.Ordinal)) { EncryptionKeyUnwrapResult unwrapResult = await this.UnWrapDekMdeEncAlgoAsync( tempDekProperties, diff --git a/Microsoft.Azure.Cosmos.Encryption.Custom/src/EncryptionProcessor.cs b/Microsoft.Azure.Cosmos.Encryption.Custom/src/EncryptionProcessor.cs index 0370b94771..d4d3acb6ac 100644 --- a/Microsoft.Azure.Cosmos.Encryption.Custom/src/EncryptionProcessor.cs +++ b/Microsoft.Azure.Cosmos.Encryption.Custom/src/EncryptionProcessor.cs @@ -61,26 +61,26 @@ public static async Task EncryptAsync( return input; } - if (!encryptionOptions.PathsToEncrypt.Distinct().SequenceEqual(encryptionOptions.PathsToEncrypt)) + if (encryptionOptions.PathsToEncrypt.Distinct().Count() != encryptionOptions.PathsToEncrypt.Count()) { throw new InvalidOperationException("Duplicate paths in PathsToEncrypt passed via EncryptionOptions."); } foreach (string path in encryptionOptions.PathsToEncrypt) { - if (string.IsNullOrWhiteSpace(path) || path[0] != '/' || path.LastIndexOf('/') != 0) + if (string.IsNullOrWhiteSpace(path) || path[0] != '/' || path.IndexOf('/', 1) != -1) { throw new InvalidOperationException($"Invalid path {path ?? string.Empty}, {nameof(encryptionOptions.PathsToEncrypt)}"); } - if (string.Equals(path.Substring(1), "id")) + if (path.AsSpan(1).Equals("id".AsSpan(), StringComparison.Ordinal)) { throw new InvalidOperationException($"{nameof(encryptionOptions.PathsToEncrypt)} includes a invalid path: '{path}'."); } } JObject itemJObj = EncryptionProcessor.BaseSerializer.FromStream(input); - List pathsEncrypted = new List(); + List pathsEncrypted = new List(encryptionOptions.PathsToEncrypt.Count()); EncryptionProperties encryptionProperties = null; byte[] plainText = null; byte[] cipherText = null; diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/NonStreamingOrderByQueryTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/NonStreamingOrderByQueryTests.cs index c21f76d610..abf9261351 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/NonStreamingOrderByQueryTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Query/NonStreamingOrderByQueryTests.cs @@ -324,9 +324,9 @@ private sealed class Document private static class DebugTraceHelpers { +#pragma warning disable CS0162, CS0649 // Unreachable code detected private const bool Enabled = false; -#pragma warning disable CS0162 // Unreachable code detected public static void TraceSupportedFeaturesString(string supportedQueryFeatures) { if (Enabled) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ChangeFeed/ChangeFeedPartitionKeyResultSetIteratorCoreTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ChangeFeed/ChangeFeedPartitionKeyResultSetIteratorCoreTests.cs index 5f8a9903bf..8de33c9c0a 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ChangeFeed/ChangeFeedPartitionKeyResultSetIteratorCoreTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ChangeFeed/ChangeFeedPartitionKeyResultSetIteratorCoreTests.cs @@ -40,6 +40,7 @@ public async Task EtagPassesContinuation() Mock containerMock = new Mock(); Mock mockContext = new Mock(); +#pragma warning disable CA1416 // 'ResourceType' is only supported on: 'windows' mockContext.Setup(x => x.OperationHelperAsync( It.Is(str => str.Contains("Change Feed Processor")), It.IsAny(), @@ -59,6 +60,7 @@ public async Task EtagPassesContinuation() return func(trace); } }); +#pragma warning restore CA1416 mockContext.Setup(c => c.ProcessResourceOperationStreamAsync( It.IsAny(), @@ -121,6 +123,7 @@ public async Task NextReadHasUpdatedContinuation() Mock containerMock = new Mock(); Mock mockContext = new Mock(); +#pragma warning disable CA1416 // 'ResourceType' is only supported on: 'windows' mockContext.Setup(x => x.OperationHelperAsync( It.Is(str => str.Contains("Change Feed Processor")), It.IsAny(), @@ -140,6 +143,7 @@ public async Task NextReadHasUpdatedContinuation() return func(trace); } }); +#pragma warning restore CA1416 mockContext.SetupSequence(c => c.ProcessResourceOperationStreamAsync( It.IsAny(), @@ -192,6 +196,7 @@ public async Task ShouldSetFeedRangePartitionKeyRange() Mock containerMock = new Mock(); Mock mockContext = new Mock(); +#pragma warning disable CA1416 // 'ResourceType' is only supported on: 'windows' mockContext.Setup(x => x.OperationHelperAsync( It.Is(str => str.Contains("Change Feed Processor")), It.IsAny(), @@ -211,6 +216,7 @@ public async Task ShouldSetFeedRangePartitionKeyRange() return func(trace); } }); +#pragma warning restore CA1416 mockContext.Setup(c => c.ProcessResourceOperationStreamAsync( It.IsAny(), diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs index caa56b2911..0c7c332854 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/ClientRetryPolicyTests.cs @@ -270,54 +270,54 @@ public void HttpRequestExceptionHandelingTests( } [TestMethod] - public Task ClientRetryPolicy_Retry_SingleMaster_Read_PreferredLocations() + public async Task ClientRetryPolicy_Retry_SingleMaster_Read_PreferredLocationsAsync() { - return this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: true); + await this.ValidateConnectTimeoutTriggersClientRetryPolicyAsync(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: true); } [TestMethod] - public Task ClientRetryPolicy_Retry_MultiMaster_Read_PreferredLocations() + public async Task ClientRetryPolicy_Retry_MultiMaster_Read_PreferredLocationsAsync() { - return this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); + await this.ValidateConnectTimeoutTriggersClientRetryPolicyAsync(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); } [TestMethod] - public Task ClientRetryPolicy_Retry_MultiMaster_Write_PreferredLocations() + public async Task ClientRetryPolicy_Retry_MultiMaster_Write_PreferredLocationsAsync() { - return this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); + await this.ValidateConnectTimeoutTriggersClientRetryPolicyAsync(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: true, shouldHaveRetried: true); } [TestMethod] - public Task ClientRetryPolicy_NoRetry_SingleMaster_Write_PreferredLocations() + public async Task ClientRetryPolicy_NoRetry_SingleMaster_Write_PreferredLocationsAsync() { - return this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: false); + await this.ValidateConnectTimeoutTriggersClientRetryPolicyAsync(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: true, shouldHaveRetried: false); } [TestMethod] - public Task ClientRetryPolicy_NoRetry_SingleMaster_Read_NoPreferredLocations() + public async Task ClientRetryPolicy_NoRetry_SingleMaster_Read_NoPreferredLocationsAsync() { - return this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); + await this.ValidateConnectTimeoutTriggersClientRetryPolicyAsync(isReadRequest: true, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); } [TestMethod] - public Task ClientRetryPolicy_NoRetry_SingleMaster_Write_NoPreferredLocations() + public async Task ClientRetryPolicy_NoRetry_SingleMaster_Write_NoPreferredLocationsAsync() { - return this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); + await this.ValidateConnectTimeoutTriggersClientRetryPolicyAsync(isReadRequest: false, useMultipleWriteLocations: false, usesPreferredLocations: false, shouldHaveRetried: false); } [TestMethod] - public Task ClientRetryPolicy_NoRetry_MultiMaster_Read_NoPreferredLocations() + public async Task ClientRetryPolicy_NoRetry_MultiMaster_Read_NoPreferredLocationsAsync() { - return this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: false, false); + await this.ValidateConnectTimeoutTriggersClientRetryPolicyAsync(isReadRequest: true, useMultipleWriteLocations: true, usesPreferredLocations: false, false); } [TestMethod] - public Task ClientRetryPolicy_NoRetry_MultiMaster_Write_NoPreferredLocations() + public async Task ClientRetryPolicy_NoRetry_MultiMaster_Write_NoPreferredLocationsAsync() { - return this.ValidateConnectTimeoutTriggersClientRetryPolicy(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: false, false); + await this.ValidateConnectTimeoutTriggersClientRetryPolicyAsync(isReadRequest: false, useMultipleWriteLocations: true, usesPreferredLocations: false, false); } - private async Task ValidateConnectTimeoutTriggersClientRetryPolicy( + private async Task ValidateConnectTimeoutTriggersClientRetryPolicyAsync( bool isReadRequest, bool useMultipleWriteLocations, bool usesPreferredLocations, diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs index c27ca8abf1..61fddc521d 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosClientOptionsUnitTests.cs @@ -11,6 +11,7 @@ namespace Microsoft.Azure.Cosmos.Tests using System.Net; using System.Net.Http; using System.Net.Security; + using System.Reflection; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text; @@ -699,6 +700,8 @@ public void VerifyCorrectProtocolIsSet() public void VerifyLimitToEndpointSettings() { CosmosClientOptions cosmosClientOptions = new CosmosClientOptions { ApplicationRegion = Regions.EastUS, LimitToEndpoint = true }; + + // For invalid regions GetConnectionPolicy will throw exception cosmosClientOptions.GetConnectionPolicy(clientId: 0); } @@ -707,6 +710,8 @@ public void VerifyLimitToEndpointSettings() public void VerifyLimitToEndpointSettingsWithPreferredRegions() { CosmosClientOptions cosmosClientOptions = new CosmosClientOptions { ApplicationPreferredRegions = new List() { Regions.EastUS }, LimitToEndpoint = true }; + + // For invalid regions GetConnectionPolicy will throw exception cosmosClientOptions.GetConnectionPolicy(clientId: 0); } @@ -715,9 +720,40 @@ public void VerifyLimitToEndpointSettingsWithPreferredRegions() public void VerifyApplicationRegionSettingsWithPreferredRegions() { CosmosClientOptions cosmosClientOptions = new CosmosClientOptions { ApplicationPreferredRegions = new List() { Regions.EastUS }, ApplicationRegion = Regions.EastUS }; + + // For invalid regions GetConnectionPolicy will throw exception cosmosClientOptions.GetConnectionPolicy(clientId: 0); } + [TestMethod] + [DynamicData(nameof(GetPublicRegionNames), DynamicDataSourceType.Method)] + public void VerifyApplicationRegionSettingsForAllPublicRegions(string regionName) + { + CosmosClientOptions cosmosClientOptions = new CosmosClientOptions { ApplicationRegion = regionName }; + + // For invalid regions GetConnectionPolicy will throw exception + cosmosClientOptions.GetConnectionPolicy(clientId: 0); + } + + private static IEnumerable GetPublicRegionNames() + { + List regionNames = new List(); + + // BindingFlags.FlattenHierarchy MUST for const fields + foreach (FieldInfo fieldInfo in typeof(Regions).GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)) + { + string regionValue = fieldInfo.GetValue(null).ToString(); + + if (!regionValue.Equals(Regions.GermanyCentral, StringComparison.OrdinalIgnoreCase) + && !regionValue.Equals(Regions.GermanyNortheast, StringComparison.OrdinalIgnoreCase)) + { + regionNames.Add(new object[] { regionValue }); + } + } + + return regionNames; + } + [TestMethod] [ExpectedException(typeof(ArgumentException))] public void VerifyWebProxyHttpClientFactorySet() @@ -1074,8 +1110,10 @@ public void TestServerCertificatesValidationWithDisableSSLFlagTrue(string connSt CosmosHttpClient httpClient = cosmosClient.DocumentClient.httpClient; SocketsHttpHandler socketsHttpHandler = (SocketsHttpHandler)httpClient.HttpMessageHandler; +#nullable enable RemoteCertificateValidationCallback? httpClientRemoreCertValidationCallback = socketsHttpHandler.SslOptions.RemoteCertificateValidationCallback; Assert.IsNotNull(httpClientRemoreCertValidationCallback); +#nullable disable } private class TestWebProxy : IWebProxy diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Microsoft.Azure.Cosmos.Tests.csproj b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Microsoft.Azure.Cosmos.Tests.csproj index 5a5cfa28d2..12773b7493 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Microsoft.Azure.Cosmos.Tests.csproj +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Microsoft.Azure.Cosmos.Tests.csproj @@ -10,6 +10,7 @@ false Microsoft.Azure.Cosmos.Tests $(LangVersion) + true diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/NonStreamingOrderByQueryTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/NonStreamingOrderByQueryTests.cs index e579a86ee1..46753d3a49 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/NonStreamingOrderByQueryTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Query/Pipeline/NonStreamingOrderByQueryTests.cs @@ -727,8 +727,8 @@ private async Task SplitMergeAsync() private static class DebugTraceHelpers { - private const bool Enabled = false; -#pragma warning disable CS0162 // Unreachable code detected +#pragma warning disable CS0162, CS0649 // Unreachable code detected + private static readonly bool Enabled; [Conditional("DEBUG")] public static void TraceSplit(FeedRangeInternal feedRange) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHash.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHash.cs index 0d7189abb2..6b098d5440 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHash.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Routing/PartitionKeyHash.cs @@ -76,10 +76,12 @@ public override bool Equals(object obj) return false; } +#pragma warning disable CA2013 // value boxing, also this check seems redundant (future todo) if (object.ReferenceEquals(this, obj)) { return true; } +#pragma warning restore CA2013 return this.Equals(effectivePartitionKey); } diff --git a/templates/build-test.yml b/templates/build-test.yml index f1def5dab5..6d342fefc8 100644 --- a/templates/build-test.yml +++ b/templates/build-test.yml @@ -46,7 +46,7 @@ jobs: dotnet tool install -g dotnet-reportgenerator-globaltool reportgenerator -reports:$(Build.SourcesDirectory)/Microsoft.Azure.Cosmos/tests/**/coverage.cobertura.xml -targetdir:$(Build.SourcesDirectory)/CodeCoverage -reporttypes:HtmlInline_AzurePipelines;Cobertura displayName: Create Code coverage report - - task: PublishCodeCoverageResults@1 + - task: PublishCodeCoverageResults@2 displayName: 'Publish code coverage' inputs: codeCoverageTool: Cobertura diff --git a/templates/emulator-setup.yml b/templates/emulator-setup.yml index f081209295..bc8ab088dc 100644 --- a/templates/emulator-setup.yml +++ b/templates/emulator-setup.yml @@ -6,11 +6,28 @@ steps: Invoke-WebRequest "$env:EMULATORMSIURL" -OutFile "$env:temp\azure-cosmosdb-emulator.msi" Write-Host "Finished Downloading Cosmos Emulator - $env:temp\azure-cosmosdb-emulator.msi" -ForegroundColor green dir "$env:temp" - choco install lessmsi - choco upgrade lessmsi - mkdir "$env:temp\Azure Cosmos DB Emulator" - lessmsi x "$env:temp\azure-cosmosdb-emulator.msi" "$env:temp\Azure Cosmos DB Emulator\" - Add-MpPreference -ExclusionPath "$env:temp\Azure Cosmos DB Emulator\SourceDir\Azure Cosmos DB Emulator" + + function Remove-DirectoryIfExists { + param ([string]$Path) + + if (Test-Path -Path $Path -PathType Container) { + Remove-Item -Path $Path -Recurse -Force + Write-Output "Folder deleted: $Path" + } else { + Write-Output "Folder does not exist: $Path" + } + } + + $lessMsiDir="$env:temp\lessmsi" + $emulatorDir="$env:temp\Azure Cosmos DB Emulator\" + + Remove-DirectoryIfExists -Path $lessMsiDir + Remove-DirectoryIfExists -Path $emulatorDir + + Expand-Archive -LiteralPath 'tools\lessmsi-v2.1.1.zip' -DestinationPath $lessMsiDir + &"$env:temp\lessmsi\lessmsi.exe" x "$env:temp\azure-cosmosdb-emulator.msi" "$emulatorDir" + + Add-MpPreference -ExclusionPath "$emulatorDir\SourceDir\Azure Cosmos DB Emulator" Add-MpPreference -ExclusionPath "$env:localappdata\CosmosDBEmulator" displayName: Downloading and Installing Cosmos DB Emulator failOnStderr: true diff --git a/tools/lessmsi-v2.1.1.zip b/tools/lessmsi-v2.1.1.zip new file mode 100644 index 0000000000..15cc3d9f24 Binary files /dev/null and b/tools/lessmsi-v2.1.1.zip differ