@@ -37,6 +37,97 @@ public static void RunAllTestsForSingleServer_TCP()
37
37
RunAllTestsForSingleServer ( DataTestUtility . TCPConnectionString ) ;
38
38
}
39
39
40
+ [ ConditionalFact ( typeof ( DataTestUtility ) , nameof ( DataTestUtility . AreConnStringsSetup ) ) ]
41
+ public static async Task AsyncMultiPacketStreamRead ( )
42
+ {
43
+ int packetSize = 514 ; // force small packet size so we can quickly check multi packet reads
44
+
45
+ SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder ( DataTestUtility . TCPConnectionString ) ;
46
+ builder . PacketSize = 514 ;
47
+ string connectionString = builder . ToString ( ) ;
48
+
49
+ byte [ ] inputData = null ;
50
+ byte [ ] outputData = null ;
51
+ string tableName = DataTestUtility . GetUniqueNameForSqlServer ( "data" ) ;
52
+
53
+ using ( SqlConnection connection = new SqlConnection ( connectionString ) )
54
+ {
55
+ await connection . OpenAsync ( ) ;
56
+
57
+ try
58
+ {
59
+ inputData = CreateBinaryTable ( connection , tableName , packetSize ) ;
60
+
61
+ using ( SqlCommand command = new SqlCommand ( $ "SELECT foo FROM { tableName } ", connection ) )
62
+ using ( SqlDataReader reader = await command . ExecuteReaderAsync ( System . Data . CommandBehavior . SequentialAccess ) )
63
+ {
64
+ await reader . ReadAsync ( ) ;
65
+
66
+ using ( Stream stream = reader . GetStream ( 0 ) )
67
+ using ( CancellationTokenSource cancellationTokenSource = new CancellationTokenSource ( TimeSpan . FromSeconds ( 60 ) ) )
68
+ using ( MemoryStream memory = new MemoryStream ( 16 * 1024 ) )
69
+ {
70
+ await stream . CopyToAsync ( memory , 37 , cancellationTokenSource . Token ) ; // prime number sized buffer to cause many cross packet partial reads
71
+ outputData = memory . ToArray ( ) ;
72
+ }
73
+ }
74
+ }
75
+ finally
76
+ {
77
+ DataTestUtility . DropTable ( connection , tableName ) ;
78
+ }
79
+ }
80
+
81
+ Assert . NotNull ( outputData ) ;
82
+ int sharedLength = Math . Min ( inputData . Length , outputData . Length ) ;
83
+ if ( sharedLength < outputData . Length )
84
+ {
85
+ Assert . False ( true , $ "output is longer than input, input={ inputData . Length } bytes, output={ outputData . Length } bytes") ;
86
+ }
87
+ if ( sharedLength < inputData . Length )
88
+ {
89
+ Assert . False ( true , $ "input is longer than output, input={ inputData . Length } bytes, output={ outputData . Length } bytes") ;
90
+ }
91
+ for ( int index = 0 ; index < sharedLength ; index ++ )
92
+ {
93
+ if ( inputData [ index ] != outputData [ index ] ) // avoid formatting the output string unless there is a difference
94
+ {
95
+ Assert . True ( false , $ "input and output differ at index { index } , input={ inputData [ index ] } , output={ outputData [ index ] } ") ;
96
+ }
97
+ }
98
+
99
+ }
100
+
101
+ private static byte [ ] CreateBinaryTable ( SqlConnection connection , string tableName , int packetSize )
102
+ {
103
+ byte [ ] pattern = new byte [ ] { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 } ;
104
+ byte [ ] data = new byte [ packetSize * 10 ] ;
105
+ int position = 0 ;
106
+ while ( position < data . Length )
107
+ {
108
+ int copyCount = Math . Min ( pattern . Length , data . Length - position ) ;
109
+ Array . Copy ( pattern , 0 , data , position , copyCount ) ;
110
+ position += copyCount ;
111
+ }
112
+
113
+ using ( var cmd = connection . CreateCommand ( ) )
114
+ {
115
+ cmd . CommandText = $@ "
116
+ IF OBJECT_ID('dbo.{ tableName } ', 'U') IS NOT NULL
117
+ DROP TABLE { tableName } ;
118
+ CREATE TABLE { tableName } (id INT, foo VARBINARY(MAX))
119
+ " ;
120
+ cmd . ExecuteNonQuery ( ) ;
121
+
122
+ cmd . CommandText = $ "INSERT INTO { tableName } (id, foo) VALUES (@id, @foo)";
123
+ cmd . Parameters . AddWithValue ( "id" , 1 ) ;
124
+ cmd . Parameters . AddWithValue ( "foo" , data ) ;
125
+ cmd . ExecuteNonQuery ( ) ;
126
+ }
127
+
128
+ return data ;
129
+ }
130
+
40
131
private static void RunAllTestsForSingleServer ( string connectionString , bool usingNamePipes = false )
41
132
{
42
133
RowBuffer ( connectionString ) ;
@@ -1811,7 +1902,7 @@ private static void TestXEventsStreaming(string connectionString)
1811
1902
SqlDataReader reader = cmd . ExecuteReader ( System . Data . CommandBehavior . SequentialAccess ) ;
1812
1903
for ( int i = 0 ; i < streamXeventCount && reader . Read ( ) ; i ++ )
1813
1904
{
1814
- Int32 colType = reader . GetInt32 ( 0 ) ;
1905
+ int colType = reader . GetInt32 ( 0 ) ;
1815
1906
int cb = ( int ) reader . GetBytes ( 1 , 0 , null , 0 , 0 ) ;
1816
1907
1817
1908
byte [ ] bytes = new byte [ cb ] ;
0 commit comments