Can't open sqlconnection within nunit test

回眸只為那壹抹淺笑 提交于 2019-12-20 07:18:06

问题


I'm having a weird issue that I can't figure out. I'm trying to write some integration tests around some database code and my unit tests fail with a weird exception. Running the code normally under a console application work just fine.

public static class DatabaseManager
{
    public static VerifyServceConnectionResult VerifyServerConnection(Server server)
    {
        try
        {

            using (var conn = new SqlConnection(BuildConnectionString(server)))
            {
                conn.Open();
            }

            return new VerifyServceConnectionResult { ConnectionSuccessful = true };
        }
        catch (SqlException ex)
        {
            return new VerifyServceConnectionResult
            {
                ConnectionSuccessful = false, 
                ErrorMessage = ex.Message
            };
        }
        catch (Exception ex)
        {
            return new VerifyServceConnectionResult
            {
                ConnectionSuccessful = false,
                ErrorMessage = "General Exception: " + ex.Message
            };
        }
    }

    private static string BuildConnectionString(Server server)
    {
        var builder = new SqlConnectionStringBuilder();

        builder.DataSource = server.DataSource;
        builder.IntegratedSecurity = server.UseIntegratedSecurity;

        return builder.ConnectionString;
    }

}

as soon as conn.open gets called within the Nunit Test I get an exception "Arithmetic operation resulted in an overflow." Any ideas on why such a simple test would be failing in nunit with such a weird error. Again, the code works just fine outside of the context of the unit test.

Thanks

edit: adding stack trace

at SNIOpenSyncExWrapper(SNI_CLIENT_CONSUMER_INFO* , SNI_ConnWrapper** )
at SNINativeMethodWrapper.SNIOpenSyncEx(ConsumerInfo consumerInfo, String constring, IntPtr& pConn, Byte[] spnBuffer, Byte[] instanceName, Boolean fOverrideCache, Boolean fSync, Int32 timeout, Boolean fParallel)
at System.Data.SqlClient.SNIHandle..ctor(ConsumerInfo myInfo, String serverName, Byte[] spnBuffer, Boolean ignoreSniOpenTimeout, Int32 timeout, Byte[]& instanceName, Boolean flushCache, Boolean fSync, Boolean fParallel)
at System.Data.SqlClient.TdsParserStateObject.CreatePhysicalSNIHandle(String serverName, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Byte[]& instanceName, Byte[] spnBuffer, Boolean flushCache, Boolean async, Boolean fParallel)
at System.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity, Boolean withFailover)
at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover)
at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout)
at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance)
at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData)
at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.Open()
at xxx.Database.DatabaseManager.VerifyServerConnection(Server server) in d:\projects\TFS\xxx.visualstudio.com\SnydJK.DatabaseUtility\Database\DatabaseManager.cs:line 17

回答1:


Recently, I experienced an exception with the same call stack.

Enviroment

I was using LocalDB server on Windows 8.1 64-bit (not in domain) with default UAC settings and the user is local admin, Framework v4.0.2 (see why it's important). Sadly, the issue can't be reproduced on other computers with the same enviroment.

Issue description

Found out that the exception occurs in the following conditions:

  • There is Integrated Security parameter in the connection string which is used to create a new database.
  • The same process opens a connection to the newly created DB after it got created.

Breaking one of these two conditions allows to get through without exceptions. So omitting the Integrated Security is the easiest way to go. As an option - don't open connection to the newly created DB in the same process. But just adding a pause after creating a DB wouldn’t help if we’re still working in the scope of one process.

Solution

Chuck out the Integrated Security parameter in the connection string when have a deal with LocalDB.

General Comments

Integrated Security is an option, which specifies that Windows account credentials are used for authentication (see details on MSDN and here). Having this option (value True or SSPI) is recommended for SQL Servers.

Meanwhile this option doesn’t make any difference for LocalDB servers. Regardless of this setting, LocalDB will still be a user instance, running under the account that started it. Basically, it’ll be as Integrated Security was set to True or SSPI. There is no way in LocalDB to prevent the user from accessing data in their database (e.g. by using SQL authorisation). Once the user has access to the database file, they can spin up their own LocalDB instance and open the database.

Hence all recommendations to specify the Integrated Security when connecting to LocalDB have no grounds.



来源:https://stackoverflow.com/questions/25836198/cant-open-sqlconnection-within-nunit-test

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!