diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/RetryPolicy.DataTransferDetectionErrorStrategy.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/RetryPolicy.DataTransferDetectionErrorStrategy.cs index a52619d2..74be5faf 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/RetryPolicy.DataTransferDetectionErrorStrategy.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/RetryPolicy.DataTransferDetectionErrorStrategy.cs @@ -13,7 +13,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection /// /// Provides the error detection logic for temporary faults that are commonly found during data transfer. /// - internal sealed class DataTransferErrorDetectionStrategy : ErrorDetectionStrategyBase, IErrorDetectionStrategy + internal class DataTransferErrorDetectionStrategy : ErrorDetectionStrategyBase, IErrorDetectionStrategy { private static readonly DataTransferErrorDetectionStrategy instance = new DataTransferErrorDetectionStrategy(); diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/RetryPolicy.SqlAzureTemporaryAndIgnorableErrorDetectionStrategy.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/RetryPolicy.SqlAzureTemporaryAndIgnorableErrorDetectionStrategy.cs index 0cf26070..e538f88b 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/RetryPolicy.SqlAzureTemporaryAndIgnorableErrorDetectionStrategy.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/RetryPolicy.SqlAzureTemporaryAndIgnorableErrorDetectionStrategy.cs @@ -18,7 +18,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection /// want to consider this as passing since the first execution that has timed out (or failed for some other temporary error) /// might have managed to create the object. /// - internal sealed class SqlAzureTemporaryAndIgnorableErrorDetectionStrategy : ErrorDetectionStrategyBase, IErrorDetectionStrategy + internal class SqlAzureTemporaryAndIgnorableErrorDetectionStrategy : ErrorDetectionStrategyBase, IErrorDetectionStrategy { /// /// Azure error that can be ignored diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/SqlSchemaModelErrorCodes.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/SqlSchemaModelErrorCodes.cs index 4d7a65b7..e5f126cc 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/SqlSchemaModelErrorCodes.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/ReliableConnection/SqlSchemaModelErrorCodes.cs @@ -271,21 +271,21 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection public const int InvalidFileStreamOptions = ValidationBaseCode + 65; public const int StorageShouldNotSetOnDifferentInstance = ValidationBaseCode + 66; public const int TableShouldNotHaveStorage = ValidationBaseCode + 67; - public static int MemoryOptimizedObjectsValidation_NonMemoryOptimizedTableCannotBeAccessed = ValidationBaseCode + 68; - public static int MemoryOptimizedObjectsValidation_SyntaxNotSupportedOnHekatonElement = ValidationBaseCode + 69; - public static int MemoryOptimizedObjectsValidation_ValidatePrimaryKeyForSchemaAndDataTables = ValidationBaseCode + 70; - public static int MemoryOptimizedObjectsValidation_ValidatePrimaryKeyForSchemaOnlyTables = ValidationBaseCode + 71; - public static int MemoryOptimizedObjectsValidation_OnlyNotNullableColumnsOnIndexes = ValidationBaseCode + 72; - public static int MemoryOptimizedObjectsValidation_HashIndexesOnlyOnMemoryOptimizedObjects = ValidationBaseCode + 73; - public static int MemoryOptimizedObjectsValidation_OptionOnlyForHashIndexes = ValidationBaseCode + 74; - public static int IncrementalStatisticsValidation_FilterNotSupported = ValidationBaseCode + 75; - public static int IncrementalStatisticsValidation_ViewNotSupported = ValidationBaseCode + 76; - public static int IncrementalStatisticsValidation_IndexNotPartitionAligned = ValidationBaseCode + 77; - public static int AzureV12SurfaceAreaValidation = ValidationBaseCode + 78; - public static int DuplicatedTargetObjectReferencesInSecurityPolicy = ValidationBaseCode + 79; - public static int MultipleSecurityPoliciesOnTargetObject = ValidationBaseCode + 80; - public static int ExportedRowsMayBeIncomplete = ValidationBaseCode + 81; - public static int ExportedRowsMayContainSomeMaskedData = ValidationBaseCode + 82; + public const int MemoryOptimizedObjectsValidation_NonMemoryOptimizedTableCannotBeAccessed = ValidationBaseCode + 68; + public const int MemoryOptimizedObjectsValidation_SyntaxNotSupportedOnHekatonElement = ValidationBaseCode + 69; + public const int MemoryOptimizedObjectsValidation_ValidatePrimaryKeyForSchemaAndDataTables = ValidationBaseCode + 70; + public const int MemoryOptimizedObjectsValidation_ValidatePrimaryKeyForSchemaOnlyTables = ValidationBaseCode + 71; + public const int MemoryOptimizedObjectsValidation_OnlyNotNullableColumnsOnIndexes = ValidationBaseCode + 72; + public const int MemoryOptimizedObjectsValidation_HashIndexesOnlyOnMemoryOptimizedObjects = ValidationBaseCode + 73; + public const int MemoryOptimizedObjectsValidation_OptionOnlyForHashIndexes = ValidationBaseCode + 74; + public const int IncrementalStatisticsValidation_FilterNotSupported = ValidationBaseCode + 75; + public const int IncrementalStatisticsValidation_ViewNotSupported = ValidationBaseCode + 76; + public const int IncrementalStatisticsValidation_IndexNotPartitionAligned = ValidationBaseCode + 77; + public const int AzureV12SurfaceAreaValidation = ValidationBaseCode + 78; + public const int DuplicatedTargetObjectReferencesInSecurityPolicy = ValidationBaseCode + 79; + public const int MultipleSecurityPoliciesOnTargetObject = ValidationBaseCode + 80; + public const int ExportedRowsMayBeIncomplete = ValidationBaseCode + 81; + public const int ExportedRowsMayContainSomeMaskedData = ValidationBaseCode + 82; public const int EncryptedColumnValidation_EncryptedPrimaryKey = ValidationBaseCode + 83; public const int EncryptedColumnValidation_EncryptedUniqueColumn = ValidationBaseCode + 84; public const int EncryptedColumnValidation_EncryptedCheckConstraint = ValidationBaseCode + 85; @@ -315,8 +315,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection public const int TemporalValidation_SchemaMismatch = ValidationBaseCode + 109; public const int TemporalValidation_ComputedColumns = ValidationBaseCode + 110; public const int TemporalValidation_NoAlwaysEncryptedCols = ValidationBaseCode + 111; - public static int IndexesOnExternalTable = ValidationBaseCode + 112; - public static int TriggersOnExternalTable = ValidationBaseCode + 113; + public const int IndexesOnExternalTable = ValidationBaseCode + 112; + public const int TriggersOnExternalTable = ValidationBaseCode + 113; public const int StretchValidation_ExportBlocked = ValidationBaseCode + 114; public const int StretchValidation_ImportBlocked = ValidationBaseCode + 115; public const int DeploymentBlocked = ValidationBaseCode + 116; diff --git a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/StorageDataReader.cs b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/StorageDataReader.cs index cc5d1443..33fdf6d3 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/StorageDataReader.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/QueryExecution/DataStorage/StorageDataReader.cs @@ -304,7 +304,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage /// This code is take almost verbatim from Microsoft.SqlServer.Management.UI.Grid, SSMS /// DataStorage, StorageDataReader class. /// - private class StringWriterWithMaxCapacity : StringWriter + internal class StringWriterWithMaxCapacity : StringWriter { private bool stopWriting; diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ConnectionServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ConnectionServiceTests.cs index 631a2106..80904b96 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ConnectionServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ConnectionServiceTests.cs @@ -834,7 +834,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection summary2.DatabaseName = "tempdb"; Assert.False(comparer.Equals(summary1, summary2)); - } + Assert.False(comparer.Equals(null, summary2)); + + Assert.False(summary1.GetHashCode() == summary2.GetHashCode()); + } /// /// Verify when a connection is created that the URI -> Connection mapping is created in the connection service. diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ReliableConnectionTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ReliableConnectionTests.cs index 816a4d38..4a1a42e2 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ReliableConnectionTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Connection/ReliableConnectionTests.cs @@ -19,6 +19,7 @@ using Xunit; using static Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection.ReliableConnectionHelper; using static Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection.RetryPolicy; using static Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection.RetryPolicy.TimeBasedRetryPolicy; +using static Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection.SqlSchemaModelErrorCodes; namespace Microsoft.SqlTools.ServiceLayer.Test.Connection { @@ -28,6 +29,31 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection /// public class ReliableConnectionTests { + internal class TestDataTransferErrorDetectionStrategy : DataTransferErrorDetectionStrategy + { + public bool InvokeCanRetrySqlException(SqlException exception) + { + return CanRetrySqlException(exception); + } + } + internal class TestSqlAzureTemporaryAndIgnorableErrorDetectionStrategy : SqlAzureTemporaryAndIgnorableErrorDetectionStrategy + { + public TestSqlAzureTemporaryAndIgnorableErrorDetectionStrategy() + : base (new int[] { 100 }) + { + } + + public bool InvokeCanRetrySqlException(SqlException exception) + { + return CanRetrySqlException(exception); + } + + public bool InvokeShouldIgnoreSqlException(SqlException exception) + { + return ShouldIgnoreSqlException(exception); + } + } + internal class TestFixedDelayPolicy : FixedDelayPolicy { public TestFixedDelayPolicy( @@ -613,6 +639,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection var command = new ReliableSqlConnection.ReliableSqlCommand(connection); Assert.NotNull(command.Connection); + var retryPolicy = connection.CommandRetryPolicy; + connection.CommandRetryPolicy = retryPolicy; + Assert.True(connection.CommandRetryPolicy == retryPolicy); + connection.ChangeDatabase("master"); + Assert.True(connection.ConnectionTimeout > 0); + connection.ClearPool(); } [Fact] @@ -640,6 +672,15 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection var errorReason = RetryPolicy.ThrottlingReason.FromError(sqlException.Errors[0]); Assert.NotNull(errorReason); + + var detectionStrategy = new TestDataTransferErrorDetectionStrategy(); + Assert.True(detectionStrategy.InvokeCanRetrySqlException(sqlException)); + Assert.True(detectionStrategy.CanRetry(new InvalidOperationException())); + Assert.False(detectionStrategy.ShouldIgnoreError(new InvalidOperationException())); + + var detectionStrategy2 = new TestSqlAzureTemporaryAndIgnorableErrorDetectionStrategy(); + Assert.NotNull(detectionStrategy2.InvokeCanRetrySqlException(sqlException)); + Assert.NotNull(detectionStrategy2.InvokeShouldIgnoreSqlException(sqlException)); } var unknownCodeReason = RetryPolicy.ThrottlingReason.FromReasonCode(-1); @@ -656,6 +697,29 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection Assert.NotNull(codeReason.IsUnknown); Assert.NotNull(codeReason.ToString()); } + + [Fact] + public void RetryErrorsTest() + { + var sqlServerRetryError = new SqlServerRetryError( + "test message", new Exception(), + 1, 200, ErrorSeverity.Warning); + Assert.True(sqlServerRetryError.RetryCount == 1); + Assert.NotNull(SqlServerRetryError.FormatRetryMessage(1, TimeSpan.FromSeconds(15), new Exception())); + Assert.NotNull(SqlServerRetryError.FormatIgnoreMessage(1, new Exception())); + + var sqlServerError1 = new SqlServerError("test message", "document", ErrorSeverity.Warning); + var sqlServerError2 = new SqlServerError("test message", "document", 1, ErrorSeverity.Warning); + var sqlServerError3 = new SqlServerError(new Exception(), "document",1, ErrorSeverity.Warning); + var sqlServerError4 = new SqlServerError("test message", "document", 1, 2, ErrorSeverity.Warning); + var sqlServerError5 = new SqlServerError(new Exception(), "document", 1, 2, 3, ErrorSeverity.Warning); + var sqlServerError6 = new SqlServerError("test message", "document", 1, 2, 3, ErrorSeverity.Warning); + var sqlServerError7 = new SqlServerError("test message", new Exception(), "document", 1, 2, 3, ErrorSeverity.Warning); + + Assert.True(SqlSchemaModelErrorCodes.IsParseErrorCode(46010)); + Assert.True(SqlSchemaModelErrorCodes.IsInterpretationErrorCode(Interpretation.InterpretationBaseCode+ 1)); + Assert.True(SqlSchemaModelErrorCodes.IsStatementFilterError(StatementFilter.StatementFilterBaseCode + 1)); + } } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/DataStorage/StorageDataReaderTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/DataStorage/StorageDataReaderTests.cs index 9ba5c0b9..e29c8394 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/DataStorage/StorageDataReaderTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/QueryExecution/DataStorage/StorageDataReaderTests.cs @@ -81,6 +81,18 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.QueryExecution.DataStorage string shortXml = storageReader.GetXmlWithMaxCapacity(0, 2); Assert.True(shortXml.Length == 3); } + + /// + /// Validate StringWriterWithMaxCapacity Write test + /// + [Fact] + public void StringWriterWithMaxCapacityTest() + { + var writer = new StorageDataReader.StringWriterWithMaxCapacity(null, 100); + string output = "..."; + writer.Write(output); + Assert.True(writer.ToString().Equals(output)); + } } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/SrTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/SrTests.cs new file mode 100644 index 00000000..38f46228 --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/ServiceHost/SrTests.cs @@ -0,0 +1,51 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Xunit; + +namespace Microsoft.SqlTools.ServiceLayer.Test.ServiceHost +{ + /// + /// ScriptFile test case + /// + public class SrTests + { + /// + /// Simple "test" to access string resources + /// The purpose of this test is for code coverage. It's probably better to just + /// exclude string resources in the code coverage report than maintain this test. + /// + [Fact] + public void SrStringsTest() + { + var culture = SR.Culture; + SR.Culture = culture; + Assert.True(SR.Culture == culture); + + var connectionServiceListDbErrorNullOwnerUri = SR.ConnectionServiceListDbErrorNullOwnerUri; + var connectionParamsValidateNullConnection = SR.ConnectionParamsValidateNullConnection; + var credentialsServiceInvalidCriticalHandle = SR.CredentialsServiceInvalidCriticalHandle; + var credentialsServicePasswordLengthExceeded = SR.CredentialsServicePasswordLengthExceeded; + var credentialsServiceTargetForDelete = SR.CredentialsServiceTargetForDelete; + var credentialsServiceTargetForLookup = SR.CredentialsServiceTargetForLookup; + var queryServiceCancelDisposeFailed = SR.QueryServiceCancelDisposeFailed; + var queryServiceQueryCancelled = SR.QueryServiceQueryCancelled; + var queryServiceDataReaderByteCountInvalid = SR.QueryServiceDataReaderByteCountInvalid; + var queryServiceDataReaderCharCountInvalid = SR.QueryServiceDataReaderCharCountInvalid; + var queryServiceDataReaderXmlCountInvalid = SR.QueryServiceDataReaderXmlCountInvalid; + var queryServiceFileWrapperReadOnly = SR.QueryServiceFileWrapperReadOnly; + var queryServiceAffectedOneRow = SR.QueryServiceAffectedOneRow; + var queryServiceMessageSenderNotSql = SR.QueryServiceMessageSenderNotSql; + var queryServiceResultSetNotRead = SR.QueryServiceResultSetNotRead; + var queryServiceResultSetNoColumnSchema = SR.QueryServiceResultSetNoColumnSchema; + var connectionServiceListDbErrorNotConnected = SR.ConnectionServiceListDbErrorNotConnected(".."); + var connectionServiceConnStringInvalidAuthType = SR.ConnectionServiceConnStringInvalidAuthType(".."); + var connectionServiceConnStringInvalidIntent = SR.ConnectionServiceConnStringInvalidIntent(".."); + var queryServiceAffectedRows = SR.QueryServiceAffectedRows(10); + var queryServiceErrorFormat = SR.QueryServiceErrorFormat(1, 1, 1, 1, "\n", ".."); + var queryServiceQueryFailed = SR.QueryServiceQueryFailed(".."); + var workspaceServiceBufferPositionOutOfOrder = SR.WorkspaceServiceBufferPositionOutOfOrder(1, 2, 3, 4); + } + } +}