blob: e2a3ddf2fe09ed8d37d4fd9a3c139f0b240a7e75 [file] [log] [blame]
Yuta HIGUCHI4d187952014-10-16 19:59:35 -07001package org.onlab.onos.store.flow.impl;
2
3import static com.google.common.base.Preconditions.checkState;
4import static org.junit.Assert.*;
5
6import java.util.Collections;
7import java.util.Map;
Ayaka Koshibefc981cf2014-10-21 12:44:17 -07008import java.util.LinkedList;
Yuta HIGUCHI4d187952014-10-16 19:59:35 -07009import java.util.concurrent.CountDownLatch;
10import java.util.concurrent.TimeUnit;
11
12import org.junit.After;
13import org.junit.Before;
14import org.junit.Test;
15import org.onlab.onos.cluster.NodeId;
Ayaka Koshibefc981cf2014-10-21 12:44:17 -070016import org.onlab.onos.cluster.RoleInfo;
Yuta HIGUCHI4d187952014-10-16 19:59:35 -070017import org.onlab.onos.event.AbstractListenerRegistry;
18import org.onlab.onos.event.DefaultEventSinkRegistry;
19import org.onlab.onos.event.Event;
20import org.onlab.onos.event.EventDeliveryService;
21import org.onlab.onos.event.EventSink;
22import org.onlab.onos.mastership.MastershipEvent;
23import org.onlab.onos.mastership.MastershipEvent.Type;
24import org.onlab.onos.mastership.MastershipListener;
25import org.onlab.onos.mastership.MastershipService;
26import org.onlab.onos.mastership.MastershipServiceAdapter;
27import org.onlab.onos.net.DeviceId;
28import org.onlab.onos.store.flow.ReplicaInfo;
29import org.onlab.onos.store.flow.ReplicaInfoEvent;
30import org.onlab.onos.store.flow.ReplicaInfoEventListener;
31import org.onlab.onos.store.flow.ReplicaInfoService;
32
33import com.google.common.base.Optional;
34import com.google.common.collect.Maps;
35
36public class ReplicaInfoManagerTest {
37
38
39 private static final DeviceId DID1 = DeviceId.deviceId("of:1");
40 private static final DeviceId DID2 = DeviceId.deviceId("of:2");
41 private static final NodeId NID1 = new NodeId("foo");
42
43 private ReplicaInfoManager mgr;
44 private ReplicaInfoService service;
45
46 private AbstractListenerRegistry<MastershipEvent, MastershipListener>
47 mastershipListenerRegistry;
48 private TestEventDispatcher eventDispatcher;
49
50
51 @Before
52 public void setUp() throws Exception {
53 mastershipListenerRegistry = new AbstractListenerRegistry<>();
54
55 mgr = new ReplicaInfoManager();
56 service = mgr;
57
58 eventDispatcher = new TestEventDispatcher();
59 mgr.eventDispatcher = eventDispatcher;
60 mgr.mastershipService = new TestMastershipService();
61
62 // register dummy mastership event source
63 mgr.eventDispatcher.addSink(MastershipEvent.class, mastershipListenerRegistry);
64
65 mgr.activate();
66 }
67
68 @After
69 public void tearDown() throws Exception {
70 mgr.deactivate();
71 }
72
73 @Test
74 public void testGetReplicaInfoFor() {
75 ReplicaInfo info1 = service.getReplicaInfoFor(DID1);
76 assertEquals(Optional.of(NID1), info1.master());
77 // backups are always empty for now
78 assertEquals(Collections.emptyList(), info1.backups());
79
80 ReplicaInfo info2 = service.getReplicaInfoFor(DID2);
81 assertEquals("There's no master", Optional.absent(), info2.master());
82 // backups are always empty for now
83 assertEquals(Collections.emptyList(), info2.backups());
84 }
85
86 @Test
87 public void testReplicaInfoEvent() throws InterruptedException {
88 final CountDownLatch latch = new CountDownLatch(1);
89 service.addListener(new MasterNodeCheck(latch, DID1, NID1));
90
91 // fake MastershipEvent
Ayaka Koshibefc981cf2014-10-21 12:44:17 -070092 eventDispatcher.post(new MastershipEvent(Type.MASTER_CHANGED, DID1,
93 new RoleInfo(NID1, new LinkedList<NodeId>())));
Yuta HIGUCHI4d187952014-10-16 19:59:35 -070094
95 assertTrue(latch.await(1, TimeUnit.SECONDS));
96 }
97
98
99 private final class MasterNodeCheck implements ReplicaInfoEventListener {
100 private final CountDownLatch latch;
101 private Optional<NodeId> expectedMaster;
102 private DeviceId expectedDevice;
103
104
105 MasterNodeCheck(CountDownLatch latch, DeviceId did,
106 NodeId nid) {
107 this.latch = latch;
108 this.expectedMaster = Optional.fromNullable(nid);
109 this.expectedDevice = did;
110 }
111
112 @Override
113 public void event(ReplicaInfoEvent event) {
114 assertEquals(expectedDevice, event.subject());
115 assertEquals(expectedMaster, event.replicaInfo().master());
116 // backups are always empty for now
117 assertEquals(Collections.emptyList(), event.replicaInfo().backups());
118 latch.countDown();
119 }
120 }
121
122
123 private final class TestMastershipService
124 extends MastershipServiceAdapter
125 implements MastershipService {
126
127 private Map<DeviceId, NodeId> masters;
128
129 TestMastershipService() {
130 masters = Maps.newHashMap();
131 masters.put(DID1, NID1);
132 // DID2 has no master
133 }
134
135 @Override
136 public NodeId getMasterFor(DeviceId deviceId) {
137 return masters.get(deviceId);
138 }
139
140 @Override
141 public void addListener(MastershipListener listener) {
142 mastershipListenerRegistry.addListener(listener);
143 }
144
145 @Override
146 public void removeListener(MastershipListener listener) {
147 mastershipListenerRegistry.removeListener(listener);
148 }
149 }
150
151
152 // code clone
153 /**
154 * Implements event delivery system that delivers events synchronously, or
155 * in-line with the post method invocation.
156 */
157 private static class TestEventDispatcher extends DefaultEventSinkRegistry
158 implements EventDeliveryService {
159
160 @SuppressWarnings({ "rawtypes", "unchecked" })
161 @Override
162 public void post(Event event) {
163 EventSink sink = getSink(event.getClass());
164 checkState(sink != null, "No sink for event %s", event);
165 sink.process(event);
166 }
167 }
168}