Add integration tests
These tests are small Spring Cloud Kubernetes application that are deployed inside a Kubernetes cluster launched with microk8s. The deployment of the applications is done with the Fabric8 Maven Plugin
This commit is contained in:
committed by
Ioannis Canellos
parent
9504dc56ee
commit
9f02f7e753
@@ -20,8 +20,7 @@ jobs:
|
||||
branches:
|
||||
ignore:
|
||||
- gh-pages
|
||||
docker:
|
||||
- image: circleci/openjdk:8-jdk-node-browsers
|
||||
machine: true
|
||||
environment:
|
||||
_JAVA_OPTIONS: "-Xms1024m -Xmx2048m"
|
||||
_SERVICE_OCCURENCE: 5
|
||||
@@ -41,13 +40,57 @@ jobs:
|
||||
- ~/.m2
|
||||
key: spring-cloud-kubernetes-{{ .Branch }}-{{ checksum "pom.xml" }}
|
||||
- run:
|
||||
name: test
|
||||
name: Run regular tests
|
||||
command: |
|
||||
./mvnw -s .settings.xml clean install -Dservice.occurence=${_SERVICE_OCCURENCE} #org.jacoco:jacoco-maven-plugin:prepare-agent install -U -P sonar -nsu --batch-mode -Dmaven.test.redirectTestOutputToFile=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
|
||||
mkdir -p $HOME/artifacts/junit/
|
||||
find . -type f -regex ".*/spring-cloud-*.*/target/*.*" -exec cp {} $HOME/artifacts/ \;
|
||||
find . -type f -regex ".*/target/.*-reports/.*" -exec cp {} $HOME/artifacts/junit/ \;
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
- run:
|
||||
name: Install Snap
|
||||
command: |
|
||||
sudo apt update
|
||||
sudo apt install snapd
|
||||
- run:
|
||||
name: Launch Kubernetes with microk8s
|
||||
command: |
|
||||
sudo snap install microk8s --classic --channel=1.11/stable
|
||||
|
||||
# wait until a k8s node is ready
|
||||
sleep 10
|
||||
n=0
|
||||
until [ $n -ge 10 ]
|
||||
do
|
||||
(/snap/bin/microk8s.kubectl get no | grep -z "Ready") && break
|
||||
n=$[$n+1]
|
||||
sleep 20
|
||||
done
|
||||
|
||||
echo "Kubernetes cluster launched"
|
||||
|
||||
# Allow intra-pod communication
|
||||
sudo iptables -P FORWARD ACCEPT
|
||||
|
||||
/snap/bin/microk8s.enable dns registry
|
||||
|
||||
# wait until the registry is up and running
|
||||
sleep 10
|
||||
n=0
|
||||
until [ $n -ge 10 ]
|
||||
do
|
||||
(/snap/bin/microk8s.kubectl get pod --namespace=container-registry | grep -z "Running") && break
|
||||
n=$[$n+1]
|
||||
sleep 10
|
||||
done
|
||||
|
||||
echo "Kubernetes Container Registry enabled"
|
||||
- run:
|
||||
name: Run integration tests
|
||||
command: |
|
||||
cd spring-cloud-kubernetes-integration-tests
|
||||
/snap/bin/microk8s.kubectl config view --raw > /tmp/kubeconfig
|
||||
./deploy_test_undeploy_all.sh
|
||||
- store_test_results:
|
||||
path: $HOME/artifacts/junit/
|
||||
- store_artifacts:
|
||||
@@ -55,4 +98,3 @@ jobs:
|
||||
notify:
|
||||
webhooks:
|
||||
- url: https://webhooks.gitter.im/e/22e6bb4eb945dd61ba54
|
||||
|
||||
|
||||
4
pom.xml
4
pom.xml
@@ -71,6 +71,7 @@
|
||||
<fabric8.maven.plugin.version>3.5.37</fabric8.maven.plugin.version>
|
||||
<gmavenplus-plugin.version>1.6</gmavenplus-plugin.version>
|
||||
<groovy.version>2.4.12</groovy.version>
|
||||
<restassured.version>3.0.2</restassured.version>
|
||||
<spock-spring.version>1.1-groovy-2.4</spock-spring.version>
|
||||
</properties>
|
||||
|
||||
@@ -86,12 +87,13 @@
|
||||
<module>spring-cloud-starter-kubernetes-all</module>
|
||||
<module>spring-cloud-kubernetes-examples</module>
|
||||
<module>spring-cloud-kubernetes-leader</module>
|
||||
<module>spring-cloud-kubernetes-integration-tests</module>
|
||||
<module>docs</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes-dependencies</artifactId>
|
||||
|
||||
108
spring-cloud-kubernetes-integration-tests/README.md
Normal file
108
spring-cloud-kubernetes-integration-tests/README.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# Purpose
|
||||
|
||||
Demonstrate how integration tests can be run against a local cluster setup with [microk8s](https://microk8s.io/)
|
||||
The Kubernetes resources necessary to get the test application
|
||||
onto the cluster are created using the [Fabric8 Maven Plugin](https://maven.fabric8.io/)
|
||||
|
||||
# Instructions
|
||||
|
||||
## Install microk8s
|
||||
|
||||
```bash
|
||||
sudo snap install microk8s --classic --channel=1.11/stable
|
||||
sleep 10
|
||||
microk8s.enable dns registry
|
||||
```
|
||||
|
||||
Ensure everything is running by inspecting the output of:
|
||||
|
||||
```bash
|
||||
microk8s.kubectl get all --all-namespaces
|
||||
```
|
||||
|
||||
It should look something like:
|
||||
|
||||
```
|
||||
NAMESPACE NAME READY STATUS RESTARTS AGE
|
||||
container-registry pod/registry-6bc95dfd76-274lc 1/1 Running 0 40s
|
||||
kube-system pod/hostpath-provisioner-9979c7f64-f96tw 1/1 Running 0 41s
|
||||
kube-system pod/kube-dns-864b8bdc77-68kmn 2/3 Running 0 41s
|
||||
|
||||
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
container-registry service/registry NodePort 10.152.183.175 <none> 5000:32000/TCP 50s
|
||||
default service/kubernetes ClusterIP 10.152.183.1 <none> 443/TCP 1m
|
||||
kube-system service/kube-dns ClusterIP 10.152.183.10 <none> 53/UDP,53/TCP 56s
|
||||
|
||||
NAMESPACE NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
container-registry deployment.apps/registry 1 1 1 1 50s
|
||||
kube-system deployment.apps/hostpath-provisioner 1 1 1 1 51s
|
||||
kube-system deployment.apps/kube-dns 1 1 1 0 56s
|
||||
|
||||
NAMESPACE NAME DESIRED CURRENT READY AGE
|
||||
container-registry replicaset.apps/registry-6bc95dfd76 1 1 1 41s
|
||||
kube-system replicaset.apps/hostpath-provisioner-9979c7f64 1 1 1 41s
|
||||
kube-system replicaset.apps/kube-dns-864b8bdc77 1 1 0 41s
|
||||
```
|
||||
|
||||
## Setup environment for FMP to work
|
||||
|
||||
One premise for the Fabric8 Maven Plugin to work is that is can read the proper Kubernetes Config file.
|
||||
We export the corresponding config file for the cluster microk8s sets up to temp file which will
|
||||
be used later
|
||||
|
||||
```bash
|
||||
microk8s.kubectl config view --raw > /tmp/kubeconfig
|
||||
```
|
||||
|
||||
## Deploy application
|
||||
|
||||
**The following commands assume that they are executed inside the maven module of each specific test**
|
||||
|
||||
Since FMP is based on the Fabric8 Kubernetes Client, we can leverage the `KUBECONFIG` environment variable
|
||||
to make FMP aware of the Kubernetes Config file we created above
|
||||
|
||||
```bash
|
||||
export KUBECONFIG=/tmp/kubeconfig
|
||||
../../mvnw clean package fabric8:build fabric8:push fabric8:deploy -Pfmp
|
||||
```
|
||||
|
||||
Make sure the application was deployed be executing:
|
||||
|
||||
```bash
|
||||
microk8s.kubectl get pod -l app=sb-fmp-microk8s
|
||||
```
|
||||
|
||||
It should look something like:
|
||||
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
simple-core-5fbb7646dc-66t7b 1/1 Running 0 57s
|
||||
```
|
||||
|
||||
The integration tests can be run against the service which is deployed inside the cluster by executing:
|
||||
|
||||
```bash
|
||||
../../mvnw verify -Pfmp,it -Dfabric8.skip
|
||||
```
|
||||
|
||||
This integration tests runs locally (making it easily debuggable), and interacts with the deployed service
|
||||
using the exposed port.
|
||||
By leveraging [Aquillian Cube Kubernetes](http://arquillian.org/arquillian-cube/#_kubernetes), it's able to setup and teardown resources needed for each test
|
||||
|
||||
To undeploy the application from the cluster simply execute:
|
||||
|
||||
```bash
|
||||
../../mvnw fabric8:undeploy -Pfmp
|
||||
```
|
||||
|
||||
## Run all tests
|
||||
|
||||
By executing
|
||||
|
||||
```bash
|
||||
deploy_test_undeploy_all.sh
|
||||
```
|
||||
|
||||
each one of the test applications will be deployed to the cluster and the integration tests will be executed
|
||||
|
||||
|
||||
13
spring-cloud-kubernetes-integration-tests/deploy_test_undeploy_all.sh
Executable file
13
spring-cloud-kubernetes-integration-tests/deploy_test_undeploy_all.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
# The script launches and tests each test application - one at a time
|
||||
|
||||
for D in $(find . -maxdepth 1 -mindepth 1 -not -path '*/\.*' -type d); do
|
||||
pushd ${D} > /dev/null
|
||||
../deploy_test_undeploy_single.sh
|
||||
/snap/bin/microk8s.kubectl wait --for=delete pod -l group=org.springframework.cloud --timeout=60s > /dev/null
|
||||
popd > /dev/null
|
||||
done
|
||||
|
||||
27
spring-cloud-kubernetes-integration-tests/deploy_test_undeploy_single.sh
Executable file
27
spring-cloud-kubernetes-integration-tests/deploy_test_undeploy_single.sh
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
# The script assumes that there is only one application deployed by FMP running at a time
|
||||
|
||||
SCRIPT_ABSOLUTE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
mvnCmd="${SCRIPT_ABSOLUTE_DIR}"/../mvnw
|
||||
kubectlCmd=/snap/bin/microk8s.kubectl
|
||||
|
||||
export KUBECONFIG=/tmp/kubeconfig
|
||||
|
||||
echo "Starting application deployment to cluster"
|
||||
$mvnCmd clean package fabric8:build fabric8:push fabric8:deploy -Pfmp
|
||||
echo "Finished deployment"
|
||||
|
||||
echo "Waiting for pod to become Ready"
|
||||
# We are leveraging the fact the fact that FMP adds the group label and the fact that only one
|
||||
# application can be running at a time
|
||||
$kubectlCmd wait --for=condition=Ready pod -l group=org.springframework.cloud --timeout=60s > /dev/null
|
||||
|
||||
echo "Starting the integration tests"
|
||||
$mvnCmd verify -Pfmp,it -Dfabric8.skip
|
||||
|
||||
echo "Successfully executed integration tests"
|
||||
echo "Undeploying application"
|
||||
$mvnCmd fabric8:undeploy -Pfmp
|
||||
140
spring-cloud-kubernetes-integration-tests/pom.xml
Normal file
140
spring-cloud-kubernetes-integration-tests/pom.xml
Normal file
@@ -0,0 +1,140 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>spring-cloud-kubernetes-integration-tests</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Spring Cloud Kubernetes :: Integration Tests</name>
|
||||
<description>Integration tests where SCK applications are run inside a Kubernetes cluster
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<fmp.version>3.5.42</fmp.version>
|
||||
<arquillian-cube.version>1.18.2</arquillian-cube.version>
|
||||
<arquillian.version>1.4.0.Final</arquillian.version>
|
||||
<rest-assured.version>3.2.0</rest-assured.version>
|
||||
|
||||
<!-- We use the unix socket where microk8s' docker daemon listens -->
|
||||
<docker.host>unix:///var/snap/microk8s/current/docker.sock</docker.host>
|
||||
|
||||
<!-- This is the default location of the container registry that comes with microk8s -->
|
||||
<microk8s.registry>localhost:32000</microk8s.registry>
|
||||
|
||||
<!--
|
||||
The port on localhost where the application will listen to from outside the cluster
|
||||
Will be used to construct a NodePort
|
||||
-->
|
||||
<nodeport.value>32222</nodeport.value>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>${maven-deploy-plugin.version}</version>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>fmp</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>io.fabric8</groupId>
|
||||
<artifactId>fabric8-maven-plugin</artifactId>
|
||||
<version>${fmp.version}</version>
|
||||
<configuration>
|
||||
<!--
|
||||
FMP can work with Openshift as well, so here we explicitly force it
|
||||
to work with vanilla Kubernetes and Docker builds
|
||||
-->
|
||||
<buildStrategy>docker</buildStrategy>
|
||||
<mode>kubernetes</mode>
|
||||
<pushRegistry>${microk8s.registry}</pushRegistry>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>fabric8</id>
|
||||
<goals>
|
||||
<goal>resource</goal>
|
||||
<goal>build</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>it</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<service.host>localhost</service.host>
|
||||
<service.port>${nodeport.value}</service.port>
|
||||
</systemPropertyVariables>
|
||||
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jboss.arquillian</groupId>
|
||||
<artifactId>arquillian-bom</artifactId>
|
||||
<version>${arquillian.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<version>${rest-assured.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<modules>
|
||||
<module>simple-core</module>
|
||||
<module>simple-configmap</module>
|
||||
</modules>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes-integration-tests</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<name>Spring Cloud Kubernetes :: Integration Tests :: Simple Configmap</name>
|
||||
<artifactId>simple-configmap</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-kubernetes-config</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.arquillian.cube</groupId>
|
||||
<artifactId>arquillian-cube-kubernetes</artifactId>
|
||||
<version>${arquillian-cube.version}</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>undertow-core</artifactId>
|
||||
<groupId>io.undertow</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.arquillian.junit</groupId>
|
||||
<artifactId>arquillian-junit-standalone</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,10 @@
|
||||
# We need this fragment in order for the kubernetes client to talk to
|
||||
# the Kubernetes API without caring about proper certificates
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: KUBERNETES_TRUST_CERTIFICATES
|
||||
value: true
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# We are using an FMP fragment to ensure that NodePort is used correctly
|
||||
spec:
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8080
|
||||
nodePort: ${nodeport.value}
|
||||
type: NodePort
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.cloud.kubernetes.it;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties(prefix = "config")
|
||||
public class DummyConfig {
|
||||
|
||||
private String message = "This is a dummy message";
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.springframework.cloud.kubernetes.it;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@SpringBootApplication
|
||||
@RestController
|
||||
@EnableConfigurationProperties(DummyConfig.class)
|
||||
public class SimpleConfigMapApplication {
|
||||
|
||||
@Autowired
|
||||
private DummyConfig dummyConfig;
|
||||
|
||||
@GetMapping("/greeting")
|
||||
public Greeting greeting() {
|
||||
return new Greeting(dummyConfig.getMessage());
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SimpleConfigMapApplication.class, args);
|
||||
}
|
||||
|
||||
public static class Greeting {
|
||||
|
||||
private final String message;
|
||||
|
||||
public Greeting(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
server:
|
||||
port: 8080
|
||||
|
||||
# we enable some of the management endpoints to make it possible to restart the application
|
||||
management:
|
||||
endpoint:
|
||||
restart:
|
||||
enabled: true
|
||||
health:
|
||||
enabled: true
|
||||
info:
|
||||
enabled: true
|
||||
@@ -0,0 +1,14 @@
|
||||
spring:
|
||||
application:
|
||||
name: sck-example
|
||||
cloud:
|
||||
kubernetes:
|
||||
# enable reloading of the application when on the property sources has changed
|
||||
reload:
|
||||
enabled: true
|
||||
mode: polling
|
||||
period: 5000
|
||||
config:
|
||||
sources:
|
||||
- name: ${spring.application.name}
|
||||
namespace: default
|
||||
@@ -0,0 +1,52 @@
|
||||
package org.springframework.cloud.kubernetes.it;
|
||||
|
||||
import static io.restassured.RestAssured.given;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
|
||||
import org.arquillian.cube.kubernetes.annotations.KubernetesResource;
|
||||
import org.arquillian.cube.kubernetes.impl.requirement.RequiresKubernetes;
|
||||
import org.jboss.arquillian.junit.Arquillian;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.MethodSorters;
|
||||
|
||||
@RequiresKubernetes
|
||||
@RunWith(Arquillian.class)
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class GreetingIT {
|
||||
|
||||
private static final String HOST = System.getProperty("service.host");
|
||||
private static final Integer PORT = Integer.valueOf(System.getProperty("service.port"));
|
||||
|
||||
@Test
|
||||
public void firstTestThatTheDefaultMessageIsReturned() {
|
||||
given()
|
||||
.baseUri(String.format("http://%s:%d", HOST, PORT))
|
||||
.get("greeting")
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.body("message", is("This is a dummy message"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@KubernetesResource("classpath:config-map.yml")
|
||||
public void thenApplyAConfigMapAndEnsureThatTheMessageIsUpdated() {
|
||||
waitForApplicationToReload();
|
||||
|
||||
given()
|
||||
.baseUri(String.format("http://%s:%d", HOST, PORT))
|
||||
.get("greeting")
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.body("message", is("Hello from Spring Cloud Kubernetes!"));
|
||||
}
|
||||
|
||||
private void waitForApplicationToReload() {
|
||||
try {
|
||||
Thread.sleep(15000);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://jboss.org/schema/arquillian"
|
||||
xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
|
||||
|
||||
<extension qualifier="kubernetes">
|
||||
<property name="namespace.use.existing">default</property>
|
||||
|
||||
<!-- Make sure Arquillian Cube does not setup or take down the application -->
|
||||
<property name="env.init.enabled">false</property>
|
||||
<property name="namespace.cleanup.enabled">false</property>
|
||||
</extension>
|
||||
|
||||
</arquillian>
|
||||
@@ -0,0 +1,6 @@
|
||||
spring:
|
||||
application:
|
||||
name: sck-example
|
||||
cloud:
|
||||
kubernetes:
|
||||
enabled: false
|
||||
@@ -0,0 +1,8 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: sck-example
|
||||
data:
|
||||
application.properties: |-
|
||||
config.message=Hello from Spring Cloud Kubernetes!
|
||||
another.property=value
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<include resource="org/springframework/boot/logging/logback/base.xml" />
|
||||
<logger name="org.hibernate.validator" level="info" /> <!-- Validator prints a lot of debug messages during integration tests -->
|
||||
</configuration>
|
||||
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes-integration-tests</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<name>Spring Cloud Kubernetes :: Integration Tests :: Simple Core</name>
|
||||
<artifactId>simple-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-kubernetes-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.arquillian.cube</groupId>
|
||||
<artifactId>arquillian-cube-kubernetes</artifactId>
|
||||
<version>${arquillian-cube.version}</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>undertow-core</artifactId>
|
||||
<groupId>io.undertow</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.arquillian.junit</groupId>
|
||||
<artifactId>arquillian-junit-standalone</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,10 @@
|
||||
# We need this fragment in order for the kubernetes client to talk to
|
||||
# the Kubernetes API without caring about proper certificates
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: KUBERNETES_TRUST_CERTIFICATES
|
||||
value: true
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
# we are using an FMP fragment to ensure that NodePort is used correctly
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: ${project.artifactId}
|
||||
labels:
|
||||
app: ${project.artifactId}
|
||||
spec:
|
||||
selector:
|
||||
app: ${project.artifactId}
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8080
|
||||
nodePort: ${nodeport.value}
|
||||
type: NodePort
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.springframework.cloud.kubernetes.it;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@SpringBootApplication
|
||||
@RestController
|
||||
public class SimpleCoreApplication {
|
||||
|
||||
@GetMapping("/greeting")
|
||||
public Greeting home() {
|
||||
return new Greeting("Hello Spring Boot");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SimpleCoreApplication.class, args);
|
||||
}
|
||||
|
||||
public static class Greeting {
|
||||
|
||||
private final String message;
|
||||
|
||||
public Greeting(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
server:
|
||||
port: 8080
|
||||
|
||||
# we enable some of the management endpoints to make it possible to restart the application
|
||||
management:
|
||||
endpoint:
|
||||
health:
|
||||
enabled: true
|
||||
show-details: always
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.springframework.cloud.kubernetes.it;
|
||||
|
||||
import static io.restassured.RestAssured.given;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
|
||||
import org.arquillian.cube.kubernetes.impl.requirement.RequiresKubernetes;
|
||||
import org.jboss.arquillian.junit.Arquillian;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RequiresKubernetes
|
||||
@RunWith(Arquillian.class)
|
||||
public class GreetingAndHealthIT {
|
||||
|
||||
private static final String HOST = System.getProperty("service.host");
|
||||
private static final Integer PORT = Integer.valueOf(System.getProperty("service.port"));
|
||||
|
||||
@Test
|
||||
public void testGreetingEndpoint() {
|
||||
given()
|
||||
.baseUri(String.format("http://%s:%d", HOST, PORT))
|
||||
.get("greeting")
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.body("message", is("Hello Spring Boot"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHealthEndpoint() {
|
||||
given()
|
||||
.baseUri(String.format("http://%s:%d", HOST, PORT))
|
||||
.contentType("application/json")
|
||||
.get("actuator/health")
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.body("details.kubernetes.details.inside", is(true));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://jboss.org/schema/arquillian"
|
||||
xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
|
||||
|
||||
<extension qualifier="kubernetes">
|
||||
<property name="namespace.use.existing">default</property>
|
||||
|
||||
<!-- Make sure Arquillian Cube does not make any modification to the environment -->
|
||||
<property name="env.init.enabled">false</property>
|
||||
<property name="namespace.cleanup.enabled">false</property>
|
||||
</extension>
|
||||
|
||||
</arquillian>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<include resource="org/springframework/boot/logging/logback/base.xml" />
|
||||
<logger name="org.hibernate.validator" level="info" /> <!-- Validator prints a lot of debug messages during integration tests -->
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user