package org.jboss.cache.multiplexer;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;

import org.jboss.cache.TreeCache;
import org.jgroups.JChannel;
import org.w3c.dom.Element;

import junit.framework.TestCase;

/**
 * Tests that JBC starts correctly even if the multiplexer
 * configuration is incorrect.
 * 
 * @author <a href="brian.stansberry@jboss.com">Brian Stansberry</a>
 * @version $Revision: 2825 $
 */
public class BadMuxConfigTest extends TestCase
{
   private MultiplexerTestHelper muxHelper;
   private TreeCache cache;
   private boolean cacheStarted;

   protected void setUp() throws Exception
   {
      muxHelper = new MultiplexerTestHelper();
      cache = new TreeCache();
      cache.setCacheMode("REPL_SYNC");
      cache.setClusterProperties(JChannel.DEFAULT_PROTOCOL_STACK);
      cacheStarted = false;
      
      super.setUp();
   }

   public void tearDown() throws Exception
   {
      try
      {
         super.tearDown();
         if (cacheStarted && cache != null)
         {
            cache.stopService();
            cache.destroyService();
         }         
      }
      finally
      {
         if (muxHelper != null)
         {
            muxHelper.tearDown();
            muxHelper = null;
         }
      }
   }
   
   public void testValidMuxConfig() throws Exception
   {
      muxHelper.configureCacheForMux(cache);
      
      checkStart(false, true);      
   }
   
   public void testWrongMBeanServer() throws Exception
   {
      Element el = MultiplexerTestHelper.getClusterConfigElement(cache.getClusterProperties());
      ObjectName on = muxHelper.createMuxChannelFactory(el);
      cache.setMultiplexerService(on.getCanonicalName());
      cache.setMultiplexerStack(MultiplexerTestHelper.MUX_STACK);
      
      MBeanServer wrong = 
         MBeanServerFactory.createMBeanServer("wrong");
      try
      {
         wrong.registerMBean(cache, new ObjectName("jboss.cache:service=MuxTest"));
         checkStart(false, false);
      }
      finally
      {
         MBeanServerFactory.releaseMBeanServer(wrong);
      }
   }
   
   public void testBadMuxServiceName() throws Exception
   {
      muxHelper.configureCacheForMux(cache);
      // This creates a non-conformant ObjectName
      String badName = cache.getMultiplexerService() + ",bad";
      cache.setMultiplexerService(badName);
      
      checkStart(false, false);
   }
   
   public void testInvalidMuxServiceName() throws Exception
   {
      muxHelper.configureCacheForMux(cache);
      // This is a valid but non-existent ObjectName
      String badName = cache.getMultiplexerService() + ",type=invalid";
      cache.setMultiplexerService(badName);
      
      checkStart(false, false);      
   }
   
   public void testMissingMuxServiceName() throws Exception
   {
      muxHelper.configureCacheForMux(cache);
      cache.setMultiplexerService(null);
      
      checkStart(false, false);       
   }
   
   public void testInvalidStackName() throws Exception
   {
      muxHelper.configureCacheForMux(cache);
      cache.setMultiplexerStack("bogus");
      
      checkStart(false, false);      
   }
   
   public void testMissingStackName() throws Exception
   {
      muxHelper.configureCacheForMux(cache);
      cache.setMultiplexerStack(null);
      
      checkStart(false, false);      
   }

   private void checkStart(boolean expectFail, boolean expectMux)
   {
      try
      {
         cache.startService();
         cacheStarted = true;
         if (expectFail)
            fail("Start did not fail as expected");
         
         if (expectMux)
            assertTrue("Cache is using mux", cache.isUsingMultiplexer());
         else
            assertFalse("Cache is not using mux ", cache.isUsingMultiplexer());
      }
      catch (Exception e)
      {
         if (!expectFail)
            fail("Caught exception starting cache " + e.getLocalizedMessage());
      }
      
   }
}
