Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

Ncrunch & Mef
Connes
#1 Posted : Tuesday, December 2, 2014 4:20:05 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 12/2/2014(UTC)
Posts: 4
Location: France

Thanks: 2 times
Hi,

I some of my tests i inject a dependency by MEF with :
Code:

// In My TestClass
 [AssemblyInitialize]
        public static void InitializeAssembly(TestContext testContext)
        {
            // Add Task scheduler DAL assembly for MEF injection.
            Bootstrapper.ConfigureAggregateCatalog(new AssemblyCatalog(typeof(CommandManager).Assembly));
            Bootstrapper.ConfigureAggregateCatalog(new AssemblyCatalog(typeof(CommandAdapterDataAccessMock).Assembly));

            // Configures recomposition container using MEF
            Bootstrapper.ConfigureContainer();
        }
...
 // In the tested class.
        [Import]
        private IIngestionDataAccessFactory factory;
public DataIngestionService()
        {
            Bootstrapper.SatisfyImportsOnce(this); // -> Boum
        }


If i run all the test in VS, all are green, in MsTest, all green but in NCrunch i get a composition Error:

System.ComponentModel.Composition.CompositionException: The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.

1) More than one export was found that matches the constraint:
ContractName Itesoft.ProductionManager.DataIngestion.Contracts.IIngestionDataAccessFactory
RequiredTypeIdentity Itesoft.ProductionManager.DataIngestion.Contracts.IIngestionDataAccessFactory

Resulting in: Cannot set import 'Itesoft.ProductionManager.DataIngestion.BLL.DataIngestionService.factory (ContractName="Itesoft.ProductionManager.DataIngestion.Contracts.IIngestionDataAccessFactory")' on part 'Itesoft.ProductionManager.DataIngestion.BLL.DataIngestionService'.
Element: Itesoft.ProductionManager.DataIngestion.BLL.DataIngestionService.factory (ContractName="Itesoft.ProductionManager.DataIngestion.Contracts.IIngestionDataAccessFactory") --> Itesoft.ProductionManager.DataIngestion.BLL.DataIngestionService


It 's seemed that several MEF exports are injected in the Container but only when they are runned in ncrunch. Is the handling of the AssemblyInitializeAttribute is different with NCrunch ?

If I run the test one by one in ncrunch, they are all ok, if i run all the tests at a time with 'Run test in new task runnerProcess' they are all KO.
How can i have more informations on what's happen ?

Thanks in advance
CConnes
Remco
#2 Posted : Tuesday, December 2, 2014 8:25:43 PM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 7,144

Thanks: 959 times
Was thanked: 1290 time(s) in 1196 post(s)
Hi,

Thanks for sharing this issue.

These tests are likely to be sequence/batch dependent. Because NCrunch is able to call into test runners multiple times within the same process (as part of its task batching), it is possible for the Bootstrapper code above to be run multiple times for the same process.

Placing a static boolean check at the top of the InitializeAssembly method to ensure it doesn't execute multiple times should resolve this problem. See 'Test runner re-use' under http://www.ncrunch.net/documentation/considerations-and-constraints_test-atomicity for more information on this one.

Cheers,

Remco
1 user thanked Remco for this useful post.
Connes on 12/3/2014(UTC)
Connes
#3 Posted : Wednesday, December 3, 2014 9:04:23 AM(UTC)
Rank: Newbie

Groups: Registered
Joined: 12/2/2014(UTC)
Posts: 4
Location: France

Thanks: 2 times
Thanks a lot.
The static check made the trick but i would understand why the InitializeAssembly function is called several times ? The AssemblyInitialize attribute does not guarantee us to be called only once when assembly is loaded ?

CConnes
Remco
#4 Posted : Wednesday, December 3, 2014 9:26:58 AM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 7,144

Thanks: 959 times
Was thanked: 1290 time(s) in 1196 post(s)
The repeated calls to AssemblyInitialize occur because of the behaviour of NCrunch's test pipeline. NCrunch will split the entire test queue into multiple tasks to be executed independently of one another. Because the execution of each task involves a full fresh call into the test framework, and the test framework is not designed to have its activities split between multiple invocations, it needs to be reinitialised for each task that is run. This results in AssemblyInitialize being called once per task, rather than once per process. The alternative is to terminate the process after each task run, but this is very expensive as the act of building and JITing assemblies into a process is very time consuming.

When you use a normal synchronous test runner, tests are run sequentially end-to-end in a single process within the lifespan of one control thread, and the process is torn down on test completion. This is a design that simply doesn't work for NCrunch, so the re-initialisation of the test framework is a concession made to allow NCrunch to run tests selectively without massive loss in performance.
Connes
#5 Posted : Wednesday, December 3, 2014 10:13:09 AM(UTC)
Rank: Newbie

Groups: Registered
Joined: 12/2/2014(UTC)
Posts: 4
Location: France

Thanks: 2 times
Thanks a lot.
I have appreciated you take the time for a detailled response.

CConnes.
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

YAF | YAF © 2003-2011, Yet Another Forum.NET
This page was generated in 0.048 seconds.
Trial NCrunch
Take NCrunch for a spin
Do your fingers a favour and supercharge your testing workflow
Free Download