Skip to content

Commit

Permalink
test: refactored layered jar tests, no mocks required
Browse files Browse the repository at this point in the history
Signed-off-by: Marc Nuri <marc@marcnuri.com>
  • Loading branch information
manusa committed Aug 30, 2023
1 parent 1636d4b commit e417623
Show file tree
Hide file tree
Showing 10 changed files with 409 additions and 428 deletions.
Expand Up @@ -86,10 +86,6 @@ public File resolveDefaultOpenShiftResourceDir() {
return resolveFile("build", "classes", "java", "main", "META-INF", "jkube", "openshift");
}

public File resolveDefaultDockerfile(String imageNamespace, String imageName, String imageTag) {
return resolveFile("build", "docker", imageNamespace, imageName, imageTag, "build", "Dockerfile");
}

public BuildResult build() {
return gradleRunner.build();
}
Expand Down
Expand Up @@ -13,6 +13,7 @@
*/
package org.eclipse.jkube.gradle.plugin.tests;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;

Expand All @@ -27,7 +28,30 @@

class SpringBootIT {
@RegisterExtension
private final ITGradleRunnerExtension gradleRunner = new ITGradleRunnerExtension();
protected final ITGradleRunnerExtension gradleRunner = new ITGradleRunnerExtension();

@Test
void k8sBuild_whenRunWithJibBuildStrategy_generatesLayeredImage() throws IOException {
// When
final BuildResult result = gradleRunner.withITProject("spring-boot")
.withArguments("clean", "build", "k8sBuild", "-Pjkube.build.strategy=jib", "--stacktrace")
.build();
// Then
final File dockerFile = gradleRunner.resolveFile("build", "docker", "gradle", "spring-boot", "latest", "build", "Dockerfile");
assertThat(new String(Files.readAllBytes(dockerFile.toPath())))
.contains("FROM quay.io/jkube/jkube-java:")
.contains("ENV JAVA_MAIN_CLASS=org.springframework.boot.loader.JarLauncher JAVA_APP_DIR=/deployments")
.contains("EXPOSE 8080 8778 9779")
.contains("COPY /dependencies/deployments /deployments/")
.contains("COPY /spring-boot-loader/deployments /deployments/")
.contains("COPY /application/deployments /deployments/")
.contains("WORKDIR /deployments")
.contains("ENTRYPOINT [\"java\",\"org.springframework.boot.loader.JarLauncher\"]");
assertThat(result).extracting(BuildResult::getOutput).asString()
.contains("Running generator spring-boot")
.contains("Spring Boot layered jar detected")
.contains("JIB image build started");
}

@Test
void k8sResource_whenRun_generatesK8sManifests() throws IOException, ParseException {
Expand Down Expand Up @@ -68,25 +92,4 @@ void ocResource_whenRun_generatesOpenShiftManifests() throws IOException, ParseE
.contains("jkube-revision-history: Adding revision history limit to 2");
}

@Test
void k8sBuild_whenRunWithJibBuildStrategy_generatesLayeredImage() throws IOException {
// When
final BuildResult result = gradleRunner.withITProject("spring-boot")
.withArguments("clean", "build", "k8sBuild", "-Pjkube.build.strategy=jib", "--stacktrace")
.build();
// Then
String generatedDockerfileContent = new String(Files.readAllBytes(gradleRunner.resolveDefaultDockerfile( "gradle", "spring-boot", "latest").toPath()));
assertThat(generatedDockerfileContent)
.contains("FROM quay.io/jkube/jkube-java:")
.contains("ENV JAVA_MAIN_CLASS=org.springframework.boot.loader.JarLauncher JAVA_APP_DIR=/deployments")
.contains("EXPOSE 8080 8778 9779")
.contains("COPY /dependencies/deployments /deployments/")
.contains("COPY /spring-boot-loader/deployments /deployments/")
.contains("COPY /application/deployments /deployments/")
.contains("WORKDIR /deployments")
.contains("ENTRYPOINT [\"java\",\"org.springframework.boot.loader.JarLauncher\"]");
assertThat(result).extracting(BuildResult::getOutput).asString()
.contains("Running generator spring-boot")
.contains("Spring Boot layered jar detected");
}
}
Expand Up @@ -32,7 +32,6 @@

/**
* @author roland
* @since 14/09/16
*/
public abstract class ExternalCommand {
protected final KitLogger log;
Expand Down
Expand Up @@ -13,6 +13,7 @@
*/
package org.eclipse.jkube.springboot;

import lombok.Getter;
import org.eclipse.jkube.kit.common.ExternalCommand;
import org.eclipse.jkube.kit.common.KitLogger;

Expand All @@ -21,11 +22,18 @@
import java.util.ArrayList;
import java.util.List;

public class SpringBootLayeredJarExecUtils {
private SpringBootLayeredJarExecUtils() { }
public class SpringBootLayeredJar {

public static List<String> listLayers(KitLogger kitLogger, File layeredJar) {
LayerListCommand layerListCommand = new LayerListCommand(kitLogger, layeredJar);
private final File layeredJar;
private final KitLogger kitLogger;

public SpringBootLayeredJar(File layeredJar, KitLogger kitLogger) {
this.layeredJar = layeredJar;
this.kitLogger = kitLogger;
}

public List<String> listLayers() {
final LayerListCommand layerListCommand = new LayerListCommand(kitLogger, layeredJar);
try {
layerListCommand.execute();
return layerListCommand.getLayers();
Expand All @@ -34,10 +42,9 @@ public static List<String> listLayers(KitLogger kitLogger, File layeredJar) {
}
}

public static void extractLayers(KitLogger kitLogger, File extractionDir, File layeredJar) {
LayerExtractorCommand layerExtractorCommand = new LayerExtractorCommand(kitLogger, extractionDir, layeredJar);
public void extractLayers(File extractionDir) {
try {
layerExtractorCommand.execute();
new LayerExtractorCommand(kitLogger, extractionDir, layeredJar).execute();
} catch (IOException ioException) {
throw new IllegalStateException("Failure in extracting spring boot jar layers", ioException);
}
Expand All @@ -57,12 +64,14 @@ protected String[] getArgs() {
}

private static class LayerListCommand extends ExternalCommand {
private final List<String> layers;
private final File layeredJar;
@Getter
private final List<String> layers;

protected LayerListCommand(KitLogger log, File layeredJar) {
super(log);
layers = new ArrayList<>();
this.layeredJar = layeredJar;
layers = new ArrayList<>();
}

@Override
Expand All @@ -75,8 +84,5 @@ protected void processLine(String line) {
layers.add(line);
}

public List<String> getLayers() {
return layers;
}
}
}
Expand Up @@ -15,11 +15,11 @@

import org.eclipse.jkube.generator.api.GeneratorConfig;
import org.eclipse.jkube.generator.api.GeneratorContext;
import org.eclipse.jkube.generator.javaexec.FatJarDetector;
import org.eclipse.jkube.kit.common.Arguments;
import org.eclipse.jkube.kit.common.Assembly;
import org.eclipse.jkube.kit.common.AssemblyConfiguration;
import org.eclipse.jkube.kit.common.AssemblyFileSet;
import org.eclipse.jkube.springboot.SpringBootLayeredJar;

import java.io.File;
import java.util.ArrayList;
Expand All @@ -29,38 +29,37 @@
import java.util.Map;

import static org.eclipse.jkube.kit.common.util.FileUtil.getRelativePath;
import static org.eclipse.jkube.springboot.SpringBootLayeredJarExecUtils.extractLayers;
import static org.eclipse.jkube.springboot.SpringBootLayeredJarExecUtils.listLayers;

public class LayeredJarGenerator extends AbstractSpringBootNestedGenerator {
private final FatJarDetector.Result fatJarDetectorResult;
public LayeredJarGenerator(GeneratorContext generatorContext, GeneratorConfig generatorConfig, FatJarDetector.Result result) {

private static final String MAIN_CLASS = "org.springframework.boot.loader.JarLauncher";
private final SpringBootLayeredJar springBootLayeredJar;

public LayeredJarGenerator(GeneratorContext generatorContext, GeneratorConfig generatorConfig, File layeredJar) {
super(generatorContext, generatorConfig);
fatJarDetectorResult = result;
springBootLayeredJar = new SpringBootLayeredJar(layeredJar, getLogger());
}

@Override
public Arguments getBuildEntryPoint() {
return Arguments.builder()
.exec(Arrays.asList("java", "org.springframework.boot.loader.JarLauncher"))
.exec(Arrays.asList("java", MAIN_CLASS))
.build();
}

@Override
public Map<String, String> getEnv() {
return Collections.singletonMap("JAVA_MAIN_CLASS", "org.springframework.boot.loader.JarLauncher");
return Collections.singletonMap("JAVA_MAIN_CLASS", MAIN_CLASS);
}

@Override
public AssemblyConfiguration createAssemblyConfiguration(List<AssemblyFileSet> defaultFileSets) {
getLogger().info("Spring Boot layered jar detected");

List<String> layerNames = listLayers(getLogger(), fatJarDetectorResult.getArchiveFile());
List<Assembly> layerAssemblies = new ArrayList<>();
final List<Assembly> layerAssemblies = new ArrayList<>();
layerAssemblies.add(Assembly.builder().id("jkube-includes").fileSets(defaultFileSets).build());
extractLayers(getLogger(), getProject().getBuildPackageDirectory(), fatJarDetectorResult.getArchiveFile());
springBootLayeredJar.extractLayers(getProject().getBuildPackageDirectory());

for (String springBootLayer : layerNames) {
for (String springBootLayer : springBootLayeredJar.listLayers()) {
File layerDir = new File(getProject().getBuildPackageDirectory(), springBootLayer);
layerAssemblies.add(Assembly.builder()
.id(springBootLayer)
Expand Down
Expand Up @@ -63,7 +63,7 @@ default Map<String, String> getEnv() {
static SpringBootNestedGenerator from(GeneratorContext generatorContext, GeneratorConfig generatorConfig, FatJarDetector.Result fatJarDetectorResult) {
if (fatJarDetectorResult != null && fatJarDetectorResult.getArchiveFile() != null &&
isLayeredJar(fatJarDetectorResult.getArchiveFile())) {
return new LayeredJarGenerator(generatorContext, generatorConfig, fatJarDetectorResult);
return new LayeredJarGenerator(generatorContext, generatorConfig, fatJarDetectorResult.getArchiveFile());
}
return new FatJarGenerator(generatorContext, generatorConfig);
}
Expand Down

This file was deleted.

@@ -0,0 +1,96 @@
/*
* 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.springboot;

import org.eclipse.jkube.kit.common.KitLogger;
import org.eclipse.jkube.kit.common.assertj.FileAssertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
import java.util.Objects;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;

class SpringBootLayeredJarTest {

@TempDir
private File projectDir;

private SpringBootLayeredJar springBootLayeredJar;

@Nested
@DisplayName("with invalid jar")
class InvalidJar {
@BeforeEach
void setup() {
springBootLayeredJar = new SpringBootLayeredJar(new File(projectDir, "invalid.jar"), new KitLogger.SilentLogger());
}

@Test
void listLayers_whenJarInvalid_thenThrowException() {
assertThatIllegalStateException()
.isThrownBy(() -> springBootLayeredJar.listLayers())
.withMessage("Failure in getting spring boot jar layers information");
}

@Test
void extractLayers_whenJarInvalid_thenThrowException() {
assertThatIllegalStateException()
.isThrownBy(() -> springBootLayeredJar.extractLayers(projectDir))
.withMessage("Failure in extracting spring boot jar layers");
}
}
@Nested
@DisplayName("with valid jar")
class ValidJar {
@BeforeEach
void setup() throws IOException {
final File layeredJar = new File(projectDir, "layered.jar");
Files.copy(
Objects.requireNonNull(SpringBootLayeredJarTest.class.getResourceAsStream("/generator-integration-test/layered-jar.jar")),
new File(projectDir, "layered.jar").toPath()
);
springBootLayeredJar = new SpringBootLayeredJar(layeredJar, new KitLogger.SilentLogger());
}

@Test
void listLayers_whenJarInvalid_thenThrowException() {
// When
final List<String> result = springBootLayeredJar.listLayers();
// Then
assertThat(result)
.containsExactly("dependencies", "spring-boot-loader", "snapshot-dependencies", "application");
}

@Test
void extractLayers_whenJarInvalid_thenThrowException() throws IOException {
// Given
final File extractionDir = Files.createDirectory(new File(projectDir, "extracted").toPath()).toFile();
// When
springBootLayeredJar.extractLayers(extractionDir);
// Then
FileAssertions.assertThat(extractionDir)
.fileTree()
.contains("dependencies", "spring-boot-loader", "snapshot-dependencies", "application");
}
}
}

0 comments on commit e417623

Please sign in to comment.