From 8614025bc9ebe387a9c2b41355d1a0bfe4b081ad Mon Sep 17 00:00:00 2001 From: Apoorv Deshmukh Date: Thu, 5 Dec 2024 17:45:21 +0530 Subject: [PATCH 1/5] Enhance BCP tests to transfer multiple rows --- .../netfx/src/Microsoft.Data.SqlClient.csproj | 1 + .../SQL/JsonTest/JsonBulkCopyTest.cs | 66 +++++++++++-------- 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index 591977ef2d..c0cd585971 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -901,6 +901,7 @@ + diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonBulkCopyTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonBulkCopyTest.cs index 7cb3044e6a..493e0b56ae 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonBulkCopyTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonBulkCopyTest.cs @@ -23,14 +23,17 @@ public JsonBulkCopyTest(ITestOutputHelper output) _output = output; } - private void PopulateData(int noOfRecords) + private void PopulateData(int noOfRecords, int rows) { using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString)) { DataTestUtility.CreateTable(connection, "jsonTab", "(data json)"); DataTestUtility.CreateTable(connection, "jsonTabCopy", "(data json)"); - GenerateJsonFile(50000, _jsonFile); - StreamJsonFileToServer(connection); + GenerateJsonFile(noOfRecords, _jsonFile); + while (rows-- > 0) + { + StreamJsonFileToServer(connection); + } } } @@ -70,21 +73,21 @@ private void CompareJsonFiles() } } - private void PrintJsonDataToFile(SqlConnection connection) + private void PrintJsonDataToFileAndCompare(SqlConnection connection) { DeleteFile(_outputFile); using (SqlCommand command = new SqlCommand("SELECT [data] FROM [jsonTabCopy]", connection)) { using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess)) { - using (StreamWriter sw = new StreamWriter(_outputFile)) + while (reader.Read()) { - while (reader.Read()) - { - char[] buffer = new char[4096]; - int charsRead = 0; + char[] buffer = new char[4096]; + int charsRead = 0; - using (TextReader data = reader.GetTextReader(0)) + using (TextReader data = reader.GetTextReader(0)) + { + using (StreamWriter sw = new StreamWriter(_outputFile)) { do { @@ -93,8 +96,8 @@ private void PrintJsonDataToFile(SqlConnection connection) } while (charsRead > 0); } - _output.WriteLine("Output written to " + _outputFile); } + CompareJsonFiles(); } } } @@ -107,14 +110,14 @@ private async Task PrintJsonDataToFileAsync(SqlConnection connection) { using (SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess)) { - using (StreamWriter sw = new StreamWriter(_outputFile)) + while (await reader.ReadAsync()) { - while (await reader.ReadAsync()) - { - char[] buffer = new char[4096]; - int charsRead = 0; + char[] buffer = new char[4096]; + int charsRead = 0; - using (TextReader data = reader.GetTextReader(0)) + using (TextReader data = reader.GetTextReader(0)) + { + using (StreamWriter sw = new StreamWriter(_outputFile)) { do { @@ -123,8 +126,9 @@ private async Task PrintJsonDataToFileAsync(SqlConnection connection) } while (charsRead > 0); } - _output.WriteLine("Output written to file " + _outputFile); } + CompareJsonFiles(); + DeleteFile(_outputFile); } } } @@ -162,7 +166,7 @@ private void DeleteFile(string filename) } } - private void BulkCopyData(CommandBehavior cb, bool enableStraming) + private void BulkCopyData(CommandBehavior cb, bool enableStraming, int expectedTransferCount) { using (SqlConnection sourceConnection = new SqlConnection(DataTestUtility.TCPConnectionString)) { @@ -195,11 +199,12 @@ private void BulkCopyData(CommandBehavior cb, bool enableStraming) long countEnd = System.Convert.ToInt32(commandRowCount.ExecuteScalar()); _output.WriteLine("Ending row count = {0}", countEnd); _output.WriteLine("{0} rows were added.", countEnd - countStart); + Assert.Equal(expectedTransferCount, countEnd - countStart); } } } - private async Task BulkCopyDataAsync(CommandBehavior cb, bool enableStraming) + private async Task BulkCopyDataAsync(CommandBehavior cb, bool enableStraming, int expectedTransferCount) { using (SqlConnection sourceConnection = new SqlConnection(DataTestUtility.TCPConnectionString)) { @@ -232,43 +237,46 @@ private async Task BulkCopyDataAsync(CommandBehavior cb, bool enableStraming) long countEnd = System.Convert.ToInt32(await commandRowCount.ExecuteScalarAsync()); _output.WriteLine("Ending row count = {0}", countEnd); _output.WriteLine("{0} rows were added.", countEnd - countStart); + Assert.Equal(expectedTransferCount, countEnd - countStart); } } } + [Theory] [InlineData(CommandBehavior.Default, false)] [InlineData(CommandBehavior.Default, true)] [InlineData(CommandBehavior.SequentialAccess, false)] [InlineData(CommandBehavior.SequentialAccess, true)] - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))] public void TestJsonBulkCopy(CommandBehavior cb, bool enableStraming) { - PopulateData(10000); + int jsonArrayElements = 300; + int rows = 100; + PopulateData(jsonArrayElements, rows); using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString)) { - BulkCopyData(cb, enableStraming); + BulkCopyData(cb, enableStraming, rows); connection.Open(); - PrintJsonDataToFile(connection); - CompareJsonFiles(); + PrintJsonDataToFileAndCompare(connection); DeleteFile(_jsonFile); DeleteFile(_outputFile); } } + [Theory] [InlineData(CommandBehavior.Default, false)] [InlineData(CommandBehavior.Default, true)] [InlineData(CommandBehavior.SequentialAccess, false)] [InlineData(CommandBehavior.SequentialAccess, true)] - [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))] public async Task TestJsonBulkCopyAsync(CommandBehavior cb, bool enableStraming) { - PopulateData(10000); + int jsonArrayElements = 10; + int rows = 10000; + PopulateData(jsonArrayElements, rows); using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString)) { - await BulkCopyDataAsync(cb, enableStraming); + await BulkCopyDataAsync(cb, enableStraming, rows); await connection.OpenAsync(); await PrintJsonDataToFileAsync(connection); - CompareJsonFiles(); DeleteFile(_jsonFile); DeleteFile(_outputFile); } From b6a3d60aa9744a10fce48a6ce9f8e4af45832d25 Mon Sep 17 00:00:00 2001 From: Apoorv Deshmukh Date: Thu, 5 Dec 2024 19:04:50 +0530 Subject: [PATCH 2/5] Add SqlDataReader specific API tests --- .../ManualTests/SQL/JsonTest/JsonTest.cs | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs index a0f02b9c20..53db29d3d2 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs @@ -10,6 +10,8 @@ using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; +using System.Text.Json; +using Newtonsoft.Json.Linq; namespace Microsoft.Data.SqlClient.ManualTesting.Tests { @@ -333,6 +335,46 @@ public void TestNullJson() var reader = command.ExecuteReader(); ValidateNullJson(reader); + reader.Close(); + DataTestUtility.DropTable(connection, tableName); + } + + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))] + public void TestJsonAPIs() + { + string tableName = "jsonTest"; + + string tableInsert = "INSERT INTO " + tableName + " VALUES (@jsonData)"; + string tableRead = "SELECT * FROM " + tableName; + + using SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString); + connection.Open(); + using SqlCommand command = connection.CreateCommand(); + + //Create Table + DataTestUtility.CreateTable(connection, tableName, "(Data json)"); + + //Insert Null value + command.CommandText = tableInsert; + var parameter = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json); + parameter.Value = jsonDataString; + command.Parameters.Add(parameter); + command.ExecuteNonQuery(); + + //Query the table + command.CommandText = tableRead; + var reader = command.ExecuteReader(); + while (reader.Read()) + { + string data = reader.GetFieldValue(0); + Assert.Equal(jsonDataString, data); + JsonDocument jsonDocument = reader.GetFieldValue(0); + Assert.Equal(jsonDataString, jsonDocument.RootElement.ToString()); + Assert.Equal("json", reader.GetDataTypeName(0)); + Assert.Equal("System.String", reader.GetFieldType(0).ToString()); + } + + reader.Close(); DataTestUtility.DropTable(connection, tableName); } From 2b8f2343eaf0bb951a55bac203910882a5ddb48c Mon Sep 17 00:00:00 2001 From: Apoorv Deshmukh Date: Thu, 5 Dec 2024 19:39:04 +0530 Subject: [PATCH 3/5] Read MARS involving json datatype --- .../ManualTests/SQL/JsonTest/JsonTest.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs index 53db29d3d2..ead01f86de 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs @@ -378,5 +378,49 @@ public void TestJsonAPIs() reader.Close(); DataTestUtility.DropTable(connection, tableName); } + + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))] + public void TestJsonWithMARS() + { + string tableName = "jsonTest"; + + using SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString+ "MultipleActiveResultSets=True;"); + connection.Open(); + + //Create Table + DataTestUtility.CreateTable(connection, tableName+"1", "(Data json)"); + DataTestUtility.CreateTable(connection, tableName+"2", "(Id int, Data json)"); + + //Insert Data + string table1Insert = "INSERT INTO " + tableName + "1" + " VALUES (\'" + jsonDataString + "\')"; + string table2Insert = "INSERT INTO " + tableName + "2" + " VALUES (1,\'" + jsonDataString + "\')"; + SqlCommand command = connection.CreateCommand(); + command.CommandText = table1Insert; + command.ExecuteNonQuery(); + command.CommandText = table2Insert; + command.ExecuteNonQuery(); + + //Read Data + SqlCommand command1 = new SqlCommand("select * from " + tableName + "1", connection); + SqlCommand command2 = new SqlCommand("select * from " + tableName + "2", connection); + + using (SqlDataReader reader1 = command1.ExecuteReader()) + { + while (reader1.Read()) + { + Assert.Equal(jsonDataString, reader1["data"]); + } + + using (SqlDataReader reader2 = command2.ExecuteReader()) + { + while (reader2.Read()) + { + Assert.Equal(1, reader2["Id"]); + Assert.Equal(jsonDataString, reader2["data"]); + } + } + } + DataTestUtility.DropTable(connection, tableName); + } } } From 1f4b6cecea87956e678840487ae3c414f299273e Mon Sep 17 00:00:00 2001 From: Apoorv Deshmukh Date: Sat, 7 Dec 2024 00:39:16 +0530 Subject: [PATCH 4/5] Address review comments --- .../netfx/src/Microsoft.Data.SqlClient.csproj | 1 - .../SQL/JsonTest/JsonBulkCopyTest.cs | 157 ++++++++------- .../ManualTests/SQL/JsonTest/JsonTest.cs | 185 ++++++++++-------- 3 files changed, 189 insertions(+), 154 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index c0cd585971..591977ef2d 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -901,7 +901,6 @@ - diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonBulkCopyTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonBulkCopyTest.cs index 493e0b56ae..bc5f170df7 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonBulkCopyTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonBulkCopyTest.cs @@ -2,21 +2,36 @@ using System.Collections.Generic; using System.Data; using System.IO; -using System.Linq; -using System.Text; using System.Threading.Tasks; using Newtonsoft.Json.Linq; using Newtonsoft.Json; using Xunit.Abstractions; using Xunit; +using System.Collections; namespace Microsoft.Data.SqlClient.ManualTesting.Tests.SQL.JsonTest { + public class JsonBulkCopyTestData : IEnumerable + { + public IEnumerator GetEnumerator() + { + yield return new object[] { CommandBehavior.Default, false }; + yield return new object[] { CommandBehavior.Default, true }; + yield return new object[] { CommandBehavior.SequentialAccess, false }; + yield return new object[] { CommandBehavior.SequentialAccess, true }; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } + public class JsonBulkCopyTest { private readonly ITestOutputHelper _output; - private static readonly string _jsonFile = "randomRecords.json"; - private static readonly string _outputFile = "serverRecords.json"; + private static readonly string _generatedJsonFile = DataTestUtility.GenerateRandomCharacters("randomRecords"); + private static readonly string _outputFile = DataTestUtility.GenerateRandomCharacters("serverResults"); + private static readonly string _sourceTableName = DataTestUtility.GenerateObjectName(); + private static readonly string _destinationTableName = DataTestUtility.GenerateObjectName(); + private static readonly int _jsonArrayElements = 300; + private static readonly int _rows = 100; public JsonBulkCopyTest(ITestOutputHelper output) { @@ -27,9 +42,9 @@ private void PopulateData(int noOfRecords, int rows) { using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString)) { - DataTestUtility.CreateTable(connection, "jsonTab", "(data json)"); - DataTestUtility.CreateTable(connection, "jsonTabCopy", "(data json)"); - GenerateJsonFile(noOfRecords, _jsonFile); + DataTestUtility.CreateTable(connection, _sourceTableName, "(data json)"); + DataTestUtility.CreateTable(connection, _destinationTableName, "(data json)"); + GenerateJsonFile(noOfRecords, _generatedJsonFile); while (rows-- > 0) { StreamJsonFileToServer(connection); @@ -62,7 +77,7 @@ private void GenerateJsonFile(int noOfRecords, string filename) private void CompareJsonFiles() { - using (var stream1 = File.OpenText(_jsonFile)) + using (var stream1 = File.OpenText(_generatedJsonFile)) using (var stream2 = File.OpenText(_outputFile)) using (var reader1 = new JsonTextReader(stream1)) using (var reader2 = new JsonTextReader(stream2)) @@ -75,70 +90,84 @@ private void CompareJsonFiles() private void PrintJsonDataToFileAndCompare(SqlConnection connection) { - DeleteFile(_outputFile); - using (SqlCommand command = new SqlCommand("SELECT [data] FROM [jsonTabCopy]", connection)) + try { - using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess)) + DeleteFile(_outputFile); + using (SqlCommand command = new SqlCommand("SELECT [data] FROM [" + _destinationTableName + "]", connection)) { - while (reader.Read()) + using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess)) { - char[] buffer = new char[4096]; - int charsRead = 0; - - using (TextReader data = reader.GetTextReader(0)) + while (reader.Read()) { - using (StreamWriter sw = new StreamWriter(_outputFile)) + char[] buffer = new char[4096]; + int charsRead = 0; + + using (TextReader data = reader.GetTextReader(0)) { - do + using (StreamWriter sw = new StreamWriter(_outputFile)) { - charsRead = data.Read(buffer, 0, buffer.Length); - sw.Write(buffer, 0, charsRead); + do + { + charsRead = data.Read(buffer, 0, buffer.Length); + sw.Write(buffer, 0, charsRead); - } while (charsRead > 0); + } while (charsRead > 0); + } } + CompareJsonFiles(); } - CompareJsonFiles(); } } } + finally + { + DeleteFile(_outputFile); + } + } - private async Task PrintJsonDataToFileAsync(SqlConnection connection) + private async Task PrintJsonDataToFileAndCompareAsync(SqlConnection connection) { - DeleteFile(_outputFile); - using (SqlCommand command = new SqlCommand("SELECT [data] FROM [jsonTab]", connection)) + try { - using (SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess)) + DeleteFile(_outputFile); + using (SqlCommand command = new SqlCommand("SELECT [data] FROM [" + _destinationTableName + "]", connection)) { - while (await reader.ReadAsync()) + using (SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess)) { - char[] buffer = new char[4096]; - int charsRead = 0; - - using (TextReader data = reader.GetTextReader(0)) + while (await reader.ReadAsync()) { - using (StreamWriter sw = new StreamWriter(_outputFile)) + char[] buffer = new char[4096]; + int charsRead = 0; + + using (TextReader data = reader.GetTextReader(0)) { - do + using (StreamWriter sw = new StreamWriter(_outputFile)) { - charsRead = await data.ReadAsync(buffer, 0, buffer.Length); - await sw.WriteAsync(buffer, 0, charsRead); + do + { + charsRead = await data.ReadAsync(buffer, 0, buffer.Length); + await sw.WriteAsync(buffer, 0, charsRead); - } while (charsRead > 0); + } while (charsRead > 0); + } } + CompareJsonFiles(); } - CompareJsonFiles(); - DeleteFile(_outputFile); } } } + finally + { + DeleteFile(_outputFile); + } } private void StreamJsonFileToServer(SqlConnection connection) { - using (SqlCommand cmd = new SqlCommand("INSERT INTO [jsonTab] (data) VALUES (@jsondata)", connection)) + using (SqlCommand cmd = new SqlCommand("INSERT INTO [" + _sourceTableName + "] (data) VALUES (@jsondata)", connection)) { - using (StreamReader jsonFile = File.OpenText(_jsonFile)) + using (StreamReader jsonFile = File.OpenText(_generatedJsonFile)) { cmd.Parameters.Add("@jsondata", Microsoft.Data.SqlDbTypeExtensions.Json, -1).Value = jsonFile; cmd.ExecuteNonQuery(); @@ -148,9 +177,9 @@ private void StreamJsonFileToServer(SqlConnection connection) private async Task StreamJsonFileToServerAsync(SqlConnection connection) { - using (SqlCommand cmd = new SqlCommand("INSERT INTO [jsonTab] (data) VALUES (@jsondata)", connection)) + using (SqlCommand cmd = new SqlCommand("INSERT INTO [" + _sourceTableName + "] (data) VALUES (@jsondata)", connection)) { - using (StreamReader jsonFile = File.OpenText(_jsonFile)) + using (StreamReader jsonFile = File.OpenText(_generatedJsonFile)) { cmd.Parameters.Add("@jsondata", Microsoft.Data.SqlDbTypeExtensions.Json, -1).Value = jsonFile; await cmd.ExecuteNonQueryAsync(); @@ -171,10 +200,10 @@ private void BulkCopyData(CommandBehavior cb, bool enableStraming, int expectedT using (SqlConnection sourceConnection = new SqlConnection(DataTestUtility.TCPConnectionString)) { sourceConnection.Open(); - SqlCommand commandRowCount = new SqlCommand("SELECT COUNT(*) FROM " + "dbo.jsonTabCopy;", sourceConnection); + SqlCommand commandRowCount = new SqlCommand("SELECT COUNT(*) FROM " + _destinationTableName, sourceConnection); long countStart = System.Convert.ToInt32(commandRowCount.ExecuteScalar()); _output.WriteLine("Starting row count = {0}", countStart); - SqlCommand commandSourceData = new SqlCommand("SELECT data FROM dbo.jsonTab;", sourceConnection); + SqlCommand commandSourceData = new SqlCommand("SELECT data FROM " + _sourceTableName, sourceConnection); SqlDataReader reader = commandSourceData.ExecuteReader(cb); using (SqlConnection destinationConnection = new SqlConnection(DataTestUtility.TCPConnectionString)) { @@ -182,7 +211,7 @@ private void BulkCopyData(CommandBehavior cb, bool enableStraming, int expectedT using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection)) { bulkCopy.EnableStreaming = enableStraming; - bulkCopy.DestinationTableName = "dbo.jsonTabCopy"; + bulkCopy.DestinationTableName = _destinationTableName; try { bulkCopy.WriteToServer(reader); @@ -209,10 +238,10 @@ private async Task BulkCopyDataAsync(CommandBehavior cb, bool enableStraming, in using (SqlConnection sourceConnection = new SqlConnection(DataTestUtility.TCPConnectionString)) { await sourceConnection.OpenAsync(); - SqlCommand commandRowCount = new SqlCommand("SELECT COUNT(*) FROM " + "dbo.jsonTabCopy;", sourceConnection); + SqlCommand commandRowCount = new SqlCommand("SELECT COUNT(*) FROM " + _destinationTableName, sourceConnection); long countStart = System.Convert.ToInt32(await commandRowCount.ExecuteScalarAsync()); _output.WriteLine("Starting row count = {0}", countStart); - SqlCommand commandSourceData = new SqlCommand("SELECT data FROM dbo.jsonTab;", sourceConnection); + SqlCommand commandSourceData = new SqlCommand("SELECT data FROM " + _sourceTableName, sourceConnection); SqlDataReader reader = await commandSourceData.ExecuteReaderAsync(cb); using (SqlConnection destinationConnection = new SqlConnection(DataTestUtility.TCPConnectionString)) { @@ -220,7 +249,7 @@ private async Task BulkCopyDataAsync(CommandBehavior cb, bool enableStraming, in using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection)) { bulkCopy.EnableStreaming = enableStraming; - bulkCopy.DestinationTableName = "dbo.jsonTabCopy"; + bulkCopy.DestinationTableName = _destinationTableName; try { await bulkCopy.WriteToServerAsync(reader); @@ -242,42 +271,32 @@ private async Task BulkCopyDataAsync(CommandBehavior cb, bool enableStraming, in } } - [Theory] - [InlineData(CommandBehavior.Default, false)] - [InlineData(CommandBehavior.Default, true)] - [InlineData(CommandBehavior.SequentialAccess, false)] - [InlineData(CommandBehavior.SequentialAccess, true)] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))] + [ClassData(typeof(JsonBulkCopyTestData))] public void TestJsonBulkCopy(CommandBehavior cb, bool enableStraming) { - int jsonArrayElements = 300; - int rows = 100; - PopulateData(jsonArrayElements, rows); + PopulateData(_jsonArrayElements, _rows); using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString)) { - BulkCopyData(cb, enableStraming, rows); + BulkCopyData(cb, enableStraming, _rows); connection.Open(); PrintJsonDataToFileAndCompare(connection); - DeleteFile(_jsonFile); + DeleteFile(_generatedJsonFile); DeleteFile(_outputFile); } } - [Theory] - [InlineData(CommandBehavior.Default, false)] - [InlineData(CommandBehavior.Default, true)] - [InlineData(CommandBehavior.SequentialAccess, false)] - [InlineData(CommandBehavior.SequentialAccess, true)] + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))] + [ClassData(typeof(JsonBulkCopyTestData))] public async Task TestJsonBulkCopyAsync(CommandBehavior cb, bool enableStraming) { - int jsonArrayElements = 10; - int rows = 10000; - PopulateData(jsonArrayElements, rows); + PopulateData(_jsonArrayElements, _rows); using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString)) { - await BulkCopyDataAsync(cb, enableStraming, rows); + await BulkCopyDataAsync(cb, enableStraming, _rows); await connection.OpenAsync(); - await PrintJsonDataToFileAsync(connection); - DeleteFile(_jsonFile); + await PrintJsonDataToFileAndCompareAsync(connection); + DeleteFile(_generatedJsonFile); DeleteFile(_outputFile); } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs index ead01f86de..cc8b43f1a6 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonTest.cs @@ -4,14 +4,12 @@ using System; using System.Data; -using Microsoft.Data; using System.Data.Common; using System.Data.SqlTypes; using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; using System.Text.Json; -using Newtonsoft.Json.Linq; namespace Microsoft.Data.SqlClient.ManualTesting.Tests { @@ -23,8 +21,8 @@ public JsonTest(ITestOutputHelper output) { _output = output; } - - private static readonly string jsonDataString = "[{\"name\":\"Dave\",\"skills\":[\"Python\"]},{\"name\":\"Ron\",\"surname\":\"Peter\"}]"; + + private static readonly string JsonDataString = "[{\"name\":\"Dave\",\"skills\":[\"Python\"]},{\"name\":\"Ron\",\"surname\":\"Peter\"}]"; private void ValidateRowsAffected(int rowsAffected) { @@ -38,7 +36,7 @@ private void ValidateRows(SqlDataReader reader) { string jsonData = reader.GetString(0); _output.WriteLine(jsonData); - Assert.Equal(jsonDataString, jsonData); + Assert.Equal(JsonDataString, jsonData); } } @@ -48,7 +46,7 @@ private async Task ValidateRowsAsync(SqlDataReader reader) { string jsonData = reader.GetString(0); _output.WriteLine(jsonData); - Assert.Equal(jsonDataString, jsonData); + Assert.Equal(JsonDataString, jsonData); } } @@ -77,8 +75,8 @@ private void ValidateNullJson(SqlDataReader reader) [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))] public void TestJsonWrite() { - string tableName = "jsonWriteTest"; - string spName = "spJsonWriteTest"; + string tableName = DataTestUtility.GenerateObjectName(); + string spName = DataTestUtility.GenerateObjectName(); string tableInsert = "INSERT INTO " + tableName + " VALUES (@jsonData)"; string spCreate = "CREATE PROCEDURE " + spName + " (@jsonData json) AS " + tableInsert; @@ -103,13 +101,13 @@ public void TestJsonWrite() //Test 1 //Write json value using a parameterized query - parameter.Value = jsonDataString; + parameter.Value = JsonDataString; int rowsAffected = command.ExecuteNonQuery(); ValidateRowsAffected(rowsAffected); //Test 2 //Write a SqlString type as json - parameter.Value = new SqlString(jsonDataString); + parameter.Value = new SqlString(JsonDataString); int rowsAffected2 = command.ExecuteNonQuery(); ValidateRowsAffected(rowsAffected2); @@ -120,7 +118,7 @@ public void TestJsonWrite() command2.CommandText = spName; command2.CommandType = CommandType.StoredProcedure; var parameter2 = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json); - parameter2.Value = jsonDataString; + parameter2.Value = JsonDataString; command2.Parameters.Add(parameter2); int rowsAffected3 = command2.ExecuteNonQuery(); ValidateRowsAffected(rowsAffected3); @@ -135,8 +133,8 @@ public void TestJsonWrite() [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))] public async Task TestJsonWriteAsync() { - string tableName = "jsonWriteTest"; - string spName = "spJsonWriteTest"; + string tableName = DataTestUtility.GenerateObjectName(); + string spName = DataTestUtility.GenerateObjectName(); string tableInsert = "INSERT INTO " + tableName + " VALUES (@jsonData)"; string spCreate = "CREATE PROCEDURE " + spName + " (@jsonData json) AS " + tableInsert; @@ -161,13 +159,13 @@ public async Task TestJsonWriteAsync() //Test 1 //Write json value using a parameterized query - parameter.Value = jsonDataString; + parameter.Value = JsonDataString; int rowsAffected = await command.ExecuteNonQueryAsync(); ValidateRowsAffected(rowsAffected); //Test 2 //Write a SqlString type as json - parameter.Value = new SqlString(jsonDataString); + parameter.Value = new SqlString(JsonDataString); int rowsAffected2 = await command.ExecuteNonQueryAsync(); ValidateRowsAffected(rowsAffected2); @@ -178,7 +176,7 @@ public async Task TestJsonWriteAsync() command2.CommandText = spName; command2.CommandType = CommandType.StoredProcedure; var parameter2 = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json); - parameter2.Value = jsonDataString; + parameter2.Value = JsonDataString; command2.Parameters.Add(parameter2); int rowsAffected3 = await command.ExecuteNonQueryAsync(); ValidateRowsAffected(rowsAffected3); @@ -193,8 +191,8 @@ public async Task TestJsonWriteAsync() [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))] public void TestJsonRead() { - string tableName = "jsonReadTest"; - string spName = "spJsonReadTest"; + string tableName = DataTestUtility.GenerateObjectName(); + string spName = DataTestUtility.GenerateObjectName(); string tableInsert = "INSERT INTO " + tableName + " VALUES (@jsonData)"; string tableRead = "SELECT * FROM " + tableName; @@ -217,7 +215,7 @@ public void TestJsonRead() //This will be used for reading command.CommandText = tableInsert; var parameter = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json); - parameter.Value = jsonDataString; + parameter.Value = JsonDataString; command.Parameters.Add(parameter); command.ExecuteNonQuery(); @@ -252,8 +250,8 @@ public void TestJsonRead() [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))] public async Task TestJsonReadAsync() { - string tableName = "jsonReadTest"; - string spName = "spJsonReadTest"; + string tableName = DataTestUtility.GenerateObjectName(); + string spName = DataTestUtility.GenerateObjectName(); string tableInsert = "INSERT INTO " + tableName + " VALUES (@jsonData)"; string tableRead = "SELECT * FROM " + tableName; @@ -276,7 +274,7 @@ public async Task TestJsonReadAsync() //This will be used for reading command.CommandText = tableInsert; var parameter = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json); - parameter.Value = jsonDataString; + parameter.Value = JsonDataString; command.Parameters.Add(parameter); await command.ExecuteNonQueryAsync(); @@ -311,7 +309,7 @@ public async Task TestJsonReadAsync() [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))] public void TestNullJson() { - string tableName = "jsonTest"; + string tableName = DataTestUtility.GenerateObjectName(); string tableInsert = "INSERT INTO " + tableName + " VALUES (@jsonData)"; string tableRead = "SELECT * FROM " + tableName; @@ -342,85 +340,104 @@ public void TestNullJson() [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))] public void TestJsonAPIs() { - string tableName = "jsonTest"; - + string tableName = DataTestUtility.GenerateObjectName(); string tableInsert = "INSERT INTO " + tableName + " VALUES (@jsonData)"; string tableRead = "SELECT * FROM " + tableName; - using SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString); - connection.Open(); - using SqlCommand command = connection.CreateCommand(); - - //Create Table - DataTestUtility.CreateTable(connection, tableName, "(Data json)"); - - //Insert Null value - command.CommandText = tableInsert; - var parameter = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json); - parameter.Value = jsonDataString; - command.Parameters.Add(parameter); - command.ExecuteNonQuery(); - - //Query the table - command.CommandText = tableRead; - var reader = command.ExecuteReader(); - while (reader.Read()) + using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString)) { - string data = reader.GetFieldValue(0); - Assert.Equal(jsonDataString, data); - JsonDocument jsonDocument = reader.GetFieldValue(0); - Assert.Equal(jsonDataString, jsonDocument.RootElement.ToString()); - Assert.Equal("json", reader.GetDataTypeName(0)); - Assert.Equal("System.String", reader.GetFieldType(0).ToString()); + connection.Open(); + using (SqlCommand command = connection.CreateCommand()) + { + try + { + // Create Table + DataTestUtility.CreateTable(connection, tableName, "(Data json)"); + + // Insert Null value + command.CommandText = tableInsert; + var parameter = new SqlParameter("@jsonData", SqlDbTypeExtensions.Json); + parameter.Value = JsonDataString; + command.Parameters.Add(parameter); + command.ExecuteNonQuery(); + + // Query the table + command.CommandText = tableRead; + using (var reader = command.ExecuteReader()) + { + while (reader.Read()) + { + string data = reader.GetFieldValue(0); + Assert.Equal(JsonDataString, data); + JsonDocument jsonDocument = reader.GetFieldValue(0); + Assert.Equal(JsonDataString, jsonDocument.RootElement.ToString()); + Assert.Equal("json", reader.GetDataTypeName(0)); + Assert.Equal("System.String", reader.GetFieldType(0).ToString()); + } + } + } + finally + { + DataTestUtility.DropTable(connection, tableName); + } + } } - - - reader.Close(); - DataTestUtility.DropTable(connection, tableName); } [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))] public void TestJsonWithMARS() { - string tableName = "jsonTest"; - - using SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString+ "MultipleActiveResultSets=True;"); - connection.Open(); - - //Create Table - DataTestUtility.CreateTable(connection, tableName+"1", "(Data json)"); - DataTestUtility.CreateTable(connection, tableName+"2", "(Id int, Data json)"); - - //Insert Data - string table1Insert = "INSERT INTO " + tableName + "1" + " VALUES (\'" + jsonDataString + "\')"; - string table2Insert = "INSERT INTO " + tableName + "2" + " VALUES (1,\'" + jsonDataString + "\')"; - SqlCommand command = connection.CreateCommand(); - command.CommandText = table1Insert; - command.ExecuteNonQuery(); - command.CommandText = table2Insert; - command.ExecuteNonQuery(); + string table1Name = DataTestUtility.GenerateObjectName(); + string table2Name = DataTestUtility.GenerateObjectName(); - //Read Data - SqlCommand command1 = new SqlCommand("select * from " + tableName + "1", connection); - SqlCommand command2 = new SqlCommand("select * from " + tableName + "2", connection); - - using (SqlDataReader reader1 = command1.ExecuteReader()) + using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString + "MultipleActiveResultSets=True;")) { - while (reader1.Read()) + connection.Open(); + try { - Assert.Equal(jsonDataString, reader1["data"]); - } + // Create Table + DataTestUtility.CreateTable(connection, table1Name, "(Data json)"); + DataTestUtility.CreateTable(connection, table2Name, "(Id int, Data json)"); + + // Insert Data + string table1Insert = "INSERT INTO " + table1Name + " VALUES ('" + JsonDataString + "')"; + string table2Insert = "INSERT INTO " + table2Name + " VALUES (1,'" + JsonDataString + "')"; + using (SqlCommand command = connection.CreateCommand()) + { + command.CommandText = table1Insert; + command.ExecuteNonQuery(); + command.CommandText = table2Insert; + command.ExecuteNonQuery(); + } - using (SqlDataReader reader2 = command2.ExecuteReader()) - { - while (reader2.Read()) + // Read Data + using (SqlCommand command1 = new SqlCommand("select * from " + table1Name, connection)) + using (SqlCommand command2 = new SqlCommand("select * from " + table2Name, connection)) { - Assert.Equal(1, reader2["Id"]); - Assert.Equal(jsonDataString, reader2["data"]); + using (SqlDataReader reader1 = command1.ExecuteReader()) + { + while (reader1.Read()) + { + Assert.Equal(JsonDataString, reader1["data"]); + } + + using (SqlDataReader reader2 = command2.ExecuteReader()) + { + while (reader2.Read()) + { + Assert.Equal(1, reader2["Id"]); + Assert.Equal(JsonDataString, reader2["data"]); + } + } + } } } + finally + { + DataTestUtility.DropTable(connection, table1Name); + DataTestUtility.DropTable(connection, table2Name); + } } - DataTestUtility.DropTable(connection, tableName); } } } From f98229544754a326c62d53b2fbd406410b76b01c Mon Sep 17 00:00:00 2001 From: Apoorv Deshmukh Date: Tue, 10 Dec 2024 22:13:27 +0530 Subject: [PATCH 5/5] Parameterize jsonArrayElements and rows for JsonBulkCopyTests --- .../SQL/JsonTest/JsonBulkCopyTest.cs | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonBulkCopyTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonBulkCopyTest.cs index bc5f170df7..816537cb8f 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonBulkCopyTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/JsonTest/JsonBulkCopyTest.cs @@ -15,10 +15,10 @@ public class JsonBulkCopyTestData : IEnumerable { public IEnumerator GetEnumerator() { - yield return new object[] { CommandBehavior.Default, false }; - yield return new object[] { CommandBehavior.Default, true }; - yield return new object[] { CommandBehavior.SequentialAccess, false }; - yield return new object[] { CommandBehavior.SequentialAccess, true }; + yield return new object[] { CommandBehavior.Default, false, 300, 100 }; + yield return new object[] { CommandBehavior.Default, true, 300, 100 }; + yield return new object[] { CommandBehavior.SequentialAccess, false, 300, 100 }; + yield return new object[] { CommandBehavior.SequentialAccess, true, 300, 100 }; } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } @@ -30,8 +30,6 @@ public class JsonBulkCopyTest private static readonly string _outputFile = DataTestUtility.GenerateRandomCharacters("serverResults"); private static readonly string _sourceTableName = DataTestUtility.GenerateObjectName(); private static readonly string _destinationTableName = DataTestUtility.GenerateObjectName(); - private static readonly int _jsonArrayElements = 300; - private static readonly int _rows = 100; public JsonBulkCopyTest(ITestOutputHelper output) { @@ -273,12 +271,12 @@ private async Task BulkCopyDataAsync(CommandBehavior cb, bool enableStraming, in [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))] [ClassData(typeof(JsonBulkCopyTestData))] - public void TestJsonBulkCopy(CommandBehavior cb, bool enableStraming) + public void TestJsonBulkCopy(CommandBehavior cb, bool enableStraming, int jsonArrayElements, int rows) { - PopulateData(_jsonArrayElements, _rows); + PopulateData(jsonArrayElements, rows); using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString)) { - BulkCopyData(cb, enableStraming, _rows); + BulkCopyData(cb, enableStraming, rows); connection.Open(); PrintJsonDataToFileAndCompare(connection); DeleteFile(_generatedJsonFile); @@ -288,12 +286,12 @@ public void TestJsonBulkCopy(CommandBehavior cb, bool enableStraming) [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.IsJsonSupported))] [ClassData(typeof(JsonBulkCopyTestData))] - public async Task TestJsonBulkCopyAsync(CommandBehavior cb, bool enableStraming) + public async Task TestJsonBulkCopyAsync(CommandBehavior cb, bool enableStraming, int jsonArrayElements, int rows) { - PopulateData(_jsonArrayElements, _rows); + PopulateData(jsonArrayElements, rows); using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString)) { - await BulkCopyDataAsync(cb, enableStraming, _rows); + await BulkCopyDataAsync(cb, enableStraming, rows); await connection.OpenAsync(); await PrintJsonDataToFileAndCompareAsync(connection); DeleteFile(_generatedJsonFile);