92a47543674a485cc178842a940fd2ea1b93d6eb
[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.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;
18
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;
37
38
39 /**
40  * Tests for {@link NodeConnectorInventoryEventTranslator}.
41  */
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();
50
51     @Mock
52     private NodeConnectorEventsObserver eventsObserver;
53     @Mock
54     private NodeConnectorEventsObserver eventsObserver2;
55
56     private NodeConnectorInventoryEventTranslator translator;
57
58     @Before
59     public void setUp() {
60         translator = new NodeConnectorInventoryEventTranslator(mock(DataBroker.class), eventsObserver, eventsObserver2);
61     }
62
63     /**
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}.
67      */
68     @Test
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);
74     }
75
76     /**
77      * Test that checks that nothing is called when port appeared in inventory in link down state.
78      */
79     @Test
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);
85     }
86
87     /**
88      * Test that checks that nothing is called when port appeared in inventory in admin down state.
89      */
90     @Test
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);
96     }
97
98     /**
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}.
102      */
103     @Test
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);
110     }
111
112     /**
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}.
116      */
117     @Test
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);
124     }
125
126     /**
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}.
130      */
131     @Test
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);
138     }
139
140     /**
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.
144      */
145     @Test
146     public void testNodeConnectorRemoval() {
147         DataTreeModification dataTreeModification = setupDataTreeChange(DELETE, NODE_CONNECTOR_INSTANCE_IDENTIFIER,
148                                                                         null);
149         // Invoke NodeConnectorInventoryEventTranslator and check result
150         translator.onDataTreeChanged(Collections.singleton(dataTreeModification));
151         verify(eventsObserver).nodeConnectorRemoved(ID);
152     }
153
154     /**
155      * Test that if {@link NodeConnectorEventsObserver#nodeConnectorAdded} and.
156      * @{NodeConnectorEventsObserver#nodeConnectorRemoved} are called for each observer when multiple
157      * observers are registered for notifications.
158      */
159     @Test
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);
173     }
174
175     @Test
176     public void tearDown() {
177         translator.close();
178     }
179
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;
190
191     }
192 }