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

Notification

Icon
Error

NCrunch console doesn't run each test in its own process.
samholder
#1 Posted : Tuesday, January 27, 2015 7:36:03 PM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 5/11/2012(UTC)
Posts: 94

Thanks: 28 times
Was thanked: 12 time(s) in 12 post(s)
I am seeing some different behaviour between the console and the VS plugin I think. I have class which creates a temporary database for each test. This class simply has a static id for the db which is a guid and relies on the fact that NCrunch runs each test in its own process to ensure that the guid is different in each test. This works fine in VS (and each guid is unique in each test as far as I am aware).

I have also been using NCrunch console on my build server, but have had some tests failing randomly with DB access timeouts and have noticed that I seem to get batches of tests all using the same guid, and I think it may be that the db is being destroyed/created by each test even though the other tests are still using it.

Am I imagining this difference? Or does the console work slightly differently to the VSPlugin in terms of test isolation? If it does are there any recommendations for tackling this?

**UPDATE**

I've just reduced the number of concurrent tests to 1 and all my tests have gone back to passing. I was originally using 4 concurrent tests on a 2 core machine and didn't see many test failures due to this issue. Reducing to 2 seemed to have upped the numbers of tests that failed. I could live with some tests being run in the same process as long as the ones scheduled in the same process never ran in parallel, and the parallelisation was always achieved by running tests in different processes together

Cheers

Sam
Remco
#2 Posted : Tuesday, January 27, 2015 9:21:44 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 Sam,

The behaviour in the console app in regards to this area should be technically the same as in the VS plugin, but it's possible that the difference in environment is causing race conditions to surface. There is no way NCrunch will ever run two tests concurrently within the same process, though it IS possible to have code from two tests inside one process overlap if they are running background tasks on different threads - see http://www.ncrunch.net/documentation/considerations-and-constraints_multi-threaded-tests.

Instead of using guids, you might find you have more success with using Process IDs (i.e. System.Diagnostics.Process.GetCurrentProcess().Id). These will be unique per test runner and they won't rely on any kind of random generation, so they are 100% reliable.

The ExclusivelyUsesAttribute may also be of some use here, although this won't work if you are running multiple instances of the NCrunch console tool (for example, if the build server kicks off two builds concurrently on the machine).
samholder
#3 Posted : Wednesday, January 28, 2015 12:26:10 PM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 5/11/2012(UTC)
Posts: 94

Thanks: 28 times
Was thanked: 12 time(s) in 12 post(s)
Thanks for the quick reply Remco.

I was under the (possibly incorrect) assumption that each test was run completely isolated so any static properties would be per test. I have a static field:

public static Guid DbId = Guid.NewGuid();

or similar and this field is used to generate the name of a mdf file which localdb uses as the db for the current test, and EF runs migrations on to create the schema. This ensures each test is running entirely isolated. In debug I think that each test always gets its own ID, although I'll need to check that, but it seems that this id is the same in some tests when I use the console runner.

I can't use the process id as I want each test to use its own unique db (hence the GUID). I can't just genberate a new guid everytime the class is created as EF creates multiple instances when its doing the migrations.

Hope this is clear.

I'm working round the issue by only runnning 1 test at a time currently, but part of the reason to use NCrunch on the server was to be able to parallelize the tests as they are reasonably slow (given each one creates its own db :))
Remco
#4 Posted : Wednesday, January 28, 2015 10:09:57 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)
Ok - that does explain the behaviour you're seeing :)

NCrunch will re-use test runners for multiple tests. This is by design as building a whole new environment for each individual test causes very poor performance. This means that in your design, you will have tests re-using the same ID if they are later executed in the same process. This doesn't mean that the tests are being run concurrently with the same ID, it just means that the ID is re-used.

You have a couple of options on how to solve this one ...

1. Mark up all tests with NCrunch.Framework.IsolatedAttribute. This will tell NCrunch to run them in isolation (building a new environment each time). You can also specify this at assembly-level and it will then be applied to each individual test fixture within the assembly.
2. Change the DbId so that this value is updated at the beginning of every test run - for example, place it in the SetUp code for each test that makes use of it. This will ensure each test has a unique ID assigned at the beginning of its run. It's still safe to keep this static as long as the value is consistently updated at the beginning of each test run.
samholder
#5 Posted : Sunday, February 1, 2015 2:44:48 PM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 5/11/2012(UTC)
Posts: 94

Thanks: 28 times
Was thanked: 12 time(s) in 12 post(s)
Hi Remco.

Thanks for the response. I have been able to restore the 'each test usijng its own database' situation now, by doing both things suggested above (using the Isolated attribute on the entire assembly, and setting the guid in each test setup. I can probably remove the isolated attribute now), but I'm still not seeing the tests running in parallel. As each test creates its own db, if they were running in parallel then I'd see multiple db files being created at once, but I don't. and I upped the VM they are running on to an 8 core machine and tried to configure NCRunch to run using 8 threads, but the tests all took the same time still.

I'm not sure if its my config file, so this is the contents of that:

<GlobalConfiguration>
<CoverageMarkerStyle>Circle</CoverageMarkerStyle>
<AutoAdjustMarkerColors>true</AutoAdjustMarkerColors>
<MarkerPerformanceDisplaySensitivity>100</MarkerPerformanceDisplaySensitivity>
<MarkerPerformanceAggregationType>Average</MarkerPerformanceAggregationType>
<SpinnerInnerCircleColor>-1</SpinnerInnerCircleColor>
<SpinnerBuildFailureCircleColor>-4558080</SpinnerBuildFailureCircleColor>
<SpinnerTestFailureCircleColor>-65536</SpinnerTestFailureCircleColor>
<SpinnerInitialisingCircleColor>-16776961</SpinnerInitialisingCircleColor>
<SpinnerNormalCircleColor>-16744423</SpinnerNormalCircleColor>
<SpinnerNormalTextColor>-16776961</SpinnerNormalTextColor>
<SpinnerFailingTestsTextColor>-65536</SpinnerFailingTestsTextColor>
<SpinnerRecentlyFailingTestsTextColor>1509949440</SpinnerRecentlyFailingTestsTextColor>
<SpinnerFailingBuildTextColor>-16777216</SpinnerFailingBuildTextColor>
<SpinnerRecentlyFailingBuildTextColor>1509949440</SpinnerRecentlyFailingBuildTextColor>
<SpinnerTestsQueuedTextColor>-16756736</SpinnerTestsQueuedTextColor>
<SpinnerBuildTaskSpinnerColor>-1</SpinnerBuildTaskSpinnerColor>
<SpinnerAnalysisTaskSpinnerColor>-1</SpinnerAnalysisTaskSpinnerColor>
<BackgroundColor>-1</BackgroundColor>
<ForegroundColor>-16777216</ForegroundColor>
<SecondaryBackgroundColor>-2039584</SecondaryBackgroundColor>
<SecondaryForegroundColor>-16777216</SecondaryForegroundColor>
<SpinnerTestTaskSpinnerColor>-1</SpinnerTestTaskSpinnerColor>
<UseVSColors>true</UseVSColors>
<TextOutputFontName>Courier New</TextOutputFontName>
<TextOutputFontStyle>Regular</TextOutputFontStyle>
<TextOutputFontSize>8.25</TextOutputFontSize>
<GridReconnectionDelayInSeconds>10</GridReconnectionDelayInSeconds>
<FastLaneThreads>2</FastLaneThreads>
<FastLaneThresholdInMilliseconds>10000</FastLaneThresholdInMilliseconds>
<SlidingBuildDelayInMilliseconds>0</SlidingBuildDelayInMilliseconds>
<LogToOutputWindow>false</LogToOutputWindow>
<CheckForUpdates>true</CheckForUpdates>
<CPUCoresAssignedToVisualStudio>7</CPUCoresAssignedToVisualStudio>
<CPUCoresAssignedToNCrunch>0,1,2,3,4,5,6</CPUCoresAssignedToNCrunch>
<MarkerColorNoCoverage>-16777216</MarkerColorNoCoverage>
<MarkerColorPoorPerformance>-256</MarkerColorPoorPerformance>
<MarkerColorPassingCoverage>-16744448</MarkerColorPassingCoverage>
<MarkerColorFailingCoverage>-65536</MarkerColorFailingCoverage>
<FileVersion>2</FileVersion>
<WorkspaceBasePath>e:\ncrunch\</WorkspaceBasePath>
<BuildProcessMemoryLimit>125000000</BuildProcessMemoryLimit>
<TestProcessMemoryLimit>0</TestProcessMemoryLimit>
<MaxNumberOfProcessingThreads>8</MaxNumberOfProcessingThreads>
<LogVerbosity>Summary</LogVerbosity>
<TerminateTestRunnerTasksOnExecutionComplete>true</TerminateTestRunnerTasksOnExecutionComplete>
<MaxTestRunnerProcessesToPool>4</MaxTestRunnerProcessesToPool>
<TestSelectorExpression></TestSelectorExpression>
</GlobalConfiguration>

Are there anything wrong with the config? or is there some way to determine why the tests are not running in parallel?

Cheers

Sam
Remco
#6 Posted : Sunday, February 1, 2015 9:55:54 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 Sam,

There is also a solution-level setting that controls parallel execution. If you take the default steps in the wizard, this is turned off. Do you have this disabled? http://www.ncrunch.net/documentation/reference_solution-configuration_allow-parallel-test-execution.
samholder
#7 Posted : Tuesday, February 3, 2015 6:55:53 AM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 5/11/2012(UTC)
Posts: 94

Thanks: 28 times
Was thanked: 12 time(s) in 12 post(s)
I don't have a solution configuration checked in to source control, but adding one has allowed the tests to run in parallel. Thanks for the tip. I'd expected the global setting to be used if none existed, but I assume that it has defaulted to 'false' as none was available
Remco
#8 Posted : Tuesday, February 3, 2015 7:01:17 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)
NCrunch is need of a big configuration overhaul. My hope is that eventually these sorts of issues will have an elegant and heavily customisable solution.

At the moment, parallel execution defaults to off. This is because the first run of NCrunch on a new codebase can be very daunting, and tests usually haven't been engineered with parallel execution in mind. It can often be difficult to strike an adequate balance between features and compatibility.
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.063 seconds.
Trial NCrunch
Take NCrunch for a spin
Do your fingers a favour and supercharge your testing workflow
Free Download