RemotingException thrown when invoking remote object from NUnit
Asked Answered
S

0

11

I discovered a strange problem while playing with .Net Remoting and Mono.
When I invoke a remote object in code executed by NUnit this exception is thrown:

System.Runtime.Remoting.RemotingException : Cannot create channel sink to connect to URL 9cd3eef9_6e1f_4e0e_a4fe_0d43b3b0d157/2d2f9b_6.rem. An appropriate channel has probably not been registered. 
Stack trace:  
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke (System.Runtime.Remoting.Proxies.RealProxy rp, IMessage msg, System.Exception& exc, System.Object[]& out_args) [0x001e9] in /tmp/buildd/mono-4.0.1/mcs/class/corlib/System.Runtime.Remoting.Proxies/RealProxy.cs:249

When executing the exact same code from a Console application everything works fine.

Given this interface:

public interface IEchoService {
    string Echo(string message);
}

And a server hosting a implementation like this:

var serverProvider = new BinaryServerFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
var channel = new TcpServerChannel("RemotingTest", 4242, serverProvider);
ChannelServices.RegisterChannel(channel, false);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(HelloEchoService), "RemotingTest.rem", WellKnownObjectMode.Singleton);

This will cause the exception:

[Test]
public void SendEchoRequest()
{
    var chan = new TcpClientChannel();
    ChannelServices.RegisterChannel(chan, false);
    string url = "tcp://localhost:4242/RemotingTest.rem";
    var runner = (IEchoService)Activator.GetObject(typeof(IEchoService), url);
    string echoMessage = runner.Echo("World");
    Console.WriteLine(echoMessage);
    Assert.That(echoMessage, Is.EqualTo("Hello World"));
}

But when running it like this from Console Main it works:

new Program().SendEchoRequest();

The main difference between NUnit and Console that I can tell is the AppDomain. While in NUnit the code is executed in it is own child AppDomain the Console executes it in the DefaultAppDomain. However I haven't found anything difference while comparing this two AppDomains.

The error also occurs when running NUnit on a Windows machine but it DOES NOT when hosting the server on Windows. In this case both Linux and Windows NUnit runners can successfully execute the test.

After some debugging of the Mono BCL I found that the switch happens in System.Runtime.Serialization.Formatters.Binary/MessageFormatter.cs. At line 282 MethodFlags are read. When running in NUnit they are IncludesLogicalCallContext|PrimitiveArguments but when in Console ExcludeLogicalCallContext|PrimitiveArguments.
Because of this the if-statement at line 310 is entered where objectReader.ReadObjectGraph is executed which ultimately leads to the exception in System.Runtime.Remoting/RemotingServices.cs line 695

I created a sample solution for download which reproduces the problem: https://mega.co.nz/#!xYQkwBba!g-jOex-EXSP6e3JYgh-FoWi7VhXjF4e6i494lO4J5po

Just run the server via mono RemotingTest.Server.exe and then run the client test with MonoDevelop.

My testing environment is Ubuntu 15.04 x64 with Mono 4.0.1 from the official Mono repository.

Saccharase answered 30/5, 2015 at 19:8 Comment(2)
Whilst this is interesting, it reads like a bug report. Can you clarify what the question is that you are hoping somebody can answer?Astonishment
The question is if someone knows what exactly the issue is. Is it a bug in Mono or is it something I can change from the caller side?Saccharase

© 2022 - 2024 — McMap. All rights reserved.