I'm not sure if this is discussed elsewhere, but I'm trying to use the create persistent dbConnection method to save time in each of our unit tests. (We have about 1000 unit tests and the step to create the connection is substantial portion of the runtime).
Everything works fine when we run our tests using a single thread (VS default). However, when we turn on running tests in parallel, execution appears to hang when using a persistent connection. CreateTransient dbconnection with parallel tests works fine.
Anyways, I would love to use the persistent DB connection as it appears to save about 33% of total test execution time in single threaded execution.
Thanks for the excellent work on this tool!
Apr 13, 2015 at 12:17 PM
If you use persistent connection then all of your tests will run against the same instance of the database. In your case they will run even concurrently. Theoretically this should work as NMemory should handle concurrent transactions without any issue.
However I never really
the initialisation part of the fake database, so it is possible that something is not completely thread safe during that phase. Does the test runner start to hang right at the beginning?
Btw I am not really a fan of using persistent connection for multiple tests, because it makes setting up the tests much harder and the tests may fail in ways that are really hard to reproduce. So I would rather start to think how to optimise the db setup phase.
I think you are correct, it seems like there is something during the initialization phase. I tried debugging the unit tests in the configuration that hangs and eventually saw the following exception occur during a call to the CreatePersistent method.
From a writing of tests standpoint, using a persistent DB is not really a challenge for us. The way we set up our test data takes our multi-tenant design into account so everything worked perfectly in single threaded mode. Faster performance on db setup phase
would be much appreciated in any case!
System.Reflection.TargetInvocationException was unhandled by user code
Message=Exception has been thrown by the target of an invocation.
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object parameters, Object arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object parameters)
at Effort.Internal.Common.DatabaseReflectionHelper.CreateTable(Database database, Type entityType, IKeyInfo primaryKeyInfo, MemberInfo identityField, Object constraintFactories)
at Effort.Internal.DbManagement.DbContainer.Initialize(DbSchema schema)
at Effort.Internal.DbManagement.DbContainer.Initialize(StoreItemCollection edmStoreSchema)
at Effort.Provider.EffortProviderServices.<>c__DisplayClass4.<DbCreateDatabase>b__3(DbConnection x)
at Effort.Provider.EffortProviderServices.Wrap[T](DbConnection connection, Func`2 action)
at Effort.Provider.EffortProviderServices.DbCreateDatabase(DbConnection connection, Nullable`1 commandTimeout, StoreItemCollection storeItemCollection)
at System.Data.Entity.Core.Common.DbProviderServices.CreateDatabase(DbConnection connection, Nullable`1 commandTimeout, StoreItemCollection storeItemCollection)
at Effort.EntityConnectionFactory.CreateEntityConnection(MetadataWorkspace metadata, DbConnection connection)
at Effort.EntityConnectionFactory.CreatePersistent(String entityConnectionString, IDataLoader dataLoader)
at Effort.EntityConnectionFactory.CreatePersistent(String entityConnectionString)
at SchedulePro.Tests.UnitTests.Fakes.FakeRepositoryModule.Load() in FakeRepositoryModule.cs:line 31
at Ninject.Modules.NinjectModule.OnLoad(IKernel kernel)
at Ninject.KernelBase.Load(IEnumerable`1 m)
at Ninject.ModuleLoadExtensions.Load(IKernel kernel, INinjectModule modules)
at Tests.UnitTests\BaseTest.cs:line 149
at BuildGraphWithLimitsRunToCompletionTest() in
Message=Object reference not set to an instance of an object.
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at NMemory.Concurrency.TableLockConcurrencyManager.RegisterTable(ITable table)
at NMemory.Tables.TableCollection.RegisterTable(ITable table)
at NMemory.Tables.TableCollection.Create[TEntity,TPrimaryKey](IKeyInfo`2 primaryKey, IdentitySpecification`1 identitySpecification)
at Effort.Internal.Common.DatabaseReflectionHelper.WrapperMethods.CreateTable[TEntity,TPrimaryKey](Database database, IKeyInfo`2 primaryKeyInfo, Expression`1 identity, Object constraintFactories)