/*
 * 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
{

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

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

        try
        {
            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);
        }
        finally
        {
            cleanup(caches);
        }
    }

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

        try
        {
            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);
        }
        finally
        {
            cleanup(caches);
        }
    }

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

        try
        {
            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);
        }
        finally
        {
            cleanup(caches);
        }
    }

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

        try
        {
            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);
        }
        finally
        {
            cleanup(caches);
        }
    }
}
