blob: ac4ce411bf54e186d4a4a0073424f9a596f26170 [file] [log] [blame]
yoonseonfe721972017-01-10 17:18:49 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
yoonseonfe721972017-01-10 17:18:49 -08003 *
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 */
16
17package org.onosproject.incubator.net.virtual.event;
18
yoonseonc6a69272017-01-12 18:22:20 -080019import com.google.common.collect.ClassToInstanceMap;
20import com.google.common.collect.MutableClassToInstanceMap;
yoonseonfe721972017-01-10 17:18:49 -080021import org.junit.After;
22import org.junit.Before;
23import org.junit.Test;
yoonseonc6a69272017-01-12 18:22:20 -080024import org.onlab.osgi.ServiceDirectory;
yoonseonfe721972017-01-10 17:18:49 -080025import org.onosproject.event.AbstractEvent;
26import org.onosproject.event.Event;
27import org.onosproject.event.EventDeliveryService;
28import org.onosproject.event.EventListener;
29import org.onosproject.event.EventSink;
30import org.onosproject.incubator.net.virtual.NetworkId;
Jovana Vuletac884b692017-11-28 16:52:35 +010031import org.onosproject.incubator.net.virtual.TenantId;
32import org.onosproject.incubator.net.virtual.VirtualNetwork;
yoonseonc6a69272017-01-12 18:22:20 -080033import org.onosproject.incubator.net.virtual.VirtualNetworkService;
Yoonseon Hanffcc32f2017-05-03 14:42:17 -070034import org.onosproject.incubator.net.virtual.VirtualNetworkServiceAdapter;
yoonseonfe721972017-01-10 17:18:49 -080035
36import java.util.ArrayList;
37import java.util.List;
38import java.util.Set;
39import java.util.concurrent.CountDownLatch;
40import java.util.concurrent.TimeUnit;
41
42import static org.junit.Assert.*;
43
44/**
45 * Test of the virtual event dispatcher mechanism.
46 */
47public class AbstractVirtualListenerManagerTest {
48
Yoonseon Hanb14461b2017-03-07 14:08:01 +090049 private TestEventDispatcher dispatcher = new TestEventDispatcher();
50 private VirtualListenerRegistryManager listenerRegistryManager =
yoonseonfe721972017-01-10 17:18:49 -080051 VirtualListenerRegistryManager.getInstance();
52
Yoonseon Hanb14461b2017-03-07 14:08:01 +090053 private PrickleManager prickleManager;
54 private PrickleListener prickleListener;
yoonseonfe721972017-01-10 17:18:49 -080055
Yoonseon Hanb14461b2017-03-07 14:08:01 +090056 private GooManager gooManager;
57 private GooListener gooListener;
yoonseonfe721972017-01-10 17:18:49 -080058
Yoonseon Hanb14461b2017-03-07 14:08:01 +090059 private BarManager barManager;
60 private BarListener barListener;
yoonseonfe721972017-01-10 17:18:49 -080061
62 @Before
63 public void setUp() {
Yoonseon Hanb14461b2017-03-07 14:08:01 +090064 VirtualNetworkService manager = new TestVirtualNetworkManager();
yoonseonc6a69272017-01-12 18:22:20 -080065
yoonseonfe721972017-01-10 17:18:49 -080066 dispatcher.addSink(VirtualEvent.class, listenerRegistryManager);
67
68 prickleListener = new PrickleListener();
yoonseonc6a69272017-01-12 18:22:20 -080069 prickleManager = new PrickleManager(manager, NetworkId.networkId(1));
yoonseonfe721972017-01-10 17:18:49 -080070 prickleManager.addListener(prickleListener);
71
72 gooListener = new GooListener();
yoonseonc6a69272017-01-12 18:22:20 -080073 gooManager = new GooManager(manager, NetworkId.networkId(1));
yoonseonfe721972017-01-10 17:18:49 -080074 gooManager.addListener(gooListener);
75
76 barListener = new BarListener();
yoonseonc6a69272017-01-12 18:22:20 -080077 barManager = new BarManager(manager, NetworkId.networkId(2));
yoonseonfe721972017-01-10 17:18:49 -080078 barManager.addListener(barListener);
79 }
80
81 @After
82 public void tearDown() {
83 dispatcher.removeSink(VirtualEvent.class);
84
85 prickleListener.events.clear();
86 gooListener.events.clear();
87 barListener.events.clear();
88
89 prickleListener.latch = null;
90 gooListener.latch = null;
91 barListener.latch = null;
92 }
93
94 @Test
95 public void postPrickle() throws InterruptedException {
96 prickleListener.latch = new CountDownLatch(1);
97 prickleManager.post(new Prickle("prickle"));
98 prickleListener.latch.await(100, TimeUnit.MILLISECONDS);
99
100 validate(prickleListener, "prickle");
101 validate(gooListener);
102 validate(barListener);
103 }
104
105 @Test
106 public void postGoo() throws InterruptedException {
107 gooListener.latch = new CountDownLatch(1);
108 gooManager.post(new Goo("goo"));
109 gooListener.latch.await(100, TimeUnit.MILLISECONDS);
110
111 validate(prickleListener);
112 validate(gooListener, "goo");
113 validate(barListener);
114 }
115
116 @Test
117 public void postBar() throws InterruptedException {
118 barListener.latch = new CountDownLatch(1);
119 barManager.post(new Bar("bar"));
120 barListener.latch.await(100, TimeUnit.MILLISECONDS);
121
122 validate(prickleListener);
123 validate(gooListener);
124 validate(barListener, "bar");
125 }
126
127 @Test
128 public void postEventWithNoListener() throws Exception {
129 dispatcher.post(new Thing("boom"));
130
131 validate(prickleListener);
132 validate(gooListener);
133 validate(barListener);
134 }
135
136 private void validate(TestListener listener, String... strings) {
137 int i = 0;
138 assertEquals("incorrect event count", strings.length, listener.events.size());
139 for (String string : strings) {
140 Event event = (Event) listener.events.get(i++);
141 assertEquals("incorrect event", string, event.subject());
142 }
143 }
144
145 private enum Type { FOO }
146
147 private static class Thing extends AbstractEvent<Type, String> {
Hyunsun Moonffaeac32017-04-05 11:25:17 +0900148 protected Thing(String subject) {
yoonseonfe721972017-01-10 17:18:49 -0800149 super(Type.FOO, subject);
150 }
151 }
152
Hyunsun Moonffaeac32017-04-05 11:25:17 +0900153 private static final class Prickle extends Thing {
Yoonseon Hanb14461b2017-03-07 14:08:01 +0900154 private Prickle(String subject) {
yoonseonfe721972017-01-10 17:18:49 -0800155 super(subject);
156 }
157 }
158
Hyunsun Moonffaeac32017-04-05 11:25:17 +0900159 private static final class Goo extends Thing {
Yoonseon Hanb14461b2017-03-07 14:08:01 +0900160 private Goo(String subject) {
yoonseonfe721972017-01-10 17:18:49 -0800161 super(subject);
162 }
163 }
164
Hyunsun Moonffaeac32017-04-05 11:25:17 +0900165 private static final class Bar extends Thing {
Yoonseon Hanb14461b2017-03-07 14:08:01 +0900166 private Bar(String subject) {
yoonseonfe721972017-01-10 17:18:49 -0800167 super(subject);
168 }
169 }
170
171 private class TestListener<E extends Event> implements EventListener<E> {
172 List<E> events = new ArrayList<>();
173 CountDownLatch latch;
174
175 @Override
176 public void event(E event) {
yoonseonfe721972017-01-10 17:18:49 -0800177 events.add(event);
178 latch.countDown();
179 }
180 }
181
182 private class PrickleListener extends TestListener<Prickle> {
183 }
184
185 private class GooListener extends TestListener<Goo> {
186 }
187
188 private class BarListener extends TestListener<Bar> {
189 }
190
191 private class PrickleManager extends AbstractVirtualListenerManager<Prickle, PrickleListener> {
yoonseonc6a69272017-01-12 18:22:20 -0800192 public PrickleManager(VirtualNetworkService service, NetworkId networkId) {
Yoonseon Hanb14461b2017-03-07 14:08:01 +0900193 super(service, networkId, Prickle.class);
yoonseonfe721972017-01-10 17:18:49 -0800194 }
195 }
196
197 private class GooManager extends AbstractVirtualListenerManager<Goo, GooListener> {
yoonseonc6a69272017-01-12 18:22:20 -0800198 public GooManager(VirtualNetworkService service, NetworkId networkId) {
Yoonseon Hanb14461b2017-03-07 14:08:01 +0900199 super(service, networkId, Goo.class);
yoonseonfe721972017-01-10 17:18:49 -0800200 }
201 }
202
203 private class BarManager extends AbstractVirtualListenerManager<Bar, BarListener> {
yoonseonc6a69272017-01-12 18:22:20 -0800204 public BarManager(VirtualNetworkService service, NetworkId networkId) {
Yoonseon Hanb14461b2017-03-07 14:08:01 +0900205 super(service, networkId, Bar.class);
yoonseonfe721972017-01-10 17:18:49 -0800206 }
207 }
208
209
210 private class TestEventDispatcher implements EventDeliveryService {
211 private EventSink sink;
212
213 @Override
214 public <E extends Event> void addSink(Class<E> eventClass, EventSink<E> sink) {
215 this.sink = sink;
216 }
217
218 @Override
219 public <E extends Event> void removeSink(Class<E> eventClass) {
220 this.sink = null;
221 }
222
223 @Override
224 public <E extends Event> EventSink<E> getSink(Class<E> eventClass) {
225 return null;
226 }
227
228 @Override
229 public Set<Class<? extends Event>> getSinks() {
230 return null;
231 }
232
233 @Override
234 public void setDispatchTimeLimit(long millis) {
235
236 }
237
238 @Override
239 public long getDispatchTimeLimit() {
240 return 0;
241 }
242
243 @Override
244 public void post(Event event) {
245 if (event instanceof VirtualEvent) {
246 sink.process(event);
247 }
248 }
249 }
yoonseonc6a69272017-01-12 18:22:20 -0800250
Yoonseon Hanffcc32f2017-05-03 14:42:17 -0700251 private class TestVirtualNetworkManager extends VirtualNetworkServiceAdapter {
yoonseonc6a69272017-01-12 18:22:20 -0800252 TestServiceDirectory serviceDirectory = new TestServiceDirectory();
253
254 public TestVirtualNetworkManager() {
255 serviceDirectory.add(EventDeliveryService.class, dispatcher);
256 }
257
258 @Override
Jovana Vuletac884b692017-11-28 16:52:35 +0100259 public VirtualNetwork getVirtualNetwork(NetworkId networkId) {
260 return null;
261 }
262
263 @Override
264 public TenantId getTenantId(NetworkId networkId) {
265 return null;
266 }
267
268 @Override
yoonseonc6a69272017-01-12 18:22:20 -0800269 public ServiceDirectory getServiceDirectory() {
270 return serviceDirectory;
271 }
272 }
273
274 private class TestServiceDirectory implements ServiceDirectory {
275
276 private ClassToInstanceMap<Object> services = MutableClassToInstanceMap.create();
277
278 @Override
279 public <T> T get(Class<T> serviceClass) {
280 return services.getInstance(serviceClass);
281 }
282
283 /**
284 * Adds a new service to the directory.
285 *
286 * @param serviceClass service class
287 * @param service service instance
288 * @return self
289 */
290 public TestServiceDirectory add(Class serviceClass, Object service) {
291 services.putInstance(serviceClass, service);
292 return this;
293 }
294
295 }
yoonseonfe721972017-01-10 17:18:49 -0800296}