// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. namespace ProductivityApiUnitTests { using System; using System.Configuration; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Data.Entity.Internal; using System.Data.Entity.Resources; using System.Data.SqlClient; using System.Data.SqlServerCe; using Moq; using Xunit; /// /// Tests for creating and managing connections using IInternalConnection. /// public class InternalConnectionTests : TestBase { #region Positive existing connection tests [Fact] public void Existing_connection_provided_is_returned() { using (var connection = new SqlConnection()) { using (var internalConnection = new EagerInternalConnection(connection, connectionOwned: false)) { Assert.Same(connection, internalConnection.Connection); } } } #endregion #region Positive app.config connection tests [Fact] public void Full_name_of_context_is_found_in_app_config() { using (var internalConnection = new LazyInternalConnection("Couger35.Hubcap.FullNameDbContext")) { var connection = internalConnection.Connection; Assert.Equal("FullNameInAppConfig", connection.Database); Assert.IsType(connection); } } [Fact] public void Name_of_context_with_Context_stripped_is_not_found_in_app_config() { using (var internalConnection = new LazyInternalConnection("Couger35.Hubcap.FullNameStrippedContext")) { var connection = internalConnection.Connection; Assert.Equal("Couger35.Hubcap.FullNameStrippedContext", connection.Database); Assert.IsType(connection); } } [Fact] public void Name_of_context_with_DbContext_stripped_is_not_found_in_app_config() { using (var internalConnection = new LazyInternalConnection("Couger35.Hubcap.FullNameDbStrippedDbContext")) { var connection = internalConnection.Connection; Assert.Equal("Couger35.Hubcap.FullNameDbStrippedDbContext", connection.Database); Assert.IsType(connection); } } [Fact] public void Name_of_context_with_namespace_stripped_is_found_in_app_config() { using (var internalConnection = new LazyInternalConnection("Couger35.Hubcap.ShortNameDbContext")) { var connection = internalConnection.Connection; Assert.Equal("ShortNameInAppConfig", connection.Database); Assert.IsType(connection); } } [Fact] public void Name_of_context_with_namespace_and_Context_stripped_is_not_found_in_app_config() { using (var internalConnection = new LazyInternalConnection("Couger35.Hubcap.ShortNameStrippedContext")) { var connection = internalConnection.Connection; Assert.Equal("Couger35.Hubcap.ShortNameStrippedContext", connection.Database); Assert.IsType(connection); } } [Fact] public void Name_of_context_with_namespace_and_DbContext_stripped_is_found_in_app_config() { using (var internalConnection = new LazyInternalConnection("Couger35.Hubcap.ShortNameDbStrippedDbContext")) { var connection = internalConnection.Connection; Assert.Equal("Couger35.Hubcap.ShortNameDbStrippedDbContext", connection.Database); Assert.IsType(connection); } } [Fact] public void Connection_from_app_config_is_cached() { using (var internalConnection = new LazyInternalConnection("Couger35.Hubcap.FullNameDbContext")) { var connection = internalConnection.Connection; Assert.Same(connection, internalConnection.Connection); Assert.Same(connection, internalConnection.Connection); } } // See Dev11 bug 113586 [Fact] public void Nice_exception_is_thrown_if_connection_string_in_app_config_does_not_contain_provider_name() { using (var internalConnection = new LazyInternalConnection("ConnectionWithoutProviderName")) { Assert.Equal( Strings.DbContext_ProviderNameMissing("ConnectionWithoutProviderName"), Assert.Throws(() => { var _ = internalConnection.Connection; }).Message); } } #endregion #region Positive hard-coded connection string tests [Fact] public void Connection_from_hard_coded_connection_string_is_cached() { using (var internalConnection = new LazyInternalConnection("Database=HardCodedConnectionString")) { var connection = internalConnection.Connection; Assert.Same(connection, internalConnection.Connection); Assert.Same(connection, internalConnection.Connection); } } [Fact] public void Default_connection_factory_is_used_to_create_connection_from_connection_string() { using (var internalConnection = new LazyInternalConnection("Database=HardCodedConnectionString")) { var connection = internalConnection.Connection; Assert.IsType(connection); } } [Fact] public void Changed_connection_factory_is_used_to_create_connection_from_connection_string() { try { var mockFactory = new Mock(); mockFactory.Setup(f => f.CreateConnection("Database=HardCodedConnectionString")).Returns(new SqlConnection()); MutableResolver.AddResolver(k => mockFactory.Object); using (var internalConnection = new LazyInternalConnection("Database=HardCodedConnectionString")) { var _ = internalConnection.Connection; } mockFactory.Verify(f => f.CreateConnection("Database=HardCodedConnectionString")); } finally { MutableResolver.ClearResolvers(); } } #endregion #region Negative hard-coded connection string tests [Fact] public void Using_bad_connection_string_throws() { var expectedException = GenerateException(() => new SqlConnection("Step1=YouNeedToAsk?").Open()); using (var internalConnection = new LazyInternalConnection("Step1=YouNeedToAsk?")) { Assert.Equal( expectedException.Message, Assert.Throws(() => { var _ = internalConnection.Connection; }).Message); } } #endregion #region Positive IDbConnectionFactory tests [Fact] public void Default_IDbConnectionFactory_is_used_to_create_connection() { using (var internalConnection = new LazyInternalConnection("NameNotInAppConfig")) { var connection = internalConnection.Connection; Assert.Equal("NameNotInAppConfig", connection.Database); Assert.IsType(connection); } } [Fact] public void Changed_by_convention_IDbConnectionFactory_is_used_to_create_connection() { try { var mockFactory = new Mock(); mockFactory.Setup(f => f.CreateConnection(It.IsAny())).Returns(new SqlConnection()); MutableResolver.AddResolver(k => mockFactory.Object); using (var internalConnection = new LazyInternalConnection("NameNotInAppConfig")) { var connection = internalConnection.Connection; } mockFactory.Verify(f => f.CreateConnection("NameNotInAppConfig")); } finally { MutableResolver.ClearResolvers(); } } [Fact] public void Explicit_name_is_used_without_stripping_Context() { using (var internalConnection = new LazyInternalConnection("Couger35.Hubcap.NameForFactoryContext")) { var connection = internalConnection.Connection; Assert.Equal("Couger35.Hubcap.NameForFactoryContext", connection.Database); Assert.IsType(connection); } } [Fact] public void Explicit_name_is_used_without_stripping_DbContext() { using (var internalConnection = new LazyInternalConnection("Couger35.Hubcap.NameForFactoryDbContext")) { var connection = internalConnection.Connection; Assert.Equal("Couger35.Hubcap.NameForFactoryDbContext", connection.Database); Assert.IsType(connection); } } [Fact] public void By_convention_name_does_not_have_Context_stripped() { using (var internalConnection = new LazyInternalConnection("Couger35.Hubcap.NameForFactoryContext")) { var connection = internalConnection.Connection; Assert.Equal("Couger35.Hubcap.NameForFactoryContext", connection.Database); Assert.IsType(connection); } } [Fact] public void By_convention_name_does_not_have_DbContext_stripped() { using (var internalConnection = new LazyInternalConnection("Couger35.Hubcap.NameForFactoryDbContext")) { var connection = internalConnection.Connection; Assert.Equal("Couger35.Hubcap.NameForFactoryDbContext", connection.Database); Assert.IsType(connection); } } [Fact] public void Connection_from_factory_is_cached() { using (var internalConnection = new LazyInternalConnection("NameForFactory")) { var connection = internalConnection.Connection; Assert.Same(connection, internalConnection.Connection); Assert.Same(connection, internalConnection.Connection); } } #endregion #region Negative IDbConnectionFactory tests [Fact] public void Changed_default_connection_factory_that_results_in_null_connections_throws() { try { MutableResolver.AddResolver(k => new Mock().Object); using (var internalConnection = new LazyInternalConnection("NameNotInAppConfig")) { Assert.Equal( Strings.DbContext_ConnectionFactoryReturnedNullConnection, Assert.Throws(() => { var _ = internalConnection.Connection; }).Message); } } finally { MutableResolver.ClearResolvers(); } } #endregion #region Positive connection dispose tests [Fact] public void Existing_connection_is_not_disposed_after_use() { var disposed = false; using (var connection = new SqlConnection()) { connection.Disposed += (_, __) => disposed = true; using (var internalConnection = new EagerInternalConnection(connection, connectionOwned: false)) { var _ = internalConnection.Connection; } Assert.False(disposed); } Assert.True(disposed); } [Fact] public void Existing_connection_is_disposed_after_use_if_it_is_owned_by_the_connection_object() { var disposed = false; var connection = new SqlConnection(); connection.Disposed += (_, __) => disposed = true; using (var internalConnection = new EagerInternalConnection(connection, connectionOwned: true)) { var _ = internalConnection.Connection; } Assert.True(disposed); } [Fact] public void Connection_created_from_app_config_is_disposed_after_use() { var disposed = false; using (var internalConnection = new LazyInternalConnection("Couger35.Hubcap.FullNameDbContext")) { var connection = internalConnection.Connection; connection.Disposed += (_, __) => disposed = true; } Assert.True(disposed); } [Fact] public void Connection_created_from_hard_coded_connection_string_is_disposed_after_use() { var disposed = false; using (var internalConnection = new LazyInternalConnection("Database=HardCodedConnectionString")) { var connection = internalConnection.Connection; connection.Disposed += (_, __) => disposed = true; } Assert.True(disposed); } [Fact] public void Connection_created_from_factory_is_disposed_after_use() { var disposed = false; using (var internalConnection = new LazyInternalConnection("NameForFactory")) { var connection = internalConnection.Connection; connection.Disposed += (_, __) => disposed = true; } Assert.True(disposed); } [Fact] public void Disposed_LazyInternalConnection_can_be_reused() { var internalConnection = new LazyInternalConnection("NameForFactory"); try { var disposed1 = 0; var disposed2 = 0; var connection1 = internalConnection.Connection; connection1.Disposed += (_, __) => disposed1++; internalConnection.Dispose(); Assert.Equal(1, disposed1); Assert.Equal(0, disposed2); var connection2 = internalConnection.Connection; connection2.Disposed += (_, __) => disposed2++; internalConnection.Dispose(); Assert.Equal(1, disposed1); Assert.Equal(1, disposed2); } finally { internalConnection.Dispose(); } } [Fact] public void Disposed_EagerInternalConnection_created_with_existing_connection_can_be_reused() { var disposed = false; using (var connection = new SqlConnection()) { connection.Disposed += (_, __) => disposed = true; var internalConnection = new EagerInternalConnection(connection, connectionOwned: false); try { Assert.Same(connection, internalConnection.Connection); internalConnection.Dispose(); Assert.False(disposed); Assert.Same(connection, internalConnection.Connection); internalConnection.Dispose(); Assert.False(disposed); } finally { internalConnection.Dispose(); } } Assert.True(disposed); } #endregion #region Lazy connection tests [Fact] public void LazyInternalConnection_can_create_connection_from_DbConnectionInfo_with_connection_string() { using ( var connection = new LazyInternalConnection(new DbConnectionInfo("Database=DatabaseFromDbConnectionInfo", "System.Data.SqlClient"))) { Assert.IsType(connection.Connection); Assert.Equal("DatabaseFromDbConnectionInfo", connection.Connection.Database); Assert.Equal(null, connection.ConnectionStringName); Assert.Equal(DbConnectionStringOrigin.DbContextInfo, connection.ConnectionStringOrigin); } } [Fact] public void LazyInternalConnection_can_create_connection_from_DbConnectionInfo_from_config_file() { using (var connection = new LazyInternalConnection(new DbConnectionInfo("LazyConnectionTest"))) { Assert.IsType(connection.Connection); Assert.Equal("ConnectionFromAppConfig.sdf", connection.Connection.Database); Assert.Equal("LazyConnectionTest", connection.ConnectionStringName); Assert.Equal(DbConnectionStringOrigin.DbContextInfo, connection.ConnectionStringOrigin); } } [Fact] public void LazyInternalConnection_throws_when_cant_find_connection_from_DbConnectionInfo_in_config_file() { using (var connection = new LazyInternalConnection(new DbConnectionInfo("YouWontFindMe"))) { Assert.Equal( Strings.DbConnectionInfo_ConnectionStringNotFound("YouWontFindMe"), Assert.Throws(() => { var temp = connection.Connection; }).Message); } } [Fact] public void LazyInternalConnection_can_create_connection_from_DbConnectionInfo_from_overridden_config_file() { using (var connection = new LazyInternalConnection(new DbConnectionInfo("LazyConnectionTest"))) { connection.AppConfig = new AppConfig( CreateEmptyConfig().AddConnectionString( "LazyConnectionTest", "Database=FromOverridenConfig", "System.Data.SqlClient")); Assert.IsType(connection.Connection); Assert.Equal("FromOverridenConfig", connection.Connection.Database); Assert.Equal("LazyConnectionTest", connection.ConnectionStringName); Assert.Equal(DbConnectionStringOrigin.DbContextInfo, connection.ConnectionStringOrigin); } } [Fact] public void LazyInternalConnection_can_calculate_ConnectionHasModel_false_from_convention_without_initializing() { using (var connection = new LazyInternalConnection("MyName")) { Assert.False(connection.ConnectionHasModel); Assert.False(connection.IsInitialized); } } [Fact] public void LazyInternalConnection_can_calculate_ConnectionHasModel_false_from_config_file_without_initializing() { using (var connection = new LazyInternalConnection("name=LazyConnectionTest")) { Assert.False(connection.ConnectionHasModel); Assert.False(connection.IsInitialized); } } [Fact] public void LazyInternalConnection_can_calculate_ConnectionHasModel_true_from_config_file_without_initializing() { using (var connection = new LazyInternalConnection("name=EntityConnectionString")) { Assert.True(connection.ConnectionHasModel); Assert.False(connection.IsInitialized); } } [Fact] public void LazyInternalConnection_can_calculate_ConnectionHasModel_false_from_connection_string_without_initializing() { var efString = ConfigurationManager.ConnectionStrings["LazyConnectionTest"].ConnectionString; using (var connection = new LazyInternalConnection(efString)) { Assert.False(connection.ConnectionHasModel); Assert.False(connection.IsInitialized); } } [Fact] public void LazyInternalConnection_can_calculate_ConnectionHasModel_true_from_connection_string_without_initializing() { var efString = ConfigurationManager.ConnectionStrings["EntityConnectionString"].ConnectionString; using (var connection = new LazyInternalConnection(efString)) { Assert.True(connection.ConnectionHasModel); Assert.False(connection.IsInitialized); } } [Fact] public void LazyInternalConnection_can_calculate_ConnectionHasModel_false_from_DbConnectionInfo_without_initializing() { using (var connection = new LazyInternalConnection(new DbConnectionInfo("LazyConnectionTest"))) { Assert.False(connection.ConnectionHasModel); Assert.False(connection.IsInitialized); } } [Fact] public void LazyInternalConnection_can_calculate_ConnectionHasModel_true_from_DbConnectionInfo_without_initializing() { using (var connection = new LazyInternalConnection(new DbConnectionInfo("EntityConnectionString"))) { Assert.True(connection.ConnectionHasModel); Assert.False(connection.IsInitialized); } } [Fact] public void LazyInternalConnection_can_calculate_ConnectionHasModel_false_after_initializing() { using (var connection = new LazyInternalConnection("name=LazyConnectionTest")) { var x = connection.Connection; Assert.True(connection.IsInitialized); Assert.False(connection.ConnectionHasModel); } } [Fact] public void LazyInternalConnection_can_calculate_ConnectionHasModel_true_after_initializing() { using (var connection = new LazyInternalConnection("name=EntityConnectionString")) { var x = connection.Connection; Assert.True(connection.IsInitialized); Assert.True(connection.ConnectionHasModel); } } [Fact] public void LazyInternalConnection_ConnectionHasModel_without_initializing_throws_when_connection_not_in_config() { using (var connection = new LazyInternalConnection("name=WontFindMe")) { Assert.Equal( Strings.DbContext_ConnectionStringNotFound("WontFindMe"), Assert.Throws(() => { var temp = connection.ConnectionHasModel; }).Message); } } [Fact] public void LazyInternalConnection_ConnectionHasModel_without_initializing_throws_when_connection_not_in_config_DbConnectionInfo() { using (var connection = new LazyInternalConnection(new DbConnectionInfo("WontFindMe"))) { Assert.Equal( Strings.DbConnectionInfo_ConnectionStringNotFound("WontFindMe"), Assert.Throws(() => { var temp = connection.ConnectionHasModel; }).Message); } } [Fact] public void LazyInternalConnection_provider_name_calculated_when_connection_by_convention() { using (var connection = new LazyInternalConnection("ConnectionName")) { Assert.Equal("System.Data.SqlClient", connection.ProviderName); } } [Fact] public void LazyInternalConnection_provider_name_calculated_when_connection_from_config() { using (var connection = new LazyInternalConnection("name=LazyConnectionTest")) { Assert.Equal("System.Data.SqlServerCe.4.0", connection.ProviderName); } } [Fact] public void LazyInternalConnection_provider_name_calculated_when_connection_from_DbConnectionInfo() { using ( var connection = new LazyInternalConnection( new DbConnectionInfo("Data Source=ConnectionFromDbConnectionInfo.sdf", "System.Data.SqlServerCe.4.0"))) { Assert.Equal("System.Data.SqlServerCe.4.0", connection.ProviderName); } } #endregion } }