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

Notification

Icon
Error

All Database tests fail with latest version
TerryS
#1 Posted : Monday, July 22, 2013 4:32:46 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 7/22/2013(UTC)
Posts: 8
Location: United States of America

Thanks: 1 times
All Database tests fail with latest version. I have tried to eliminate this by setting NCrunch to a single CPU core, and process but it still fails. MS test passes all the tests so it is appears to be an issue with the latest version of NCrunch. All these tests worked fine under the previous version.

The Errors is:

System.Data.SqlClient.SqlException (0x80131904): An attempt to attach an auto-named database for file C:\Users\[USERNAME]\AppData\Local\NCrunch\7988\30\TestResults\26af65b2-2d7e-40ca-a962-74f0abaead72\Out\Resources\MdmTestDb.mdf failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share.
Remco
#2 Posted : Monday, July 22, 2013 10:39:29 PM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 6,979

Thanks: 931 times
Was thanked: 1257 time(s) in 1170 post(s)
Hi Terry,

Can you share any more information about the life cycle of this .mdf file? Is it a resource that is stored with your solution and deployed into the MSTest working area, or is it a file generated from one of your tests?

If you right click on the failed test in the Tests Window, then go to Advanced->Browse to workspace, can you find this file in the NCrunch workspace?
TerryS
#3 Posted : Wednesday, July 24, 2013 3:54:45 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 7/22/2013(UTC)
Posts: 8
Location: United States of America

Thanks: 1 times
Yes the mdf file is stored with the project, all operations/tests never changes the content of the DB, so it can remain read only.
the connection string in the project app.config file is

connectionString="Data Source=(localdb)\v11.0;AttachDbFilename=|DataDirectory|\Resources\MdmTestDb.mdf;Integrated Security=True"

yes if can see the mdf file in the test workspace.
we never had a problem until we upgraded to the new version.
Remco
#4 Posted : Wednesday, July 24, 2013 10:55:17 PM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 6,979

Thanks: 931 times
Was thanked: 1257 time(s) in 1170 post(s)
The new version introduced support for the MSTest variable 'DataDirectory', so I wonder if this might be what is causing the issue. Does removing this value from the connection string and replacing it with an alternative value (i.e. perhaps constructing the .mdf path using the current directory) make any difference?

I'm curious as to why the value NCrunch is placing against DataDirectory is different to MSBuild. Is there any chance you'd be able to get me a capture of the difference in this value between NCrunch/MSTest on your solution? Try adding the following code and running your test using each runner:

Console.WriteLine(AppDomain.CurrentDomain.GetData("DataDirectory"));


Thanks!

Remco
TerryS
#5 Posted : Thursday, July 25, 2013 5:25:17 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 7/22/2013(UTC)
Posts: 8
Location: United States of America

Thanks: 1 times
DataDirectory is the issue; NCrunch uses the same folder across multiple tests.
as such, it is behaving badly to error out.

The preferred behavior is: If the database is already there, it should use it, not error out. Many test running against a single database.

We have multiple tests, against the same database, with the same connection string. Which I would think is how most tests run, you have many individual test.
Remco
#6 Posted : Thursday, July 25, 2013 10:29:35 PM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 6,979

Thanks: 931 times
Was thanked: 1257 time(s) in 1170 post(s)
NCrunch will make multiple calls into the same process to run sets of tests in batches. This is necessary in order to perform proper continuous testing, as the priorities of tests can constantly change as the source code is being altered. Unfortunately, this makes impossible the old traditional approach of running all tests from start to finish in a single process. Most tests are are OK with this - but some tests that perform setup actions on each test run without considering the behaviour of NCrunch can experience problems. Usually it's fairly easy to fix these tests using a static flag that is set when the setup code is first run, then compared at each time the code is invoked to make sure the setup code is never called twice.

Have a look at test atomicity for more information on this.

If you're experiencing problems with NCrunch running these database tests in parallel with each other over the same .mdf file, you might want to look at introducing some concurrency constraints using attributes.
TerryS
#7 Posted : Thursday, July 25, 2013 11:16:52 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 7/22/2013(UTC)
Posts: 8
Location: United States of America

Thanks: 1 times
Ya, that's really not a good solution, in this case if the DB is available it should just use it, and not bail, its a test database, not a resource file - the error message even recognizes it as the database. Would not the best solution be able to adjust the engine - so it sees it is a DB not a file and use it, and ignore the file copy error?

The concurrent example as I read it would create a copy of the db for each test - well given a typical solution may have 100's of tests .. I assume I've understood that wrong?

I will investigate the IsolatedAttribute and other methods - Thanks.
Remco
#8 Posted : Friday, July 26, 2013 12:30:43 AM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 6,979

Thanks: 931 times
Was thanked: 1257 time(s) in 1170 post(s)
Hi Terry,

Sorry, I think I have misunderstood your problem.

NCrunch has no knowledge of databases or of the workings of your source code. It does not manipulate connection strings or anything around how your code connects to the database. Your code is basically just code that is executed under test. There is a line of code in NCrunch that explicitly sets the DataDirectory AppDomain variable to be the working directory of the executing test, it does so in this way:

AppDomain.CurrentDomain.SetData("DataDirectory", <working directory>);

This was added because some people make use of the DataDirectory appdomain value which is automatically set by MSTest. This value is automatically placed into connection strings during connection by ADO.NET, so if for some reason this value is different to that which is normally set by MSTest, then your code will be unable to find the database.

The .mdf file is just a file, treated like NCrunch the same as any other file. Because the file is being shared between tests, you should definitely look into making use of ExclusivelyUsesAttribute if you are using parallel execution for your database tests.

But anyway, the key question here is whether or not the database resource file is being referenced in the place that it exists in the NCrunch workspace.

Try adding the following two lines to your test code, then inspecting the results in the test output:

Console.WriteLine(AppDomain.CurrentDomain.GetData("DataDirectory") + @"\Resources\MdmTestDb.mdf");
Console.WriteLine(System.IO.File.Exists(AppDomain.CurrentDomain.GetData("DataDirectory") + @"\Resources\MdmTestDb.mdf"));

This will tell us whether or not the file is in its expected location in NCrunch's workspace. If you can let me know what the results are from the above two lines, I can help with further troubleshooting.

Cheers,

Remco
TerryS
#9 Posted : Monday, July 29, 2013 7:06:01 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 7/22/2013(UTC)
Posts: 8
Location: United States of America

Thanks: 1 times
Here is the output:
C:\Users\terry.sansom\AppData\Local\NCrunch\8428\31\TestResults\bb89c3d7-2699-410d-bbc9-2bc0e38ad722\Out\Resources\MdmTestDb.mdf
False
Assembly initialize/cleanup failed: System.Data.SqlClient.SqlException (0x80131904): An attempt to attach an auto-named database for file C:\Users\terry.sansom\AppData\Local\NCrunch\8428\31\TestResults\bb89c3d7-2699-410d-bbc9-2bc0e38ad722\Out\Resources\MdmTestDb.mdf failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share.

TerryS
#10 Posted : Monday, July 29, 2013 9:06:37 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 7/22/2013(UTC)
Posts: 8
Location: United States of America

Thanks: 1 times
Some success. I added the attributes :

[DeploymentItem(@"Resources\MdmTestDb.mdf", "Resources")]
[DeploymentItem(@"Resources\MdmTestDb.ldf", "Resources")]

To the first class in the test project, and that seems to work, however, the ideal solution would be to have the attributes work on the method decorated with [AssemblyInitialize]
but that does not seem to work.
Remco
#11 Posted : Monday, July 29, 2013 10:50:24 PM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 6,979

Thanks: 931 times
Was thanked: 1257 time(s) in 1170 post(s)
Thanks Terry, you've found the hole :)

NCrunch doesn't handle these attributes on the AssemblyInitialize method. I'll note this down for a fix. Thanks for your help in troubleshooting this!

To work around this, you may wish to consider referencing the .mdf file directly using relative paths that reach outside the MSTest working directory. If you can reference the file without needing the DeploymentItem attributes, you can then avoid needing to specify these on every test in your project.
TerryS
#12 Posted : Tuesday, July 30, 2013 5:11:28 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 7/22/2013(UTC)
Posts: 8
Location: United States of America

Thanks: 1 times
On a further note,
when I add

AppDomain.CurrentDomain.SetData("DataDirectory", dataDirectory);

to a test class method with the [TestInitialize] attribute the class will find and use the Database, however when I do this on the method marked with
[AssemblyInitialize] the classes are unable to find the databases - does the DataDirectory item get reset?
Remco
#13 Posted : Tuesday, July 30, 2013 10:34:03 PM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 6,979

Thanks: 931 times
Was thanked: 1257 time(s) in 1170 post(s)
Yes - NCrunch will specifically set it before each individual test run. It looks like this is also different to the behaviour in MSTest 2012, which sets it only at the beginning of the test run. I've also noted this down for a fix. You may wish to replace the DataDirectory with something else (perhaps a manually coded file path) until this can be resolved. Sorry for the trouble.
TerryS
#14 Posted : Tuesday, July 30, 2013 11:25:19 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 7/22/2013(UTC)
Posts: 8
Location: United States of America

Thanks: 1 times
Here is what I have done...
I created a base test class, which all our other DB test classes will inherit from.
[TestClass]
public class RepositoryBaseTests
{
[TestInitialize]
public virtual void TestInitialize()
{
//-- Set the DataDirectory for NCrunch
if (NCrunchEnvironment.NCrunchIsResident())
{
AppDomain.CurrentDomain.SetData("DataDirectory", dataDirectory);
}
}
}

(Made it virtual to support the case where an override may be required.)

That seems to have it licked.
Remco
#15 Posted : Tuesday, July 30, 2013 11:38:30 PM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 6,979

Thanks: 931 times
Was thanked: 1257 time(s) in 1170 post(s)
Nicely done! This will do the trick. Thanks again for reporting these problems.
1 user thanked Remco for this useful post.
TerryS on 7/31/2013(UTC)
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.078 seconds.
Trial NCrunch
Take NCrunch for a spin
Do your fingers a favour and supercharge your testing workflow
Free Download