BUG-7222: Make BGP DS clean up asynchronous
[bgpcep.git] / bgp / rib-impl / src / test / java / org / opendaylight / protocol / bgp / rib / impl / StrictBGPPeerRegistryTest.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. 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.protocol.bgp.rib.impl;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertSame;
13 import static org.junit.Assert.fail;
14
15 import com.google.common.base.Optional;
16 import com.google.common.collect.Lists;
17 import com.google.common.util.concurrent.Futures;
18 import java.net.InetSocketAddress;
19 import java.util.Collections;
20 import java.util.List;
21 import org.junit.Before;
22 import org.junit.Test;
23 import org.mockito.Mockito;
24 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
25 import org.opendaylight.protocol.bgp.parser.BGPError;
26 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionPreferences;
27 import org.opendaylight.protocol.bgp.rib.impl.spi.PeerRegistrySessionListener;
28 import org.opendaylight.protocol.bgp.rib.spi.BGPSessionListener;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Open;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.OpenBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.BgpParameters;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.BgpParametersBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.OptionalCapabilitiesBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.optional.capabilities.CParametersBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.optional.capabilities.c.parameters.As4BytesCapabilityBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpId;
40
41 public class StrictBGPPeerRegistryTest {
42
43     private static final AsNumber LOCAL_AS = new AsNumber(1234L);
44     private static final AsNumber REMOTE_AS = new AsNumber(1235L);
45     private static final Ipv4Address FROM = new Ipv4Address("0.0.0.1");
46     private static final IpAddress REMOTE_IP = new IpAddress(FROM);
47     private static final Ipv4Address TO = new Ipv4Address("255.255.255.255");
48
49     private final BGPSessionListener peer1 = getMockSession();
50     private final Open classicOpen = createOpen(TO, LOCAL_AS);
51     private StrictBGPPeerRegistry peerRegistry;
52     private BGPSessionPreferences mockPreferences;
53
54     private Open createOpen(final Ipv4Address bgpId, final AsNumber as) {
55         final List<BgpParameters> params = Lists.newArrayList(new BgpParametersBuilder()
56         .setOptionalCapabilities(Lists.newArrayList(new OptionalCapabilitiesBuilder()
57         .setCParameters(new CParametersBuilder()
58         .setAs4BytesCapability(new As4BytesCapabilityBuilder().setAsNumber(as).build()).build()).build())).build());
59         return new OpenBuilder().setBgpIdentifier(bgpId).setBgpParameters(params).build();
60     }
61
62     @Before
63     public void setUp() throws Exception {
64         this.peerRegistry = new StrictBGPPeerRegistry();
65         this.mockPreferences =  new BGPSessionPreferences(LOCAL_AS, 1, new BgpId("0.0.0.1"), LOCAL_AS, Collections.<BgpParameters> emptyList(),
66                 Optional.<byte[]>absent());
67     }
68
69     private static BGPSessionListener getMockSession() {
70         final BGPSessionListener mock = Mockito.mock(BGPSessionListener.class);
71         Mockito.doReturn(Futures.immediateFuture(null)).when(mock).releaseConnection();
72         return mock;
73     }
74
75     private static PeerRegistrySessionListener getMockSessionListener() {
76         final PeerRegistrySessionListener mock = Mockito.mock(PeerRegistrySessionListener.class);
77         Mockito.doNothing().when(mock).onSessionCreated(Mockito.any(IpAddress.class));
78         Mockito.doNothing().when(mock).onSessionRemoved(Mockito.any(IpAddress.class));
79         return mock;
80     }
81
82     @Test
83     public void testIpAddressConstruction() throws Exception {
84         final InetSocketAddress adr = new InetSocketAddress("127.0.0.1", 179);
85         final IpAddress ipAdr = StrictBGPPeerRegistry.getIpAddress(adr);
86         assertEquals("127.0.0.1", ipAdr.getIpv4Address().getValue());
87     }
88
89     @Test
90     public void testDuplicatePeerConnection() throws Exception {
91         this.peerRegistry.addPeer(REMOTE_IP, this.peer1, this.mockPreferences);
92         this.peerRegistry.getPeer(REMOTE_IP, FROM, TO, this.classicOpen);
93         try {
94             this.peerRegistry.getPeer(REMOTE_IP, FROM, TO, this.classicOpen);
95         } catch (final BGPDocumentedException e) {
96             assertEquals(BGPError.CEASE, e.getError());
97             return;
98         }
99         fail("Same peer cannot be connected twice");
100     }
101
102     @Test
103     public void testPeerNotConfigured() throws Exception {
104         try {
105             this.peerRegistry.getPeer(REMOTE_IP, FROM, TO, this.classicOpen);
106         } catch (final IllegalStateException e) {
107             return;
108         }
109         fail("Unknown peer cannot be connected");
110     }
111
112     @Test
113     public void testPeerConnectionSuccessfull() throws Exception {
114         final Ipv4Address to2 = new Ipv4Address("255.255.255.254");
115         final IpAddress remoteIp2 = new IpAddress(to2);
116
117         this.peerRegistry.addPeer(REMOTE_IP, this.peer1, this.mockPreferences);
118         final BGPSessionListener session2 = getMockSession();
119         this.peerRegistry.addPeer(remoteIp2, session2, this.mockPreferences);
120
121         final BGPSessionListener returnedSession1 = this.peerRegistry.getPeer(REMOTE_IP, FROM, TO, this.classicOpen);
122         assertSame(this.peer1, returnedSession1);
123         final BGPSessionListener returnedSession2 = this.peerRegistry.getPeer(remoteIp2, FROM, to2, this.classicOpen);
124         assertSame(session2, returnedSession2);
125
126         Mockito.verifyZeroInteractions(this.peer1);
127         Mockito.verifyZeroInteractions(session2);
128     }
129
130     @Test
131     public void testDropSecondPeer() throws Exception {
132         final Ipv4Address higher = new Ipv4Address("192.168.200.200");
133         final Ipv4Address lower = new Ipv4Address("10.10.10.10");
134         final IpAddress remoteIp = new IpAddress(lower);
135
136         this.peerRegistry.addPeer(remoteIp, this.peer1, this.mockPreferences);
137
138         this.peerRegistry.getPeer(remoteIp, higher, lower, createOpen(lower, LOCAL_AS));
139         try {
140             this.peerRegistry.getPeer(remoteIp, lower, higher, createOpen(higher, LOCAL_AS));
141         } catch (final BGPDocumentedException e) {
142             assertEquals(BGPError.CEASE, e.getError());
143             return;
144         }
145         fail("Same peer cannot be connected twice");
146     }
147
148     @Test
149     public void testDropFirstPeer() throws Exception {
150         final Ipv4Address higher = new Ipv4Address("123.123.123.123");
151         final Ipv4Address lower = new Ipv4Address("123.123.123.122");
152         final IpAddress remoteIp = new IpAddress(lower);
153
154         this.peerRegistry.addPeer(remoteIp, this.peer1, this.mockPreferences);
155
156         this.peerRegistry.getPeer(remoteIp, lower, higher, createOpen(higher, LOCAL_AS));
157         this.peerRegistry.getPeer(remoteIp, higher, lower, createOpen(lower, LOCAL_AS));
158         Mockito.verify(this.peer1).releaseConnection();
159     }
160
161     @Test
162     public void testDuplicatePeersWDifferentIds() throws Exception {
163         this.peerRegistry.addPeer(REMOTE_IP, this.peer1, this.mockPreferences);
164
165         this.peerRegistry.getPeer(REMOTE_IP, FROM, TO, this.classicOpen);
166         try {
167             this.peerRegistry.getPeer(REMOTE_IP, TO, TO, this.classicOpen);
168         } catch (final BGPDocumentedException e) {
169             assertEquals(BGPError.CEASE, e.getError());
170             return;
171         }
172         fail("Same peer cannot be connected twice");
173     }
174
175     @Test
176     public void testDuplicatePeersHigherAs() throws Exception {
177         this.peerRegistry.addPeer(REMOTE_IP, this.peer1, this.mockPreferences);
178
179         this.peerRegistry.getPeer(REMOTE_IP, FROM, TO, this.classicOpen);
180         this.peerRegistry.getPeer(REMOTE_IP, FROM, TO, createOpen(TO, REMOTE_AS));
181         Mockito.verify(this.peer1).releaseConnection();
182     }
183
184     @Test
185     public void testDuplicatePeersLowerAs() throws Exception {
186         final AsNumber as2 = new AsNumber(3L);
187
188         this.peerRegistry.addPeer(REMOTE_IP, this.peer1, this.mockPreferences);
189
190         this.peerRegistry.getPeer(REMOTE_IP, FROM, TO, this.classicOpen);
191         try {
192             this.peerRegistry.getPeer(REMOTE_IP, FROM, TO, createOpen(TO, as2));
193         } catch (final BGPDocumentedException e) {
194             assertEquals(BGPError.CEASE, e.getError());
195             return;
196         }
197         fail("Same peer cannot be connected twice");
198     }
199
200     @Test
201     public void testAsMismatch() throws Exception {
202         final AsNumber as2 = new AsNumber(3L);
203
204         this.peerRegistry.addPeer(REMOTE_IP, this.peer1, this.mockPreferences);
205         try {
206             this.peerRegistry.getPeer(REMOTE_IP, FROM, TO, createOpen(TO, as2));
207         } catch (final BGPDocumentedException e) {
208             assertEquals(BGPError.BAD_PEER_AS, e.getError());
209             return;
210         }
211         fail("Peer AS number mismatch");
212     }
213
214     @Test
215     public void testRegisterPeerSessionListener() throws Exception {
216         final PeerRegistrySessionListener sessionListener1 = getMockSessionListener();
217         this.peerRegistry.registerPeerSessionListener(sessionListener1);
218
219         final PeerRegistrySessionListener sessionListener2 = getMockSessionListener();
220         this.peerRegistry.registerPeerSessionListener(sessionListener2);
221
222         this.peerRegistry.addPeer(REMOTE_IP, this.peer1, this.mockPreferences);
223         this.peerRegistry.getPeer(REMOTE_IP, FROM, TO, this.classicOpen);
224         Mockito.verify(sessionListener1, Mockito.times(1)).onSessionCreated(REMOTE_IP);
225         Mockito.verify(sessionListener2, Mockito.times(1)).onSessionCreated(REMOTE_IP);
226
227         this.peerRegistry.removePeerSession(REMOTE_IP);
228         Mockito.verify(sessionListener1, Mockito.times(1)).onSessionRemoved(REMOTE_IP);
229         Mockito.verify(sessionListener2, Mockito.times(1)).onSessionRemoved(REMOTE_IP);
230     }
231
232     @Test
233     public void testClosePeerSessionOneListener() throws Exception {
234         final PeerRegistrySessionListener sessionListener1 = getMockSessionListener();
235         final AutoCloseable registration1 = this.peerRegistry.registerPeerSessionListener(sessionListener1);
236
237         final PeerRegistrySessionListener sessionListener2 = getMockSessionListener();
238         this.peerRegistry.registerPeerSessionListener(sessionListener2);
239
240         this.peerRegistry.addPeer(REMOTE_IP, this.peer1, this.mockPreferences);
241         this.peerRegistry.getPeer(REMOTE_IP, FROM, TO, this.classicOpen);
242         this.peerRegistry.removePeerSession(REMOTE_IP);
243
244         registration1.close();
245         this.peerRegistry.getPeer(REMOTE_IP, FROM, TO, this.classicOpen);
246         this.peerRegistry.removePeerSession(REMOTE_IP);
247
248         Mockito.verify(sessionListener1, Mockito.times(1)).onSessionCreated(REMOTE_IP);
249         Mockito.verify(sessionListener2, Mockito.times(2)).onSessionCreated(REMOTE_IP);
250         Mockito.verify(sessionListener1, Mockito.times(1)).onSessionRemoved(REMOTE_IP);
251         Mockito.verify(sessionListener2, Mockito.times(2)).onSessionRemoved(REMOTE_IP);
252     }
253 }