@ -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 ;
@ -56,16 +50,11 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
assertThat ( jar ) . isFile ( ) ;
File original = new File ( project , "target/build-image-0.0.1.BUILD-SNAPSHOT.jar.original" ) ;
assertThat ( original ) . doesNotExist ( ) ;
assertThat ( buildLog ( project ) ) . contains ( "Building image" ) . contains ( "paketo-buildpacks/builder" )
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" ) ;
} ) ;
}
@ -79,15 +68,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" ) ;
} ) ;
}
@ -103,15 +86,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" ) ;
} ) ;
}
@ -124,17 +101,11 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
File original = new File ( project ,
"target/build-image-with-repackage-0.0.1.BUILD-SNAPSHOT.jar.original" ) ;
assertThat ( original ) . isFile ( ) ;
assertThat ( buildLog ( project ) ) . contains ( "Building image" ) . contains ( "paketo-buildpacks/builder" )
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" ) ;
} ) ;
}
@ -150,15 +121,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" ) ;
} ) ;
}
@ -174,15 +139,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" ) ;
} ) ;
}
@ -198,53 +157,40 @@ 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" ) ;
} ) ;
}
@TestTemplate
void whenBuildImageIsInvokedWithCommandLineParameters ( MavenBuild mavenBuild ) {
mavenBuild . project ( "build-image ") . goals ( "package" )
mavenBuild . project ( "build-image-cmd-line" ) . goals ( "package" )
. 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 ( "paketobuildpacks/builder:full" )
. contains ( "paketobuildpacks/run:full-cnb" ) . 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 ( "spring-boot-cnb-builder:0.0.1" )
. contains ( "projects.registry.vmware.com/springboot/run:tiny-cnb" )
. contains ( "---> Test Info buildpack building" ) . contains ( "---> Test Info buildpack done" )
. contains ( "Successfully built image" ) ;
removeImage ( "example.com/test/cmd-property-name" , "v1" ) ;
} ) ;
}
@TestTemplate
void whenBuildImageIsInvokedWithCustomBuilderImageAndRunImage ( MavenBuild mavenBuild ) {
mavenBuild . project ( "build-image-custom-builder" ) . goals ( "package" ) . execute ( ( project ) - > {
assertThat ( buildLog ( project ) ) . contains ( "Building image" ) . contains ( "paketobuildpacks/builder:full" )
. contains ( "paketobuildpacks/run:full-cnb" )
assertThat ( buildLog ( project ) ) . contains ( "Building image" )
. contains ( "docker.io/library/build-image-v2-builder:0.0.1.BUILD-SNAPSHOT" )
. contains ( "projects.registry.vmware.com/springboot/spring-boot-cnb-builder:0.0.1" )
. contains ( "projects.registry.vmware.com/springboot/run:tiny-cnb" )
. 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" ) ;
} ) ;
}
@ -252,52 +198,33 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests {
void whenBuildImageIsInvokedWithEmptyEnvEntry ( MavenBuild mavenBuild ) {
mavenBuild . project ( "build-image-empty-env-entry" ) . goals ( "package" ) . prepare ( this : : writeLongNameResource )
. execute ( ( project ) - > {
assertThat ( buildLog ( project ) ) . contains ( "Building image" ) . contains ( "paketo-buildpacks/builder" )
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" ) ;
mavenBuild . goals ( "package" ) ;
mavenBuild . prepare ( this : : writeLongNameResource ) ;
mavenBuild . 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 ( "paketo-buildpacks/builder" )
. contains ( "docker.io/library/build-image-zip-packaging:0.0.1.BUILD-SNAPSHOT" )
. 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 ;
mavenBuild . project ( "build-image-zip-packaging" ) . goals ( "package" ) . prepare ( this : : writeLongNameResource )
. 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" ) ;
removeImage ( "build-image-zip-packaging" , "0.0.1.BUILD-SNAPSHOT" ) ;
} ) ;
}
finally {
removeImage ( imageReference ) ;
}
} ) ;
}
@TestTemplate
void failsWhenBuilderFails ( MavenBuild mavenBuild ) {
mavenBuild . project ( "build-image-builder-error" ) . goals ( "package" )
. executeAndFail ( ( project ) - > assertThat ( buildLog ( project ) ) . contains ( "Building image" )
. contains ( "---> Test Info buildpack building" ) . contains ( "Forced builder failure" )
. containsPattern ( "Builder lifecycle '.*' failed with status code" ) ) ;
}
@ -327,7 +254,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 ) ;
}