package org.jboss.cache.cluster;

import org.jboss.cache.Cache;
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.util.TestingUtil;
import org.jboss.cache.util.internals.ReplicationQueueNotifier;
import org.jboss.cache.config.Configuration;
import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import javax.transaction.TransactionManager;

@Test(groups = {"functional", "transaction"})
public class ReplicationQueueTxTest
{
   Cache cache, cache2;
   TransactionManager txManager;

   @BeforeMethod
   public void setUp() throws CloneNotSupportedException
   {
      cache = new DefaultCacheFactory().createCache(UnitTestCacheConfigurationFactory.createConfiguration(Configuration.CacheMode.REPL_ASYNC), false);
      cache.getConfiguration().setUseReplQueue(true);
      cache.getConfiguration().setReplQueueInterval(100);
      cache.getConfiguration().setReplQueueMaxElements(10);
      cache.start();
      cache2 = new DefaultCacheFactory().createCache(cache.getConfiguration().clone());

      TestingUtil.blockUntilViewsReceived(60000, cache, cache2);
      txManager = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
   }

   @AfterMethod
   public void tearDown()
   {
      TestingUtil.killCaches(cache, cache2);
   }

   public void testTransactionalReplication() throws Exception
   {
      // outside of tx scope
      cache.put("/a", "k", "v");

      ReplicationQueueNotifier replicationQueueNotifier = new ReplicationQueueNotifier(cache);
      replicationQueueNotifier.waitUntillAllReplicated(200);

      assert cache2.get("/a", "k").equals("v");

      // now, a transactional call
      txManager.begin();
      cache2.put("/a", "k", "v2");
      txManager.commit();

      ReplicationQueueNotifier replicationQueueNotifier2 = new ReplicationQueueNotifier(cache2);
      replicationQueueNotifier2.waitUntillAllReplicated(200);


      assert cache.get("/a", "k").equals("v2");
   }
}
