a5269220435e9c0357a71d957a6224fa62feaced
[openflowplugin.git] / applications / lldp-speaker / src / test / java / org / opendaylight / openflowplugin / applications / lldpspeaker / NodeConnectorInventoryEventTranslatorTest.java
1 /*
2  * Copyright (c) 2014 Pacnet 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
9 package org.opendaylight.openflowplugin.applications.lldpspeaker;
10
11 import static org.mockito.Mockito.*;
12
13 import java.util.HashMap;
14 import java.util.HashSet;
15 import java.util.Map;
16 import java.util.Set;
17 import org.junit.*;
18 import org.junit.runner.RunWith;
19 import org.mockito.Mock;
20 import org.mockito.runners.MockitoJUnitRunner;
21 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
22 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
23 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
24 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
28 import org.opendaylight.yangtools.concepts.ListenerRegistration;
29 import org.opendaylight.yangtools.yang.binding.DataObject;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31
32
33 /**
34  * Tests for @{NodeConnectorInventoryEventTranslator} class.
35  */
36 @RunWith(MockitoJUnitRunner.class)
37 public class NodeConnectorInventoryEventTranslatorTest {
38     static InstanceIdentifier<NodeConnector> id = TestUtils.createNodeConnectorId("openflow:1", "openflow:1:1");
39     static FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector().build();
40
41     @Mock DataBroker dataBroker;
42     @Mock ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
43     @Mock NodeConnectorEventsObserver eventsObserver;
44     @Mock NodeConnectorEventsObserver eventsObserver2;
45
46     MockDataChangedEvent dataChangedEvent = new MockDataChangedEvent();
47     NodeConnectorInventoryEventTranslator translator;
48
49     @Before
50     public void setUp() {
51         when(dataBroker.registerDataChangeListener(
52                 any(LogicalDatastoreType.class),
53                 any(InstanceIdentifier.class),
54                 any(DataChangeListener.class),
55                 any(AsyncDataBroker.DataChangeScope.class)))
56                 .thenReturn(dataChangeListenerRegistration);
57         translator = new NodeConnectorInventoryEventTranslator(dataBroker, eventsObserver, eventsObserver2);
58     }
59
60     /**
61      * Test that checks if @{NodeConnectorEventsObserver#nodeConnectorAdded} is called
62      * for each FlowCapableNodeConnector item that @{AsyncDataChangeEvent#getCreatedData} return.
63      */
64     @Test
65     public void testNodeConnectorCreation() {
66         // Setup dataChangedEvent to mock new port creation in inventory
67         dataChangedEvent.created.put(id, fcnc);
68
69         // Invoke NodeConnectorInventoryEventTranslator and check result
70         translator.onDataChanged(dataChangedEvent);
71         verify(eventsObserver).nodeConnectorAdded(id, fcnc);
72     }
73
74     /**
75      * Test that checks that nothing is called when port appeared in inventory in link down state.
76      */
77     @Test
78     public void testNodeConnectorCreationLinkDown() {
79         FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector(true, false).build();
80
81         // Setup dataChangedEvent to mock new port creation in inventory
82         dataChangedEvent.created.put(id, fcnc);
83
84         // Invoke NodeConnectorInventoryEventTranslator and check result
85         translator.onDataChanged(dataChangedEvent);
86         verifyZeroInteractions(eventsObserver);
87     }
88
89     /**
90      * Test that checks that nothing is called when port appeared in inventory in admin down state.
91      */
92     @Test
93     public void testNodeConnectorCreationAdminDown() {
94         FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector(false, true).build();
95
96         // Setup dataChangedEvent to mock new port creation in inventory
97         dataChangedEvent.created.put(id, fcnc);
98
99         // Invoke NodeConnectorInventoryEventTranslator and check result
100         translator.onDataChanged(dataChangedEvent);
101         verifyZeroInteractions(eventsObserver);
102     }
103
104     /**
105      * Test that checks if @{NodeConnectorEventsObserver#nodeConnectorRemoved} is called
106      * for each FlowCapableNodeConnector item inside @{AsyncDataChangeEvent#getUpdatedData}
107      * that have link down state.
108      */
109     @Test
110     public void testNodeConnectorUpdateToLinkDown() {
111         FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector(true, false).build();
112
113         // Setup dataChangedEvent to mock link down
114         dataChangedEvent.updated.put(id, fcnc);
115
116         // Invoke NodeConnectorInventoryEventTranslator and check result
117         translator.onDataChanged(dataChangedEvent);
118         verify(eventsObserver).nodeConnectorRemoved(id);
119     }
120
121     /**
122      * Test that checks if @{NodeConnectorEventsObserver#nodeConnectorRemoved} is called
123      * for each FlowCapableNodeConnector item inside @{AsyncDataChangeEvent#getUpdatedData}
124      * that have administrative down state.
125      */
126     @Test
127     public void testNodeConnectorUpdateToAdminDown() {
128         FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector(false, true).build();
129
130         // Setup dataChangedEvent to mock link down and administrative port down
131         dataChangedEvent.updated.put(id, fcnc);
132
133         // Invoke NodeConnectorInventoryEventTranslator and check result
134         translator.onDataChanged(dataChangedEvent);
135         verify(eventsObserver).nodeConnectorRemoved(id);
136     }
137
138     /**
139      * Test that checks if @{NodeConnectorEventsObserver#nodeConnectorAdded} is called
140      * for each FlowCapableNodeConnector item inside @{AsyncDataChangeEvent#getUpdatedData}
141      * that have administrative up and link up state.
142      */
143     @Test
144     public void testNodeConnectorUpdateToUp() {
145         // Setup dataChangedEvent to mock link up and administrative port up
146         dataChangedEvent.updated.put(id, fcnc);
147
148         // Invoke NodeConnectorInventoryEventTranslator and check result
149         translator.onDataChanged(dataChangedEvent);
150         verify(eventsObserver).nodeConnectorAdded(id, fcnc);
151     }
152
153     /**
154      * Test that checks if @{NodeConnectorEventsObserver#nodeConnectorRemoved} is called
155      * for each FlowCapableNodeConnector path that @{AsyncDataChangeEvent#getRemovedPaths} return.
156      */
157     @Test
158     public void testNodeConnectorRemoval() {
159         // Setup dataChangedEvent to mock node connector removal
160         dataChangedEvent.removed.add(id);
161
162         // Invoke NodeConnectorInventoryEventTranslator and check result
163         translator.onDataChanged(dataChangedEvent);
164         verify(eventsObserver).nodeConnectorRemoved(id);
165     }
166
167     /**
168      * Test that checks if @{NodeConnectorEventsObserver#nodeConnectorAdded} and
169      * @{NodeConnectorEventsObserver#nodeConnectorRemoved} are called for each
170      * observer when multiple observers are registered for notifications.
171      */
172     @Test
173     public  void testMultipleObserversNotified() throws Exception {
174         // Create prerequisites
175         InstanceIdentifier<NodeConnector> id2 = TestUtils.createNodeConnectorId("openflow:1", "openflow:1:2");
176
177         // Setup dataChangedEvent to mock port creation and removal
178         dataChangedEvent.created.put(id, fcnc);
179         dataChangedEvent.removed.add(id2);
180
181         // Invoke onDataChanged and check that both observers notified
182         translator.onDataChanged(dataChangedEvent);
183         verify(eventsObserver).nodeConnectorAdded(id, fcnc);
184         verify(eventsObserver).nodeConnectorRemoved(id2);
185         verify(eventsObserver2).nodeConnectorAdded(id, fcnc);
186         verify(eventsObserver2).nodeConnectorRemoved(id2);
187     }
188
189     /**
190      * Test that @{ListenerRegistration} is closed when ${NodeConnectorInventoryEventTranslator#close}
191      * method is called.
192      * @throws Exception
193      */
194     @Test
195     public void testCleanup() throws Exception {
196         // Trigger cleanup
197         translator.close();
198
199         // Verify that ListenerRegistration to DOM events
200         verify(dataChangeListenerRegistration).close();
201     }
202
203     static class MockDataChangedEvent implements AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> {
204         Map<InstanceIdentifier<?>,DataObject> created = new HashMap<>();
205         Map<InstanceIdentifier<?>,DataObject> updated = new HashMap<>();
206         Set<InstanceIdentifier<?>> removed = new HashSet<>();
207
208         @Override
209         public Map<InstanceIdentifier<?>, DataObject> getCreatedData() {
210             return created;
211         }
212
213         @Override
214         public Map<InstanceIdentifier<?>, DataObject> getUpdatedData() {
215             return updated;
216         }
217
218         @Override
219         public Set<InstanceIdentifier<?>> getRemovedPaths() {
220             return removed;
221         }
222
223         @Override
224         public Map<InstanceIdentifier<?>, DataObject> getOriginalData() {
225             throw new UnsupportedOperationException("Not implemented by mock");
226         }
227
228         @Override
229         public DataObject getOriginalSubtree() {
230             throw new UnsupportedOperationException("Not implemented by mock");
231         }
232
233         @Override
234         public DataObject getUpdatedSubtree() {
235             throw new UnsupportedOperationException("Not implemented by mock");
236         }
237     }
238 }