2 * Copyright (c) 2014 Pacnet and others. All rights reserved.
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
9 package org.opendaylight.openflowplugin.applications.lldpspeaker;
11 import static org.mockito.Mockito.*;
13 import java.util.HashMap;
14 import java.util.HashSet;
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;
34 * Tests for @{NodeConnectorInventoryEventTranslator} class.
36 @RunWith(MockitoJUnitRunner.class)
37 public class NodeConnectorInventoryEventTranslatorTest {
38 static InstanceIdentifier<NodeConnector> id = TestUtils.createNodeConnectorId("openflow:1", "openflow:1:1");
39 static InstanceIdentifier<FlowCapableNodeConnector> iiToConnector = id.augmentation(FlowCapableNodeConnector.class);
40 static FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector().build();
42 @Mock DataBroker dataBroker;
43 @Mock ListenerRegistration<DataChangeListener> dataChangeListenerRegistration;
44 @Mock NodeConnectorEventsObserver eventsObserver;
45 @Mock NodeConnectorEventsObserver eventsObserver2;
47 MockDataChangedEvent dataChangedEvent = new MockDataChangedEvent();
48 NodeConnectorInventoryEventTranslator translator;
53 when(dataBroker.registerDataChangeListener(
54 any(LogicalDatastoreType.class),
55 any(InstanceIdentifier.class),
56 any(DataChangeListener.class),
57 any(AsyncDataBroker.DataChangeScope.class)))
58 .thenReturn(dataChangeListenerRegistration);
59 translator = new NodeConnectorInventoryEventTranslator(dataBroker, eventsObserver, eventsObserver2);
63 * Test that checks if @{NodeConnectorEventsObserver#nodeConnectorAdded} is called
64 * for each FlowCapableNodeConnector item that @{AsyncDataChangeEvent#getCreatedData} return.
67 public void testNodeConnectorCreation() {
68 // Setup dataChangedEvent to mock new port creation in inventory
69 dataChangedEvent.created.put(iiToConnector, fcnc);
71 // Invoke NodeConnectorInventoryEventTranslator and check result
72 translator.onDataChanged(dataChangedEvent);
73 verify(eventsObserver).nodeConnectorAdded(id, fcnc);
77 * Test that checks that nothing is called when port appeared in inventory in link down state.
80 public void testNodeConnectorCreationLinkDown() {
81 FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector(true, false).build();
83 // Setup dataChangedEvent to mock new port creation in inventory
84 dataChangedEvent.created.put(id, fcnc);
86 // Invoke NodeConnectorInventoryEventTranslator and check result
87 translator.onDataChanged(dataChangedEvent);
88 verifyZeroInteractions(eventsObserver);
92 * Test that checks that nothing is called when port appeared in inventory in admin down state.
95 public void testNodeConnectorCreationAdminDown() {
96 FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector(false, true).build();
98 // Setup dataChangedEvent to mock new port creation in inventory
99 dataChangedEvent.created.put(id, fcnc);
101 // Invoke NodeConnectorInventoryEventTranslator and check result
102 translator.onDataChanged(dataChangedEvent);
103 verifyZeroInteractions(eventsObserver);
107 * Test that checks if @{NodeConnectorEventsObserver#nodeConnectorRemoved} is called
108 * for each FlowCapableNodeConnector item inside @{AsyncDataChangeEvent#getUpdatedData}
109 * that have link down state.
112 public void testNodeConnectorUpdateToLinkDown() {
113 FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector(true, false).build();
115 // Setup dataChangedEvent to mock link down
116 dataChangedEvent.updated.put(iiToConnector, fcnc);
118 // Invoke NodeConnectorInventoryEventTranslator and check result
119 translator.onDataChanged(dataChangedEvent);
120 verify(eventsObserver).nodeConnectorRemoved(id);
124 * Test that checks if @{NodeConnectorEventsObserver#nodeConnectorRemoved} is called
125 * for each FlowCapableNodeConnector item inside @{AsyncDataChangeEvent#getUpdatedData}
126 * that have administrative down state.
129 public void testNodeConnectorUpdateToAdminDown() {
130 FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector(false, true).build();
132 // Setup dataChangedEvent to mock link down and administrative port down
133 dataChangedEvent.updated.put(iiToConnector, fcnc);
135 // Invoke NodeConnectorInventoryEventTranslator and check result
136 translator.onDataChanged(dataChangedEvent);
137 verify(eventsObserver).nodeConnectorRemoved(id);
141 * Test that checks if @{NodeConnectorEventsObserver#nodeConnectorAdded} is called
142 * for each FlowCapableNodeConnector item inside @{AsyncDataChangeEvent#getUpdatedData}
143 * that have administrative up and link up state.
146 public void testNodeConnectorUpdateToUp() {
147 // Setup dataChangedEvent to mock link up and administrative port up
148 dataChangedEvent.updated.put(iiToConnector, fcnc);
150 // Invoke NodeConnectorInventoryEventTranslator and check result
151 translator.onDataChanged(dataChangedEvent);
152 verify(eventsObserver).nodeConnectorAdded(id, fcnc);
156 * Test that checks if @{NodeConnectorEventsObserver#nodeConnectorRemoved} is called
157 * for each FlowCapableNodeConnector path that @{AsyncDataChangeEvent#getRemovedPaths} return.
160 public void testNodeConnectorRemoval() {
161 // Setup dataChangedEvent to mock node connector removal
162 dataChangedEvent.removed.add(iiToConnector);
164 // Invoke NodeConnectorInventoryEventTranslator and check result
165 translator.onDataChanged(dataChangedEvent);
166 verify(eventsObserver).nodeConnectorRemoved(id);
170 * Test that checks if @{NodeConnectorEventsObserver#nodeConnectorAdded} and
171 * @{NodeConnectorEventsObserver#nodeConnectorRemoved} are called for each
172 * observer when multiple observers are registered for notifications.
175 public void testMultipleObserversNotified() throws Exception {
176 // Create prerequisites
177 InstanceIdentifier<NodeConnector> id2 = TestUtils.createNodeConnectorId("openflow:1", "openflow:1:2");
178 InstanceIdentifier<FlowCapableNodeConnector> iiToConnector2 = id2.augmentation(FlowCapableNodeConnector.class);
180 // Setup dataChangedEvent to mock port creation and removal
181 dataChangedEvent.created.put(iiToConnector, fcnc);
182 dataChangedEvent.removed.add(iiToConnector2);
184 // Invoke onDataChanged and check that both observers notified
185 translator.onDataChanged(dataChangedEvent);
186 verify(eventsObserver).nodeConnectorAdded(id, fcnc);
187 verify(eventsObserver).nodeConnectorRemoved(id2);
188 verify(eventsObserver2).nodeConnectorAdded(id, fcnc);
189 verify(eventsObserver2).nodeConnectorRemoved(id2);
193 * Test that @{ListenerRegistration} is closed when ${NodeConnectorInventoryEventTranslator#close}
198 public void testCleanup() throws Exception {
202 // Verify that ListenerRegistration to DOM events
203 verify(dataChangeListenerRegistration, times(2)).close();
206 static class MockDataChangedEvent implements AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> {
207 Map<InstanceIdentifier<?>,DataObject> created = new HashMap<>();
208 Map<InstanceIdentifier<?>,DataObject> updated = new HashMap<>();
209 Set<InstanceIdentifier<?>> removed = new HashSet<>();
212 public Map<InstanceIdentifier<?>, DataObject> getCreatedData() {
217 public Map<InstanceIdentifier<?>, DataObject> getUpdatedData() {
222 public Set<InstanceIdentifier<?>> getRemovedPaths() {
227 public Map<InstanceIdentifier<?>, DataObject> getOriginalData() {
228 throw new UnsupportedOperationException("Not implemented by mock");
232 public DataObject getOriginalSubtree() {
233 throw new UnsupportedOperationException("Not implemented by mock");
237 public DataObject getUpdatedSubtree() {
238 throw new UnsupportedOperationException("Not implemented by mock");