2021-08-18 12:10:55 +02:00
package cmd
import (
"fmt"
2021-10-01 13:48:24 +02:00
"net/http"
2021-08-18 12:10:55 +02:00
"testing"
2021-09-14 16:14:50 +02:00
"github.com/SAP/jenkins-library/pkg/cnbutils"
2021-10-01 13:48:24 +02:00
piperhttp "github.com/SAP/jenkins-library/pkg/http"
2021-08-18 12:10:55 +02:00
"github.com/SAP/jenkins-library/pkg/mock"
"github.com/SAP/jenkins-library/pkg/telemetry"
2021-10-11 11:33:51 +02:00
"github.com/jarcoal/httpmock"
2021-08-18 12:10:55 +02:00
"github.com/stretchr/testify/assert"
)
2021-09-14 16:14:50 +02:00
func newCnbBuildTestsUtils ( ) cnbutils . MockUtils {
utils := cnbutils . MockUtils {
2021-08-18 12:10:55 +02:00
ExecMockRunner : & mock . ExecMockRunner { } ,
FilesMock : & mock . FilesMock { } ,
2021-09-14 16:14:50 +02:00
DockerMock : & cnbutils . DockerMock { } ,
2021-08-18 12:10:55 +02:00
}
return utils
}
2021-09-14 16:14:50 +02:00
func addBuilderFiles ( utils * cnbutils . MockUtils ) {
2021-09-14 15:38:58 +02:00
for _ , path := range [ ] string { detectorPath , builderPath , exporterPath } {
utils . FilesMock . AddFile ( path , [ ] byte ( ` xyz ` ) )
}
}
2021-08-18 12:10:55 +02:00
func TestRunCnbBuild ( t * testing . T ) {
t . Parallel ( )
commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment { }
2021-08-26 14:26:54 +02:00
t . Run ( "success case (registry with https)" , func ( t * testing . T ) {
2021-08-18 12:10:55 +02:00
t . Parallel ( )
2021-08-26 14:26:54 +02:00
registry := "some-registry"
2021-08-18 12:10:55 +02:00
config := cnbBuildOptions {
ContainerImageName : "my-image" ,
ContainerImageTag : "0.0.1" ,
2021-08-26 14:26:54 +02:00
ContainerRegistryURL : fmt . Sprintf ( "https://%s" , registry ) ,
2021-08-18 12:10:55 +02:00
DockerConfigJSON : "/path/to/config.json" ,
}
utils := newCnbBuildTestsUtils ( )
utils . FilesMock . AddFile ( config . DockerConfigJSON , [ ] byte ( ` { "auths": { "my-registry": { "auth":"dXNlcjpwYXNz"}}} ` ) )
2021-09-14 15:38:58 +02:00
addBuilderFiles ( & utils )
2021-08-18 12:10:55 +02:00
2021-10-01 13:48:24 +02:00
err := runCnbBuild ( & config , & telemetry . CustomData { } , & utils , & commonPipelineEnvironment , & piperhttp . Client { } )
2021-08-18 12:10:55 +02:00
assert . NoError ( t , err )
runner := utils . ExecMockRunner
assert . Contains ( t , runner . Env , "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}" )
assert . Equal ( t , "/cnb/lifecycle/detector" , runner . Calls [ 0 ] . Exec )
assert . Equal ( t , "/cnb/lifecycle/builder" , runner . Calls [ 1 ] . Exec )
assert . Equal ( t , "/cnb/lifecycle/exporter" , runner . Calls [ 2 ] . Exec )
2021-11-03 13:37:26 +02:00
assert . Equal ( t , [ ] string { "-buildpacks" , "/cnb/buildpacks" , "-order" , "/cnb/order.toml" , "-platform" , "/tmp/platform" } , runner . Calls [ 0 ] . Params )
assert . Equal ( t , [ ] string { "-buildpacks" , "/cnb/buildpacks" , "-platform" , "/tmp/platform" } , runner . Calls [ 1 ] . Params )
2021-10-08 11:20:05 +02:00
assert . Equal ( t , [ ] string { fmt . Sprintf ( "%s/%s:%s" , registry , config . ContainerImageName , config . ContainerImageTag ) } , runner . Calls [ 2 ] . Params )
2021-08-26 14:26:54 +02:00
} )
t . Run ( "success case (registry without https)" , func ( t * testing . T ) {
t . Parallel ( )
registry := "some-registry"
config := cnbBuildOptions {
ContainerImageName : "my-image" ,
ContainerImageTag : "0.0.1" ,
ContainerRegistryURL : registry ,
DockerConfigJSON : "/path/to/config.json" ,
}
utils := newCnbBuildTestsUtils ( )
utils . FilesMock . AddFile ( config . DockerConfigJSON , [ ] byte ( ` { "auths": { "my-registry": { "auth":"dXNlcjpwYXNz"}}} ` ) )
2021-09-14 15:38:58 +02:00
addBuilderFiles ( & utils )
2021-08-26 14:26:54 +02:00
2021-10-01 13:48:24 +02:00
err := runCnbBuild ( & config , & telemetry . CustomData { } , & utils , & commonPipelineEnvironment , & piperhttp . Client { } )
2021-09-14 16:14:50 +02:00
assert . NoError ( t , err )
runner := utils . ExecMockRunner
assert . Contains ( t , runner . Env , "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}" )
assert . Equal ( t , "/cnb/lifecycle/detector" , runner . Calls [ 0 ] . Exec )
assert . Equal ( t , "/cnb/lifecycle/builder" , runner . Calls [ 1 ] . Exec )
assert . Equal ( t , "/cnb/lifecycle/exporter" , runner . Calls [ 2 ] . Exec )
2021-11-03 13:37:26 +02:00
assert . Equal ( t , [ ] string { "-buildpacks" , "/cnb/buildpacks" , "-order" , "/cnb/order.toml" , "-platform" , "/tmp/platform" } , runner . Calls [ 0 ] . Params )
assert . Equal ( t , [ ] string { "-buildpacks" , "/cnb/buildpacks" , "-platform" , "/tmp/platform" } , runner . Calls [ 1 ] . Params )
2021-10-08 11:20:05 +02:00
assert . Equal ( t , [ ] string { fmt . Sprintf ( "%s/%s:%s" , registry , config . ContainerImageName , config . ContainerImageTag ) } , runner . Calls [ 2 ] . Params )
2021-09-14 16:14:50 +02:00
} )
2021-10-08 11:20:05 +02:00
t . Run ( "success case (custom buildpacks and custom env variables, renaming docker conf file, additional tag)" , func ( t * testing . T ) {
2021-09-14 16:14:50 +02:00
t . Parallel ( )
registry := "some-registry"
config := cnbBuildOptions {
ContainerImageName : "my-image" ,
ContainerImageTag : "0.0.1" ,
ContainerRegistryURL : registry ,
2021-10-01 10:05:15 +02:00
DockerConfigJSON : "/path/to/test.json" ,
2021-09-14 16:14:50 +02:00
Buildpacks : [ ] string { "test" } ,
2021-09-29 18:21:13 +02:00
BuildEnvVars : [ ] string { "FOO=BAR" } ,
2021-10-08 11:20:05 +02:00
AdditionalTags : [ ] string { "latest" } ,
2021-09-14 16:14:50 +02:00
}
utils := newCnbBuildTestsUtils ( )
utils . FilesMock . AddFile ( config . DockerConfigJSON , [ ] byte ( ` { "auths": { "my-registry": { "auth":"dXNlcjpwYXNz"}}} ` ) )
addBuilderFiles ( & utils )
2021-10-01 13:48:24 +02:00
err := runCnbBuild ( & config , & telemetry . CustomData { } , & utils , & commonPipelineEnvironment , & piperhttp . Client { } )
2021-08-26 14:26:54 +02:00
assert . NoError ( t , err )
runner := utils . ExecMockRunner
assert . Contains ( t , runner . Env , "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}" )
assert . Equal ( t , "/cnb/lifecycle/detector" , runner . Calls [ 0 ] . Exec )
assert . Equal ( t , "/cnb/lifecycle/builder" , runner . Calls [ 1 ] . Exec )
assert . Equal ( t , "/cnb/lifecycle/exporter" , runner . Calls [ 2 ] . Exec )
2021-09-29 18:21:13 +02:00
assert . Equal ( t , [ ] string { "-buildpacks" , "/tmp/buildpacks" , "-order" , "/tmp/buildpacks/order.toml" , "-platform" , "/tmp/platform" } , runner . Calls [ 0 ] . Params )
assert . Equal ( t , [ ] string { "-buildpacks" , "/tmp/buildpacks" , "-platform" , "/tmp/platform" } , runner . Calls [ 1 ] . Params )
2021-08-26 14:26:54 +02:00
assert . Equal ( t , [ ] string { fmt . Sprintf ( "%s/%s:%s" , registry , config . ContainerImageName , config . ContainerImageTag ) , fmt . Sprintf ( "%s/%s:latest" , registry , config . ContainerImageName ) } , runner . Calls [ 2 ] . Params )
2021-08-18 12:10:55 +02:00
} )
2021-10-01 13:48:24 +02:00
t . Run ( "success case (customTlsCertificates)" , func ( t * testing . T ) {
t . Parallel ( )
2021-10-11 11:33:51 +02:00
httpmock . Activate ( )
defer httpmock . DeactivateAndReset ( )
httpmock . RegisterResponder ( http . MethodGet , "https://test-cert.com/cert.crt" , httpmock . NewStringResponder ( 200 , "testCert" ) )
client := & piperhttp . Client { }
client . SetOptions ( piperhttp . ClientOptions { MaxRetries : - 1 , UseDefaultTransport : true } )
2021-10-01 13:48:24 +02:00
caCertsFile := "/etc/ssl/certs/ca-certificates.crt"
2021-10-07 16:04:20 +02:00
caCertsTmpFile := "/tmp/ca-certificates.crt"
2021-10-01 13:48:24 +02:00
registry := "some-registry"
config := cnbBuildOptions {
ContainerImageName : "my-image" ,
ContainerImageTag : "0.0.1" ,
ContainerRegistryURL : registry ,
DockerConfigJSON : "/path/to/config.json" ,
Buildpacks : [ ] string { "test" } ,
2021-10-11 11:33:51 +02:00
CustomTLSCertificateLinks : [ ] string { "https://test-cert.com/cert.crt" , "https://test-cert.com/cert.crt" } ,
2021-10-01 13:48:24 +02:00
}
utils := newCnbBuildTestsUtils ( )
utils . FilesMock . AddFile ( caCertsFile , [ ] byte ( "test\n" ) )
utils . FilesMock . AddFile ( config . DockerConfigJSON , [ ] byte ( ` { "auths": { "my-registry": { "auth":"dXNlcjpwYXNz"}}} ` ) )
addBuilderFiles ( & utils )
2021-10-11 11:33:51 +02:00
err := runCnbBuild ( & config , & telemetry . CustomData { } , & utils , & commonPipelineEnvironment , client )
2021-10-01 13:48:24 +02:00
assert . NoError ( t , err )
2021-10-07 16:04:20 +02:00
result , err := utils . FilesMock . FileRead ( caCertsTmpFile )
2021-10-01 13:48:24 +02:00
assert . NoError ( t , err )
assert . Equal ( t , "test\ntestCert\ntestCert\n" , string ( result ) )
assert . NoError ( t , err )
runner := utils . ExecMockRunner
assert . Contains ( t , runner . Env , "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}" )
2021-10-07 16:04:20 +02:00
assert . Contains ( t , runner . Env , fmt . Sprintf ( "SSL_CERT_FILE=%s" , caCertsTmpFile ) )
2021-10-01 13:48:24 +02:00
assert . Equal ( t , "/cnb/lifecycle/detector" , runner . Calls [ 0 ] . Exec )
assert . Equal ( t , "/cnb/lifecycle/builder" , runner . Calls [ 1 ] . Exec )
assert . Equal ( t , "/cnb/lifecycle/exporter" , runner . Calls [ 2 ] . Exec )
2021-11-03 13:37:26 +02:00
assert . Equal ( t , [ ] string { "-buildpacks" , "/tmp/buildpacks" , "-order" , "/tmp/buildpacks/order.toml" , "-platform" , "/tmp/platform" } , runner . Calls [ 0 ] . Params )
assert . Equal ( t , [ ] string { "-buildpacks" , "/tmp/buildpacks" , "-platform" , "/tmp/platform" } , runner . Calls [ 1 ] . Params )
2021-10-08 11:20:05 +02:00
assert . Equal ( t , [ ] string { fmt . Sprintf ( "%s/%s:%s" , registry , config . ContainerImageName , config . ContainerImageTag ) } , runner . Calls [ 2 ] . Params )
} )
t . Run ( "success case (additionalTags)" , func ( t * testing . T ) {
t . Parallel ( )
registry := "some-registry"
config := cnbBuildOptions {
ContainerImageName : "my-image" ,
ContainerImageTag : "3.1.5" ,
ContainerRegistryURL : registry ,
DockerConfigJSON : "/path/to/config.json" ,
Buildpacks : [ ] string { "test" } ,
AdditionalTags : [ ] string { "3" , "3.1" , "3.1" , "3.1.5" } ,
}
utils := newCnbBuildTestsUtils ( )
utils . FilesMock . AddFile ( config . DockerConfigJSON , [ ] byte ( ` { "auths": { "my-registry": { "auth":"dXNlcjpwYXNz"}}} ` ) )
addBuilderFiles ( & utils )
err := runCnbBuild ( & config , & telemetry . CustomData { } , & utils , & commonPipelineEnvironment , & piperhttp . Client { } )
assert . NoError ( t , err )
runner := utils . ExecMockRunner
assert . Equal ( t , "/cnb/lifecycle/exporter" , runner . Calls [ 2 ] . Exec )
assert . ElementsMatch ( t , [ ] string { fmt . Sprintf ( "%s/%s:%s" , registry , config . ContainerImageName , config . ContainerImageTag ) , fmt . Sprintf ( "%s/%s:3" , registry , config . ContainerImageName ) , fmt . Sprintf ( "%s/%s:3.1" , registry , config . ContainerImageName ) } , runner . Calls [ 2 ] . Params )
2021-10-01 13:48:24 +02:00
} )
2021-08-18 12:10:55 +02:00
t . Run ( "error case: Invalid DockerConfigJSON file" , func ( t * testing . T ) {
t . Parallel ( )
config := cnbBuildOptions {
2021-08-26 14:26:54 +02:00
ContainerImageName : "my-image" ,
DockerConfigJSON : "/path/to/config.json" ,
2021-08-18 12:10:55 +02:00
}
utils := newCnbBuildTestsUtils ( )
utils . FilesMock . AddFile ( config . DockerConfigJSON , [ ] byte ( ` { "auths": { "my-registry":"dXNlcjpwYXNz"}} ` ) )
2021-09-14 15:38:58 +02:00
addBuilderFiles ( & utils )
2021-08-18 12:10:55 +02:00
2021-10-01 13:48:24 +02:00
err := runCnbBuild ( & config , nil , & utils , & commonPipelineEnvironment , & piperhttp . Client { } )
2021-08-18 12:10:55 +02:00
assert . EqualError ( t , err , "failed to parse DockerConfigJSON file '/path/to/config.json': json: cannot unmarshal string into Go struct field ConfigFile.auths of type types.AuthConfig" )
} )
2021-10-01 10:05:15 +02:00
t . Run ( "error case: DockerConfigJSON file not there (config.json)" , func ( t * testing . T ) {
t . Parallel ( )
config := cnbBuildOptions {
ContainerImageName : "my-image" ,
DockerConfigJSON : "not-there/config.json" ,
}
utils := newCnbBuildTestsUtils ( )
addBuilderFiles ( & utils )
2021-10-01 13:48:24 +02:00
err := runCnbBuild ( & config , nil , & utils , & commonPipelineEnvironment , & piperhttp . Client { } )
2021-10-01 10:05:15 +02:00
assert . EqualError ( t , err , "failed to read DockerConfigJSON file 'not-there/config.json': could not read 'not-there/config.json'" )
} )
t . Run ( "error case: DockerConfigJSON file not there (not config.json)" , func ( t * testing . T ) {
2021-08-18 12:10:55 +02:00
t . Parallel ( )
config := cnbBuildOptions {
2021-08-26 14:26:54 +02:00
ContainerImageName : "my-image" ,
DockerConfigJSON : "not-there" ,
2021-08-18 12:10:55 +02:00
}
utils := newCnbBuildTestsUtils ( )
2021-09-14 15:38:58 +02:00
addBuilderFiles ( & utils )
2021-10-01 13:48:24 +02:00
err := runCnbBuild ( & config , nil , & utils , & commonPipelineEnvironment , & piperhttp . Client { } )
2021-10-01 10:05:15 +02:00
assert . EqualError ( t , err , "failed to rename DockerConfigJSON file 'not-there': renaming file 'not-there' is not supported, since it does not exist, or is not a leaf-entry" )
2021-08-18 12:10:55 +02:00
} )
2021-09-14 15:38:58 +02:00
t . Run ( "error case: dockerImage is not a valid builder" , func ( t * testing . T ) {
t . Parallel ( )
config := cnbBuildOptions { }
utils := newCnbBuildTestsUtils ( )
2021-10-01 13:48:24 +02:00
err := runCnbBuild ( & config , nil , & utils , & commonPipelineEnvironment , & piperhttp . Client { } )
2021-09-14 15:38:58 +02:00
assert . EqualError ( t , err , "the provided dockerImage is not a valid builder" )
} )
2021-10-07 16:04:20 +02:00
t . Run ( "error case: builder image does not contain tls certificates" , func ( t * testing . T ) {
t . Parallel ( )
registry := "some-registry"
config := cnbBuildOptions {
ContainerImageName : "my-image" ,
ContainerImageTag : "0.0.1" ,
ContainerRegistryURL : registry ,
DockerConfigJSON : "/path/to/config.json" ,
Buildpacks : [ ] string { "test" } ,
CustomTLSCertificateLinks : [ ] string { "http://example.com/certs.pem" } ,
}
utils := newCnbBuildTestsUtils ( )
utils . FilesMock . AddFile ( config . DockerConfigJSON , [ ] byte ( ` { "auths": { "my-registry": { "auth":"dXNlcjpwYXNz"}}} ` ) )
addBuilderFiles ( & utils )
err := runCnbBuild ( & config , nil , & utils , & commonPipelineEnvironment , & piperhttp . Client { } )
assert . EqualError ( t , err , "failed to copy certificates: cannot copy '/etc/ssl/certs/ca-certificates.crt': file does not exist" )
} )
2021-08-18 12:10:55 +02:00
}