Merge "Adding learn action"
[openflowplugin.git] / applications / lldp-speaker / src / test / java / org / opendaylight / openflowplugin / applications / lldpspeaker / LLDPSpeakerTest.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.Matchers.any;
12 import static org.mockito.Matchers.anyLong;
13 import static org.mockito.Mockito.never;
14 import static org.mockito.Mockito.times;
15 import static org.mockito.Mockito.verify;
16 import static org.mockito.Mockito.verifyNoMoreInteractions;
17 import static org.mockito.Mockito.when;
18
19 import java.util.concurrent.ScheduledExecutorService;
20 import java.util.concurrent.ScheduledFuture;
21 import java.util.concurrent.TimeUnit;
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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortNumberUni;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInputBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow.applications.lldp.speaker.rev141023.OperStatus;
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
41
42 /**
43  * Tests for {@link LLDPSpeaker}.
44  */
45 @RunWith(MockitoJUnitRunner.class)
46 public class LLDPSpeakerTest {
47     private static final InstanceIdentifier<NodeConnector> id;
48     private static final FlowCapableNodeConnector fcnc;
49     private static final TransmitPacketInput packet;
50
51     static {
52         MacAddress mac = new MacAddress("01:23:45:67:89:AB");
53         id = TestUtils.createNodeConnectorId("openflow:1", "openflow:1:1");
54         fcnc = TestUtils.createFlowCapableNodeConnector(mac, 1L).build();
55         byte[] lldpFrame = LLDPUtil.buildLldpFrame(new NodeId("openflow:1"),
56                 new NodeConnectorId("openflow:1:1"), mac, 1L);
57         packet = new TransmitPacketInputBuilder()
58                 .setEgress(new NodeConnectorRef(id))
59                 .setNode(new NodeRef(id.firstIdentifierOf(Node.class)))
60                 .setPayload(lldpFrame).build();
61     }
62
63     @Mock
64     private PacketProcessingService packetProcessingService;
65     @Mock
66     private ScheduledExecutorService scheduledExecutorService;
67     @Mock
68     private ScheduledFuture scheduledSpeakerTask;
69
70     private final MacAddress destinationMACAddress = null;
71     private LLDPSpeaker lldpSpeaker;
72
73     @Before
74     public void setUp() {
75         when(
76                 scheduledExecutorService.scheduleAtFixedRate(
77                         any(Runnable.class), anyLong(), anyLong(),
78                         any(TimeUnit.class))).thenReturn(scheduledSpeakerTask);
79         lldpSpeaker = new LLDPSpeaker(packetProcessingService,
80                 scheduledExecutorService, destinationMACAddress);
81         lldpSpeaker.setOperationalStatus(OperStatus.RUN);
82     }
83
84     /**
85      * Test that speaker does nothing when in {@link OperStatus.STANDBY} mode.
86      */
87     @Test
88     public void testStandBy() {
89         lldpSpeaker.setOperationalStatus(OperStatus.STANDBY);
90         // Add node connector - LLDP packet should be transmitted through
91         // packetProcessingService
92         lldpSpeaker.nodeConnectorAdded(id, fcnc);
93
94         // Execute one iteration of periodic task - LLDP packet should be
95         // transmitted second time
96         lldpSpeaker.run();
97
98         // Check packet transmission
99         verify(packetProcessingService, times(1)).transmitPacket(packet);
100         verifyNoMoreInteractions(packetProcessingService);
101     }
102
103     /**
104      * Test that LLDP frame is transmitted after port appeared in inventory and
105      * periodically after that.
106      */
107     @Test
108     public void testNodeConnectorAdd() {
109         // Add node connector - LLDP packet should be transmitted through
110         // packetProcessingService
111         lldpSpeaker.nodeConnectorAdded(id, fcnc);
112
113         // Execute one iteration of periodic task - LLDP packet should be
114         // transmitted second time
115         lldpSpeaker.run();
116
117         // Check packet transmission
118         verify(packetProcessingService, times(2)).transmitPacket(packet);
119         verifyNoMoreInteractions(packetProcessingService);
120     }
121
122     /**
123      * Test that LLDP frame stop to periodically transmit after port disappeared
124      * from inventory.
125      */
126     @Test
127     public void testNodeConnectorRemoval() {
128         // Prepare for test - add node connector first
129         lldpSpeaker.nodeConnectorAdded(id, fcnc);
130
131         // Trigger removal of packet
132         lldpSpeaker.nodeConnectorRemoved(id);
133
134         // Run one iteration of LLDP flood
135         lldpSpeaker.run();
136
137         // Verify that LLDP frame sent only once (by nodeConnectorAdded),
138         // e.g. no flood after removal
139         verify(packetProcessingService, times(1)).transmitPacket(packet);
140         verifyNoMoreInteractions(packetProcessingService);
141     }
142
143     /**
144      * Test that when {@link LLDPSpeaker#nodeConnectorAdded} is called multiple times
145      * with same arguments, only the first one have effect.
146      */
147     @Test
148     public void testMultipleSameNodeConnectorAddEvents() {
149         // Add node connector - LLDP packet should be transmitted through
150         // packetProcessingService
151         for (int i = 0; i < 10; i++) {
152             lldpSpeaker.nodeConnectorAdded(id, fcnc);
153         }
154
155         // Check packet transmission
156         verify(packetProcessingService, times(1)).transmitPacket(packet);
157         verifyNoMoreInteractions(packetProcessingService);
158     }
159
160     /**
161      * Test that lldpSpeaker cancels periodic LLDP flood task and stops
162      */
163     @Test
164     public void testCleanup() {
165         lldpSpeaker.close();
166         verify(scheduledSpeakerTask, times(1)).cancel(true);
167         verify(scheduledExecutorService, times(1)).shutdown();
168     }
169
170     /**
171      * Test that checks if LLDPSpeaker working fine with local ports.
172      */
173     @Test
174     public void testLocalNodeConnectorCreation() {
175         // Call nodeConnectorAdded with local port
176         FlowCapableNodeConnector fcnc = TestUtils
177                 .createFlowCapableNodeConnector()
178                 .setPortNumber(new PortNumberUni("LOCAL")).build();
179         lldpSpeaker.nodeConnectorAdded(id, fcnc);
180
181         // Verify that nothing happened for local port
182         verify(packetProcessingService, never()).transmitPacket(
183                 any(TransmitPacketInput.class));
184     }
185 }