Package com.nokia.dempsy.container

Source Code of com.nokia.dempsy.container.TestInstanceManager$OutputTestMP

/*
* Copyright 2012 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.
*/

package com.nokia.dempsy.container;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.List;

import org.junit.After;
import org.junit.Test;

import com.nokia.dempsy.Dispatcher;
import com.nokia.dempsy.annotations.Activation;
import com.nokia.dempsy.annotations.MessageHandler;
import com.nokia.dempsy.annotations.MessageKey;
import com.nokia.dempsy.annotations.MessageProcessor;
import com.nokia.dempsy.annotations.Output;
import com.nokia.dempsy.config.ClusterId;
import com.nokia.dempsy.container.MpContainer.InstanceWrapper;
import com.nokia.dempsy.monitoring.StatsCollector;
import com.nokia.dempsy.monitoring.coda.MetricGetters;
import com.nokia.dempsy.monitoring.coda.StatsCollectorCoda;
import com.nokia.dempsy.monitoring.coda.StatsCollectorFactoryCoda;
import com.nokia.dempsy.serialization.java.JavaSerializer;


public class TestInstanceManager
{
  
   private MpContainer manager;
  
//----------------------------------------------------------------------------
//  Test classes -- must be static/public for introspection
//----------------------------------------------------------------------------

   public static class MessageOne
   {
      private Integer keyValue;

      public MessageOne(int keyValue)
      {
         this.keyValue = Integer.valueOf(keyValue);
      }

      @MessageKey
      public Integer getKey()
      {
         return keyValue;
      }
   }


   public static class MessageTwo
   {
      private Integer keyValue;

      public MessageTwo(int keyValue)
      {
         this.keyValue = Integer.valueOf(keyValue);
      }

      @MessageKey
      public Integer getKey()
      {
         return keyValue;
      }
   }


   @MessageProcessor
   public static class CombinedMP
   implements Cloneable
   {
      public long activationCount;
      public long activationTime;

      public long firstMessageTime = -1;
      public List<Object> messages; // note: can't be shared

      @Override
      public CombinedMP clone()
      throws CloneNotSupportedException
      {
         return (CombinedMP)super.clone();
      }

      @Activation
      public void activate(byte[] data)
      {
         activationCount++;
         activationTime = System.nanoTime();

         messages = new ArrayList<Object>();
      }

      @MessageHandler
      public String handle(MessageOne message)
      {
         if (firstMessageTime < 0)
            firstMessageTime = System.nanoTime();
         messages.add(message);
         return "MessageOne";
      }

      @MessageHandler
      public String handle(MessageTwo message)
      {
         if (firstMessageTime < 0)
            firstMessageTime = System.nanoTime();
         messages.add(message);
         return "MessageTwo";
      }
   }


   @MessageProcessor
   public static class OutputTestMP
   extends CombinedMP
   {
      public long outputTime;

      @Override
      public OutputTestMP clone()
      throws CloneNotSupportedException
      {
         return (OutputTestMP)super.clone();
      }

      @Output
      public int doOutput()
      {
         outputTime = System.nanoTime();
         return 42;
      }
   }


   @MessageProcessor
   public static class UnsuportedMessageTestMP
   implements Cloneable
   {
      @Override
      public UnsuportedMessageTestMP clone()
      throws CloneNotSupportedException
      {
         return (UnsuportedMessageTestMP)super.clone();
      }

      @MessageHandler
      public void handle(MessageOne message)
      {
         // this method will never get called
      }
   }


   public static class MessageWithNullKey
   {
      @MessageKey
      public Integer getKey()
      {
         return null;
      }
   }


   @MessageProcessor
   public static class NullKeyTestMP
   implements Cloneable
   {
      @Override
      public NullKeyTestMP clone()
      throws CloneNotSupportedException
      {
         return (NullKeyTestMP)super.clone();
      }

      @MessageHandler
      public void handle(MessageWithNullKey message)
      {
         // this method will never get called
      }
   }

   public static class DummyDispatcher implements Dispatcher
   {
      public Object lastDispatched;

      @Override
      public void dispatch(Object message)
      {
         this.lastDispatched = message;
      }
     
      @Override
      public ClusterId getThisClusterId() { return null; }
   }


//----------------------------------------------------------------------------
//  Test Cases
//----------------------------------------------------------------------------
  
   public MpContainer setupContainer(Object prototype) throws ContainerException
   {
      DummyDispatcher dispatcher = new DummyDispatcher();
      StatsCollector stats = new StatsCollectorCoda(new ClusterId("test", "test"), new StatsCollectorFactoryCoda().getNamingStrategy());
      JavaSerializer<Object> serializer = new JavaSerializer<Object>();

      manager = new MpContainer(new ClusterId("test","test"));
      manager.setDispatcher(dispatcher);
      manager.setStatCollector(stats);
      manager.setSerializer(serializer);
      manager.setPrototype(prototype);
      return manager;
   }
  
   @After
   public void tearDown()
   {
      // Destroy any counts, so we start fresh on the next test
      StatsCollector stats = manager.getStatsCollector();
      if (stats != null)
      {
         ((StatsCollectorCoda)stats).stop();
      }
   }

   @Test
   public void testSingleInstanceOneMessage() throws Throwable
   {
      CombinedMP prototype = new CombinedMP();
      MpContainer manager = setupContainer(prototype);
     
      assertEquals("starts with no instances", 0, manager.getProcessorCount());

      MessageOne message = new MessageOne(123);
      InstanceWrapper wrapper = manager.getInstanceForDispatch(message);
      assertEquals("instance was created", 1, manager.getProcessorCount());

      CombinedMP instance = (CombinedMP)wrapper.getInstance();
      // activation is now inline with insantiation so it's active immediately
//      assertEquals("instance not already activated", 0, instance.activationCount);
      assertEquals("instance activated", 1, instance.activationCount);
      assertEquals("instance has no existing messages", -1, instance.firstMessageTime);
//      assertNull("instance has no message list", instance.messages);
      assertTrue("real activation time", instance.activationTime > 0);
      assertEquals("message count", 0, instance.messages.size());

      // dispatch the message
//      wrapper.run();
      manager.dispatch(message, true);
      assertEquals("instance activated", 1, instance.activationCount);
      assertTrue("real activation time", instance.activationTime > 0);
      assertSame("instance received message", message, instance.messages.get(0));
      assertEquals("message count", 1, instance.messages.size());
      assertTrue("activated before first message", instance.activationTime < instance.firstMessageTime);
      assertEquals("MessageOne",((DummyDispatcher)manager.getDispatcher()).lastDispatched);

      assertEquals("prototype not activated", 0, prototype.activationCount);
      assertEquals("prototype did not receive messages", -1, prototype.firstMessageTime);
      assertNull("prototype has no message list", prototype.messages);
   }


   @Test
   public void testSingleInstanceTwoMessagesSameClassSeparateExecution()
   throws Exception
   {
      CombinedMP prototype = new CombinedMP();
      MpContainer manager = setupContainer(prototype);
      DummyDispatcher dispatcher = ((DummyDispatcher)manager.getDispatcher());
     
      assertEquals("starts with no instances", 0, manager.getProcessorCount());

      MessageOne message1 = new MessageOne(123);
      InstanceWrapper wrapper1 = manager.getInstanceForDispatch(message1);
      manager.dispatch(message1, false);
      CombinedMP instance = (CombinedMP)wrapper1.getInstance();

      assertEquals("instance was created", 1, manager.getProcessorCount());

      assertEquals("instance activated", 1, instance.activationCount);
      assertTrue("real activation time", instance.activationTime > 0);
      assertSame("instance received message", message1, instance.messages.get(0));
      assertEquals("message count", 1, instance.messages.size());
      assertTrue("activated before first message", instance.activationTime < instance.firstMessageTime);
      assertEquals("MessageOne",dispatcher.lastDispatched);

      MessageOne message2 = new MessageOne(123);
      InstanceWrapper wrapper2 = manager.getInstanceForDispatch(message2);
      manager.dispatch(message2, false);
      assertSame("same wrapper returned for second message", wrapper1, wrapper2);
      assertEquals("no other instance was created", 1, manager.getProcessorCount());

      assertEquals("no second activation", 1, instance.activationCount);
      assertEquals("both messages delivered", 2, instance.messages.size());
      assertSame("message1 delivered first", message1, instance.messages.get(0));
      assertSame("message2 delivered second", message2, instance.messages.get(1));
      assertEquals("MessageOne",dispatcher.lastDispatched);
   }


   @Test
   public void testSingleInstanceTwoMessagesSameClassCombinedExecution()
   throws Exception
   {
      CombinedMP prototype = new CombinedMP();
      MpContainer manager = setupContainer(prototype);
      DummyDispatcher dispatcher = ((DummyDispatcher)manager.getDispatcher());

      assertEquals("starts with no instances", 0, manager.getProcessorCount());

      MessageOne message1 = new MessageOne(123);
      InstanceWrapper wrapper = manager.getInstanceForDispatch(message1);
      manager.dispatch(message1,false);
      assertEquals("instance was created", 1, manager.getProcessorCount());
      MessageOne message2 = new MessageOne(123);
      assertSame("same wrapper returned for second message",
                 wrapper, manager.getInstanceForDispatch(message2));
      manager.dispatch(message2, false);

      CombinedMP instance = (CombinedMP)wrapper.getInstance();
      assertEquals("no other instance was created", 1, manager.getProcessorCount());

      assertEquals("instance activated", 1, instance.activationCount);
      assertTrue("real activation time", instance.activationTime > 0);
      assertTrue("activated before first message", instance.activationTime < instance.firstMessageTime);
      assertEquals("both messages delivered", 2, instance.messages.size());
      assertSame("message1 delivered first", message1, instance.messages.get(0));
      assertSame("message2 delivered second", message2, instance.messages.get(1));
      assertEquals("MessageOne",dispatcher.lastDispatched);
   }


   @Test
   public void testSingleInstanceTwoMessagesDifferentClassSeparateExecution()
   throws Exception
   {
      CombinedMP prototype = new CombinedMP();
      MpContainer manager = setupContainer(prototype);
      DummyDispatcher dispatcher = ((DummyDispatcher)manager.getDispatcher());

      assertEquals("starts with no instances", 0, manager.getProcessorCount());

      MessageOne message1 = new MessageOne(123);
      InstanceWrapper wrapper = manager.getInstanceForDispatch(message1);
      manager.dispatch(message1, true);
      CombinedMP instance = (CombinedMP)wrapper.getInstance();

      assertEquals("instance was created", 1, manager.getProcessorCount());

      assertEquals("instance activated", 1, instance.activationCount);
      assertTrue("real activation time", instance.activationTime > 0);
      assertSame("instance received message", message1, instance.messages.get(0));
      assertEquals("message count", 1, instance.messages.size());
      assertTrue("activated before first message", instance.activationTime < instance.firstMessageTime);
      assertEquals("MessageOne",dispatcher.lastDispatched);

      MessageTwo message2 = new MessageTwo(123);
      assertSame("same wrapper returned for second message",
                 wrapper, manager.getInstanceForDispatch(message2));
      manager.dispatch(message2, false);
      assertEquals("no other instance was created", 1, manager.getProcessorCount());

      assertEquals("no second activation", 1, instance.activationCount);
      assertEquals("both messages delivered", 2, instance.messages.size());
      assertSame("message1 delivered first", message1, instance.messages.get(0));
      assertSame("message2 delivered second", message2, instance.messages.get(1));
      assertEquals("MessageTwo",dispatcher.lastDispatched);
   }


   @Test
   public void testMultipleInstanceCreation() throws Exception
   {
      CombinedMP prototype = new CombinedMP();
      MpContainer manager = setupContainer(prototype);
      DummyDispatcher dispatcher = ((DummyDispatcher)manager.getDispatcher());

      assertEquals("starts with no instances", 0, manager.getProcessorCount());

      MessageOne message1 = new MessageOne(123);
      InstanceWrapper wrapper1 = manager.getInstanceForDispatch(message1);
      manager.dispatch(message1, true);
      CombinedMP instance1 = (CombinedMP)wrapper1.getInstance();

      MessageOne message2 = new MessageOne(456);
      InstanceWrapper wrapper2 = manager.getInstanceForDispatch(message2);
      manager.dispatch(message2, false);
      CombinedMP instance2 = (CombinedMP)wrapper2.getInstance();

      assertEquals("instances were created", 2, manager.getProcessorCount());

      assertEquals("MessageOne",dispatcher.lastDispatched);

      assertEquals("message count to instance1", 1, instance1.messages.size());
      assertEquals("message count to instance2", 1, instance2.messages.size());

      assertSame("message1 went to instance1", message1, instance1.messages.get(0));
      assertSame("message2 went to instance2", message2, instance2.messages.get(0));
      assertEquals("MessageOne",dispatcher.lastDispatched);
   }


   @Test
   public void testOutput() throws Exception
   {
      OutputTestMP prototype = new OutputTestMP();
      MpContainer instanceManager = setupContainer(prototype);
      DummyDispatcher dispatcher = ((DummyDispatcher)instanceManager.getDispatcher());

      // we need to dispatch messages to create MP instances
      MessageOne message1 = new MessageOne(1);
      InstanceWrapper wrapper1 = instanceManager.getInstanceForDispatch(message1);
      instanceManager.dispatch(message1, true);
      MessageOne message2 = new MessageOne(2);
      InstanceWrapper wrapper2 = instanceManager.getInstanceForDispatch(message2);
      instanceManager.dispatch(message2, true);
      assertEquals("MessageOne",dispatcher.lastDispatched);

      instanceManager.outputPass();

      OutputTestMP mp1 = (OutputTestMP)wrapper1.getInstance();
      assertTrue("MP1 output did not occur after activation", mp1.activationTime < mp1.outputTime);

      OutputTestMP mp2 = (OutputTestMP)wrapper2.getInstance();
      assertTrue("MP2 output did not occur after activation", mp2.activationTime < mp2.outputTime);
      assertTrue(mp1 != mp2);

      assertEquals(new Integer(42),dispatcher.lastDispatched);
   }


   @Test
   public void testOutputShortCircuitsIfWrongClass() throws Exception
   {
      OutputTestMP prototype = new OutputTestMP();
      MpContainer instanceManager = setupContainer(prototype);
      DummyDispatcher dispatcher = ((DummyDispatcher)instanceManager.getDispatcher());

      // we need to dispatch messages to create MP instances
      MessageOne message1 =new MessageOne(1);
      MessageOne message2 =new MessageOne(2);
      instanceManager.dispatch(message1, true);
      instanceManager.dispatch(message2, false);
      assertEquals("MessageOne",dispatcher.lastDispatched);
     
      instanceManager.outputPass();
      assertEquals("number of processed messages should include outputs.", 4, ((MetricGetters)instanceManager.getStatsCollector()).getProcessedMessageCount());
   }


   @Test
   public void testOutputShortCircuitsIfNoOutputMethod() throws Exception
   {
      CombinedMP prototype = new CombinedMP();
      MpContainer instanceManager = setupContainer(prototype);
      DummyDispatcher dispatcher = ((DummyDispatcher)instanceManager.getDispatcher());

      // we need to dispatch messages to create MP instances
      MessageOne message1 =new MessageOne(1);
      MessageOne message2 =new MessageOne(2);
      instanceManager.dispatch(message1, true);
      instanceManager.dispatch(message2, false);
      assertEquals("MessageOne",dispatcher.lastDispatched);
     
      instanceManager.outputPass();
      // output messages are NOT considered "processed" if there is no output method on the MP.
      assertEquals("number of processed messages should include outputs.", 2, ((MetricGetters)instanceManager.getStatsCollector()).getProcessedMessageCount());
   }

   // This test no longer really matters since there is no queue but we might as well leave it
   //  since it exercises the container.
   @Test
   public void testQueueIsClearedAfterExecution() throws Exception
   {
      CombinedMP prototype = new CombinedMP();
      MpContainer manager = setupContainer(prototype);

      MessageOne message = new MessageOne(123);
      InstanceWrapper wrapper = manager.getInstanceForDispatch(message);
      manager.dispatch(message, false);
      assertEquals("instance was created", 1, manager.getProcessorCount());

      CombinedMP instance = (CombinedMP)wrapper.getInstance();

      assertEquals("instance activated", 1, instance.activationCount);
      assertTrue("real activation time", instance.activationTime > 0);
      assertSame("instance received message", message, instance.messages.get(0));
      assertEquals("message count", 1, instance.messages.size());
      assertTrue("activated before first message", instance.activationTime < instance.firstMessageTime);

      long activationTime = instance.activationTime;
      long firstMessageTime = instance.firstMessageTime;

// here is where the queue would have been advanced again ... but there is no queue anymore.
      assertTrue("activation time didn't change", activationTime == instance.activationTime);
      assertTrue("message time didn't change", firstMessageTime == instance.firstMessageTime);
      assertEquals("message count didn't change", 1, instance.messages.size());
   }


   @Test(expected=ContainerException.class)
   public void testFailureNullMessage() throws Exception
   {
      CombinedMP prototype = new CombinedMP();
      MpContainer manager = setupContainer(prototype);

      manager.getInstanceForDispatch(null);
   }


   @Test(expected=ContainerException.class)
   public void testFailureUnsupportedMessage() throws Exception
   {
      MpContainer dispatcher = setupContainer(new UnsuportedMessageTestMP());
      dispatcher.getInstanceForDispatch(new MessageTwo(123));
   }


   @Test(expected=ContainerException.class)
   public void testFailureNoKeyMethod() throws Exception
   {
      MpContainer dispatcher = setupContainer(new NullKeyTestMP());
      dispatcher.getInstanceForDispatch(new MessageWithNullKey());
   }
  
   @MessageProcessor
   public static class ThrowMe implements Cloneable
   {
      @MessageHandler
      public void handle(MessageOne message)
      {
         throw new RuntimeException("YO!");
      }
     
      @Override
      public Object clone() throws CloneNotSupportedException
      {
         return super.clone();
      }

   }
  
   @Test
   public void testMpThrows() throws Exception
   {
      MpContainer dispatcher = setupContainer(new ThrowMe());
     
      dispatcher.dispatch(new MessageOne(123), true);
     
      assertEquals(1,((MetricGetters)dispatcher.getStatsCollector()).getMessageFailedCount());
   }
}
TOP

Related Classes of com.nokia.dempsy.container.TestInstanceManager$OutputTestMP

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.