// // MonoTests.System.Runtime.Remoting.SynchronizationAttributeTest.cs // // Author: Lluis Sanchez Gual (lluis@ximian.com) // // 2003 (C) Copyright, Novell, Inc. // using System; using System.Threading; using System.Runtime.Remoting.Contexts; using NUnit.Framework; namespace MonoTests.System.Runtime.Remoting { enum SynchRes { SameSync, NewSync, NoSync } class SincroBase: ContextBoundObject { public int idx = 0; public bool CheckConcurrency () { int t = idx; for (int n=0; n<40; n++) { idx++; Thread.Sleep (25); } return (t+40 != idx); } public bool CheckUnlockedConcurrency () { Lock (false); return CheckConcurrency (); } public SynchRes CheckContext (Context ctx) { object otherp = ctx.GetProperty ("Synchronization"); object thisp = Thread.CurrentContext.GetProperty ("Synchronization"); if (thisp == null) return SynchRes.NoSync; if (thisp == otherp) return SynchRes.SameSync; return SynchRes.NewSync; } public SynchRes CheckContextTransition (Type type) { SincroBase bob = (SincroBase)Activator.CreateInstance (type); return bob.CheckContext (Thread.CurrentContext); } public bool CheckCalloutConcurrency (SincroBase bob) { bool res = bob.CheckConcurrency (); return res; } public void CheckLock1 () { Thread.Sleep (2000); Lock (false); Thread.Sleep (6000); } public void CheckLock2 () { Thread.Sleep (1000); Lock (true); Thread.Sleep (2000); } public void Lock (bool b) { SynchronizationAttribute thisp = (SynchronizationAttribute) Thread.CurrentContext.GetProperty ("Synchronization"); thisp.Locked = b; } public bool GetLocked () { SynchronizationAttribute thisp = (SynchronizationAttribute) Thread.CurrentContext.GetProperty ("Synchronization"); return thisp.Locked; } public bool CheckMonitorWait (bool exitContext) { lock (this) { return Monitor.Wait (this, 1000, exitContext); } } public void CheckMonitorPulse () { lock (this) { Monitor.Pulse (this); } } } [Synchronization (SynchronizationAttribute.SUPPORTED)] class SincroSupported: SincroBase { } [Synchronization (SynchronizationAttribute.REQUIRED)] class SincroRequired: SincroBase { } [Synchronization (SynchronizationAttribute.REQUIRES_NEW)] class SincroRequiresNew: SincroBase { public bool TestCallback () { SincroNotSupported bob = new SincroNotSupported (); return bob.CallBack (this); } } [Synchronization (SynchronizationAttribute.NOT_SUPPORTED)] class SincroNotSupported: SincroBase { public bool CallBack (SincroRequiresNew bob) { return bob.CheckConcurrency (); } } [Synchronization (SynchronizationAttribute.REQUIRES_NEW, true)] class SincroRequiresNewReentrant: SincroBase { } [TestFixture] // http://bugzilla.ximian.com/show_bug.cgi?id=72576 [Category ("NotWorking")] public class SynchronizationAttributeTest: Assertion { SincroRequiresNew sincob = new SincroRequiresNew (); SincroNotSupported notsup = new SincroNotSupported (); SincroRequiresNewReentrant reentrant = new SincroRequiresNewReentrant (); SincroRequiresNew notreentrant = new SincroRequiresNew (); bool otResult; [Test] public void TestSynchronization () { Thread tr = new Thread (new ThreadStart (FirstSyncThread)); tr.Start (); Thread.Sleep (200); SecondSyncThread (); tr.Join (); Assert ("Concurrency detected in FirstSyncThread", !otResult); } void FirstSyncThread () { otResult = sincob.CheckConcurrency (); } void SecondSyncThread () { bool concurrent = sincob.CheckConcurrency (); Assert ("Concurrency detected", !concurrent); } [Test] public void TestSupported () { SincroRequiresNew ob = new SincroRequiresNew (); SynchRes res = ob.CheckContextTransition (typeof(SincroSupported)); Assert ("Synchronizaton context expected", res == SynchRes.SameSync); SincroSupported ob2 = new SincroSupported (); res = ob2.CheckContext (Thread.CurrentContext); Assert ("Synchronizaton context not expected", res == SynchRes.NoSync); } [Test] public void TestRequired () { SincroRequiresNew ob = new SincroRequiresNew (); SynchRes res = ob.CheckContextTransition (typeof(SincroRequired)); Assert ("Synchronizaton context expected 1", res == SynchRes.SameSync); SincroRequired ob2 = new SincroRequired (); res = ob2.CheckContext (Thread.CurrentContext); Assert ("Synchronizaton context expected 2", res == SynchRes.NewSync); } [Test] public void TestRequiresNew () { SincroRequiresNew ob = new SincroRequiresNew (); SynchRes res = ob.CheckContextTransition (typeof(SincroRequiresNew)); Assert ("New synchronizaton context expected", res == SynchRes.NewSync); SincroRequiresNew ob2 = new SincroRequiresNew (); res = ob2.CheckContext (Thread.CurrentContext); Assert ("Synchronizaton context not expected", res == SynchRes.NewSync); } [Test] public void TestNotSupported () { SincroRequiresNew ob = new SincroRequiresNew (); SynchRes res = ob.CheckContextTransition (typeof(SincroNotSupported)); Assert ("Synchronizaton context not expected 1", res == SynchRes.NoSync); SincroNotSupported ob2 = new SincroNotSupported (); res = ob2.CheckContext (Thread.CurrentContext); Assert ("Synchronizaton context not expected 2", res == SynchRes.NoSync); } [Test] public void TestLocked1 () { sincob.Lock (false); Thread tr = new Thread (new ThreadStart (FirstSyncThread)); tr.Start (); Thread.Sleep (200); SecondSyncThread (); tr.Join (); Assert ("Concurrency detected in FirstSyncThread", !otResult); } [Test] public void TestLocked2 () { Thread tr = new Thread (new ThreadStart (FirstNotSyncThread)); tr.Start (); Thread.Sleep (200); SecondNotSyncThread (); tr.Join (); Assert ("Concurrency not detected in FirstReentryThread", otResult); } void FirstNotSyncThread () { otResult = sincob.CheckUnlockedConcurrency (); } void SecondNotSyncThread () { bool concurrent = sincob.CheckConcurrency (); Assert ("Concurrency not detected", concurrent); } [Test] public void TestLocked3 () { Thread tr = new Thread (new ThreadStart (Lock1Thread)); tr.Start (); Thread.Sleep (200); Lock2Thread (); } void Lock1Thread () { sincob.CheckLock1 (); } void Lock2Thread () { sincob.CheckLock2 (); } [Test] public void TestReentry () { Thread tr = new Thread (new ThreadStart (FirstReentryThread)); tr.Start (); Thread.Sleep (200); SecondReentryThread (); tr.Join (); Assert ("Concurrency not detected in FirstReentryThread", otResult); } void FirstReentryThread () { otResult = reentrant.CheckCalloutConcurrency (notsup); } void SecondReentryThread () { bool concurrent = reentrant.CheckCalloutConcurrency (notsup); Assert ("Concurrency not detected", concurrent); } [Test] public void TestNoReentry () { Thread tr = new Thread (new ThreadStart (FirstNoReentryThread)); tr.Start (); Thread.Sleep (200); SecondNoReentryThread (); tr.Join (); Assert ("Concurrency detected in FirstNoReentryThread", !otResult); } void FirstNoReentryThread () { otResult = notreentrant.CheckCalloutConcurrency (notsup); } void SecondNoReentryThread () { bool concurrent = notreentrant.CheckCalloutConcurrency (notsup); Assert ("Concurrency detected", !concurrent); } [Test] public void TestCallback () { Thread tr = new Thread (new ThreadStart (CallbackThread)); tr.Start (); Thread.Sleep (200); bool concurrent = notreentrant.CheckConcurrency (); Assert ("Concurrency detected", !concurrent); notreentrant.CheckContext (Thread.CurrentContext); tr.Join (); Assert ("Concurrency detected in CallbackThread", !otResult); } void CallbackThread () { otResult = notreentrant.TestCallback (); } [Test] [Category("NotDotNet")] public void TestMonitorWait () { Thread tr = new Thread (new ThreadStart (DoMonitorPulse)); tr.Start (); bool r = sincob.CheckMonitorWait (true); Assert ("Wait timeout", r); r = tr.Join (1000); Assert ("Join timeout", r); tr = new Thread (new ThreadStart (DoMonitorPulse)); tr.Start (); r = sincob.CheckMonitorWait (false); Assert ("Expected wait timeout", !r); r = tr.Join (1000); Assert ("Join timeout 2", r); } void DoMonitorPulse () { Thread.Sleep (100); sincob.CheckMonitorPulse (); } } }