From 10bd20bcfcca449beeae43027f9d330e4820dac9 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Wed, 8 Jan 2020 13:20:19 -0800 Subject: [PATCH 1/3] Fix issues with `SqlCommandSet` not working with Byte Array parameters --- .../src/System/Data/SqlClient/SqlCommandSet.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SqlCommandSet.cs b/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SqlCommandSet.cs index b823208ea9df55..2b30956f02cf89 100644 --- a/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SqlCommandSet.cs +++ b/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SqlCommandSet.cs @@ -150,7 +150,7 @@ internal void Append(SqlCommand command) int offset = p.Offset; int size = p.Size; int countOfBytes = byteValues.Length - offset; - if ((0 != size) && (size < countOfBytes)) + if ((size > 0) && (size < countOfBytes)) { countOfBytes = size; } From 999cb4115797a83bcb0aea9a562615db680929b4 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Fri, 17 Jan 2020 09:55:54 -0800 Subject: [PATCH 2/3] Commit new test changes --- .../SqlCommandCancelTest.cs} | 4 +- .../SQL/SqlCommandTest/SqlCommandSetTest.cs | 98 +++++++++++++++++++ ....Data.SqlClient.ManualTesting.Tests.csproj | 3 +- 3 files changed, 102 insertions(+), 3 deletions(-) rename src/libraries/System.Data.SqlClient/tests/ManualTests/SQL/{CommandCancelTest/CommandCancelTest.cs => SqlCommandTest/SqlCommandCancelTest.cs} (99%) create mode 100644 src/libraries/System.Data.SqlClient/tests/ManualTests/SQL/SqlCommandTest/SqlCommandSetTest.cs diff --git a/src/libraries/System.Data.SqlClient/tests/ManualTests/SQL/CommandCancelTest/CommandCancelTest.cs b/src/libraries/System.Data.SqlClient/tests/ManualTests/SQL/SqlCommandTest/SqlCommandCancelTest.cs similarity index 99% rename from src/libraries/System.Data.SqlClient/tests/ManualTests/SQL/CommandCancelTest/CommandCancelTest.cs rename to src/libraries/System.Data.SqlClient/tests/ManualTests/SQL/SqlCommandTest/SqlCommandCancelTest.cs index d61f4f686ec5c9..d1f4a9192dbe60 100644 --- a/src/libraries/System.Data.SqlClient/tests/ManualTests/SQL/CommandCancelTest/CommandCancelTest.cs +++ b/src/libraries/System.Data.SqlClient/tests/ManualTests/SQL/SqlCommandTest/SqlCommandCancelTest.cs @@ -8,7 +8,7 @@ namespace System.Data.SqlClient.ManualTesting.Tests { - public static class CommandCancelTest + public static class SqlCommandCancelTest { // Shrink the packet size - this should make timeouts more likely private static readonly string s_connStr = (new SqlConnectionStringBuilder(DataTestUtility.TcpConnStr) { PacketSize = 512 }).ConnectionString; @@ -136,7 +136,7 @@ private static void MultiThreadedCancel(string constr, bool async) Task.WaitAll(tasks, 15 * 1000); - CommandCancelTest.VerifyConnection(command); + SqlCommandCancelTest.VerifyConnection(command); } } diff --git a/src/libraries/System.Data.SqlClient/tests/ManualTests/SQL/SqlCommandTest/SqlCommandSetTest.cs b/src/libraries/System.Data.SqlClient/tests/ManualTests/SQL/SqlCommandTest/SqlCommandSetTest.cs new file mode 100644 index 00000000000000..74d9413ba436ba --- /dev/null +++ b/src/libraries/System.Data.SqlClient/tests/ManualTests/SQL/SqlCommandTest/SqlCommandSetTest.cs @@ -0,0 +1,98 @@ +using System; +using System.Data.SqlTypes; +using System.Reflection; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace System.Data.SqlClient.ManualTesting.Tests +{ + public class SqlCommandSetTest + { + private static Assembly mds = Assembly.GetAssembly(typeof(SqlConnection)); + + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + public void TestByteArrayParameters() + { + string tableName = DataTestUtility.GetUniqueNameForSqlServer("CMD"); + string procName = DataTestUtility.GetUniqueNameForSqlServer("CMD"); + byte[] bArray = new byte[] { 1, 2, 3 }; + + using (var connection = new SqlConnection(DataTestUtility.TcpConnStr)) + { + connection.Open(); + try + { + using (var cmd = new SqlCommand(procName, connection)) + { + setupByteArrayArtifacts(connection, tableName, procName); + + // Insert with SqlCommand + cmd.CommandType = System.Data.CommandType.StoredProcedure; + SqlCommandBuilder.DeriveParameters(cmd); + cmd.Parameters["@array"].Value = bArray; + + cmd.ExecuteNonQuery(); + + //Insert with command Set + var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet"); + var cmdSet = Activator.CreateInstance(commandSetType, true); + commandSetType.GetMethod("Append", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(cmdSet, new object[] { cmd }); + commandSetType.GetProperty("Connection", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetSetMethod(true).Invoke(cmdSet, new object[] { connection }); + commandSetType.GetMethod("ExecuteNonQuery", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(cmdSet, new object[] { }); + + cmd.CommandType = System.Data.CommandType.Text; + cmd.CommandText = $"SELECT * FROM {tableName}"; + using (SqlDataReader reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + SqlBytes byteArray = reader.GetSqlBytes(0); + Assert.Equal(byteArray.Length, bArray.Length); + + for (int i = 0; i < bArray.Length; i++) + { + Assert.Equal(bArray[i], byteArray[i]); + } + } + + } + } + } + catch (Exception e) + { + throw e; + } + finally + { + dropByteArrayArtifacts(connection, tableName, procName); + } + } + } + + private void dropByteArrayArtifacts(SqlConnection connection, string tableName, string procName) + { + using (SqlCommand cmd = connection.CreateCommand()) + { + cmd.CommandText = $"DROP TABLE IF EXISTS {tableName}"; + cmd.ExecuteNonQuery(); + + cmd.CommandText = $"DROP PROCEDURE IF EXISTS {procName}"; + cmd.ExecuteNonQuery(); + } + } + + private void setupByteArrayArtifacts(SqlConnection connection, string tableName, string procName) + { + using (SqlCommand cmd = connection.CreateCommand()) + { + cmd.CommandText = $"CREATE TABLE {tableName} (ByteArrayColumn varbinary(max))"; + cmd.ExecuteNonQuery(); + + cmd.CommandText = $"CREATE PROCEDURE {procName} @array varbinary(max) AS BEGIN SET NOCOUNT ON; " + + $"insert into {tableName}(ByteArrayColumn) values(@array) END"; + cmd.ExecuteNonQuery(); + } + } + } +} diff --git a/src/libraries/System.Data.SqlClient/tests/ManualTests/System.Data.SqlClient.ManualTesting.Tests.csproj b/src/libraries/System.Data.SqlClient/tests/ManualTests/System.Data.SqlClient.ManualTesting.Tests.csproj index 340b0a51102639..47c47a74d1b331 100644 --- a/src/libraries/System.Data.SqlClient/tests/ManualTests/System.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/libraries/System.Data.SqlClient/tests/ManualTests/System.Data.SqlClient.ManualTesting.Tests.csproj @@ -44,7 +44,7 @@ - + @@ -61,6 +61,7 @@ + From 0bfb0f1cb7f7ec349d684da76fdf596382be29b5 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Fri, 17 Jan 2020 10:55:56 -0800 Subject: [PATCH 3/3] Minor updates --- .../SQL/SqlCommandTest/SqlCommandSetTest.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Data.SqlClient/tests/ManualTests/SQL/SqlCommandTest/SqlCommandSetTest.cs b/src/libraries/System.Data.SqlClient/tests/ManualTests/SQL/SqlCommandTest/SqlCommandSetTest.cs index 74d9413ba436ba..9952ba7059914f 100644 --- a/src/libraries/System.Data.SqlClient/tests/ManualTests/SQL/SqlCommandTest/SqlCommandSetTest.cs +++ b/src/libraries/System.Data.SqlClient/tests/ManualTests/SQL/SqlCommandTest/SqlCommandSetTest.cs @@ -9,7 +9,7 @@ namespace System.Data.SqlClient.ManualTesting.Tests { public class SqlCommandSetTest { - private static Assembly mds = Assembly.GetAssembly(typeof(SqlConnection)); + private static Assembly sqlclient = Assembly.GetAssembly(typeof(SqlConnection)); [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] public void TestByteArrayParameters() @@ -35,7 +35,7 @@ public void TestByteArrayParameters() cmd.ExecuteNonQuery(); //Insert with command Set - var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet"); + var commandSetType = sqlclient.GetType("System.Data.SqlClient.SqlCommandSet"); var cmdSet = Activator.CreateInstance(commandSetType, true); commandSetType.GetMethod("Append", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(cmdSet, new object[] { cmd }); commandSetType.GetProperty("Connection", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetSetMethod(true).Invoke(cmdSet, new object[] { connection }); @@ -48,7 +48,7 @@ public void TestByteArrayParameters() while (reader.Read()) { SqlBytes byteArray = reader.GetSqlBytes(0); - Assert.Equal(byteArray.Length, bArray.Length); + Assert.Equal(bArray.Length, byteArray.Length); for (int i = 0; i < bArray.Length; i++) { @@ -59,10 +59,6 @@ public void TestByteArrayParameters() } } } - catch (Exception e) - { - throw e; - } finally { dropByteArrayArtifacts(connection, tableName, procName);