SimplePoolTest.cs :  » Inversion-of-Control-Dependency-Injection » Spring.net » Spring » Pool » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Inversion of Control Dependency Injection » Spring.net 
Spring.net » Spring » Pool » SimplePoolTest.cs
#region License

/*
* Copyright  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 System.Runtime.InteropServices;
using System.Threading;
using NUnit.Framework;
using Rhino.Mocks;
using Spring.Pool.Support;
using Spring.Threading;

#endregion

namespace Spring.Pool{
  #region Inner Class : Helper

  public class Helper
  {
    private Latch latch;
    private IObjectPool objectPool;
    private ISync sync;

    public bool gone = false;
    public object gotFromPool;

    public Helper(ISync sync, Latch latch)
    {
      Init(latch, sync, null);
    }

    public Helper(Latch latch, ISync sync, IObjectPool objectPool)
    {
      Init(latch, sync, objectPool);
    }

    public void Init(Latch latch, ISync sync, IObjectPool objectPool)
    {
      this.sync = sync;
      this.latch = latch;
      this.objectPool = objectPool;
    }

    public void Go()
    {
      latch.Release();
      sync.Acquire();
      gone = true;
      sync.Release();
    }

    public void UsePool()
    {
      gotFromPool = objectPool.BorrowObject();
      latch.Release();
    }
  }

  #endregion

  /// <summary>
  /// Unit tests for the SimplePool class.
  /// </summary>
  [TestFixture]
  public sealed class SimplePoolTests
  {
    #region Inner Class : MyFactory (IPoolableObjectFactory implementation)

      private sealed class MyFactory : IPoolableObjectFactory
    {
      public object MakeObject()
      {
        return new object();
      }

            public void DestroyObject(object o)
      {
      }

            public bool ValidateObject(object o)
      {
        return true;
      }

      public void ActivateObject(object o)
      {
      }

            public void PassivateObject(object o)
      {
      }
    }

    #endregion

    private MockRepository mocks;
    private IPoolableObjectFactory factory;
    private SimplePool pool;

    [SetUp]
    public void SetUp()
    {
      mocks = new MockRepository();
            factory = (IPoolableObjectFactory) mocks.DynamicMock(typeof(IPoolableObjectFactory));
        Expect.Call(factory.MakeObject()).Return(new object()).Repeat.Any();

            mocks.ReplayAll();
            pool = new SimplePool(factory, 1);

            mocks.BackToRecordAll();
    }


    [Test]
    [ExpectedException(typeof (ArgumentNullException))]
    public void InstantiateWithNullPoolableObjectFactory()
    {
      new SimplePool(null, 10);
    }

    [Test]
    [ExpectedException(typeof (ArgumentException))]
    public void InstantiateSpecifyingZeroPooledItems()
    {
      new SimplePool(factory, 0);
    }

    [Test]
    [ExpectedException(typeof (ArgumentException))]
    public void InstantiateSpecifyingNegativePooledItems()
    {
      new SimplePool(factory, -10000);
    }

    [Test]
    public void ActivateOnObjectOnBorrow()
    {
        Expect.Call(factory.ValidateObject(null)).IgnoreArguments().Return(true).Repeat.Any();
        factory.ActivateObject(null);
        LastCall.IgnoreArguments();
            mocks.ReplayAll();

      Assert.AreEqual(0, pool.NumActive, "active wrong");
      Assert.AreEqual(1, pool.NumIdle, "idle wrong");
      pool.BorrowObject();
      Assert.AreEqual(1, pool.NumActive, "active wrong");
      Assert.AreEqual(0, pool.NumIdle, "idle wrong");
            mocks.VerifyAll();
    }

        // TODO fix test!!!
    [Test]
        [Ignore("Cannot figure out why this is failing?")]
    public void PassivateBusyObjectsBeforeClose()
    {
            Expect.Call(factory.ValidateObject(null)).IgnoreArguments().Return(true).Repeat.Any();
            object o = pool.BorrowObject();
      factory.PassivateObject(o);
            mocks.ReplayAll();

            pool.Close();
            mocks.VerifyAll();
        }

    [Test, ExpectedException(typeof (PoolException))]
    public void NoMoreUsableAfterClose()
    {
            object o = pool.BorrowObject();
            factory.PassivateObject(o);
            mocks.ReplayAll();

            pool.Close();
            pool.BorrowObject();
            mocks.VerifyAll();
        }

    [Test, ExpectedException(typeof (PoolException))]
    public void ThrowsExceptionWhenOutOfItemsBecauseFailedValidation()
    {
        object o = new object();
        Expect.Call(factory.MakeObject()).Return(o);
      Expect.Call(factory.ValidateObject(o)).Return(false);
        mocks.ReplayAll();

      pool = new SimplePool(factory, 1);
      pool.BorrowObject();
            mocks.VerifyAll();
        }

    [Test]
    public void PassivateObjectOnReturn()
    {
            Expect.Call(factory.ValidateObject(null)).IgnoreArguments().Return(true).Repeat.Any();
            factory.PassivateObject(null);
        LastCall.IgnoreArguments();
            mocks.ReplayAll();

      pool.ReturnObject(pool.BorrowObject());
            mocks.VerifyAll();
        }

    [Test]
    public void DestroyObjectOnClose()
    {
            Expect.Call(factory.ValidateObject(null)).IgnoreArguments().Return(true).Repeat.Any();
            factory.DestroyObject(null);
        LastCall.IgnoreArguments();
            mocks.ReplayAll();

      pool.BorrowObject();
      pool.Close();
    }

    [Test]
    public void WaitOnBorrowWhenExausted()
    {
      int n = 100;
      object[] objects = new object[n];
      pool = new SimplePool(new MyFactory(), n);
      for (int i = 0; i < n; i++)
      {
        objects[i] = pool.BorrowObject();
      }
      Latch latch = new Latch();
      ISync sync = new Latch();
      Helper helper = new Helper(latch, sync, pool);
      Thread thread = new Thread(new ThreadStart(helper.UsePool));
      thread.Start();
      Assert.AreEqual(n, pool.NumActive);
      Assert.AreEqual(0, pool.NumIdle);
      object released = objects[n - 1];
      pool.ReturnObject(released);
      latch.Acquire();
      Assert.AreEqual(n, pool.NumActive);
      Assert.AreEqual(0, pool.NumIdle);
      Assert.IsNotNull(helper.gotFromPool, "helper did not get from pool");
      Assert.AreSame(released, helper.gotFromPool, "got unexpected object");
    }
  }

  [TestFixture]
  public sealed class StessSimplePool
  {
    public sealed class QueryPerformance
    {
      public interface IQueried
      {
        void Run();
      }

      [DllImport("KERNEL32")]
      private static extern bool QueryPerformanceCounter(ref long lpPerformanceCount);

      [DllImport("KERNEL32")]
      private static extern bool QueryPerformanceFrequency(ref long lpFrequency);

      public static float Query(IQueried queried)
      {
        long frequency = 0;
        QueryPerformanceFrequency(ref frequency);

        long startTime = 0;
        QueryPerformanceCounter(ref startTime);

        queried.Run();

        long endTime = 0;
        QueryPerformanceCounter(ref endTime);

        float elapsed = (float) (endTime - startTime)/frequency;
        //            Console.WriteLine("{0:0000.000}ms ", elapsed);
        //            Console.ReadLine();
        return elapsed;
      }
    }

    private sealed class Pooled : IPoolableObjectFactory, QueryPerformance.IQueried
    {
      private int creationTime;
      private int executionTime;

      public Pooled(int creationTime, int executionTime)
      {
        this.creationTime = creationTime;
        this.executionTime = executionTime;
        Thread.Sleep(creationTime);
      }

      public void Run()
      {
        Thread.Sleep(executionTime);
      }

      public object MakeObject()
      {
        return new Pooled(creationTime, executionTime);
      }

      public void DestroyObject(object o)
      {
      }

      public bool ValidateObject(object o)
      {
        return true;
      }

      public void ActivateObject(object o)
      {
      }

      public void PassivateObject(object o)
      {
      }
    }

    private sealed class Client : QueryPerformance.IQueried
    {
      private int repeat;
      private static int nRun = 0, created = 0;
      private int id;
      private ISync run;
      private SimplePool pool;
      public bool runned;

      public Client(int id, ISync run, SimplePool pool, int repeat)
      {
        this.run = run;
        this.pool = pool;
        this.id = id;
        lock (this.GetType())
        {
          created++;
          //Console.Out.WriteLine("#{0} created (created/run: {1}/{2})...", id, created, nRun);
        }
        this.repeat = repeat;
      }

      public void Run()
      {
        lock (this.GetType())
        {
          //Console.Out.WriteLine("#{0} running (created/run: {1}/{2})...", id, created, nRun);
          nRun++;
        }
        for (int i = 0; i < repeat; i++)
        {
          QueryPerformance.IQueried queried = pool.BorrowObject() as QueryPerformance.IQueried;
          queried.Run();
          pool.ReturnObject(queried);
          runned = true;
        }
        run.Release();
      }
    }

    private sealed class Job : QueryPerformance.IQueried
    {
      private int repeat;
      private IList clients = new ArrayList();
      private int poolSize;
      private int creationTime;
      private int clientSize;
      private ISync run;
      private int executionTime;

      public Job(int size, int creationTime, int clientSize, ISync start, int executionTime, int repeat)
      {
        this.poolSize = size;
        this.creationTime = creationTime;
        this.clientSize = clientSize;
        this.run = start;
        this.executionTime = executionTime;
        this.repeat = repeat;
      }

      public void Run()
      {
        SimplePool pool = new SimplePool(new Pooled(creationTime, executionTime), poolSize);
        for (int i = 0; i < clientSize; i++)
        {
          Client client = new Client(i, run, pool, repeat);
          Thread thread = new Thread(new ThreadStart(client.Run));
          thread.Start();
          clients.Add(client);
        }
        run.Acquire();

        foreach (Client client in clients)
          Assert.IsTrue(client.runned, "\nclient " + clients.IndexOf(client) + " not runned");
      }

      public static string Do(int poolSize, int clientSize, int executionTime, int repeat, int creationTime)
      {
        ISync start = new Spring.Threading.Semaphore(-(clientSize - 1));
        Job job = new Job(poolSize, creationTime, clientSize, start, executionTime, repeat);
        float elapsed = QueryPerformance.Query(job);
        return String.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5:0.000} ",
                             creationTime, executionTime, poolSize, clientSize, repeat, elapsed);
      }
    }

    [Test, Ignore("a try for a stress")]
    public void ScalingAgainstIncreasingNumberOfThreads()
    {
      Console.Out.WriteLine("creationTime\texecutionTime\tpoolSize\tclientSize\trepeat\telapsed");

      Console.Out.WriteLine("ramp pools size");
      Console.Out.WriteLine(Job.Do(10, 1000, 100, 1, 1));
      Console.Out.WriteLine(Job.Do(100, 1000, 100, 1, 1));
      Console.Out.WriteLine(Job.Do(200, 1000, 100, 1, 1));
      Console.Out.WriteLine(Job.Do(500, 1000, 100, 1, 1));
      Console.Out.WriteLine(Job.Do(1000, 1000, 100, 1, 1));

      Console.Out.WriteLine("ramp client size");
      Console.Out.WriteLine(Job.Do(10, 10, 100, 1, 1));
      Console.Out.WriteLine(Job.Do(10, 100, 100, 1, 1));
      Console.Out.WriteLine(Job.Do(10, 200, 100, 1, 1));
      Console.Out.WriteLine(Job.Do(10, 1000, 100, 1, 1));

      Console.Out.WriteLine("ramp load");
      Console.Out.WriteLine(Job.Do(10, 10, 100, 1, 1));
      Console.Out.WriteLine(Job.Do(10, 10, 100, 5, 1));
      Console.Out.WriteLine(Job.Do(10, 10, 100, 10, 1));
      Console.Out.WriteLine(Job.Do(10, 10, 100, 50, 1));
      Console.Out.WriteLine(Job.Do(10, 10, 100, 100, 1));

      Console.Out.WriteLine("ramp client size - 2");
      Console.Out.WriteLine(Job.Do(10, 1, 100, 1, 1));
      Console.Out.WriteLine(Job.Do(10, 5, 100, 5, 1));
      Console.Out.WriteLine(Job.Do(10, 10, 100, 10, 1));
      Console.Out.WriteLine(Job.Do(10, 50, 100, 50, 1));
      Console.Out.WriteLine(Job.Do(10, 100, 100, 100, 1));
      Console.Out.WriteLine(Job.Do(10, 1000, 100, 100, 1));
    }
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.