TestUtils is a utility class
[mdsal.git] / dom / mdsal-dom-broker / src / test / java / org / opendaylight / mdsal / dom / broker / DOMNotificationRouterTest.java
1 /*
2  * Copyright (c) 2016 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.mdsal.dom.broker;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertNotEquals;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.assertSame;
15 import static org.junit.Assert.assertTrue;
16 import static org.mockito.ArgumentMatchers.any;
17 import static org.mockito.Mockito.doNothing;
18 import static org.mockito.Mockito.doReturn;
19 import static org.mockito.Mockito.mock;
20 import static org.opendaylight.mdsal.dom.broker.TestUtils.TEST_CHILD;
21
22 import com.google.common.collect.Multimap;
23 import com.google.common.util.concurrent.ListenableFuture;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.List;
27 import java.util.concurrent.CountDownLatch;
28 import java.util.concurrent.ExecutorService;
29 import java.util.concurrent.TimeUnit;
30 import org.junit.Test;
31 import org.opendaylight.mdsal.dom.api.DOMNotification;
32 import org.opendaylight.mdsal.dom.api.DOMNotificationListener;
33 import org.opendaylight.mdsal.dom.api.DOMNotificationPublishService;
34 import org.opendaylight.mdsal.dom.broker.util.TestModel;
35 import org.opendaylight.mdsal.dom.spi.DOMNotificationSubscriptionListener;
36 import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
37 import org.opendaylight.yangtools.util.ListenerRegistry;
38 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
39
40 public class DOMNotificationRouterTest {
41
42     @Test
43     public void create() throws Exception {
44         assertNotNull(DOMNotificationRouter.create(1024));
45     }
46
47     @SuppressWarnings("checkstyle:IllegalCatch")
48     @Test
49     public void complexTest() throws Exception {
50         final DOMNotificationSubscriptionListener domNotificationSubscriptionListener =
51                 mock(DOMNotificationSubscriptionListener.class);
52         doNothing().when(domNotificationSubscriptionListener).onSubscriptionChanged(any());
53
54         final CountDownLatch latch = new CountDownLatch(1);
55         final DOMNotificationListener domNotificationListener = new TestListener(latch);
56         final DOMNotificationRouter domNotificationRouter = DOMNotificationRouter.create(1024);
57
58         Multimap<Absolute, ?> listeners = domNotificationRouter.listeners();
59
60         assertTrue(listeners.isEmpty());
61         assertNotNull(domNotificationRouter.registerNotificationListener(domNotificationListener,
62             Absolute.of(TestModel.TEST_QNAME)));
63         assertNotNull(domNotificationRouter.registerNotificationListener(domNotificationListener,
64             Absolute.of(TestModel.TEST2_QNAME)));
65
66         listeners = domNotificationRouter.listeners();
67
68         assertFalse(listeners.isEmpty());
69
70         ListenerRegistry<DOMNotificationSubscriptionListener> subscriptionListeners =
71                 domNotificationRouter.subscriptionListeners();
72
73         assertEquals(0, subscriptionListeners.streamListeners().count());
74         assertNotNull(domNotificationRouter.registerSubscriptionListener(domNotificationSubscriptionListener));
75
76         subscriptionListeners = domNotificationRouter.subscriptionListeners();
77         assertSame(domNotificationSubscriptionListener,
78             subscriptionListeners.streamListeners().findAny().orElseThrow());
79
80         final DOMNotification domNotification = mock(DOMNotification.class);
81         doReturn("test").when(domNotification).toString();
82         doReturn(Absolute.of(TestModel.TEST_QNAME)).when(domNotification).getType();
83         doReturn(TEST_CHILD).when(domNotification).getBody();
84
85         assertNotNull(domNotificationRouter.offerNotification(domNotification));
86
87         try {
88             assertNotNull(domNotificationRouter.offerNotification(domNotification, 1, TimeUnit.SECONDS));
89             assertNotNull(domNotificationRouter.offerNotification(domNotification, 1, TimeUnit.SECONDS));
90         } catch (Exception e) {
91             // FIXME: what is the point here?!
92             assertTrue(e instanceof UnsupportedOperationException);
93         }
94
95         assertNotNull(domNotificationRouter.putNotification(domNotification));
96     }
97
98     @Test
99     public void offerNotification() throws Exception {
100         final DOMNotificationRouter domNotificationRouter = DOMNotificationRouter.create(1024);
101         final DOMNotification domNotification = mock(DOMNotification.class);
102         doReturn(Absolute.of(TestModel.TEST_QNAME)).when(domNotification).getType();
103         doReturn(TEST_CHILD).when(domNotification).getBody();
104         assertNotNull(domNotificationRouter.putNotification(domNotification));
105         assertNotNull(domNotificationRouter.offerNotification(domNotification));
106         assertNotNull(domNotificationRouter.offerNotification(domNotification, 1, TimeUnit.SECONDS));
107     }
108
109     @Test
110     public void testOfferNotificationWithBlocking() throws Exception {
111         final CountDownLatch latch = new CountDownLatch(1);
112         final TestListener testListener = new TestListener(latch);
113         final DOMNotification domNotification = mock(DOMNotification.class);
114         doReturn("test").when(domNotification).toString();
115         doReturn(Absolute.of(TestModel.TEST_QNAME)).when(domNotification).getType();
116         doReturn(TEST_CHILD).when(domNotification).getBody();
117
118         try (TestRouter testRouter = new TestRouter(1)) {
119             assertNotNull(testRouter.registerNotificationListener(testListener, Absolute.of(TestModel.TEST_QNAME)));
120             assertNotNull(testRouter.registerNotificationListener(testListener, Absolute.of(TestModel.TEST2_QNAME)));
121
122             assertNotEquals(DOMNotificationPublishService.REJECTED,
123                 testRouter.offerNotification(domNotification, 3, TimeUnit.SECONDS));
124             assertTrue("Listener was not notified", latch.await(5, TimeUnit.SECONDS));
125             assertEquals("Received notifications", 1, testListener.getReceivedNotifications().size());
126
127             assertEquals(DOMNotificationPublishService.REJECTED,
128                     testRouter.offerNotification(domNotification, 1, TimeUnit.SECONDS));
129             assertEquals("Received notifications", 1, testListener.getReceivedNotifications().size());
130         }
131     }
132
133     @Test
134     public void close() throws Exception {
135         final DOMNotificationRouter domNotificationRouter = DOMNotificationRouter.create(1024);
136         final ExecutorService executor = domNotificationRouter.executor();
137         final ExecutorService observer = domNotificationRouter.observer();
138
139         assertFalse(executor.isShutdown());
140         assertFalse(observer.isShutdown());
141         domNotificationRouter.close();
142         assertTrue(executor.isShutdown());
143         assertTrue(observer.isShutdown());
144     }
145
146     private static class TestListener implements DOMNotificationListener {
147         private final CountDownLatch latch;
148         private final List<DOMNotification>  receivedNotifications = new ArrayList<>();
149
150         TestListener(final CountDownLatch latch) {
151             this.latch = latch;
152         }
153
154         @Override
155         public void onNotification(final DOMNotification notification) {
156             receivedNotifications.add(notification);
157             latch.countDown();
158         }
159
160         public List<DOMNotification> getReceivedNotifications() {
161             return receivedNotifications;
162         }
163     }
164
165     private static class TestRouter extends DOMNotificationRouter {
166
167         private boolean triggerRejected = false;
168
169         TestRouter(final int queueDepth) {
170             super(queueDepth);
171         }
172
173         @Override
174         ListenableFuture<? extends Object> publish(final DOMNotification notification,
175                 final Collection<AbstractListenerRegistration<? extends DOMNotificationListener>> subscribers) {
176             if (triggerRejected) {
177                 return REJECTED;
178             }
179
180             triggerRejected = true;
181             return super.publish(notification, subscribers);
182         }
183
184         @Override
185         public ListenableFuture<? extends Object> putNotification(final DOMNotification notification)
186                 throws InterruptedException {
187             Thread.sleep(2000);
188             return super.putNotification(notification);
189         }
190     }
191 }