I have changed the setup of our projects recently (mainly in order to accommodate NCrunch). Since then we lost the ability to run tests in different languages.
Before:
One solution that contained:
- native (C++/CLI) project
- a localization assembly with satellite assemblies.
- projects that consume the above
After:
Two solutions.
The native project and the localization projects are in the first one and they produce nuget packages.
Projects in the second solution consume the packages (from the local HDD, not from Nuget feed).
Since then only the main assembly is copied into the NCrunch workspace. The tests don't find the satellite assemblies and run under the default language (English).
The reason for the reorganization was to avoid having to compile the native bits on the NCrunch nodes.
Do you have any suggestion how to deal with this?
Thanks in advance,
Csaba
Remco NCrunch Developer
#9303
14 Oct 2016 22:43 UTC
Hi Csaba,
This specific problem is called an 'assembly co-location assumption'. Basically, your code is relying on referenced assemblies being co-located with other assemblies. NCrunch's build optimisations normally prevent this from happening because such an arrangement requires entire dependency chains to be built when changes are made to individual projects; which is extremely inefficient.
If the projects are referencing each other, you can use the 'Copy referenced assemblies to workspace' to solve this problem. Though it is often still better to design the tests in such a way that this setting would be unnecessary.
For more details on this problem see http://www.ncrunch.net/documentation/considerations-and-constraints_assembly-colocation-assumptions.
For an example of how to solve it using runtime code, see http://www.ncrunch.net/documentation/troubleshooting_tests-that-build-their-own-appdomains.
The implicit project dependencies setting can be very useful when working with projects that don't actually reference each other but still implicitly use output assemblies.
This specific problem is called an 'assembly co-location assumption'. Basically, your code is relying on referenced assemblies being co-located with other assemblies. NCrunch's build optimisations normally prevent this from happening because such an arrangement requires entire dependency chains to be built when changes are made to individual projects; which is extremely inefficient.
If the projects are referencing each other, you can use the 'Copy referenced assemblies to workspace' to solve this problem. Though it is often still better to design the tests in such a way that this setting would be unnecessary.
For more details on this problem see http://www.ncrunch.net/documentation/considerations-and-constraints_assembly-colocation-assumptions.
For an example of how to solve it using runtime code, see http://www.ncrunch.net/documentation/troubleshooting_tests-that-build-their-own-appdomains.
The implicit project dependencies setting can be very useful when working with projects that don't actually reference each other but still implicitly use output assemblies.
Hi Remco, I read through these articles carefully again and experimented a bit and I think I understand the situation a bit better now.
As I mentioned, the satellite assemblies were loaded fine before my refactoring. Back then, they were added as project reference.
They don't work now, after I added them as a Nuget package.
As far as I can see, the main localization assembly ("X.Y.Localization.dll") is copied from the nuget package into the '_ncrunchreferences' folder and it is loaded from there. However, the satellite assemblies ('de/X.Y.Localization.resources.dll') are not copied in. I think this should be handled by NCrunch automatically.
For now, I can make a nasty hack around this using a custom assembly resolution, but I think this is an NCrunch bug and it would be nice to see a fix for this.
As I mentioned, the satellite assemblies were loaded fine before my refactoring. Back then, they were added as project reference.
They don't work now, after I added them as a Nuget package.
As far as I can see, the main localization assembly ("X.Y.Localization.dll") is copied from the nuget package into the '_ncrunchreferences' folder and it is loaded from there. However, the satellite assemblies ('de/X.Y.Localization.resources.dll') are not copied in. I think this should be handled by NCrunch automatically.
For now, I can make a nasty hack around this using a custom assembly resolution, but I think this is an NCrunch bug and it would be nice to see a fix for this.
Remco NCrunch Developer
#9309
16 Oct 2016 21:38 UTC
Hi Csaba,
I'm glad you found a workaround that allows you to get NCrunch working in this scenario, though I'm not sure what change could be made to NCrunch to handle such a situation automatically.
If I understand this situation correctly, the X.Y.Location.resources.dll file is referenced implicitly by your code. There is no binding between your projects and these files, so there is no way for NCrunch to reliably know that the file needs to be co-located with the other assemblies. The only way I could think of such a situation being handled automatically would be for NCrunch to perform wildcard copies of all files in the output directory, which is very dangerous as it could result in files being copied that should not be copied, and may result in compatibility problems for other users.
I'm glad you found a workaround that allows you to get NCrunch working in this scenario, though I'm not sure what change could be made to NCrunch to handle such a situation automatically.
If I understand this situation correctly, the X.Y.Location.resources.dll file is referenced implicitly by your code. There is no binding between your projects and these files, so there is no way for NCrunch to reliably know that the file needs to be co-located with the other assemblies. The only way I could think of such a situation being handled automatically would be for NCrunch to perform wildcard copies of all files in the output directory, which is very dangerous as it could result in files being copied that should not be copied, and may result in compatibility problems for other users.
Hi Remco,
That is correct. It is an "implicit reference", inherited from the reference to the main localization assembly. But it's an implicit reference with well defined rules: https://msdn.microsoft.com/en-us/library/21a15yht(v=vs.110).aspx
Yes, of course, copying all the files is not desirable. However, the referenced assembly and the satellite assemblies are a "single" unit.
Anyways, I have implemented a workaround for my tests. It is a hack, and I'm not happy about it, but we are talking about non-production test code, so perhaps it's fine for the time being.
I am enjoying the power of NCrunch in a million other ways, so I'm still a happy customer. :)
Cheers,
Csaba
Remco wrote:
If I understand this situation correctly, the X.Y.Location.resources.dll file is referenced implicitly by your code. There is no binding between your projects and these files, so there is no way for NCrunch to reliably know that the file needs to be co-located with the other assemblies.
That is correct. It is an "implicit reference", inherited from the reference to the main localization assembly. But it's an implicit reference with well defined rules: https://msdn.microsoft.com/en-us/library/21a15yht(v=vs.110).aspx
Remco wrote:
The only way I could think of such a situation being handled automatically would be for NCrunch to perform wildcard copies of all files in the output directory, which is very dangerous as it could result in files being copied that should not be copied, and may result in compatibility problems for other users.
Yes, of course, copying all the files is not desirable. However, the referenced assembly and the satellite assemblies are a "single" unit.
Anyways, I have implemented a workaround for my tests. It is a hack, and I'm not happy about it, but we are talking about non-production test code, so perhaps it's fine for the time being.
I am enjoying the power of NCrunch in a million other ways, so I'm still a happy customer. :)
Cheers,
Csaba
Remco NCrunch Developer
#9313
16 Oct 2016 23:17 UTC
CsabaFabian wrote:
That is correct. It is an "implicit reference", inherited from the reference to the main localization assembly. But it's an implicit reference with well defined rules: https://msdn.microsoft.com/en-us/library/21a15yht(v=vs.110).aspx
Excellent. I wasn't aware of this. As the rules are well defined, there may be something I can do here. I'll make a note to take a closer look :)
CsabaFabian wrote:
Anyways, I have implemented a workaround for my tests. It is a hack, and I'm not happy about it, but we are talking about non-production test code, so perhaps it's fine for the time being.
I am enjoying the power of NCrunch in a million other ways, so I'm still a happy customer. :)
Fantastic! Thanks!
Post a reply
Log in to reply.