Nunit-console: Error: Found two different objects associated with the same URI, /xxxxx/TestAgency

Created on 4 May 2020  路  14Comments  路  Source: nunit/nunit-console

I am using Nunit API in my application to run test cases.
When more than one thread of execution reaches at this point
runner = engine.GetRunner(package);
I get this error: Found two different objects associated with the same URI, /xxxxx/TestAgency

Looks like engine is not able to provide more than one runner to run testcases.

done bug normal

Most helpful comment

Yes. In the prototype, the console process starts listening on a TCP port that is randomly assigned by the OS and then starts the agent process with a CLI argument telling it to connect to that port. The only conflict would be if you ran out of free ports (65k total).

All 14 comments

Perhaps you could show a bit more code. The creation of a new Runner, using GetRunner doesn't cause a new TestAgency service to be created. OTOH, if you are creating multiple __engines__ that problem might arise.

yes, here is the piece of code which is executed for each thread

ITestRunner runner = null;
ITestEngine engine = null;

engine = TestEngineActivator.CreateInstance();
runner = engine.GetRunner(package);
result = runner.Run(new NullListener(), filter);

The engine was designed originally with a Windows Service in mind. So it was never intended to have multiple instances on the same machine. It's still odd, however, that you get multiple test runners with the same address, since the code should search for an available address. There may be a race condition involved.

OTOH it was envisioned that there could be multiple runners so you may get better luck by sharing access to an engine and getting a diffeent runner per thread. I have to tell you that this is not a scenario we have spent much time on, however.

I assume you are doing this in order to manage parallel execution in ways not supported by the NUnit framework. I'd be curious to know what you use case is.

We have developed a web portal to run test cases for applications hosted on various servers. For this portal we have developed a web service which utilizes Nunit API .

How our app works: User selects the server it wants to run the test for, the call is then routed to web service which will collect all the necessary information and provide it to Nunit engine and runner to run the test cases.

Use case: At a given time user may want to initiate call for more than one server so each call then can be considered as separate thread trying to run different test cases for different server.
So its is for this use case we are trying to achieve parallel execution.

Right now I have to put the Nunit engine and runner code inside lock block as shown below, just putting engine creation statement or runner creation or both wont work. I get the exception: Found two different objects associated with the same URI, /xxxxx/TestAgency.

lock (nunitRunnerLock)
{
engine = TestEngineActivator.CreateInstance();
runner = engine.GetRunner(package);
result = runner.Run(new NullListener(), filter);
CleanupNunitRunner(runner, engine);
}

Putting result = runner.Run(new NullListener(), filter); inside lock block is expensive as its when nunit will start executing test cases, so other requests will have to wait until entire set of test cases for a sever has been completed resulting in a long wait time.

We are planning to add more servers and are concerned about the performance.

The guys at Plastic SCM developed pnUnit a number of years ago. I was able to find an article by googling but no active download link. They modified NUnit V2 to work with a network of connected machines and the NUnitV2 repo contanis source for some versions of what they did. Here's the article I found: https://www.plasticscm.com/documentation/technical-articles/pnunit-parallel-nunit

They were considering releasing a new version as open source at one time, but I can't find it in their github organization.

Anyway, may be of some interest to you. I think they still use it today.

Thank You Charlie for the information.
Will there be any Nunit release sooner to accommodate parallel execution?

Also I was thinking about your comment : OTOH it was envisioned that there could be multiple runners so you may get better luck by sharing access to an engine and getting a different runner per thread. I have to tell you that this is not a scenario we have spent much time on.

If I can get different runner per thread then just having engine creation statement in lock block should work, something like this.

lock (nunitRunnerLock)
{
engine = TestEngineActivator.CreateInstance();
}
runner = engine.GetRunner(package);
result = runner.Run(new NullListener(), filter);
CleanupNunitRunner(runner, engine);

Is there something we should be doing differently to get unique runners ?

@pamle117 NUnit already has several forms of parallel execution, both within a single assembly and across different assemblies. But I think you mean parallel on separate machines. That has always been the plan for NUnit 3 and I believe it's still a goal. @ChrisMaddock can you confirm that?

I also plan to support networks of machines in my TestCentric projects,but I'm at least one major version upgrade away from implementing it.

Yes, we have harnessed parallel execution within assemblies and across assemblies and are wanting to run assemblies for different machines in parallel.
We would be definitely waiting eagerly for that release :)

But I think you mean parallel on separate machines. That has always been the plan for NUnit 3 and I believe it's still a goal. @ChrisMaddock can you confirm that?

Absolutely - although not in the immediate future. Our first goal is to move the engine-agent communication away from .NET remoting, which locks us into Windows, which @jnm2 is currently looking at. After that, I'd personally like to see us look at user-extensible test agents, which may end up permitting multi-machine running by default, I guess...

One other thought, this particular exception will actually go away once .NET remoting is replaced. Right, @jnm2?

Yes. In the prototype, the console process starts listening on a TCP port that is randomly assigned by the OS and then starts the agent process with a CLI argument telling it to connect to that port. The only conflict would be if you ran out of free ports (65k total).

That sounds great. When can we expect the release with this feature?

@pamle117 afraid that's not clear at the moment. Everyone working on NUnit is doing so voluntarily, so it all depends on how much time people have available and are willing to spend on the project. Follow this issue for updates: https://github.com/nunit/nunit-console/issues/266 馃檪

I will be following, thanks everyone for your help!

Was this page helpful?
0 / 5 - 0 ratings