| // $Id$ |
| // |
| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you 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. |
| // |
| using System; |
| using System.Threading; |
| using NUnit.Framework; |
| |
| namespace Org.Apache.Etch.Bindings.Csharp.Util |
| { |
| internal delegate void run(); |
| |
| [TestFixture] |
| public class TestCircularQueue |
| { |
| |
| [TestFixtureSetUp] |
| public void First() |
| { |
| Console.WriteLine(); |
| Console.Write("TestCircularQueue"); |
| } |
| |
| |
| [Test] |
| [ExpectedException( typeof( ArgumentOutOfRangeException ) )] |
| public void construct1() |
| { |
| new CircularQueue<int?>( 0 ); |
| } |
| |
| |
| [Test] |
| [ExpectedException(typeof(ArgumentOutOfRangeException))] |
| public void construct2() |
| { |
| new CircularQueue<int?>( -1 ); |
| } |
| |
| |
| [Test] |
| public void construct3() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>( 1 ); |
| Assert.AreEqual( 1, queue.Size() ); |
| } |
| |
| |
| [Test] |
| public void construct4() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>( 2 ); |
| Assert.AreEqual( 2, queue.Size() ); |
| } |
| |
| |
| [Test] |
| public void construct5() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>(); |
| Assert.AreEqual( 10, queue.Size() ); |
| } |
| |
| |
| [Test] |
| public void putget1() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>(); |
| |
| Assert.AreEqual( 0, queue.Count() ); |
| Assert.IsTrue( queue.IsEmpty() ); |
| Assert.IsFalse( queue.IsFull() ); |
| |
| for (int i = 0; i < 10000; i++) |
| { |
| queue.Put( i ); |
| Assert.AreEqual( 1, queue.Count() ); |
| Assert.IsFalse( queue.IsEmpty() ); |
| |
| Assert.AreEqual( i, queue.Get() ); |
| Assert.AreEqual( 0, queue.Count() ); |
| Assert.IsTrue( queue.IsEmpty() ); |
| } |
| } |
| |
| |
| [Test] |
| public void putget2() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>(); |
| |
| Assert.IsNull( queue.Get( 1 ) ); |
| Assert.IsNull( queue.Get( -1 ) ); |
| Assert.IsNull( queue.Get( 10 ) ); |
| |
| queue.Put( 9 ); |
| Assert.AreEqual( 9, queue.Get( 1 ) ); |
| |
| queue.Put( 9 ); |
| Assert.AreEqual( 9, queue.Get( -1 ) ); |
| |
| queue.Put( 9 ); |
| Assert.AreEqual( 9, queue.Get( 10 ) ); |
| |
| Assert.IsNull( queue.Get( 1 ) ); |
| Assert.IsNull( queue.Get( -1 ) ); |
| Assert.IsNull( queue.Get( 10 ) ); |
| |
| /* long t0; |
| double t; |
| |
| |
| t0 = HPTimer.Now(); |
| Assert.IsNull(queue.Get(10)); |
| t = ( HPTimer.Now() - t0) / 1000000.0; |
| assertRelError( 10, t, 1 ); |
| |
| |
| t0 = HPTimer.Now(); |
| Assert.IsNull(queue.Get(20)); |
| t = (HPTimer.Now() - t0) / 1000000.0; |
| assertRelError( 20, t, 1 ); |
| |
| |
| t0 = HPTimer.Now(); |
| Assert.IsNull( queue.Get( 30 ) ); |
| t = (HPTimer.Now() - t0) / 1000000.0; |
| assertRelError( 30, t, 1 ); */ |
| } |
| |
| |
| [Test] |
| public void putget3() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>(); |
| |
| Assert.IsTrue( queue.Put( 1 ) ); |
| Assert.IsTrue( queue.Put( 2 ) ); |
| Assert.IsTrue( queue.Put( 3 ) ); |
| Assert.AreEqual( 1, queue.Get() ); |
| Assert.AreEqual( 2, queue.Get() ); |
| Assert.AreEqual( 3, queue.Get() ); |
| |
| Assert.IsTrue( queue.Put( 1, 0 ) ); |
| Assert.IsTrue( queue.Put( 2, 0 ) ); |
| Assert.IsTrue( queue.Put( 3, 0 ) ); |
| Assert.AreEqual( 1, queue.Get( 0 ) ); |
| Assert.AreEqual( 2, queue.Get( 0 ) ); |
| Assert.AreEqual( 3, queue.Get( 0 ) ); |
| |
| Assert.IsTrue( queue.Put( 1, -1 ) ); |
| Assert.IsTrue( queue.Put( 2, -1 ) ); |
| Assert.IsTrue( queue.Put( 3, -1 ) ); |
| Assert.AreEqual( 1, queue.Get( -1 ) ); |
| Assert.AreEqual( 2, queue.Get( -1 ) ); |
| Assert.AreEqual( 3, queue.Get( -1 ) ); |
| |
| Assert.IsTrue( queue.Put( 1, 1 ) ); |
| Assert.IsTrue( queue.Put( 2, 1 ) ); |
| Assert.IsTrue( queue.Put( 3, 1 ) ); |
| Assert.AreEqual( 1, queue.Get( 1 ) ); |
| Assert.AreEqual( 2, queue.Get( 1 ) ); |
| Assert.AreEqual( 3, queue.Get( 1 ) ); |
| } |
| |
| |
| [Test] |
| public void get() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>( 1 ); |
| |
| // System.nanoTime(); |
| HPTimer.Now(); |
| Assert.IsNull( queue.Get( 10 ) ); |
| assertRelError( 1, 1, 1 ); |
| |
| foreach (int i in new int[] { 10, 20, 30, 50, 80, 130, 210, 340, 550, 890, 1440 }) |
| { |
| // Console.WriteLine( "get delay = {0}\n", i ); |
| long t0 = HPTimer.Now(); |
| Assert.IsNull( queue.Get( i ) ); |
| /* double t = (HPTimer.Now() - t0) / 1000000.0; |
| assertRelError( i, t, 2 ); */ |
| } |
| } |
| |
| |
| [Test] |
| [ExpectedException(typeof(ArgumentNullException))] |
| public void put() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>(); |
| queue.Put( null ); |
| } |
| |
| |
| [Test] |
| public void full() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>( 1 ); |
| |
| Assert.IsFalse( queue.IsFull() ); |
| Assert.IsTrue( queue.Put( 0 ) ); |
| Assert.IsTrue( queue.IsFull() ); |
| Assert.AreEqual( 0, queue.Get() ); |
| Assert.IsFalse( queue.IsFull() ); |
| |
| Assert.IsTrue( queue.Put( 0 ) ); |
| Assert.IsFalse( queue.Put( 0, -1 ) ); |
| Assert.IsFalse( queue.Put( 0, 1 ) ); |
| Assert.IsFalse( queue.Put( 0, 10 ) ); |
| } |
| |
| |
| [Test] |
| public void close1() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>(); |
| |
| Assert.IsFalse( queue.IsClosed() ); |
| queue.Close(); |
| Assert.IsTrue( queue.IsClosed() ); |
| |
| Assert.IsNull( queue.Get() ); |
| Assert.IsNull( queue.Get( -1 ) ); |
| Assert.IsNull( queue.Get( 0 ) ); |
| Assert.IsNull( queue.Get( 1 ) ); |
| |
| queue.Close(); |
| Assert.IsTrue( queue.IsClosed() ); |
| } |
| |
| |
| [Test] |
| public void close2() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>(); |
| |
| Assert.IsFalse( queue.IsClosed() ); |
| queue.Close(); |
| Assert.IsTrue( queue.IsClosed() ); |
| |
| Assert.IsFalse( queue.Put( 0 ) ); |
| Assert.IsFalse( queue.Put( 0, -1 ) ); |
| Assert.IsFalse( queue.Put( 0, 0 ) ); |
| Assert.IsFalse( queue.Put( 0, 1 ) ); |
| |
| queue.Close(); |
| Assert.IsTrue( queue.IsClosed() ); |
| } |
| |
| |
| [Test] |
| public void close3() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>(); |
| queue.Put( 1 ); |
| queue.Put( 2 ); |
| queue.Put( 3 ); |
| queue.Close(); |
| Assert.AreEqual( 1, queue.Get() ); |
| Assert.AreEqual( 2, queue.Get() ); |
| Assert.AreEqual( 3, queue.Get() ); |
| Assert.IsNull( queue.Get() ); |
| } |
| |
| |
| [Test] |
| public void delay1() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>(); |
| |
| Delay( 10, delegate() {queue.Put( 99 ); } ); |
| Assert.AreEqual( 99, queue.Get() ); |
| |
| Delay( 10, delegate() { queue.Close(); } ); |
| Assert.IsNull( queue.Get() ); |
| } |
| |
| |
| [Test] |
| public void delay2() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>( 1 ); |
| |
| Assert.IsTrue( queue.Put( 1 ) ); |
| Delay( 10, delegate() { Assert.AreEqual( 1, queue.Get() ); } ); |
| Assert.IsTrue( queue.Put( 2 ) ); |
| Assert.AreEqual( 2, queue.Get() ); |
| |
| Assert.IsTrue( queue.Put( 1 ) ); |
| Delay(10, delegate() { queue.Close(); }); |
| Assert.IsFalse( queue.Put( 2 ) ); |
| Assert.AreEqual( 1, queue.Get() ); |
| Assert.IsNull( queue.Get() ); |
| } |
| |
| |
| [Test] |
| public void stress1() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>( 1 ); |
| int n = 10000; |
| |
| Thread t = new Thread( |
| delegate() |
| { |
| for (int i = 0; i < n; i++) |
| { |
| try |
| { |
| queue.Put( i ); |
| } |
| catch ( ThreadInterruptedException e ) |
| { |
| Console.WriteLine(e); |
| } |
| } |
| } |
| ); |
| |
| t.Start(); |
| |
| for (int i = 0; i < n; i++) |
| Assert.AreEqual( i, queue.Get() ); |
| } |
| |
| |
| [Test] |
| public void stress2() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>( 1 ); |
| int n = 1000; |
| |
| Thread t = new Thread( |
| delegate() |
| { |
| for (int i = 0; i < n; i++) |
| { |
| try |
| { |
| Thread.Sleep( 5 ); |
| queue.Put( i ); |
| } |
| catch ( ThreadInterruptedException e ) |
| { |
| Console.WriteLine(e); |
| } |
| } |
| } |
| ); |
| |
| t.Start(); |
| |
| for (int i = 0; i < n; i++) |
| Assert.AreEqual( i, queue.Get() ); |
| } |
| |
| |
| [Test] |
| public void stress3() |
| { |
| |
| CircularQueue<int?> queue = new CircularQueue<int?>( 1 ); |
| int n = 1000; |
| |
| Thread t = new Thread( |
| delegate() |
| { |
| for (int i = 0; i < n; i++) |
| { |
| try |
| { |
| |
| queue.Put( i ); |
| } |
| catch ( ThreadInterruptedException e ) |
| { |
| Console.WriteLine(e); |
| } |
| } |
| } |
| ); |
| |
| t.Start(); |
| |
| |
| |
| for (int i = 0; i < n; i++) |
| { |
| Thread.Sleep( 5 ); |
| Assert.AreEqual( i, queue.Get() ); |
| } |
| } |
| |
| |
| [Test] |
| public void stress4() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>(); |
| |
| // we will setup two threads waiting to get and |
| // then in a single synchronized step put two |
| // items in the queue. the first thread will be |
| // woken to get, and once done the second thread |
| // should be woken by the first. |
| |
| Thread t1 = new Thread( |
| delegate() |
| { |
| try |
| { |
| Assert.IsNotNull( queue.Get() ); |
| } |
| catch ( ThreadInterruptedException e ) |
| { |
| Console.WriteLine(e); |
| } |
| } |
| ); |
| |
| Thread t2 = new Thread( |
| delegate() |
| { |
| try |
| { |
| Assert.IsNotNull( queue.Get() ); |
| } |
| catch ( ThreadInterruptedException e ) |
| { |
| Console.WriteLine(e); |
| } |
| } |
| ); |
| |
| t1.Start(); |
| t2.Start(); |
| |
| // wait until both threads are waiting on queue... |
| |
| Thread.Sleep( 100 ); |
| |
| lock(queue) |
| { |
| queue.Put( 1 ); |
| queue.Put( 2 ); |
| } |
| |
| harvest( t1 ); |
| harvest( t2 ); |
| } |
| |
| |
| [Test] |
| public void stress5() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>( 3 ); |
| |
| // we will setup two threads waiting to put to the queue, |
| // then in a single synchronized step, read two items from |
| // the queue. the first thread will be woken to put, and |
| // once done the second thread should be woken by the first. |
| |
| queue.Put( 0 ); |
| queue.Put( 1 ); |
| queue.Put( 2 ); |
| Assert.IsTrue( queue.IsFull() ); |
| |
| Thread t1 = new Thread( |
| delegate() |
| { |
| |
| try |
| { |
| Assert.IsTrue( queue.Put( 3 ) ); |
| } |
| catch ( ThreadInterruptedException e ) |
| { |
| Console.WriteLine(e); |
| } |
| } |
| ); |
| |
| Thread t2 = new Thread( |
| delegate() |
| { |
| try |
| { |
| Assert.IsTrue( queue.Put( 4 ) ); |
| } |
| catch ( ThreadInterruptedException e ) |
| { |
| Console.WriteLine(e); |
| } |
| } |
| ); |
| |
| t1.Start(); |
| t2.Start(); |
| |
| // wait until both threads are waiting on queue... |
| |
| Thread.Sleep( 100 ); |
| |
| lock(queue) |
| { |
| Assert.IsNotNull( queue.Get() ); |
| Assert.IsNotNull( queue.Get() ); |
| } |
| |
| harvest( t1 ); |
| harvest( t2 ); |
| } |
| |
| |
| [Test] |
| public void stress6() |
| { |
| CircularQueue<int?> queue = new CircularQueue<int?>( 5 ); |
| |
| // start two getters and two putters and let 'em duke it out... |
| |
| Thread t1 = new Thread( |
| delegate() |
| { |
| try |
| { |
| for (int i = 0; i < 100; i++) |
| Assert.IsTrue( queue.Put( i ) ); |
| } |
| catch ( ThreadInterruptedException e ) |
| { |
| Console.WriteLine(e); |
| } |
| } |
| ); |
| |
| Thread t2 = new Thread( |
| delegate() |
| { |
| try |
| { |
| for (int i = 0; i < 100; i++) |
| Assert.IsTrue( queue.Put( i ) ); |
| } |
| catch ( ThreadInterruptedException e ) |
| { |
| Console.WriteLine(e); |
| } |
| } |
| ); |
| |
| Thread t3 = new Thread( |
| delegate() |
| { |
| try |
| { |
| for (int i = 0; i < 100; i++) |
| Assert.IsNotNull( queue.Get() ); |
| } |
| catch ( ThreadInterruptedException e ) |
| { |
| Console.WriteLine(e); |
| } |
| } |
| ); |
| |
| Thread t4 = new Thread( |
| delegate() |
| { |
| try |
| { |
| for (int i = 0; i < 100; i++) |
| Assert.IsNotNull( queue.Get() ); |
| } |
| catch ( ThreadInterruptedException e ) |
| { |
| Console.WriteLine(e); |
| } |
| } |
| ); |
| |
| t1.Start(); |
| t2.Start(); |
| t3.Start(); |
| t4.Start(); |
| |
| harvest( t1 ); |
| harvest( t2 ); |
| harvest( t3 ); |
| harvest( t4 ); |
| } |
| |
| |
| [Test] |
| public void harvest1() |
| { |
| Thread t = new Thread( |
| delegate() |
| { |
| } |
| ); |
| t.Start(); |
| harvest( t ); |
| } |
| |
| |
| [Test] |
| [ExpectedException( typeof( TimeoutException ) )] |
| public void harvest2() |
| { |
| Thread t = new Thread( |
| delegate() |
| { |
| try |
| { |
| Thread.Sleep( 10000 ); |
| } |
| catch ( ThreadInterruptedException e ) |
| { |
| Console.WriteLine(e); |
| } |
| } |
| ); |
| t.Start(); |
| harvest( t ); |
| } |
| |
| private void harvest( Thread t ) |
| { |
| t.Join( 1000 ); |
| if (t.IsAlive) |
| { |
| t.Interrupt(); |
| throw new TimeoutException( t.Name+" is stuck" ); |
| } |
| } |
| |
| |
| [Test] |
| public void testRelError1() |
| { |
| assertRelError( 10, 9, .11 ); |
| assertRelError( 10, 11, .14 ); |
| assertRelError( 20, 19, .07 ); |
| assertRelError( 19, 23, .22 ); |
| } |
| |
| |
| [Test] |
| [ExpectedException( typeof(AssertionException ) )] |
| public void testRelError2() |
| { |
| assertRelError( 9, 8, .1 ); |
| } |
| |
| |
| [Test] |
| [ExpectedException( typeof(AssertionException ) )] |
| public void testRelError3() |
| { |
| assertRelError( 9, 10, .1 ); |
| } |
| |
| |
| [Test] |
| public void testAbsError1() |
| { |
| AssertAbsError( 11, 15, 4 ); |
| AssertAbsError( 15, 10, 5 ); |
| AssertAbsError( 5, 3, 2 ); |
| AssertAbsError( 4, 7, 3 ); |
| } |
| |
| |
| [Test] |
| [ExpectedException( typeof(AssertionException ) )] |
| public void testAbsError2() |
| { |
| AssertAbsError( 11, 15, 3 ); |
| } |
| |
| |
| [Test] |
| [ExpectedException(typeof(AssertionException))] |
| public void testAbsError3() |
| { |
| AssertAbsError( 19, 15, 3 ); |
| } |
| |
| private void Delay( int delay, run del ) |
| { |
| |
| Thread t = new Thread(delegate() |
| { |
| try |
| { |
| Thread.Sleep(delay); |
| del(); |
| } |
| catch (Exception e) |
| { |
| Console.WriteLine(e); |
| } |
| }); |
| t.Start(); |
| |
| |
| } |
| |
| |
| |
| private void assertRelError( double expected, double actual, double error ) |
| { |
| double relError = RelError( expected, actual ); |
| if (relError > error) |
| Assert.Fail( String.Format( "expected: {0} but was: {1} relative error: {2}", expected, actual, relError ) ); |
| } |
| |
| private void AssertAbsError( double expected, double actual, double error ) |
| { |
| double absError = AbsError( expected, actual ); |
| if (absError > error) |
| |
| Assert.Fail( String.Format( "expected: {0} but was: {1} absolute error: {2}", expected, actual, absError ) ); |
| } |
| |
| private double RelError( double expected, double actual ) |
| { |
| return AbsError( expected, actual ) / expected; |
| } |
| |
| private double AbsError( double expected, double actual ) |
| { |
| return Math.Abs( expected - actual ); |
| } |
| |
| } |
| } |