Skip to content

Commit

Permalink
test : Update SpringBoot integration tests for layered jar
Browse files Browse the repository at this point in the history
+ Remove spring boot dependencies from dependencyManagement in parent
  pom. Spring boot projects would not use spring-boot.version property
  explicitly in poms
+ Add ZeroConfigFatJarK8sITCase to verify kubernetes maven
  plugin workflow in case of spring boot projects that don't generate a
  layered jar

Signed-off-by: Rohan Kumar <rohaan@redhat.com>
  • Loading branch information
rohanKanojia committed Aug 30, 2023
1 parent 1a0cb99 commit a998b72
Show file tree
Hide file tree
Showing 18 changed files with 400 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ public static void pull(String image) throws IOException, InterruptedException {
}
}

public static List<String> getImageHistory(String imageName) throws IOException, InterruptedException {
final CliResult result = CliUtils.runCommand(String.format("docker history %s", imageName));
return Arrays.asList(result.getOutput().replace("\r", "").split("\n"));
}

public static void loadTar(File dockerBuildTar) throws IOException, InterruptedException {
final CliResult result = CliUtils.runCommand(String.format(
"docker load -i %s", dockerBuildTar.getAbsolutePath()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import static org.eclipse.jkube.integrationtests.assertions.JKubeAssertions.assertJKube;
import static org.eclipse.jkube.integrationtests.assertions.KubernetesListAssertion.assertListResource;
import static org.eclipse.jkube.integrationtests.assertions.YamlAssertion.yaml;
import static org.eclipse.jkube.integrationtests.docker.DockerUtils.getImageHistory;
import static org.eclipse.jkube.integrationtests.docker.DockerUtils.listImageFiles;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
Expand Down Expand Up @@ -66,14 +67,22 @@ void k8sBuild() throws Exception {
// Then
assertInvocation(invocationResult);
assertImageWasRecentlyBuilt("integration-tests", getApplication());
final File dockerDirectory = new File(
String.format("../%s/target/docker/integration-tests/spring-boot-complete/", getProject()));
final List<String> imageFiles = listImageFiles(String.format("%s/%s", "integration-tests", getApplication()),
"/deployments");
assertThat(imageFiles, not(hasItem("/deployments/assembly-test")));
assertThat(imageFiles, not(hasItem("/deployments/static")));
assertThat(imageFiles, hasItem("/deployments/will-be-included-if-no-assemblies-defined.txt"));
assertThat(imageFiles, hasItem("/deployments/spring-boot-complete-0.0.0-SNAPSHOT.jar"));
assertThat(imageFiles, hasItem("/deployments/BOOT-INF"));
assertThat(imageFiles, hasItem("/deployments/BOOT-INF/lib"));
assertThat(imageFiles, hasItem("/deployments/BOOT-INF/classes"));
assertThat(imageFiles, hasItem("/deployments/BOOT-INF/classpath.idx"));
assertThat(imageFiles, hasItem("/deployments/BOOT-INF/layers.idx"));
assertThat(imageFiles, hasItem("/deployments/org/springframework/boot/loader/JarLauncher.class"));
final List<String> imageHistory = getImageHistory(String.format("%s/%s", "integration-tests", getApplication()));
long dirCopyLayers = imageHistory.stream()
.filter(l -> l.contains("COPY dir:"))
.count();
assertThat(dirCopyLayers, equalTo(4L));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.parallel.ResourceLock;

import java.util.List;

import static org.eclipse.jkube.integrationtests.Locks.CLUSTER_RESOURCE_INTENSIVE;
import static org.eclipse.jkube.integrationtests.Tags.KUBERNETES;
import static org.eclipse.jkube.integrationtests.assertions.DeploymentAssertion.awaitDeployment;
Expand All @@ -36,6 +38,8 @@
import static org.eclipse.jkube.integrationtests.assertions.PodAssertion.awaitPod;
import static org.eclipse.jkube.integrationtests.assertions.ServiceAssertion.awaitService;
import static org.eclipse.jkube.integrationtests.assertions.YamlAssertion.yaml;
import static org.eclipse.jkube.integrationtests.docker.DockerUtils.getImageHistory;
import static org.eclipse.jkube.integrationtests.docker.DockerUtils.listImageFiles;
import static org.eclipse.jkube.integrationtests.springboot.zeroconfig.ZeroConfig.GRADLE_APPLICATION;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.aMapWithSize;
Expand All @@ -44,6 +48,7 @@
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.hasSize;
Expand Down Expand Up @@ -89,6 +94,19 @@ void k8sBuild() throws Exception {
gradle.tasks("k8sBuild").build();
// Then
assertImageWasRecentlyBuilt("gradle", getApplication());
final List<String> imageFiles = listImageFiles(String.format("%s/%s", "gradle", getApplication()),
"/deployments");
assertThat(imageFiles, hasItem("/deployments/BOOT-INF"));
assertThat(imageFiles, hasItem("/deployments/BOOT-INF/lib"));
assertThat(imageFiles, hasItem("/deployments/BOOT-INF/classes"));
assertThat(imageFiles, hasItem("/deployments/BOOT-INF/classpath.idx"));
assertThat(imageFiles, hasItem("/deployments/BOOT-INF/layers.idx"));
assertThat(imageFiles, hasItem("/deployments/org/springframework/boot/loader/JarLauncher.class"));
final List<String> imageHistory = getImageHistory(String.format("%s/%s", "gradle", getApplication()));
long dirCopyLayers = imageHistory.stream()
.filter(l -> l.contains("COPY dir:"))
.count();
assertThat(dirCopyLayers, equalTo(3L));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.junit.jupiter.api.parallel.ResourceLock;

import java.io.File;
import java.util.List;
import java.util.Properties;

import static org.eclipse.jkube.integrationtests.Locks.CLUSTER_RESOURCE_INTENSIVE;
Expand All @@ -39,12 +40,15 @@
import static org.eclipse.jkube.integrationtests.assertions.JKubeAssertions.assertJKube;
import static org.eclipse.jkube.integrationtests.assertions.KubernetesListAssertion.assertListResource;
import static org.eclipse.jkube.integrationtests.assertions.YamlAssertion.yaml;
import static org.eclipse.jkube.integrationtests.docker.DockerUtils.getImageHistory;
import static org.eclipse.jkube.integrationtests.docker.DockerUtils.listImageFiles;
import static org.eclipse.jkube.integrationtests.springboot.zeroconfig.ZeroConfig.MAVEN_APPLICATION;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.anEmptyMap;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.hasSize;
Expand All @@ -68,13 +72,25 @@ public String getProject() {

@Test
@Order(1)
@DisplayName("k8s:build, should create image")
@DisplayName("k8s:build, should create layered jar image")
void k8sBuild() throws Exception {
// When
final InvocationResult invocationResult = maven("k8s:build");
// Then
assertInvocation(invocationResult);
assertImageWasRecentlyBuilt("integration-tests", "spring-boot-zero-config");
final List<String> imageFiles = listImageFiles("integration-tests/spring-boot-zero-config", "/deployments");
assertThat(imageFiles, hasItem("/deployments/BOOT-INF"));
assertThat(imageFiles, hasItem("/deployments/BOOT-INF/lib"));
assertThat(imageFiles, hasItem("/deployments/BOOT-INF/classes"));
assertThat(imageFiles, hasItem("/deployments/BOOT-INF/classpath.idx"));
assertThat(imageFiles, hasItem("/deployments/BOOT-INF/layers.idx"));
assertThat(imageFiles, hasItem("/deployments/org/springframework/boot/loader/JarLauncher.class"));
final List<String> imageHistory = getImageHistory(String.format("%s/%s", "integration-tests", getApplication()));
long dirCopyLayers = imageHistory.stream()
.filter(l -> l.contains("COPY dir:"))
.count();
assertThat(dirCopyLayers, equalTo(3L));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Copyright (c) 2019 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at:
*
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.jkube.integrationtests.springboot.zeroconfigfatjar;

import io.fabric8.junit.jupiter.api.KubernetesTest;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.client.KubernetesClient;
import org.eclipse.jkube.integrationtests.JKubeCase;
import org.eclipse.jkube.integrationtests.maven.MavenCase;

import static org.eclipse.jkube.integrationtests.assertions.PodAssertion.awaitPod;
import static org.eclipse.jkube.integrationtests.assertions.ServiceAssertion.awaitService;
import static org.hamcrest.Matchers.hasSize;

@KubernetesTest(createEphemeralNamespace = false)
public class ZeroConfigFatJar implements JKubeCase, MavenCase {
private static final String PROJECT_ZERO_CONFIG_FATJAR = "projects-to-be-tested/maven/spring/zero-config-fatjar";

private static KubernetesClient kubernetesClient;

@Override
public KubernetesClient getKubernetesClient() {
return kubernetesClient;
}

@Override
public String getProject() {
return PROJECT_ZERO_CONFIG_FATJAR;
}

@Override
public String getApplication() {
return "spring-boot-zero-config-fatjar";
}

final Pod assertThatShouldApplyResources() throws Exception {
final Pod pod = awaitPod(this)
.logContains("Started ZeroConfigFatJarApplication in", 40)
.getKubernetesResource();
awaitService(this, pod.getMetadata().getNamespace())
.assertPorts(hasSize(1))
.assertPort("http", 8080, false);
return pod;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/**
* Copyright (c) 2019 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at:
*
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.jkube.integrationtests.springboot.zeroconfigfatjar;

import io.fabric8.kubernetes.api.model.Pod;
import org.apache.maven.shared.invoker.InvocationResult;
import org.eclipse.jkube.integrationtests.maven.MavenInvocationResult;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.parallel.ResourceLock;

import java.io.File;
import java.util.List;

import static org.eclipse.jkube.integrationtests.Locks.CLUSTER_RESOURCE_INTENSIVE;
import static org.eclipse.jkube.integrationtests.Tags.KUBERNETES;
import static org.eclipse.jkube.integrationtests.assertions.DeploymentAssertion.awaitDeployment;
import static org.eclipse.jkube.integrationtests.assertions.DockerAssertion.assertImageWasRecentlyBuilt;
import static org.eclipse.jkube.integrationtests.assertions.InvocationResultAssertion.assertInvocation;
import static org.eclipse.jkube.integrationtests.assertions.JKubeAssertions.assertJKube;
import static org.eclipse.jkube.integrationtests.assertions.KubernetesListAssertion.assertListResource;
import static org.eclipse.jkube.integrationtests.assertions.YamlAssertion.yaml;
import static org.eclipse.jkube.integrationtests.docker.DockerUtils.getImageHistory;
import static org.eclipse.jkube.integrationtests.docker.DockerUtils.listImageFiles;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.anEmptyMap;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.junit.jupiter.api.parallel.ResourceAccessMode.READ_WRITE;

@Tag(KUBERNETES)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class ZeroConfigFatJarK8sITCase extends ZeroConfigFatJar {
@Test
@Order(1)
@DisplayName("k8s:build, should create fat jar image")
void k8sBuild() throws Exception {
// When
final InvocationResult invocationResult = maven("k8s:build");
// Then
assertInvocation(invocationResult);
assertImageWasRecentlyBuilt("integration-tests", "spring-boot-zero-config-fatjar");
final List<String> imageFiles = listImageFiles("integration-tests/spring-boot-zero-config-fatjar", "/deployments");
assertThat(imageFiles, hasItem("/deployments/data"));
assertThat(imageFiles, hasItem("/deployments/spring-boot-zero-config-fatjar-0.0.0-SNAPSHOT.jar"));
final List<String> imageHistory = getImageHistory(String.format("%s/%s", "integration-tests", getApplication()));
long dirCopyLayers = imageHistory.stream()
.filter(l -> l.contains("COPY dir:"))
.count();
assertThat(dirCopyLayers, equalTo(1L));
}

@Test
@Order(2)
@DisplayName("k8s:resource, should create manifests")
void k8sResource() throws Exception {
// When
final InvocationResult invocationResult = maven("k8s:resource");
// Then
assertInvocation(invocationResult);
final File metaInfDirectory = new File(
String.format("../%s/target/classes/META-INF", getProject()));
assertThat(metaInfDirectory.exists(), equalTo(true));
assertListResource(new File(metaInfDirectory, "jkube/kubernetes.yml"));
assertThat(new File(metaInfDirectory, "jkube/kubernetes/spring-boot-zero-config-fatjar-deployment.yml"), yaml(not(anEmptyMap())));
assertThat(new File(metaInfDirectory, "jkube/kubernetes/spring-boot-zero-config-fatjar-service.yml"), yaml(not(anEmptyMap())));
}

@Test
@Order(3)
@ResourceLock(value = CLUSTER_RESOURCE_INTENSIVE, mode = READ_WRITE)
@DisplayName("k8s:apply, should deploy pod and service")
@SuppressWarnings("unchecked")
void k8sApply() throws Exception {
// When
final InvocationResult invocationResult = maven("k8s:apply");
// Then
assertInvocation(invocationResult);
final Pod pod = assertThatShouldApplyResources();
awaitDeployment(this, pod.getMetadata().getNamespace())
.assertReplicas(equalTo(1))
.assertContainers(hasSize(1))
.assertContainers(hasItems(allOf(
hasProperty("image", equalTo("integration-tests/spring-boot-zero-config-fatjar:latest")),
hasProperty("name", equalTo("spring-boot")),
hasProperty("ports", hasSize(3)),
hasProperty("ports", hasItems(allOf(
hasProperty("name", equalTo("http")),
hasProperty("containerPort", equalTo(8080))
)))
)));
}

@Test
@Order(4)
@DisplayName("k8s:log, should retrieve log")
void k8sLog() throws Exception {
// When
final MavenInvocationResult invocationResult = maven("k8s:log", properties("jkube.log.follow", "false"));
// Then
assertInvocation(invocationResult);
assertThat(invocationResult.getStdOut(),
stringContainsInOrder("Tomcat started on port(s): 8080", "Started ZeroConfigFatJarApplication in", "seconds"));
}

@Test
@Order(5)
@DisplayName("k8s:undeploy, should delete all applied resources")
void k8sUndeploy() throws Exception {
// When
final InvocationResult invocationResult = maven("k8s:undeploy");
// Then
assertInvocation(invocationResult);
assertJKube(this)
.assertThatShouldDeleteAllAppliedResources()
.assertDeploymentDeleted();
}
}
22 changes: 2 additions & 20 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
<quarkus.version>3.2.3.Final</quarkus.version>
<slf4j.version>2.0.7</slf4j.version>
<spring-boot.version>2.7.5</spring-boot.version>
<spring-boot.fat-jar.version>2.3.9.RELEASE</spring-boot.fat-jar.version>
<thorntail.version>2.7.0.Final</thorntail.version>
<vertx.version>4.4.4</vertx.version>
<vertx.plugin.version>1.0.28</vertx.plugin.version>
Expand Down Expand Up @@ -128,21 +129,6 @@
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>${spring-boot.version}</version>
</dependency>

<!-- Test dependencies -->
<dependency>
Expand Down Expand Up @@ -209,11 +195,6 @@
<artifactId>maven-failsafe-plugin</artifactId>
<version>${apache.maven-failsafe-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
</plugin>
<plugin>
<groupId>org.eclipse.jkube</groupId>
<artifactId>kubernetes-maven-plugin</artifactId>
Expand Down Expand Up @@ -393,6 +374,7 @@
<module>projects-to-be-tested/maven/spring/multi-profile</module>
<module>projects-to-be-tested/maven/spring/watch</module>
<module>projects-to-be-tested/maven/spring/zero-config</module>
<module>projects-to-be-tested/maven/spring/zero-config-fatjar</module>
</modules>
<activation>
<file>
Expand Down
Loading

0 comments on commit a998b72

Please sign in to comment.