From c778c1a86db9614bd125d5442730aefa09ebf1ff Mon Sep 17 00:00:00 2001 From: Johnny Pham Date: Fri, 18 Mar 2022 15:27:02 -0700 Subject: [PATCH 1/3] 1es 3.1 --- BUILDGUIDE.md | 2 +- .../Setup/CertificateUtilityWin.cs | 3 +- .../ManualTests/DataCommon/DataTestUtility.cs | 2 + .../SQL/AdapterTest/AdapterTest.cs | 179 +++++++++++------- .../Config.cs | 1 + .../config.default.json | 3 +- 6 files changed, 120 insertions(+), 70 deletions(-) diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md index 3cddb58e7b..a838d672b7 100644 --- a/BUILDGUIDE.md +++ b/BUILDGUIDE.md @@ -122,7 +122,7 @@ Manual Tests require the below setup to run: |SupportsFileStream | (Optional) Whether or not FileStream is enabled on SQL Server| `true` OR `false`| |UseManagedSNIOnWindows | (Optional) Enables testing with Managed SNI on Windows| `true` OR `false`| |IsAzureSynpase | (Optional) When set to 'true', test suite runs compatible tests for Azure Synapse/Parallel Data Warehouse. | `true` OR `false`| - + |MakecertPath | The full path to makecert.exe. This is not required if the path is present in the PATH environment variable. | `D:\\escaped\\absolute\\path\\to\\makecert.exe` | ### Commands to run Manual Tests: - Windows (`netfx x86`): diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtilityWin.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtilityWin.cs index 91a0b6e7fb..66d3c3588d 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtilityWin.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtilityWin.cs @@ -31,7 +31,8 @@ internal static void CreateCertificate(string certificateName, string certificat Assert.False(string.IsNullOrWhiteSpace(certificateName), "FAILED: certificateName should not be null or empty."); Assert.False(string.IsNullOrWhiteSpace(certificateLocation), "FAILED: certificateLocation should not be null or empty."); - ProcessStartInfo processStartInfo = new ProcessStartInfo(@"makecert"); + string makecertPath = string.IsNullOrEmpty(DataTestUtility.MakecertPath) ? "makecert" : DataTestUtility.MakecertPath; + ProcessStartInfo processStartInfo = new ProcessStartInfo(makecertPath); processStartInfo.Arguments = string.Format(@"-n ""CN={0}"" -pe -sr {1} -r -eku 1.3.6.1.5.5.8.2.2,1.3.6.1.4.1.311.10.3.11 -ss my -sky exchange -sp ""{2}"" -sy {3} -len 2048 -a sha256", certificateName, certificateLocation, diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index e3a1fea22d..78bcbf3b15 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -48,6 +48,7 @@ public static class DataTestUtility public static readonly bool UseManagedSNIOnWindows = false; public static readonly bool IsAzureSynapse = false; public static Uri AKVBaseUri = null; + public static readonly string MakecertPath = null; public static readonly string DNSCachingConnString = null; public static readonly string DNSCachingServerCR = null; // this is for the control ring @@ -95,6 +96,7 @@ static DataTestUtility() IsDNSCachingSupportedTR = c.IsDNSCachingSupportedTR; EnclaveAzureDatabaseConnString = c.EnclaveAzureDatabaseConnString; UserManagedIdentityClientId = c.UserManagedIdentityClientId; + MakecertPath = c.MakecertPath; System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12; diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AdapterTest/AdapterTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AdapterTest/AdapterTest.cs index ae52a6efab..d00a9cf8b1 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AdapterTest/AdapterTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AdapterTest/AdapterTest.cs @@ -54,10 +54,10 @@ public class AdapterTest public AdapterTest() { // create random name for temp tables - _randomGuid = Guid.NewGuid().ToString(); - _tempTable = Environment.MachineName + "_" + _randomGuid; + _tempTable = DataTestUtility.GetUniqueName("AdapterTest"); _tempTable = _tempTable.Replace('-', '_'); + _randomGuid = Guid.NewGuid().ToString(); _tempKey = "employee_id_key_" + Environment.TickCount.ToString() + _randomGuid; _tempKey = _tempKey.Replace('-', '_'); @@ -179,15 +179,15 @@ public void PrepUnprepTest() public void SqlVariantTest() { string tableName = DataTestUtility.GenerateObjectName(); - try + // good test for null values and unicode strings + using (SqlConnection conn = new SqlConnection(DataTestUtility.TCPConnectionString)) + using (SqlCommand cmd = new SqlCommand(null, conn)) + using (SqlDataAdapter sqlAdapter = new SqlDataAdapter()) { - ExecuteNonQueryCommand("CREATE TABLE " + tableName + " (c0_bigint bigint, c1_variant sql_variant)"); - - // good test for null values and unicode strings - using (SqlConnection conn = new SqlConnection(DataTestUtility.TCPConnectionString)) - using (SqlCommand cmd = new SqlCommand(null, conn)) - using (SqlDataAdapter sqlAdapter = new SqlDataAdapter()) + try { + ExecuteNonQueryCommand("CREATE TABLE " + tableName + " (c0_bigint bigint, c1_variant sql_variant)"); + cmd.Connection.Open(); // the ORDER BY clause tests that we correctly ignore the ORDER token @@ -263,10 +263,10 @@ public void SqlVariantTest() } } } - } - finally - { - ExecuteNonQueryCommand("DROP TABLE " + tableName); + finally + { + DataTestUtility.DropTable(conn, tableName); + } } } @@ -659,7 +659,7 @@ public void UpdateTest() } finally { - ExecuteNonQueryCommand("DROP TABLE " + _tempTable); + DataTestUtility.DropTable(conn, _tempTable); } } } @@ -757,7 +757,7 @@ public void BulkUpdateTest() } finally { - ExecuteNonQueryCommand("DROP TABLE " + _tempTable); + DataTestUtility.DropTable(conn, _tempTable); } } } @@ -768,25 +768,27 @@ public void BulkUpdateTest() [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] public void UpdateRefreshTest() { + string identTableName = DataTestUtility.GetUniqueName("ID_"); string createIdentTable = - "CREATE TABLE ID_" + _tempTable + "(id int IDENTITY," + + $"CREATE TABLE {identTableName} (id int IDENTITY," + "LastName nvarchar(50) NULL," + "Firstname nvarchar(50) NULL)"; + string spName = DataTestUtility.GetUniqueName("sp_insert", withBracket: false); string spCreateInsert = - "CREATE PROCEDURE sp_insert" + _tempTable + + $"CREATE PROCEDURE {spName}" + "(@FirstName nvarchar(50), @LastName nvarchar(50), @id int OUTPUT) " + "AS INSERT INTO " + _tempTable + " (FirstName, LastName) " + "VALUES (@FirstName, @LastName); " + "SELECT @id=@@IDENTITY"; - string spDropInsert = "DROP PROCEDURE sp_insert" + _tempTable; + string spDropInsert = $"DROP PROCEDURE {spName}"; bool dropSP = false; using (SqlDataAdapter adapter = new SqlDataAdapter()) using (SqlConnection conn = new SqlConnection(DataTestUtility.TCPConnectionString)) using (SqlCommand cmd = new SqlCommand(null, conn)) - using (SqlCommand temp = new SqlCommand("SELECT id, LastName, FirstName into " + _tempTable + " from ID_" + _tempTable, conn)) + using (SqlCommand temp = new SqlCommand("SELECT id, LastName, FirstName into " + _tempTable + $" from {identTableName}", conn)) using (SqlCommand tableClean = new SqlCommand("", conn)) { ExecuteNonQueryCommand(createIdentTable); @@ -794,7 +796,7 @@ public void UpdateRefreshTest() { adapter.InsertCommand = new SqlCommand() { - CommandText = "sp_insert" + _tempTable, + CommandText = spName, CommandType = CommandType.StoredProcedure }; adapter.InsertCommand.Parameters.Add(new SqlParameter("@FirstName", SqlDbType.NVarChar, 50, "FirstName")); @@ -851,9 +853,9 @@ public void UpdateRefreshTest() { if (dropSP) { - ExecuteNonQueryCommand(spDropInsert); - ExecuteNonQueryCommand("DROP TABLE " + _tempTable); - ExecuteNonQueryCommand("DROP TABLE ID_" + _tempTable); + DataTestUtility.DropStoredProcedure(conn, spName); + DataTestUtility.DropTable(conn, _tempTable); + DataTestUtility.DropTable(conn, identTableName); } } } @@ -873,18 +875,18 @@ public void UpdateNullTest() "VALUES (@val_cvarbin, @val_cimage)"; bool dropSP = false; - try - { - ExecuteNonQueryCommand(createTable); - ExecuteNonQueryCommand(createSP); - dropSP = true; - using (SqlConnection conn = new SqlConnection(DataTestUtility.TCPConnectionString)) - using (SqlCommand cmdInsert = new SqlCommand(procName, conn)) - using (SqlCommand cmdSelect = new SqlCommand("select * from " + tableName, conn)) - using (SqlCommand tableClean = new SqlCommand("delete " + tableName, conn)) - using (SqlDataAdapter adapter = new SqlDataAdapter()) + using (SqlConnection conn = new SqlConnection(DataTestUtility.TCPConnectionString)) + using (SqlCommand cmdInsert = new SqlCommand(procName, conn)) + using (SqlCommand cmdSelect = new SqlCommand("select * from " + tableName, conn)) + using (SqlCommand tableClean = new SqlCommand("delete " + tableName, conn)) + using (SqlDataAdapter adapter = new SqlDataAdapter()) + { + try { + ExecuteNonQueryCommand(createTable); + ExecuteNonQueryCommand(createSP); + dropSP = true; conn.Open(); cmdInsert.CommandType = CommandType.StoredProcedure; @@ -905,13 +907,13 @@ public void UpdateNullTest() DataTestUtility.AssertEqualsWithDescription(DBNull.Value, ds.Tables[0].Rows[0][0], "Unexpected value."); DataTestUtility.AssertEqualsWithDescription(DBNull.Value, ds.Tables[0].Rows[0][1], "Unexpected value."); } - } - finally - { - if (dropSP) + finally { - ExecuteNonQueryCommand("DROP PROCEDURE " + procName); - ExecuteNonQueryCommand("DROP TABLE " + tableName); + if (dropSP) + { + DataTestUtility.DropStoredProcedure(conn, procName); + DataTestUtility.DropTable(conn, tableName); + } } } } @@ -930,18 +932,18 @@ public void UpdateOffsetTest() "VALUES (@val_cvarbin, @val_cimage)"; bool dropSP = false; - try - { - ExecuteNonQueryCommand(createTable); - ExecuteNonQueryCommand(createSP); - dropSP = true; - using (SqlConnection conn = new SqlConnection(DataTestUtility.TCPConnectionString)) - using (SqlCommand cmdInsert = new SqlCommand(procName, conn)) - using (SqlCommand cmdSelect = new SqlCommand("select * from " + tableName, conn)) - using (SqlCommand tableClean = new SqlCommand("delete " + tableName, conn)) - using (SqlDataAdapter adapter = new SqlDataAdapter()) + using (SqlConnection conn = new SqlConnection(DataTestUtility.TCPConnectionString)) + using (SqlCommand cmdInsert = new SqlCommand(procName, conn)) + using (SqlCommand cmdSelect = new SqlCommand("select * from " + tableName, conn)) + using (SqlCommand tableClean = new SqlCommand("delete " + tableName, conn)) + using (SqlDataAdapter adapter = new SqlDataAdapter()) + { + try { + ExecuteNonQueryCommand(createTable); + ExecuteNonQueryCommand(createSP); + dropSP = true; conn.Open(); cmdInsert.CommandType = CommandType.StoredProcedure; @@ -978,13 +980,13 @@ public void UpdateOffsetTest() val = (byte[])(ds.Tables[0].Rows[0][1]); Assert.True(ByteArraysEqual(expectedBytes2, val), "FAILED: Test 2: Unequal byte arrays."); } - } - finally - { - if (dropSP) + finally { - ExecuteNonQueryCommand("DROP PROCEDURE " + procName); - ExecuteNonQueryCommand("DROP TABLE " + tableName); + if (dropSP) + { + DataTestUtility.DropStoredProcedure(conn, procName); + DataTestUtility.DropTable(conn, tableName); + } } } } @@ -1069,7 +1071,7 @@ public void AutoGenUpdateTest() } finally { - ExecuteNonQueryCommand("DROP TABLE " + _tempTable); + DataTestUtility.DropTable(conn, _tempTable); } } } @@ -1078,16 +1080,17 @@ public void AutoGenUpdateTest() [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] public void AutoGenErrorTest() { + string identTableName = DataTestUtility.GetUniqueName("ID_"); string createIdentTable = - "CREATE TABLE ID_" + _tempTable + "(id int IDENTITY," + + $"CREATE TABLE {identTableName} (id int IDENTITY," + "LastName nvarchar(50) NULL," + "Firstname nvarchar(50) NULL)"; - try + using (SqlConnection conn = new SqlConnection(DataTestUtility.TCPConnectionString)) + using (SqlCommand cmd = new SqlCommand($"SELECT * into {_tempTable} from {identTableName}", conn)) + using (SqlDataAdapter adapter = new SqlDataAdapter()) { - using (SqlConnection conn = new SqlConnection(DataTestUtility.TCPConnectionString)) - using (SqlCommand cmd = new SqlCommand("SELECT * into " + _tempTable + " from ID_" + _tempTable, conn)) - using (SqlDataAdapter adapter = new SqlDataAdapter()) + try { ExecuteNonQueryCommand(createIdentTable); @@ -1110,11 +1113,11 @@ public void AutoGenErrorTest() SqlCommandBuilder builder = new SqlCommandBuilder(adapter); adapter.Update(ds, _tempTable); } - } - finally - { - ExecuteNonQueryCommand("DROP TABLE " + _tempTable); - ExecuteNonQueryCommand("DROP TABLE ID_" + _tempTable); + finally + { + DataTestUtility.DropTable(conn, _tempTable); + DataTestUtility.DropTable(conn, identTableName); + } } } @@ -1206,7 +1209,7 @@ public void AutoGenBulkUpdateTest() } finally { - ExecuteNonQueryCommand("DROP TABLE " + _tempTable); + DataTestUtility.DropTable(conn, _tempTable); } } } @@ -1319,6 +1322,48 @@ public void TestReadOnlyColumnMetadata() } } + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] + [InlineData(nameof(SqlCommandBuilder.GetInsertCommand), null)] + [InlineData(nameof(SqlCommandBuilder.GetInsertCommand), true)] + [InlineData(nameof(SqlCommandBuilder.GetInsertCommand), false)] + [InlineData(nameof(SqlCommandBuilder.GetUpdateCommand), null)] + [InlineData(nameof(SqlCommandBuilder.GetUpdateCommand), true)] + [InlineData(nameof(SqlCommandBuilder.GetUpdateCommand), false)] + [InlineData(nameof(SqlCommandBuilder.GetDeleteCommand), null)] + [InlineData(nameof(SqlCommandBuilder.GetDeleteCommand), false)] + [InlineData(nameof(SqlCommandBuilder.GetDeleteCommand), true)] + public void VerifyGetCommand(string methodName, bool? useColumnsForParameterNames) + { + using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString)) + { + connection.Open(); + using (SqlDataAdapter dataAdapter = new SqlDataAdapter("SELECT * FROM dbo.Customers", connection)) + { + using (SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter)) + { + object[] parameters = null; + Type[] parameterTypes = null; + if (useColumnsForParameterNames != null) + { + parameters = new object[] { useColumnsForParameterNames }; + parameterTypes = new Type[] { typeof(bool) }; + } + else + { + parameters = new object[] { }; + parameterTypes = new Type[] { }; + } + + MethodInfo method = commandBuilder.GetType().GetMethod(methodName, parameterTypes); + using (SqlCommand cmd = (SqlCommand)method.Invoke(commandBuilder, parameters)) + { + Assert.NotNull(cmd); + } + } + } + } + } + #region Utility_Methods private void CheckParameters(SqlCommand cmd, string expectedResults) { diff --git a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs index c5a3da8c3e..b56551ef1f 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs +++ b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs @@ -37,6 +37,7 @@ public class Config public bool IsDNSCachingSupportedTR = false; // this is for the tenant ring public string EnclaveAzureDatabaseConnString = null; public string UserManagedIdentityClientId = null; + public string MakecertPath = null; public static Config Load(string configPath = @"config.json") { diff --git a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json index 8d50730a33..8eb518dc90 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json +++ b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json @@ -25,5 +25,6 @@ "IsDNSCachingSupportedTR": false, "IsAzureSynapse": false, "EnclaveAzureDatabaseConnString": "", - "UserManagedIdentityClientId": "" + "UserManagedIdentityClientId": "", + "MakecertPath": "" } From 19ef90ff7e6c193585072af5794aa31c4d2108bd Mon Sep 17 00:00:00 2001 From: Johnny Pham Date: Fri, 18 Mar 2022 15:30:31 -0700 Subject: [PATCH 2/3] Update TcpDefaultForAzureTest.cs --- .../SQL/ConnectivityTests/TcpDefaultForAzureTest.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/TcpDefaultForAzureTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/TcpDefaultForAzureTest.cs index 0128571616..6667b4737b 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/TcpDefaultForAzureTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/TcpDefaultForAzureTest.cs @@ -41,7 +41,11 @@ static TcpDefaultForAzureTest() public static void NonAzureNoProtocolConnectionTest() { builder.DataSource = InvalidHostname; +#if NETFRAMEWORK + CheckConnectionFailure(builder.ConnectionString, NP); +#else CheckConnectionFailure(builder.ConnectionString, DataTestUtility.IsUsingManagedSNI() ? TCP : NP); +#endif } [Fact] From cdee78cb30d71370221728fe5de47d82865bfa0f Mon Sep 17 00:00:00 2001 From: Johnny Pham Date: Fri, 25 Mar 2022 14:13:57 -0700 Subject: [PATCH 3/3] Update CspProviderExt.cs --- .../tests/ManualTests/AlwaysEncrypted/CspProviderExt.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/CspProviderExt.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/CspProviderExt.cs index ec635afd03..0204ff3113 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/CspProviderExt.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/CspProviderExt.cs @@ -23,7 +23,7 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted [PlatformSpecific(TestPlatforms.Windows)] public class CspProviderExt { - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] [ClassData(typeof(AEConnectionStringProvider))] public void TestKeysFromCertificatesCreatedWithMultipleCryptoProviders(string connectionString) {