Initial import!
This commit is contained in:
84
test/Spring/Spring.Core.Tests/Threading/AsyncTestMethod.cs
Normal file
84
test/Spring/Spring.Core.Tests/Threading/AsyncTestMethod.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using NUnit.Framework;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Threading
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
/// <version>$Id: AsyncTestMethod.cs,v 1.2 2008/02/02 10:24:38 oakinger Exp $</version>
|
||||
public class AsyncTestMethod : AsyncTestTask
|
||||
{
|
||||
public delegate object TestMethod(object[] args);
|
||||
|
||||
private readonly TestMethod callback;
|
||||
private readonly object[] args;
|
||||
private object result;
|
||||
|
||||
private class ThreadStartTestMethodAdapter
|
||||
{
|
||||
private readonly ThreadStart threadStart;
|
||||
|
||||
public ThreadStartTestMethodAdapter(ThreadStart threadStart)
|
||||
{
|
||||
Assert.IsNotNull(threadStart);
|
||||
this.threadStart = threadStart;
|
||||
}
|
||||
|
||||
public object Execute(object[] args)
|
||||
{
|
||||
threadStart();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public AsyncTestMethod(int iterations, ThreadStart callback, params object[] args)
|
||||
: this(iterations, new TestMethod(new ThreadStartTestMethodAdapter(callback).Execute), args)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public AsyncTestMethod(int iterations, TestMethod callback, params object[] args) : base(iterations)
|
||||
{
|
||||
Assert.IsNotNull(callback);
|
||||
this.args = args;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public override void DoExecute()
|
||||
{
|
||||
result = callback(args);
|
||||
}
|
||||
|
||||
public object Result
|
||||
{
|
||||
get { return result; }
|
||||
}
|
||||
}
|
||||
}
|
||||
85
test/Spring/Spring.Core.Tests/Threading/AsyncTestTask.cs
Normal file
85
test/Spring/Spring.Core.Tests/Threading/AsyncTestTask.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Threading
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for async test operations
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
/// <version>$Id: AsyncTestTask.cs,v 1.2 2008/02/02 10:24:38 oakinger Exp $</version>
|
||||
public abstract class AsyncTestTask
|
||||
{
|
||||
private Exception exception;
|
||||
private Thread t;
|
||||
private readonly int iterations;
|
||||
private int iterationno;
|
||||
|
||||
public AsyncTestTask(int iterations)
|
||||
{
|
||||
this.iterations = iterations;
|
||||
t = new Thread(new ThreadStart(Run));
|
||||
t.IsBackground = true;
|
||||
}
|
||||
|
||||
public abstract void DoExecute();
|
||||
|
||||
public AsyncTestTask Start()
|
||||
{
|
||||
t.Start();
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
int loop = 0;
|
||||
try
|
||||
{
|
||||
iterationno = 0;
|
||||
for(loop = 0; loop < iterations; loop++)
|
||||
{
|
||||
DoExecute();
|
||||
Thread.Sleep(0);
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
iterationno = loop;
|
||||
exception = ex;
|
||||
}
|
||||
}
|
||||
|
||||
public void AssertNoException()
|
||||
{
|
||||
t.Join();
|
||||
if(exception != null)
|
||||
{
|
||||
throw new Exception("Exception occured in testtask on iteration " + iterationno, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2005 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Threading
|
||||
{
|
||||
/// <summary>
|
||||
/// Apply common thread-storage tests for <see cref="CallContextStorage"/>
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
/// <version>$Id: CallContextStorageTests.cs,v 1.1 2007/02/02 21:31:08 oakinger Exp $</version>
|
||||
[TestFixture]
|
||||
public class CallContextStorageTests : CommonThreadStorageTests
|
||||
{
|
||||
protected override IThreadStorage CreateStorage()
|
||||
{
|
||||
return new CallContextStorage();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2005 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using NUnit.Framework;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Threading
|
||||
{
|
||||
/// <summary>
|
||||
/// Any <see cref="IThreadStorage"/> implementation must pass these tests.
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
/// <version>$Id: CommonThreadStorageTests.cs,v 1.2 2007/05/14 21:31:32 oakinger Exp $</version>
|
||||
public abstract class CommonThreadStorageTests
|
||||
{
|
||||
protected abstract IThreadStorage CreateStorage();
|
||||
|
||||
protected virtual void ThreadSetup()
|
||||
{}
|
||||
|
||||
protected virtual void ThreadCleanup()
|
||||
{}
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void FixtureSetUp()
|
||||
{
|
||||
ThreadSetup();
|
||||
}
|
||||
|
||||
[TestFixtureTearDown]
|
||||
public void FixtureTearDown()
|
||||
{
|
||||
ThreadCleanup();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
// cleanup storage
|
||||
IThreadStorage storage = CreateStorage();
|
||||
storage.FreeNamedDataSlot("key");
|
||||
storage.FreeNamedDataSlot("KEY");
|
||||
storage.FreeNamedDataSlot("KeY");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsCaseSensitive()
|
||||
{
|
||||
IThreadStorage storage = CreateStorage();
|
||||
|
||||
object value1 = new object();
|
||||
object value2 = new object();
|
||||
object value3 = new object();
|
||||
|
||||
storage.SetData("key", value1);
|
||||
storage.SetData("KEY", value2);
|
||||
storage.SetData("KeY", value3);
|
||||
|
||||
Assert.AreSame(value1, storage.GetData("key"));
|
||||
Assert.AreSame(value2, storage.GetData("KEY"));
|
||||
Assert.AreSame(value3, storage.GetData("KeY"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AllowReplaceData()
|
||||
{
|
||||
IThreadStorage storage = CreateStorage();
|
||||
|
||||
object value1 = new object();
|
||||
object value2 = new object();
|
||||
|
||||
storage.SetData("key", value1);
|
||||
Assert.AreSame(value1, storage.GetData("key"));
|
||||
storage.SetData("key", value2);
|
||||
Assert.AreSame(value2, storage.GetData("key"));
|
||||
storage.SetData("key", null);
|
||||
Assert.AreSame(null, storage.GetData("key"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UnknownKeyReturnsNull()
|
||||
{
|
||||
IThreadStorage storage = CreateStorage();
|
||||
|
||||
Assert.AreSame(null, storage.GetData("key"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FreeNamedDataSlotRemovesData()
|
||||
{
|
||||
IThreadStorage storage = CreateStorage();
|
||||
|
||||
object value1 = new object();
|
||||
storage.SetData("key", value1);
|
||||
Assert.AreSame(value1, storage.GetData("key"));
|
||||
storage.FreeNamedDataSlot("key");
|
||||
Assert.AreSame(null, storage.GetData("key"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UsesDistinguishedStorageOnDifferentThreads()
|
||||
{
|
||||
IThreadStorage storage = CreateStorage();
|
||||
|
||||
object value1 = new object();
|
||||
storage.SetData("key", value1);
|
||||
|
||||
ThreadTestHelper helper = new ThreadTestHelper(this,storage);
|
||||
helper.Execute();
|
||||
|
||||
Assert.AreNotSame( value1, helper.value );
|
||||
Assert.IsNull(helper.value);
|
||||
}
|
||||
|
||||
#region Test Utility Classes
|
||||
|
||||
private class ThreadTestHelper
|
||||
{
|
||||
private CommonThreadStorageTests outer;
|
||||
private IThreadStorage storage;
|
||||
|
||||
public object value;
|
||||
|
||||
public ThreadTestHelper(CommonThreadStorageTests outer, IThreadStorage storage)
|
||||
{
|
||||
this.outer = outer;
|
||||
this.storage = storage;
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
Thread t = new Thread(new ThreadStart(this.Run));
|
||||
t.Start();
|
||||
t.Join();
|
||||
}
|
||||
|
||||
private void Run()
|
||||
{
|
||||
outer.ThreadSetup();
|
||||
value = this.storage.GetData("key");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Test Utility Classes
|
||||
}
|
||||
}
|
||||
83
test/Spring/Spring.Core.Tests/Threading/LatchTest.cs
Normal file
83
test/Spring/Spring.Core.Tests/Threading/LatchTest.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Spring.Threading;
|
||||
using NUnit.Framework;
|
||||
|
||||
#region Licence
|
||||
|
||||
/*
|
||||
* Copyright 2002-2004 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
namespace Spring.Threading
|
||||
{
|
||||
[TestFixture]
|
||||
public class LatchTest
|
||||
{
|
||||
|
||||
class Worker
|
||||
{
|
||||
public bool worked;
|
||||
ISync startPermit;
|
||||
ISync workedSync;
|
||||
|
||||
public Worker (ISync startPermit, ISync workedSync)
|
||||
{
|
||||
this.startPermit = startPermit;
|
||||
this.workedSync = workedSync;
|
||||
}
|
||||
|
||||
public void Work()
|
||||
{
|
||||
// very slow worker initialization ...
|
||||
// ... attach to messaging system
|
||||
// ... connect to database
|
||||
startPermit.Acquire();
|
||||
// ... use resources initialized in Mush
|
||||
// ... do real work
|
||||
worked = true;
|
||||
// ... we are finished
|
||||
workedSync.Release();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BossWorkerDemo()
|
||||
{
|
||||
int n = 10;
|
||||
|
||||
Latch startPermit = new Latch();
|
||||
Semaphore wait = new Semaphore(-(n - 1));
|
||||
|
||||
Worker [] workers = new Worker[n];
|
||||
for (int i=0; i<n; ++i)
|
||||
{
|
||||
workers[i] = new Worker(startPermit, wait);
|
||||
new Thread(new ThreadStart(workers[i].Work)).Start();
|
||||
}
|
||||
// very slow main initialization ...
|
||||
// ... parse configuration
|
||||
// ... initialize other resources used by workers
|
||||
startPermit.Release();
|
||||
|
||||
// now it is our turn to wait for workers
|
||||
wait.Acquire();
|
||||
|
||||
for (int i=0; i<n; ++i)
|
||||
Assert.IsTrue(workers[i].worked);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2005 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using NUnit.Framework;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Threading
|
||||
{
|
||||
/// <summary>
|
||||
/// Test behaviour of LogicalThreadContext
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
/// <version>$Id: LogicalThreadContextTest.cs,v 1.1 2007/02/02 21:31:08 oakinger Exp $</version>
|
||||
[TestFixture]
|
||||
public class LogicalThreadContextTest
|
||||
{
|
||||
private class MockStorage : IThreadStorage
|
||||
{
|
||||
internal Hashtable data = new Hashtable();
|
||||
|
||||
public object GetData(string name)
|
||||
{
|
||||
return data[name];
|
||||
}
|
||||
|
||||
public void SetData(string name, object value)
|
||||
{
|
||||
data[name] = value;
|
||||
}
|
||||
|
||||
public void FreeNamedDataSlot(string name)
|
||||
{
|
||||
data.Remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public void StorageMustNotBeNull()
|
||||
{
|
||||
LogicalThreadContext.SetStorage(null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StorageMayBeSetMoreThanOnce()
|
||||
{
|
||||
LogicalThreadContext.SetStorage(new MockStorage());
|
||||
LogicalThreadContext.SetStorage(new MockStorage());
|
||||
LogicalThreadContext.SetStorage(new MockStorage());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StorageIsUsedByFacadeMethods()
|
||||
{
|
||||
MockStorage storage = new MockStorage();
|
||||
LogicalThreadContext.SetStorage(storage);
|
||||
|
||||
object value = new object();
|
||||
|
||||
LogicalThreadContext.SetData("key", value);
|
||||
Assert.AreSame( value, storage.data["key"] );
|
||||
|
||||
object data = LogicalThreadContext.GetData("key");
|
||||
Assert.AreSame(value, data);
|
||||
|
||||
LogicalThreadContext.FreeNamedDataSlot("key");
|
||||
|
||||
Assert.IsFalse( storage.data.ContainsKey("key") );
|
||||
}
|
||||
}
|
||||
}
|
||||
219
test/Spring/Spring.Core.Tests/Threading/SemaphoreTest.cs
Normal file
219
test/Spring/Spring.Core.Tests/Threading/SemaphoreTest.cs
Normal file
@@ -0,0 +1,219 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2004 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Spring.Pool;
|
||||
using Spring.Threading;
|
||||
using NUnit.Framework;
|
||||
|
||||
|
||||
namespace Spring.Threading
|
||||
{
|
||||
[TestFixture]
|
||||
public class SemaphoreTest
|
||||
{
|
||||
private static long SHORT_DELAY_MS = 300;
|
||||
[Test]
|
||||
public void UsingLikeAMutex ()
|
||||
{
|
||||
|
||||
Semaphore semaphore = new Semaphore (1);
|
||||
Latch latch = new Latch ();
|
||||
Helper helper = new Helper (semaphore, latch);
|
||||
Thread thread = new Thread (new ThreadStart (helper.Go));
|
||||
semaphore.Acquire ();
|
||||
thread.Start ();
|
||||
latch.Acquire ();
|
||||
Assert.IsFalse (helper.gone);
|
||||
semaphore.Release ();
|
||||
thread.Join ();
|
||||
Assert.IsTrue (helper.gone, "not gone");
|
||||
|
||||
}
|
||||
[Test]
|
||||
public void AquireInSameThrad()
|
||||
{
|
||||
Semaphore s = new Semaphore(2);
|
||||
Assert.AreEqual(2, s.Permits);
|
||||
s.Acquire();
|
||||
s.Acquire();
|
||||
Assert.AreEqual(0, s.Permits);
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReleaseMultipleTimesInSameThread()
|
||||
{
|
||||
Semaphore s = new Semaphore(2);
|
||||
Assert.AreEqual(2, s.Permits);
|
||||
s.Acquire();
|
||||
s.Acquire();
|
||||
s.Release(2);
|
||||
Assert.AreEqual(2, s.Permits);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AttemptWithNegativeMillisInSameThread()
|
||||
{
|
||||
Semaphore s = new Semaphore(2);
|
||||
Assert.AreEqual(2, s.Permits);
|
||||
s.Acquire();
|
||||
Assert.IsTrue(s.Attempt(-400));
|
||||
s.Release(2);
|
||||
Assert.AreEqual(2, s.Permits);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof(ArgumentOutOfRangeException))]
|
||||
public void ReleaseMultipleBadArgument()
|
||||
{
|
||||
Semaphore s = new Semaphore(2);
|
||||
Assert.AreEqual(2, s.Permits);
|
||||
s.Acquire();
|
||||
s.Acquire();
|
||||
s.Release(-2);
|
||||
Assert.AreEqual(2, s.Permits);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AttemptInSameThread()
|
||||
{
|
||||
Semaphore s = new Semaphore(1);
|
||||
Assert.IsTrue(s.Attempt(SHORT_DELAY_MS));
|
||||
s.Release();
|
||||
Assert.IsTrue(s.Attempt(SHORT_DELAY_MS));
|
||||
s.Release();
|
||||
Assert.IsTrue(s.Attempt(SHORT_DELAY_MS));
|
||||
s.Release();
|
||||
Assert.IsTrue(s.Attempt(SHORT_DELAY_MS));
|
||||
s.Release();
|
||||
Assert.IsTrue(s.Attempt(SHORT_DELAY_MS));
|
||||
s.Release();
|
||||
Assert.AreEqual(1, s.Permits);
|
||||
|
||||
}
|
||||
|
||||
//TODO tests that interrupt a thread.
|
||||
|
||||
[Test]
|
||||
public void AquireReleaseInSameThread()
|
||||
{
|
||||
Semaphore s = new Semaphore(1);
|
||||
s.Acquire();
|
||||
s.Release();
|
||||
s.Acquire();
|
||||
s.Release();
|
||||
s.Acquire();
|
||||
s.Release();
|
||||
s.Acquire();
|
||||
s.Release();
|
||||
s.Acquire();
|
||||
s.Release();
|
||||
s.Acquire();
|
||||
s.Release();
|
||||
Assert.AreEqual(1, s.Permits);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AcquireReleaseInDifferentThreads()
|
||||
{
|
||||
Semaphore s = new Semaphore(0);
|
||||
AcquireReleaseWorker worker1 = new AcquireReleaseWorker(s);
|
||||
Thread thread1 = new Thread(new ThreadStart(worker1.DoWork));
|
||||
|
||||
thread1.Start();
|
||||
Thread.Sleep(300);
|
||||
s.Release();
|
||||
s.Release();
|
||||
s.Acquire();
|
||||
s.Acquire();
|
||||
s.Release();
|
||||
thread1.Join();
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AttemptReleaseInDifferentThreads()
|
||||
{
|
||||
Semaphore s = new Semaphore(0);
|
||||
AttemptReleaseWorker worker1 = new AttemptReleaseWorker(s);
|
||||
Thread thread1 = new Thread(new ThreadStart(worker1.DoWork));
|
||||
|
||||
thread1.Start();
|
||||
//TODO investigate...
|
||||
//Assert.IsTrue(s.Attempt(SHORT_DELAY_MS));
|
||||
s.Attempt(SHORT_DELAY_MS);
|
||||
s.Release();
|
||||
//Assert.IsTrue(s.Attempt(SHORT_DELAY_MS));
|
||||
s.Attempt(SHORT_DELAY_MS);
|
||||
s.Release();
|
||||
s.Release();
|
||||
thread1.Join();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TimetoMillis()
|
||||
{
|
||||
long millis = Utils.CurrentTimeMillis;
|
||||
//hmm should be using UtcNow, the impl in CurrentTimeMillis doesn't use UTC.
|
||||
long epochTime = ((DateTime.Now-new DateTime (1970, 1, 1)).Ticks)/TimeSpan.TicksPerMillisecond;
|
||||
long delta = epochTime-millis;
|
||||
Assert.IsTrue(delta < 500);
|
||||
}
|
||||
}
|
||||
|
||||
public class AcquireReleaseWorker
|
||||
{
|
||||
private Semaphore sem;
|
||||
public AcquireReleaseWorker(Semaphore s)
|
||||
{
|
||||
sem = s;
|
||||
}
|
||||
|
||||
public void DoWork()
|
||||
{
|
||||
sem.Acquire();
|
||||
sem.Release();
|
||||
sem.Release();
|
||||
sem.Acquire();
|
||||
}
|
||||
}
|
||||
|
||||
public class AttemptReleaseWorker
|
||||
{
|
||||
private Semaphore sem;
|
||||
public AttemptReleaseWorker(Semaphore s)
|
||||
{
|
||||
sem = s;
|
||||
}
|
||||
|
||||
public void DoWork()
|
||||
{
|
||||
long SHORT_DELAY_MS = 300;
|
||||
sem.Release();
|
||||
|
||||
//TODO can we do Assert.IsTrue here?
|
||||
sem.Attempt(SHORT_DELAY_MS);
|
||||
sem.Release();
|
||||
sem.Attempt(SHORT_DELAY_MS);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
68
test/Spring/Spring.Core.Tests/Threading/SyncHolderTest.cs
Normal file
68
test/Spring/Spring.Core.Tests/Threading/SyncHolderTest.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System.Threading;
|
||||
using DotNetMock.Dynamic;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Spring.Threading
|
||||
{
|
||||
[TestFixture]
|
||||
public class SyncHolderTest
|
||||
{
|
||||
DynamicMock mock;
|
||||
ISync sync;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp ()
|
||||
{
|
||||
mock = new DynamicMock(typeof(ISync));
|
||||
sync = (ISync) mock.Object;
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown ()
|
||||
{
|
||||
mock.Verify();
|
||||
}
|
||||
|
||||
class MySemaphore : Semaphore
|
||||
{
|
||||
public MySemaphore (long initialPermits) : base (initialPermits)
|
||||
{}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanBeUsedWithTheUsingCSharpIdiomToAttemptOnAnISync ()
|
||||
{
|
||||
MySemaphore sync = new MySemaphore(1);
|
||||
using (new SyncHolder(sync, 100))
|
||||
{
|
||||
Assert.AreEqual(0, sync.Permits);
|
||||
}
|
||||
Assert.AreEqual(1, sync.Permits);
|
||||
|
||||
sync = new MySemaphore(0);
|
||||
try
|
||||
{
|
||||
using (new SyncHolder(sync, 100))
|
||||
{
|
||||
Assert.IsTrue(false, "wrongly entered sync block");
|
||||
}
|
||||
}
|
||||
catch (TimeoutException)
|
||||
{
|
||||
Assert.AreEqual(0, sync.Permits);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[ExpectedException(typeof(ThreadStateException))]
|
||||
public void CanBeUsedWithTheUsingCSharpIdiomToAcquireAnIsync()
|
||||
{
|
||||
mock.Expect("Acquire");
|
||||
mock.Expect("Release");
|
||||
using (new SyncHolder(sync))
|
||||
{
|
||||
throw new ThreadStateException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2005 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region Imports
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Threading
|
||||
{
|
||||
/// <summary>
|
||||
/// Apply common thread-storage tests for <see cref="ThreadStaticStorage"/>
|
||||
/// </summary>
|
||||
/// <author>Erich Eichinger</author>
|
||||
/// <version>$Id: ThreadStaticStorageTests.cs,v 1.1 2007/02/02 21:31:08 oakinger Exp $</version>
|
||||
[TestFixture]
|
||||
public class ThreadStaticStorageTests : CommonThreadStorageTests
|
||||
{
|
||||
protected override IThreadStorage CreateStorage()
|
||||
{
|
||||
return new ThreadStaticStorage();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user