modified the test and addressed review comments

This commit is contained in:
Afsaneh Rafighi 2018-06-26 10:43:28 -07:00
Родитель 3551f7b503
Коммит 286eb8f789
7 изменённых файлов: 69 добавлений и 106 удалений

Просмотреть файл

@ -4,6 +4,7 @@
# that utilizes SqlDataReader.GetColumnScheme() indirectly by casting SqlDataReader to IDbColumnSchemaGenerator type.
# In order to prevent it, the API needs to be kept in public, and following 2 error message should be remaining in this baseline file.
#
# PoolBlockingPeriod was not added until .NET Framework 4.6.2, hence, these APIs are netcoreapp specific only.
Compat issues with assembly System.Data.SqlClient:
CannotRemoveBaseTypeOrInterface : Type 'System.Data.SqlClient.SqlDataReader' does not implement interface 'System.Data.Common.IDbColumnSchemaGenerator' in the reference but it does in the implementation.
MembersMustExist : Member 'System.Data.SqlClient.SqlDataReader.GetColumnSchema()' does not exist in the reference but it does exist in the implementation.

Просмотреть файл

@ -40,7 +40,7 @@
<Compile Include="System.Data.SqlClient.TypeForwards.cs" />
</ItemGroup>
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true' AND '$(OSGroup)' != 'AnyOS' AND '$(TargetGroup)' == 'netcoreapp'">
<Compile Include="System\Data\SqlClient\PoolBlockingPeriod.NetCoreApp.cs" />
<Compile Include="System\Data\SqlClient\PoolBlockingPeriod.cs" />
</ItemGroup>
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true' AND '$(OSGroup)' != 'AnyOS'">
<Compile Include="Microsoft\SqlServer\Server\ITypedGetters.cs" />

Просмотреть файл

@ -78,7 +78,6 @@ namespace System.Data.Common
// We could use Enum.TryParse<PoolBlockingPeriod> here, but it accepts value combinations like
// "ReadOnly, ReadWrite" which are unwelcome here
// Also, Enum.TryParse is 100x slower than plain StringComparer.OrdinalIgnoreCase.Equals method.
if (TryConvertToPoolBlockingPeriod(sValue, out result))
{
return result;

Просмотреть файл

@ -10,6 +10,14 @@ namespace System.Data.ProviderBase
{
sealed internal partial class DbConnectionPool
{
partial void CheckPoolBlockingPeriod(Exception e)
{
if (!IsBlockingPeriodEnabled())
{
throw e;
}
}
private bool IsBlockingPeriodEnabled()
{
var poolGroupConnectionOptions = _connectionPoolGroup.ConnectionOptions as SqlConnectionString;

Просмотреть файл

@ -8,7 +8,6 @@
using System.Collections.Generic;
using System.Data.Common;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
@ -720,12 +719,9 @@ namespace System.Data.ProviderBase
{
throw;
}
#if netcoreapp
if (!IsBlockingPeriodEnabled())
{
throw;
}
#endif
CheckPoolBlockingPeriod(e);
newObj = null; // set to null, so we do not return bad new object
// Failed to create instance
_resError = e;
@ -764,6 +760,9 @@ namespace System.Data.ProviderBase
return newObj;
}
//This method is implemented in DbConnectionPool.NetCoreApp
partial void CheckPoolBlockingPeriod(Exception e);
private void DeactivateObject(DbConnectionInternal obj)
{
obj.DeactivateConnection();

Просмотреть файл

@ -10,7 +10,6 @@ namespace System.Data.SqlClient.ManualTesting.Tests
public class PoolBlockPeriodTest
{
private static readonly string _sampleAzureEndpoint = "nonexistance.database.windows.net";
private static readonly string _sampleNonAzureEndpoint = "nonexistanceserver";
private static readonly string _policyKeyword = "PoolBlockingPeriod";
[Theory]
@ -64,126 +63,83 @@ namespace System.Data.SqlClient.ManualTesting.Tests
[InlineData("Test policy with Auto (lowercase)", new object[] { "auto" })]
[InlineData("Test policy with Auto (miXedcase)", new object[] { "auTo" })]
[InlineData("Test policy with Auto (Pascalcase)", new object[] { "Auto" })]
public void TestSetPolicyWithAutoVariations(string description, object[] Params)
{
SqlConnection.ClearAllPools();
string policyString = Params[0] as string;
string connString = CreateConnectionString(_sampleAzureEndpoint, null) + $";{_policyKeyword}={policyString}";
PoolBlockingPeriodAzureTest(connString, PoolBlockingPeriod.Auto);
}
[Theory]
[InlineData("Test policy with Always (lowercase)", new object[] { "alwaysblock" })]
[InlineData("Test policy with Always (miXedcase)", new object[] { "aLwAysBlock" })]
[InlineData("Test policy with Always (Pascalcase)", new object[] { "AlwaysBlock" })]
public void TestSetPolicyWithAlwaysVariations(string description, object[] Params)
{
SqlConnection.ClearAllPools();
string policyString = Params[0] as string;
string connString = CreateConnectionString(_sampleAzureEndpoint, null) + $";{_policyKeyword}={policyString}";
PoolBlockingPeriodAzureTest(connString, PoolBlockingPeriod.AlwaysBlock);
}
[Theory]
[InlineData("Test policy with Never (lowercase)", new object[] { "neverblock" })]
[InlineData("Test policy with Never (miXedcase)", new object[] { "neVeRblock" })]
[InlineData("Test policy with Never (Pascalcase)", new object[] { "NeverBlock" })]
public void TestSetPolicyWithNeverVariations(string description, object[] Params)
public void TestSetPolicyWithVariations(string description, object[] Params)
{
SqlConnection.ClearAllPools();
string policyString = Params[0] as string;
string connString = CreateConnectionString(_sampleNonAzureEndpoint, null) + $";{_policyKeyword}={policyString}";
PoolBlockingPeriodNonAzureTest(connString, PoolBlockingPeriod.NeverBlock);
PoolBlockingPeriod? policy = null;
if (policyString.ToLower().Contains("auto"))
{
policy = PoolBlockingPeriod.Auto;
}
else if (policyString.ToLower().Contains("always"))
{
policy = PoolBlockingPeriod.AlwaysBlock;
}
else
{
policy = PoolBlockingPeriod.NeverBlock;
}
string connString = CreateConnectionString(_sampleAzureEndpoint, null) + $";{_policyKeyword}={policyString}";
PoolBlockingPeriodAzureTest(connString, policy);
}
public void PoolBlockingPeriodNonAzureTest(string connStr, PoolBlockingPeriod? policy)
{
SqlConnection.ClearAllPools();
Guid previousConnectionId = Guid.Empty;
int count = 0;
while (count < 2)
int firstErrorTimeInSecs = GetConnectionOpenTimeInSeconds(connStr);
int secondErrorTimeInSecs = GetConnectionOpenTimeInSeconds(connStr);
switch (policy)
{
using (SqlConnection sqlConnection = new SqlConnection(connStr))
{
try
{
sqlConnection.Open();
throw new Exception("Connection Open must expect an exception!");
}
catch (SqlException e)
{
// if it is the first time the exception is happening (previousConnectionId == Guid.Empty) skip the check
if (previousConnectionId != Guid.Empty)
{
switch (policy)
{
case PoolBlockingPeriod.Auto:
case PoolBlockingPeriod.AlwaysBlock:
if (e.ClientConnectionId != previousConnectionId)
{
throw new Exception($"Connection Open with Policy '{policy}' expect an exception with same connection id!");
}
break;
case PoolBlockingPeriod.NeverBlock:
if (e.ClientConnectionId == previousConnectionId)
{
throw new Exception($"Connection Open with Policy '{policy}' expect an exception with different connection id!");
}
break;
}
}
previousConnectionId = e.ClientConnectionId;
}
}
count++;
case PoolBlockingPeriod.Auto:
case PoolBlockingPeriod.AlwaysBlock:
Assert.InRange(secondErrorTimeInSecs, 0, firstErrorTimeInSecs);
break;
case PoolBlockingPeriod.NeverBlock:
Assert.InRange(secondErrorTimeInSecs, 1, int.MaxValue);
break;
}
}
public void PoolBlockingPeriodAzureTest(string connStr, PoolBlockingPeriod? policy)
{
SqlConnection.ClearAllPools();
Guid previousConnectionId = Guid.Empty;
int count = 0;
while (count < 2)
int firstErrorTimeInSecs = GetConnectionOpenTimeInSeconds(connStr);
int secondErrorTimeInSecs = GetConnectionOpenTimeInSeconds(connStr);
switch (policy)
{
using (SqlConnection sqlConnection = new SqlConnection(connStr))
case PoolBlockingPeriod.AlwaysBlock:
Assert.InRange(secondErrorTimeInSecs, 0, firstErrorTimeInSecs);
break;
case PoolBlockingPeriod.Auto:
case PoolBlockingPeriod.NeverBlock:
Assert.InRange(secondErrorTimeInSecs, 1, int.MaxValue);
break;
}
}
private int GetConnectionOpenTimeInSeconds(string connString)
{
using (SqlConnection conn = new SqlConnection(connString))
{
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
try
{
try
{
sqlConnection.Open();
throw new Exception("Connection Open must expect an exception!");
}
catch (SqlException e)
{
// if it is the first time the exception is happening (previousConnectionId == Guid.Empty) skip the check
if (previousConnectionId != Guid.Empty)
{
switch (policy)
{
case PoolBlockingPeriod.AlwaysBlock:
if (e.ClientConnectionId != previousConnectionId)
{
throw new Exception($"Connection Open with Policy '{policy}' expect an exception with same connection id!");
}
break;
case PoolBlockingPeriod.Auto:
case PoolBlockingPeriod.NeverBlock:
if (e.ClientConnectionId == previousConnectionId)
{
throw new Exception($"Connection Open with Policy '{policy}' expect an exception with different connection id!");
}
break;
}
}
previousConnectionId = e.ClientConnectionId;
}
stopwatch.Start();
conn.Open();
throw new Exception("Connection Open must expect an exception");
}
count++;
catch (Exception)
{
stopwatch.Stop();
}
return stopwatch.Elapsed.Seconds;
}
}