Unable to disable Shadow Copy

Bug #1084284 reported by Edouard Poor
10
This bug affects 2 people
Affects Status Importance Assigned to Milestone
NUnit Test Adapter
Triaged
Undecided
Unassigned

Bug Description

We've got tests that load DLLs dynamically, and the shadow copy mechanism within NUnit fails to copy these DLLs to the temporary directory where the test are run from.

The simple work around we've been using in NUnit (as well as Reshaprer's NUinit runner) is to disable shadow copy in the options.

The NUnit Test Adapter for Visual Studio doesn't allow us to disable Shadow Copy and therefore prevents our use of NUnit within Visual Studio 2012.

Could you add the ability to disable Shadow Copy to the adapter?

Tags: github
Revision history for this message
Charlie Poole (charlie.poole) wrote : Re: [Bug 1084284] [NEW] Unable to disable Shadow Copy

Currently, we don't support setting any run options in the adapter, so
that would be a prerequisite to dealing with this bug. There are
several other requests that require the same thing.

However, for this specific request, there is an additional issue.
Currently, we plan to drop support for disabling shadow copy entirely
in NUnit 3.0. Folks on the nunit-discuss mail list have been asked for
use cases that would require us to keep it and nothing credible has
come up so far. So... if you have a use case that requires this
feature, please explain it!

By a use case, what I mean is why do you need to disable shadow copy?
What doesn't work when you don't disable it?

Charlie

On Wed, Nov 28, 2012 at 3:11 PM, Edouard Poor
<email address hidden> wrote:
> Public bug reported:
>
> We've got tests that load DLLs dynamically, and the shadow copy
> mechanism within NUnit fails to copy these DLLs to the temporary
> directory where the test are run from.
>
> The simple work around we've been using in NUnit (as well as Reshaprer's
> NUinit runner) is to disable shadow copy in the options.
>
> The NUnit Test Adapter for Visual Studio doesn't allow us to disable
> Shadow Copy and therefore prevents our use of NUnit within Visual Studio
> 2012.
>
> Could you add the ability to disable Shadow Copy to the adapter?
>
> ** Affects: nunit-vs-adapter
> Importance: Undecided
> Status: New
>
> --
> You received this bug notification because you are subscribed to NUnit
> Extended Testing Platform.
> https://bugs.launchpad.net/bugs/1084284
>
> Title:
> Unable to disable Shadow Copy
>
> To manage notifications about this bug go to:
> https://bugs.launchpad.net/nunit-vs-adapter/+bug/1084284/+subscriptions

Revision history for this message
David Moore (jdmoore99) wrote :

We are also impacted by this issue. In our case we are also dynamically loading additional assemblies for our unit tests. If we have assembly A.UnitTests.dll, it will look for file A.UnitTests.dll.loader.config during [SetupFixture] for a list of additional dependencies to load.

This configuration file is in A.UnitTests.csproj and is marked as BuildAction=Content and "Copy always" so the configuration file is always built right next to A.UnitTests.dll. If Shadow Copying would honor that build action + bring such files along, I believe it might work.

If there is another way I can package or tag that .config file with my UnitTests so that the shadow copying process would know to bring A.UnitTests.dll.loader.config along with the .dll and .pdb, that would probably work for my case.

Like another poster on this topic, we have a large codebase and we've introduced this dynamic loading complication to avoid endless CopyLocal=True which drastically slows and destabilizes our builds. On our build servers we disable shadow copying for running our test suites both for performance reasons and because it broke for any of our unit tests that needed to perform dynamic loading. If you were to drop support for disabling shadow copying, we'd need a way to tell NUnit's shadow copying to bring along additional files side-by-side with the .dll.

Revision history for this message
Charlie Poole (charlie.poole) wrote : Re: [Bug 1084284] Re: Unable to disable Shadow Copy

The need to access files in the same directory as the test assembly is
the most commonly cited reason for disabling shadow copy. However,
this is spurious.

NUnit doesn't copy any assemblies: shadow copy is a function of .NET
itself. Consequently, the problem needs to be viewed as "How can I
access the file where it is?" rather than "How can I get the file
copied to where I think it should be?"

There are three ways to locate a file that is located in the same
directory as the assembly:

1) Use Assembly.Codebase - this will give you the location as a URI,
which you must then tranform to an appropriate path.

2) Use the current directory, which NUnit has historically set to
directory containing the executing test assembly. However, this may
not be true for future releases.

3) Use NUnit's TestContext.CurrentContext.TestDirectory, which is the
available in the most recent releases.

All of these approaches actually use Assembly.Codebase under the
covers, with NUnit doing the work of tranforming the URI correctly in
#2 and #3. The common approach of using Assembly.Location is
incorrect, unless you actually want the location of the shadow copy
cache.

Charlie

On Fri, Dec 28, 2012 at 5:09 AM, David Moore <email address hidden> wrote:
> We are also impacted by this issue. In our case we are also dynamically
> loading additional assemblies for our unit tests. If we have assembly
> A.UnitTests.dll, it will look for file A.UnitTests.dll.loader.config
> during [SetupFixture] for a list of additional dependencies to load.
>
> This configuration file is in A.UnitTests.csproj and is marked as
> BuildAction=Content and "Copy always" so the configuration file is
> always built right next to A.UnitTests.dll. If Shadow Copying would
> honor that build action + bring such files along, I believe it might
> work.
>
> If there is another way I can package or tag that .config file with my
> UnitTests so that the shadow copying process would know to bring
> A.UnitTests.dll.loader.config along with the .dll and .pdb, that would
> probably work for my case.
>
> Like another poster on this topic, we have a large codebase and we've
> introduced this dynamic loading complication to avoid endless
> CopyLocal=True which drastically slows and destabilizes our builds. On
> our build servers we disable shadow copying for running our test suites
> both for performance reasons and because it broke for any of our unit
> tests that needed to perform dynamic loading. If you were to drop
> support for disabling shadow copying, we'd need a way to tell NUnit's
> shadow copying to bring along additional files side-by-side with the
> .dll.
>
> --
> You received this bug notification because you are subscribed to NUnit
> Extended Testing Platform.
> https://bugs.launchpad.net/bugs/1084284
>
> Title:
> Unable to disable Shadow Copy
>
> To manage notifications about this bug go to:
> https://bugs.launchpad.net/nunit-vs-adapter/+bug/1084284/+subscriptions

Revision history for this message
Charlie Poole (charlie.poole) wrote :
Download full text (3.6 KiB)

@Edouard: The comments above were addressed to David, who described
needing to access files in the same directory as the assembly. Your
original bug didn't specify this, but if that's your problem, the same
solution will apply to you. I didn't question your need for
suppressing shadow copy originally, since there are extremely rare
cases where it is truly necessary. Generally, such cases involve not
owning the source code to some component that needs to access the
assembly directory and does it in a way that's incompatible with
shadow copy.

On Fri, Dec 28, 2012 at 8:15 AM, Charlie Poole <email address hidden> wrote:
> The need to access files in the same directory as the test assembly is
> the most commonly cited reason for disabling shadow copy. However,
> this is spurious.
>
> NUnit doesn't copy any assemblies: shadow copy is a function of .NET
> itself. Consequently, the problem needs to be viewed as "How can I
> access the file where it is?" rather than "How can I get the file
> copied to where I think it should be?"
>
> There are three ways to locate a file that is located in the same
> directory as the assembly:
>
> 1) Use Assembly.Codebase - this will give you the location as a URI,
> which you must then tranform to an appropriate path.
>
> 2) Use the current directory, which NUnit has historically set to
> directory containing the executing test assembly. However, this may
> not be true for future releases.
>
> 3) Use NUnit's TestContext.CurrentContext.TestDirectory, which is the
> available in the most recent releases.
>
> All of these approaches actually use Assembly.Codebase under the
> covers, with NUnit doing the work of tranforming the URI correctly in
> #2 and #3. The common approach of using Assembly.Location is
> incorrect, unless you actually want the location of the shadow copy
> cache.
>
> Charlie
>
> On Fri, Dec 28, 2012 at 5:09 AM, David Moore <email address hidden> wrote:
>> We are also impacted by this issue. In our case we are also dynamically
>> loading additional assemblies for our unit tests. If we have assembly
>> A.UnitTests.dll, it will look for file A.UnitTests.dll.loader.config
>> during [SetupFixture] for a list of additional dependencies to load.
>>
>> This configuration file is in A.UnitTests.csproj and is marked as
>> BuildAction=Content and "Copy always" so the configuration file is
>> always built right next to A.UnitTests.dll. If Shadow Copying would
>> honor that build action + bring such files along, I believe it might
>> work.
>>
>> If there is another way I can package or tag that .config file with my
>> UnitTests so that the shadow copying process would know to bring
>> A.UnitTests.dll.loader.config along with the .dll and .pdb, that would
>> probably work for my case.
>>
>> Like another poster on this topic, we have a large codebase and we've
>> introduced this dynamic loading complication to avoid endless
>> CopyLocal=True which drastically slows and destabilizes our builds. On
>> our build servers we disable shadow copying for running our test suites
>> both for performance reasons and because it broke for any of our unit
>> tests that needed to perform dynamic loading. If you were to drop
>...

Read more...

Revision history for this message
David Moore (jdmoore99) wrote :

Thanks very much - I'll try these suggestions and post the results.

Revision history for this message
David Moore (jdmoore99) wrote :

Charlie,

Switching to Assembly.CodeBase as you suggested got things working well for us with the NUnit adapter. Thanks for taking the time to explain what wasn't a bug or problem with NUnit at all. I really appreciate it.

In the bigger picture of NUnit 3.0 taking away the ability to disable shadow copies, I'll poll a few co-workers and try to contribute some concrete concerns around our experiences when we run large test suites on our build servers.

Regards,
Dave

Revision history for this message
Rob Prouse (m-rob) wrote :

We need to disable shadow copying to access legacy code in native DLLs. We have a very large native C++ code base that cannot be rewritten or even extensively refactored. All of our applications are now written in C# and we have written a layer between the C# application and the native DLLs using managed C++.

(C# Application) -> (C++/CLR Interface) -> (C++ Legacy DLLs)

When we shadow copy, all the referenced assemblies get pulled in, but none of the native assemblies do and therefore fail to load.

Any suggestions on how to get around this without shadow copy?

Revision history for this message
Ruedi Gabriel (ruedi-gabriel) wrote :

We have exactly the same situation. A 3rd party .NET assembly tries to dynamically load an interop assemply which is not copied to the execution directory.
For that reason we use the disable shallow copy option in the nUnit runner!

Changed in nunit-vs-adapter:
milestone: none → 2.0
Revision history for this message
Charlie Poole (charlie.poole) wrote :

Moved to https://github.com/nunit/nunit-vs-adapter/issues/8 and marked Won't Fix here.

Changed in nunit-vs-adapter:
status: New → Won't Fix
milestone: 2.0 → none
Changed in nunit-vs-adapter:
status: Won't Fix → Triaged
tags: added: github
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.