package org.opendaylight.controller.cluster.raft.behaviors;
import static org.junit.Assert.assertEquals;
+
import com.google.common.base.Optional;
import com.google.protobuf.ByteString;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
Map<String, String> 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");
@Test
public void testAddChunk() throws SnapshotTracker.InvalidChunkException {
- SnapshotTracker tracker1 = new SnapshotTracker(logger, 5);
+ SnapshotTracker tracker1 = new SnapshotTracker(logger, 5, "leader");
tracker1.addChunk(1, chunk1, Optional.<Integer>absent());
tracker1.addChunk(2, chunk2, Optional.<Integer>absent());
tracker1.addChunk(3, chunk3, Optional.<Integer>absent());
// Verify that an InvalidChunkException is thrown when we try to add a chunk to a sealed tracker
- SnapshotTracker tracker2 = new SnapshotTracker(logger, 2);
+ SnapshotTracker tracker2 = new SnapshotTracker(logger, 2, "leader");
tracker2.addChunk(1, chunk1, Optional.<Integer>absent());
tracker2.addChunk(2, chunk2, Optional.<Integer>absent());
try {
tracker2.addChunk(3, chunk3, Optional.<Integer>absent());
Assert.fail();
- } catch(SnapshotTracker.InvalidChunkException e){
- e.getMessage().startsWith("Invalid chunk");
+ } catch (SnapshotTracker.InvalidChunkException e) {
+ // expected
}
// The first chunk's index must at least be FIRST_CHUNK_INDEX
- SnapshotTracker tracker3 = new SnapshotTracker(logger, 2);
+ SnapshotTracker tracker3 = new SnapshotTracker(logger, 2, "leader");
try {
- tracker3.addChunk(AbstractLeader.FIRST_CHUNK_INDEX - 1, chunk1, Optional.<Integer>absent());
+ tracker3.addChunk(LeaderInstallSnapshotState.FIRST_CHUNK_INDEX - 1, chunk1, Optional.<Integer>absent());
Assert.fail();
- } catch(SnapshotTracker.InvalidChunkException e){
-
+ } catch (SnapshotTracker.InvalidChunkException e) {
+ // expected
}
// Out of sequence chunk indexes won't work
- SnapshotTracker tracker4 = new SnapshotTracker(logger, 2);
+ SnapshotTracker tracker4 = new SnapshotTracker(logger, 2, "leader");
- tracker4.addChunk(AbstractLeader.FIRST_CHUNK_INDEX, chunk1, Optional.<Integer>absent());
+ tracker4.addChunk(LeaderInstallSnapshotState.FIRST_CHUNK_INDEX, chunk1, Optional.<Integer>absent());
try {
- tracker4.addChunk(AbstractLeader.FIRST_CHUNK_INDEX+2, chunk2, Optional.<Integer>absent());
+ tracker4.addChunk(LeaderInstallSnapshotState.FIRST_CHUNK_INDEX + 2, chunk2, Optional.<Integer>absent());
Assert.fail();
- } catch(SnapshotTracker.InvalidChunkException e){
-
+ } catch (SnapshotTracker.InvalidChunkException e) {
+ // expected
}
// 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);
+ SnapshotTracker tracker5 = new SnapshotTracker(logger, 2, "leader");
- tracker5.addChunk(AbstractLeader.FIRST_CHUNK_INDEX, chunk1, Optional.<Integer>absent());
+ tracker5.addChunk(LeaderInstallSnapshotState.FIRST_CHUNK_INDEX, chunk1, Optional.<Integer>absent());
// Look I can add the same chunk again
- tracker5.addChunk(AbstractLeader.FIRST_CHUNK_INDEX + 1, chunk1, Optional.<Integer>absent());
+ tracker5.addChunk(LeaderInstallSnapshotState.FIRST_CHUNK_INDEX + 1, chunk1, Optional.<Integer>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);
+ SnapshotTracker tracker6 = new SnapshotTracker(logger, 2, "leader");
- tracker6.addChunk(AbstractLeader.FIRST_CHUNK_INDEX, chunk1, Optional.of(-1));
+ tracker6.addChunk(LeaderInstallSnapshotState.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));
+ tracker6.addChunk(LeaderInstallSnapshotState.FIRST_CHUNK_INDEX + 1, chunk2, Optional.of(777));
Assert.fail();
- }catch(SnapshotTracker.InvalidChunkException e){
-
+ } catch (SnapshotTracker.InvalidChunkException e) {
+ // expected
}
}
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);
+ SnapshotTracker tracker1 = new SnapshotTracker(logger, 5, "leader");
tracker1.addChunk(1, chunk1, Optional.<Integer>absent());
try {
tracker1.getSnapshot();
Assert.fail();
- } catch(IllegalStateException e){
-
+ } catch (IllegalStateException e) {
+ // expected
}
- SnapshotTracker tracker2 = new SnapshotTracker(logger, 3);
+ SnapshotTracker tracker2 = new SnapshotTracker(logger, 3, "leader");
- tracker2.addChunk(1, chunk1, Optional.<Integer>absent());
- tracker2.addChunk(2, chunk2, Optional.<Integer>absent());
- tracker2.addChunk(3, chunk3, Optional.<Integer>absent());
+ tracker2.addChunk(1, chunk1, Optional.of(LeaderInstallSnapshotState.INITIAL_LAST_CHUNK_HASH_CODE));
+ tracker2.addChunk(2, chunk2, Optional.of(Arrays.hashCode(chunk1)));
+ tracker2.addChunk(3, chunk3, Optional.of(Arrays.hashCode(chunk2)));
byte[] snapshot = tracker2.getSnapshot();
@Test
public void testGetCollectedChunks() throws SnapshotTracker.InvalidChunkException {
- SnapshotTracker tracker1 = new SnapshotTracker(logger, 5);
+ SnapshotTracker tracker1 = new SnapshotTracker(logger, 5, "leader");
- ByteString chunks = chunk1.concat(chunk2);
+ ByteString chunks = ByteString.copyFrom(chunk1).concat(ByteString.copyFrom(chunk2));
- tracker1.addChunk(1, chunk1, Optional.<Integer>absent());
- tracker1.addChunk(2, chunk2, Optional.<Integer>absent());
+ tracker1.addChunk(1, chunk1, Optional.of(LeaderInstallSnapshotState.INITIAL_LAST_CHUNK_HASH_CODE));
+ tracker1.addChunk(2, chunk2, Optional.of(Arrays.hashCode(chunk1)));
assertEquals(chunks, tracker1.getCollectedChunks());
}
- public ByteString getNextChunk (ByteString bs, int offset, int size){
+ public 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);
+
+ byte[] nextChunk = new byte[size];
+ bs.copyTo(nextChunk, start, 0, size);
+ return nextChunk;
}
- private ByteString toByteString(Map<String, String> state) {
- ByteArrayOutputStream b = null;
- ObjectOutputStream o = null;
+ private static ByteString toByteString(Map<String, String> state) {
+ ByteArrayOutputStream bos = null;
+ ObjectOutputStream os = null;
try {
try {
- b = new ByteArrayOutputStream();
- o = new ObjectOutputStream(b);
- o.writeObject(state);
- byte[] snapshotBytes = b.toByteArray();
+ bos = new ByteArrayOutputStream();
+ os = new ObjectOutputStream(bos);
+ os.writeObject(state);
+ byte[] snapshotBytes = bos.toByteArray();
return ByteString.copyFrom(snapshotBytes);
} finally {
- if (o != null) {
- o.flush();
- o.close();
+ if (os != null) {
+ os.flush();
+ os.close();
}
- if (b != null) {
- b.close();
+ if (bos != null) {
+ bos.close();
}
}
} catch (IOException e) {
}
-}
\ No newline at end of file
+}