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