9bef4fb750f3b2326c54859e9aeeb54cab2dd167
[controller.git] / opendaylight / md-sal / sal-akka-raft / src / test / java / org / opendaylight / controller / cluster / raft / ReplicatedLogImplTest.java
1 /*
2  * Copyright (c) 2015 Brocade Communications Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.cluster.raft;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.mockito.Matchers.same;
12 import static org.mockito.Mockito.doReturn;
13 import static org.mockito.Mockito.reset;
14 import static org.mockito.Mockito.verify;
15 import static org.mockito.Mockito.verifyNoMoreInteractions;
16 import akka.japi.Procedure;
17 import java.util.Collections;
18 import java.util.function.Supplier;
19 import org.hamcrest.BaseMatcher;
20 import org.hamcrest.Description;
21 import org.hamcrest.Matcher;
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.mockito.ArgumentCaptor;
25 import org.mockito.Matchers;
26 import org.mockito.Mock;
27 import org.mockito.Mockito;
28 import org.mockito.MockitoAnnotations;
29 import org.mockito.internal.matchers.Same;
30 import org.opendaylight.controller.cluster.DataPersistenceProvider;
31 import org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload;
32 import org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockReplicatedLogEntry;
33 import org.opendaylight.controller.cluster.raft.base.messages.DeleteEntries;
34 import org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 /**
39  * Unit tests for ReplicatedLogImpl.
40  *
41  * @author Thomas Pantelis
42  */
43 public class ReplicatedLogImplTest {
44     private static final Logger LOG = LoggerFactory.getLogger(RaftActorRecoverySupportTest.class);
45
46     @Mock
47     private DataPersistenceProvider mockPersistence;
48
49     @Mock
50     private RaftActorBehavior mockBehavior;
51
52     private RaftActorContext context;
53     private final DefaultConfigParamsImpl configParams = new DefaultConfigParamsImpl();
54
55     @Before
56     public void setup() {
57         MockitoAnnotations.initMocks(this);
58
59         context = new RaftActorContextImpl(null, null, "test",
60                 new ElectionTermImpl(mockPersistence, "test", LOG),
61                 -1, -1, Collections.<String,String>emptyMap(), configParams, mockPersistence, LOG);
62     }
63
64     private void verifyPersist(Object message) throws Exception {
65         verifyPersist(message, new Same(message));
66     }
67
68     @SuppressWarnings({ "unchecked", "rawtypes" })
69     private void verifyPersist(Object message, Matcher<?> matcher) throws Exception {
70         ArgumentCaptor<Procedure> procedure = ArgumentCaptor.forClass(Procedure.class);
71         verify(mockPersistence).persist(Matchers.argThat(matcher), procedure.capture());
72
73         procedure.getValue().apply(message);
74     }
75
76     @SuppressWarnings("unchecked")
77     @Test
78     public void testAppendAndPersistExpectingNoCapture() throws Exception {
79         ReplicatedLog log = ReplicatedLogImpl.newInstance(context);
80
81         MockReplicatedLogEntry logEntry = new MockReplicatedLogEntry(1, 1, new MockPayload("1"));
82
83         log.appendAndPersist(logEntry);
84
85         verifyPersist(logEntry);
86
87         assertEquals("size", 1, log.size());
88
89         reset(mockPersistence);
90
91         Procedure<ReplicatedLogEntry> mockCallback = Mockito.mock(Procedure.class);
92         log.appendAndPersist(logEntry, mockCallback);
93
94         verifyPersist(logEntry);
95
96         verify(mockCallback).apply(same(logEntry));
97
98         assertEquals("size", 2, log.size());
99     }
100
101     @Test
102     public void testAppendAndPersistExpectingCaptureDueToJournalCount() throws Exception {
103         configParams.setSnapshotBatchCount(2);
104
105         doReturn(1L).when(mockBehavior).getReplicatedToAllIndex();
106
107         ReplicatedLog log = ReplicatedLogImpl.newInstance(context);
108
109         MockReplicatedLogEntry logEntry1 = new MockReplicatedLogEntry(1, 2, new MockPayload("2"));
110         MockReplicatedLogEntry logEntry2 = new MockReplicatedLogEntry(1, 3, new MockPayload("3"));
111
112         log.appendAndPersist(logEntry1);
113         verifyPersist(logEntry1);
114
115         reset(mockPersistence);
116
117         log.appendAndPersist(logEntry2);
118         verifyPersist(logEntry2);
119
120
121         assertEquals("size", 2, log.size());
122     }
123
124     @Test
125     public void testAppendAndPersistExpectingCaptureDueToDataSize() throws Exception {
126         doReturn(1L).when(mockBehavior).getReplicatedToAllIndex();
127
128         context.setTotalMemoryRetriever(new Supplier<Long>() {
129             @Override
130             public Long get() {
131                 return 100L;
132             }
133         });
134
135         ReplicatedLog log = ReplicatedLogImpl.newInstance(context);
136
137         int dataSize = 600;
138         MockReplicatedLogEntry logEntry = new MockReplicatedLogEntry(1, 2, new MockPayload("2", dataSize));
139
140         log.appendAndPersist(logEntry);
141         verifyPersist(logEntry);
142
143         reset(mockPersistence);
144
145         logEntry = new MockReplicatedLogEntry(1, 3, new MockPayload("3", 5));
146
147         log.appendAndPersist(logEntry);
148         verifyPersist(logEntry);
149
150         assertEquals("size", 2, log.size());
151     }
152
153     @Test
154     public void testRemoveFromAndPersist() throws Exception {
155
156         ReplicatedLog log = ReplicatedLogImpl.newInstance(context);
157
158         log.append(new MockReplicatedLogEntry(1, 0, new MockPayload("0")));
159         log.append(new MockReplicatedLogEntry(1, 1, new MockPayload("1")));
160         log.append(new MockReplicatedLogEntry(1, 2, new MockPayload("2")));
161
162         log.removeFromAndPersist(1);
163
164         DeleteEntries deleteEntries = new DeleteEntries(1);
165         verifyPersist(deleteEntries, match(deleteEntries));
166
167         assertEquals("size", 1, log.size());
168
169         reset(mockPersistence);
170
171         log.removeFromAndPersist(1);
172
173         verifyNoMoreInteractions(mockPersistence);
174     }
175
176     public Matcher<DeleteEntries> match(final DeleteEntries actual){
177         return new BaseMatcher<DeleteEntries>() {
178             @Override
179             public boolean matches(Object o) {
180                 DeleteEntries other = (DeleteEntries) o;
181                 return actual.getFromIndex() == other.getFromIndex();
182             }
183
184             @Override
185             public void describeTo(Description description) {
186                 description.appendText("DeleteEntries: fromIndex: " + actual.getFromIndex());
187             }
188         };
189     }
190 }

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.