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

Notification

Icon
Error

How to get a file copied to bin\Debug (/Release) for test projects?
GreenMoose
#1 Posted : Tuesday, September 16, 2014 10:24:20 AM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 6/17/2012(UTC)
Posts: 503

Thanks: 142 times
Was thanked: 66 time(s) in 64 post(s)
Hi,

Scenario: I have project "Domain" in which a file hibernate.cfg.xml is located. My test project requires this to be located inside same directory as the test dll (or process working directory) in order to find it.

What can I do to resolve this?

I've been trying to fiddle with the "additional files to include" both at solution level and project level. I tried putting dependency on the Domain project for the test project (both explicitly via vstudio and implicitly via NCrunch configuration) but I only get file ending up in the Domain project within the workspace, not inside bin\Debug (or bin\Release if that config is used).

Thanks.

p.s. When building with visual studio the hibernate.cfg.xml end up in bin\Debug, so previously I worked around it by use "additional files to include" per project to use bin\Debug path, but that fails when trying to incorporate it with console tool and TeamCity since I there only rely on NCrunch to do the building d.s.
Remco
#2 Posted : Tuesday, September 16, 2014 11:49:24 AM(UTC)
Rank: NCrunch Developer

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

Thanks: 931 times
Was thanked: 1257 time(s) in 1170 post(s)
The standard way to solve this is to enable the 'Copy referenced assemblies to workspace' setting for the test project, and down the dependency chain into the project containing the hibernate file. When this setting is enabled, NCrunch will copy the file in the same manner as a normal MSBuild action, eventually depositing it in the test project's bin directory.

Of course, this will have an impact on performance. So there may be a better way - it just depends upon how non-standard you want to get. Do you have any opportunity to run code before the XML file is read from the current directory? If so, it may be possible to locate the file and copy it during the test initialisation using the methods available on the NCrunch.Framework.Environment class.

GreenMoose
#3 Posted : Tuesday, September 16, 2014 11:57:20 AM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 6/17/2012(UTC)
Posts: 503

Thanks: 142 times
Was thanked: 66 time(s) in 64 post(s)
Remco;6401 wrote:
Of course, this will have an impact on performance. So there may be a better way - it just depends upon how non-standard you want to get. Do you have any opportunity to run code before the XML file is read from the current directory? If so, it may be possible to locate the file and copy it during the test initialisation using the methods available on the NCrunch.Framework.Environment class.

Hrm that might work. I'll give that a try, thanks. (I'm a bit reluctant doing the "easy route" via decreasing performance since currently the largest test project is taking over 30seconds to be built+"analyzed" by NCrunch on a RAMDrive which is a pain when developing).
Remco
#6 Posted : Tuesday, September 16, 2014 9:47:24 PM(UTC)
Rank: NCrunch Developer

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

Thanks: 931 times
Was thanked: 1257 time(s) in 1170 post(s)
Ok - Out of interest, how large is this 30s project in lines of code? And how long does it normally take for VS to build it?
GreenMoose
#7 Posted : Wednesday, September 17, 2014 11:58:18 AM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 6/17/2012(UTC)
Posts: 503

Thanks: 142 times
Was thanked: 66 time(s) in 64 post(s)
Remco;6404 wrote:
Ok - Out of interest, how large is this 30s project in lines of code? And how long does it normally take for VS to build it?

161 000 "code lines" and 64 000 "compiled lines" according to NCrunch metrics.

Changing one file in project result in 17-18s build time with Vstudio 2012.
Doing the same with NCrunch and server (local) and NUnit dynamic analysis I get Build Time 28s-30s and Analyze time 20s.
With static analysis I get what seems same build time 30s and no Analyze time.

(We tend to split it up into more projects as we go but then there's the isssue of a static NHibernate session factory which needs to reinitialize ~10s for every new process NCrunch starts which if we want to prevent requires us to pool more and more test runners if I understand it correctly to minimize waiting time for static initialization routines).
Remco
#8 Posted : Wednesday, September 17, 2014 10:04:05 PM(UTC)
Rank: NCrunch Developer

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

Thanks: 931 times
Was thanked: 1257 time(s) in 1170 post(s)
Thanks, this is really useful information to help with further optimisation. The difference in static vs dynamic analysis is particularly interesting.
GreenMoose
#4 Posted : Thursday, September 18, 2014 11:17:29 AM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 6/17/2012(UTC)
Posts: 503

Thanks: 142 times
Was thanked: 66 time(s) in 64 post(s)
GreenMoose;6402 wrote:
Remco;6401 wrote:
Of course, this will have an impact on performance. So there may be a better way - it just depends upon how non-standard you want to get. Do you have any opportunity to run code before the XML file is read from the current directory? If so, it may be possible to locate the file and copy it during the test initialisation using the methods available on the NCrunch.Framework.Environment class.

Hrm that might work. I'll give that a try, thanks. (I'm a bit reluctant doing the "easy route" via decreasing performance since currently the largest test project is taking over 30seconds to be built+"analyzed" by NCrunch on a RAMDrive which is a pain when developing).

Hrm but can I somehow via NCRunch framework determine which the intermediate test output dir is? I don't want to risk copying files to c:\windows\system32 or whatever "working directory" might be for the process.
Remco
#9 Posted : Thursday, September 18, 2014 11:56:10 AM(UTC)
Rank: NCrunch Developer

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

Thanks: 931 times
Was thanked: 1257 time(s) in 1170 post(s)
Your best bet is the NCrunch.Environment.GetAllAssemblyLocations method. This method will return the full file path of ALL assemblies included in the test application domain. It's possible for you to enumerate this list of files, find the output file from the project containing the NHibernate config file, then extract the directory of this file. The NHibernate config file will be in the same directory. This will be in one of the NCrunch workspaces. Give it a try inside a debugger and see if it helps.
1 user thanked Remco for this useful post.
GreenMoose on 9/18/2014(UTC)
GreenMoose
#10 Posted : Thursday, September 18, 2014 12:59:23 PM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 6/17/2012(UTC)
Posts: 503

Thanks: 142 times
Was thanked: 66 time(s) in 64 post(s)
Remco;6423 wrote:
Your best bet is the NCrunch.Environment.GetAllAssemblyLocations method. This method will return the full file path of ALL assemblies included in the test application domain. It's possible for you to enumerate this list of files, find the output file from the project containing the NHibernate config file, then extract the directory of this file. The NHibernate config file will be in the same directory. This will be in one of the NCrunch workspaces. Give it a try inside a debugger and see if it helps.

But then I get the source file, which is easy enough using above (or via GetOriginalSolutionPath), but how can I determine output path of the current test assembly in a general way? Is Assembly.GetExecutingAssembly().Location reliable in this scenario?
GreenMoose
#11 Posted : Thursday, September 18, 2014 2:42:16 PM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 6/17/2012(UTC)
Posts: 503

Thanks: 142 times
Was thanked: 66 time(s) in 64 post(s)
GreenMoose;6424 wrote:
Remco;6423 wrote:
Your best bet is the NCrunch.Environment.GetAllAssemblyLocations method. This method will return the full file path of ALL assemblies included in the test application domain. It's possible for you to enumerate this list of files, find the output file from the project containing the NHibernate config file, then extract the directory of this file. The NHibernate config file will be in the same directory. This will be in one of the NCrunch workspaces. Give it a try inside a debugger and see if it helps.

But then I get the source file, which is easy enough using above (or via GetOriginalSolutionPath), but how can I determine output path of the current test assembly in a general way? Is Assembly.GetExecutingAssembly().Location reliable in this scenario?

Nope using Assembly.GetExecutingAssembly().Location didn't work out since this returns the utility assembly having this code. Using System.Environment.CurrentDirectory seems to work, but can I trust NCrunch that this is always set to the test assembly location?
GreenMoose
#12 Posted : Thursday, September 18, 2014 3:07:25 PM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 6/17/2012(UTC)
Posts: 503

Thanks: 142 times
Was thanked: 66 time(s) in 64 post(s)
So if System.Environment.CurrentDirectory is safe to use, I have 2 additional issues:

For a log4net appender with NHibernate logs to work I need to have log4net.dll and NHibernate.dll in the same output directory. I assume this is the same problem I had with hibernate.cfg.xml, but what I don't get is:

1) What is "Additional files to include" meant to be used for? Why can't I reference my log4net.dll and NHibernate.dll at solution level by adding path e.g. "Externals\log4net.dll"?

2) When I alter configuration for a project, NCrunch creates a new workspace e.g. NCrunch\4972\152\, while the old NCrunch\4972\138\ is kept and content is identical. Is this a bug?

*Edit: When having to copy log4net.dll and NHibernate.dll manually it starts to get real ugly since they are using nuget... Am a bit stalled of how to proceed, it works fine if I force devstudio to build the solution and then use "additional files to include" from e.g. bin\debug but it feels a pity having to first build solution with vstudio to get console tool running.

*Edit2: And when manually copying files I get warnings like below:
Code:

The following references raised this warning, something to be concerned about or can I simply ignore them? 
E:\NCGNode\Workspaces\1544\370\Utils\Proj1\bin\Debug\log4net.DLL was expected to be loaded from E:\NCGNode\Workspaces\1544\370\_ncrunchreferences\log4net.dll
E:\NCGNode\Workspaces\1544\370\Utils\Proj1\bin\Debug\NHibernate.DLL was expected to be loaded from E:\NCGNode\Workspaces\1544\370\_ncrunchreferences\NHibernate.dll


*Edit3: And when trying with this solution I get fishy test failures like below
Code:

SetUp : System.MissingMethodException : Method not found: 'System.Collections.Generic.IList...

I think I need to get back to drawing board and compile entire project with vstudio as a first step before running it with NCrunch's console runner.
Remco
#13 Posted : Thursday, September 18, 2014 10:35:59 PM(UTC)
Rank: NCrunch Developer

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

Thanks: 931 times
Was thanked: 1257 time(s) in 1170 post(s)
GreenMoose;6426 wrote:

1) What is "Additional files to include" meant to be used for? Why can't I reference my log4net.dll and NHibernate.dll at solution level by adding path e.g. "Externals\log4net.dll"?


'Additional files to include' is needed to specify files that NCrunch should copy to the workspace. This is basically the same as referencing them in the project file. It isn't intended to be used to specify files that should exist in the build output directory - although this is technically possible by including files that are in the bin\debug directory in the foreground solution, I generally don't recommend this because it creates a dependency on the foreground build (though sometimes this is the easiest option).

GreenMoose;6426 wrote:

2) When I alter configuration for a project, NCrunch creates a new workspace e.g. NCrunch\4972\152\, while the old NCrunch\4972\138\ is kept and content is identical. Is this a bug?


This is by design. NCrunch can have many workspaces for a single project and will create new ones when it needs to.

GreenMoose;6426 wrote:

*Edit: When having to copy log4net.dll and NHibernate.dll manually it starts to get real ugly since they are using nuget... Am a bit stalled of how to proceed, it works fine if I force devstudio to build the solution and then use "additional files to include" from e.g. bin\debug but it feels a pity having to first build solution with vstudio to get console tool running.


A cleaner option is to include the DLL files using 'Additional files to include' from their original place in your solution (i.e. nuget packages directory). You can then include a PostBuildEvent to copy the files into $(ProjectDir)$(OutDir) so that they exist in the same directory as the output file. Set a condition on the PostBuildEvent so that it will only run under NCrunch - condition="$(NCrunch) == '1'". This will remove the dependency on the foreground build while still allowing the files to land in the right place.

GreenMoose;6426 wrote:

*Edit2: And when manually copying files I get warnings like below:
Code:

The following references raised this warning, something to be concerned about or can I simply ignore them? 
E:\NCGNode\Workspaces\1544\370\Utils\Proj1\bin\Debug\log4net.DLL was expected to be loaded from E:\NCGNode\Workspaces\1544\370\_ncrunchreferences\log4net.dll
E:\NCGNode\Workspaces\1544\370\Utils\Proj1\bin\Debug\NHibernate.DLL was expected to be loaded from E:\NCGNode\Workspaces\1544\370\_ncrunchreferences\NHibernate.dll



Yes. Placing the files manually (or via PostBuildEvent) inside the output directory manually will trigger NCrunch to show these warnings, as it causes the CLR to load assemblies from places that NCrunch isn't expecting. As long as the DLLs are binary-equivalent to the files NCrunch is trying to reference, you shouldn't experience any runtime problems here.

GreenMoose;6426 wrote:

*Edit3: And when trying with this solution I get fishy test failures like below
Code:

SetUp : System.MissingMethodException : Method not found: 'System.Collections.Generic.IList...

I think I need to get back to drawing board and compile entire project with vstudio as a first step before running it with NCrunch's console runner.



Try to avoid touching the files inside the workspaces manually, and make sure you don't copy around output files from other projects in your solution. Generally when I've seen this error occur, its because NCrunch is loading and resolving the wrong version of user-built assembly at runtime.
GreenMoose
#14 Posted : Friday, September 19, 2014 5:43:47 AM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 6/17/2012(UTC)
Posts: 503

Thanks: 142 times
Was thanked: 66 time(s) in 64 post(s)
Thanks. Looks like post build event is the way to go. Speaking of which, does NCrunch always run the Nuget pre build restore of packages like vstudio (making build times take a lot longer than when not restoring)?

>This is by design. NCrunch can have many workspaces for a single project and will create new ones when it needs to.

So something is still using the old workspace even though the new is identical or will these be cleaned only when I resync solution and/or restart vstudio?
Remco
#15 Posted : Friday, September 19, 2014 5:51:25 AM(UTC)
Rank: NCrunch Developer

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

Thanks: 931 times
Was thanked: 1257 time(s) in 1170 post(s)
GreenMoose;6428 wrote:
Thanks. Looks like post build event is the way to go. Speaking of which, does NCrunch always run the Nuget pre build restore of packages like vstudio (making build times take a lot longer than when not restoring)?


No. NCrunch will not perform an auto package restore, as this tends to use a large amount of disk space (through the multiple workspaces), and as you've described, it also slows down the build. The drawback is that if you don't have the packages restored at the time you enable NCrunch, you'll need to do a VS build to restore them before the engine can work.

GreenMoose;6428 wrote:

So something is still using the old workspace even though the new is identical or will these be cleaned only when I resync solution and/or restart vstudio?


Most likely the workspace is still in use by a test runner process that hasn't yet been terminated. NCrunch will clean up workspaces when it identifies that they can no longer be re-used. It will also clean them up when the engine is shut down or the IDE is closed.
GreenMoose
#16 Posted : Friday, September 19, 2014 6:40:22 AM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 6/17/2012(UTC)
Posts: 503

Thanks: 142 times
Was thanked: 66 time(s) in 64 post(s)
Remco;6429 wrote:
GreenMoose;6428 wrote:
Thanks. Looks like post build event is the way to go. Speaking of which, does NCrunch always run the Nuget pre build restore of packages like vstudio (making build times take a lot longer than when not restoring)?


No. NCrunch will not perform an auto package restore, as this tends to use a large amount of disk space (through the multiple workspaces), and as you've described, it also slows down the build. The drawback is that if you don't have the packages restored at the time you enable NCrunch, you'll need to do a VS build to restore them before the engine can work.

Hrm,which means, since I am in the process of integrating console tool with TeamCity, I need to "redesign" build behavior so I use nuget restore explicitly then to avoid dependency on pre-building with msbuild (with nuget.exe restore), which fortunately seems to be easy enough to solve.

Thanks.
Remco
#17 Posted : Friday, September 19, 2014 6:49:16 AM(UTC)
Rank: NCrunch Developer

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

Thanks: 931 times
Was thanked: 1257 time(s) in 1170 post(s)
GreenMoose;6430 wrote:

Hrm,which means, since I am in the process of integrating console tool with TeamCity, I need to "redesign" build behavior so I use nuget restore explicitly then to avoid dependency on pre-building with msbuild (with nuget.exe restore), which fortunately seems to be easy enough to solve.

Thanks.


I think this is a design oversight. It should be possible for NCrunch to build a solution on a fresh checkout from VCS on the build server. I'll make a note to see if there is a way this can be improved. Thanks for making me aware of it.
Remco
#18 Posted : Tuesday, November 25, 2014 1:59:01 AM(UTC)
Rank: NCrunch Developer

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

Thanks: 931 times
Was thanked: 1257 time(s) in 1170 post(s)
I've done some careful revision of this problem, and concluded that it likely isn't something that can be easily solved within NCrunch itself.

NCrunch's build behaviour is very different to a standard build. It requires the assemblies to exist prior to their dependencies being resolved by NCrunch (which happens during the load process). The project load step executed by NCrunch is designed to be very lightweight and is not intended for actions such as restoring Nuget packages.

The only feasible solution would be for NCrunch itself to initiate a packages restore as a special step prior to loading a solution on a build server. Because this step is environment-specific and is easy to manually add in most build environments anyway, I don't think this is something I'd like to add to the tool unless there is heavy demand for it. Adding a command-line call into nuget as a custom build step should be enough to resolve this issue for most people. If you'd like to see NCrunch tackle this as a feature, you're welcome to vote for it on uservoice.
GreenMoose
#19 Posted : Tuesday, November 25, 2014 5:39:16 AM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 6/17/2012(UTC)
Posts: 503

Thanks: 142 times
Was thanked: 66 time(s) in 64 post(s)
Thanks for feedback. Yeah nuget package issue is easily solvable by running nuget restore before starting the build via NCrunch.

(and I seem to require to build it via msbuild anyhow before invoking NCrunch so I can utilize the "copy dll from project output folder" since I can't solve the "MethodNotFound" exception when copying log4net.dll manually.)
mkamoski
#5 Posted : Tuesday, September 29, 2015 6:31:51 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 9/29/2015(UTC)
Posts: 1
Location: United States of America

Remco;6401 wrote:
The standard way to solve this is to enable the 'Copy referenced assemblies to workspace' setting for the test project, and down the dependency chain into the project containing the hibernate file. When this setting is enabled, NCrunch will copy the file in the same manner as a normal MSBuild action, eventually depositing it in the test project's bin directory.

Of course, this will have an impact on performance. So there may be a better way - it just depends upon how non-standard you want to get. Do you have any opportunity to run code before the XML file is read from the current directory? If so, it may be possible to locate the file and copy it during the test initialisation using the methods available on the NCrunch.Framework.Environment class.



FYI, using "copy referenced assemblies to workspace"="true" did not work for me.

I got the same error, as follows.

Message=Could not find a part of the path 'C:\Users\mkamoski\AppData\Local\NCrunch\1496\2\MyProjectName.Services.Blah.Test\bin\output\TestDataHibernate.cfg.xml'.

So then I set "copy referenced assemblies to workspace"="false" but manually set "additional files to include" and included "\bin\output\TestDataHibernate.cfg.xml" (which is a file that I had to manually put in that location because it did not exist in that exact location but it did exist in 2 other locations in the project, such as the bin root, but including from those locations did not copy them over to the nCrunch shadow compilation hive area) so that manual step worked but it would be good if nCrunch did not require a manual setting for this, especially since cfg.xml is pretty common for nHibernate and since nCrunch could auto-detect it in bin root, which is where it is by default. Etc. But it works.


(Version Info -- VS 2013 Pro, nCrunch lastest and greatest, downloaded today).
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.132 seconds.
Trial NCrunch
Take NCrunch for a spin
Do your fingers a favour and supercharge your testing workflow
Free Download