Bug 6380 lldp-speaker - DTCL instead of DTL
[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.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;
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.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;
37
38
39 /**
40  * Tests for @{NodeConnectorInventoryEventTranslator} class.
41  */
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();
47
48     @Mock
49     private NodeConnectorEventsObserver eventsObserver;
50     @Mock
51     private NodeConnectorEventsObserver eventsObserver2;
52
53     private NodeConnectorInventoryEventTranslator translator;
54
55     @Before
56     public void setUp() {
57         translator = new NodeConnectorInventoryEventTranslator(mock(DataBroker.class), 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         DataTreeModification dataTreeModification = setupDataTreeChange(WRITE, iiToConnector, fcnc);
67         translator.onDataTreeChanged(Collections.singleton(dataTreeModification));
68         verify(eventsObserver).nodeConnectorAdded(id, fcnc);
69     }
70
71     /**
72      * Test that checks that nothing is called when port appeared in inventory in link down state.
73      */
74     @Test
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);
80     }
81
82     /**
83      * Test that checks that nothing is called when port appeared in inventory in admin down state.
84      */
85     @Test
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);
91     }
92
93     /**
94      * Test that checks if @{NodeConnectorEventsObserver#nodeConnectorRemoved} is called
95      * for each FlowCapableNodeConnector item inside @{AsyncDataChangeEvent#getUpdatedData}
96      * that have link down state.
97      */
98     @Test
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);
104     }
105
106     /**
107      * Test that checks if @{NodeConnectorEventsObserver#nodeConnectorRemoved} is called
108      * for each FlowCapableNodeConnector item inside @{AsyncDataChangeEvent#getUpdatedData}
109      * that have administrative down state.
110      */
111     @Test
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);
117     }
118
119     /**
120      * Test that checks if @{NodeConnectorEventsObserver#nodeConnectorAdded} is called
121      * for each FlowCapableNodeConnector item inside @{AsyncDataChangeEvent#getUpdatedData}
122      * that have administrative up and link up state.
123      */
124     @Test
125     public void testNodeConnectorUpdateToUp() {
126         DataTreeModification dataTreeModification = setupDataTreeChange(SUBTREE_MODIFIED, iiToConnector, fcnc);
127         translator.onDataTreeChanged(Collections.singleton(dataTreeModification));
128         verify(eventsObserver).nodeConnectorAdded(id, fcnc);
129     }
130
131     /**
132      * Test that checks if @{NodeConnectorEventsObserver#nodeConnectorRemoved} is called
133      * for each FlowCapableNodeConnector path that @{AsyncDataChangeEvent#getRemovedPaths} return.
134      */
135     @Test
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);
141     }
142
143     /**
144      * Test that checks if @{NodeConnectorEventsObserver#nodeConnectorAdded} and
145      * @{NodeConnectorEventsObserver#nodeConnectorRemoved} are called for each
146      * observer when multiple observers are registered for notifications.
147      */
148     @Test
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);
162     }
163
164     @Test
165     public void tearDown() throws Exception {
166         translator.close();
167     }
168
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;
179
180     }
181 }