Improve error messages in distro tests
[honeycomb.git] / infra / bgp-distribution-test / src / test / java / io / fd / honeycomb / infra / bgp / distro / BgpDistributionTest.java
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package io.fd.honeycomb.infra.bgp.distro;
18
19 import static org.junit.Assert.assertTrue;
20
21 import com.google.common.base.Charsets;
22 import com.google.common.io.ByteStreams;
23 import com.google.common.net.InetAddresses;
24 import com.mashape.unirest.http.HttpResponse;
25 import com.mashape.unirest.http.Unirest;
26 import com.mashape.unirest.http.exceptions.UnirestException;
27 import io.fd.honeycomb.infra.distro.Main;
28 import io.fd.honeycomb.infra.distro.activation.ActivationModule;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.net.InetAddress;
32 import java.net.Socket;
33 import java.nio.file.Files;
34 import java.nio.file.Paths;
35 import javax.net.ssl.SSLContext;
36 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
37 import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
38 import org.apache.http.impl.client.CloseableHttpClient;
39 import org.apache.http.impl.client.HttpClients;
40 import org.apache.http.ssl.SSLContexts;
41 import org.junit.Assert;
42 import org.junit.Before;
43 import org.junit.Test;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 public class BgpDistributionTest {
48     private static final String BGP_HOST_ADDRESS = "127.0.0.1";
49     private static final int HTTP_PORT = 8182;
50     private static final String UNAME = "admin";
51     private static final String PASSWORD = "admin";
52
53     private static final Logger LOG = LoggerFactory.getLogger(BgpDistributionTest.class);
54     private static final String CERT_PASSWORD = "testing";
55     private static final int HELLO_WAIT = 2500;
56
57     private static final int BGP_MSG_TYPE_OFFSET = 18; // 16 (MARKER) + 2 (LENGTH);
58     private static final byte BGP_OPEN_MSG_TYPE = 1;
59     private static final int BGP_PORT = 1790;
60
61     @Before
62     public void setUp() throws Exception {
63         SSLContext sslcontext = SSLContexts.custom()
64             .loadTrustMaterial(getClass().getResource("/honeycomb-keystore"),
65                 CERT_PASSWORD.toCharArray(), new TrustSelfSignedStrategy())
66             .build();
67
68         SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext);
69         CloseableHttpClient httpclient = HttpClients.custom()
70             .setSSLSocketFactory(sslsf)
71             .build();
72         Unirest.setHttpClient(httpclient);
73     }
74
75     @Test(timeout = 180000)
76     public void test() throws Exception {
77         Main.init(new ActivationModule());
78         LOG.info("Testing Honeycomb BGP distribution");
79         assertBgp();
80     }
81
82     private void assertBgp() throws Exception {
83         // Wait until BGP server is started
84         Thread.sleep(HELLO_WAIT);
85
86         configureBgpPeers();
87
88         assertBgpOpenIsSent("127.0.0.2");
89         assertBgpOpenIsSent("127.0.0.3");
90     }
91
92     private void configureBgpPeers() throws UnirestException, IOException {
93         final String url =
94             "http://" + BGP_HOST_ADDRESS + ":" + HTTP_PORT
95                 + "/restconf/config/openconfig-network-instance:network-instances/network-instance/global-bgp/"
96                 + "openconfig-network-instance:protocols/protocol/openconfig-policy-types:BGP/hc-bgp-instance/"
97                 + "bgp/bgp-openconfig-extensions:neighbors";
98
99         final String request =
100             new String(Files.readAllBytes(Paths.get("src/test/resources/bgp-peers.json")), Charsets.UTF_8);
101         final HttpResponse<String> response =
102             Unirest.put(url)
103                 .basicAuth(UNAME, PASSWORD)
104                 .header("Content-Type", "application/json")
105                 .body(request)
106                 .asString();
107
108         assertSuccessStatus(response);
109     }
110
111     private void assertBgpOpenIsSent(final String peerAddress) throws IOException, InterruptedException {
112         final InetAddress bgpHost = InetAddresses.forString(BGP_HOST_ADDRESS);
113         final InetAddress bgpPeerAddress = InetAddresses.forString(peerAddress);
114         try (final Socket localhost = new Socket(bgpHost, BGP_PORT, bgpPeerAddress, 0);
115              final InputStream inputStream = localhost.getInputStream()) {
116             // Wait until bgp message is sent
117             Thread.sleep(HELLO_WAIT);
118
119             final byte[] msg = readMessage(inputStream);
120             LOG.info("Received BGP message: {}", msg);
121
122             Assert.assertEquals("BGP OPEN message type was expected", BGP_OPEN_MSG_TYPE, msg[BGP_MSG_TYPE_OFFSET]);
123         }
124     }
125
126     private byte[] readMessage(final InputStream inputStream) throws IOException {
127         final int available = inputStream.available();
128         final byte[] msg = new byte[available];
129         ByteStreams.read(inputStream, msg, 0, available);
130         return msg;
131     }
132
133     private void assertSuccessStatus(final HttpResponse<String> jsonNodeHttpResponse) {
134         final int statusCode = jsonNodeHttpResponse.getStatus();
135         assertTrue("Expected HTTP status code in range [200, 400), but was: " + statusCode,
136             statusCode >= 200 && statusCode < 400);
137     }
138 }