blob: 1195e692bd72fb3d0754ff7f716828b634302446 [file] [log] [blame]
yoonseonfe721972017-01-10 17:18:49 -08001/*
2 * Copyright 2017-present 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 */
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;
yoonseon322c9c32016-12-07 16:47:02 -080025import org.onosproject.core.ApplicationId;
yoonseonfe721972017-01-10 17:18:49 -080026import org.onosproject.event.AbstractEvent;
27import org.onosproject.event.Event;
28import org.onosproject.event.EventDeliveryService;
29import org.onosproject.event.EventListener;
30import org.onosproject.event.EventSink;
31import org.onosproject.incubator.net.virtual.NetworkId;
yoonseonc6a69272017-01-12 18:22:20 -080032import org.onosproject.incubator.net.virtual.TenantId;
33import org.onosproject.incubator.net.virtual.VirtualDevice;
34import org.onosproject.incubator.net.virtual.VirtualHost;
35import org.onosproject.incubator.net.virtual.VirtualLink;
36import org.onosproject.incubator.net.virtual.VirtualNetwork;
37import org.onosproject.incubator.net.virtual.VirtualNetworkService;
38import org.onosproject.incubator.net.virtual.VirtualPort;
39import org.onosproject.net.DeviceId;
yoonseonfe721972017-01-10 17:18:49 -080040
41import java.util.ArrayList;
42import java.util.List;
43import java.util.Set;
44import java.util.concurrent.CountDownLatch;
45import java.util.concurrent.TimeUnit;
46
47import static org.junit.Assert.*;
48
49/**
50 * Test of the virtual event dispatcher mechanism.
51 */
52public class AbstractVirtualListenerManagerTest {
53
yoonseonc6a69272017-01-12 18:22:20 -080054 private VirtualNetworkService manager;
55
yoonseonfe721972017-01-10 17:18:49 -080056 TestEventDispatcher dispatcher = new TestEventDispatcher();
57 VirtualListenerRegistryManager listenerRegistryManager =
58 VirtualListenerRegistryManager.getInstance();
59
60 PrickleManager prickleManager;
61 PrickleListener prickleListener;
62
63 GooManager gooManager;
64 GooListener gooListener;
65
66 BarManager barManager;
67 BarListener barListener;
68
69 @Before
70 public void setUp() {
yoonseonc6a69272017-01-12 18:22:20 -080071 manager = new TestVirtualNetworkManager();
72
yoonseonfe721972017-01-10 17:18:49 -080073 dispatcher.addSink(VirtualEvent.class, listenerRegistryManager);
74
75 prickleListener = new PrickleListener();
yoonseonc6a69272017-01-12 18:22:20 -080076 prickleManager = new PrickleManager(manager, NetworkId.networkId(1));
yoonseonfe721972017-01-10 17:18:49 -080077 prickleManager.addListener(prickleListener);
78
79 gooListener = new GooListener();
yoonseonc6a69272017-01-12 18:22:20 -080080 gooManager = new GooManager(manager, NetworkId.networkId(1));
yoonseonfe721972017-01-10 17:18:49 -080081 gooManager.addListener(gooListener);
82
83 barListener = new BarListener();
yoonseonc6a69272017-01-12 18:22:20 -080084 barManager = new BarManager(manager, NetworkId.networkId(2));
yoonseonfe721972017-01-10 17:18:49 -080085 barManager.addListener(barListener);
86 }
87
88 @After
89 public void tearDown() {
90 dispatcher.removeSink(VirtualEvent.class);
91
92 prickleListener.events.clear();
93 gooListener.events.clear();
94 barListener.events.clear();
95
96 prickleListener.latch = null;
97 gooListener.latch = null;
98 barListener.latch = null;
99 }
100
101 @Test
102 public void postPrickle() throws InterruptedException {
103 prickleListener.latch = new CountDownLatch(1);
104 prickleManager.post(new Prickle("prickle"));
105 prickleListener.latch.await(100, TimeUnit.MILLISECONDS);
106
107 validate(prickleListener, "prickle");
108 validate(gooListener);
109 validate(barListener);
110 }
111
112 @Test
113 public void postGoo() throws InterruptedException {
114 gooListener.latch = new CountDownLatch(1);
115 gooManager.post(new Goo("goo"));
116 gooListener.latch.await(100, TimeUnit.MILLISECONDS);
117
118 validate(prickleListener);
119 validate(gooListener, "goo");
120 validate(barListener);
121 }
122
123 @Test
124 public void postBar() throws InterruptedException {
125 barListener.latch = new CountDownLatch(1);
126 barManager.post(new Bar("bar"));
127 barListener.latch.await(100, TimeUnit.MILLISECONDS);
128
129 validate(prickleListener);
130 validate(gooListener);
131 validate(barListener, "bar");
132 }
133
134 @Test
135 public void postEventWithNoListener() throws Exception {
136 dispatcher.post(new Thing("boom"));
137
138 validate(prickleListener);
139 validate(gooListener);
140 validate(barListener);
141 }
142
143 private void validate(TestListener listener, String... strings) {
144 int i = 0;
145 assertEquals("incorrect event count", strings.length, listener.events.size());
146 for (String string : strings) {
147 Event event = (Event) listener.events.get(i++);
148 assertEquals("incorrect event", string, event.subject());
149 }
150 }
151
152 private enum Type { FOO }
153
154 private static class Thing extends AbstractEvent<Type, String> {
155 protected Thing(String subject) {
156 super(Type.FOO, subject);
157 }
158 }
159
160 private static class Prickle extends Thing {
161 protected Prickle(String subject) {
162 super(subject);
163 }
164 }
165
166 private static class Goo extends Thing {
167 protected Goo(String subject) {
168 super(subject);
169 }
170 }
171
172 private static class Bar extends Thing {
173 protected Bar(String subject) {
174 super(subject);
175 }
176 }
177
178 private class TestListener<E extends Event> implements EventListener<E> {
179 List<E> events = new ArrayList<>();
180 CountDownLatch latch;
181
182 @Override
183 public void event(E event) {
yoonseonfe721972017-01-10 17:18:49 -0800184 events.add(event);
185 latch.countDown();
186 }
187 }
188
189 private class PrickleListener extends TestListener<Prickle> {
190 }
191
192 private class GooListener extends TestListener<Goo> {
193 }
194
195 private class BarListener extends TestListener<Bar> {
196 }
197
198 private class PrickleManager extends AbstractVirtualListenerManager<Prickle, PrickleListener> {
yoonseonc6a69272017-01-12 18:22:20 -0800199 public PrickleManager(VirtualNetworkService service, NetworkId networkId) {
200 super(service, networkId);
yoonseonfe721972017-01-10 17:18:49 -0800201 }
202 }
203
204 private class GooManager extends AbstractVirtualListenerManager<Goo, GooListener> {
yoonseonc6a69272017-01-12 18:22:20 -0800205 public GooManager(VirtualNetworkService service, NetworkId networkId) {
206 super(service, networkId);
yoonseonfe721972017-01-10 17:18:49 -0800207 }
208 }
209
210 private class BarManager extends AbstractVirtualListenerManager<Bar, BarListener> {
yoonseonc6a69272017-01-12 18:22:20 -0800211 public BarManager(VirtualNetworkService service, NetworkId networkId) {
212 super(service, networkId);
yoonseonfe721972017-01-10 17:18:49 -0800213 }
214 }
215
216
217 private class TestEventDispatcher implements EventDeliveryService {
218 private EventSink sink;
219
220 @Override
221 public <E extends Event> void addSink(Class<E> eventClass, EventSink<E> sink) {
222 this.sink = sink;
223 }
224
225 @Override
226 public <E extends Event> void removeSink(Class<E> eventClass) {
227 this.sink = null;
228 }
229
230 @Override
231 public <E extends Event> EventSink<E> getSink(Class<E> eventClass) {
232 return null;
233 }
234
235 @Override
236 public Set<Class<? extends Event>> getSinks() {
237 return null;
238 }
239
240 @Override
241 public void setDispatchTimeLimit(long millis) {
242
243 }
244
245 @Override
246 public long getDispatchTimeLimit() {
247 return 0;
248 }
249
250 @Override
251 public void post(Event event) {
252 if (event instanceof VirtualEvent) {
253 sink.process(event);
254 }
255 }
256 }
yoonseonc6a69272017-01-12 18:22:20 -0800257
258 private class TestVirtualNetworkManager implements VirtualNetworkService {
259 TestServiceDirectory serviceDirectory = new TestServiceDirectory();
260
261 public TestVirtualNetworkManager() {
262 serviceDirectory.add(EventDeliveryService.class, dispatcher);
263 }
264
265 @Override
266 public Set<VirtualNetwork> getVirtualNetworks(TenantId tenantId) {
267 return null;
268 }
269
270 @Override
271 public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) {
272 return null;
273 }
274
275 @Override
276 public Set<VirtualHost> getVirtualHosts(NetworkId networkId) {
277 return null;
278 }
279
280 @Override
281 public Set<VirtualLink> getVirtualLinks(NetworkId networkId) {
282 return null;
283 }
284
285 @Override
286 public Set<VirtualPort> getVirtualPorts(NetworkId networkId, DeviceId deviceId) {
287 return null;
288 }
289
290 @Override
291 public <T> T get(NetworkId networkId, Class<T> serviceClass) {
292 return null;
293 }
294
295 @Override
296 public ServiceDirectory getServiceDirectory() {
297 return serviceDirectory;
298 }
yoonseon322c9c32016-12-07 16:47:02 -0800299
300 @Override
301 public ApplicationId getVirtualNetworkApplicationId(NetworkId networkId) {
302 return null;
303 }
yoonseonc6a69272017-01-12 18:22:20 -0800304 }
305
306 private class TestServiceDirectory implements ServiceDirectory {
307
308 private ClassToInstanceMap<Object> services = MutableClassToInstanceMap.create();
309
310 @Override
311 public <T> T get(Class<T> serviceClass) {
312 return services.getInstance(serviceClass);
313 }
314
315 /**
316 * Adds a new service to the directory.
317 *
318 * @param serviceClass service class
319 * @param service service instance
320 * @return self
321 */
322 public TestServiceDirectory add(Class serviceClass, Object service) {
323 services.putInstance(serviceClass, service);
324 return this;
325 }
326
327 }
yoonseonfe721972017-01-10 17:18:49 -0800328}