// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. #if !NO_REMOTING using System; using System.Reactive.Linq; using System.Reflection; using System.Runtime.Remoting.Lifetime; using System.Threading; using Microsoft.Reactive.Testing; #if NUNIT using NUnit.Framework; using TestClassAttribute = NUnit.Framework.TestFixtureAttribute; using TestMethodAttribute = NUnit.Framework.TestAttribute; using TestInitializeAttribute = NUnit.Framework.SetUpAttribute; #else using Microsoft.VisualStudio.TestTools.UnitTesting; #endif namespace ReactiveTests.Tests { [TestClass] public partial class ObservableRemotingTest : ReactiveTest { [TestMethod] public void Remotable_ArgumentChecking() { ReactiveAssert.Throws(() => RemotingObservable.Remotable(default(IObservable))); ReactiveAssert.Throws(() => RemotingObservable.Remotable(default(IObservable), new MyLease())); ReactiveAssert.Throws(() => RemotingObservable.Remotable(default(IQbservable))); ReactiveAssert.Throws(() => RemotingObservable.Remotable(default(IQbservable), new MyLease())); RemotingObservable.Remotable(Observable.Return(42)); RemotingObservable.Remotable(Observable.Return(42), null /* valid lease object */); #if !NO_REFLECTION_EMIT RemotingObservable.Remotable(Qbservable.Return(Qbservable.Provider, 42)); RemotingObservable.Remotable(Qbservable.Return(Qbservable.Provider, 42), null /* valid lease object */); #endif } class MyLease : ILease { public TimeSpan CurrentLeaseTime { get { throw new NotImplementedException(); } } public LeaseState CurrentState { get { throw new NotImplementedException(); } } public TimeSpan InitialLeaseTime { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } public void Register(ISponsor obj) { throw new NotImplementedException(); } public void Register(ISponsor obj, TimeSpan renewalTime) { throw new NotImplementedException(); } public TimeSpan Renew(TimeSpan renewalTime) { throw new NotImplementedException(); } public TimeSpan RenewOnCallTime { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } public TimeSpan SponsorshipTimeout { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } public void Unregister(ISponsor obj) { throw new NotImplementedException(); } } [TestMethod] public void Remotable_Empty() { var evt = new ManualResetEvent(false); var e = GetRemoteObservable(t => t.Empty()); using (e.Subscribe(_ => { Assert.Fail(); }, _ => { Assert.Fail(); }, () => { evt.Set(); })) { evt.WaitOne(); } } [TestMethod] public void Remotable_Return() { var evt = new ManualResetEvent(false); bool next = false; var e = GetRemoteObservable(t => t.Return(42)); using (e.Subscribe(value => { next = true; Assert.AreEqual(42, value); }, _ => { Assert.Fail(); }, () => { evt.Set(); })) { evt.WaitOne(); Assert.IsTrue(next); } } [TestMethod] public void Remotable_Return_LongLease() { var evt = new ManualResetEvent(false); bool next = false; var e = GetRemoteObservable(t => t.ReturnLongLease(42)); using (e.Subscribe(value => { next = true; Assert.AreEqual(42, value); }, _ => { Assert.Fail(); }, () => { evt.Set(); })) { evt.WaitOne(); Assert.IsTrue(next); } } [TestMethod] public void Remotable_Throw() { var ex = new InvalidOperationException("Oops!"); var evt = new ManualResetEvent(false); bool error = false; var e = GetRemoteObservable(t => t.Throw(ex)); using (e.Subscribe(value => { Assert.Fail(); }, err => { error = true; Assert.IsTrue(err is InvalidOperationException && err.Message == ex.Message); evt.Set(); }, () => { Assert.Fail(); })) { evt.WaitOne(); Assert.IsTrue(error); } } [TestMethod] public void Remotable_Disposal() { var test = GetRemoteTestObject(); test.Disposal().Subscribe().Dispose(); Assert.IsTrue(test.Disposed); } private IObservable GetRemoteObservable(Func> f) { var test = GetRemoteTestObject(); return f(test); } private RemotingTest GetRemoteTestObject() { var ads = new AppDomainSetup { ApplicationBase = Utils.GetTestBaseDirectory() }; var ad = AppDomain.CreateDomain("test", null, ads); var test = (RemotingTest)ad.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, "ReactiveTests.Tests.RemotingTest"); return test; } } public class RemotingTest : MarshalByRefObject { public override object InitializeLifetimeService() { return null; } public IObservable Empty() { return Observable.Empty().Remotable(); } public IObservable Return(int value) { return Observable.Return(value).Remotable(); } public IObservable ReturnLongLease(int value) { return Observable.Return(value).Remotable(null); } public IObservable Throw(Exception ex) { return Observable.Throw(ex).Remotable(); } public IObservable Disposal() { return Observable.Create(obs => { return () => { Disposed = true; }; }).Remotable(); } public bool Disposed { get; set; } } } #endif