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