blob: 9bc115364cda504147b3531fe8b824316a31e89c [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.store.flow.impl;
Yuta HIGUCHI4d187952014-10-16 19:59:35 -070017
18import static com.google.common.base.Preconditions.checkState;
19import static org.junit.Assert.*;
20
21import java.util.Collections;
22import java.util.Map;
Ayaka Koshibefc981cf2014-10-21 12:44:17 -070023import java.util.LinkedList;
Yuta HIGUCHI4d187952014-10-16 19:59:35 -070024import java.util.concurrent.CountDownLatch;
25import java.util.concurrent.TimeUnit;
26
27import org.junit.After;
28import org.junit.Before;
29import org.junit.Test;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.cluster.NodeId;
31import org.onosproject.cluster.RoleInfo;
32import org.onosproject.event.AbstractListenerRegistry;
33import org.onosproject.event.DefaultEventSinkRegistry;
34import org.onosproject.event.Event;
35import org.onosproject.event.EventDeliveryService;
36import org.onosproject.event.EventSink;
37import org.onosproject.mastership.MastershipEvent;
38import org.onosproject.mastership.MastershipEvent.Type;
39import org.onosproject.mastership.MastershipListener;
40import org.onosproject.mastership.MastershipService;
41import org.onosproject.mastership.MastershipServiceAdapter;
42import org.onosproject.net.DeviceId;
43import org.onosproject.store.flow.ReplicaInfo;
44import org.onosproject.store.flow.ReplicaInfoEvent;
45import org.onosproject.store.flow.ReplicaInfoEventListener;
46import org.onosproject.store.flow.ReplicaInfoService;
Yuta HIGUCHI4d187952014-10-16 19:59:35 -070047
48import com.google.common.base.Optional;
49import com.google.common.collect.Maps;
50
51public class ReplicaInfoManagerTest {
52
53
54 private static final DeviceId DID1 = DeviceId.deviceId("of:1");
55 private static final DeviceId DID2 = DeviceId.deviceId("of:2");
56 private static final NodeId NID1 = new NodeId("foo");
57
58 private ReplicaInfoManager mgr;
59 private ReplicaInfoService service;
60
61 private AbstractListenerRegistry<MastershipEvent, MastershipListener>
62 mastershipListenerRegistry;
63 private TestEventDispatcher eventDispatcher;
64
65
66 @Before
67 public void setUp() throws Exception {
68 mastershipListenerRegistry = new AbstractListenerRegistry<>();
69
70 mgr = new ReplicaInfoManager();
71 service = mgr;
72
73 eventDispatcher = new TestEventDispatcher();
74 mgr.eventDispatcher = eventDispatcher;
75 mgr.mastershipService = new TestMastershipService();
76
77 // register dummy mastership event source
78 mgr.eventDispatcher.addSink(MastershipEvent.class, mastershipListenerRegistry);
79
80 mgr.activate();
81 }
82
83 @After
84 public void tearDown() throws Exception {
85 mgr.deactivate();
86 }
87
88 @Test
89 public void testGetReplicaInfoFor() {
90 ReplicaInfo info1 = service.getReplicaInfoFor(DID1);
91 assertEquals(Optional.of(NID1), info1.master());
92 // backups are always empty for now
93 assertEquals(Collections.emptyList(), info1.backups());
94
95 ReplicaInfo info2 = service.getReplicaInfoFor(DID2);
96 assertEquals("There's no master", Optional.absent(), info2.master());
97 // backups are always empty for now
98 assertEquals(Collections.emptyList(), info2.backups());
99 }
100
101 @Test
102 public void testReplicaInfoEvent() throws InterruptedException {
103 final CountDownLatch latch = new CountDownLatch(1);
104 service.addListener(new MasterNodeCheck(latch, DID1, NID1));
105
106 // fake MastershipEvent
Ayaka Koshibefc981cf2014-10-21 12:44:17 -0700107 eventDispatcher.post(new MastershipEvent(Type.MASTER_CHANGED, DID1,
108 new RoleInfo(NID1, new LinkedList<NodeId>())));
Yuta HIGUCHI4d187952014-10-16 19:59:35 -0700109
110 assertTrue(latch.await(1, TimeUnit.SECONDS));
111 }
112
113
114 private final class MasterNodeCheck implements ReplicaInfoEventListener {
115 private final CountDownLatch latch;
116 private Optional<NodeId> expectedMaster;
117 private DeviceId expectedDevice;
118
119
120 MasterNodeCheck(CountDownLatch latch, DeviceId did,
121 NodeId nid) {
122 this.latch = latch;
123 this.expectedMaster = Optional.fromNullable(nid);
124 this.expectedDevice = did;
125 }
126
127 @Override
128 public void event(ReplicaInfoEvent event) {
129 assertEquals(expectedDevice, event.subject());
130 assertEquals(expectedMaster, event.replicaInfo().master());
131 // backups are always empty for now
132 assertEquals(Collections.emptyList(), event.replicaInfo().backups());
133 latch.countDown();
134 }
135 }
136
137
138 private final class TestMastershipService
139 extends MastershipServiceAdapter
140 implements MastershipService {
141
142 private Map<DeviceId, NodeId> masters;
143
144 TestMastershipService() {
145 masters = Maps.newHashMap();
146 masters.put(DID1, NID1);
147 // DID2 has no master
148 }
149
150 @Override
151 public NodeId getMasterFor(DeviceId deviceId) {
152 return masters.get(deviceId);
153 }
154
155 @Override
Madan Jampani86940d92015-05-06 11:47:57 -0700156 public RoleInfo getNodesFor(DeviceId deviceId) {
157 return new RoleInfo(masters.get(deviceId), Collections.emptyList());
158 }
159
160 @Override
Yuta HIGUCHI4d187952014-10-16 19:59:35 -0700161 public void addListener(MastershipListener listener) {
162 mastershipListenerRegistry.addListener(listener);
163 }
164
165 @Override
166 public void removeListener(MastershipListener listener) {
167 mastershipListenerRegistry.removeListener(listener);
168 }
169 }
170
171
172 // code clone
173 /**
174 * Implements event delivery system that delivers events synchronously, or
175 * in-line with the post method invocation.
176 */
177 private static class TestEventDispatcher extends DefaultEventSinkRegistry
178 implements EventDeliveryService {
179
180 @SuppressWarnings({ "rawtypes", "unchecked" })
181 @Override
182 public void post(Event event) {
183 EventSink sink = getSink(event.getClass());
184 checkState(sink != null, "No sink for event %s", event);
185 sink.process(event);
186 }
187 }
188}