package org.jgroups.tests; import org.jgroups.Address; import org.jgroups.Global; import org.jgroups.View; import org.jgroups.util.Digest; import org.jgroups.util.MutableDigest; import org.jgroups.util.Util; import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.util.Arrays; /** * @author Bela Ban */ @Test(groups=Global.FUNCTIONAL, singleThreaded=true) public class DigestTest { protected Digest d, d2; protected MutableDigest md; protected Address a1, a2, a3; protected Address[] members; @BeforeClass void beforeClass() throws Exception { a1=Util.createRandomAddress("a1"); a2=Util.createRandomAddress("a2"); a3=Util.createRandomAddress("a3"); members=new Address[]{a1,a2,a3}; } @BeforeMethod void beforeMethod() { d=new Digest(members, new long[]{500,501, 26,26, 25,33}); md=new MutableDigest(members); } public void testConstructor1() { Digest dd=new MutableDigest(members); Assert.assertEquals(dd.capacity(),members.length); } public void testConstructor2() { d=new Digest(members, new long[]{1,2,3,4,5,6}); System.out.println("d = " + d); try { d=new Digest(members, new long[]{1,2,3,4,5,6,7}); assert false : "seqnos of length 7 should be thrown an exception"; } catch(IllegalArgumentException ex) { System.out.println("caught exception as expected: " + ex); } } public void testCopyConstructor() { Digest digest=new Digest(d); assert digest.equals(d); } public void testCopyConstructor2() { MutableDigest digest=new MutableDigest(d); assert digest.equals(d); } public void testCopyConstructor3() { MutableDigest digest=new MutableDigest(md); assert digest.equals(md); } public void testCapacity() { Assert.assertEquals(md.capacity(), 3); Assert.assertEquals(d.capacity(), 3); } public void testViewId() throws Exception { byte[] buf=Util.streamableToByteBuffer(d); Digest digest=(Digest)Util.streamableFromByteBuffer(Digest.class,buf); System.out.println("digest = " + digest); } public void testContains() { assert d.contains(a1) && d.contains(a2) && d.contains(a3); } public void testContainsAll() { MutableDigest digest=new MutableDigest(members); digest.set(a1,1,1); digest.set(a2,1,1); assert digest.containsAll(a1, a2, a3); digest.set(a3,1,1); assert digest.containsAll(a1, a2, a3); assert d.containsAll(a1, a2, a3); } public void testEquals() { d2=d.copy(); System.out.println("d: " + d + "\nd2= " + d2); Assert.assertEquals(d, d); Assert.assertEquals(d, d2); } public void testEquals2() { md=new MutableDigest(d); System.out.println("d: " + d + "\nmd= " + md); Assert.assertEquals(d, d); Assert.assertEquals(d,md); System.out.println("d: " + d + "\nmd= " + md); md=new MutableDigest(members).set(a1, 1,2).set(a2, 3,4); Assert.assertNotEquals(d,md); } public void testEquals3() { Digest digest=d; Assert.assertEquals(d,digest); digest=new Digest(members, new long[]{500,501, 26,26, 25,33}); Assert.assertEquals(d, digest); digest=new Digest(members, new long[]{500,501, 26,26, 25,37}); Assert.assertNotEquals(d,digest); digest=new MutableDigest(members).set(a1, 500,501).set(a2, 26,26); Assert.assertNotEquals(d,digest); } public void testImmutability2() { Digest tmp=d.copy(); Assert.assertEquals(d, tmp); } public void testImmutability3() { Digest tmp=new Digest(d); Assert.assertEquals(tmp, d); } public void testSet() { md.set(a2,200,201); long[] seqnos=md.get(a2); Assert.assertEquals(seqnos[0], 200); Assert.assertEquals(seqnos[1], 201); } public void testImmutablity() { md=new MutableDigest(d); System.out.println("d = " + d); System.out.println("md = " + md); long[] before=d.get(a1); md.set(a1, 1, 1); System.out.println("d = " + d); System.out.println("md = " + md); long[] after=d.get(a1); Assert.assertEquals(after[0], before[0]); Assert.assertEquals(after[1], before[1]); } public void testSetDigest() { Digest tmp=md.copy(); md.set(tmp); Assert.assertEquals(md.capacity(), 3); } public void testSetDigest2() { MutableDigest tmp=new MutableDigest(members); tmp.set(Util.createRandomAddress(),2,3); // ignored as view doesn't include this member tmp.set(Util.createRandomAddress(),2,3); // ditto tmp.set(a2,2,3); tmp.set(a3,2,3); md.set(tmp); Assert.assertEquals(md.capacity(), 3); } public void testGet() { long[] entry=d.get(a1); assert entry[0] ==500 && entry[1] == 501; entry=d.get(a2); assert entry[0] == 26 && entry[1] == 26; entry=d.get(a3); assert entry[0] == 25 && entry[1] == 33; } public void testIncrementHighSeqno() { md=new MutableDigest(members); md.set(a1,1,100).set(a2,3,300).set(a3,7,700); long tmp=md.get(a1)[0]; md.set(a1,tmp + 1,tmp + 1); Assert.assertEquals(md.get(a1)[0], tmp + 1); tmp=md.get(a2)[0]; md.set(a2,tmp + 1,tmp + 1); Assert.assertEquals(md.get(a2)[0], tmp + 1); tmp=md.get(a3)[0]; md.set(a3,tmp + 1,tmp + 1); Assert.assertEquals(md.get(a3)[0], tmp + 1); } public void testHighSeqnoAt() { Assert.assertEquals(d.get(a1)[0], 500); Assert.assertEquals(d.get(a2)[0], 26); Assert.assertEquals(d.get(a3)[0], 25); } public void testReplace() { MutableDigest digest=new MutableDigest(members); digest.set(a1,1,1); digest.set(a2,2,2); md.set(digest); assert digest.equals(md); } public void testHighSeqnoSeenAt() { Assert.assertEquals(d.get(a1)[1], 501); Assert.assertEquals(d.get(a2)[1], 26); Assert.assertEquals(d.get(a3)[1], 33); } public void testSetHighestDeliveredAndSeenSeqnoAt() { md=new MutableDigest(d); Assert.assertEquals(md.get(a1)[0], 500); Assert.assertEquals(md.get(a1)[1], 501); md.set(a1,10,20); Assert.assertEquals(md.get(a1)[0], 10); Assert.assertEquals(md.get(a1)[1], 20); } public void testCopy() { d=d.copy(); testHighSeqnoAt(); testHighSeqnoSeenAt(); testContains(); } public void testCopy2() { assert d.equals(d.copy()); } public void testMutableCopy() { Digest copy=md.copy(); System.out.println("md=" + md + "\ncopy=" + copy); Assert.assertEquals(md, copy); md.set(Util.createRandomAddress("p"),500,1000); // is ignored as p is not a member System.out.println("md=" + md + "\ncopy=" + copy); assert md.equals(copy); } public void testAllSet() { Address[] mbrs=Util.createRandomAddresses(5); MutableDigest dig=new MutableDigest(mbrs); assert !dig.allSet(); for(int index: Arrays.asList(1,3,4)) dig.set(mbrs[index], index, index+1); System.out.println("dig = " + dig); assert !dig.allSet(); Address[] non_set=dig.getNonSetMembers(); System.out.println("non_set = " + Arrays.toString(non_set)); assert non_set != null && non_set.length == 2; Assert.assertEquals(non_set, new Address[]{mbrs[0], mbrs[2]}); for(int index: Arrays.asList(0,2)) dig.set(mbrs[index], index, index+1); System.out.println("dig = " + dig); assert dig.allSet(); non_set=dig.getNonSetMembers(); assert non_set.length == 0; dig=new MutableDigest(members); assert !dig.allSet(); non_set=dig.getNonSetMembers(); Assert.assertEquals(non_set, members); dig.set(d); System.out.println("dig = " + dig); assert dig.allSet(); non_set=dig.getNonSetMembers(); assert non_set.length == 0; } public void testMerge() { MutableDigest digest=new MutableDigest(members) .set(a1, 499,502).set(a2, 26,27).set(a3, 26,35); System.out.println("d: " + d); System.out.println("digest: " + digest); digest.merge(d); System.out.println("merged digest: " + digest); Assert.assertEquals(d.capacity(), 3); Assert.assertEquals(digest.capacity(), 3); Assert.assertEquals(digest.get(a1)[0], 500); Assert.assertEquals(digest.get(a1)[1], 502); Assert.assertEquals(digest.get(a2)[0], 26); Assert.assertEquals(digest.get(a2)[1], 27); Assert.assertEquals(digest.get(a3)[0], 26); Assert.assertEquals(digest.get(a3)[1], 35); } public void testNonConflictingMerge() { Address ip1=Util.createRandomAddress("x"), ip2=Util.createRandomAddress("y"); View tmp_view=View.create(a1,1,a1,a2,a3,ip1,ip2); MutableDigest cons_d=new MutableDigest(tmp_view.getMembersRaw()); cons_d.set(ip1,10,10); cons_d.set(ip2,20,20); cons_d.merge(d); Assert.assertEquals(cons_d.capacity(), 5); Assert.assertEquals(cons_d.get(ip1)[0], 10); Assert.assertEquals(cons_d.get(ip2)[0], 20); Assert.assertEquals(cons_d.get(a1)[0], 500); Assert.assertEquals(cons_d.get(a2)[0], 26); Assert.assertEquals(cons_d.get(a3)[0], 25); Assert.assertEquals(cons_d.get(ip1)[1], 10); Assert.assertEquals(cons_d.get(ip2)[1], 20); Assert.assertEquals(cons_d.get(a1)[1], 501); Assert.assertEquals(cons_d.get(a2)[1], 26); Assert.assertEquals(cons_d.get(a3)[1], 33); } public void testConflictingMerge() { MutableDigest new_d=new MutableDigest(members); new_d.set(a1,450,501); new_d.set(a3,28,35); md=new MutableDigest(d); md.merge(new_d); Assert.assertEquals(md.capacity(), 3); Assert.assertEquals(md.get(a1)[0], 500); Assert.assertEquals(md.get(a1)[1], 501); Assert.assertEquals(md.get(a2)[0], 26); Assert.assertEquals(md.get(a2)[1], 26); Assert.assertEquals(md.get(a3)[0], 28); Assert.assertEquals(md.get(a3)[1], 35); } public void testStreamable() throws Exception { ByteArrayOutputStream outstream=new ByteArrayOutputStream(); DataOutputStream dos=new DataOutputStream(outstream); d.writeTo(dos); dos.close(); byte[] buf=outstream.toByteArray(); ByteArrayInputStream instream=new ByteArrayInputStream(buf); DataInputStream dis=new DataInputStream(instream); Digest tmp=new Digest(); tmp.readFrom(dis); Assert.assertEquals(d, tmp); } public void testSerializedSize() throws Exception { long len=d.serializedSize(true); byte[] buf=Util.streamableToByteBuffer(d); Assert.assertEquals(buf.length, len); } public void testViewBasedMarshalling() throws Exception { byte[] buf=Util.streamableToByteBuffer(d); Digest new_digest=(Digest)Util.streamableFromByteBuffer(Digest.class,buf); System.out.println("new_digest = " + new_digest); assert new_digest.equals(d); } public void testViewBasedMarshallingLargeView() throws Exception { final int DIGEST_SIZE=1000; long[] seqnos=new long[DIGEST_SIZE *2]; Address[] mbrs=new Address[DIGEST_SIZE]; for(int i=0; i < DIGEST_SIZE; i++) mbrs[i]=Util.createRandomAddress(String.valueOf(i)); for(int i=0; i < DIGEST_SIZE; i++) { int hd=(int)Util.random(Integer.MAX_VALUE); seqnos[i*2]=hd; seqnos[i*2 +1]=hd + Util.random(1000); } Digest digest=new Digest(mbrs, seqnos); byte[] buf1=Util.streamableToByteBuffer(digest); System.out.println("buf1: " + buf1.length + " bytes"); Digest digest1=(Digest)Util.streamableFromByteBuffer(Digest.class,buf1); System.out.println("digest1 = " + digest1); assert digest.equals(digest1); assert digest.capacity() == digest1.capacity(); } }