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