Tune replication and stabilize tests
[controller.git] / opendaylight / md-sal / sal-akka-raft / src / test / java / org / opendaylight / controller / cluster / raft / AbstractReplicatedLogImplTest.java
1 /*
2  * Copyright (c) 2014 Cisco 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 junit.framework.Assert;
11 import org.junit.After;
12 import org.junit.Before;
13 import org.junit.Test;
14
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertNull;
22 import static org.junit.Assert.assertTrue;
23 import static org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload;
24 import static org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockReplicatedLogEntry;
25 /**
26 *
27 */
28 public class AbstractReplicatedLogImplTest {
29
30     private MockAbstractReplicatedLogImpl replicatedLogImpl;
31
32     @Before
33     public void setUp() {
34         replicatedLogImpl = new MockAbstractReplicatedLogImpl();
35         // create a set of initial entries in the in-memory log
36         replicatedLogImpl.append(new MockReplicatedLogEntry(1, 0, new MockPayload("A")));
37         replicatedLogImpl.append(new MockReplicatedLogEntry(1, 1, new MockPayload("B")));
38         replicatedLogImpl.append(new MockReplicatedLogEntry(1, 2, new MockPayload("C")));
39         replicatedLogImpl.append(new MockReplicatedLogEntry(2, 3, new MockPayload("D")));
40
41     }
42
43     @After
44     public void tearDown() {
45         replicatedLogImpl.journal.clear();
46         replicatedLogImpl.setSnapshotIndex(-1);
47         replicatedLogImpl.setSnapshotTerm(-1);
48         replicatedLogImpl = null;
49     }
50
51     @Test
52     public void testIndexOperations() {
53
54         // check if the values returned are correct, with snapshotIndex = -1
55         assertEquals("B", replicatedLogImpl.get(1).getData().toString());
56         assertEquals("D", replicatedLogImpl.last().getData().toString());
57         assertEquals(3, replicatedLogImpl.lastIndex());
58         assertEquals(2, replicatedLogImpl.lastTerm());
59         assertEquals(2, replicatedLogImpl.getFrom(2).size());
60         assertEquals(4, replicatedLogImpl.size());
61         assertTrue(replicatedLogImpl.isPresent(2));
62         assertFalse(replicatedLogImpl.isPresent(4));
63         assertFalse(replicatedLogImpl.isInSnapshot(2));
64
65         // now create a snapshot of 3 entries, with 1 unapplied entry left in the log
66         // It removes the entries which have made it to snapshot
67         // and updates the snapshot index and term
68         Map state = takeSnapshot(3);
69
70         // check the values after the snapshot.
71         // each index value passed in the test is the logical index (log entry index)
72         // which gets mapped to the list's physical index
73         assertEquals("D", replicatedLogImpl.get(3).getData().toString());
74         assertEquals("D", replicatedLogImpl.last().getData().toString());
75         assertNull(replicatedLogImpl.get(1));
76         assertEquals(3, replicatedLogImpl.lastIndex());
77         assertEquals(2, replicatedLogImpl.lastTerm());
78         assertEquals(0, replicatedLogImpl.getFrom(2).size());
79         assertEquals(1, replicatedLogImpl.size());
80         assertFalse(replicatedLogImpl.isPresent(2));
81         assertTrue(replicatedLogImpl.isPresent(3));
82         assertFalse(replicatedLogImpl.isPresent(4));
83         assertTrue(replicatedLogImpl.isInSnapshot(2));
84
85         // append few more entries
86         replicatedLogImpl.append(new MockReplicatedLogEntry(2, 4, new MockPayload("E")));
87         replicatedLogImpl.append(new MockReplicatedLogEntry(2, 5, new MockPayload("F")));
88         replicatedLogImpl.append(new MockReplicatedLogEntry(3, 6, new MockPayload("G")));
89         replicatedLogImpl.append(new MockReplicatedLogEntry(3, 7, new MockPayload("H")));
90
91         // check their values as well
92         assertEquals(5, replicatedLogImpl.size());
93         assertEquals("D", replicatedLogImpl.get(3).getData().toString());
94         assertEquals("E", replicatedLogImpl.get(4).getData().toString());
95         assertEquals("H", replicatedLogImpl.last().getData().toString());
96         assertEquals(3, replicatedLogImpl.lastTerm());
97         assertEquals(7, replicatedLogImpl.lastIndex());
98         assertTrue(replicatedLogImpl.isPresent(7));
99         assertFalse(replicatedLogImpl.isInSnapshot(7));
100         assertEquals(1, replicatedLogImpl.getFrom(7).size());
101         assertEquals(2, replicatedLogImpl.getFrom(6).size());
102
103         // take a second snapshot with 5 entries with 0 unapplied entries left in the log
104         state = takeSnapshot(5);
105
106         assertEquals(0, replicatedLogImpl.size());
107         assertNull(replicatedLogImpl.last());
108         assertNull(replicatedLogImpl.get(7));
109         assertNull(replicatedLogImpl.get(1));
110         assertFalse(replicatedLogImpl.isPresent(7));
111         assertTrue(replicatedLogImpl.isInSnapshot(7));
112         assertEquals(0, replicatedLogImpl.getFrom(7).size());
113         assertEquals(0, replicatedLogImpl.getFrom(6).size());
114
115     }
116
117     @Test
118     public void testGetFromWithMax(){
119         List<ReplicatedLogEntry> from = replicatedLogImpl.getFrom(0, 1);
120         Assert.assertEquals(1, from.size());
121         Assert.assertEquals(1, from.get(0).getTerm());
122
123         from = replicatedLogImpl.getFrom(0, 20);
124         Assert.assertEquals(4, from.size());
125         Assert.assertEquals(2, from.get(3).getTerm());
126
127         from = replicatedLogImpl.getFrom(1, 2);
128         Assert.assertEquals(2, from.size());
129         Assert.assertEquals(1, from.get(1).getTerm());
130
131     }
132
133     // create a snapshot for test
134     public Map takeSnapshot(int numEntries) {
135         Map map = new HashMap(numEntries);
136         List<ReplicatedLogEntry> entries = replicatedLogImpl.getEntriesTill(numEntries);
137         for (ReplicatedLogEntry entry : entries) {
138             map.put(entry.getIndex(), entry.getData().toString());
139         }
140
141         int term = (int) replicatedLogImpl.lastTerm();
142         int lastIndex = (int) entries.get(entries.size() - 1).getIndex();
143         entries.clear();
144         replicatedLogImpl.setSnapshotTerm(term);
145         replicatedLogImpl.setSnapshotIndex(lastIndex);
146
147         return map;
148
149     }
150     class MockAbstractReplicatedLogImpl extends AbstractReplicatedLogImpl {
151         @Override
152         public void appendAndPersist(ReplicatedLogEntry replicatedLogEntry) {
153         }
154
155         @Override
156         public void removeFromAndPersist(long index) {
157         }
158
159         public void setSnapshotIndex(long snapshotIndex) {
160             this.snapshotIndex = snapshotIndex;
161         }
162
163         public void setSnapshotTerm(long snapshotTerm) {
164             this.snapshotTerm = snapshotTerm;
165         }
166
167         public List<ReplicatedLogEntry> getEntriesTill(int index) {
168             return journal.subList(0, index);
169         }
170     }
171 }