/*
 * JBoss, Home of Professional Open Source
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package org.jboss.cache.buddyreplication;

import org.jboss.cache.TreeCache;
import org.jboss.cache.misc.TestingUtil;

/**
 * Tests how groups are formed and disbanded
 *
 * @author <a href="mailto:manik@jboss.org">Manik Surtani (manik@jboss.org)</a>
 */
public class BuddyGroupAssignmentTest extends BuddyReplicationTestsBase
{
   private TreeCache[] caches;

   protected void tearDown() throws Exception
   {
      System.out.println("*** In tearDown()");
      cleanup(caches);
   }


   public void testSingleBuddy() throws Exception
   {
      caches = createCaches(3, false);

      for (int i = 0; i < caches.length; i++)
      {
         printBuddyGroup(caches[i]);
      }

      System.out.println("*** Testing cache 0:");
      assertIsBuddy(caches[0], caches[1], true);
      System.out.println("*** Testing cache 1:");
      assertIsBuddy(caches[1], caches[2], true);
      System.out.println("*** Testing cache 2:");
      assertIsBuddy(caches[2], caches[0], true);
   }

   public void test2Buddies() throws Exception
   {
      caches = createCaches(2, 3, false);

      System.out.println("*** Testing cache 0");
      assertIsBuddy(caches[0], caches[1], false);
      assertIsBuddy(caches[0], caches[2], false);
      System.out.println("*** Testing cache 1");
      assertIsBuddy(caches[1], caches[2], false);
      assertIsBuddy(caches[1], caches[0], false);
      System.out.println("*** Testing cache 2");
      assertIsBuddy(caches[2], caches[1], false);
      assertIsBuddy(caches[2], caches[0], false);
   }

   public void testRemovalFromClusterSingleBuddy() throws Exception
   {
      caches = createCaches(3, false);

      System.out.println("*** Testing cache 0");
      assertIsBuddy(caches[0], caches[1], true);
      System.out.println("*** Testing cache 1");
      assertIsBuddy(caches[1], caches[2], true);
      System.out.println("*** Testing cache 2");
      assertIsBuddy(caches[2], caches[0], true);

      // now remove a cache from the cluster
      caches[1].stopService();
      caches[1] = null;

      TestingUtil.sleepThread(getSleepTimeout());

      // now test new buddy groups
      System.out.println("*** Testing cache 0");
      assertIsBuddy(caches[0], caches[2], true);
      System.out.println("*** Testing cache 2");
      assertIsBuddy(caches[2], caches[0], true);
      System.out.println("*** Completed successfully ***");
      assertNoLocks(caches);
   }

   public void testRemovalFromCluster2Buddies() throws Exception
   {
      caches = createCaches(2, 4, false);
      assertNoLocks(caches);

      System.out.println("*** Testing cache 0");
      assertIsBuddy(caches[0], caches[1], false);
      assertIsBuddy(caches[0], caches[2], false);
      System.out.println("*** Testing cache 1");
      assertIsBuddy(caches[1], caches[2], false);
      assertIsBuddy(caches[1], caches[3], false);
      System.out.println("*** Testing cache 2");
      assertIsBuddy(caches[2], caches[3], false);
      assertIsBuddy(caches[2], caches[0], false);
      System.out.println("*** Testing cache 3");
      assertIsBuddy(caches[3], caches[0], false);
      assertIsBuddy(caches[3], caches[1], false);

      // now remove a cache from the cluster
      caches[1].stopService();
      caches[1] = null;

      TestingUtil.sleepThread(getSleepTimeout());

      // now test new buddy groups
      System.out.println("*** Testing cache 0");
      assertIsBuddy(caches[0], caches[2], false);
      assertIsBuddy(caches[0], caches[3], false);
      System.out.println("*** Testing cache 2");
      assertIsBuddy(caches[2], caches[3], false);
      assertIsBuddy(caches[2], caches[0], false);
      System.out.println("*** Testing cache 3");
      assertIsBuddy(caches[3], caches[0], false);
      assertIsBuddy(caches[3], caches[2], false);
      assertNoLocks(caches);
   }
}
