X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-akka-raft%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fraft%2Fbehaviors%2FSnapshotTrackerTest.java;h=281f8071d7cbc8c186ca423b1c4d7f5341b670c0;hp=f103abcf8409d7d69abd51baee8bbb29198e943c;hb=5fd4213b5bfaf2db21f1b37139f6b98535a872c0;hpb=726ee824671781b5031c0108794c22bd0d96eaad diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/SnapshotTrackerTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/SnapshotTrackerTest.java index f103abcf84..281f8071d7 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/SnapshotTrackerTest.java +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/SnapshotTrackerTest.java @@ -1,14 +1,24 @@ +/* + * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + package org.opendaylight.controller.cluster.raft.behaviors; import static org.junit.Assert.assertEquals; + import com.google.common.base.Optional; +import com.google.common.io.ByteSource; import com.google.protobuf.ByteString; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; -import org.junit.Assert; +import org.apache.commons.lang3.SerializationUtils; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; @@ -20,164 +30,90 @@ public class SnapshotTrackerTest { Map data; ByteString byteString; - ByteString chunk1; - ByteString chunk2; - ByteString chunk3; + byte[] chunk1; + byte[] chunk2; + byte[] chunk3; @Before - public void setup(){ + public void setup() { data = new HashMap<>(); data.put("key1", "value1"); data.put("key2", "value2"); data.put("key3", "value3"); - byteString = toByteString(data); + byteString = ByteString.copyFrom(SerializationUtils.serialize((Serializable) data)); chunk1 = getNextChunk(byteString, 0, 10); chunk2 = getNextChunk(byteString, 10, 10); chunk3 = getNextChunk(byteString, 20, byteString.size()); } @Test - public void testAddChunk() throws SnapshotTracker.InvalidChunkException { - SnapshotTracker tracker1 = new SnapshotTracker(logger, 5); - - tracker1.addChunk(1, chunk1, Optional.absent()); - tracker1.addChunk(2, chunk2, Optional.absent()); - tracker1.addChunk(3, chunk3, Optional.absent()); + public void testAddChunks() throws IOException { + SnapshotTracker tracker = new SnapshotTracker(logger, 3, "leader"); - // Verify that an InvalidChunkException is thrown when we try to add a chunk to a sealed tracker - SnapshotTracker tracker2 = new SnapshotTracker(logger, 2); + tracker.addChunk(1, chunk1, Optional.of(LeaderInstallSnapshotState.INITIAL_LAST_CHUNK_HASH_CODE)); + tracker.addChunk(2, chunk2, Optional.of(Arrays.hashCode(chunk1))); + tracker.addChunk(3, chunk3, Optional.of(Arrays.hashCode(chunk2))); - tracker2.addChunk(1, chunk1, Optional.absent()); - tracker2.addChunk(2, chunk2, Optional.absent()); - - try { - tracker2.addChunk(3, chunk3, Optional.absent()); - Assert.fail(); - } catch(SnapshotTracker.InvalidChunkException e){ - e.getMessage().startsWith("Invalid chunk"); - } + ByteSource snapshotBytes = tracker.getSnapshotBytes(); + assertEquals("Deserialized", data, SerializationUtils.deserialize(snapshotBytes.read())); - // The first chunk's index must at least be FIRST_CHUNK_INDEX - SnapshotTracker tracker3 = new SnapshotTracker(logger, 2); - - try { - tracker3.addChunk(AbstractLeader.FIRST_CHUNK_INDEX - 1, chunk1, Optional.absent()); - Assert.fail(); - } catch(SnapshotTracker.InvalidChunkException e){ + tracker.close(); + } + @Test(expected = SnapshotTracker.InvalidChunkException.class) + public void testAddChunkWhenAlreadySealed() throws IOException { + try (SnapshotTracker tracker = new SnapshotTracker(logger, 2, "leader")) { + tracker.addChunk(1, chunk1, Optional.absent()); + tracker.addChunk(2, chunk2, Optional.absent()); + tracker.addChunk(3, chunk3, Optional.absent()); } + } - // Out of sequence chunk indexes won't work - SnapshotTracker tracker4 = new SnapshotTracker(logger, 2); - - tracker4.addChunk(AbstractLeader.FIRST_CHUNK_INDEX, chunk1, Optional.absent()); - - try { - tracker4.addChunk(AbstractLeader.FIRST_CHUNK_INDEX+2, chunk2, Optional.absent()); - Assert.fail(); - } catch(SnapshotTracker.InvalidChunkException e){ - + @Test(expected = SnapshotTracker.InvalidChunkException.class) + public void testInvalidFirstChunkIndex() throws IOException { + try (SnapshotTracker tracker = new SnapshotTracker(logger, 2, "leader")) { + tracker.addChunk(LeaderInstallSnapshotState.FIRST_CHUNK_INDEX - 1, chunk1, Optional.absent()); } + } - // No exceptions will be thrown when invalid chunk is added with the right sequence - // If the lastChunkHashCode is missing - SnapshotTracker tracker5 = new SnapshotTracker(logger, 2); - - tracker5.addChunk(AbstractLeader.FIRST_CHUNK_INDEX, chunk1, Optional.absent()); - // Look I can add the same chunk again - tracker5.addChunk(AbstractLeader.FIRST_CHUNK_INDEX + 1, chunk1, Optional.absent()); - - // An exception will be thrown when an invalid chunk is addedd with the right sequence - // when the lastChunkHashCode is present - SnapshotTracker tracker6 = new SnapshotTracker(logger, 2); - - tracker6.addChunk(AbstractLeader.FIRST_CHUNK_INDEX, chunk1, Optional.of(-1)); - - try { - // Here we add a second chunk and tell addChunk that the previous chunk had a hash code 777 - tracker6.addChunk(AbstractLeader.FIRST_CHUNK_INDEX + 1, chunk2, Optional.of(777)); - Assert.fail(); - }catch(SnapshotTracker.InvalidChunkException e){ - + @Test(expected = SnapshotTracker.InvalidChunkException.class) + public void testOutOfSequenceChunk() throws IOException { + try (SnapshotTracker tracker = new SnapshotTracker(logger, 2, "leader")) { + tracker.addChunk(1, chunk1, Optional.absent()); + tracker.addChunk(3, chunk3, Optional.absent()); } - } - @Test - public void testGetSnapShot() throws SnapshotTracker.InvalidChunkException { - - // Trying to get a snapshot before all chunks have been received will throw an exception - SnapshotTracker tracker1 = new SnapshotTracker(logger, 5); - - tracker1.addChunk(1, chunk1, Optional.absent()); - try { - tracker1.getSnapshot(); - Assert.fail(); - } catch(IllegalStateException e){ - + @Test(expected = SnapshotTracker.InvalidChunkException.class) + public void testInvalidLastChunkHashCode() throws IOException { + try (SnapshotTracker tracker = new SnapshotTracker(logger, 2, "leader")) { + tracker.addChunk(1, chunk1, Optional.of(LeaderInstallSnapshotState.INITIAL_LAST_CHUNK_HASH_CODE)); + tracker.addChunk(2, chunk2, Optional.of(1)); } - - SnapshotTracker tracker2 = new SnapshotTracker(logger, 3); - - tracker2.addChunk(1, chunk1, Optional.absent()); - tracker2.addChunk(2, chunk2, Optional.absent()); - tracker2.addChunk(3, chunk3, Optional.absent()); - - byte[] snapshot = tracker2.getSnapshot(); - - assertEquals(byteString, ByteString.copyFrom(snapshot)); } - @Test - public void testGetCollectedChunks() throws SnapshotTracker.InvalidChunkException { - SnapshotTracker tracker1 = new SnapshotTracker(logger, 5); - - ByteString chunks = chunk1.concat(chunk2); - - tracker1.addChunk(1, chunk1, Optional.absent()); - tracker1.addChunk(2, chunk2, Optional.absent()); - - assertEquals(chunks, tracker1.getCollectedChunks()); + @Test(expected = IllegalStateException.class) + public void testGetSnapshotBytesWhenNotSealed() throws IOException { + try (SnapshotTracker tracker = new SnapshotTracker(logger, 2, "leader")) { + tracker.addChunk(1, chunk1, Optional.absent()); + tracker.getSnapshotBytes(); + } } - public ByteString getNextChunk (ByteString bs, int offset, int size){ + private byte[] getNextChunk(ByteString bs, int offset, int size) { int snapshotLength = bs.size(); int start = offset; if (size > snapshotLength) { size = snapshotLength; } else { - if ((start + size) > snapshotLength) { + if (start + size > snapshotLength) { size = snapshotLength - start; } } - return bs.substring(start, start + size); - } - private ByteString toByteString(Map state) { - ByteArrayOutputStream b = null; - ObjectOutputStream o = null; - try { - try { - b = new ByteArrayOutputStream(); - o = new ObjectOutputStream(b); - o.writeObject(state); - byte[] snapshotBytes = b.toByteArray(); - return ByteString.copyFrom(snapshotBytes); - } finally { - if (o != null) { - o.flush(); - o.close(); - } - if (b != null) { - b.close(); - } - } - } catch (IOException e) { - org.junit.Assert.fail("IOException in converting Hashmap to Bytestring:" + e); - } - return null; + byte[] nextChunk = new byte[size]; + bs.copyTo(nextChunk, start, 0, size); + return nextChunk; } - - -} \ No newline at end of file +}