Ejemplo n.º 1
0
 public UnitTestThread(ThreadQueue readFrom, ThreadQueue writeTo, TimeSpan toWait, int numItems)
 {
     m_from     = readFrom;
     m_to       = writeTo;
     m_numItems = Math.Max(1, numItems);
     m_toWait   = toWait;
 }
Ejemplo n.º 2
0
 public void Add(String key, ThreadQueue value)
 {
     Dictionary.Add(key, value);
 }
Ejemplo n.º 3
0
 public UnitTestThread(ThreadQueue readFrom, ThreadQueue writeTo)
 {
     m_from = readFrom;
     m_to   = writeTo;
 }
Ejemplo n.º 4
0
//		public static void Main( string[] args )
//		{
//
//			if ( args != null && args.Length > 0 )
//			{
//				foreach( string arg in args )
//				{
//					switch( arg )
//					{
//
//						case "-unittest":
//							//
//							// Unit test
//							//
//							Environment.Exit( ThreadQueue.UnitTest() ) ;
//							break ;
//
//						default:
//							Console.WriteLine("Error: unknown argument {0}", arg ) ;
//							break ;
//					}
//				}
//			}
//		}

        public static int UnitTest()
        {
            // Generic item to produce random values
            Random rand = new Random();

            string testDescription =
                string.Format(
                    "***\n" +
                    "*** Unit test to ensure that an item only comes off of the queue once, not\n" +
                    "*** multiple times for each Remove() operation\n" +
                    "***\n");

            Console.WriteLine(testDescription);

            ArrayList   allThreads = new ArrayList();
            ArrayList   consumers  = new ArrayList();
            ThreadQueue startQueue = new ThreadQueue();
            ThreadQueue feedQueue  = new ThreadQueue();

            feedQueue.HighWater       = rand.Next(11, 250);
            feedQueue.LowWater        = rand.Next(1, feedQueue.HighWater);
            feedQueue.EnableHighWater = true;

            // Create a queue, and start running against it
            for (int i = 0; i < rand.Next(7, 23); i++)
            {
                UnitTestThread feeder =
                    new UnitTestThread(startQueue, feedQueue, new TimeSpan(Timeout.Infinite), rand.Next(1, 100));

                Thread feederThread = new Thread(new ThreadStart(feeder.Start));
                feederThread.Name = string.Format("Feeder {0}", i);

                feedQueue.AddProducer(feederThread);

                allThreads.Add(feederThread);
            }

            for (int i = 0; i < rand.Next(2, 7); i++)
            {
                // Note:, the first thread will always do one item at a time
                int numItems = i == 0 ?
                               1 :
                               rand.Next(2, 23);

                TimeSpan toWait = i == 0 ?
                                  new TimeSpan(Timeout.Infinite) :
                                  new TimeSpan(0, 0, 0, 0, rand.Next(10, 10 * 1000));

                UnitTestThread consumer =
                    new UnitTestThread(feedQueue, null, toWait, numItems);

                Thread consumerThread = new Thread(new ThreadStart(consumer.Start));
                consumerThread.Name =
                    string.Format("Consumer: {0}, numPerCall: {1}, toWait: {2}", i, numItems, toWait);

                consumers.Add(consumer);
                allThreads.Add(consumerThread);
            }


            // Queue up some items
            int totalItems = rand.Next(10 * 1000, 20 * 1000);

            Console.WriteLine("Total items to process: {0}", totalItems);
            for (int i = 0; i < totalItems; i++)
            {
                startQueue.Add(i, false);
            }

            foreach (Thread thd in allThreads)
            {
                Console.WriteLine("Starting thread: {0}...", thd.Name);
                thd.Start();
            }

            // Wait for all the threads to finish

            bool isAlive = false;

            do
            {
                Console.WriteLine(
                    "StartQueue: {0} items, FeedQueue: {1} (LowWater: {2}, HighWater: {3})",
                    startQueue.Count,
                    feedQueue.Count,
                    feedQueue.LowWater,
                    feedQueue.HighWater);

                isAlive = false;

                foreach (Thread thd in allThreads)
                {
                    isAlive |= thd.IsAlive;

                    if (isAlive)
                    {
                        break;
                    }
                }

                if (isAlive)
                {
                    Thread.Sleep(2 * 1000);
                }
            }while(isAlive);

            Console.WriteLine(
                "*Finished: StartQueue: {0} items, FeedQueue: {1}", startQueue.Count, feedQueue.Count);

            Console.WriteLine("Consumer counts: ");

            long consumerCount = 0;

            foreach (UnitTestThread consumer in consumers)
            {
                Console.WriteLine("\t{0} items", consumer.NumProcessed);

                consumerCount += consumer.NumProcessed;
            }

            if (consumerCount != totalItems)
            {
                Console.WriteLine("***\n" +
                                  "*** Failed test, consumers consumed {0} of {1} items\n" +
                                  "***\n",
                                  consumerCount, totalItems);
            }
            else
            {
                Console.WriteLine("***\n" +
                                  "*** Passed test, consumers consumed {0} of {1} items\n" +
                                  "***\n",
                                  consumerCount, totalItems);
            }

            //
            // Unit test for items flowing from one Queue to another to make sure all the
            // items get from the head to the tail
            //


            // Create several queues to shuffle the objects along
            ThreadQueue[] queues = new ThreadQueue[rand.Next(5, 15)];
            for (int i = 0; i < queues.Length; i++)
            {
                queues[i] = new ThreadQueue();
            }

            Console.WriteLine("* Created {0} queues", queues.Length);

            // Prime the first queue with some objects
            totalItems = rand.Next(10, 20000);
            for (int i = 0; i < totalItems; i++)
            {
                queues[0].Add(rand.Next(-10000, -1000).ToString(), false);
            }

            Console.WriteLine("* Primed the first queue with {0} items",
                              totalItems);

            ArrayList allThds = new ArrayList();

            Console.Write("* Threads per queue (queue number: thread count):\n*");

            // Setup threads to read from the queues and write to the next queue
            for (int i = 0; i < queues.Length - 1; i++)
            {
                int numThds;

                // Create at a minimum of threads reading from each queue
                for (numThds = 0; numThds < rand.Next(5, 30); numThds++)
                {
                    ThreadQueue    fromQueue = queues[i];
                    ThreadQueue    toQueue   = (i == queues.Length) ? null : queues[i + 1];
                    UnitTestThread test      = new UnitTestThread(fromQueue, toQueue);

                    // Create the thread
                    Thread thd = new Thread(new ThreadStart(test.Start));
                    thd.Name = String.Format("{0} -> {1}", i, i + 1);

                    if (i == 1)
                    {
                        // Make this thread a producer of itself
                        fromQueue.AddProducer(thd);
                    }

                    // Set the thread as a producer for the next queue
                    toQueue.AddProducer(thd);


                    allThds.Add(thd);
                }

//					// Add one loop that continually takes and item from it's queue and
//					// places it back up the stream some where
//
//					int  earlier	= rand.Next( 0, i - 1 ) ;
//					readFromOwn = new UnitTestThread( queues[i], queues[i+1], queues[ earlier ] );
//					loop		= new Thread( new ThreadStart(readFromOwn.Start ) ) ;
//					loop.Name	= String.Format("{0} -> {1}", i, earlier ) ;
//					allThds.Add( loop ) ;
//
//					numThds++ ;


                Console.Write(" {0}:{1},", i, numThds);
            }

            Console.WriteLine("");

            // Disable the high water on the last queue
            queues[queues.Length - 1].EnableHighWater = false;

            // Start all the threads
            foreach (Thread thd in allThds)
            {
                thd.Start();
            }

            DateTime endTime = DateTime.Now + new TimeSpan(0, 10, 0);

            // Wait for all of the elements to end up in the last queue
            while (queues[queues.Length - 1].Count < totalItems &&
                   DateTime.Now < endTime)
            {
                Thread.Sleep(5000);
                Console.WriteLine("* {0} of {1} items have arrived in the final queue (#{2})",
                                  queues[queues.Length - 1].Count,
                                  totalItems,
                                  queues.Length - 1);
            }

            int waitingThreads = 0;

            // Kill all of the threads
            foreach (Thread thd in allThds)
            {
                thd.Join(new TimeSpan(0, 0, 5));
                if (thd.IsAlive)
                {
                    if ((thd.ThreadState & System.Threading.ThreadState.WaitSleepJoin) != 0)
                    {
                        waitingThreads++;
                    }
                    thd.Abort();
                }
            }

            int itemsProcessed = queues[queues.Length - 1].Count;

            if (itemsProcessed != totalItems || waitingThreads != 0)
            {
                Console.WriteLine("* Failed test, only {0} of {1} items were processed " +
                                  " and {2} of {3} threads were waiting",
                                  itemsProcessed, totalItems, waitingThreads, allThds.Count);
            }
            else
            {
                Console.WriteLine("* Passed test, final queue has {0} of {1} items, " +
                                  "{2} of {3} threads were waiting",
                                  itemsProcessed,
                                  totalItems,
                                  waitingThreads,
                                  allThds.Count);
            }

            int toReturn = (itemsProcessed == totalItems) ? 0 : -1;

            return(toReturn);
        }