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.mock;
12 import static org.mockito.Mockito.verify;
13 import static org.mockito.Mockito.verifyZeroInteractions;
14 import static org.mockito.Mockito.when;
15 import static org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType.DELETE;
16 import static org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType.SUBTREE_MODIFIED;
17 import static org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType.WRITE;
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.List;
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.junit.runner.RunWith;
25 import org.mockito.Mock;
26 import org.mockito.runners.MockitoJUnitRunner;
27 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
28 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
29 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
30 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
31 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
32 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
35 import org.opendaylight.yangtools.yang.binding.DataObject;
36 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
40 * Tests for {@link NodeConnectorInventoryEventTranslator}.
42 @RunWith(MockitoJUnitRunner.class)
43 public class NodeConnectorInventoryEventTranslatorTest {
44 private static final InstanceIdentifier<NodeConnector> id = TestUtils.createNodeConnectorId("openflow:1", "openflow:1:1");
45 private static final InstanceIdentifier<FlowCapableNodeConnector> iiToConnector = id.augmentation(FlowCapableNodeConnector.class);
46 private static final FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector().build();
49 private NodeConnectorEventsObserver eventsObserver;
51 private NodeConnectorEventsObserver eventsObserver2;
53 private NodeConnectorInventoryEventTranslator translator;
57 translator = new NodeConnectorInventoryEventTranslator(mock(DataBroker.class), eventsObserver, eventsObserver2);
61 * Test that checks if {@link NodeConnectorEventsObserver#nodeConnectorAdded} is called
62 * for each FlowCapableNodeConnector item that @{AsyncDataChangeEvent#getCreatedData} return.
65 public void testNodeConnectorCreation() {
66 DataTreeModification dataTreeModification = setupDataTreeChange(WRITE, iiToConnector, fcnc);
67 translator.onDataTreeChanged(Collections.singleton(dataTreeModification));
68 verify(eventsObserver).nodeConnectorAdded(id, fcnc);
72 * Test that checks that nothing is called when port appeared in inventory in link down state.
75 public void testNodeConnectorCreationLinkDown() {
76 FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector(true, false).build();
77 DataTreeModification dataTreeModification = setupDataTreeChange(WRITE, id, fcnc);
78 translator.onDataTreeChanged(Collections.singleton(dataTreeModification));
79 verifyZeroInteractions(eventsObserver);
83 * Test that checks that nothing is called when port appeared in inventory in admin down state.
86 public void testNodeConnectorCreationAdminDown() {
87 FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector(false, true).build();
88 DataTreeModification dataTreeModification = setupDataTreeChange(WRITE, id, fcnc);
89 translator.onDataTreeChanged(Collections.singleton(dataTreeModification));
90 verifyZeroInteractions(eventsObserver);
94 * Test that checks if {@link NodeConnectorEventsObserver#nodeConnectorRemoved} is called
95 * for each FlowCapableNodeConnector item inside @{AsyncDataChangeEvent#getUpdatedData}
96 * that have link down state.
99 public void testNodeConnectorUpdateToLinkDown() {
100 FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector(true, false).build();
101 DataTreeModification dataTreeModification = setupDataTreeChange(SUBTREE_MODIFIED, iiToConnector, fcnc);
102 translator.onDataTreeChanged(Collections.singleton(dataTreeModification));
103 verify(eventsObserver).nodeConnectorRemoved(id);
107 * Test that checks if {@link NodeConnectorEventsObserver#nodeConnectorRemoved} is called
108 * for each FlowCapableNodeConnector item inside @{AsyncDataChangeEvent#getUpdatedData}
109 * that have administrative down state.
112 public void testNodeConnectorUpdateToAdminDown() {
113 FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector(false, true).build();
114 DataTreeModification dataTreeModification = setupDataTreeChange(SUBTREE_MODIFIED, iiToConnector, fcnc);
115 translator.onDataTreeChanged(Collections.singleton(dataTreeModification));
116 verify(eventsObserver).nodeConnectorRemoved(id);
120 * Test that checks if {@link NodeConnectorEventsObserver#nodeConnectorAdded} is called
121 * for each FlowCapableNodeConnector item inside @{AsyncDataChangeEvent#getUpdatedData}
122 * that have administrative up and link up state.
125 public void testNodeConnectorUpdateToUp() {
126 DataTreeModification dataTreeModification = setupDataTreeChange(SUBTREE_MODIFIED, iiToConnector, fcnc);
127 translator.onDataTreeChanged(Collections.singleton(dataTreeModification));
128 verify(eventsObserver).nodeConnectorAdded(id, fcnc);
132 * Test that checks if {@link NodeConnectorEventsObserver#nodeConnectorRemoved} is called
133 * for each FlowCapableNodeConnector path that @{AsyncDataChangeEvent#getRemovedPaths} return.
136 public void testNodeConnectorRemoval() {
137 DataTreeModification dataTreeModification = setupDataTreeChange(DELETE, iiToConnector, null);
138 // Invoke NodeConnectorInventoryEventTranslator and check result
139 translator.onDataTreeChanged(Collections.singleton(dataTreeModification));
140 verify(eventsObserver).nodeConnectorRemoved(id);
144 * Test that checks if {@link NodeConnectorEventsObserver#nodeConnectorAdded} and
145 * @{NodeConnectorEventsObserver#nodeConnectorRemoved} are called for each
146 * observer when multiple observers are registered for notifications.
149 public void testMultipleObserversNotified() throws Exception {
150 // Create prerequisites
151 InstanceIdentifier<NodeConnector> id2 = TestUtils.createNodeConnectorId("openflow:1", "openflow:1:2");
152 InstanceIdentifier<FlowCapableNodeConnector> iiToConnector2 = id2.augmentation(FlowCapableNodeConnector.class);
153 List<DataTreeModification> modifications = new ArrayList();
154 modifications.add(setupDataTreeChange(WRITE, iiToConnector, fcnc));
155 modifications.add(setupDataTreeChange(DELETE, iiToConnector2, null));
156 // Invoke onDataChanged and check that both observers notified
157 translator.onDataTreeChanged(modifications);
158 verify(eventsObserver).nodeConnectorAdded(id, fcnc);
159 verify(eventsObserver).nodeConnectorRemoved(id2);
160 verify(eventsObserver2).nodeConnectorAdded(id, fcnc);
161 verify(eventsObserver2).nodeConnectorRemoved(id2);
165 public void tearDown() throws Exception {
169 private <T extends DataObject> DataTreeModification setupDataTreeChange(final ModificationType type,
170 final InstanceIdentifier<T> ii,
171 final FlowCapableNodeConnector connector) {
172 final DataTreeModification dataTreeModification = mock(DataTreeModification.class);
173 when(dataTreeModification.getRootNode()).thenReturn(mock(DataObjectModification.class));
174 DataTreeIdentifier<T> identifier = new DataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, ii);
175 when(dataTreeModification.getRootNode().getModificationType()).thenReturn(type);
176 when(dataTreeModification.getRootPath()).thenReturn(identifier);
177 when(dataTreeModification.getRootNode().getDataAfter()).thenReturn(connector);
178 return dataTreeModification;