2 * Copyright (c) 2015 Brocade Communications Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.cluster.raft;
10 import static org.junit.Assert.assertEquals;
11 import static org.mockito.Matchers.anyLong;
12 import static org.mockito.Matchers.same;
13 import static org.mockito.Mockito.doReturn;
14 import static org.mockito.Mockito.verify;
15 import akka.actor.ActorRef;
16 import akka.japi.Procedure;
17 import akka.persistence.SaveSnapshotFailure;
18 import akka.persistence.SaveSnapshotSuccess;
19 import akka.persistence.SnapshotMetadata;
20 import java.util.Arrays;
21 import java.util.Collections;
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.mockito.ArgumentCaptor;
25 import org.mockito.Mock;
26 import org.mockito.MockitoAnnotations;
27 import org.opendaylight.controller.cluster.DataPersistenceProvider;
28 import org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload;
29 import org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockReplicatedLogEntry;
30 import org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot;
31 import org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshot;
32 import org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshotReply;
33 import org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
38 * Unit tests for RaftActorSnapshotMessageSupport.
40 * @author Thomas Pantelis
42 public class RaftActorSnapshotMessageSupportTest {
44 private static final Logger LOG = LoggerFactory.getLogger(RaftActorRecoverySupportTest.class);
47 private DataPersistenceProvider mockPersistence;
50 private RaftActorBehavior mockBehavior;
53 private RaftActorSnapshotCohort mockCohort;
56 private SnapshotManager mockSnapshotManager;
59 ActorRef mockRaftActorRef;
61 private RaftActorSnapshotMessageSupport support;
63 private RaftActorContext context;
64 private final DefaultConfigParamsImpl configParams = new DefaultConfigParamsImpl();
68 MockitoAnnotations.initMocks(this);
70 context = new RaftActorContextImpl(mockRaftActorRef, null, "test",
71 new ElectionTermImpl(mockPersistence, "test", LOG),
72 -1, -1, Collections.<String,String>emptyMap(), configParams, LOG) {
74 public SnapshotManager getSnapshotManager() {
75 return mockSnapshotManager;
79 support = new RaftActorSnapshotMessageSupport(mockPersistence, context, mockBehavior, mockCohort);
81 doReturn(true).when(mockPersistence).isRecoveryApplicable();
83 context.setReplicatedLog(ReplicatedLogImpl.newInstance(context, mockPersistence, mockBehavior));
86 private void sendMessageToSupport(Object message) {
87 sendMessageToSupport(message, true);
90 private void sendMessageToSupport(Object message, boolean expHandled) {
91 boolean handled = support.handleSnapshotMessage(message);
92 assertEquals("complete", expHandled, handled);
96 public void testOnApplySnapshot() {
98 ReplicatedLog replicatedLog = context.getReplicatedLog();
99 replicatedLog.append(new MockReplicatedLogEntry(1, 1, new MockPayload("1")));
101 byte[] snapshotBytes = {1,2,3,4,5};
103 ReplicatedLogEntry unAppliedEntry = new MockReplicatedLogEntry(1, 2, new MockPayload("2"));
105 long lastAppliedDuringSnapshotCapture = 1;
106 long lastIndexDuringSnapshotCapture = 2;
108 Snapshot snapshot = Snapshot.create(snapshotBytes, Arrays.asList(unAppliedEntry),
109 lastIndexDuringSnapshotCapture, 1, lastAppliedDuringSnapshotCapture, 1);
111 sendMessageToSupport(new ApplySnapshot(snapshot));
113 assertEquals("Journal log size", 1, context.getReplicatedLog().size());
114 assertEquals("Last index", lastIndexDuringSnapshotCapture, context.getReplicatedLog().lastIndex());
115 assertEquals("Last applied", lastAppliedDuringSnapshotCapture, context.getLastApplied());
116 assertEquals("Commit index", -1, context.getCommitIndex());
117 assertEquals("Snapshot term", 1, context.getReplicatedLog().getSnapshotTerm());
118 assertEquals("Snapshot index", lastAppliedDuringSnapshotCapture, context.getReplicatedLog().getSnapshotIndex());
120 verify(mockCohort).applySnapshot(snapshotBytes);
123 @SuppressWarnings({ "rawtypes", "unchecked" })
125 public void testOnCaptureSnapshot() throws Exception {
127 sendMessageToSupport(new CaptureSnapshot(3, 1, 2, 1, 2, 1));
129 ArgumentCaptor<Procedure> procedure = ArgumentCaptor.forClass(Procedure.class);
130 verify(mockSnapshotManager).create(procedure.capture());
132 procedure.getValue().apply(null);
134 verify(mockCohort).createSnapshot(same(mockRaftActorRef));
138 public void testOnCaptureSnapshotReply() {
140 byte[] snapshot = {1,2,3,4,5};
141 sendMessageToSupport(new CaptureSnapshotReply(snapshot));
143 verify(mockSnapshotManager).persist(same(mockPersistence), same(snapshot), same(mockBehavior), anyLong());
147 public void testOnSaveSnapshotSuccess() {
149 long sequenceNumber = 100;
150 sendMessageToSupport(new SaveSnapshotSuccess(new SnapshotMetadata("foo", sequenceNumber, 1234L)));
152 verify(mockSnapshotManager).commit(mockPersistence, sequenceNumber);
156 public void testOnSaveSnapshotFailure() {
158 sendMessageToSupport(new SaveSnapshotFailure(new SnapshotMetadata("foo", 100, 1234L),
159 new Throwable("mock")));
161 verify(mockSnapshotManager).rollback();
165 public void testOnCommitSnapshot() {
167 sendMessageToSupport(RaftActorSnapshotMessageSupport.COMMIT_SNAPSHOT);
169 verify(mockSnapshotManager).commit(mockPersistence, -1);
173 public void testUnhandledMessage() {
175 sendMessageToSupport("unhandled", false);