package org.jgroups.tests; import org.jgroups.Global; import org.jgroups.util.*; import org.testng.annotations.Test; import java.util.*; import java.util.concurrent.ConcurrentHashMap; /** * @author Bela Ban */ @Test(groups=Global.FUNCTIONAL, sequential=false) public class SeqnoTest { public static void testConstructor() { SeqnoRange range=new SeqnoRange(10, 10); System.out.println(print(range)); assert range.size() == 1; assert range.getLow() == 10; assert range.getHigh() == 10; assert range.contains(10); assert !range.contains(11); range=new SeqnoRange(10, 15); System.out.println(print(range)); assert range.size() == 6; assert range.getLow() == 10; assert range.getHigh() == 15; assert range.contains(10); assert range.contains(14); } public static void testSetAndGetWith1Seqno() { Seqno range=new SeqnoRange(10, 10); assert range.getNumberOfMissingMessages() == 1; assert range.getNumberOfReceivedMessages() == 0; range.set(10); assert range.getNumberOfMissingMessages() == 0; assert range.getNumberOfReceivedMessages() == 1; assert range.get(10); range.clear(10); assert !range.get(10); assert range.getNumberOfMissingMessages() == 1; assert range.getNumberOfReceivedMessages() == 0; } public static void testSetAndGetWith5Seqnos() { SeqnoRange range=new SeqnoRange(10, 15); System.out.println("range=" + print(range)); assert range.size() == 6; assert range.getNumberOfMissingMessages() == 6; assert range.getNumberOfReceivedMessages() == 0; range.set(10); assert range.getNumberOfMissingMessages() == 5; assert range.getNumberOfReceivedMessages() == 1; assert range.get(10); range.set(13); assert range.size() == 6; assert range.getNumberOfMissingMessages() == 4; assert range.getNumberOfReceivedMessages() == 2; range.set(13); assert range.size() == 6; assert range.getNumberOfMissingMessages() == 4; assert range.getNumberOfReceivedMessages() == 2; System.out.println("range=" + print(range)); Collection<Range> xmits=range.getMessagesToRetransmit(); Collection<Range> cleared_bits=range.getBits(false); System.out.println("xmits = " + xmits); System.out.println("cleared_bits = " + cleared_bits); assert xmits.equals(cleared_bits); } public static void testGetBits() { SeqnoRange range=new SeqnoRange(1, 100); System.out.println("range = " + range); assert range.size() == 100; Collection<Range> bits=range.getBits(false); assert bits.size() == 1; Range tmp=bits.iterator().next(); assert tmp.low == 1 && tmp.high == 100; range.set(1,2); assert range.size() == 100; bits=range.getBits(true); assert bits != null && bits.size() == 1; // 1 range: [1-2] tmp=bits.iterator().next(); assert tmp.low == 1 && tmp.high == 2; for(int i=1; i < 100; i++) range.set(i); bits=range.getBits(false); assert bits.size() == 1; tmp=bits.iterator().next(); assert tmp.low == 100 && tmp.high == 100; for(int i=1; i <= range.size(); i++) range.clear(i); for(int i=2; i <= 99; i++) range.set(i); bits=range.getBits(true); assert bits.size() == 1; tmp=bits.iterator().next(); assert tmp.low == 2 && tmp.high == 99; bits=range.getBits(false); assert bits.size() == 2; tmp=bits.iterator().next(); assert tmp.low == 1 && tmp.high == 1; Iterator<Range> it=bits.iterator(); it.next(); tmp=it.next(); assert tmp.low == 100 && tmp.high == 100; } public static void testSet() { SeqnoRange range=new SeqnoRange(10, 15); range.set(11, 12, 13, 14); System.out.println("range=" + print(range)); assert range.size() == 6; assert range.getNumberOfReceivedMessages() == 4; assert range.getNumberOfMissingMessages() == 2; Collection<Range> xmits=range.getMessagesToRetransmit(); assert xmits.size() == 2; Iterator<Range> it=xmits.iterator(); Range r=it.next(); assert r.low == 10 && r.high == 10; r=it.next(); assert r.low == 15 && r.high == 15; range=new SeqnoRange(10, 15); range.set(10,11,12,13,14); System.out.println("range=" + print(range)); assert range.size() == 6; assert range.getNumberOfReceivedMessages() == 5; assert range.getNumberOfMissingMessages() == 1; xmits=range.getMessagesToRetransmit(); assert xmits.size() == 1; it=xmits.iterator(); r=it.next(); assert r.low == 15 && r.high == 15; range=new SeqnoRange(10, 15); range.set(11,12,13,14,15); System.out.println("range=" + print(range)); assert range.size() == 6; assert range.getNumberOfReceivedMessages() == 5; assert range.getNumberOfMissingMessages() == 1; xmits=range.getMessagesToRetransmit(); assert xmits.size() == 1; it=xmits.iterator(); r=it.next(); assert r.low == 10 && r.high == 10; range=new SeqnoRange(10, 15); range.set(10,11,12,13,14,15); System.out.println("range=" + print(range)); assert range.size() == 6; assert range.getNumberOfReceivedMessages() == 6; assert range.getNumberOfMissingMessages() == 0; xmits=range.getMessagesToRetransmit(); assert xmits.isEmpty(); range=new SeqnoRange(10, 15); range.set(11,12,14,15); System.out.println("range=" + print(range)); assert range.size() == 6; assert range.getNumberOfReceivedMessages() == 4; assert range.getNumberOfMissingMessages() == 2; xmits=range.getMessagesToRetransmit(); assert xmits.size() == 2; it=xmits.iterator(); r=it.next(); assert r.low == 10 && r.high == 10; r=it.next(); assert r.low == 13 && r.high == 13; range.set(13); assert range.getNumberOfReceivedMessages() == 5; assert range.getNumberOfMissingMessages() == 1; xmits=range.getMessagesToRetransmit(); it=xmits.iterator(); r=it.next(); assert r.low == 10 && r.high == 10; range.set(10); System.out.println("range=" + print(range)); assert range.getNumberOfReceivedMessages() == 6; assert range.getNumberOfMissingMessages() == 0; xmits=range.getMessagesToRetransmit(); assert xmits.isEmpty(); } @Test(expectedExceptions=IllegalArgumentException.class) public static void testSetOfInvalidIndex() { SeqnoRange range=new SeqnoRange(10, 10); range.set(9); } public static void testCompareTo() { TreeMap<Seqno,Seqno> map=new TreeMap<Seqno,Seqno>(new SeqnoComparator()); Seqno[] ranges={new SeqnoRange(900,905), new Seqno(222), new SeqnoRange(700,800), new SeqnoRange(23,200)}; for(Seqno range: ranges) map.put(range, range); System.out.println("map = " + map.keySet()); assert map.size() == ranges.length; for(long num: new long[]{0, 1, 201, 202, 223, 1000}) { checkNull(map, num); } checkInRange(map, 23, 23, 200); checkInRange(map, 100, 23, 200); checkInRange(map, 200, 23, 200); checkInRange(map, 222, 222, 222); checkInRange(map, 750, 700, 800); checkInRange(map, 905, 900, 905); } public static void testCompareTo2() { TreeMap<Seqno,Seqno> map=new TreeMap<Seqno,Seqno>(new SeqnoComparator()); Seqno[] ranges={new SeqnoRange(900,905), new Seqno(550), new Seqno(222), new SeqnoRange(700,800), new Seqno(650), new SeqnoRange(23,200)}; for(Seqno range: ranges) map.put(range, range); System.out.println("map = " + map.keySet()); assert map.size() == 6; for(long num: new long[]{0, 1, 201, 202, 223, 1000}) { checkNull(map, num); } checkInRange(map, 550, 550, 550); checkInRange(map, 650, 650, 650); checkInRange(map, 23, 23, 200); checkInRange(map, 100, 23, 200); checkInRange(map, 200, 23, 200); checkInRange(map, 222, 222, 222); checkInRange(map, 750, 700, 800); checkInRange(map, 905, 900, 905); } public static void testLargeRange() { SeqnoRange range=new SeqnoRange(0, 1500); Set<Integer> sorted_set=new TreeSet<Integer>(); for(int i=0; i < 500; i++) { int num=(int)Util.random(1499); sorted_set.add(num); } for(int num: sorted_set) range.set(num); int num_set=sorted_set.size(); System.out.println("set " + num_set + " bits"); assert range.getNumberOfReceivedMessages() == num_set; Collection<Range> missing=range.getMessagesToRetransmit(); System.out.println("missing = " + missing); } public static void testRemovalFromTreeMap() { Map<Seqno,Seqno> map=new TreeMap<Seqno,Seqno>(new SeqnoComparator()); Seqno[] ranges=new Seqno[]{new SeqnoRange(900,905), new Seqno(222), new Seqno(500), new SeqnoRange(700,800), new Seqno(801), new SeqnoRange(23,200)}; for(Seqno range: ranges) map.put(range, range); System.out.println("map = " + map.keySet()); assert map.size() == ranges.length; for(Seqno r: ranges) { Seqno range=map.get(r); assert range != null; assert range == r; // must point to the same object in memory } for(Seqno r: ranges) { Seqno range=map.remove(r); assert range != null; assert range == r; } assert map.isEmpty(); } public static void testRemovalFromHashMap() { Map<Seqno,Seqno> map=new ConcurrentHashMap<Seqno,Seqno>(); Seqno[] ranges=new Seqno[]{new SeqnoRange(900,905), new Seqno(222), new SeqnoRange(700,800), new SeqnoRange(23,200), new Seqno(201), new Seqno(205)}; for(Seqno range: ranges) map.put(range, range); System.out.println("map = " + map.keySet()); assert map.size() == ranges.length; for(Seqno r: ranges) { Seqno range=map.get(r); assert range != null; assert range == r; // must point to the same object in memory } for(Seqno r: ranges) { Seqno range=map.remove(r); assert range != null; assert range == r; } assert map.isEmpty(); } private static void checkInRange(Map<Seqno,Seqno> map, long seqno, long from, long to) { Seqno val=map.get(new Seqno(seqno, true)); System.out.println("seqno=" + seqno + ", val = " + val); assert val != null; assert val.contains(seqno); assert val.getLow() == from; if(val instanceof SeqnoRange) assert ((SeqnoRange)val).getHigh() == to; } private static void checkNull(Map<Seqno,Seqno> map, long seqno) { Seqno val=map.get(new Seqno(seqno, true)); assert val == null; } private static String print(Seqno seqno) { StringBuilder sb=new StringBuilder(); sb.append(seqno.toString()); sb.append(", size= " + seqno.size()); if(seqno instanceof SeqnoRange) { sb.append(", received=" + ((SeqnoRange)seqno).printBits(true) + " (" + seqno.getNumberOfReceivedMessages() + ")"); sb.append(", missing=" + ((SeqnoRange)seqno).printBits(false) + " (" + seqno.getNumberOfMissingMessages() + ")"); } return sb.toString(); } }