2021-08-18 12:10:55 +02:00
package cmd
import (
"fmt"
2021-10-01 13:48:24 +02:00
"net/http"
"net/http/httptest"
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"
"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-09-29 18:21:13 +02:00
assert . Equal ( t , [ ] string { "-buildpacks" , "/cnb/buildpacks" , "-order" , "/cnb/order.toml" , "-platform" , "/platform" } , runner . Calls [ 0 ] . Params )
assert . Equal ( t , [ ] string { "-buildpacks" , "/cnb/buildpacks" , "-platform" , "/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 )
} )
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-09-29 18:21:13 +02:00
assert . Equal ( t , [ ] string { "-buildpacks" , "/cnb/buildpacks" , "-order" , "/cnb/order.toml" , "-platform" , "/platform" } , runner . Calls [ 0 ] . Params )
assert . Equal ( t , [ ] string { "-buildpacks" , "/cnb/buildpacks" , "-platform" , "/platform" } , runner . Calls [ 1 ] . Params )
2021-09-14 16:14:50 +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-10-01 10:05:15 +02:00
t . Run ( "success case (custom buildpacks and custom env variables, renaming docker conf file)" , 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-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 ( )
server := httptest . NewServer ( http . HandlerFunc ( func ( rw http . ResponseWriter , req * http . Request ) {
rw . Write ( [ ] byte ( "testCert" ) )
} ) )
// Close the server when test finishes
defer server . Close ( )
caCertsFile := "/etc/ssl/certs/ca-certificates.crt"
registry := "some-registry"
config := cnbBuildOptions {
ContainerImageName : "my-image" ,
ContainerImageTag : "0.0.1" ,
ContainerRegistryURL : registry ,
DockerConfigJSON : "/path/to/config.json" ,
Buildpacks : [ ] string { "test" } ,
CustomTLSCertificateLinks : [ ] string { server . URL , server . URL } ,
}
utils := newCnbBuildTestsUtils ( )
utils . FilesMock . AddFile ( caCertsFile , [ ] byte ( "test\n" ) )
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 )
result , err := utils . FilesMock . FileRead ( caCertsFile )
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\"}" )
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 )
assert . Equal ( t , [ ] string { "-buildpacks" , "/tmp/buildpacks" , "-order" , "/tmp/buildpacks/order.toml" , "-platform" , "/platform" } , runner . Calls [ 0 ] . Params )
assert . Equal ( t , [ ] string { "-buildpacks" , "/tmp/buildpacks" , "-platform" , "/platform" } , runner . Calls [ 1 ] . Params )
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
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-08-18 12:10:55 +02:00
}