package org.infinispan.distribution;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
import static org.testng.AssertJUnit.fail;
import org.infinispan.statetransfer.OutdatedTopologyException;
import org.infinispan.test.AbstractInfinispanTest;
import org.infinispan.test.Exceptions;
import org.infinispan.topology.CacheTopology;
import org.mockito.Mockito;
import org.testng.annotations.Test;
/**
* Unit test for {@link TriangleOrderManager}.
*
* @author Pedro Ruivo
* @since 9.0
*/
@Test(groups = "unit", testName = "distribution.TriangleOrderManagerTest")
public class TriangleOrderManagerTest extends AbstractInfinispanTest {
private static CacheTopology mockCacheTopology(int topologyId) {
CacheTopology mock = Mockito.mock(CacheTopology.class);
Mockito.when(mock.getTopologyId()).thenReturn(topologyId);
return mock;
}
public void testInvalidTopologyId() {
TriangleOrderManager triangleOrderManager = new TriangleOrderManager(4);
triangleOrderManager.updateCacheTopology(mockCacheTopology(1));
try {
triangleOrderManager.next(0, 0);
fail("Exception expected!");
} catch (OutdatedTopologyException e) {
Exceptions.assertException(OutdatedTopologyException.class, e);
}
try {
triangleOrderManager.next(1, 2);
fail("Exception expected!");
} catch (OutdatedTopologyException e) {
Exceptions.assertException(OutdatedTopologyException.class, e);
}
}
public void testSequence() {
TriangleOrderManager triangleOrderManager = new TriangleOrderManager(4);
triangleOrderManager.updateCacheTopology(mockCacheTopology(0));
assertEquals(1, triangleOrderManager.next(0, 0));
assertEquals(1, triangleOrderManager.next(1, 0));
assertEquals(2, triangleOrderManager.next(1, 0));
}
public void testSequenceWithTopologyChange() {
int topologyId = 1;
TriangleOrderManager triangleOrderManager = new TriangleOrderManager(5);
triangleOrderManager.updateCacheTopology(mockCacheTopology(topologyId));
assertEquals(1, triangleOrderManager.next(1, topologyId));
assertEquals(2, triangleOrderManager.next(1, topologyId));
triangleOrderManager.updateCacheTopology(mockCacheTopology(++topologyId));
assertEquals(1, triangleOrderManager.next(1, topologyId));
assertEquals(2, triangleOrderManager.next(1, topologyId));
assertEquals(1, triangleOrderManager.next(4, topologyId));
triangleOrderManager.updateCacheTopology(mockCacheTopology(++topologyId));
assertEquals(1, triangleOrderManager.next(1, topologyId));
assertEquals(1, triangleOrderManager.next(2, topologyId));
assertEquals(1, triangleOrderManager.next(3, topologyId));
assertEquals(1, triangleOrderManager.next(4, topologyId));
}
public void testDeliverOrder() {
TriangleOrderManager triangleOrderManager = new TriangleOrderManager(4);
triangleOrderManager.updateCacheTopology(mockCacheTopology(0));
assertTrue(triangleOrderManager.isNext(1, 1, 0));
assertFalse(triangleOrderManager.isNext(1, 2, 0));
assertFalse(triangleOrderManager.isNext(1, 3, 0));
triangleOrderManager.markDelivered(1, 1, 0);
assertTrue(triangleOrderManager.isNext(1, 2, 0));
assertFalse(triangleOrderManager.isNext(1, 3, 0));
triangleOrderManager.markDelivered(1, 2, 0);
assertTrue(triangleOrderManager.isNext(1, 3, 0));
triangleOrderManager.markDelivered(1, 3, 0);
triangleOrderManager.markDelivered(2, 1, 0);
triangleOrderManager.markDelivered(3, 1, 0);
triangleOrderManager.markDelivered(3, 2, 0);
}
public void testUnblockOldTopology() {
TriangleOrderManager triangleOrderManager = new TriangleOrderManager(4);
triangleOrderManager.updateCacheTopology(mockCacheTopology(1));
//same topology, but incorrect sequence number
assertFalse(triangleOrderManager.isNext(0, 2, 1));
//lower topology. should unlock everything
triangleOrderManager.updateCacheTopology(mockCacheTopology(2));
assertTrue(triangleOrderManager.isNext(0, 2, 1));
//higher topology than current one, everything is blocked
assertFalse(triangleOrderManager.isNext(0, 1, 3));
//unlocks everything (correct sequence number)
triangleOrderManager.updateCacheTopology(mockCacheTopology(3));
assertTrue(triangleOrderManager.isNext(0, 1, 3));
}
}