Skip to content

Commit

Permalink
Modify TestEngineActivator to look for an NUnit.Engine package
Browse files Browse the repository at this point in the history
  • Loading branch information
CharliePoole committed Feb 29, 2016
1 parent beccef5 commit d2cfa7b
Showing 1 changed file with 32 additions and 0 deletions.
32 changes: 32 additions & 0 deletions src/NUnitEngine/nunit.engine.api/TestEngineActivator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,37 @@ private static Assembly FindNewestEngine(Version minVersion, bool privateCopy)
}
}

// Check for an engine that has been installed as part of a
// development project using NuGet.
//
// NOTE: This code assumes that we are working in
// bin/Debug or bin/Release and includes a lot of
// knowledge of how we handle nuget packages. It
// is only intended for use while a new runner is
// under development.
if (newestAssemblyFound == null)
{
var packages = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../packages");

This comment has been minimized.

Copy link
@jcansdale

jcansdale Jun 16, 2016

@CharliePoole I notice we're only looking for the packages directory two levels up. Might it be an idea to search all directories up from there (kind of like 'node_modules' works in the Node.js world)? This way projects could bring their own 'nunit.engine' version (handy if they start relying some up-level feature).

This comment has been minimized.

Copy link
@CharliePoole

CharliePoole Jun 16, 2016

Author Contributor

@jcansdale Hey! Nice to see you hanging around once again. :-)

That's a good thought. This whole area of finding the engine and its extensions is still a work in progress. This code was added to solve a specific problem we were having at the time. I'm going to be working on an issue in the next few days that relates to this, so you might get to review some code before it's merged!

This comment has been minimized.

Copy link
@CharliePoole

CharliePoole Jun 16, 2016

Author Contributor

Not sure however what you mean about projects bringing their own engine version. Currently, it's supported (as a private engine) but we take that to mean it's in the ApplicationBase.

This comment has been minimized.

Copy link
@jcansdale

jcansdale Jun 16, 2016

@CharliePoole It's nice to be back. I've been lurking for a while and getting to know Git/GitHub. You and @rprouse have been busy!

This comment has been minimized.

Copy link
@jcansdale

jcansdale Jun 16, 2016

Re: projects bringing their own engine. If someone included the NUnit.ConsoleRunner package with their solution, it seems reasonable to use that specific version (rather that whatever version a developer happens to have installed on their machine). That would make it much easier for people to start using a new NUnit version in a project. Currently wouldn't they have to make everyone update their installed version of NUnit?

Currently, it's supported (as a private engine) but we take that to mean it's in the ApplicationBase

This would indeed be different. It would look for the 'nunit.engine' assembly in 'packages/NUnit.ConsoleRunner.' rather than "packages/NUnit.Engine.". It would look in all of the directories above the ApplicationBase.

This comment has been minimized.

Copy link
@CharliePoole

CharliePoole Jun 16, 2016

Author Contributor

So you're talking about a project that both uses the engine (like a runner of some kind) and makes use of the Console.Runner package to run its tests? That's an unusual case, of course. Which engine got used would depend on what engine packages are available and what other engines are installed globally.

The user in this case could control what engine is used for the runner but not what is used for NUnit3-Console because the latter is written to use the best copy it can find.

This is all pretty old code - I think six months or more - and could change as a result of a few issues, particularly #1132.

NUnit3-Console does not use a private engine, in fact. It sets privateCopy to false when creating an engine instance.

This comment has been minimized.

Copy link
@jcansdale

jcansdale Jun 16, 2016

So you're talking about a project that both uses the engine (like a runner of some kind) and makes use of the Console.Runner package to run its tests?

I was thinking about a project that uses the ConsoleRunner as part of its build process, but who's developers also use other tools. Would it make sense for all of these tools to use the same 'nunit.engine' directory? This way the engine version and extensions would always be completely consistent.

NUnit3-Console does not use a private engine, in fact. It sets privateCopy to false when creating an engine instance.

I'd worry that an application that appears to be xcopy-deployed might behave differently on a machine that happens to have a newer version installed. Is this the kind of thins that should be considered as part of #1132?

This comment has been minimized.

Copy link
@CharliePoole

CharliePoole Jun 17, 2016

Author Contributor

So like TestDriven. :-) Sure, we should allow for that. I just don't know how you use the engine, if you package it, etc. so it's hard to relate.

So let's say I'm using both the console runner and testdriven in the same project? The version of the console runner I'm using should use the version of the engine it's designed to use. It specifies that when it creates an instance. The version of testdriven should clearly also use the engine it's designed for and should specify the same. We can't (either of us) really say that the two should use the same engine, because we can't control what the users have installed.

One limitation appears from this. Given the definition of "private" as "residing in the application base" two tools can't coexist in the same directory if they both specify they want a private engine. This isn't a problem if you install the tools using NuGet, because they don't end up in the same directory.

However, two tools decide to use two different engine packages, installed by nuget, then there will be two different engine packages in the packages directory. For that reason, and also because NuGet doesn't seem to remove old package directories on upgrade, we have an issue that says NUnit has to be a bit smarter about looking for extensions.

Yes, this is all part of #1132 and we should discuss it there when I get going on it. We've decided to only solve the most critical problems for 3.4 and deal with the rest of it later.

I'm not sure if you can say the engine is xcopy deployable. We don't think of it that way. It was designed from the beginning (2007!) with the idea that a runner would automatically use an upgraded version of the engine unless it actively refused to do so.

This comment has been minimized.

Copy link
@jcansdale

jcansdale Jun 17, 2016

Damn, it's tricky and NuGet doesn't make it any easier!

We can't (either of us) really say that the two should use the same engine, because we can't control what the users have installed.

You're absolutely right. It's one thing for the 'nunit.engine.api' to be compatible with later versions of 'nunit.engine', but quite another for it to guarantee compatibility with earlier versions. I can see how that would lock in the API and prevent us from evolving anything.

For that reason, and also because NuGet doesn't seem to remove old package directories on upgrade, we have an issue that says NUnit has to be a bit smarter about looking for extensions.

How to support extensions with NuGet seems to be a tricky problem in general!

I notice that that NUnit3 VS adapter uses its own private copy of 'nunit.engine':
https://github.com/nunit/nunit3-vs-adapter/blob/f56031ba7cb602c9e4e471ee422b86d28eb67dc1/src/NUnitTestAdapter/NUnitTestAdapter.cs#L95

Clever use of "extern alias ENG" BTW! I accidentally took some dependencies on 'nunit.engine' before I realized what was happening.

I think this is what I'll do with the TestDriven.Net adapter rather than experimenting with anything too fancy. Predictability is good. :)


if (Directory.Exists(packages))
{
var packagesDir = new DirectoryInfo(packages);
foreach (var subDir in packagesDir.GetDirectories("NUnit.Engine.*"))
{
// In future, we will use tools directory but currently we use lib
path = Path.Combine(Path.Combine(subDir.FullName, "tools"), DefaultAssemblyName);
newestAssemblyFound = CheckPathForEngine(path, minVersion, ref newestVersionFound, null);
if (newestAssemblyFound != null)
break;

path = Path.Combine(Path.Combine(subDir.FullName, "lib"), DefaultAssemblyName);
newestAssemblyFound = CheckPathForEngine(path, minVersion, ref newestVersionFound, null);
if (newestAssemblyFound != null)
break;
}
}
}

if (!privateCopy)
{
// Check the install for the current user, 32 bit process
Expand All @@ -134,6 +165,7 @@ private static Assembly FindNewestEngine(Version minVersion, bool privateCopy)
path = FindEngineInRegistry(Registry.LocalMachine, NunitInstallRegKeyWow64);
newestAssemblyFound = CheckPathForEngine(path, minVersion, ref newestVersionFound, newestAssemblyFound);
}

return newestAssemblyFound;
}

Expand Down

0 comments on commit d2cfa7b

Please sign in to comment.