package org.jgroups.tests; import org.jgroups.Global; import org.jgroups.Message; import org.jgroups.util.RetransmitTable; import org.jgroups.util.Util; import org.testng.annotations.Test; import java.util.ArrayList; import java.util.List; /** Tests {@link org.jgroups.util.RetransmitTable} * @author Bela Ban */ @Test(groups=Global.FUNCTIONAL,sequential=false) public class RetransmitTableTest { static final Message MSG=new Message(null, null, "test"); public static void testCreation() { RetransmitTable table=new RetransmitTable(3, 10, 0); int size=table.size(); assert size == 0; assert table.get(15) == null; } public static void testAddition() { RetransmitTable table=new RetransmitTable(3, 10, 0); addAndGet(table, 0, "0"); addAndGet(table, 1, "1"); addAndGet(table, 5, "5"); addAndGet(table, 9, "9"); addAndGet(table, 10, "10"); addAndGet(table, 11, "11"); addAndGet(table, 19, "19"); addAndGet(table, 20, "20"); addAndGet(table, 29, "29"); System.out.println("table: " + table.dump()); assert table.size() == 9; assert table.size() == table.computeSize(); assert table.capacity() == 30; } public static void testAdditionWithOffset() { RetransmitTable table=new RetransmitTable(3, 10, 100); addAndGet(table, 100, "100"); addAndGet(table, 101, "101"); addAndGet(table, 105, "105"); addAndGet(table, 109, "109"); addAndGet(table, 110, "110"); addAndGet(table, 111, "111"); addAndGet(table, 119, "119"); addAndGet(table, 120, "120"); addAndGet(table, 129, "129"); System.out.println("table: " + table.dump()); assert table.size() == 9; assert table.capacity() == 30; } public static void testAdditionWithOffset2() { RetransmitTable table=new RetransmitTable(3, 10, 2); addAndGet(table, 1000, "1000"); addAndGet(table, 1001, "1001"); table.compact(); addAndGet(table, 1005, "1005"); addAndGet(table, 1009, "1009"); addAndGet(table, 1010, "1010"); addAndGet(table, 1011, "1011"); addAndGet(table, 1019, "1019"); addAndGet(table, 1020, "1020"); addAndGet(table, 1029, "1029"); System.out.println("table: " + table.dump()); assert table.size() == 9; } public static void testDuplicateAddition() { RetransmitTable table=new RetransmitTable(3, 10, 0); addAndGet(table, 0, "0"); addAndGet(table, 1, "1"); addAndGet(table, 5, "5"); addAndGet(table, 9, "9"); addAndGet(table, 10, "10"); assert !table.put(5, new Message()); assert table.get(5).getObject().equals("5"); assert table.size() == 5; } public static void testRemove() { RetransmitTable table=new RetransmitTable(3, 10, 1); for(long i=1; i <= 20; i++) if(i % 2 == 0) table.put(i, new Message()); System.out.println("table = " + table); assert table.size() == 10; int num_null_msgs=table.getNullMessages(0, 20); System.out.println("num_null_msgs = " + num_null_msgs); assert num_null_msgs == 10; for(long i=1; i <= 10; i++) table.remove(i); System.out.println("table = " + table); assert table.size() == 5; num_null_msgs=table.getNullMessages(0, 20); System.out.println("num_null_msgs = " + num_null_msgs); assert num_null_msgs == 15; } public static void testGetNullMessages() { RetransmitTable table=new RetransmitTable(3, 10, 0); table.put(1, MSG); table.put(100, MSG); System.out.println("table = " + table); int num_null_elements=table.getNullMessages(0, 100); assert num_null_elements == 98; // [1 .. 99] excluding 100, as it has been received } public static void testDumpMatrix() { RetransmitTable table=new RetransmitTable(3, 10, 1); long[] seqnos={1,3,5,7,9,12,14,16,18,20,21,22,23,24}; for(long seqno: seqnos) table.put(seqno, MSG); System.out.println("matrix:\n" + table.dumpMatrix()); } public static void testMassAddition() { RetransmitTable table=new RetransmitTable(3, 10, 0); final int NUM_MSGS=10005; final Message MSG=new Message(null, null, "hello world"); for(int i=0; i < NUM_MSGS; i++) table.put(i, MSG); System.out.println("table = " + table); assert table.size() == NUM_MSGS; assert table.capacity() == 10010; } public static void testResize() { RetransmitTable table=new RetransmitTable(3, 10, 0); assert table.capacity() == 30; addAndGet(table, 30, "30"); addAndGet(table, 35, "35"); assert table.capacity() == 40; addAndGet(table, 500, "500"); assert table.capacity() == 510; addAndGet(table, 515, "515"); assert table.capacity() == 520; } public void testResizeWithPurge() { RetransmitTable table=new RetransmitTable(3, 10, 0); for(long i=1; i <= 100; i++) addAndGet(table, i, "hello-" + i); System.out.println("table: " + table); // now remove 60 messages for(long i=1; i <= 60; i++) { Message msg=table.remove(i); assert msg.getObject().equals("hello-" + i); } System.out.println("table after removal of seqno 60: " + table); table.purge(50); System.out.println("now triggering a resize() by addition of seqno=120"); addAndGet(table, 120, "120"); } public void testResizeWithPurgeAndGetOfNonExistingElement() { RetransmitTable table=new RetransmitTable(3, 10, 0); for(long i=0; i < 50; i++) addAndGet(table, i, "hello-" + i); System.out.println("table: " + table); // now remove 15 messages for(long i=0; i <= 15; i++) { Message msg=table.remove(i); assert msg.getObject().equals("hello-" + i); } System.out.println("table after removal of seqno 15: " + table); table.purge(15); System.out.println("now triggering a resize() by addition of seqno=55"); addAndGet(table, 55, "hello-55"); // now we have elements 40-49 in row 1 and 55 in row 2: List<String> list=new ArrayList<String>(20); for(int i=16; i < 50; i++) list.add("hello-" + i); list.add("hello-55"); for(long i=table.getOffset(); i < table.capacity() + table.getOffset(); i++) { Message msg=table.get(i); if(msg != null) { String message=(String)msg.getObject(); System.out.println(i + ": " + message); list.remove(message); } } System.out.println("table:\n" + table.dumpMatrix()); assert list.isEmpty() : " list: " + Util.print(list); } public void testResizeWithPurge2() { RetransmitTable table=new RetransmitTable(3, 10, 0); for(long i=0; i < 50; i++) addAndGet(table, i, "hello-" + i); System.out.println("table = " + table); assert table.size() == 50; assert table.capacity() == 50; assert table.getHighestPurged() == 0; assert table.getHighest() == 49; table.purge(43); addAndGet(table, 52, "hello-52"); assert table.get(43) == null; for(long i=44; i < 50; i++) { Message msg=table.get(i); assert msg != null && msg.getObject().equals("hello-" + i); } assert table.get(50) == null; assert table.get(51) == null; Message msg=table.get(52); assert msg != null && msg.getObject().equals("hello-52"); assert table.get(53) == null; } public static void testMove() { RetransmitTable table=new RetransmitTable(3, 10, 0); for(long i=0; i < 50; i++) addAndGet(table, i, "hello-" + i); table.purge(49); assert table.isEmpty(); addAndGet(table, 50, "50"); assert table.size() == 1; assert table.capacity() == 50; } public static void testPurge() { RetransmitTable table=new RetransmitTable(5, 10, 0); for(long seqno=0; seqno < 25; seqno++) table.put(seqno, MSG); long[] seqnos={30,31,32,37,38,39, 40,41,42,47,48,49}; for(long seqno: seqnos) table.put(seqno, MSG); System.out.println("table (before remove):\n" + table.dump()); for(long seqno=0; seqno <= 22; seqno++) table.remove(seqno); System.out.println("\ntable (after remove 22, before purge):\n" + table.dump()); table.purge(22); System.out.println("\ntable: (after purge 22):\n" + table.dump()); assert table.size() == 2 + seqnos.length; } public void testCompact() { RetransmitTable table=new RetransmitTable(3, 10, 0); for(long i=0; i < 80; i++) addAndGet(table, i, "hello-" + i); assert table.size() == 80; table.purge(59); assert table.size() == 20; table.compact(); assert table.size() == 20; assert table.capacity() == 40; } public void testCompactWithAutomaticPurging() { RetransmitTable table=new RetransmitTable(3, 10, 0); table.setAutomaticPurging(true); for(long i=0; i < 80; i++) addAndGet(table, i, "hello-" + i); assert table.size() == 80; for(long i=0; i <= 59; i++) table.remove(i); assert table.size() == 20; table.compact(); assert table.size() == 20; assert table.capacity() == 40; } public void testSizeOfAllMessages() { RetransmitTable table=new RetransmitTable(3, 10, 0); long size=table.sizeOfAllMessages(false); assert size == 0; size=table.sizeOfAllMessages(true); assert size == 0; byte[] buf=new byte[100]; Message msg=new Message(null, null, buf); table.put(2,msg); size=table.sizeOfAllMessages(false); System.out.println("Size(): " + table.sizeOfAllMessages(true) + ", getLength(): " + size); assert size == 100; for(long i=5; i < 10; i++) table.put(i, new Message(null, null, buf)); size=table.sizeOfAllMessages(false); System.out.println("Size(): " + table.sizeOfAllMessages(true) + ", getLength(): " + size); assert size == 6 * 100; } protected static void addAndGet(RetransmitTable table, long seqno, String message) { boolean added=table.put(seqno, new Message(null, null, message)); assert added; Message msg=table.get(seqno); assert msg != null && msg.getObject().equals(message); } }