1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Collections; 6 using System.Linq; 7 8 using Xunit; 9 10 namespace System.Data.SqlClient.Tests 11 { 12 public partial class SqlConnectionTest 13 { 14 private static readonly string[] s_retrieveStatisticsKeys = 15 { 16 "BuffersReceived", 17 "BuffersSent", 18 "BytesReceived", 19 "BytesSent", 20 "CursorOpens", 21 "IduCount", 22 "IduRows", 23 "PreparedExecs", 24 "Prepares", 25 "SelectCount", 26 "SelectRows", 27 "ServerRoundtrips", 28 "SumResultSets", 29 "Transactions", 30 "UnpreparedExecs", 31 "ConnectionTime", 32 "ExecutionTime", 33 "NetworkServerTime" 34 }; 35 36 [Fact] RetrieveStatistics_Success()37 public void RetrieveStatistics_Success() 38 { 39 var connection = new SqlConnection(); 40 IDictionary d = connection.RetrieveStatistics(); 41 Assert.NotNull(d); 42 Assert.NotSame(d, connection.RetrieveStatistics()); 43 } 44 45 [Fact] RetrieveStatistics_ExpectedKeysInDictionary_Success()46 public void RetrieveStatistics_ExpectedKeysInDictionary_Success() 47 { 48 IDictionary d = new SqlConnection().RetrieveStatistics(); 49 50 Assert.NotEmpty(d); 51 Assert.Equal(s_retrieveStatisticsKeys.Length, d.Count); 52 53 Assert.NotEmpty(d.Keys); 54 Assert.Equal(s_retrieveStatisticsKeys.Length, d.Keys.Count); 55 56 Assert.NotEmpty(d.Values); 57 Assert.Equal(s_retrieveStatisticsKeys.Length, d.Values.Count); 58 59 foreach (string key in s_retrieveStatisticsKeys) 60 { 61 Assert.True(d.Contains(key)); 62 63 object value = d[key]; 64 Assert.NotNull(value); 65 Assert.IsType<long>(value); 66 Assert.Equal(0L, value); 67 } 68 } 69 70 [Fact] RetrieveStatistics_UnexpectedKeysNotInDictionary_Success()71 public void RetrieveStatistics_UnexpectedKeysNotInDictionary_Success() 72 { 73 IDictionary d = new SqlConnection().RetrieveStatistics(); 74 Assert.False(d.Contains("Foo")); 75 Assert.Null(d["Foo"]); 76 } 77 78 [Fact] RetrieveStatistics_IsSynchronized_Success()79 public void RetrieveStatistics_IsSynchronized_Success() 80 { 81 IDictionary d = new SqlConnection().RetrieveStatistics(); 82 Assert.False(d.IsSynchronized); 83 } 84 85 [Fact] RetrieveStatistics_SyncRoot_Success()86 public void RetrieveStatistics_SyncRoot_Success() 87 { 88 IDictionary d = new SqlConnection().RetrieveStatistics(); 89 Assert.NotNull(d.SyncRoot); 90 Assert.Same(d.SyncRoot, d.SyncRoot); 91 } 92 93 [Fact] RetrieveStatistics_IsFixedSize_Success()94 public void RetrieveStatistics_IsFixedSize_Success() 95 { 96 IDictionary d = new SqlConnection().RetrieveStatistics(); 97 Assert.False(d.IsFixedSize); 98 } 99 100 [Fact] RetrieveStatistics_IsReadOnly_Success()101 public void RetrieveStatistics_IsReadOnly_Success() 102 { 103 IDictionary d = new SqlConnection().RetrieveStatistics(); 104 Assert.False(d.IsReadOnly); 105 } 106 107 public static readonly object[][] RetrieveStatisticsKeyValueData = 108 { 109 new object[] { "Foo", 100L }, 110 new object[] { "Foo", null }, 111 new object[] { "Blah", "Blah" }, 112 new object[] { 100, "Value" } 113 }; 114 115 [Theory] 116 [MemberData(nameof(RetrieveStatisticsKeyValueData))] RetrieveStatistics_Add_Success(object key, object value)117 public void RetrieveStatistics_Add_Success(object key, object value) 118 { 119 IDictionary d = new SqlConnection().RetrieveStatistics(); 120 121 d.Add(key, value); 122 123 Assert.True(d.Contains(key)); 124 125 object v = d[key]; 126 Assert.Same(value, v); 127 } 128 129 [Fact] RetrieveStatistics_Add_ExistingKey_Throws()130 public void RetrieveStatistics_Add_ExistingKey_Throws() 131 { 132 IDictionary d = new SqlConnection().RetrieveStatistics(); 133 string key = s_retrieveStatisticsKeys[0]; 134 AssertExtensions.Throws<ArgumentException>(null, () => d.Add(key, 100L)); 135 } 136 137 [Fact] RetrieveStatistics_Add_NullKey_Throws()138 public void RetrieveStatistics_Add_NullKey_Throws() 139 { 140 IDictionary d = new SqlConnection().RetrieveStatistics(); 141 AssertExtensions.Throws<ArgumentNullException>("key", () => d.Add(null, 100L)); 142 } 143 144 [Theory] 145 [MemberData(nameof(RetrieveStatisticsKeyValueData))] RetrieveStatistics_Setter_Success(object key, object value)146 public void RetrieveStatistics_Setter_Success(object key, object value) 147 { 148 IDictionary d = new SqlConnection().RetrieveStatistics(); 149 150 d[key] = value; 151 152 Assert.True(d.Contains(key)); 153 154 object v = d[key]; 155 Assert.Same(value, v); 156 } 157 158 [Fact] RetrieveStatistics_Setter_ExistingKey_Success()159 public void RetrieveStatistics_Setter_ExistingKey_Success() 160 { 161 IDictionary d = new SqlConnection().RetrieveStatistics(); 162 string key = s_retrieveStatisticsKeys[0]; 163 164 d[key] = 100L; 165 Assert.Equal(100L, d[key]); 166 } 167 168 [Fact] RetrieveStatistics_Setter_NullKey_Throws()169 public void RetrieveStatistics_Setter_NullKey_Throws() 170 { 171 IDictionary d = new SqlConnection().RetrieveStatistics(); 172 AssertExtensions.Throws<ArgumentNullException>("key", () => d[null] = 100L); 173 } 174 175 [Fact] RetrieveStatistics_Clear_Success()176 public void RetrieveStatistics_Clear_Success() 177 { 178 IDictionary d = new SqlConnection().RetrieveStatistics(); 179 180 d.Clear(); 181 182 Assert.Empty(d); 183 Assert.Equal(0, d.Count); 184 185 Assert.Empty(d.Keys); 186 Assert.Equal(0, d.Keys.Count); 187 188 Assert.Empty(d.Values); 189 Assert.Equal(0, d.Values.Count); 190 } 191 192 [Fact] RetrieveStatistics_Remove_ExistingKey_Success()193 public void RetrieveStatistics_Remove_ExistingKey_Success() 194 { 195 IDictionary d = new SqlConnection().RetrieveStatistics(); 196 197 string key = s_retrieveStatisticsKeys[0]; 198 199 Assert.Equal(s_retrieveStatisticsKeys.Length, d.Count); 200 Assert.Equal(s_retrieveStatisticsKeys.Length, d.Keys.Count); 201 Assert.Equal(s_retrieveStatisticsKeys.Length, d.Values.Count); 202 Assert.True(d.Contains(key)); 203 Assert.NotNull(d[key]); 204 205 d.Remove(key); 206 207 Assert.Equal(s_retrieveStatisticsKeys.Length - 1, d.Count); 208 Assert.Equal(s_retrieveStatisticsKeys.Length - 1, d.Keys.Count); 209 Assert.Equal(s_retrieveStatisticsKeys.Length - 1, d.Values.Count); 210 Assert.False(d.Contains(key)); 211 Assert.Null(d[key]); 212 } 213 214 [Fact] RetrieveStatistics_Remove_NonExistentKey_Success()215 public void RetrieveStatistics_Remove_NonExistentKey_Success() 216 { 217 IDictionary d = new SqlConnection().RetrieveStatistics(); 218 219 const string key = "Foo"; 220 221 Assert.Equal(s_retrieveStatisticsKeys.Length, d.Count); 222 Assert.Equal(s_retrieveStatisticsKeys.Length, d.Keys.Count); 223 Assert.Equal(s_retrieveStatisticsKeys.Length, d.Values.Count); 224 Assert.False(d.Contains(key)); 225 Assert.Null(d[key]); 226 227 d.Remove(key); 228 229 Assert.Equal(s_retrieveStatisticsKeys.Length, d.Count); 230 Assert.Equal(s_retrieveStatisticsKeys.Length, d.Keys.Count); 231 Assert.Equal(s_retrieveStatisticsKeys.Length, d.Values.Count); 232 Assert.False(d.Contains(key)); 233 Assert.Null(d[key]); 234 } 235 236 [Fact] RetrieveStatistics_Remove_NullKey_Throws()237 public void RetrieveStatistics_Remove_NullKey_Throws() 238 { 239 IDictionary d = new SqlConnection().RetrieveStatistics(); 240 AssertExtensions.Throws<ArgumentNullException>("key", () => d.Remove(null)); 241 } 242 243 [Fact] RetrieveStatistics_Contains_NullKey_Throws()244 public void RetrieveStatistics_Contains_NullKey_Throws() 245 { 246 IDictionary d = new SqlConnection().RetrieveStatistics(); 247 AssertExtensions.Throws<ArgumentNullException>("key", () => d.Contains(null)); 248 } 249 250 [Fact] RetrieveStatistics_CopyTo_Success()251 public void RetrieveStatistics_CopyTo_Success() 252 { 253 IDictionary d = new SqlConnection().RetrieveStatistics(); 254 DictionaryEntry[] destination = new DictionaryEntry[d.Count]; 255 256 d.CopyTo(destination, 0); 257 258 int i = 0; 259 foreach (DictionaryEntry entry in d) 260 { 261 Assert.Equal(entry, destination[i]); 262 i++; 263 } 264 } 265 266 [Fact] RetrieveStatistics_CopyTo_Throws()267 public void RetrieveStatistics_CopyTo_Throws() 268 { 269 IDictionary d = new SqlConnection().RetrieveStatistics(); 270 271 AssertExtensions.Throws<ArgumentNullException>("array", () => d.CopyTo(null, 0)); 272 AssertExtensions.Throws<ArgumentNullException>("array", () => d.CopyTo(null, -1)); 273 AssertExtensions.Throws<ArgumentOutOfRangeException>("arrayIndex", () => d.CopyTo(new DictionaryEntry[20], -1)); 274 AssertExtensions.Throws<ArgumentException>(null, () => d.CopyTo(new DictionaryEntry[20], 18)); 275 AssertExtensions.Throws<ArgumentException>(null, () => d.CopyTo(new DictionaryEntry[20], 1000)); 276 AssertExtensions.Throws<ArgumentException>(null, () => d.CopyTo(new DictionaryEntry[4, 3], 0)); 277 Assert.Throws<InvalidCastException>(() => d.CopyTo(new string[20], 0)); 278 } 279 280 [Fact] RetrieveStatistics_IDictionary_GetEnumerator_Success()281 public void RetrieveStatistics_IDictionary_GetEnumerator_Success() 282 { 283 IDictionary d = new SqlConnection().RetrieveStatistics(); 284 285 IDictionaryEnumerator e = d.GetEnumerator(); 286 287 Assert.NotNull(e); 288 Assert.NotSame(e, d.GetEnumerator()); 289 290 for (int i = 0; i < 2; i++) 291 { 292 Assert.Throws<InvalidOperationException>(() => e.Current); 293 294 foreach (string ignored in s_retrieveStatisticsKeys) 295 { 296 Assert.True(e.MoveNext()); 297 298 Assert.NotNull(e.Current); 299 Assert.IsType<DictionaryEntry>(e.Current); 300 301 Assert.NotNull(e.Entry.Key); 302 Assert.IsType<string>(e.Entry.Key); 303 Assert.NotNull(e.Entry.Value); 304 Assert.IsType<long>(e.Entry.Value); 305 306 Assert.Equal(e.Current, e.Entry); 307 Assert.Same(e.Key, e.Entry.Key); 308 Assert.Same(e.Value, e.Entry.Value); 309 310 Assert.True(s_retrieveStatisticsKeys.Contains(e.Entry.Key)); 311 } 312 313 Assert.False(e.MoveNext()); 314 Assert.False(e.MoveNext()); 315 Assert.False(e.MoveNext()); 316 317 Assert.Throws<InvalidOperationException>(() => e.Current); 318 319 e.Reset(); 320 } 321 } 322 323 [Fact] RetrieveStatistics_IEnumerable_GetEnumerator_Success()324 public void RetrieveStatistics_IEnumerable_GetEnumerator_Success() 325 { 326 // Treat the result as IEnumerable instead of IDictionary. 327 IEnumerable d = new SqlConnection().RetrieveStatistics(); 328 329 IEnumerator e = d.GetEnumerator(); 330 331 Assert.NotNull(e); 332 Assert.NotSame(e, d.GetEnumerator()); 333 334 for (int i = 0; i < 2; i++) 335 { 336 Assert.Throws<InvalidOperationException>(() => e.Current); 337 338 foreach (string ignored in s_retrieveStatisticsKeys) 339 { 340 Assert.True(e.MoveNext()); 341 342 Assert.NotNull(e.Current); 343 344 // Verify the IEnumerable.GetEnumerator enumerator is yielding DictionaryEntry entries, 345 // not KeyValuePair entries. 346 Assert.IsType<DictionaryEntry>(e.Current); 347 348 DictionaryEntry entry = (DictionaryEntry)e.Current; 349 350 Assert.NotNull(entry.Key); 351 Assert.IsType<string>(entry.Key); 352 Assert.NotNull(entry.Value); 353 Assert.IsType<long>(entry.Value); 354 355 Assert.True(s_retrieveStatisticsKeys.Contains(entry.Key)); 356 } 357 358 Assert.False(e.MoveNext()); 359 Assert.False(e.MoveNext()); 360 Assert.False(e.MoveNext()); 361 362 Assert.Throws<InvalidOperationException>(() => e.Current); 363 364 e.Reset(); 365 } 366 } 367 368 [Fact] RetrieveStatistics_GetEnumerator_ModifyCollection_Throws()369 public void RetrieveStatistics_GetEnumerator_ModifyCollection_Throws() 370 { 371 IDictionary d = new SqlConnection().RetrieveStatistics(); 372 373 IDictionaryEnumerator e = d.GetEnumerator(); 374 375 d.Add("Foo", 0L); 376 377 Assert.Throws<InvalidOperationException>(() => e.MoveNext()); 378 Assert.Throws<InvalidOperationException>(() => e.Reset()); 379 } 380 381 [Fact] RetrieveStatistics_Keys_Success()382 public void RetrieveStatistics_Keys_Success() 383 { 384 IDictionary d = new SqlConnection().RetrieveStatistics(); 385 Assert.NotNull(d.Keys); 386 Assert.Same(d.Keys, d.Keys); 387 } 388 389 [Fact] RetrieveStatistics_Keys_IsSynchronized_Success()390 public void RetrieveStatistics_Keys_IsSynchronized_Success() 391 { 392 IDictionary d = new SqlConnection().RetrieveStatistics(); 393 ICollection c = d.Keys; 394 Assert.False(c.IsSynchronized); 395 } 396 397 [Fact] RetrieveStatistics_Keys_SyncRoot_Success()398 public void RetrieveStatistics_Keys_SyncRoot_Success() 399 { 400 IDictionary d = new SqlConnection().RetrieveStatistics(); 401 ICollection c = d.Keys; 402 Assert.NotNull(c.SyncRoot); 403 Assert.Same(c.SyncRoot, c.SyncRoot); 404 } 405 406 [Fact] RetrieveStatistics_Keys_CopyTo_ObjectArray_Success()407 public void RetrieveStatistics_Keys_CopyTo_ObjectArray_Success() 408 { 409 IDictionary d = new SqlConnection().RetrieveStatistics(); 410 ICollection c = d.Keys; 411 object[] destination = new object[c.Count]; 412 413 c.CopyTo(destination, 0); 414 415 Assert.Equal(c.Cast<object>().ToArray(), destination); 416 } 417 418 [Fact] RetrieveStatistics_Keys_CopyTo_StringArray_Success()419 public void RetrieveStatistics_Keys_CopyTo_StringArray_Success() 420 { 421 IDictionary d = new SqlConnection().RetrieveStatistics(); 422 ICollection c = d.Keys; 423 string[] destination = new string[c.Count]; 424 425 c.CopyTo(destination, 0); 426 427 Assert.Equal(c.Cast<string>().ToArray(), destination); 428 } 429 430 [Fact] RetrieveStatistics_Keys_CopyTo_Throws()431 public void RetrieveStatistics_Keys_CopyTo_Throws() 432 { 433 IDictionary d = new SqlConnection().RetrieveStatistics(); 434 ICollection c = d.Keys; 435 436 AssertExtensions.Throws<ArgumentNullException>("array", () => c.CopyTo(null, 0)); 437 AssertExtensions.Throws<ArgumentNullException>("array", () => c.CopyTo(null, -1)); 438 AssertExtensions.Throws<ArgumentOutOfRangeException>("arrayIndex", () => c.CopyTo(new string[20], -1)); 439 AssertExtensions.Throws<ArgumentException>(null, () => c.CopyTo(new string[20], 18)); 440 AssertExtensions.Throws<ArgumentException>(null, () => c.CopyTo(new string[20], 1000)); 441 AssertExtensions.Throws<ArgumentException>(null, () => c.CopyTo(new string[4, 3], 0)); 442 Assert.Throws<InvalidCastException>(() => c.CopyTo(new Version[20], 0)); 443 } 444 445 [Fact] RetrieveStatistics_Keys_GetEnumerator_Success()446 public void RetrieveStatistics_Keys_GetEnumerator_Success() 447 { 448 IDictionary d = new SqlConnection().RetrieveStatistics(); 449 ICollection c = d.Keys; 450 451 IEnumerator e = c.GetEnumerator(); 452 453 Assert.NotNull(e); 454 Assert.NotSame(e, c.GetEnumerator()); 455 456 for (int i = 0; i < 2; i++) 457 { 458 Assert.Throws<InvalidOperationException>(() => e.Current); 459 460 foreach (string ignored in s_retrieveStatisticsKeys) 461 { 462 Assert.True(e.MoveNext()); 463 Assert.NotNull(e.Current); 464 Assert.True(s_retrieveStatisticsKeys.Contains(e.Current)); 465 } 466 467 Assert.False(e.MoveNext()); 468 Assert.False(e.MoveNext()); 469 Assert.False(e.MoveNext()); 470 471 Assert.Throws<InvalidOperationException>(() => e.Current); 472 473 e.Reset(); 474 } 475 } 476 477 [Fact] RetrieveStatistics_Keys_GetEnumerator_ModifyCollection_Throws()478 public void RetrieveStatistics_Keys_GetEnumerator_ModifyCollection_Throws() 479 { 480 IDictionary d = new SqlConnection().RetrieveStatistics(); 481 ICollection c = d.Keys; 482 483 IEnumerator e = c.GetEnumerator(); 484 485 d.Add("Foo", 0L); 486 487 Assert.Throws<InvalidOperationException>(() => e.MoveNext()); 488 Assert.Throws<InvalidOperationException>(() => e.Reset()); 489 } 490 491 [Fact] RetrieveStatistics_Values_Success()492 public void RetrieveStatistics_Values_Success() 493 { 494 IDictionary d = new SqlConnection().RetrieveStatistics(); 495 Assert.NotNull(d.Values); 496 Assert.Same(d.Values, d.Values); 497 } 498 499 [Fact] RetrieveStatistics_Values_IsSynchronized_Success()500 public void RetrieveStatistics_Values_IsSynchronized_Success() 501 { 502 IDictionary d = new SqlConnection().RetrieveStatistics(); 503 ICollection c = d.Values; 504 Assert.False(c.IsSynchronized); 505 } 506 507 [Fact] RetrieveStatistics_Values_SyncRoot_Success()508 public void RetrieveStatistics_Values_SyncRoot_Success() 509 { 510 IDictionary d = new SqlConnection().RetrieveStatistics(); 511 ICollection c = d.Values; 512 Assert.NotNull(c.SyncRoot); 513 Assert.Same(c.SyncRoot, c.SyncRoot); 514 } 515 516 [Fact] RetrieveStatistics_Values_CopyTo_ObjectArray_Success()517 public void RetrieveStatistics_Values_CopyTo_ObjectArray_Success() 518 { 519 IDictionary d = new SqlConnection().RetrieveStatistics(); 520 ICollection c = d.Values; 521 object[] destination = new object[c.Count]; 522 523 c.CopyTo(destination, 0); 524 525 Assert.Equal(c.Cast<object>().ToArray(), destination); 526 } 527 528 [Fact] RetrieveStatistics_Values_CopyTo_Int64Array_Success()529 public void RetrieveStatistics_Values_CopyTo_Int64Array_Success() 530 { 531 IDictionary d = new SqlConnection().RetrieveStatistics(); 532 ICollection c = d.Values; 533 long[] destination = new long[c.Count]; 534 535 c.CopyTo(destination, 0); 536 537 Assert.Equal(c.Cast<long>().ToArray(), destination); 538 } 539 540 [Fact] RetrieveStatistics_Values_CopyTo_Throws()541 public void RetrieveStatistics_Values_CopyTo_Throws() 542 { 543 IDictionary d = new SqlConnection().RetrieveStatistics(); 544 ICollection c = d.Values; 545 546 AssertExtensions.Throws<ArgumentNullException>("array", () => c.CopyTo(null, 0)); 547 AssertExtensions.Throws<ArgumentNullException>("array", () => c.CopyTo(null, -1)); 548 AssertExtensions.Throws<ArgumentOutOfRangeException>("arrayIndex", () => c.CopyTo(new long[20], -1)); 549 AssertExtensions.Throws<ArgumentException>(null, () => c.CopyTo(new long[20], 18)); 550 AssertExtensions.Throws<ArgumentException>(null, () => c.CopyTo(new long[20], 1000)); 551 AssertExtensions.Throws<ArgumentException>(null, () => c.CopyTo(new long[4, 3], 0)); 552 Assert.Throws<InvalidCastException>(() => c.CopyTo(new Version[20], 0)); 553 } 554 555 [Fact] RetrieveStatistics_Values_GetEnumerator_Success()556 public void RetrieveStatistics_Values_GetEnumerator_Success() 557 { 558 IDictionary d = new SqlConnection().RetrieveStatistics(); 559 ICollection c = d.Values; 560 561 IEnumerator e = c.GetEnumerator(); 562 563 Assert.NotNull(e); 564 Assert.NotSame(e, c.GetEnumerator()); 565 566 for (int i = 0; i < 2; i++) 567 { 568 Assert.Throws<InvalidOperationException>(() => e.Current); 569 570 foreach (string ignored in s_retrieveStatisticsKeys) 571 { 572 Assert.True(e.MoveNext()); 573 Assert.NotNull(e.Current); 574 Assert.Equal(0L, e.Current); 575 } 576 577 Assert.False(e.MoveNext()); 578 Assert.False(e.MoveNext()); 579 Assert.False(e.MoveNext()); 580 581 Assert.Throws<InvalidOperationException>(() => e.Current); 582 583 e.Reset(); 584 } 585 } 586 587 [Fact] RetrieveStatistics_Values_GetEnumerator_ModifyCollection_Throws()588 public void RetrieveStatistics_Values_GetEnumerator_ModifyCollection_Throws() 589 { 590 IDictionary d = new SqlConnection().RetrieveStatistics(); 591 ICollection c = d.Values; 592 593 IEnumerator e = c.GetEnumerator(); 594 595 d.Add("Foo", 0L); 596 597 Assert.Throws<InvalidOperationException>(() => e.MoveNext()); 598 Assert.Throws<InvalidOperationException>(() => e.Reset()); 599 } 600 } 601 } 602