Merge pull request #7255 from geoand/prod-more-test-additional-deps

Add support for configuring additional dependencies in @QuarkusProdModeTest
This commit is contained in:
Manyanda Chitimbo
2020-02-18 19:21:09 +01:00
committed by GitHub
24 changed files with 324 additions and 811 deletions

View File

@@ -80,6 +80,8 @@ public class BootstrapAppModelFactory {
private LocalProject appClassesWorkspace;
private List<AppDependency> forcedDependencies = Collections.emptyList();
private BootstrapAppModelFactory() {
}
@@ -143,6 +145,11 @@ public class BootstrapAppModelFactory {
return this;
}
public BootstrapAppModelFactory setForcedDependencies(List<AppDependency> forcedDependencies) {
this.forcedDependencies = forcedDependencies;
return this;
}
public AppModelResolver getAppModelResolver() {
if (bootstrapAppModelResolver != null) {
@@ -273,7 +280,7 @@ public class BootstrapAppModelFactory {
}
AppModelResolver appModelResolver = getAppModelResolver();
CurationResult curationResult = new CurationResult(appModelResolver
.resolveManagedModel(appArtifact, Collections.emptyList(), managingProject));
.resolveManagedModel(appArtifact, forcedDependencies, managingProject));
if (cachedCpPath != null) {
Files.createDirectories(cachedCpPath.getParent());
try (DataOutputStream out = new DataOutputStream(Files.newOutputStream(cachedCpPath))) {

View File

@@ -3,6 +3,7 @@ package io.quarkus.bootstrap.app;
import io.quarkus.bootstrap.BootstrapAppModelFactory;
import io.quarkus.bootstrap.BootstrapException;
import io.quarkus.bootstrap.model.AppArtifact;
import io.quarkus.bootstrap.model.AppDependency;
import io.quarkus.bootstrap.resolver.AppModelResolver;
import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver;
import io.quarkus.bootstrap.resolver.update.DependenciesOrigin;
@@ -72,6 +73,7 @@ public class QuarkusBootstrap implements Serializable {
private final boolean isolateDeployment;
private final MavenArtifactResolver mavenArtifactResolver;
private final AppArtifact managingProject;
private final List<AppDependency> forcedDependencies;
private QuarkusBootstrap(Builder builder) {
this.applicationRoot = builder.applicationRoot;
@@ -95,6 +97,7 @@ public class QuarkusBootstrap implements Serializable {
this.additionalDeploymentArchives = builder.additionalDeploymentArchives;
this.mavenArtifactResolver = builder.mavenArtifactResolver;
this.managingProject = builder.managingProject;
this.forcedDependencies = new ArrayList<>(builder.forcedDependencies);
}
public CuratedApplication bootstrap() throws BootstrapException {
@@ -119,6 +122,7 @@ public class QuarkusBootstrap implements Serializable {
.setLocalProjectsDiscovery(localProjectDiscovery)
.setAppArtifact(appArtifact)
.setManagingProject(managingProject)
.setForcedDependencies(forcedDependencies)
.setAppClasses(getProjectRoot() != null ? getProjectRoot()
: getApplicationRoot());
if (mode == Mode.TEST || test) {
@@ -213,6 +217,7 @@ public class QuarkusBootstrap implements Serializable {
boolean isolateDeployment;
MavenArtifactResolver mavenArtifactResolver;
AppArtifact managingProject;
List<AppDependency> forcedDependencies = new ArrayList<>();
public Builder(Path applicationRoot) {
this.applicationRoot = applicationRoot;
@@ -329,6 +334,15 @@ public class QuarkusBootstrap implements Serializable {
return this;
}
/**
* If set, each of these dependencies will either be added to the application dependencies if the GA doesn't match any
* application dependencies, or override the existing version if the GA does match
*/
public Builder setForcedDependencies(List<AppDependency> forcedDependencies) {
this.forcedDependencies = forcedDependencies;
return this;
}
public QuarkusBootstrap build() {
return new QuarkusBootstrap(this);
}

View File

@@ -1,121 +0,0 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.acme</groupId>
<artifactId>kubernetes-with-client</artifactId>
<version>0.1-SNAPSHOT</version>
<properties>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<surefire-plugin.version>2.22.0</surefire-plugin.version>
<maven.compiler.source>1.8</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-bom</artifactId>
<version>@project.version@</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-kubernetes</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-kubernetes-client</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>@project.version@</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemProperties>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>@project.version@</version>
<executions>
<execution>
<goals>
<goal>native-image</goal>
</goals>
<configuration>
<enableHttpUrlHandler>true</enableHttpUrlHandler>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemProperties>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
</systemProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -1,16 +0,0 @@
package org.acme;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/hello")
public class Hello {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello";
}
}

View File

@@ -1,152 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>kubernetes - 0.1-SNAPSHOT</title>
<style>
h1, h2, h3, h4, h5, h6 {
margin-bottom: 0.5rem;
font-weight: 400;
line-height: 1.5;
}
h1 {
font-size: 2.5rem;
}
h2 {
font-size: 2rem
}
h3 {
font-size: 1.75rem
}
h4 {
font-size: 1.5rem
}
h5 {
font-size: 1.25rem
}
h6 {
font-size: 1rem
}
.lead {
font-weight: 300;
font-size: 2rem;
}
.banner {
font-size: 2.7rem;
margin: 0;
padding: 2rem 1rem;
background-color: #00A1E2;
color: white;
}
body {
margin: 0;
font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
code {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 87.5%;
color: #e83e8c;
word-break: break-word;
}
.left-column {
padding: .75rem;
max-width: 75%;
min-width: 55%;
}
.right-column {
padding: .75rem;
max-width: 25%;
}
.container {
display: flex;
width: 100%;
}
li {
margin: 0.75rem;
}
.right-section {
margin-left: 1rem;
padding-left: 0.5rem;
}
.right-section h3 {
padding-top: 0;
font-weight: 200;
}
.right-section ul {
border-left: 0.3rem solid #00A1E2;
list-style-type: none;
padding-left: 0;
}
</style>
</head>
<body>
<div class="banner lead">
Your new Cloud-Native application is ready!
</div>
<div class="container">
<div class="left-column">
<p class="lead"> Congratulations, you have created a new Quarkus application.</p>
<h2>Why do you see this?</h2>
<p>This page is served by Quarkus. The source is in
<code>src/main/resources/META-INF/resources/index.html</code>.</p>
<h2>What can I do from here?</h2>
<p>If not already done, run the application in <em>dev mode</em> using: <code>mvn compile quarkus:dev</code>.
</p>
<ul>
<li>Add REST resources, Servlets, functions and other services in <code>src/main/java</code>.</li>
<li>Your static assets are located in <code>src/main/resources/META-INF/resources</code>.</li>
<li>Configure your application in <code>src/main/resources/application.properties</code>.
</li>
</ul>
<h2>How do I get rid of this page?</h2>
<p>Just delete the <code>src/main/resources/META-INF/resources/index.html</code> file.</p>
</div>
<div class="right-column">
<div class="right-section">
<h3>Application</h3>
<ul>
<li>GroupId: org.acme</li>
<li>ArtifactId: kubernetes</li>
<li>Version: 0.1-SNAPSHOT</li>
<li>Quarkus Version: 999-SNAPSHOT</li>
</ul>
</div>
<div class="right-section">
<h3>Next steps</h3>
<ul>
<li><a href="https://quarkus.io/guides/maven-tooling.html" target="_blank">Setup your IDE</a></li>
<li><a href="https://quarkus.io/guides/getting-started.html" target="_blank">Getting started</a></li>
<li><a href="https://quarkus.io" target="_blank">Quarkus Web Site</a></li>
</ul>
</div>
</div>
</div>
</body>
</html>

View File

@@ -1,28 +0,0 @@
import io.dekorate.utils.Serialization
import io.dekorate.deps.kubernetes.api.model.KubernetesList
import io.dekorate.deps.kubernetes.api.model.ServiceAccount
import io.dekorate.deps.kubernetes.api.model.apps.Deployment;
import io.dekorate.deps.kubernetes.api.model.rbac.RoleBinding;
//Check that file exits
String base = basedir
File kubernetesYml = new File(base, "target/kubernetes/kubernetes.yml")
assert kubernetesYml.exists()
kubernetesYml.withInputStream { stream ->
//Check that its parse-able
KubernetesList list = Serialization.unmarshalAsList(stream)
assert list != null
Deployment deployment = list.items.find{r -> r.kind == "Deployment"}
//Check that ti contains a Deployment named after the project
assert deployment != null
assert deployment.metadata.name == "kubernetes-with-client"
ServiceAccount serviceAccount = list.items.find{r -> r.kind == "ServiceAccount"}
assert serviceAccount != null
assert serviceAccount.metadata.name == "kubernetes-with-client"
RoleBinding rolebinding = list.items.find{r -> r.kind == "RoleBinding"}
assert rolebinding != null
assert rolebinding.metadata.name == "kubernetes-with-client:view"
}

View File

@@ -1,121 +0,0 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.acme</groupId>
<artifactId>kubernetes-with-http-root-and-health</artifactId>
<version>0.1-SNAPSHOT</version>
<properties>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<surefire-plugin.version>2.22.0</surefire-plugin.version>
<maven.compiler.source>1.8</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-bom</artifactId>
<version>@project.version@</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-kubernetes</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-health</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>@project.version@</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemProperties>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>@project.version@</version>
<executions>
<execution>
<goals>
<goal>native-image</goal>
</goals>
<configuration>
<enableHttpUrlHandler>true</enableHttpUrlHandler>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemProperties>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
</systemProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -1,16 +0,0 @@
package org.acme;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/hello")
public class Hello {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello";
}
}

View File

@@ -1,28 +0,0 @@
import io.dekorate.utils.Serialization
import io.dekorate.deps.kubernetes.api.model.*
import io.dekorate.deps.kubernetes.api.model.apps.Deployment;
//Check that file exits
String base = basedir
File kubernetesYml = new File(base, "target/kubernetes/kubernetes.yml")
assert kubernetesYml.exists()
kubernetesYml.withInputStream { stream ->
//Check that its parse-able
KubernetesList list = Serialization.unmarshalAsList(stream)
assert list != null
Deployment deployment = list.items.find{r -> r.kind == "Deployment"}
assert deployment != null
assert deployment.metadata.name == "kubernetes-with-http-root-and-health"
//Check that container has probes pointing to smallrye-health endpoint
Container container = deployment.spec.template.spec.containers.get(0)
assert container != null
Probe readiness = container.readinessProbe
assert readiness != null
assert readiness.httpGet.path == "/api/health/ready"
Probe liveness = container.livenessProbe
assert liveness != null
assert liveness.httpGet.path == "/api/health/liveness"
}

View File

@@ -1,121 +0,0 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.acme</groupId>
<artifactId>kubernetes-with-smallrye-health</artifactId>
<version>0.1-SNAPSHOT</version>
<properties>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<surefire-plugin.version>2.22.0</surefire-plugin.version>
<maven.compiler.source>1.8</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-bom</artifactId>
<version>@project.version@</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-kubernetes</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-health</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>@project.version@</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemProperties>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>@project.version@</version>
<executions>
<execution>
<goals>
<goal>native-image</goal>
</goals>
<configuration>
<enableHttpUrlHandler>true</enableHttpUrlHandler>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemProperties>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
</systemProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -1,16 +0,0 @@
package org.acme;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/hello")
public class Hello {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello";
}
}

View File

@@ -1,152 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>kubernetes - 0.1-SNAPSHOT</title>
<style>
h1, h2, h3, h4, h5, h6 {
margin-bottom: 0.5rem;
font-weight: 400;
line-height: 1.5;
}
h1 {
font-size: 2.5rem;
}
h2 {
font-size: 2rem
}
h3 {
font-size: 1.75rem
}
h4 {
font-size: 1.5rem
}
h5 {
font-size: 1.25rem
}
h6 {
font-size: 1rem
}
.lead {
font-weight: 300;
font-size: 2rem;
}
.banner {
font-size: 2.7rem;
margin: 0;
padding: 2rem 1rem;
background-color: #00A1E2;
color: white;
}
body {
margin: 0;
font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
code {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 87.5%;
color: #e83e8c;
word-break: break-word;
}
.left-column {
padding: .75rem;
max-width: 75%;
min-width: 55%;
}
.right-column {
padding: .75rem;
max-width: 25%;
}
.container {
display: flex;
width: 100%;
}
li {
margin: 0.75rem;
}
.right-section {
margin-left: 1rem;
padding-left: 0.5rem;
}
.right-section h3 {
padding-top: 0;
font-weight: 200;
}
.right-section ul {
border-left: 0.3rem solid #00A1E2;
list-style-type: none;
padding-left: 0;
}
</style>
</head>
<body>
<div class="banner lead">
Your new Cloud-Native application is ready!
</div>
<div class="container">
<div class="left-column">
<p class="lead"> Congratulations, you have created a new Quarkus application.</p>
<h2>Why do you see this?</h2>
<p>This page is served by Quarkus. The source is in
<code>src/main/resources/META-INF/resources/index.html</code>.</p>
<h2>What can I do from here?</h2>
<p>If not already done, run the application in <em>dev mode</em> using: <code>mvn compile quarkus:dev</code>.
</p>
<ul>
<li>Add REST resources, Servlets, functions and other services in <code>src/main/java</code>.</li>
<li>Your static assets are located in <code>src/main/resources/META-INF/resources</code>.</li>
<li>Configure your application in <code>src/main/resources/application.properties</code>.
</li>
</ul>
<h2>How do I get rid of this page?</h2>
<p>Just delete the <code>src/main/resources/META-INF/resources/index.html</code> file.</p>
</div>
<div class="right-column">
<div class="right-section">
<h3>Application</h3>
<ul>
<li>GroupId: org.acme</li>
<li>ArtifactId: kubernetes</li>
<li>Version: 0.1-SNAPSHOT</li>
<li>Quarkus Version: 999-SNAPSHOT</li>
</ul>
</div>
<div class="right-section">
<h3>Next steps</h3>
<ul>
<li><a href="https://quarkus.io/guides/maven-tooling.html" target="_blank">Setup your IDE</a></li>
<li><a href="https://quarkus.io/guides/getting-started.html" target="_blank">Getting started</a></li>
<li><a href="https://quarkus.io" target="_blank">Quarkus Web Site</a></li>
</ul>
</div>
</div>
</div>
</body>
</html>

View File

@@ -1,28 +0,0 @@
import io.dekorate.utils.Serialization
import io.dekorate.deps.kubernetes.api.model.*
import io.dekorate.deps.kubernetes.api.model.apps.Deployment;
//Check that file exits
String base = basedir
File kubernetesYml = new File(base, "target/kubernetes/kubernetes.yml")
assert kubernetesYml.exists()
kubernetesYml.withInputStream { stream ->
//Check that its parse-able
KubernetesList list = Serialization.unmarshalAsList(stream)
assert list != null
Deployment deployment = list.items.find{r -> r.kind == "Deployment"}
assert deployment != null
assert deployment.metadata.name == "kubernetes-with-smallrye-health"
//Check that container has probes pointing to smallrye-health endpoint
Container container = deployment.spec.template.spec.containers.get(0)
assert container != null
Probe readiness = container.readinessProbe
assert readiness != null
assert readiness.httpGet.path == "/health/ready"
Probe liveness = container.livenessProbe
assert liveness != null
assert liveness.httpGet.path == "/health/live"
}

View File

@@ -80,5 +80,24 @@
<scope>test</scope>
</dependency>
</dependencies>
<build>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<includes>
<include>**/*.txt</include>
</includes>
<filtering>true</filtering>
</testResource>
<testResource>
<directory>src/test/resources</directory>
<excludes>
<exclude>**/*.txt</exclude>
</excludes>
<filtering>false</filtering>
</testResource>
</testResources>
</build>
</project>

View File

@@ -0,0 +1,94 @@
package io.quarkus.it.kubernetes;
import static io.restassured.RestAssured.given;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.is;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.Probe;
import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.quarkus.bootstrap.model.AppArtifact;
import io.quarkus.test.LogFile;
import io.quarkus.test.ProdBuildResults;
import io.quarkus.test.ProdModeTestResults;
import io.quarkus.test.QuarkusProdModeTest;
public class KubernetesWithHealthTest {
@RegisterExtension
static final QuarkusProdModeTest config = new QuarkusProdModeTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class))
.setApplicationName("health")
.setApplicationVersion("0.1-SNAPSHOT")
.setRun(true)
.setLogFileName("k8s.log")
.setForcedDependencies(
Collections.singletonList(
new AppArtifact("io.quarkus", "quarkus-smallrye-health", TestUtil.getProjectVersion())));
@ProdBuildResults
private ProdModeTestResults prodModeTestResults;
@LogFile
private Path logfile;
@Test
public void asertApplicationRuns() throws IOException {
assertThat(logfile).isRegularFile().hasFileName("k8s.log");
String entireLogContent = String.join("\n", Files.readAllLines(logfile));
assertThat(entireLogContent).contains("kubernetes").contains("health");
given()
.when().get("/greeting")
.then()
.statusCode(200)
.body(is("hello"));
}
@Test
public void assertGeneratedResources() throws IOException {
final Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes");
assertThat(kubernetesDir)
.isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.json"))
.isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.yml"));
List<HasMetadata> kubernetesList = DeserializationUtil
.deserializeAsList(kubernetesDir.resolve("kubernetes.yml"));
assertThat(kubernetesList.get(0)).isInstanceOfSatisfying(Deployment.class, d -> {
assertThat(d.getMetadata()).satisfies(m -> {
assertThat(m.getName()).isEqualTo("health");
});
assertThat(d.getSpec()).satisfies(deploymentSpec -> {
assertThat(deploymentSpec.getTemplate()).satisfies(t -> {
assertThat(t.getSpec()).satisfies(podSpec -> {
assertThat(podSpec.getContainers()).hasOnlyOneElementSatisfying(container -> {
assertThat(container.getReadinessProbe()).satisfies(p -> {
assertProbePath(p, "/health/ready");
});
assertThat(container.getLivenessProbe()).satisfies(p -> {
assertProbePath(p, "/health/live");
});
});
});
});
});
});
}
private void assertProbePath(Probe p, String expectedPath) {
assertThat(p.getHttpGet()).satisfies(h -> {
assertThat(h.getPath()).isEqualTo(expectedPath);
});
}
}

View File

@@ -0,0 +1,73 @@
package io.quarkus.it.kubernetes;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.Probe;
import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.quarkus.bootstrap.model.AppArtifact;
import io.quarkus.test.ProdBuildResults;
import io.quarkus.test.ProdModeTestResults;
import io.quarkus.test.QuarkusProdModeTest;
public class KubernetesWithRootAndHealthTest {
@RegisterExtension
static final QuarkusProdModeTest config = new QuarkusProdModeTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class))
.setApplicationName("root-and-health")
.setApplicationVersion("0.1-SNAPSHOT")
.withConfigurationResource("kubernetes-with-root-and-health.properties")
.setForcedDependencies(
Collections.singletonList(
new AppArtifact("io.quarkus", "quarkus-smallrye-health", TestUtil.getProjectVersion())));
@ProdBuildResults
private ProdModeTestResults prodModeTestResults;
@Test
public void assertGeneratedResources() throws IOException {
final Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes");
assertThat(kubernetesDir)
.isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.json"))
.isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.yml"));
List<HasMetadata> kubernetesList = DeserializationUtil
.deserializeAsList(kubernetesDir.resolve("kubernetes.yml"));
assertThat(kubernetesList.get(0)).isInstanceOfSatisfying(Deployment.class, d -> {
assertThat(d.getMetadata()).satisfies(m -> {
assertThat(m.getName()).isEqualTo("root-and-health");
});
assertThat(d.getSpec()).satisfies(deploymentSpec -> {
assertThat(deploymentSpec.getTemplate()).satisfies(t -> {
assertThat(t.getSpec()).satisfies(podSpec -> {
assertThat(podSpec.getContainers()).hasOnlyOneElementSatisfying(container -> {
assertThat(container.getReadinessProbe()).satisfies(p -> {
assertProbePath(p, "/api/health/ready");
});
assertThat(container.getLivenessProbe()).satisfies(p -> {
assertProbePath(p, "/api/health/liveness");
});
});
});
});
});
});
}
private void assertProbePath(Probe p, String expectedPath) {
assertThat(p.getHttpGet()).satisfies(h -> {
assertThat(h.getPath()).isEqualTo(expectedPath);
});
}
}

View File

@@ -1,4 +0,0 @@
package io.quarkus.it.kubernetes;
public class OpenshiftWithOverridenNameTest {
}

View File

@@ -0,0 +1,25 @@
package io.quarkus.it.kubernetes;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UncheckedIOException;
final class TestUtil {
private TestUtil() {
}
/**
* Gets the project version from a version.txt (that has been properly setup in maven to contain the version)
* This is needed in order to avoid hard-coding Quarkus dependency versions that could break the release process
*/
public static String getProjectVersion() {
try (BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(TestUtil.class.getResourceAsStream("/version.txt")))) {
return bufferedReader.readLine();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}

View File

@@ -0,0 +1,74 @@
package io.quarkus.it.kubernetes;
import static io.restassured.RestAssured.given;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.is;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.quarkus.bootstrap.model.AppArtifact;
import io.quarkus.test.LogFile;
import io.quarkus.test.ProdBuildResults;
import io.quarkus.test.ProdModeTestResults;
import io.quarkus.test.QuarkusProdModeTest;
public class WithKubernetesClientTest {
@RegisterExtension
static final QuarkusProdModeTest config = new QuarkusProdModeTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class))
.setApplicationName("kubernetes-with-client")
.setApplicationVersion("0.1-SNAPSHOT")
.setRun(true)
.setLogFileName("k8s.log")
.setForcedDependencies(
Collections.singletonList(
new AppArtifact("io.quarkus", "quarkus-kubernetes-client", TestUtil.getProjectVersion())));
@ProdBuildResults
private ProdModeTestResults prodModeTestResults;
@LogFile
private Path logfile;
@Test
public void asertApplicationRuns() throws IOException {
assertThat(logfile).isRegularFile().hasFileName("k8s.log");
String entireLogContent = String.join("\n", Files.readAllLines(logfile));
assertThat(entireLogContent).contains("kubernetes").contains("kubernetes-client");
given()
.when().get("/greeting")
.then()
.statusCode(200)
.body(is("hello"));
}
@Test
public void assertGeneratedResources() throws IOException {
final Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes");
assertThat(kubernetesDir)
.isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.json"))
.isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.yml"));
List<HasMetadata> kubernetesList = DeserializationUtil
.deserializeAsList(kubernetesDir.resolve("kubernetes.yml"));
assertThat(kubernetesList).filteredOn(h -> "ServiceAccount".equals(h.getKind())).hasOnlyOneElementSatisfying(h -> {
assertThat(h.getMetadata().getName()).isEqualTo("kubernetes-with-client");
});
assertThat(kubernetesList).filteredOn(h -> "RoleBinding".equals(h.getKind())).hasOnlyOneElementSatisfying(h -> {
assertThat(h.getMetadata().getName()).isEqualTo("kubernetes-with-client:view");
});
}
}

View File

@@ -0,0 +1 @@
${project.version}

View File

@@ -15,6 +15,7 @@ import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
@@ -42,6 +43,8 @@ import io.quarkus.bootstrap.app.AugmentAction;
import io.quarkus.bootstrap.app.AugmentResult;
import io.quarkus.bootstrap.app.CuratedApplication;
import io.quarkus.bootstrap.app.QuarkusBootstrap;
import io.quarkus.bootstrap.model.AppArtifact;
import io.quarkus.bootstrap.model.AppDependency;
import io.quarkus.test.common.PathTestHelper;
import io.quarkus.test.common.RestAssuredURLManager;
import io.quarkus.utilities.JavaBinFinder;
@@ -84,6 +87,7 @@ public class QuarkusProdModeTest
private Optional<Field> prodModeTestResultsField = Optional.empty();
private Path logfilePath;
private Optional<Field> logfileField = Optional.empty();
private List<AppArtifact> forcedDependencies = Collections.emptyList();
public Supplier<JavaArchive> getArchiveProducer() {
return archiveProducer;
@@ -148,6 +152,15 @@ public class QuarkusProdModeTest
return this;
}
/**
* Provides a convenient way to either add additional dependencies to the application (if it doesn't already contain a
* dependency), or override a version (if the dependency already exists)
*/
public QuarkusProdModeTest setForcedDependencies(List<AppArtifact> forcedDependencies) {
this.forcedDependencies = forcedDependencies;
return this;
}
private void exportArchive(Path deploymentDir, Class<?> testClass) {
try {
JavaArchive archive = getArchiveProducerOrDefault();
@@ -229,7 +242,9 @@ public class QuarkusProdModeTest
.setLocalProjectDiscovery(true)
.addExcludedPath(testLocation)
.setProjectRoot(testLocation)
.setTargetDirectory(buildDir);
.setTargetDirectory(buildDir)
.setForcedDependencies(forcedDependencies.stream().map(d -> new AppDependency(d, "compile"))
.collect(Collectors.toList()));
if (applicationName != null) {
builder.setBaseName(applicationName);
}