linux-packaging-mono/mcs/class/corlib/Test/System.Threading/ManualResetEventSlimTests.cs
Jo Shields 3c1f479b9d Imported Upstream version 4.0.0~alpha1
Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
2015-04-07 09:35:12 +01:00

310 lines
7.2 KiB
C#

// ManualResetEventSlimTests.cs
//
// Authors:
// Marek Safar (marek.safar@gmail.com)
// Jeremie Laval (jeremie.laval@gmail.com)
//
// Copyright (c) 2008 Jérémie "Garuma" Laval
// Copyright (c) 2012 Xamarin, Inc (http://www.xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//
#if NET_4_0
using System;
using System.Threading;
using NUnit.Framework;
using MonoTests.System.Threading.Tasks;
namespace MonoTests.System.Threading
{
[TestFixture]
public class ManualResetEventSlimTests
{
ManualResetEventSlim mre;
[SetUp]
public void Setup()
{
mre = new ManualResetEventSlim();
}
[Test]
public void Constructor_Defaults ()
{
Assert.IsFalse (mre.IsSet, "#1");
Assert.AreEqual (10, mre.SpinCount, "#2");
}
[Test]
public void Constructor_Invalid ()
{
try {
new ManualResetEventSlim (true, -1);
Assert.Fail ("#1");
} catch (ArgumentException) {
}
try {
new ManualResetEventSlim (true, 2048);
Assert.Fail ("#2");
} catch (ArgumentException) {
}
}
[Test]
public void IsSetTestCase()
{
Assert.IsFalse(mre.IsSet, "#1");
mre.Set();
Assert.IsTrue(mre.IsSet, "#2");
mre.Reset();
Assert.IsFalse(mre.IsSet, "#3");
}
[Test]
public void WaitTest()
{
int count = 0;
bool s = false;
ParallelTestHelper.ParallelStressTest(mre, delegate (ManualResetEventSlim m) {
if (Interlocked.Increment(ref count) % 2 == 0) {
Thread.Sleep(50);
for (int i = 0; i < 10; i++) {
if (i % 2 == 0)
m.Reset();
else
m.Set();
}
} else {
m.Wait();
s = true;
}
}, 2);
Assert.IsTrue(s, "#1");
Assert.IsTrue(mre.IsSet, "#2");
}
[Test]
public void Wait_SetConcurrent ()
{
for (int i = 0; i < 10000; ++i) {
var mre = new ManualResetEventSlim ();
bool b = true;
ThreadPool.QueueUserWorkItem (delegate {
mre.Set ();
});
ThreadPool.QueueUserWorkItem (delegate {
b &= mre.Wait (1000);
});
Assert.IsTrue (mre.Wait (1000), i.ToString ());
Assert.IsTrue (b, i.ToString ());
}
}
[Test]
public void Wait_DisposeWithCancel ()
{
var token = new CancellationTokenSource ();
ThreadPool.QueueUserWorkItem (delegate {
Thread.Sleep (10);
mre.Dispose ();
token.Cancel ();
});
try {
mre.Wait (10000, token.Token);
Assert.Fail ("#0");
} catch (OperationCanceledException e) {
}
}
[Test]
public void Wait_Expired ()
{
Assert.IsFalse (mre.Wait (10));
}
[Test, ExpectedException (typeof (ObjectDisposedException))]
public void WaitAfterDisposeTest ()
{
mre.Dispose ();
mre.Wait ();
}
[Test]
public void SetAfterDisposeTest ()
{
ParallelTestHelper.Repeat (delegate {
Exception disp = null, setting = null;
CountdownEvent evt = new CountdownEvent (2);
CountdownEvent evtFinish = new CountdownEvent (2);
ThreadPool.QueueUserWorkItem (delegate {
try {
evt.Signal ();
evt.Wait (1000);
mre.Dispose ();
} catch (Exception e) {
disp = e;
}
evtFinish.Signal ();
});
ThreadPool.QueueUserWorkItem (delegate {
try {
evt.Signal ();
evt.Wait (1000);
mre.Set ();
} catch (Exception e) {
setting = e;
}
evtFinish.Signal ();
});
bool bb = evtFinish.Wait (1000);
if (!bb)
Assert.AreEqual (true, evtFinish.IsSet);
Assert.IsTrue (bb, "#0");
Assert.IsNull (disp, "#1");
Assert.IsNull (setting, "#2");
evt.Dispose ();
evtFinish.Dispose ();
});
}
[Test]
public void WaitHandle_Initialized ()
{
var mre = new ManualResetEventSlim (true);
Assert.IsTrue (mre.WaitHandle.WaitOne (0), "#1");
mre.Reset ();
Assert.IsFalse (mre.WaitHandle.WaitOne (0), "#2");
Assert.AreEqual (mre.WaitHandle, mre.WaitHandle, "#3");
}
[Test]
public void WaitHandle_NotInitialized ()
{
var mre = new ManualResetEventSlim (false);
Assert.IsFalse (mre.WaitHandle.WaitOne (0), "#1");
mre.Set ();
Assert.IsTrue (mre.WaitHandle.WaitOne (0), "#2");
}
[Test]
public void WaitHandleConsistencyTest ()
{
var mre = new ManualResetEventSlim ();
mre.WaitHandle.WaitOne (0);
for (int i = 0; i < 10000; i++) {
int count = 2;
SpinWait wait = new SpinWait ();
ThreadPool.QueueUserWorkItem (_ => { while (count > 1) wait.SpinOnce (); mre.Set (); Interlocked.Decrement (ref count); });
ThreadPool.QueueUserWorkItem (_ => { mre.Reset (); Interlocked.Decrement (ref count); });
while (count > 0)
wait.SpinOnce ();
Assert.AreEqual (mre.IsSet, mre.WaitHandle.WaitOne (0));
}
}
[Test]
public void WaitWithCancellationTokenAndNotImmediateSetTest ()
{
var mres = new ManualResetEventSlim ();
var cts = new CancellationTokenSource ();
ThreadPool.QueueUserWorkItem(x => { Thread.Sleep (1000); mres.Set (); });
Assert.IsTrue (mres.Wait (TimeSpan.FromSeconds (10), cts.Token), "Wait returned false despite event was set.");
}
[Test]
public void WaitWithCancellationTokenAndCancel ()
{
var mres = new ManualResetEventSlim ();
var cts = new CancellationTokenSource ();
ThreadPool.QueueUserWorkItem(x => { Thread.Sleep (1000); cts.Cancel (); });
try {
mres.Wait (TimeSpan.FromSeconds (10), cts.Token);
Assert.Fail ("Wait did not throw an exception despite cancellation token was cancelled.");
} catch (OperationCanceledException) {
}
}
[Test]
public void WaitWithCancellationTokenAndTimeout ()
{
var mres = new ManualResetEventSlim ();
var cts = new CancellationTokenSource ();
Assert.IsFalse (mres.Wait (TimeSpan.FromSeconds (1), cts.Token), "Wait returned true despite timeout.");
}
[Test]
public void Dispose ()
{
var mre = new ManualResetEventSlim (false);
mre.Dispose ();
Assert.IsFalse (mre.IsSet, "#0a");
try {
mre.Reset ();
Assert.Fail ("#1");
} catch (ObjectDisposedException) {
}
mre.Set ();
try {
mre.Wait (0);
Assert.Fail ("#3");
} catch (ObjectDisposedException) {
}
try {
var v = mre.WaitHandle;
Assert.Fail ("#4");
} catch (ObjectDisposedException) {
}
}
[Test]
public void Dispose_Double ()
{
var mre = new ManualResetEventSlim ();
mre.Dispose ();
mre.Dispose ();
}
}
}
#endif