summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/minimal-distribution-parent/pom.xml20
-rw-r--r--infra/minimal-distribution/pom.xml18
-rw-r--r--infra/minimal-distribution/src/test/java/io/fd/honeycomb/infra/distro/BaseMinimalDistributionTest.java178
-rw-r--r--infra/minimal-distribution/src/test/resources/WEB-INF/web.xml89
-rw-r--r--infra/minimal-distribution/src/test/resources/honeycomb-keystorebin0 -> 2392 bytes
-rw-r--r--infra/minimal-distribution/src/test/resources/honeycomb.json40
-rw-r--r--infra/minimal-distribution/src/test/resources/logback.xml31
7 files changed, 376 insertions, 0 deletions
diff --git a/common/minimal-distribution-parent/pom.xml b/common/minimal-distribution-parent/pom.xml
index 373b642c7..12dce7357 100644
--- a/common/minimal-distribution-parent/pom.xml
+++ b/common/minimal-distribution-parent/pom.xml
@@ -55,6 +55,11 @@ done
<mdsal.version>2.0.2-Beryllium-SR2</mdsal.version>
<!-- Used by mdsal as provided/runtime dependency-->
<osgi.core.version>5.0.0</osgi.core.version>
+ <junit.version>4.11</junit.version>
+ <!-- Use /dev/urandom instead of /dev/random during tests to speed up execution
+ http://stackoverflow.com/questions/137212/how-to-solve-performance-problem-with-java-securerandom
+ -->
+ <random.seed.file>/dev/./urandom</random.seed.file>
</properties>
<dependencyManagement>
@@ -152,6 +157,14 @@ done
<artifactId>org.osgi.core</artifactId>
<version>${osgi.core.version}</version>
</dependency>
+
+ <!-- Junit for test -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</dependencyManagement>
@@ -313,6 +326,13 @@ done
</execution>
</executions>
</plugin>
+
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <argLine>-Djava.security.egd=file:${random.seed.file}</argLine>
+ </configuration>
+ </plugin>
</plugins>
</pluginManagement>
</build>
diff --git a/infra/minimal-distribution/pom.xml b/infra/minimal-distribution/pom.xml
index a03e3a97e..d22f5b7b7 100644
--- a/infra/minimal-distribution/pom.xml
+++ b/infra/minimal-distribution/pom.xml
@@ -167,5 +167,23 @@
<artifactId>notification-impl</artifactId>
<version>${project.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.mashape.unirest</groupId>
+ <artifactId>unirest-java</artifactId>
+ <version>1.4.9</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.jcraft</groupId>
+ <artifactId>jsch</artifactId>
+ <version>0.1.54</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/infra/minimal-distribution/src/test/java/io/fd/honeycomb/infra/distro/BaseMinimalDistributionTest.java b/infra/minimal-distribution/src/test/java/io/fd/honeycomb/infra/distro/BaseMinimalDistributionTest.java
new file mode 100644
index 000000000..61042868f
--- /dev/null
+++ b/infra/minimal-distribution/src/test/java/io/fd/honeycomb/infra/distro/BaseMinimalDistributionTest.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.infra.distro;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.ByteStreams;
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.ChannelSubsystem;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.Session;
+import com.mashape.unirest.http.HttpResponse;
+import com.mashape.unirest.http.Unirest;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+import java.util.Properties;
+import javax.net.ssl.SSLContext;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.ssl.SSLContexts;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BaseMinimalDistributionTest {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BaseMinimalDistributionTest.class);
+
+ private static final int HTTP_PORT = 8182;
+ private static final int HTTPS_PORT = 8444;
+ private static final String UNAME = "admin";
+ private static final String PASSWORD = "admin";
+ private static final String CERT_PASSWORD = "testing";
+ private static final int NETCONF_TCP_PORT = 7778;
+ private static final int NETCONF_SSH_PORT = 2832;
+ private static final String NETCONF_NAMESPACE = "urn:ietf:params:xml:ns:netconf:base:1.0";
+ private static final int NETCONF_HELLO_WAIT = 2500;
+
+ @Before
+ public void setUp() throws Exception {
+ SSLContext sslcontext = SSLContexts.custom()
+ .loadTrustMaterial(getClass().getResource("/honeycomb-keystore"),
+ CERT_PASSWORD.toCharArray(), new TrustSelfSignedStrategy())
+ .build();
+
+ SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext);
+ CloseableHttpClient httpclient = HttpClients.custom()
+ .setSSLSocketFactory(sslsf)
+ .build();
+ Unirest.setHttpClient(httpclient);
+ }
+
+ /**
+ * Start base distribution and check all northbound interfaces
+ */
+ @Test(timeout = 60000)
+ public void test() throws Exception {
+ Main.init(Main.BASE_MODULES);
+
+ LOG.info("Testing Honeycomb base distribution");
+ LOG.info("Testing NETCONF TCP");
+ assertNetconfTcp();
+ LOG.info("Testing NETCONF SSH");
+ assertNetconfSsh();
+ LOG.info("Testing RESTCONF HTTP");
+ assertRestconfHttp();
+ LOG.info("Testing RESTCONF HTTPS");
+ assertRestconfHttps();
+ }
+
+ private void assertNetconfTcp() throws Exception {
+ try (final Socket localhost = new Socket("127.0.0.1", NETCONF_TCP_PORT);
+ final InputStream inputStream = localhost.getInputStream()) {
+ // Wait until hello msg is sent from server
+ Thread.sleep(NETCONF_HELLO_WAIT);
+ final String helloMessage = inputStreamToString(inputStream);
+
+ LOG.info("NETCONF TCP sent hello: {}", helloMessage);
+
+ assertThat(helloMessage, containsString("hello"));
+ assertThat(helloMessage, containsString(NETCONF_NAMESPACE));
+ }
+ }
+
+ private String inputStreamToString(final InputStream inputStream) throws IOException {
+ final int available = inputStream.available();
+ final byte[] helloBytes = new byte[available];
+ ByteStreams.read(inputStream, helloBytes, 0, available);
+ return new String(helloBytes, Charsets.UTF_8);
+ }
+
+ private void assertNetconfSsh() throws Exception {
+ JSch jsch = new JSch();
+ final Session session = jsch.getSession(UNAME, "127.0.0.1", NETCONF_SSH_PORT);
+ session.setPassword(PASSWORD);
+ Properties config = new Properties();
+ config.put("StrictHostKeyChecking", "no");
+ session.setConfig(config);
+ session.connect(20000);
+
+ Channel channel = session.openChannel("subsystem");
+
+ ((ChannelSubsystem) channel).setSubsystem("netconf");
+ ((ChannelSubsystem) channel).setPty(true);
+ final InputStream inputStream = channel.getInputStream();
+ channel.connect(20000);
+
+ // Wait until hello msg is sent from server
+ Thread.sleep(NETCONF_HELLO_WAIT);
+ final String helloMessage = inputStreamToString(inputStream);
+ LOG.info("NETCONF SSH sent hello: {}", helloMessage);
+
+ assertThat(helloMessage, containsString("hello"));
+ assertThat(helloMessage, containsString(NETCONF_NAMESPACE));
+
+ channel.disconnect();
+ session.disconnect();
+ }
+
+ private void assertRestconfHttp() throws Exception {
+ final String url =
+ "http://127.0.0.1:" + HTTP_PORT + "/restconf/operational/ietf-netconf-monitoring:netconf-state";
+ LOG.info("RESTCONF HTTP GET to {}", url);
+ final HttpResponse<String> jsonNodeHttpResponse = Unirest.get(url)
+ .basicAuth(UNAME, PASSWORD)
+ .asString();
+ LOG.info("RESTCONF HTTP GET to {}, status: {}, data: {}",
+ url, jsonNodeHttpResponse.getStatus(), jsonNodeHttpResponse.getBody());
+
+ assertSuccessStatus(jsonNodeHttpResponse);
+ assertSuccessResponseForNetconfMonitoring(jsonNodeHttpResponse);
+ }
+
+ private void assertRestconfHttps() throws Exception {
+ final String url =
+ "https://127.0.0.1:" + HTTPS_PORT + "/restconf/operational/ietf-netconf-monitoring:netconf-state";
+ LOG.info("RESTCONF HTTPS GET to {}", url);
+ final HttpResponse<String> jsonNodeHttpResponse = Unirest.get(url)
+ .basicAuth(UNAME, PASSWORD)
+ .asString();
+ LOG.info("RESTCONF HTTPS GET to {}, status: {}, data: {}",
+ url, jsonNodeHttpResponse.getStatus(), jsonNodeHttpResponse.getBody());
+
+ assertSuccessStatus(jsonNodeHttpResponse);
+ assertSuccessResponseForNetconfMonitoring(jsonNodeHttpResponse);
+ }
+
+ private void assertSuccessResponseForNetconfMonitoring(final HttpResponse<String> jsonNodeHttpResponse) {
+ assertThat(jsonNodeHttpResponse.getBody(), containsString("schemas"));
+ assertThat(jsonNodeHttpResponse.getBody(), containsString(NETCONF_NAMESPACE));
+ }
+
+ private void assertSuccessStatus(final HttpResponse<String> jsonNodeHttpResponse) {
+ assertTrue(jsonNodeHttpResponse.getStatus() >= 200);
+ assertTrue(jsonNodeHttpResponse.getStatus() < 400);
+ }
+} \ No newline at end of file
diff --git a/infra/minimal-distribution/src/test/resources/WEB-INF/web.xml b/infra/minimal-distribution/src/test/resources/WEB-INF/web.xml
new file mode 100644
index 000000000..45fcce741
--- /dev/null
+++ b/infra/minimal-distribution/src/test/resources/WEB-INF/web.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ ~ Copyright (c) 2016 Cisco and/or its affiliates.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at:
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ version="3.0">
+
+ <servlet>
+ <servlet-name>JAXRSRestconf</servlet-name>
+ <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
+ <init-param>
+ <param-name>javax.ws.rs.Application</param-name>
+ <param-value>org.opendaylight.netconf.sal.rest.impl.RestconfApplication</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>JAXRSRestconf</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+
+ <filter>
+ <filter-name>GzipFilter</filter-name>
+ <filter-class>org.eclipse.jetty.servlets.GzipFilter</filter-class>
+ <init-param>
+ <param-name>mimeTypes</param-name>
+ <param-value>application/xml,application/yang.data+xml,xml,application/json,application/yang.data+json</param-value>
+ </init-param>
+ </filter>
+ <!-- TODO HONEYCOMB-168 gzip filter is deprecated -->
+ <filter-mapping>
+ <filter-name>GzipFilter</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+ <filter>
+ <filter-name>cross-origin-restconf</filter-name>
+ <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
+ <init-param>
+ <param-name>allowedOrigins</param-name>
+ <param-value>*</param-value>
+ </init-param>
+ <init-param>
+ <param-name>allowedMethods</param-name>
+ <param-value>GET,POST,OPTIONS,DELETE,PUT,HEAD</param-value>
+ </init-param>
+ <init-param>
+ <param-name>allowedHeaders</param-name>
+ <param-value>origin, content-type, accept, authorization</param-value>
+ </init-param>
+ <init-param>
+ <param-name>exposedHeaders</param-name>
+ <param-value>location</param-value>
+ </init-param>
+ </filter>
+ <filter-mapping>
+ <filter-name>cross-origin-restconf</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>NB api</web-resource-name>
+ <url-pattern>/*</url-pattern>
+ <http-method>POST</http-method>
+ <http-method>GET</http-method>
+ <http-method>PUT</http-method>
+ <http-method>PATCH</http-method>
+ <http-method>DELETE</http-method>
+ <http-method>HEAD</http-method>
+ </web-resource-collection>
+ </security-constraint>
+
+</web-app>
diff --git a/infra/minimal-distribution/src/test/resources/honeycomb-keystore b/infra/minimal-distribution/src/test/resources/honeycomb-keystore
new file mode 100644
index 000000000..44093dc09
--- /dev/null
+++ b/infra/minimal-distribution/src/test/resources/honeycomb-keystore
Binary files differ
diff --git a/infra/minimal-distribution/src/test/resources/honeycomb.json b/infra/minimal-distribution/src/test/resources/honeycomb.json
new file mode 100644
index 000000000..a0b2a633c
--- /dev/null
+++ b/infra/minimal-distribution/src/test/resources/honeycomb.json
@@ -0,0 +1,40 @@
+ {
+ "persisted-context-path": "/tmp/honeycomb/persist/context/data.json",
+ "persisted-context-restoration-type": "Merge",
+ "persisted-config-path": "/tmp/honeycomb/persist/config/data.json",
+ "persisted-config-restoration-type": "Merge",
+
+ "notification-service-queue-depth": 1,
+
+ "restconf-http-enabled": "true",
+ "restconf-root-path": "/restconf",
+ "restconf-binding-address": "127.0.0.1",
+ "restconf-port": 8182,
+ "restconf-https-enabled": "true",
+ "restconf-https-binding-address": "127.0.0.1",
+ "restconf-https-port": 8444,
+ "restconf-keystore": "/honeycomb-keystore",
+ "restconf-keystore-password": "testing",
+ "restconf-keystore-manager-password": "testing",
+ "restconf-truststore": "/honeycomb-keystore",
+ "restconf-truststore-password": "testing",
+ "restconf-websocket-port": 7780,
+ "restconf-pool-max-size": 10,
+ "restconf-pool-min-size": 1,
+ "restconf-acceptors-size": 1,
+ "restconf-selectors-size": 1,
+ "restconf-https-acceptors-size": 1,
+ "restconf-https-selectors-size": 1,
+
+ "netconf-netty-threads": 2,
+ "netconf-tcp-enabled" : "true",
+ "netconf-tcp-binding-address": "127.0.0.1",
+ "netconf-tcp-binding-port": 7778,
+ "netconf-ssh-enabled" : "true",
+ "netconf-ssh-binding-address": "127.0.0.1",
+ "netconf-ssh-binding-port": 2832,
+ "netconf-notification-stream-name": "honeycomb",
+
+ "username": "admin",
+ "password": "admin"
+} \ No newline at end of file
diff --git a/infra/minimal-distribution/src/test/resources/logback.xml b/infra/minimal-distribution/src/test/resources/logback.xml
new file mode 100644
index 000000000..2ee89db4e
--- /dev/null
+++ b/infra/minimal-distribution/src/test/resources/logback.xml
@@ -0,0 +1,31 @@
+ <!--
+ ~ Copyright (c) 2016 Cisco and/or its affiliates.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at:
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<configuration scan="true">
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <root level="warn">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+ <logger name="org.opendaylight" level="INFO"/>
+ <logger name="io.fd" level="INFO"/>
+</configuration>