From 5e397db0899ed1f6c1d386b889d28fc6a728a2c1 Mon Sep 17 00:00:00 2001 From: Juan Martinez Ramirez Date: Fri, 27 Sep 2024 15:12:22 -0600 Subject: [PATCH] Added testing --- .../IntegrationTests/SFDbDataReaderIT.cs | 314 +++++++++++++----- 1 file changed, 240 insertions(+), 74 deletions(-) diff --git a/Snowflake.Data.Tests/IntegrationTests/SFDbDataReaderIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFDbDataReaderIT.cs index b0e555185..1df5cff45 100755 --- a/Snowflake.Data.Tests/IntegrationTests/SFDbDataReaderIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFDbDataReaderIT.cs @@ -20,14 +20,14 @@ namespace Snowflake.Data.Tests.IntegrationTests class SFDbDataReaderIT : SFBaseTest { protected override string TestName => base.TestName + _resultFormat; - + private readonly ResultFormat _resultFormat; - + public SFDbDataReaderIT(ResultFormat resultFormat) { _resultFormat = resultFormat; } - + private void ValidateResultFormat(IDataReader reader) { Assert.AreEqual(_resultFormat, ((SnowflakeDbDataReader)reader).ResultFormat); @@ -39,7 +39,7 @@ public void TestRecordsAffected() using (var conn = CreateAndOpenConnection()) { CreateOrReplaceTable(conn, TableName, new []{"cola NUMBER"}); - + IDbCommand cmd = conn.CreateCommand(); string insertCommand = $"insert into {TableName} values (1),(1),(1)"; @@ -67,7 +67,7 @@ public void TestGetNumber() using (var conn = CreateAndOpenConnection()) { CreateOrReplaceTable(conn, TableName, new []{"cola NUMBER"}); - + IDbCommand cmd = conn.CreateCommand(); int numInt = 10000; @@ -114,7 +114,7 @@ public void TestGetNumber() Assert.IsFalse(reader.Read()); reader.Close(); - + CloseConnection(conn); } @@ -152,9 +152,9 @@ public void TestGetDouble() cmd.CommandText = $"select * from {TableName}"; IDataReader reader = cmd.ExecuteReader(); - + ValidateResultFormat(reader); - + Assert.IsTrue(reader.Read()); Assert.AreEqual(numFloat, reader.GetFloat(0)); Assert.AreEqual((decimal)numFloat, reader.GetDecimal(0)); @@ -235,7 +235,7 @@ public void TestGetTime(string inputTimeStr, int? precision) [TestCase("11:22:33.4455667")] [TestCase("23:59:59.9999999")] [TestCase("16:20:00.6666666")] - [TestCase("00:00:00.0000000")] + [TestCase("00:00:00.0000000")] [TestCase("00:00:00")] [TestCase("23:59:59.1")] [TestCase("23:59:59.12")] @@ -284,7 +284,7 @@ public void TestGetTimeSpan(string inputTimeStr) Assert.AreEqual(dateTimeTime.Minute, timeSpanTime.Minutes); Assert.AreEqual(dateTimeTime.Second, timeSpanTime.Seconds); Assert.AreEqual(dateTimeTime.Millisecond, timeSpanTime.Milliseconds); - + CloseConnection(conn); } } @@ -336,7 +336,7 @@ public void TestGetTimeSpanError() IDataReader reader = cmd.ExecuteReader(); ValidateResultFormat(reader); - + Assert.IsTrue(reader.Read()); // All types except TIME fail conversion when calling GetTimeSpan @@ -344,19 +344,19 @@ public void TestGetTimeSpanError() { try { - + ((SnowflakeDbDataReader)reader).GetTimeSpan(i); Assert.Fail("Data should not be converted to TIME"); } catch (SnowflakeDbException e) { - Assert.AreEqual(270003, e.ErrorCode); + Assert.AreEqual(270003, e.ErrorCode); } } // Null value // Null value can not be converted to TimeSpan because it is a non-nullable type - + try { ((SnowflakeDbDataReader)reader).GetTimeSpan(12); @@ -371,7 +371,7 @@ public void TestGetTimeSpanError() TimeSpan timeSpanTime = ((SnowflakeDbDataReader)reader).GetTimeSpan(13); reader.Close(); - + CloseConnection(conn); } } @@ -425,9 +425,9 @@ private void TestGetDateAndOrTime(string inputTimeStr, int? precision, SFDataTyp cmd.CommandText = $"select * from {TableName}"; IDataReader reader = cmd.ExecuteReader(); - + ValidateResultFormat(reader); - + Assert.IsTrue(reader.Read()); // For time, we getDateTime on the column and ignore date part @@ -495,9 +495,9 @@ public void TestGetTimestampTZ(int timezoneOffsetInHours) using (var conn = CreateAndOpenConnection()) { CreateOrReplaceTable(conn, TableName, new []{"cola TIMESTAMP_TZ"}); - + DateTimeOffset now = DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(timezoneOffsetInHours)); - + IDbCommand cmd = conn.CreateCommand(); string insertCommand = $"insert into {TableName} values (?)"; @@ -514,9 +514,9 @@ public void TestGetTimestampTZ(int timezoneOffsetInHours) cmd.CommandText = $"select * from {TableName}"; IDataReader reader = cmd.ExecuteReader(); - + ValidateResultFormat(reader); - + Assert.IsTrue(reader.Read()); DateTimeOffset dtOffset = (DateTimeOffset)reader.GetValue(0); reader.Close(); @@ -535,9 +535,9 @@ public void TestGetTimestampLTZ() using (var conn = CreateAndOpenConnection()) { CreateOrReplaceTable(conn, TableName, new []{"cola TIMESTAMP_LTZ"}); - + DateTimeOffset now = DateTimeOffset.Now; - + IDbCommand cmd = conn.CreateCommand(); string insertCommand = $"insert into {TableName} values (?)"; @@ -555,9 +555,9 @@ public void TestGetTimestampLTZ() cmd.CommandText = $"select * from {TableName}"; IDataReader reader = cmd.ExecuteReader(); - + ValidateResultFormat(reader); - + Assert.IsTrue(reader.Read()); DateTimeOffset dtOffset = (DateTimeOffset)reader.GetValue(0); reader.Close(); @@ -592,9 +592,9 @@ public void TestGetBoolean([Values]bool value) cmd.CommandText = $"select * from {TableName}"; IDataReader reader = cmd.ExecuteReader(); - + ValidateResultFormat(reader); - + Assert.IsTrue(reader.Read()); Assert.AreEqual(value, reader.GetBoolean(0)); reader.Close(); @@ -655,18 +655,18 @@ public void TestGetBinary() "col2 VARCHAR(50)", "col3 DOUBLE" }); - + byte[] testBytes = Encoding.UTF8.GetBytes("TEST_GET_BINARAY"); string testChars = "TEST_GET_CHARS"; double testDouble = 1.2345678; string insertCommand = $"insert into {TableName} values (?, '{testChars}',{testDouble.ToString()})"; IDbCommand cmd = conn.CreateCommand(); cmd.CommandText = insertCommand; - + var p1 = cmd.CreateParameter(); p1.ParameterName = "1"; p1.DbType = DbType.Binary; - p1.Value = testBytes; + p1.Value = testBytes; cmd.Parameters.Add(p1); var count = cmd.ExecuteNonQuery(); @@ -674,9 +674,9 @@ public void TestGetBinary() cmd.CommandText = $"select * from {TableName}"; IDataReader reader = cmd.ExecuteReader(); - + ValidateResultFormat(reader); - + Assert.IsTrue(reader.Read()); // Auto type conversion Assert.IsTrue(testBytes.SequenceEqual((byte[])reader.GetValue(0))); @@ -714,7 +714,7 @@ public void TestGetBinary() Assert.AreEqual(read, toReadLength); Assert.IsTrue(testSubBytes.SequenceEqual(sub)); - // Read subset 'GET_BINARAY' from actual 'TEST_GET_BINARAY' data + // Read subset 'GET_BINARAY' from actual 'TEST_GET_BINARAY' data // and copy inside existing buffer replacing Xs toReadLength = 11; byte[] testSubBytesWithTargetOffset = Encoding.UTF8.GetBytes("OFFSET GET_BINARAY EXTRA"); @@ -731,7 +731,7 @@ public void TestGetBinary() //** Invalid data offsets **/ try { - // Data offset > data length + // Data offset > data length reader.GetBytes(0, 25, sub, 7, toReadLength); Assert.Fail(); } @@ -754,7 +754,7 @@ public void TestGetBinary() //** Invalid buffer offsets **// try { - // Buffer offset > buffer length + // Buffer offset > buffer length reader.GetBytes(0, 6, sub, 25, toReadLength); Assert.Fail(); } @@ -775,7 +775,7 @@ public void TestGetBinary() } //** Null buffer **// - // If null, this method returns the size required of the array in order to fit all + // If null, this method returns the size required of the array in order to fit all // of the specified data. read = reader.GetBytes(0, 6, null, 0, toReadLength); Assert.AreEqual(testBytes.Length, read); @@ -828,7 +828,7 @@ public void TestGetChars() "col2 BINARY", "col3 DOUBLE" }); - + string testChars = "TEST_GET_CHARS"; byte[] testBytes = Encoding.UTF8.GetBytes("TEST_GET_BINARY"); double testDouble = 1.2345678; @@ -849,7 +849,7 @@ public void TestGetChars() IDataReader reader = cmd.ExecuteReader(); ValidateResultFormat(reader); - + Assert.IsTrue(reader.Read()); // Auto type conversion Assert.IsTrue(testChars.Equals(reader.GetValue(0))); @@ -889,7 +889,7 @@ public void TestGetChars() Assert.IsTrue(testSubChars.SequenceEqual(sub)); - // Read subset 'GET_CHARS' from actual 'TEST_GET_CHARS' data + // Read subset 'GET_CHARS' from actual 'TEST_GET_CHARS' data // and copy inside existing buffer replacing Xs char[] testSubCharsWithTargetOffset = "OFFSET GET_CHARS EXTRA".ToArray(); toReadLength = 9; @@ -906,7 +906,7 @@ public void TestGetChars() //** Invalid data offsets **// try { - // Data offset > data length + // Data offset > data length reader.GetChars(0, 25, sub, 7, toReadLength); Assert.Fail(); } @@ -929,7 +929,7 @@ public void TestGetChars() //** Invalid buffer offsets **// try { - // Buffer offset > buffer length + // Buffer offset > buffer length reader.GetChars(0, 6, sub, 25, toReadLength); Assert.Fail(); } @@ -950,7 +950,7 @@ public void TestGetChars() } //** Null buffer **// - // If null, this method returns the size required of the array in order to fit all + // If null, this method returns the size required of the array in order to fit all // of the specified data. read = reader.GetChars(0, 6, null, 0, toReadLength); Assert.AreEqual(testChars.Length, read); @@ -1016,7 +1016,7 @@ public void TestGetStream() "col2 BINARY", "col3 DOUBLE" }); - + string testChars = "TEST_GET_CHARS"; byte[] testBytes = Encoding.UTF8.GetBytes("TEST_GET_BINARY"); double testDouble = 1.2345678; @@ -1037,7 +1037,7 @@ public void TestGetStream() DbDataReader reader = (DbDataReader) cmd.ExecuteReader(); ValidateResultFormat(reader); - + Assert.IsTrue(reader.Read()); // Auto type conversion @@ -1087,9 +1087,9 @@ public void TestGetValueIndexOutOfBound() IDbCommand cmd = conn.CreateCommand(); cmd.CommandText = "select 1"; IDataReader reader = cmd.ExecuteReader(); - + ValidateResultFormat(reader); - + Assert.IsTrue(reader.Read()); try @@ -1128,7 +1128,7 @@ public void TestBasicDataReader() using (IDataReader reader = cmd.ExecuteReader()) { ValidateResultFormat(reader); - + Assert.AreEqual(2, reader.FieldCount); Assert.AreEqual(0, reader.Depth); Assert.IsTrue(((SnowflakeDbDataReader)reader).HasRows); @@ -1151,7 +1151,7 @@ public void TestBasicDataReader() reader.Close(); Assert.IsTrue(reader.IsClosed); - + try { reader.Read(); @@ -1199,7 +1199,7 @@ public void TestReadOutNullVal() using (IDataReader reader = cmd.ExecuteReader()) { ValidateResultFormat(reader); - + reader.Read(); object nullVal = reader.GetValue(0); Assert.AreEqual(DBNull.Value, nullVal); @@ -1211,7 +1211,7 @@ public void TestReadOutNullVal() } CloseConnection(conn); - } + } } [Test] @@ -1238,9 +1238,9 @@ public void TestGetGuid() cmd.CommandText = $"select * from {TableName}"; IDataReader reader = cmd.ExecuteReader(); - + ValidateResultFormat(reader); - + Assert.IsTrue(reader.Read()); Assert.AreEqual(val, reader.GetGuid(0)); @@ -1302,7 +1302,7 @@ public void TestCopyCmdResultSet() cmd.CommandText = $"create or replace stage {stageName}"; cmd.ExecuteNonQuery(); - cmd.CommandText = $"copy into {TableName} from @{stageName}"; + cmd.CommandText = $"copy into {TableName} from @{stageName}"; using (var rdr = cmd.ExecuteReader()) { // Can read the first row @@ -1433,7 +1433,7 @@ public void TestResultSetMetadata() CloseConnection(conn); } } - + [Test] public void TestHasRows() { @@ -1441,9 +1441,9 @@ public void TestHasRows() { DbCommand cmd = conn.CreateCommand(); cmd.CommandText = "select 1 where 1=2"; - + DbDataReader reader = cmd.ExecuteReader(); - + ValidateResultFormat(reader); Assert.IsFalse(reader.HasRows); @@ -1451,7 +1451,7 @@ public void TestHasRows() CloseConnection(conn); } } - + [Test] public void TestHasRowsMultiStatement() { @@ -1460,15 +1460,15 @@ public void TestHasRowsMultiStatement() DbCommand cmd = conn.CreateCommand(); cmd.CommandText = "select 1;" + "select 1 where 1=2;" + - "select 1;" + + "select 1;" + "select 1 where 1=2;"; - + DbParameter param = cmd.CreateParameter(); param.ParameterName = "MULTI_STATEMENT_COUNT"; param.DbType = DbType.Int16; param.Value = 4; cmd.Parameters.Add(param); - + DbDataReader reader = cmd.ExecuteReader(); // multi statements are always returned in JSON @@ -1483,7 +1483,7 @@ public void TestHasRowsMultiStatement() // select 1 where 1=2 Assert.IsFalse(reader.HasRows); reader.NextResult(); - + // select 1 Assert.IsTrue(reader.HasRows); reader.Read(); @@ -1494,12 +1494,12 @@ public void TestHasRowsMultiStatement() Assert.IsFalse(reader.HasRows); reader.NextResult(); Assert.IsFalse(reader.HasRows); - + reader.Close(); CloseConnection(conn); } } - + [Test] [TestCase("99")] // Int8 [TestCase("9.9")] // Int8 + scale @@ -1564,23 +1564,23 @@ public void TestTimestampTz(string testValue, int scale) using (var conn = CreateAndOpenConnection()) { DbCommand cmd = conn.CreateCommand(); - + cmd.CommandText = $"select '{testValue}'::TIMESTAMP_TZ({scale})"; using (SnowflakeDbDataReader reader = (SnowflakeDbDataReader)cmd.ExecuteReader()) { ValidateResultFormat(reader); reader.Read(); - + var expectedValue = DateTimeOffset.Parse(testValue); Assert.AreEqual(expectedValue, reader.GetValue(0)); } - + CloseConnection(conn); } } - + [Test] [TestCase("2019-01-01 12:12:12.1234567 +0500", 7)] [TestCase("2019-01-01 12:12:12.1234567 +1400", 7)] @@ -1591,23 +1591,23 @@ public void TestTimestampLtz(string testValue, int scale) using (var conn = CreateAndOpenConnection()) { DbCommand cmd = conn.CreateCommand(); - + cmd.CommandText = $"select '{testValue}'::TIMESTAMP_LTZ({scale})"; using (SnowflakeDbDataReader reader = (SnowflakeDbDataReader)cmd.ExecuteReader()) { ValidateResultFormat(reader); reader.Read(); - + var expectedValue = DateTimeOffset.Parse(testValue).ToLocalTime(); Assert.AreEqual(expectedValue, reader.GetValue(0)); } - + CloseConnection(conn); } } - + [Test] [TestCase("2019-01-01 12:12:12.1234567", 7)] [TestCase("0001-01-01 00:00:00.0000000", 9)] @@ -1617,19 +1617,185 @@ public void TestTimestampNtz(string testValue, int scale) using (var conn = CreateAndOpenConnection()) { DbCommand cmd = conn.CreateCommand(); - + cmd.CommandText = $"select '{testValue}'::TIMESTAMP_NTZ({scale})"; using (SnowflakeDbDataReader reader = (SnowflakeDbDataReader)cmd.ExecuteReader()) { ValidateResultFormat(reader); reader.Read(); - + var expectedValue = DateTime.Parse(testValue); Assert.AreEqual(expectedValue, reader.GetValue(0)); } - + + CloseConnection(conn); + } + } + + [Test] + public void TestGetEnumerator() + { + using (var conn = CreateAndOpenConnection()) + { + CreateOrReplaceTable(conn, TableName, new []{"cola NUMBER"}); + + IDbCommand cmd = conn.CreateCommand(); + + string insertCommand = $"insert into {TableName} values (1),(2),(3)"; + cmd.CommandText = insertCommand; + cmd.ExecuteNonQuery(); + + string selectCommandText = $"select * from {TableName}"; + IDbCommand selectCmd = conn.CreateCommand(); + selectCmd.CommandText = selectCommandText; + DbDataReader reader = selectCmd.ExecuteReader() as DbDataReader; + + var enumerator = reader.GetEnumerator(); + Assert.IsTrue(enumerator.MoveNext()); + Assert.AreEqual(1, (enumerator.Current as DbDataRecord).GetInt64(0)); + Assert.IsTrue(enumerator.MoveNext()); + Assert.AreEqual(2, (enumerator.Current as DbDataRecord).GetInt64(0)); + Assert.IsTrue(enumerator.MoveNext()); + Assert.AreEqual(3, (enumerator.Current as DbDataRecord).GetInt64(0)); + + reader.Close(); + + cmd.CommandText = $"drop table if exists {TableName}"; + var count = cmd.ExecuteNonQuery(); + Assert.AreEqual(0, count); + + CloseConnection(conn); + } + } + + [Test] + public void TestGetEnumeratorShouldBeEmptyWhenNotRowsReturned() + { + using (var conn = CreateAndOpenConnection()) + { + CreateOrReplaceTable(conn, TableName, new []{"cola NUMBER"}); + + IDbCommand cmd = conn.CreateCommand(); + + string insertCommand = $"insert into {TableName} values (1),(2),(3)"; + cmd.CommandText = insertCommand; + cmd.ExecuteNonQuery(); + + string selectCommandText = $"select * from {TableName} WHERE cola > 10"; + IDbCommand selectCmd = conn.CreateCommand(); + selectCmd.CommandText = selectCommandText; + DbDataReader reader = selectCmd.ExecuteReader() as DbDataReader; + + var enumerator = reader.GetEnumerator(); + Assert.IsFalse(enumerator.MoveNext()); + Assert.IsNull(enumerator.Current); + + reader.Close(); + + cmd.CommandText = $"drop table if exists {TableName}"; + var count = cmd.ExecuteNonQuery(); + Assert.AreEqual(0, count); + + CloseConnection(conn); + } + } + + [Test] + public void TestGetEnumeratorWithCastMethod() + { + using (var conn = CreateAndOpenConnection()) + { + CreateOrReplaceTable(conn, TableName, new []{"cola NUMBER"}); + + IDbCommand cmd = conn.CreateCommand(); + + string insertCommand = $"insert into {TableName} values (1),(2),(3)"; + cmd.CommandText = insertCommand; + cmd.ExecuteNonQuery(); + + string selectCommandText = $"select * from {TableName}"; + IDbCommand selectCmd = conn.CreateCommand(); + selectCmd.CommandText = selectCommandText; + DbDataReader reader = selectCmd.ExecuteReader() as DbDataReader; + + var x = reader.Cast().ToList(); + Assert.AreEqual(3, x.Count); + + reader.Close(); + + cmd.CommandText = $"drop table if exists {TableName}"; + var count = cmd.ExecuteNonQuery(); + Assert.AreEqual(0, count); + + CloseConnection(conn); + } + } + + [Test] + public void TestGetEnumeratorForEachShouldNotEnterWhenResultsIsEmpty() + { + using (var conn = CreateAndOpenConnection()) + { + CreateOrReplaceTable(conn, TableName, new []{"cola NUMBER"}); + + IDbCommand cmd = conn.CreateCommand(); + + string insertCommand = $"insert into {TableName} values (1),(2),(3)"; + cmd.CommandText = insertCommand; + cmd.ExecuteNonQuery(); + + string selectCommandText = $"select * from {TableName} WHERE cola > 10"; + IDbCommand selectCmd = conn.CreateCommand(); + selectCmd.CommandText = selectCommandText; + DbDataReader reader = selectCmd.ExecuteReader() as DbDataReader; + + int i = 1; + foreach (var record in reader) + { + Assert.Fail("Should not enter when results is empty"); + } + + reader.Close(); + + cmd.CommandText = $"drop table if exists {TableName}"; + var count = cmd.ExecuteNonQuery(); + Assert.AreEqual(0, count); + + CloseConnection(conn); + } + } + + [Test] + public void TestGetEnumeratorShouldThrowNonSupportedExceptionWhenReset() + { + using (var conn = CreateAndOpenConnection()) + { + CreateOrReplaceTable(conn, TableName, new []{"cola NUMBER"}); + + IDbCommand cmd = conn.CreateCommand(); + + string insertCommand = $"insert into {TableName} values (1),(2),(3)"; + cmd.CommandText = insertCommand; + cmd.ExecuteNonQuery(); + + string selectCommandText = $"select * from {TableName}"; + IDbCommand selectCmd = conn.CreateCommand(); + selectCmd.CommandText = selectCommandText; + DbDataReader reader = selectCmd.ExecuteReader() as DbDataReader; + + var enumerator = reader.GetEnumerator(); + Assert.IsTrue(enumerator.MoveNext()); + + Assert.Throws(() => enumerator.Reset()); + + reader.Close(); + + cmd.CommandText = $"drop table if exists {TableName}"; + var count = cmd.ExecuteNonQuery(); + Assert.AreEqual(0, count); + CloseConnection(conn); } }