// // System.Runtime.Remoting.RemotingServices NUnit V2.0 test class // // Author Jean-Marc ANDRE (jean-marc.andre@polymtl.ca) // // ToDo: I didn't write test functions for the method not yep // implemented by Mono using System; using System.Collections; using NUnit.Framework; using System.Reflection; using System.Runtime.Remoting; using System.Threading; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Proxies; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; namespace MonoTests.System.Runtime.Remoting.RemotingServicesInternal { // We need our own proxy to intercept messages to remote object // and forward them using RemotingServices.ExecuteMessage public class MyProxy: RealProxy { MarshalByRefObject target; IMessageSink _sink; MethodBase _mthBase; bool methodOverloaded = false; public MethodBase MthBase { get{ return _mthBase;} } public bool IsMethodOverloaded { get{return methodOverloaded;} } public MyProxy(Type serverType, MarshalByRefObject target): base(serverType) { this.target = target; IChannel[] registeredChannels = ChannelServices.RegisteredChannels; string ObjectURI; // A new IMessageSink chain has to be created // since the RemotingServices.GetEnvoyChainForProxy() is not yet // implemented. foreach(IChannel channel in registeredChannels) { IChannelSender channelSender = channel as IChannelSender; if(channelSender != null) { _sink = (IMessageSink) channelSender.CreateMessageSink(RemotingServices.GetObjectUri(target), null, out ObjectURI); } } } // Messages will be intercepted here and redirected // to another object. public override IMessage Invoke(IMessage msg) { try { if(msg is IConstructionCallMessage) { IActivator remActivator = (IActivator) RemotingServices.Connect(typeof(IActivator), "tcp://localhost:1234/RemoteActivationService.rem"); IConstructionReturnMessage crm = remActivator.Activate((IConstructionCallMessage)msg); return crm; } else { methodOverloaded = RemotingServices.IsMethodOverloaded((IMethodMessage)msg); _mthBase = RemotingServices.GetMethodBaseFromMethodMessage((IMethodMessage)msg); MethodCallMessageWrapper mcm = new MethodCallMessageWrapper((IMethodCallMessage) msg); mcm.Uri = RemotingServices.GetObjectUri((MarshalByRefObject)target); MarshalByRefObject objRem = (MarshalByRefObject)Activator.CreateInstance(GetProxiedType()); RemotingServices.ExecuteMessage((MarshalByRefObject)objRem, (IMethodCallMessage)msg); IMessage rtnMsg = null; try { rtnMsg = _sink.SyncProcessMessage(msg); } catch(Exception e) { Console.WriteLine(e.Message); } Console.WriteLine ("RR:" + rtnMsg); return rtnMsg; } } catch (Exception ex) { Console.WriteLine (ex); return null; } } } // end MyProxy // This class is used to create "CAO" public class MarshalObjectFactory: MarshalByRefObject { public MarshalObject GetNewMarshalObject() { return new MarshalObject(); } } // A class used by the tests public class MarshalObject: ContextBoundObject { public MarshalObject() { } public MarshalObject(int id, string uri) { this.id = id; this.uri = uri; } public int Id { get{return id;} set{id = value;} } public string Uri { get{return uri;} } public void Method1() { _called++; methodOneWay = RemotingServices.IsOneWay(MethodBase.GetCurrentMethod()); } public void Method2() { methodOneWay = RemotingServices.IsOneWay(MethodBase.GetCurrentMethod()); } public void Method2(int i) { methodOneWay = RemotingServices.IsOneWay(MethodBase.GetCurrentMethod()); } [OneWay()] public void Method3() { methodOneWay = RemotingServices.IsOneWay(MethodBase.GetCurrentMethod()); } public static int Called { get{return _called;} } public static bool IsMethodOneWay { get{return methodOneWay;} } private static int _called; private int id = 0; private string uri; private static bool methodOneWay = false; } // Another class used by the tests public class DerivedMarshalObject: MarshalObject { public DerivedMarshalObject(){} public DerivedMarshalObject(int id, string uri): base(id, uri) {} } interface A { } interface B: A { } public class CC: MarshalByRefObject { } public class DD: MarshalByRefObject { } } // namespace MonoTests.System.Runtime.Remoting.RemotingServicesInternal namespace MonoTests.Remoting { using MonoTests.System.Runtime.Remoting.RemotingServicesInternal; // The main test class [TestFixture] public class RemotingServicesTest : Assertion { private static int MarshalObjectId = 0; public RemotingServicesTest() { MarshalObjectId = 0; } // Helper function that create a new // MarshalObject with an unique ID private static MarshalObject NewMarshalObject() { string uri = "MonoTests.System.Runtime.Remoting.RemotingServicesTest.MarshalObject" + MarshalObjectId.ToString(); MarshalObject objMarshal = new MarshalObject(MarshalObjectId, uri); MarshalObjectId++; return objMarshal; } // Another helper function private DerivedMarshalObject NewDerivedMarshalObject() { string uri = "MonoTests.System.Runtime.Remoting.RemotingServicesTest.DerivedMarshalObject" + MarshalObjectId.ToString(); DerivedMarshalObject objMarshal = new DerivedMarshalObject(MarshalObjectId, uri); MarshalObjectId++; return objMarshal; } // The two folling method test RemotingServices.Marshal() [Test] public void Marshal1() { MarshalObject objMarshal = NewMarshalObject(); ObjRef objRef = RemotingServices.Marshal(objMarshal); Assert("#A01", objRef.URI != null); MarshalObject objRem = (MarshalObject) RemotingServices.Unmarshal(objRef); AssertEquals("#A02", objMarshal.Id, objRem.Id); objRem.Id = 2; AssertEquals("#A03", objMarshal.Id, objRem.Id); // TODO: uncomment when RemotingServices.Disconnect is implemented //RemotingServices.Disconnect(objMarshal); objMarshal = NewMarshalObject(); objRef = RemotingServices.Marshal(objMarshal, objMarshal.Uri); Assert("#A04", objRef.URI.EndsWith(objMarshal.Uri)); // TODO: uncomment when RemotingServices.Disconnect is implemented //RemotingServices.Disconnect(objMarshal); } [Test] public void Marshal2() { DerivedMarshalObject derivedObjMarshal = NewDerivedMarshalObject(); ObjRef objRef = RemotingServices.Marshal(derivedObjMarshal, derivedObjMarshal.Uri, typeof(MarshalObject)); // Check that the type of the marshaled object is MarshalObject Assert("#A05", objRef.TypeInfo.TypeName.StartsWith((typeof(MarshalObject)).ToString())); // TODO: uncomment when RemotingServices.Disconnect is implemented //RemotingServices.Disconnect(derivedObjMarshal); } // Tests RemotingServices.GetObjectUri() [Test] public void GetObjectUri() { MarshalObject objMarshal = NewMarshalObject(); Assert("#A06", RemotingServices.GetObjectUri(objMarshal) == null); RemotingServices.Marshal(objMarshal); Assert("#A07", RemotingServices.GetObjectUri(objMarshal) != null); // TODO: uncomment when RemotingServices.Disconnect is implemented //RemotingServices.Disconnect(objMarshal); } // Tests RemotingServices.Connect [Test] public void Connect() { MarshalObject objMarshal = NewMarshalObject(); IDictionary props = new Hashtable(); props["name"] = objMarshal.Uri; props["port"] = 1236; TcpChannel chn = new TcpChannel(props, null, null); ChannelServices.RegisterChannel(chn); RemotingServices.Marshal(objMarshal,objMarshal.Uri); MarshalObject objRem = (MarshalObject) RemotingServices.Connect(typeof(MarshalObject), "tcp://localhost:1236/" + objMarshal.Uri); Assert("#A08", RemotingServices.IsTransparentProxy(objRem)); ChannelServices.UnregisterChannel(chn); RemotingServices.Disconnect(objMarshal); } // Tests RemotingServices.Marshal() [Test] [ExpectedException(typeof(RemotingException))] public void MarshalThrowException() { MarshalObject objMarshal = NewMarshalObject(); IDictionary props = new Hashtable(); props["name"] = objMarshal.Uri; props["port"] = 1237; TcpChannel chn = new TcpChannel(props, null, null); ChannelServices.RegisterChannel(chn); RemotingServices.Marshal(objMarshal,objMarshal.Uri); MarshalObject objRem = (MarshalObject) RemotingServices.Connect(typeof(MarshalObject), "tcp://localhost:1237/" + objMarshal.Uri); // This line sould throw a RemotingException // It is forbidden to export an object which is not // a real object try { RemotingServices.Marshal(objRem, objMarshal.Uri); } catch(Exception e) { ChannelServices.UnregisterChannel(chn); // TODO: uncomment when RemotingServices.Disconnect is implemented //RemotingServices.Disconnect(objMarshal); throw e; } } // Tests RemotingServices.ExecuteMessage() // also tests GetMethodBaseFromMessage() // IsMethodOverloaded() [Test] public void ExecuteMessage() { TcpChannel chn = null; try { chn = new TcpChannel(1235); ChannelServices.RegisterChannel(chn); MarshalObject objMarshal = NewMarshalObject(); RemotingConfiguration.RegisterWellKnownServiceType(typeof(MarshalObject), objMarshal.Uri, WellKnownObjectMode.SingleCall); // use a proxy to catch the Message MyProxy proxy = new MyProxy(typeof(MarshalObject), (MarshalObject) Activator.GetObject(typeof(MarshalObject), "tcp://localhost:1235/" + objMarshal.Uri)); MarshalObject objRem = (MarshalObject) proxy.GetTransparentProxy(); objRem.Method1(); // Tests RemotingServices.GetMethodBaseFromMethodMessage() AssertEquals("#A09","Method1",proxy.MthBase.Name); Assert("#A09.1", !proxy.IsMethodOverloaded); objRem.Method2(); Assert("#A09.2", proxy.IsMethodOverloaded); // Tests RemotingServices.ExecuteMessage(); // If ExecuteMessage does it job well, Method1 should be called 2 times AssertEquals("#A10", 2, MarshalObject.Called); } finally { if(chn != null) ChannelServices.UnregisterChannel(chn); } } // Tests the IsOneWay method [Test] public void IsOneWay() { TcpChannel chn = null; try { chn = new TcpChannel(1238); ChannelServices.RegisterChannel(chn); RemotingConfiguration.RegisterWellKnownServiceType(typeof(MarshalObject), "MarshalObject.rem", WellKnownObjectMode.Singleton); MarshalObject objRem = (MarshalObject) Activator.GetObject(typeof(MarshalObject), "tcp://localhost:1238/MarshalObject.rem"); Assert("#A10.1", RemotingServices.IsTransparentProxy(objRem)); objRem.Method1(); Thread.Sleep(20); Assert("#A10.2", !MarshalObject.IsMethodOneWay); objRem.Method3(); Thread.Sleep(20); Assert("#A10.3", MarshalObject.IsMethodOneWay); } finally { if(chn != null) ChannelServices.UnregisterChannel(chn); } } [Test] public void GetObjRefForProxy() { TcpChannel chn = null; try { chn = new TcpChannel(1239); ChannelServices.RegisterChannel(chn); // Register le factory as a SAO RemotingConfiguration.RegisterWellKnownServiceType(typeof(MarshalObjectFactory), "MonoTests.System.Runtime.Remoting.RemotingServicesTest.Factory.soap", WellKnownObjectMode.Singleton); MarshalObjectFactory objFactory = (MarshalObjectFactory) Activator.GetObject(typeof(MarshalObjectFactory), "tcp://localhost:1239/MonoTests.System.Runtime.Remoting.RemotingServicesTest.Factory.soap"); // Get a new "CAO" MarshalObject objRem = objFactory.GetNewMarshalObject(); ObjRef objRefRem = RemotingServices.GetObjRefForProxy((MarshalByRefObject)objRem); Assert("#A11", objRefRem != null); } finally { if(chn != null) ChannelServices.UnregisterChannel(chn); } } // Tests GetRealProxy [Test] public void GetRealProxy() { TcpChannel chn = null; try { chn = new TcpChannel(1241); ChannelServices.RegisterChannel(chn); RemotingConfiguration.RegisterWellKnownServiceType(typeof(MarshalObject), "MonoTests.System.Runtime.Remoting.RemotingServicesTest.MarshalObject.soap", WellKnownObjectMode.Singleton); MyProxy proxy = new MyProxy(typeof(MarshalObject), (MarshalByRefObject)Activator.GetObject(typeof(MarshalObject), "tcp://localhost:1241/MonoTests.System.Runtime.Remoting.RemotingServicesTest.MarshalObject.soap")); MarshalObject objRem = (MarshalObject) proxy.GetTransparentProxy(); RealProxy rp = RemotingServices.GetRealProxy(objRem); Assert("#A12", rp != null); AssertEquals("#A13", "MonoTests.System.Runtime.Remoting.RemotingServicesInternal.MyProxy", rp.GetType().ToString()); } finally { if(chn != null) ChannelServices.UnregisterChannel(chn); } } // Tests SetObjectUriForMarshal() [Test] public void SetObjectUriForMarshal() { TcpChannel chn = null; try { chn = new TcpChannel(1242); ChannelServices.RegisterChannel(chn); MarshalObject objRem = NewMarshalObject(); RemotingServices.SetObjectUriForMarshal(objRem, objRem.Uri); RemotingServices.Marshal(objRem); objRem = (MarshalObject) Activator.GetObject(typeof(MarshalObject), "tcp://localhost:1242/"+objRem.Uri); Assert("#A14", objRem != null); } finally { if(chn != null) ChannelServices.UnregisterChannel(chn); } } // Tests GetServeurTypeForUri() [Test] public void GetServeurTypeForUri() { TcpChannel chn = null; Type type = typeof(MarshalObject); try { chn = new TcpChannel(1243); ChannelServices.RegisterChannel(chn); MarshalObject objRem = NewMarshalObject(); RemotingServices.SetObjectUriForMarshal(objRem, objRem.Uri); RemotingServices.Marshal(objRem); Type typeRem = RemotingServices.GetServerTypeForUri(RemotingServices.GetObjectUri(objRem)); AssertEquals("#A15", type, typeRem); } finally { if(chn != null) ChannelServices.UnregisterChannel(chn); } } // Tests IsObjectOutOfDomain // Tests IsObjectOutOfContext [Test] public void IsObjectOutOf() { TcpChannel chn = null; try { chn = new TcpChannel(1245); ChannelServices.RegisterChannel(chn); RemotingConfiguration.RegisterWellKnownServiceType(typeof(MarshalObject), "MarshalObject2.rem", WellKnownObjectMode.Singleton); MarshalObject objRem = (MarshalObject) Activator.GetObject(typeof(MarshalObject), "tcp://localhost:1245/MarshalObject2.rem"); Assert("#A16", RemotingServices.IsObjectOutOfAppDomain(objRem)); Assert("#A17", RemotingServices.IsObjectOutOfContext(objRem)); MarshalObject objMarshal = new MarshalObject(); Assert("#A18", !RemotingServices.IsObjectOutOfAppDomain(objMarshal)); Assert("#A19", !RemotingServices.IsObjectOutOfContext(objMarshal)); } finally { ChannelServices.UnregisterChannel(chn); } } [Test] public void ApplicationNameTest () { RemotingConfiguration.ApplicationName = "app"; TcpChannel chn = null; try { chn = new TcpChannel(1246); ChannelServices.RegisterChannel(chn); RemotingConfiguration.RegisterWellKnownServiceType(typeof(MarshalObject), "obj3.rem", WellKnownObjectMode.Singleton); MarshalObject objRem = (MarshalObject) Activator.GetObject(typeof(MarshalObject), "tcp://localhost:1246/app/obj3.rem"); MarshalObject objRem2 = (MarshalObject) Activator.GetObject(typeof(MarshalObject), "tcp://localhost:1246/obj3.rem"); Assert ("#AN1", RemotingServices.IsTransparentProxy(objRem)); Assert ("#AN2", RemotingServices.IsTransparentProxy(objRem2)); AssertNotNull ("#AN3", RemotingServices.GetServerTypeForUri ("obj3.rem")); AssertNotNull ("#AN4", RemotingServices.GetServerTypeForUri ("/app/obj3.rem")); AssertNull ("#AN5", RemotingServices.GetServerTypeForUri ("//app/obj3.rem")); AssertNull ("#AN6", RemotingServices.GetServerTypeForUri ("app/obj3.rem")); AssertNull ("#AN7", RemotingServices.GetServerTypeForUri ("/whatever/obj3.rem")); AssertNotNull ("#AN8", RemotingServices.GetServerTypeForUri ("/obj3.rem")); AssertNull ("#AN9", RemotingServices.GetServerTypeForUri ("//obj3.rem")); } finally { try { ChannelServices.UnregisterChannel(chn); } catch { } } } [Test] public void ConnectProxyCast () { object o; RemotingConfiguration.Configure (null); o = RemotingServices.Connect (typeof(MarshalByRefObject), "tcp://localhost:3434/ff1.rem"); Assert ("#m1", o is DD); Assert ("#m2", o is A); Assert ("#m3", o is B); Assert ("#m4", !(o is CC)); o = RemotingServices.Connect (typeof(A), "tcp://localhost:3434/ff3.rem"); Assert ("#a1", o is DD); Assert ("#a2", o is A); Assert ("#a3", o is B); Assert ("#a4", !(o is CC)); o = RemotingServices.Connect (typeof(DD), "tcp://localhost:3434/ff4.rem"); Assert ("#d1", o is DD); Assert ("#d2", o is A); Assert ("#d3", o is B); Assert ("#d4", !(o is CC)); o = RemotingServices.Connect (typeof(CC), "tcp://localhost:3434/ff5.rem"); Assert ("#c1", !(o is DD)); Assert ("#c2", o is A); Assert ("#c3", o is B); Assert ("#c4", o is CC); } // Don't add any tests that must create channels // after ConnectProxyCast (), because this test calls // RemotingConfiguration.Configure (). } // end class RemotingServicesTest } // end of namespace MonoTests.Remoting