package org.jgroups.protocols;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.jgroups.Event;
import org.jgroups.Global;
import org.jgroups.Message;
import org.jgroups.View;
import org.jgroups.debug.Simulator;
import org.jgroups.stack.IpAddress;
import org.jgroups.stack.Protocol;
import java.nio.ByteBuffer;
import java.util.Properties;
import java.util.Vector;
/**
* Tests the fragmentation (FRAG) protocol for http://jira.jboss.com/jira/browse/JGRP-215
* @author Bela Ban
*/
public class FRAG_Test extends TestCase {
IpAddress a1;
Vector members;
View v;
static Simulator s=null;
static int num_done=0;
static Sender[] senders=null;
public static final int SIZE=10000; // bytes
public static final int NUM_MSGS=10;
public static final int NUM_THREADS=100;
public FRAG_Test(String name) {
super(name);
}
public void setUp() throws Exception {
super.setUp();
a1=new IpAddress(1111);
members=new Vector();
members.add(a1);
v=new View(a1, 1, members);
s=new Simulator();
s.setLocalAddress(a1);
s.setView(v);
s.addMember(a1);
Protocol frag=createProtocol();
System.out.println("protocol to be tested: " + frag);
Properties props=new Properties();
props.setProperty("frag_size", "512");
frag.setPropertiesInternal(props);
Protocol[] stack=new Protocol[]{frag};
s.setProtocolStack(stack);
s.start();
}
protected Protocol createProtocol() {
return new FRAG();
}
public void tearDown() throws Exception {
super.tearDown();
s.stop();
}
public void testFragmentation() throws InterruptedException {
FRAG_Test.Receiver r=new FRAG_Test.Receiver();
s.setReceiver(r);
senders=new Sender[NUM_THREADS];
for(int i=0; i < senders.length; i++) {
senders[i]=new Sender(i);
}
for(int i=0; i < senders.length; i++) {
Sender sender=senders[i];
sender.start();
}
for(int i=0; i < senders.length; i++) {
Sender sender=senders[i];
sender.join(5000);
if(sender.isAlive()) {
System.err.println("sender #" + i + " could not be joined (still alive)");
}
}
int sent=0, received=0, corrupted=0;
for(int i=0; i < senders.length; i++) {
Sender sender=senders[i];
received+=sender.getNumReceived();
sent+=sender.getNumSent();
corrupted+=sender.getNumCorrupted();
}
System.out.println("sent: " + sent + ", received: " + received + ", corrupted: " + corrupted);
assertEquals("sent and received should be the same", sent, received);
assertEquals("we should have 0 corrupted messages", 0, corrupted);
}
static class Sender extends Thread {
int id=-1;
int num_sent=0;
int num_received=0;
int num_corrupted=0;
boolean done=false;
public int getIdent() {
return id;
}
public int getNumReceived() {
return num_received;
}
public int getNumSent() {
return num_sent;
}
public int getNumCorrupted() {
return num_corrupted;
}
public Sender(int id) {
super("sender #" + id);
this.id=id;
}
public void run() {
byte[] buf=createBuffer(id);
Message msg;
Event evt;
for(int i=0; i < NUM_MSGS; i++) {
msg=new Message(null, null, buf);
evt=new Event(Event.MSG, msg);
s.send(evt);
num_sent++;
}
synchronized(this) {
try {
while(!done)
this.wait(500);
num_done++;
System.out.println("thread #" + id + " is done (" + num_done + ")");
}
catch(InterruptedException e) {
}
}
}
private byte[] createBuffer(int id) {
ByteBuffer buf=ByteBuffer.allocate(SIZE);
int elements=SIZE / Global.INT_SIZE;
for(int i=0; i < elements; i++) {
buf.putInt(id);
}
return buf.array();
}
/** 1 int has already been read by the Receiver */
public void verify(ByteBuffer buf) {
boolean corrupted=false;
int num_elements=(SIZE / Global.INT_SIZE) -1;
int tmp;
for(int i=0; i < num_elements; i++) {
tmp=buf.getInt();
if(tmp != id) {
corrupted=true;
break;
}
}
if(corrupted)
num_corrupted++;
else
num_received++;
if(num_corrupted + num_received >= NUM_MSGS) {
synchronized(this) {
done=true;
this.notify();
}
}
}
}
static class Receiver implements Simulator.Receiver {
int received=0;
public void receive(Event evt) {
if(evt.getType() == Event.MSG) {
received++;
if(received % 1000 == 0)
System.out.println("<== " + received);
Message msg=(Message)evt.getArg();
byte[] data=msg.getBuffer();
ByteBuffer buf=ByteBuffer.wrap(data);
int id=buf.getInt();
Sender sender=senders[id];
sender.verify(buf);
}
}
}
public static Test suite() {
return new TestSuite(FRAG_Test.class);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(FRAG_Test.suite());
}
}