@ -16,21 +16,15 @@
package org.springframework.boot.maven ;
import java.io.BufferedReader ;
import java.io.File ;
import java.io.IOException ;
import java.io.InputStreamReader ;
import java.nio.charset.StandardCharsets ;
import java.nio.file.Files ;
import java.nio.file.Path ;
import java.nio.file.Paths ;
import java.util.Random ;
import java.util.stream.Collectors ;
import org.junit.jupiter.api.TestTemplate ;
import org.junit.jupiter.api.extension.ExtendWith ;
import org.testcontainers.containers.GenericContainer ;
import org.testcontainers.containers.wait.strategy.Wait ;
import org.springframework.boot.buildpack.platform.docker.DockerApi ;
import org.springframework.boot.buildpack.platform.docker.type.ImageName ;
@ -60,15 +54,9 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
assertThat ( original ) . doesNotExist ( ) ;
assertThat ( buildLog ( project ) ) . contains ( "Building image" )
. contains ( "docker.io/library/build-image:0.0.1.BUILD-SNAPSHOT" )
. contains ( "Successfully built image" ) ;
ImageReference imageReference = ImageReference . of ( ImageName . of ( "build-image" ) ,
"0.0.1.BUILD-SNAPSHOT" ) ;
try ( GenericContainer < ? > container = new GenericContainer < > ( imageReference . toString ( ) ) ) {
container . waitingFor ( Wait . forLogMessage ( "Launched\\n" , 1 ) ) . start ( ) ;
}
finally {
removeImage ( imageReference ) ;
}
. contains ( "---> Test Info buildpack building" ) . contains ( "env: BP_JVM_VERSION=8.*" )
. contains ( "---> Test Info buildpack done" ) . contains ( "Successfully built image" ) ;
removeImage ( "build-image" , "0.0.1.BUILD-SNAPSHOT" ) ;
} ) ;
}
@ -83,15 +71,9 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
assertThat ( classifier ) . doesNotExist ( ) ;
assertThat ( buildLog ( project ) ) . contains ( "Building image" )
. contains ( "docker.io/library/build-image-classifier:0.0.1.BUILD-SNAPSHOT" )
. contains ( "Successfully built image" ) ;
ImageReference imageReference = ImageReference . of ( ImageName . of ( "build-image-classifier" ) ,
"0.0.1.BUILD-SNAPSHOT" ) ;
try ( GenericContainer < ? > container = new GenericContainer < > ( imageReference . toString ( ) ) ) {
container . waitingFor ( Wait . forLogMessage ( "Launched\\n" , 1 ) ) . start ( ) ;
}
finally {
removeImage ( imageReference ) ;
}
. contains ( "---> Test Info buildpack building" ) . contains ( "env: BP_JVM_VERSION=8.*" )
. contains ( "---> Test Info buildpack done" ) . contains ( "Successfully built image" ) ;
removeImage ( "build-image-classifier" , "0.0.1.BUILD-SNAPSHOT" ) ;
} ) ;
}
@ -108,15 +90,9 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
assertThat ( original ) . doesNotExist ( ) ;
assertThat ( buildLog ( project ) ) . contains ( "Building image" )
. contains ( "docker.io/library/build-image-classifier-source:0.0.1.BUILD-SNAPSHOT" )
. contains ( "---> Test Info buildpack building" ) . contains ( "---> Test Info buildpack done" )
. contains ( "Successfully built image" ) ;
ImageReference imageReference = ImageReference . of ( ImageName . of ( "build-image-classifier-source" ) ,
"0.0.1.BUILD-SNAPSHOT" ) ;
try ( GenericContainer < ? > container = new GenericContainer < > ( imageReference . toString ( ) ) ) {
container . waitingFor ( Wait . forLogMessage ( "Launched\\n" , 1 ) ) . start ( ) ;
}
finally {
removeImage ( imageReference ) ;
}
removeImage ( "build-image-classifier-source" , "0.0.1.BUILD-SNAPSHOT" ) ;
} ) ;
}
@ -132,15 +108,9 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
assertThat ( original ) . isFile ( ) ;
assertThat ( buildLog ( project ) ) . contains ( "Building image" )
. contains ( "docker.io/library/build-image-with-repackage:0.0.1.BUILD-SNAPSHOT" )
. contains ( "---> Test Info buildpack building" ) . contains ( "---> Test Info buildpack done" )
. contains ( "Successfully built image" ) ;
ImageReference imageReference = ImageReference . of ( ImageName . of ( "build-image-with-repackage" ) ,
"0.0.1.BUILD-SNAPSHOT" ) ;
try ( GenericContainer < ? > container = new GenericContainer < > ( imageReference . toString ( ) ) ) {
container . waitingFor ( Wait . forLogMessage ( "Launched\\n" , 1 ) ) . start ( ) ;
}
finally {
removeImage ( imageReference ) ;
}
removeImage ( "build-image-with-repackage" , "0.0.1.BUILD-SNAPSHOT" ) ;
} ) ;
}
@ -157,15 +127,9 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
assertThat ( original ) . isFile ( ) ;
assertThat ( buildLog ( project ) ) . contains ( "Building image" )
. contains ( "docker.io/library/build-image-classifier-with-repackage:0.0.1.BUILD-SNAPSHOT" )
. contains ( "---> Test Info buildpack building" ) . contains ( "---> Test Info buildpack done" )
. contains ( "Successfully built image" ) ;
ImageReference imageReference = ImageReference
. of ( ImageName . of ( "build-image-classifier-with-repackage" ) , "0.0.1.BUILD-SNAPSHOT" ) ;
try ( GenericContainer < ? > container = new GenericContainer < > ( imageReference . toString ( ) ) ) {
container . waitingFor ( Wait . forLogMessage ( "Launched\\n" , 1 ) ) . start ( ) ;
}
finally {
removeImage ( imageReference ) ;
}
removeImage ( "build-image-classifier-with-repackage" , "0.0.1.BUILD-SNAPSHOT" ) ;
} ) ;
}
@ -182,15 +146,9 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
assertThat ( original ) . isFile ( ) ;
assertThat ( buildLog ( project ) ) . contains ( "Building image" ) . contains (
"docker.io/library/build-image-classifier-source-with-repackage:0.0.1.BUILD-SNAPSHOT" )
. contains ( "---> Test Info buildpack building" ) . contains ( "---> Test Info buildpack done" )
. contains ( "Successfully built image" ) ;
ImageReference imageReference = ImageReference
. of ( ImageName . of ( "build-image-classifier-source-with-repackage" ) , "0.0.1.BUILD-SNAPSHOT" ) ;
try ( GenericContainer < ? > container = new GenericContainer < > ( imageReference . toString ( ) ) ) {
container . waitingFor ( Wait . forLogMessage ( "Launched\\n" , 1 ) ) . start ( ) ;
}
finally {
removeImage ( imageReference ) ;
}
removeImage ( "build-image-classifier-source-with-repackage" , "0.0.1.BUILD-SNAPSHOT" ) ;
} ) ;
}
@ -206,15 +164,9 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
assertThat ( original ) . doesNotExist ( ) ;
assertThat ( buildLog ( project ) ) . contains ( "Building image" )
. contains ( "docker.io/library/build-image-war-packaging:0.0.1.BUILD-SNAPSHOT" )
. contains ( "---> Test Info buildpack building" ) . contains ( "---> Test Info buildpack done" )
. contains ( "Successfully built image" ) ;
ImageReference imageReference = ImageReference . of ( ImageName . of ( "build-image-war-packaging" ) ,
"0.0.1.BUILD-SNAPSHOT" ) ;
try ( GenericContainer < ? > container = new GenericContainer < > ( imageReference . toString ( ) ) ) {
container . waitingFor ( Wait . forLogMessage ( "Launched\\n" , 1 ) ) . start ( ) ;
}
finally {
removeImage ( imageReference ) ;
}
removeImage ( "build-image-war-packaging" , "0.0.1.BUILD-SNAPSHOT" ) ;
} ) ;
}
@ -231,15 +183,9 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
assertThat ( original ) . doesNotExist ( ) ;
assertThat ( buildLog ( project ) ) . contains ( "Building image" )
. contains ( "example.com/test/build-image:0.0.1.BUILD-SNAPSHOT" )
. contains ( "---> Test Info buildpack building" ) . contains ( "---> Test Info buildpack done" )
. contains ( "Successfully built image" ) ;
ImageReference imageReference = ImageReference
. of ( "example.com/test/build-image:0.0.1.BUILD-SNAPSHOT" ) ;
try ( GenericContainer < ? > container = new GenericContainer < > ( imageReference . toString ( ) ) ) {
container . waitingFor ( Wait . forLogMessage ( "Launched\\n" , 1 ) ) . start ( ) ;
}
finally {
removeImage ( imageReference ) ;
}
removeImage ( "example.com/test/build-image" , "0.0.1.BUILD-SNAPSHOT" ) ;
} ) ;
}
@ -248,18 +194,16 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
mavenBuild . project ( "build-image" ) . goals ( "package" )
. systemProperty ( "spring-boot.build-image.pullPolicy" , "IF_NOT_PRESENT" )
. systemProperty ( "spring-boot.build-image.imageName" , "example.com/test/cmd-property-name:v1" )
. systemProperty ( "spring-boot.build-image.builder" , "paketobuildpacks/builder:full" )
. systemProperty ( "spring-boot.build-image.runImage" , "paketobuildpacks/run:full-cnb" )
. systemProperty ( "spring-boot.build-image.builder" ,
"projects.registry.vmware.com/springboot/spring-boot-cnb-builder:0.0.1" )
. systemProperty ( "spring-boot.build-image.runImage" ,
"projects.registry.vmware.com/springboot/run:tiny-cnb" )
. execute ( ( project ) - > {
assertThat ( buildLog ( project ) ) . contains ( "Building image" )
. contains ( "example.com/test/cmd-property-name:v1" ) . contains ( "Successfully built image" ) ;
ImageReference imageReference = ImageReference . of ( "example.com/test/cmd-property-name:v1" ) ;
try ( GenericContainer < ? > container = new GenericContainer < > ( imageReference . toString ( ) ) ) {
container . waitingFor ( Wait . forLogMessage ( "Launched\\n" , 1 ) ) . start ( ) ;
}
finally {
removeImage ( imageReference ) ;
}
. contains ( "example.com/test/cmd-property-name:v1" )
. contains ( "---> Test Info buildpack building" ) . contains ( "---> Test Info buildpack done" )
. contains ( "Successfully built image" ) ;
removeImage ( "example.com/test/cmd-property-name" , "v1" ) ;
} ) ;
}
@ -269,15 +213,9 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
. systemProperty ( "spring-boot.build-image.pullPolicy" , "IF_NOT_PRESENT" ) . execute ( ( project ) - > {
assertThat ( buildLog ( project ) ) . contains ( "Building image" )
. contains ( "docker.io/library/build-image-v2-builder:0.0.1.BUILD-SNAPSHOT" )
. contains ( "---> Test Info buildpack building" ) . contains ( "---> Test Info buildpack done" )
. contains ( "Successfully built image" ) ;
ImageReference imageReference = ImageReference
. of ( "docker.io/library/build-image-v2-builder:0.0.1.BUILD-SNAPSHOT" ) ;
try ( GenericContainer < ? > container = new GenericContainer < > ( imageReference . toString ( ) ) ) {
container . waitingFor ( Wait . forLogMessage ( "Launched\\n" , 1 ) ) . start ( ) ;
}
finally {
removeImage ( imageReference ) ;
}
removeImage ( "docker.io/library/build-image-v2-builder" , "0.0.1.BUILD-SNAPSHOT" ) ;
} ) ;
}
@ -288,42 +226,23 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
. prepare ( this : : writeLongNameResource ) . execute ( ( project ) - > {
assertThat ( buildLog ( project ) ) . contains ( "Building image" )
. contains ( "docker.io/library/build-image-empty-env-entry:0.0.1.BUILD-SNAPSHOT" )
. contains ( "---> Test Info buildpack building" ) . contains ( "---> Test Info buildpack done" )
. contains ( "Successfully built image" ) ;
ImageReference imageReference = ImageReference . of ( ImageName . of ( "build-image-empty-env-entry" ) ,
"0.0.1.BUILD-SNAPSHOT" ) ;
try ( GenericContainer < ? > container = new GenericContainer < > ( imageReference . toString ( ) ) ) {
container . waitingFor ( Wait . forLogMessage ( "Launched\\n" , 1 ) ) . start ( ) ;
}
finally {
removeImage ( imageReference ) ;
}
removeImage ( "build-image-empty-env-entry" , "0.0.1.BUILD-SNAPSHOT" ) ;
} ) ;
}
@TestTemplate
void whenBuildImageIsInvokedWithZipPackaging ( MavenBuild mavenBuild ) {
mavenBuild . project ( "build-image-zip-packaging" ) . goals ( "package" )
. systemProperty ( "spring-boot.build-image.pullPolicy" , "IF_NOT_PRESENT" )
. prepare ( this : : writeLongNameResource ) . execute ( ( project ) - > {
mavenBuild . project ( "build-image-zip-packaging" ) . goals ( "package" ) . prepare ( this : : writeLongNameResource )
. systemProperty ( "spring-boot.build-image.pullPolicy" , "IF_NOT_PRESENT" ) . execute ( ( project ) - > {
File jar = new File ( project , "target/build-image-zip-packaging-0.0.1.BUILD-SNAPSHOT.jar" ) ;
assertThat ( jar ) . isFile ( ) ;
assertThat ( buildLog ( project ) ) . contains ( "Building image" )
. contains ( "docker.io/library/build-image-zip-packaging:0.0.1.BUILD-SNAPSHOT" )
. contains ( "Main-Class: org.springframework.boot.loader.PropertiesLauncher" )
. contains ( "Successfully built image" ) ;
ImageReference imageReference = ImageReference . of ( ImageName . of ( "build-image-zip-packaging" ) ,
"0.0.1.BUILD-SNAPSHOT" ) ;
try ( GenericContainer < ? > container = new GenericContainer < > ( imageReference . toString ( ) ) ) {
container . waitingFor ( Wait . forLogMessage ( "Launched\\n" , 1 ) ) . start ( ) ;
container . copyFileFromContainer ( "/workspace/META-INF/MANIFEST.MF" , ( inputStream ) - > {
String text = new BufferedReader ( new InputStreamReader ( inputStream , StandardCharsets . UTF_8 ) )
. lines ( ) . collect ( Collectors . joining ( "\n" ) ) ;
assertThat ( text ) . contains ( "Main-Class: org.springframework.boot.loader.PropertiesLauncher" ) ;
return null ;
} ) ;
}
finally {
removeImage ( imageReference ) ;
}
removeImage ( "build-image-zip-packaging" , "0.0.1.BUILD-SNAPSHOT" ) ;
} ) ;
}
@ -334,24 +253,21 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
assertThat ( buildLog ( project ) ) . contains ( "Building image" )
. contains ( "docker.io/library/build-image-custom-buildpacks:0.0.1.BUILD-SNAPSHOT" )
. contains ( "Successfully built image" ) ;
ImageReference imageReference = ImageReference
. of ( "docker.io/library/build-image-custom-buildpacks:0.0.1.BUILD-SNAPSHOT" ) ;
try ( GenericContainer < ? > container = new GenericContainer < > ( imageReference . toString ( ) ) ) {
container . waitingFor ( Wait . forLogMessage ( "Launched\\n" , 1 ) ) . start ( ) ;
}
finally {
removeImage ( imageReference ) ;
}
removeImage ( "build-image-custom-buildpacks" , "0.0.1.BUILD-SNAPSHOT" ) ;
} ) ;
}
@TestTemplate
void failsWithBindingContainingInvalidCertificate ( MavenBuild mavenBuild ) {
void whenBuildImageIsInvokedWithBinding ( MavenBuild mavenBuild ) {
mavenBuild . project ( "build-image-bindings" ) . goals ( "package" )
. systemProperty ( "spring-boot.build-image.pullPolicy" , "IF_NOT_PRESENT" )
. executeAndFail ( ( project ) - > assertThat ( buildLog ( project ) ) . contains ( "Building image" )
. contains ( "failed to decode certificate" )
. contains ( "/platform/bindings/ca-certificates/test.crt" ) ) ;
. systemProperty ( "spring-boot.build-image.pullPolicy" , "IF_NOT_PRESENT" ) . execute ( ( project ) - > {
assertThat ( buildLog ( project ) ) . contains ( "Building image" )
. contains ( "docker.io/library/build-image-bindings:0.0.1.BUILD-SNAPSHOT" )
. contains ( "binding: ca-certificates/type=ca-certificates" )
. contains ( "binding: ca-certificates/test.crt=---certificate one---" )
. contains ( "Successfully built image" ) ;
removeImage ( "build-image-bindings" , "0.0.1.BUILD-SNAPSHOT" ) ;
} ) ;
}
@TestTemplate
@ -365,6 +281,7 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
mavenBuild . project ( "build-image-builder-error" ) . goals ( "package" )
. systemProperty ( "spring-boot.build-image.pullPolicy" , "IF_NOT_PRESENT" )
. executeAndFail ( ( project ) - > assertThat ( buildLog ( project ) ) . contains ( "Building image" )
. contains ( "---> Test Info buildpack building" ) . contains ( "Forced builder failure" )
. containsPattern ( "Builder lifecycle '.*' failed with status code" ) ) ;
}
@ -396,7 +313,8 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
}
}
private void removeImage ( ImageReference imageReference ) {
private void removeImage ( String name , String version ) {
ImageReference imageReference = ImageReference . of ( ImageName . of ( name ) , version ) ;
try {
new DockerApi ( ) . image ( ) . remove ( imageReference , false ) ;
}