using System;
using System.Threading;
using System.Diagnostics;
using NUnit.Framework;
using grof;
namespace grof{
namespace util
{
/// <summary>
/// Description of TestBlockingQueueImpl.
/// </summary>
[TestFixture]
public class TestBlockingQueueImpl : AbstractTest
{
private IBlockingQueue<int> queue;
private Thread producerThread;
private Thread consumerThread;
private bool consumerInterrupted;
private int elementCounter;
/// <summary>
///
/// </summary>
/// <returns></returns>
public TestBlockingQueueImpl()
{
}
[SetUp]
public void Init()
{
base.SetUp();
this.consumerInterrupted = false;
this.queue = new BlockingQueueImpl<int>( "queue" );
Debug.WriteLine( "[TestBlockingQueueImpl#Init] Test set up." );
}
[TearDown]
public void Clean()
{
base.TearDown();
this.queue = null;
Debug.WriteLine( "[TestBlockingQueueImpl#Init] Test torn down." );
}
[Test]
/// <summary>
/// Tests the queueing and dequeueing of elements.
/// </summary>
public void TestQueueing()
{
this.producerThread = new Thread( new ThreadStart( this.Produce ) );
this.producerThread.IsBackground = true;
this.consumerThread = new Thread( new ThreadStart( this.Consume ) );
this.consumerThread.IsBackground = true;
Debug.WriteLine( "[TestBlockingQueueImpl#TestQueueing] called." );
this.consumerThread.Start();
this.producerThread.Start();
this.consumerThread.Join();
Assert.IsNotNull( this.queue );
}
[Test]
/// <summary>
/// Tests whether a <code>BlockingQueueStoppedException</code>
/// is thrown if the queue empty queue was stopped and elements
/// shall be taken from queue.
/// </summary>
public void TestTakingWhenQueueWasStopped()
{
Debug.WriteLine( "[TestBlockingQueueImpl#TestTakingWhenQueueWasStopped] called." );
this.consumerThread = new Thread( new ThreadStart( this.Consume ) );
this.consumerThread.IsBackground = true;
// putting some elements into queue
for ( int i=0; i<50; i++ )
{
this.queue.Put( i );
}
// the queue is stopped but the
// Exception is thrown when all elements
// are taken from queue
this.queue.Stop();
this.consumerThread.Start();
this.WaitForConsumerInterruption();
Assert.AreEqual( 50, this.elementCounter );
}
[Test]
/// <summary>
/// Tests whether a <code>BlockingQueueStoppedException</code>
/// is thrown when the queue was stopped and further elements are
/// put into queue.
/// </summary>
public void TestPuttingWhenQueueWasStopped()
{
Debug.WriteLine( "[TestBlockingQueueImpl#TestPuttingWhenQueueWasStopped] called." );
this.queue.Stop();
bool exceptionThrown = false;
try
{
this.queue.Put( 4 );
} catch( BlockingQueueStoppedException e )
{
exceptionThrown = true;
}
Assert.AreEqual( true, exceptionThrown );
}
private void Produce()
{
for ( int i=0; i<1000; i++ )
{
this.queue.Put( i );
Console.WriteLine( "produce" + i );
}
}
private void Consume()
{
this.elementCounter = 0;
for ( int i=0; i<1000; i++ )
{
try
{
int n = this.queue.Take();
this.elementCounter++;
Console.WriteLine( "consume" + i );
} catch( BlockingQueueStoppedException e )
{
this.ConsumerInterrupted();
break;
}
}
}
private void ConsumerInterrupted()
{
Monitor.Enter( this );
this.consumerInterrupted = true;
Monitor.PulseAll( this );
Monitor.Exit( this );
}
private void WaitForConsumerInterruption()
{
Monitor.Enter( this );
while( !this.consumerInterrupted )
{
Monitor.Wait( this );
}
Monitor.Exit( this );
}
}
}
}
|