Skip to content

Commit 5e11184

Browse files
authored
Script to run new integration tests against a "kind" cluster (#1626)
* Run new integration tests with Kind * Mark as executable * Fix typos * Work in progress * Improved Docker registry * Restory worker * Set JAVA_HOME variable if missing * Support WIT specific JAVA_HOME * Support different versions and review comments * Update other file * Fix grep * Review comments * Show how to install * Use kubeconfig option * Clarify how to access cluster * Use kubeconfig option for delete * Fix up NGINX test * Add test filter option * Remove unnecessary directories
1 parent 372ffa8 commit 5e11184

File tree

8 files changed

+243
-18
lines changed

8 files changed

+243
-18
lines changed

kindtest.sh

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
#!/bin/bash
2+
# Copyright (c) 2020, Oracle Corporation and/or its affiliates.
3+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
4+
#
5+
# This script provisions a Kubernetes cluster using Kind (https://kind.sigs.k8s.io/) and runs the new
6+
# integration test suite against that cluster.
7+
#
8+
# To install Kind:
9+
# curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.8.0/kind-$(uname)-amd64
10+
# chmod +x ./kind
11+
# mv ./kind /some-dir-in-your-PATH/kind
12+
#
13+
# Kind creates Kubernetes nodes on your local box by running each node as a Docker container. This
14+
# makes it very easy to setup and tear down clusters. Presently, this script creates a cluster with a
15+
# master node and a worker node. Each node will run the same Kubernetes version. Future enhancements to
16+
# this script could allow for the configuration of a different number of nodes or for nodes to run a
17+
# differing set of Kubernetes versions.
18+
#
19+
# Kind nodes do not have access to the Docker repository on the local machine. Therefore this script works
20+
# around this limitation by running a Docker registry in a Docker container and connecting the networks so
21+
# that the Kubernetes nodes have visibility to the registry. When you run tests, you will see that Docker
22+
# images are pushed to this local registry and then are pulled to the Kubernetes nodes as needed.
23+
# You can see the images on a node by running: "docker exec -it kind-worker crictl images" where kind-worker
24+
# is the name of the Docker container.
25+
#
26+
# As of May 6, 2020, the tests are clean on Kubernetes 1.16 with the following JDK workarounds:
27+
# 1. Maven must be run with OpenJDK 11.0.7, available here: https://github.com/AdoptOpenJDK/openjdk11-upstream-binaries/releases/download/jdk-11.0.7%2B10/OpenJDK11U-jdk_x64_linux_11.0.7_10.tar.gz
28+
# This is because of a critical bug fix. Unfortunately, the Oracle JDK 11.0.7 release was based on an earlier build and doesn't have the fix.
29+
# 2. The WebLogic Image Tool will not accept an OpenJDK JDK. Set WIT_JAVA_HOME to an Oracle JDK Java Home.
30+
# For example, "export WIT_JAVA_HOME=/usr/java/jdk-11.0.7" before running this script.
31+
#
32+
# If you want to access the cluster, use "kubectl cluster-info --context kind-kind" where the trailing "kind" is the value of the "-n" argument.
33+
set -o errexit
34+
35+
script="${BASH_SOURCE[0]}"
36+
scriptDir="$( cd "$( dirname "${script}" )" && pwd )"
37+
38+
function usage {
39+
echo "usage: ${script} [-v <version>] [-n <name>] [-o <directory>] [-t <tests>] [-h]"
40+
echo " -v Kubernetes version (optional) "
41+
echo " (default: 1.15.11, supported values: 1.18, 1.18.2, 1.17, 1.17.5, 1.16, 1.16.9, 1.15, 1.15.11, 1.14, 1.14.10) "
42+
echo " -n Kind cluster name (optional) "
43+
echo " (default: kind) "
44+
echo " -o Output directory (optional) "
45+
echo " (default: \${WORKSPACE}/logdir/\${BUILD_TAG}, if \${WORKSPACE} defined, else /scratch/\${USER}/kindtest) "
46+
echo " -t Test filter (optional) "
47+
echo " (default: **/It*) "
48+
echo " -h Help"
49+
exit $1
50+
}
51+
52+
k8s_version="1.15.11"
53+
kind_name="kind"
54+
if [[ -z "${WORKSPACE}" ]]; then
55+
outdir="/scratch/${USER}/kindtest"
56+
else
57+
outdir="${WORKSPACE}/logdir/${BUILD_TAG}"
58+
fi
59+
test_filter="**/It*"
60+
61+
while getopts ":h:n:o:t:v:" opt; do
62+
case $opt in
63+
v) k8s_version="${OPTARG}"
64+
;;
65+
n) kind_name="${OPTARG}"
66+
;;
67+
o) outdir="${OPTARG}"
68+
;;
69+
t) test_filter="${OPTARG}"
70+
;;
71+
h) usage 0
72+
;;
73+
*) usage 1
74+
;;
75+
esac
76+
done
77+
78+
function versionprop {
79+
grep "${1}=" "${scriptDir}/kindversions.properties"|cut -d'=' -f2
80+
}
81+
82+
kind_image=$(versionprop "${k8s_version}")
83+
if [ -z "${kind_image}" ]; then
84+
echo "Unsupported Kubernetes version: ${k8s_version}"
85+
exit 1
86+
fi
87+
88+
echo "Using Kubernetes version: ${k8s_version}"
89+
90+
mkdir -m777 -p "${outdir}"
91+
export RESULT_ROOT="${outdir}/wl_k8s_test_results"
92+
if [ -d "${RESULT_ROOT}" ]; then
93+
rm -Rf "${RESULT_ROOT}/*"
94+
else
95+
mkdir -m777 "${RESULT_ROOT}"
96+
fi
97+
98+
echo "Results will be in ${RESULT_ROOT}"
99+
100+
export PV_ROOT="${outdir}/k8s-pvroot"
101+
if [ -d "${PV_ROOT}" ]; then
102+
rm -Rf "${PV_ROOT}/*"
103+
else
104+
mkdir -m777 "${PV_ROOT}"
105+
fi
106+
107+
echo "Persistent volume files, if any, will be in ${PV_ROOT}"
108+
109+
echo 'Remove old cluster (if any)...'
110+
kind delete cluster --name ${kind_name} --kubeconfig "${RESULT_ROOT}/kubeconfig"
111+
112+
kind_version=$(kind version)
113+
kind_network='kind'
114+
reg_name='kind-registry'
115+
reg_port='5000'
116+
case "${kind_version}" in
117+
"kind v0.7."* | "kind v0.6."* | "kind v0.5."*)
118+
kind_network='bridge'
119+
;;
120+
esac
121+
122+
echo 'Create registry container unless it already exists'
123+
running="$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)"
124+
if [ "${running}" != 'true' ]; then
125+
docker run \
126+
-d --restart=always -p "${reg_port}:5000" --name "${reg_name}" \
127+
registry:2
128+
fi
129+
130+
reg_host="${reg_name}"
131+
if [ "${kind_network}" = "bridge" ]; then
132+
reg_host="$(docker inspect -f '{{.NetworkSettings.IPAddress}}' "${reg_name}")"
133+
fi
134+
echo "Registry Host: ${reg_host}"
135+
136+
echo 'Create a cluster with the local registry enabled in containerd'
137+
cat <<EOF | kind create cluster --name "${kind_name}" --kubeconfig "${RESULT_ROOT}/kubeconfig" --config=-
138+
kind: Cluster
139+
apiVersion: kind.x-k8s.io/v1alpha4
140+
containerdConfigPatches:
141+
- |-
142+
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:${reg_port}"]
143+
endpoint = ["http://${reg_host}:${reg_port}"]
144+
nodes:
145+
- role: control-plane
146+
image: ${kind_image}
147+
- role: worker
148+
image: ${kind_image}
149+
extraMounts:
150+
- hostPath: ${PV_ROOT}
151+
containerPath: ${PV_ROOT}
152+
EOF
153+
154+
echo "Access your cluster in other terminals with:"
155+
echo " export KUBECONFIG=\"${RESULT_ROOT}/kubeconfig\""
156+
echo " kubectl cluster-info --context \"kind-${kind_name}\""
157+
export KUBECONFIG="${RESULT_ROOT}/kubeconfig"
158+
kubectl cluster-info --context "kind-${kind_name}"
159+
kubectl get node -o wide
160+
161+
for node in $(kind get nodes --name "${kind_name}"); do
162+
kubectl annotate node "${node}" tilt.dev/registry=localhost:${reg_port};
163+
done
164+
165+
if [ "${kind_network}" != "bridge" ]; then
166+
containers=$(docker network inspect ${kind_network} -f "{{range .Containers}}{{.Name}} {{end}}")
167+
needs_connect="true"
168+
for c in ${containers}; do
169+
if [ "$c" = "${reg_name}" ]; then
170+
needs_connect="false"
171+
fi
172+
done
173+
if [ "${needs_connect}" = "true" ]; then
174+
docker network connect "${kind_network}" "${reg_name}" || true
175+
fi
176+
fi
177+
178+
echo 'Set up test running ENVVARs...'
179+
export KIND_REPO="localhost:${reg_port}/"
180+
export K8S_NODEPORT_HOST=`kubectl get node kind-worker -o jsonpath='{.status.addresses[?(@.type == "InternalIP")].address}'`
181+
export JAVA_HOME="${JAVA_HOME:-`type -p java|xargs readlink -f|xargs dirname|xargs dirname`}"
182+
183+
echo 'Clean up result root...'
184+
rm -rf "${RESULT_ROOT:?}/*"
185+
186+
echo 'Run tests...'
187+
time mvn -Dit.test="${test_filter}" -pl new-integration-tests -P integration-tests verify 2>&1 | tee "${RESULT_ROOT}/kindtest.log"

kindversions.properties

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright (c) 2020, Oracle Corporation and/or its affiliates.
2+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
3+
1.18=kindest/node:v1.18.2@sha256:7b27a6d0f2517ff88ba444025beae41491b016bc6af573ba467b70c5e8e0d85f
4+
1.18.2=kindest/node:v1.18.2@sha256:7b27a6d0f2517ff88ba444025beae41491b016bc6af573ba467b70c5e8e0d85f
5+
1.17=kindest/node:v1.17.5@sha256:ab3f9e6ec5ad8840eeb1f76c89bb7948c77bbf76bcebe1a8b59790b8ae9a283a
6+
1.17.5=kindest/node:v1.17.5@sha256:ab3f9e6ec5ad8840eeb1f76c89bb7948c77bbf76bcebe1a8b59790b8ae9a283a
7+
1.16=kindest/node:v1.16.9@sha256:7175872357bc85847ec4b1aba46ed1d12fa054c83ac7a8a11f5c268957fd5765
8+
1.16.9=kindest/node:v1.16.9@sha256:7175872357bc85847ec4b1aba46ed1d12fa054c83ac7a8a11f5c268957fd5765
9+
1.15=kindest/node:v1.15.11@sha256:6cc31f3533deb138792db2c7d1ffc36f7456a06f1db5556ad3b6927641016f50
10+
1.15.11=kindest/node:v1.15.11@sha256:6cc31f3533deb138792db2c7d1ffc36f7456a06f1db5556ad3b6927641016f50
11+
1.14=kindest/node:v1.14.10@sha256:6cd43ff41ae9f02bb46c8f455d5323819aec858b99534a290517ebc181b443c6
12+
1.14.10=kindest/node:v1.14.10@sha256:6cd43ff41ae9f02bb46c8f455d5323819aec858b99534a290517ebc181b443c6

new-integration-tests/src/test/java/oracle/weblogic/kubernetes/ItMiiDomain.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,12 +246,15 @@ public void testCreateMiiDomain() {
246246
// create image with model files
247247
miiImage = createImageAndVerify();
248248

249-
// push the image to OCIR to make the test work in multi node cluster
249+
// docker login, if necessary
250250
if (!REPO_USERNAME.equals(REPO_DUMMY_VALUE)) {
251251
logger.info("docker login");
252252
assertTrue(dockerLogin(REPO_REGISTRY, REPO_USERNAME, REPO_PASSWORD), "docker login failed");
253+
}
253254

254-
logger.info("docker push image {0} to OCIR", miiImage);
255+
// push image, if necessary
256+
if (!REPO_NAME.isEmpty()) {
257+
logger.info("docker push image {0} to {1}", miiImage, REPO_NAME);
255258
assertTrue(dockerPush(miiImage), String.format("docker push failed for image %s", miiImage));
256259
}
257260

@@ -545,7 +548,7 @@ private String createImageAndVerify() {
545548
Date date = new Date();
546549
final String imageTag = dateFormat.format(date) + "-" + System.currentTimeMillis();
547550
// Add repository name in image name for Jenkins runs
548-
final String imageName = REPO_USERNAME.equals(REPO_DUMMY_VALUE) ? MII_IMAGE_NAME : REPO_NAME + MII_IMAGE_NAME;
551+
final String imageName = REPO_NAME + MII_IMAGE_NAME;
549552
final String image = imageName + ":" + imageTag;
550553

551554
// build the model file list
@@ -564,6 +567,14 @@ private String createImageAndVerify() {
564567
Map<String, String> env = new HashMap<>();
565568
env.put("WLSIMG_BLDDIR", WIT_BUILD_DIR);
566569

570+
// For k8s 1.16 support and as of May 6, 2020, we presently need a different JDK for these
571+
// tests and for image tool. This is expected to no longer be necessary once JDK 11.0.8 or
572+
// the next JDK 14 versions are released.
573+
String witJavaHome = System.getenv("WIT_JAVA_HOME");
574+
if (witJavaHome != null) {
575+
env.put("JAVA_HOME", witJavaHome);
576+
}
577+
567578
// build an image using WebLogic Image Tool
568579
logger.info("Create image {0} using model directory {1}", image, MODEL_DIR);
569580
boolean result = createMiiImage(

new-integration-tests/src/test/java/oracle/weblogic/kubernetes/ItSimpleNginxValidation.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,15 @@ public void testCreateMiiDomain() {
182182
// create image with model files
183183
String miiImage = createImageAndVerify();
184184

185-
// push the image to registry to make the test work in multi node cluster
185+
// docker login, if necessary
186186
if (!REPO_USERNAME.equals(REPO_DUMMY_VALUE)) {
187187
logger.info("docker login");
188188
assertTrue(dockerLogin(REPO_REGISTRY, REPO_USERNAME, REPO_PASSWORD), "docker login failed");
189+
}
189190

190-
logger.info("docker push image {0} to OCIR", miiImage);
191+
// push image, if necessary
192+
if (!REPO_NAME.isEmpty()) {
193+
logger.info("docker push image {0} to {1}", miiImage, REPO_NAME);
191194
assertTrue(dockerPush(miiImage), String.format("docker push failed for image %s", miiImage));
192195
}
193196

@@ -517,7 +520,7 @@ private String createImageAndVerify() {
517520
Date date = new Date();
518521
final String imageTag = dateFormat.format(date) + "-" + System.currentTimeMillis();
519522
// Add repository name in image name for Jenkins runs
520-
final String imageName = REPO_USERNAME.equals(REPO_DUMMY_VALUE) ? MII_IMAGE_NAME : REPO_NAME + MII_IMAGE_NAME;
523+
final String imageName = REPO_NAME + MII_IMAGE_NAME;
521524
final String image = imageName + ":" + imageTag;
522525

523526
// build the model file list
@@ -536,6 +539,14 @@ private String createImageAndVerify() {
536539
Map<String, String> env = new HashMap<>();
537540
env.put("WLSIMG_BLDDIR", WIT_BUILD_DIR);
538541

542+
// For k8s 1.16 support and as of May 6, 2020, we presently need a different JDK for these
543+
// tests and for image tool. This is expected to no longer be necessary once JDK 11.0.8 or
544+
// the next JDK 14 versions are released.
545+
String witJavaHome = System.getenv("WIT_JAVA_HOME");
546+
if (witJavaHome != null) {
547+
env.put("JAVA_HOME", witJavaHome);
548+
}
549+
539550
// build an image using WebLogic Image Tool
540551
logger.info("Create image {0} using model directory {1}", image, MODEL_DIR);
541552
boolean result = createMiiImage(

new-integration-tests/src/test/java/oracle/weblogic/kubernetes/ItSimpleValidation.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@
5555
import static oracle.weblogic.kubernetes.assertions.TestAssertions.domainExists;
5656
import static oracle.weblogic.kubernetes.assertions.TestAssertions.isHelmReleaseDeployed;
5757
import static oracle.weblogic.kubernetes.assertions.TestAssertions.operatorIsReady;
58-
import static oracle.weblogic.kubernetes.extensions.LoggedTest.logger;
5958
import static org.awaitility.Awaitility.with;
6059
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
6160
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -116,7 +115,7 @@ public void setup(@Namespaces(2) List<String> namespaces) {
116115
.putCapacityItem("storage", Quantity.fromString("5Gi"))
117116
.persistentVolumeReclaimPolicy("Recycle")
118117
.hostPath(new V1HostPathVolumeSource()
119-
.path(TestConstants.PV_ROOT + "/" + domainUid + "-persistentVolume")))
118+
.path(TestConstants.PV_ROOT))) // Removing `+ "/" + domainUid + "-persistentVolume"` for now
120119
.metadata(new V1ObjectMetaBuilder()
121120
.withName(pvName)
122121
.withNamespace(domainNamespace1)

new-integration-tests/src/test/java/oracle/weblogic/kubernetes/TestConstants.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ public interface TestConstants {
1818
"oracle/weblogic-kubernetes-operator";
1919
public static final String OPERATOR_DOCKER_BUILD_SCRIPT =
2020
"../buildDockerImage.sh";
21-
public static final String REPO_NAME = "phx.ocir.io/weblogick8s/";
2221
public static final String REPO_DUMMY_VALUE = "dummy";
2322
public static final String REPO_SECRET_NAME = "ocir-secret";
2423
public static final String REPO_REGISTRY = Optional.ofNullable(System.getenv("REPO_REGISTRY"))
2524
.orElse(REPO_DUMMY_VALUE);
25+
public static final String REPO_DEFAULT = "phx.ocir.io/weblogick8s/";
26+
public static final String REPO_NAME = Optional.ofNullable(System.getenv("KIND_REPO"))
27+
.orElse(!REPO_REGISTRY.equals(REPO_DUMMY_VALUE) ? REPO_DEFAULT : "");
2628
public static final String REPO_USERNAME = Optional.ofNullable(System.getenv("REPO_USERNAME"))
2729
.orElse(REPO_DUMMY_VALUE);
2830
public static final String REPO_PASSWORD = Optional.ofNullable(System.getenv("REPO_PASSWORD"))
@@ -39,7 +41,7 @@ public interface TestConstants {
3941
public static final String LOGS_DIR = System.getenv().getOrDefault("RESULT_ROOT",
4042
System.getProperty("java.io.tmpdir")) + "/diagnosticlogs";
4143
public static final String PV_ROOT = System.getenv().getOrDefault("PV_ROOT",
42-
System.getProperty("java.io.tmpdir")) + "/ittestspvroot";
44+
System.getProperty("java.io.tmpdir") + "/ittestspvroot");
4345
public static final String NGINX_RELEASE_NAME = "nginx-release" + BUILD_ID;
4446
public static final String STABLE_REPO_NAME = "stable";
4547
public static final String NGINX_CHART_NAME = "nginx-ingress";

new-integration-tests/src/test/java/oracle/weblogic/kubernetes/actions/impl/Operator.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,12 @@ public static String getImageName() {
6767
String imageName = Optional.ofNullable(System.getenv("IMAGE_NAME_OPERATOR"))
6868
.orElse(IMAGE_NAME_OPERATOR);
6969
// use branch name and build id for Jenkins runs in image tag
70+
if (!REPO_NAME.isEmpty()) {
71+
imageName = REPO_NAME + imageName;
72+
}
7073
String branchName = "";
7174
if (!BUILD_ID.isEmpty()) {
7275
branchName = BRANCH_NAME_FROM_JENKINS;
73-
imageName = REPO_NAME + imageName;
7476
} else {
7577
CommandParams params = Command.defaultCommandParams()
7678
.command("git branch | grep \\* | cut -d ' ' -f2-")

new-integration-tests/src/test/java/oracle/weblogic/kubernetes/extensions/ImageBuilders.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.junit.jupiter.api.extension.ExtensionContext;
1212

1313
import static oracle.weblogic.kubernetes.TestConstants.REPO_DUMMY_VALUE;
14+
import static oracle.weblogic.kubernetes.TestConstants.REPO_NAME;
1415
import static oracle.weblogic.kubernetes.TestConstants.REPO_PASSWORD;
1516
import static oracle.weblogic.kubernetes.TestConstants.REPO_REGISTRY;
1617
import static oracle.weblogic.kubernetes.TestConstants.REPO_USERNAME;
@@ -50,19 +51,19 @@ public void beforeAll(ExtensionContext context) {
5051
// assertFalse(true);
5152
assertFalse(operatorImage.isEmpty(), "Image name can not be empty");
5253

53-
// push the image to OCIR to make the test work in multi node cluster
54-
if (!REPO_USERNAME.equals(REPO_DUMMY_VALUE)) {
55-
assertTrue(Operator.buildImage(operatorImage));
54+
assertTrue(Operator.buildImage(operatorImage));
5655

56+
// docker login, if needed
57+
if (!REPO_USERNAME.equals(REPO_DUMMY_VALUE)) {
5758
logger.info("docker login");
5859
assertTrue(dockerLogin(REPO_REGISTRY, REPO_USERNAME, REPO_PASSWORD), "docker login failed");
60+
}
5961

60-
logger.info("docker push image {0} to OCIR", operatorImage);
62+
// push the image
63+
if (!REPO_NAME.isEmpty()) {
64+
logger.info("docker push image {0} to {1}", operatorImage, REPO_NAME);
6165
assertTrue(dockerPush(operatorImage), String.format("docker push failed for image %s", operatorImage));
62-
} else {
63-
assertTrue(Operator.buildImage(operatorImage));
6466
}
65-
6667
} finally {
6768
// Initialization is done. Release all waiting other threads. The latch is now disabled so
6869
// other threads

0 commit comments

Comments
 (0)