package org.jgroups.tests;
import org.jgroups.*;
import org.jgroups.protocols.BARRIER;
import org.jgroups.protocols.EXAMPLE;
import org.jgroups.protocols.PING;
import org.jgroups.protocols.SHARED_LOOPBACK;
import org.jgroups.util.Util;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Tests the BARRIER protocol
* @author Bela Ban
*/
@Test(groups=Global.FUNCTIONAL,sequential=true)
public class BARRIERTest {
JChannel ch;
PING ping_prot;
BARRIER barrier_prot;
EXAMPLE example_prot;
@BeforeMethod
void setUp() throws Exception {
ping_prot=new PING();
example_prot=new EXAMPLE();
barrier_prot=new BARRIER();
ch=Util.createChannel(new SHARED_LOOPBACK(), ping_prot, barrier_prot, example_prot);
ch.connect("BARRIERTest");
}
@AfterMethod
void destroy() {
Util.close(ch);
}
public void testBlocking() {
assert !barrier_prot.isClosed();
ch.down(new Event(Event.CLOSE_BARRIER));
assert barrier_prot.isClosed();
ch.down(new Event(Event.OPEN_BARRIER));
assert !barrier_prot.isClosed();
}
public void testThreadsBlockedOnBarrier() {
MyReceiver receiver=new MyReceiver();
ch.setReceiver(receiver);
ch.down(new Event(Event.CLOSE_BARRIER));
for(int i=0; i < 5; i++) {
new Thread() {
public void run() {
ping_prot.up(new Event(Event.MSG, new Message(null, null, null)));
}
}.start();
}
Util.sleep(2000);
int num_in_flight_threads=barrier_prot.getNumberOfInFlightThreads();
assert num_in_flight_threads == 0;
ch.down(new Event(Event.OPEN_BARRIER));
Util.sleep(2000);
num_in_flight_threads=barrier_prot.getNumberOfInFlightThreads();
assert num_in_flight_threads == 0;
int received_msgs=receiver.getNumberOfReceivedMessages();
assert received_msgs == 5 : "expected " + 5 + " messages but got " + received_msgs;
}
public void testThreadsBlockedOnMutex() throws InterruptedException {
BlockingReceiver receiver=new BlockingReceiver();
ch.setReceiver(receiver);
Thread thread=new Thread() {
public void run() {
ping_prot.up(new Event(Event.MSG, new Message()));}
};
Thread thread2=new Thread() {
public void run() {
ping_prot.up(new Event(Event.MSG, new Message()));}
};
thread.start();
thread2.start();
thread.join();
thread2.join();
}
static class MyReceiver extends ReceiverAdapter {
AtomicInteger num_mgs_received=new AtomicInteger(0);
public void receive(Message msg) {
if(num_mgs_received.incrementAndGet() % 1000 == 0)
System.out.println("<== " + num_mgs_received.get());
}
public int getNumberOfReceivedMessages() {
return num_mgs_received.get();
}
}
class BlockingReceiver extends ReceiverAdapter {
public void receive(Message msg) {
System.out.println("Thread " + Thread.currentThread().getId() + " receive() called - about to enter mutex");
synchronized(this) {
System.out.println("Thread " + Thread.currentThread().getId() + " entered mutex");
Util.sleep(2000);
System.out.println("Thread " + Thread.currentThread().getId() + " closing barrier");
ch.down(new Event(Event.CLOSE_BARRIER));
System.out.println("Thread " + Thread.currentThread().getId() + " closed barrier");
}
}
}
}