You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@submarine.apache.org by li...@apache.org on 2020/02/15 11:58:37 UTC
[submarine] branch master updated: SUBMARINE-385. [k8s-e2e] Create
k8s e2e test module
This is an automated email from the ASF dual-hosted git repository.
liuxun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/submarine.git
The following commit(s) were added to refs/heads/master by this push:
new d9e0282 SUBMARINE-385. [k8s-e2e] Create k8s e2e test module
d9e0282 is described below
commit d9e0282e2eaf79f2b0028c325aa81d8763404c37
Author: Xun Liu <li...@apache.org>
AuthorDate: Sat Feb 15 19:29:53 2020 +0800
SUBMARINE-385. [k8s-e2e] Create k8s e2e test module
### What is this PR for?
1. Add new travis job, create k8s by Kind & deploy submairne in k8s
1. Support developers to use kind to create k8s cluster in local / travis
2. depoly submarine in kind cluster
3. By calling the submarine's rest interface, determine whether the submarine is deployed correctly in k8s. like this : curl `http://127.0.0.1/api/v1/cluster/nodes`
### What type of PR is it?
Feature
### Todos
* [ ] - Support tensorflow in k8s e2e test
* [ ] - Support pytorch in k8s e2e test
### What is the Jira issue?
* https://issues.apache.org/jira/browse/SUBMARINE-385
### How should this be tested?
* https://travis-ci.org/liuxunorg/submarine/builds/650766597
### Screenshots (if appropriate)
### Questions:
* Does the licenses files need update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No
Author: Xun Liu <li...@apache.org>
Closes #184 from liuxunorg/SUBMARINE-385 and squashes the following commits:
ac774a0 [Xun Liu] Add version number in dependencyManagement
59ddd77 [Xun Liu] Remove the version number of the dependent package
3ff31dc [Xun Liu] SUBMARINE-385. [k8s-e2e] Create k8s e2e test module
---
.travis.yml | 8 +
pom.xml | 20 +++
submarine-cloud/hack/deploy-submarine.sh | 22 ++-
submarine-cloud/hack/integration-test.sh | 47 ++++++
submarine-cloud/hack/kind-cluster-build.sh | 4 +
submarine-dist/src/assembly/distribution.xml | 13 ++
submarine-test/e2e/pom.xml | 18 ++
submarine-test/pom.xml | 21 ++-
submarine-test/{e2e => test-k8s}/pom.xml | 99 +++++------
.../rest/AbstractSubmarineServerTest.java | 181 +++++++++++++++++++++
.../java/org/apache/submarine/rest/ClusterIT.java | 50 ++++++
.../test-k8s/src/test/resources/log4j.properties | 24 +++
12 files changed, 445 insertions(+), 62 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index d389ec4..6ac14fa 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -165,6 +165,14 @@ matrix:
chrome: stable
env: PROFILE="-Phadoop-2.9" BUILD_FLAG="clean package -DskipTests" TEST_FLAG="verify -DskipRat -am" TEST_MODULES="-pl submarine-test/e2e" TEST_PROJECTS=""
+ - name: Test submarine-test-k8s
+ language: java
+ jdk: "openjdk8"
+ dist: xenial
+ addons:
+ chrome: stable
+ env: PROFILE="-Phadoop-2.9" BUILD_FLAG="clean package -DskipTests" TEST_FLAG="verify -DskipRat -am" TEST_MODULES="-pl submarine-test/test-k8s" TEST_PROJECTS=""
+
# Template disable by SUBMARINE-381
#- name: Test submarine interpreter
# language: java
diff --git a/pom.xml b/pom.xml
index 56754c5..3885fd4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -154,6 +154,11 @@
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
<!-- Unit Tests -->
<dependency>
@@ -166,6 +171,11 @@
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>${testng.version}</version>
+ </dependency>
<!-- Submarine on Kubernetes -->
<dependency>
@@ -271,6 +281,16 @@
<version>${zookeeper.version}</version>
</dependency>
<dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <version>${commons-httpclient.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ <version>${javax.ws.rsapi.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-xc</artifactId>
<version>${codehaus-jackson.version}</version>
diff --git a/submarine-cloud/hack/deploy-submarine.sh b/submarine-cloud/hack/deploy-submarine.sh
index 410e8a2..23571a6 100755
--- a/submarine-cloud/hack/deploy-submarine.sh
+++ b/submarine-cloud/hack/deploy-submarine.sh
@@ -42,11 +42,16 @@ function install_submarine() {
cp ${SUBMARINE_HOME}/conf/log4j.properties.template ${ROOT}/hack/conf/log4j.properties
fi
- echo ""
- echo -e "Have you configured the \033[31m${ROOT}/hack/conf/submarine-site.xml\033[0m file?"
- echo -e "Have you configured the \033[31m${ROOT}/hack/conf/log4j.properties\033[0m file?"
- echo -n "Do you want to deploy submarine in k8s cluster now? [y/n]"
- read myselect
+ if [[ "$TEST" == "" ]]; then
+ echo ""
+ echo -e "Have you configured the \033[31m${ROOT}/hack/conf/submarine-site.xml\033[0m file?"
+ echo -e "Have you configured the \033[31m${ROOT}/hack/conf/log4j.properties\033[0m file?"
+ echo -n "Do you want to deploy submarine in k8s cluster now? [y/n]"
+ read myselect
+ else
+ myselect="y"
+ fi
+
if [[ "$myselect" == "y" || "$myselect" == "Y" ]]; then
if $KUBECTL_BIN get configmap --namespace default | grep submarine-config >/dev/null ; then
$KUBECTL_BIN delete configmap --namespace default submarine-config
@@ -97,6 +102,7 @@ This script use kind to create Submarine cluster, about kind please refer: https
Options:
-d,--database ip/service of submarine database, default value: submarine-database
-u,--uninstall uninstall submarine cluster
+ -t,--test auto install
-h,--help prints the usage message
Usage:
install: $0 --database database_ip
@@ -115,6 +121,10 @@ case $key in
shift
shift
;;
+ -t|--test)
+ TEST="TRUE"
+ shift
+ ;;
-u|--uninstall)
UNINSTALL="TRUE"
shift
@@ -130,6 +140,8 @@ done
DATABASE_IP=${DATABASE_IP:-submarine-database}
echo "Submarine database ip: ${DATABASE_IP}"
+export KUBECONFIG=~/.kube/kind-config-${clusterName:-kind}
+
if [[ "$UNINSTALL" == "TRUE" ]]; then
uninstall_submarine
else
diff --git a/submarine-cloud/hack/integration-test.sh b/submarine-cloud/hack/integration-test.sh
new file mode 100755
index 0000000..714e199
--- /dev/null
+++ b/submarine-cloud/hack/integration-test.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+set -e
+
+ROOT=$(unset CDPATH && cd $(dirname "${BASH_SOURCE[0]}")/.. && pwd)
+cd $ROOT
+SUBMARINE_HOME=${ROOT}/..
+
+function start() {
+ $ROOT/hack/kind-cluster-build.sh
+ $ROOT/hack/deploy-submarine.sh --test
+
+ for((i=1;i<=100;i++)); do
+ if curl http://127.0.0.1/api/v1/cluster/address | grep \"status\":\"OK\" ; then
+ echo "Cluster start success!"
+ exit;
+ fi
+ sleep 3
+ done
+
+ echo "Cluster start failure!"
+}
+
+function stop() {
+ $ROOT/hack/kind delete cluster
+}
+
+if [[ "$1" == "stop" ]]; then
+ stop
+else
+ start
+fi
diff --git a/submarine-cloud/hack/kind-cluster-build.sh b/submarine-cloud/hack/kind-cluster-build.sh
index 36242d7..b88ff7b 100755
--- a/submarine-cloud/hack/kind-cluster-build.sh
+++ b/submarine-cloud/hack/kind-cluster-build.sh
@@ -144,8 +144,10 @@ EOF
done
echo "start to create k8s cluster"
+test -d "~/.kube" || mkdir -p "~/.kube"
export KUBECONFIG=~/.kube/kind-config-${clusterName}
$KIND_BIN create cluster --config ${configFile} --image kindest/node:${k8sVersion} --name=${clusterName}
+$KIND_BIN export kubeconfig --kubeconfig ${KUBECONFIG}
echo "deploy docker registry in kind"
registryNode=${clusterName}-control-plane
@@ -241,6 +243,8 @@ $KUBECTL_BIN apply -f $ROOT/hack/ingress/mandatory.yaml
$KUBECTL_BIN apply -f $ROOT/hack/ingress/service-nodeport.yaml
$KUBECTL_BIN patch deployments -n ingress-nginx nginx-ingress-controller -p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx-ingress-controller","ports":[{"containerPort":80,"hostPort":80},{"containerPort":443,"hostPort":443}]}],"nodeSelector":{"ingress-ready":"true"},"tolerations":[{"key":"node-role.kubernetes.io/master","operator":"Equal","effect":"NoSchedule"}]}}}}'
+$KUBECTL_BIN get pod -A
+
echo "############# success create cluster:[${clusterName}] #############"
echo "To start using your cluster, run:"
diff --git a/submarine-dist/src/assembly/distribution.xml b/submarine-dist/src/assembly/distribution.xml
index ed93d05..049146e 100644
--- a/submarine-dist/src/assembly/distribution.xml
+++ b/submarine-dist/src/assembly/distribution.xml
@@ -74,6 +74,19 @@
</includes>
</fileSet>
<fileSet>
+ <directory>../submarine-cloud/manifests</directory>
+ <outputDirectory>/submarine-cloud/manifests</outputDirectory>
+ </fileSet>
+ <fileSet>
+ <directory>../submarine-cloud/hack</directory>
+ <outputDirectory>/submarine-cloud/hack</outputDirectory>
+ <excludes>
+ <exclude>*.go.txt</exclude>
+ <exclude>update-codegen.sh</exclude>
+ <exclude>verify-codegen.sh</exclude>
+ </excludes>
+ </fileSet>
+ <fileSet>
<directory>../submarine-commons/commons-utils/target</directory>
<outputDirectory>/lib</outputDirectory>
<includes>
diff --git a/submarine-test/e2e/pom.xml b/submarine-test/e2e/pom.xml
index 109f9be..bb37a99 100644
--- a/submarine-test/e2e/pom.xml
+++ b/submarine-test/e2e/pom.xml
@@ -1,4 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+ -->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
diff --git a/submarine-test/pom.xml b/submarine-test/pom.xml
index e220ebd..3cc7e42 100644
--- a/submarine-test/pom.xml
+++ b/submarine-test/pom.xml
@@ -1,4 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+ -->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
@@ -16,6 +34,7 @@
<modules>
<module>e2e</module>
+ <module>test-k8s</module>
</modules>
-</project>
\ No newline at end of file
+</project>
diff --git a/submarine-test/e2e/pom.xml b/submarine-test/test-k8s/pom.xml
similarity index 67%
copy from submarine-test/e2e/pom.xml
copy to submarine-test/test-k8s/pom.xml
index 109f9be..33da4c5 100644
--- a/submarine-test/e2e/pom.xml
+++ b/submarine-test/test-k8s/pom.xml
@@ -1,4 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+ -->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
@@ -10,10 +28,9 @@
<version>0.4.0-SNAPSHOT</version>
</parent>
- <artifactId>submarine-e2e</artifactId>
+ <artifactId>submarine-test-k8s</artifactId>
<version>0.4.0-SNAPSHOT</version>
- <name>Submarine: E2E Test</name>
-
+ <name>Submarine: Kubernetes Test</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -26,43 +43,13 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.seleniumhq.selenium</groupId>
- <artifactId>selenium-java</artifactId>
- <version>${selenium.version}</version>
- <exclusions>
- <exclusion>
- <groupId>commons-codec</groupId>
- <artifactId>commons-codec</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- </dependency>
- <dependency>
- <groupId>commons-codec</groupId>
- <artifactId>commons-codec</artifactId>
- <version>${commons-codec.version}</version>
- </dependency>
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- </dependency>
- <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
- <version>${slf4j.version}</version>
- </dependency>
- <dependency>
- <groupId>org.rauschig</groupId>
- <artifactId>jarchivelib</artifactId>
- <version>${jarchivelib.version}</version>
+ <scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
- <version>${testng.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
@@ -71,9 +58,23 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>commons-httpclient</groupId>
+ <artifactId>commons-httpclient</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
-
<build>
<plugins>
<plugin>
@@ -110,14 +111,12 @@
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
- <id>start-submarine-server</id>
+ <id>start-kind</id>
<phase>pre-integration-test</phase>
<configuration>
<target unless="skipTests">
- <exec executable="./submarine-daemon.sh" dir="${submarine.daemon.package.base}"
- spawn="false">
+ <exec executable="./integration-test.sh" dir="${submarine.cloud.path}" spawn="false">
<arg value="start"/>
- <arg value="getMysqlJar" />
</exec>
</target>
</configuration>
@@ -126,12 +125,11 @@
</goals>
</execution>
<execution>
- <id>stop-submarine-server</id>
+ <id>stop-kind</id>
<phase>post-integration-test</phase>
<configuration>
<target unless="skipTests">
- <exec executable="./submarine-daemon.sh" dir="${submarine.daemon.package.base}"
- spawn="false">
+ <exec executable="./integration-test.sh" dir="${submarine.cloud.path}" spawn="false">
<arg value="stop"/>
</exec>
</target>
@@ -147,25 +145,14 @@
<profiles>
<profile>
- <id>using-source-tree</id>
- <activation>
- <activeByDefault>false</activeByDefault>
- </activation>
- <properties>
- <submarine.daemon.package.base>
- ../bin
- </submarine.daemon.package.base>
- </properties>
- </profile>
- <profile>
<id>using-packaged-distr</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
- <submarine.daemon.package.base>
- ../../submarine-dist/target/submarine-dist-${project.version}-hadoop-2.9/submarine-dist-${project.version}-hadoop-2.9/bin
- </submarine.daemon.package.base>
+ <submarine.cloud.path>
+ ../../submarine-dist/target/submarine-dist-${project.version}-hadoop-2.9/submarine-dist-${project.version}-hadoop-2.9/submarine-cloud/hack
+ </submarine.cloud.path>
</properties>
</profile>
</profiles>
diff --git a/submarine-test/test-k8s/src/test/java/org/apache/submarine/rest/AbstractSubmarineServerTest.java b/submarine-test/test-k8s/src/test/java/org/apache/submarine/rest/AbstractSubmarineServerTest.java
new file mode 100644
index 0000000..b4aa70d
--- /dev/null
+++ b/submarine-test/test-k8s/src/test/java/org/apache/submarine/rest/AbstractSubmarineServerTest.java
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.submarine.rest;
+
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.cookie.CookiePolicy;
+import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
+import org.apache.commons.httpclient.methods.DeleteMethod;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.PutMethod;
+import org.apache.commons.httpclient.methods.RequestEntity;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.core.MediaType;
+import java.io.IOException;
+import java.util.regex.Pattern;
+
+public abstract class AbstractSubmarineServerTest {
+ protected static final Logger LOG = LoggerFactory.getLogger(AbstractSubmarineServerTest.class);
+
+ static final String URL = getUrlToTest();
+
+ public static String getUrlToTest() {
+ // The submarine server deployed in k8s uses the default port of 8080 in submarine-site.xml.
+ // However, port 80 is exposed through k8s Ingress.
+ String url = "http://localhost:80";
+ if (System.getProperty("url") != null) {
+ url = System.getProperty("url");
+ }
+ return url;
+ }
+
+ protected static PostMethod httpPost(String path, String body) throws IOException {
+ return httpPost(path, body, StringUtils.EMPTY, StringUtils.EMPTY);
+ }
+
+ protected static PostMethod httpPost(String path, String request, String user, String pwd)
+ throws IOException {
+ LOG.info("Connecting to {}", URL + path);
+
+ HttpClient httpClient = new HttpClient();
+ PostMethod postMethod = new PostMethod(URL + path);
+ postMethod.setRequestBody(request);
+ postMethod.setRequestHeader("Content-type", MediaType.APPLICATION_JSON);
+ postMethod.getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
+
+ if (userAndPasswordAreNotBlank(user, pwd)) {
+ postMethod.setRequestHeader("Cookie", "JSESSIONID=" + getCookie(user, pwd));
+ }
+
+ httpClient.executeMethod(postMethod);
+
+ LOG.info("{} - {}", postMethod.getStatusCode(), postMethod.getStatusText());
+
+ return postMethod;
+ }
+
+ protected static PutMethod httpPut(String path, String body) throws IOException {
+ return httpPut(path, body, StringUtils.EMPTY, StringUtils.EMPTY);
+ }
+
+ protected static PutMethod httpPut(String path, String body, String user, String pwd) throws IOException {
+ LOG.info("Connecting to {}", URL + path);
+ HttpClient httpClient = new HttpClient();
+ PutMethod putMethod = new PutMethod(URL + path);
+ putMethod.addRequestHeader("Origin", URL);
+ putMethod.setRequestHeader("Content-type", "application/yaml");
+ RequestEntity entity = new ByteArrayRequestEntity(body.getBytes("UTF-8"));
+ putMethod.setRequestEntity(entity);
+ if (userAndPasswordAreNotBlank(user, pwd)) {
+ putMethod.setRequestHeader("Cookie", "JSESSIONID=" + getCookie(user, pwd));
+ }
+ httpClient.executeMethod(putMethod);
+ LOG.info("{} - {}", putMethod.getStatusCode(), putMethod.getStatusText());
+ return putMethod;
+ }
+
+ protected static DeleteMethod httpDelete(String path) throws IOException {
+ return httpDelete(path, StringUtils.EMPTY, StringUtils.EMPTY);
+ }
+
+ protected static DeleteMethod httpDelete(String path, String user, String pwd) throws IOException {
+ LOG.info("Connecting to {}", URL + path);
+ HttpClient httpClient = new HttpClient();
+ DeleteMethod deleteMethod = new DeleteMethod(URL + path);
+ deleteMethod.addRequestHeader("Origin", URL);
+ if (userAndPasswordAreNotBlank(user, pwd)) {
+ deleteMethod.setRequestHeader("Cookie", "JSESSIONID=" + getCookie(user, pwd));
+ }
+ httpClient.executeMethod(deleteMethod);
+ LOG.info("{} - {}", deleteMethod.getStatusCode(), deleteMethod.getStatusText());
+ return deleteMethod;
+ }
+
+ protected static GetMethod httpGet(String path) throws IOException {
+ return httpGet(path, "", "");
+ }
+
+ protected static GetMethod httpGet(String path, String user, String pwd) throws IOException {
+ return httpGet(path, user, pwd, "");
+ }
+
+ protected static GetMethod httpGet(String path, String user, String pwd, String cookies)
+ throws IOException {
+ LOG.info("Connecting to {}", URL + path);
+ HttpClient httpClient = new HttpClient();
+ GetMethod getMethod = new GetMethod(URL + path);
+ getMethod.addRequestHeader("Origin", URL);
+ httpClient.executeMethod(getMethod);
+ LOG.info("{} - {}", getMethod.getStatusCode(), getMethod.getStatusText());
+ return getMethod;
+ }
+
+ protected static boolean checkIfServerIsRunning() {
+ GetMethod request = null;
+ boolean isRunning = false;
+ try {
+ request = httpGet("/");
+ isRunning = request.getStatusCode() == 200;
+ } catch (IOException e) {
+ LOG.warn("AbstractTestRestApi.checkIfServerIsRunning() fails .. " +
+ "Submarine server is not running");
+ isRunning = false;
+ } finally {
+ if (request != null) {
+ request.releaseConnection();
+ }
+ }
+ return isRunning;
+ }
+
+ private static String getCookie(String user, String password) throws IOException {
+ HttpClient httpClient = new HttpClient();
+ PostMethod postMethod = new PostMethod(URL + "/login");
+ postMethod.addRequestHeader("Origin", URL);
+ postMethod.setParameter("password", password);
+ postMethod.setParameter("userName", user);
+ httpClient.executeMethod(postMethod);
+ LOG.info("{} - {}", postMethod.getStatusCode(), postMethod.getStatusText());
+ Pattern pattern = Pattern.compile("JSESSIONID=([a-zA-Z0-9-]*)");
+ Header[] setCookieHeaders = postMethod.getResponseHeaders("Set-Cookie");
+ String jsessionId = null;
+ for (Header setCookie : setCookieHeaders) {
+ java.util.regex.Matcher matcher = pattern.matcher(setCookie.toString());
+ if (matcher.find()) {
+ jsessionId = matcher.group(1);
+ }
+ }
+
+ if (jsessionId != null) {
+ return jsessionId;
+ } else {
+ return StringUtils.EMPTY;
+ }
+ }
+
+ protected static boolean userAndPasswordAreNotBlank(String user, String pwd) {
+ if (StringUtils.isBlank(user) && StringUtils.isBlank(pwd)) {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/submarine-test/test-k8s/src/test/java/org/apache/submarine/rest/ClusterIT.java b/submarine-test/test-k8s/src/test/java/org/apache/submarine/rest/ClusterIT.java
new file mode 100644
index 0000000..b3798d4
--- /dev/null
+++ b/submarine-test/test-k8s/src/test/java/org/apache/submarine/rest/ClusterIT.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.submarine.rest;
+
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.junit.Assert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ClusterIT extends AbstractSubmarineServerTest {
+ public final static Logger LOG = LoggerFactory.getLogger(ClusterIT.class);
+
+ @BeforeClass
+ public static void startUp(){
+ Assert.assertTrue(checkIfServerIsRunning());
+ }
+
+ @Test
+ public void getClusterAddress() throws Exception {
+ GetMethod get = httpGet("/api/v1/cluster/address");
+ Assert.assertEquals(200, get.getStatusCode());
+ String body = get.getResponseBodyAsString();
+ LOG.info("body = {}", body);
+ }
+
+ @Test
+ public void getClusterNodes() throws Exception {
+ GetMethod get = httpGet("/api/v1/cluster/nodes");
+ Assert.assertEquals(200, get.getStatusCode());
+ String body = get.getResponseBodyAsString();
+ LOG.info("body = {}", body);
+ }
+}
diff --git a/submarine-test/test-k8s/src/test/resources/log4j.properties b/submarine-test/test-k8s/src/test/resources/log4j.properties
new file mode 100644
index 0000000..7ad6f5f
--- /dev/null
+++ b/submarine-test/test-k8s/src/test/resources/log4j.properties
@@ -0,0 +1,24 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+
+# Root logger option
+log4j.rootLogger=INFO, stdout
+
+# Direct log messages to stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %-5p [%t]: %c{2} (%F:%M(%L)) - %m%n
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@submarine.apache.org
For additional commands, e-mail: dev-help@submarine.apache.org