package pt.ul.jarmus.inst;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Phaser;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.mockito.InOrder;
import org.mockito.Mockito;
import pt.ul.armus.DeadlockInfo;
import pt.ul.jarmus.DeadlockIdentifiedException;
import pt.ul.jarmus.JArmus;
import pt.ul.jarmus.checkers.PhaserListener;
@RunWith(value = Parameterized.class)
public class PhaserTest {
PhaserListener jarmus;
InOrder inOrder;
Phaser phaser;
public PhaserTest(Phaser phaser) {
this.phaser = phaser;
}
@Parameters
public static Collection<Object[]> data() {
List<Object[]> result = new ArrayList<>();
result.add(new Object[]{new Phaser(1)});
result.add(new Object[]{new pt.ul.jarmus.ext.Phaser(1)});
return result;
}
@Before
public void setUp() throws InstantiationException, IllegalAccessException {
jarmus = Mockito.mock(PhaserListener.class);
inOrder = inOrder(jarmus);
if (phaser instanceof pt.ul.jarmus.ext.Phaser) {
((pt.ul.jarmus.ext.Phaser) phaser).setListener(jarmus);
}
PhaserObserver.aspectOf().setListener(jarmus);
}
@After
public void checkNoMoreInteractions() {
verifyNoMoreInteractions(jarmus);
}
@Test
public void phaserArrive() {
JArmus.register(phaser);
phaser.arrive();
inOrder.verify(jarmus).onArrive(phaser);
}
@Test
public void phaserAwaitAdvance() {
JArmus.register(phaser);
phaser.arrive();
phaser.awaitAdvance(0);
inOrder.verify(jarmus).onArrive(phaser);
inOrder.verify(jarmus).beforeAwaitAdvance(phaser, 0);
inOrder.verify(jarmus).afterAwaitAdvance();
}
@Test
public void phaserAwaitAdvanceException() {
DeadlockInfo deadlock = mock(DeadlockInfo.class);
doThrow(new DeadlockIdentifiedException(deadlock)).when(jarmus).beforeAwaitAdvance(phaser, 0);
JArmus.register(phaser);
phaser.arrive();
try {
phaser.awaitAdvance(0);
fail();
} catch (DeadlockIdentifiedException e) {
// should have thrown an exception
}
inOrder.verify(jarmus).onArrive(phaser);
inOrder.verify(jarmus).beforeAwaitAdvance(phaser, 0);
}
@Test
public void phaserAwaitAdvanceUnregistred() {
phaser.arrive();
phaser.awaitAdvance(0);
inOrder.verify(jarmus).onArrive(phaser);
inOrder.verify(jarmus).beforeAwaitAdvance(phaser, 0);
inOrder.verify(jarmus).afterAwaitAdvance();
}
@Test
public void phaserArriveAndAwaitAdvanceTerminate() {
JArmus.register(phaser);
phaser.forceTermination();
phaser.arriveAndAwaitAdvance();
inOrder.verify(jarmus).beforeArriveAndAwaitAdvance(phaser);
inOrder.verify(jarmus).afterArriveAndAwaitAdvance();
}
@Test
public void phaserArriveAndAwaitAdvance() {
JArmus.register(phaser);
phaser.arriveAndAwaitAdvance();
inOrder.verify(jarmus).beforeArriveAndAwaitAdvance(phaser);
inOrder.verify(jarmus).afterArriveAndAwaitAdvance();
}
@Test
public void phaserArriveAndAwaitAdvanceUnregistered() {
phaser.arriveAndAwaitAdvance();
inOrder.verify(jarmus).beforeArriveAndAwaitAdvance(phaser);
inOrder.verify(jarmus).afterArriveAndAwaitAdvance();
}
@Test
public void phaserArriveAndDeregister() {
JArmus.register(phaser);
phaser.arriveAndDeregister();
inOrder.verify(jarmus).onArriveAndDeregister(phaser);
}
@Test
public void phaserArriveAndDeregisterUnregistered() {
phaser.arriveAndDeregister();
inOrder.verify(jarmus).onArriveAndDeregister(phaser);
}
}