Initial import!

This commit is contained in:
markpollack
2008-05-30 22:55:02 +00:00
commit c478a783c0
2978 changed files with 510966 additions and 0 deletions

View 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; }
}
}
}

View 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);
}
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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
}
}

View 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);
}
}
}

View File

@@ -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") );
}
}
}

View 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);
}
}
}

View 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();
}
}
}
}

View File

@@ -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();
}
}
}