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.mdsal.binding.api.DataObjectModification.ModificationType.DELETE;
16 import static org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType.SUBTREE_MODIFIED;
17 import static org.opendaylight.mdsal.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.junit.MockitoJUnitRunner;
27 import org.opendaylight.mdsal.binding.api.DataBroker;
28 import org.opendaylight.mdsal.binding.api.DataObjectModification;
29 import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType;
30 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
31 import org.opendaylight.mdsal.binding.api.DataTreeModification;
32 import org.opendaylight.mdsal.common.api.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
45 .createNodeConnectorId("openflow:1", "openflow:1:1");
46 private static final InstanceIdentifier<FlowCapableNodeConnector> NODE_CONNECTOR_INSTANCE_IDENTIFIER = ID
47 .augmentation(FlowCapableNodeConnector.class);
48 private static final FlowCapableNodeConnector FLOW_CAPABLE_NODE_CONNECTOR = TestUtils
49 .createFlowCapableNodeConnector().build();
52 private NodeConnectorEventsObserver eventsObserver;
54 private NodeConnectorEventsObserver eventsObserver2;
56 private NodeConnectorInventoryEventTranslator translator;
60 translator = new NodeConnectorInventoryEventTranslator(mock(DataBroker.class), eventsObserver, eventsObserver2);
64 * Test that checks if {@link NodeConnectorEventsObserver#nodeConnectorAdded} is called
65 * for each FlowCapableNodeConnector item added in
66 * {@link org.opendaylight.mdsal.binding.api.DataTreeModification}.
69 public void testNodeConnectorCreation() {
70 DataTreeModification dataTreeModification = setupDataTreeChange(WRITE, NODE_CONNECTOR_INSTANCE_IDENTIFIER,
71 FLOW_CAPABLE_NODE_CONNECTOR);
72 translator.onDataTreeChanged(Collections.singleton(dataTreeModification));
73 verify(eventsObserver).nodeConnectorAdded(ID, FLOW_CAPABLE_NODE_CONNECTOR);
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();
82 DataTreeModification dataTreeModification = setupDataTreeChange(WRITE, ID, fcnc);
83 translator.onDataTreeChanged(Collections.singleton(dataTreeModification));
84 verifyZeroInteractions(eventsObserver);
88 * Test that checks that nothing is called when port appeared in inventory in admin down state.
91 public void testNodeConnectorCreationAdminDown() {
92 FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector(false, true).build();
93 DataTreeModification dataTreeModification = setupDataTreeChange(WRITE, ID, fcnc);
94 translator.onDataTreeChanged(Collections.singleton(dataTreeModification));
95 verifyZeroInteractions(eventsObserver);
99 * Test that checks if {@link NodeConnectorEventsObserver#nodeConnectorRemoved} is called
100 * for each FlowCapableNodeConnector item that have link down state removed in
101 * {@link org.opendaylight.mdsal.binding.api.DataTreeModification}.
104 public void testNodeConnectorUpdateToLinkDown() {
105 FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector(true, false).build();
106 DataTreeModification dataTreeModification = setupDataTreeChange(SUBTREE_MODIFIED,
107 NODE_CONNECTOR_INSTANCE_IDENTIFIER, fcnc);
108 translator.onDataTreeChanged(Collections.singleton(dataTreeModification));
109 verify(eventsObserver).nodeConnectorRemoved(ID);
113 * Test that checks if {@link NodeConnectorEventsObserver#nodeConnectorRemoved} is called
114 * for each FlowCapableNodeConnector item with administrative down state removed in
115 * {@link org.opendaylight.mdsal.binding.api.DataTreeModification}.
118 public void testNodeConnectorUpdateToAdminDown() {
119 FlowCapableNodeConnector fcnc = TestUtils.createFlowCapableNodeConnector(false, true).build();
120 DataTreeModification dataTreeModification = setupDataTreeChange(SUBTREE_MODIFIED,
121 NODE_CONNECTOR_INSTANCE_IDENTIFIER, fcnc);
122 translator.onDataTreeChanged(Collections.singleton(dataTreeModification));
123 verify(eventsObserver).nodeConnectorRemoved(ID);
127 * Test that checks if {@link NodeConnectorEventsObserver#nodeConnectorAdded} is called
128 * for each FlowCapableNodeConnector item with administrative up and link up state added in
129 * {@link org.opendaylight.md}.
132 public void testNodeConnectorUpdateToUp() {
133 DataTreeModification dataTreeModification = setupDataTreeChange(SUBTREE_MODIFIED,
134 NODE_CONNECTOR_INSTANCE_IDENTIFIER,
135 FLOW_CAPABLE_NODE_CONNECTOR);
136 translator.onDataTreeChanged(Collections.singleton(dataTreeModification));
137 verify(eventsObserver).nodeConnectorAdded(ID, FLOW_CAPABLE_NODE_CONNECTOR);
141 * Test that checks if {@link NodeConnectorEventsObserver#nodeConnectorRemoved} is called
142 * for each FlowCapableNodeConnector path that
143 * {@link org.opendaylight.mdsal.binding.api.DataTreeModification} return.
146 public void testNodeConnectorRemoval() {
147 DataTreeModification dataTreeModification = setupDataTreeChange(DELETE, NODE_CONNECTOR_INSTANCE_IDENTIFIER,
149 // Invoke NodeConnectorInventoryEventTranslator and check result
150 translator.onDataTreeChanged(Collections.singleton(dataTreeModification));
151 verify(eventsObserver).nodeConnectorRemoved(ID);
155 * Test that if {@link NodeConnectorEventsObserver#nodeConnectorAdded} and.
156 * @{NodeConnectorEventsObserver#nodeConnectorRemoved} are called for each observer when multiple
157 * observers are registered for notifications.
160 public void testMultipleObserversNotified() {
161 // Create prerequisites
162 InstanceIdentifier<NodeConnector> id2 = TestUtils.createNodeConnectorId("openflow:1", "openflow:1:2");
163 InstanceIdentifier<FlowCapableNodeConnector> iiToConnector2 = id2.augmentation(FlowCapableNodeConnector.class);
164 List<DataTreeModification> modifications = new ArrayList<>();
165 modifications.add(setupDataTreeChange(WRITE, NODE_CONNECTOR_INSTANCE_IDENTIFIER, FLOW_CAPABLE_NODE_CONNECTOR));
166 modifications.add(setupDataTreeChange(DELETE, iiToConnector2, null));
167 // Invoke onDataTreeChanged and check that both observers notified
168 translator.onDataTreeChanged(modifications);
169 verify(eventsObserver).nodeConnectorAdded(ID, FLOW_CAPABLE_NODE_CONNECTOR);
170 verify(eventsObserver).nodeConnectorRemoved(id2);
171 verify(eventsObserver2).nodeConnectorAdded(ID, FLOW_CAPABLE_NODE_CONNECTOR);
172 verify(eventsObserver2).nodeConnectorRemoved(id2);
176 public void tearDown() {
180 private <T extends DataObject> DataTreeModification setupDataTreeChange(final ModificationType type,
181 final InstanceIdentifier<T> ii,
182 final FlowCapableNodeConnector connector) {
183 final DataTreeModification dataTreeModification = mock(DataTreeModification.class);
184 when(dataTreeModification.getRootNode()).thenReturn(mock(DataObjectModification.class));
185 DataTreeIdentifier<T> identifier = DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL, ii);
186 when(dataTreeModification.getRootNode().getModificationType()).thenReturn(type);
187 when(dataTreeModification.getRootPath()).thenReturn(identifier);
188 when(dataTreeModification.getRootNode().getDataAfter()).thenReturn(connector);
189 return dataTreeModification;