2018-06-27 10:41:00 -04:00
package kubernetes
import (
2019-01-28 10:54:38 -05:00
"fmt"
"io/ioutil"
2019-01-25 03:58:31 -05:00
"path/filepath"
2018-06-27 10:41:00 -04:00
"testing"
2019-01-28 10:54:38 -05:00
"github.com/docker/cli/cli/compose/loader"
composetypes "github.com/docker/cli/cli/compose/types"
2019-01-25 03:58:31 -05:00
"github.com/docker/compose-on-kubernetes/api/compose/v1alpha3"
"github.com/docker/compose-on-kubernetes/api/compose/v1beta1"
"github.com/docker/compose-on-kubernetes/api/compose/v1beta2"
2018-06-27 10:41:00 -04:00
"gotest.tools/assert"
is "gotest.tools/assert/cmp"
2019-04-12 09:18:45 -04:00
v1 "k8s.io/api/core/v1"
2019-01-25 03:58:31 -05:00
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2018-06-27 10:41:00 -04:00
)
func TestNewStackConverter ( t * testing . T ) {
_ , err := NewStackConverter ( "v1alpha1" )
assert . Check ( t , is . ErrorContains ( err , "stack version v1alpha1 unsupported" ) )
_ , err = NewStackConverter ( "v1beta1" )
assert . NilError ( t , err )
_ , err = NewStackConverter ( "v1beta2" )
assert . NilError ( t , err )
2019-01-16 06:56:37 -05:00
_ , err = NewStackConverter ( "v1alpha3" )
assert . NilError ( t , err )
2018-06-27 10:41:00 -04:00
}
2019-01-25 03:58:31 -05:00
func TestConvertFromToV1beta1 ( t * testing . T ) {
composefile := ` version : "3.3"
services :
test :
image : nginx
secrets :
test :
file : testdata / secret
configs :
test :
file : testdata / config
`
stackv1beta1 := & v1beta1 . Stack {
ObjectMeta : metav1 . ObjectMeta {
Name : "test" ,
} ,
Spec : v1beta1 . StackSpec {
ComposeFile : composefile ,
} ,
}
result , err := stackFromV1beta1 ( stackv1beta1 )
assert . NilError ( t , err )
expected := Stack {
Name : "test" ,
ComposeFile : composefile ,
Spec : & v1alpha3 . StackSpec {
Services : [ ] v1alpha3 . ServiceConfig {
{
Name : "test" ,
Image : "nginx" ,
Environment : make ( map [ string ] * string ) ,
} ,
} ,
Secrets : map [ string ] v1alpha3 . SecretConfig {
"test" : { File : filepath . FromSlash ( "testdata/secret" ) } ,
} ,
Configs : map [ string ] v1alpha3 . ConfigObjConfig {
"test" : { File : filepath . FromSlash ( "testdata/config" ) } ,
} ,
} ,
}
assert . DeepEqual ( t , expected , result )
assert . DeepEqual ( t , stackv1beta1 , stackToV1beta1 ( result ) )
}
func TestConvertFromToV1beta2 ( t * testing . T ) {
stackv1beta2 := & v1beta2 . Stack {
ObjectMeta : metav1 . ObjectMeta {
Name : "test" ,
} ,
Spec : & v1beta2 . StackSpec {
Services : [ ] v1beta2 . ServiceConfig {
{
Name : "test" ,
Image : "nginx" ,
Environment : make ( map [ string ] * string ) ,
} ,
} ,
Secrets : map [ string ] v1beta2 . SecretConfig {
"test" : { File : filepath . FromSlash ( "testdata/secret" ) } ,
} ,
Configs : map [ string ] v1beta2 . ConfigObjConfig {
"test" : { File : filepath . FromSlash ( "testdata/config" ) } ,
} ,
} ,
}
expected := Stack {
Name : "test" ,
Spec : & v1alpha3 . StackSpec {
Services : [ ] v1alpha3 . ServiceConfig {
{
Name : "test" ,
Image : "nginx" ,
Environment : make ( map [ string ] * string ) ,
} ,
} ,
Secrets : map [ string ] v1alpha3 . SecretConfig {
"test" : { File : filepath . FromSlash ( "testdata/secret" ) } ,
} ,
Configs : map [ string ] v1alpha3 . ConfigObjConfig {
"test" : { File : filepath . FromSlash ( "testdata/config" ) } ,
} ,
} ,
}
result , err := stackFromV1beta2 ( stackv1beta2 )
assert . NilError ( t , err )
assert . DeepEqual ( t , expected , result )
gotBack , err := stackToV1beta2 ( result )
assert . NilError ( t , err )
assert . DeepEqual ( t , stackv1beta2 , gotBack )
}
func TestConvertFromToV1alpha3 ( t * testing . T ) {
stackv1alpha3 := & v1alpha3 . Stack {
ObjectMeta : metav1 . ObjectMeta {
Name : "test" ,
} ,
Spec : & v1alpha3 . StackSpec {
Services : [ ] v1alpha3 . ServiceConfig {
{
Name : "test" ,
Image : "nginx" ,
Environment : make ( map [ string ] * string ) ,
} ,
} ,
Secrets : map [ string ] v1alpha3 . SecretConfig {
"test" : { File : filepath . FromSlash ( "testdata/secret" ) } ,
} ,
Configs : map [ string ] v1alpha3 . ConfigObjConfig {
"test" : { File : filepath . FromSlash ( "testdata/config" ) } ,
} ,
} ,
}
expected := Stack {
Name : "test" ,
Spec : & v1alpha3 . StackSpec {
Services : [ ] v1alpha3 . ServiceConfig {
{
Name : "test" ,
Image : "nginx" ,
Environment : make ( map [ string ] * string ) ,
} ,
} ,
Secrets : map [ string ] v1alpha3 . SecretConfig {
"test" : { File : filepath . FromSlash ( "testdata/secret" ) } ,
} ,
Configs : map [ string ] v1alpha3 . ConfigObjConfig {
"test" : { File : filepath . FromSlash ( "testdata/config" ) } ,
} ,
} ,
}
result := stackFromV1alpha3 ( stackv1alpha3 )
assert . DeepEqual ( t , expected , result )
gotBack := stackToV1alpha3 ( result )
assert . DeepEqual ( t , stackv1alpha3 , gotBack )
}
2019-01-28 10:54:38 -05:00
func loadTestStackWith ( t * testing . T , with string ) * composetypes . Config {
t . Helper ( )
filePath := fmt . Sprintf ( "testdata/compose-with-%s.yml" , with )
data , err := ioutil . ReadFile ( filePath )
assert . NilError ( t , err )
yamlData , err := loader . ParseYAML ( data )
assert . NilError ( t , err )
cfg , err := loader . Load ( composetypes . ConfigDetails {
ConfigFiles : [ ] composetypes . ConfigFile {
{ Config : yamlData , Filename : filePath } ,
} ,
} )
assert . NilError ( t , err )
return cfg
}
func TestHandlePullSecret ( t * testing . T ) {
testData := loadTestStackWith ( t , "pull-secret" )
cases := [ ] struct {
version string
err string
} {
2019-04-12 09:18:45 -04:00
{ version : "v1beta1" , err : ` stack API version v1beta1 does not support pull secrets (field "x-kubernetes.pull_secret"), please use version v1alpha3 or higher ` } ,
{ version : "v1beta2" , err : ` stack API version v1beta2 does not support pull secrets (field "x-kubernetes.pull_secret"), please use version v1alpha3 or higher ` } ,
2019-01-28 10:54:38 -05:00
{ version : "v1alpha3" } ,
}
for _ , c := range cases {
t . Run ( c . version , func ( t * testing . T ) {
conv , err := NewStackConverter ( c . version )
assert . NilError ( t , err )
s , err := conv . FromCompose ( ioutil . Discard , "test" , testData )
if c . err != "" {
assert . Error ( t , err , c . err )
} else {
assert . NilError ( t , err )
assert . Equal ( t , s . Spec . Services [ 0 ] . PullSecret , "some-secret" )
}
} )
}
}
func TestHandlePullPolicy ( t * testing . T ) {
testData := loadTestStackWith ( t , "pull-policy" )
cases := [ ] struct {
version string
err string
} {
2019-04-12 09:18:45 -04:00
{ version : "v1beta1" , err : ` stack API version v1beta1 does not support pull policies (field "x-kubernetes.pull_policy"), please use version v1alpha3 or higher ` } ,
{ version : "v1beta2" , err : ` stack API version v1beta2 does not support pull policies (field "x-kubernetes.pull_policy"), please use version v1alpha3 or higher ` } ,
2019-01-28 10:54:38 -05:00
{ version : "v1alpha3" } ,
}
for _ , c := range cases {
t . Run ( c . version , func ( t * testing . T ) {
conv , err := NewStackConverter ( c . version )
assert . NilError ( t , err )
s , err := conv . FromCompose ( ioutil . Discard , "test" , testData )
if c . err != "" {
assert . Error ( t , err , c . err )
} else {
assert . NilError ( t , err )
assert . Equal ( t , s . Spec . Services [ 0 ] . PullPolicy , "Never" )
}
} )
}
}
2019-04-08 04:37:18 -04:00
func TestHandleInternalServiceType ( t * testing . T ) {
cases := [ ] struct {
name string
value string
caps composeCapabilities
err string
expected v1alpha3 . InternalServiceType
} {
{
name : "v1beta1" ,
value : "ClusterIP" ,
caps : v1beta1Capabilities ,
2019-04-12 09:18:45 -04:00
err : ` stack API version v1beta1 does not support intra-stack load balancing (field "x-kubernetes.internal_service_type"), please use version v1alpha3 or higher ` ,
2019-04-08 04:37:18 -04:00
} ,
{
name : "v1beta2" ,
value : "ClusterIP" ,
caps : v1beta2Capabilities ,
2019-04-12 09:18:45 -04:00
err : ` stack API version v1beta2 does not support intra-stack load balancing (field "x-kubernetes.internal_service_type"), please use version v1alpha3 or higher ` ,
2019-04-08 04:37:18 -04:00
} ,
{
name : "v1alpha3" ,
value : "ClusterIP" ,
caps : v1alpha3Capabilities ,
expected : v1alpha3 . InternalServiceTypeClusterIP ,
} ,
{
name : "v1alpha3-invalid" ,
value : "invalid" ,
caps : v1alpha3Capabilities ,
2019-04-12 09:18:45 -04:00
err : ` invalid value "invalid" for field "x-kubernetes.internal_service_type", valid values are "ClusterIP" or "Headless" ` ,
2019-04-08 04:37:18 -04:00
} ,
}
for _ , c := range cases {
t . Run ( c . name , func ( t * testing . T ) {
res , err := fromComposeServiceConfig ( composetypes . ServiceConfig {
Name : "test" ,
Image : "test" ,
Extras : map [ string ] interface { } {
2019-04-12 09:18:45 -04:00
"x-kubernetes" : map [ string ] interface { } {
"internal_service_type" : c . value ,
} ,
2019-04-08 04:37:18 -04:00
} ,
} , c . caps )
if c . err == "" {
assert . NilError ( t , err )
assert . Equal ( t , res . InternalServiceType , c . expected )
} else {
assert . ErrorContains ( t , err , c . err )
}
} )
}
}
func TestIgnoreExpose ( t * testing . T ) {
testData := loadTestStackWith ( t , "expose" )
for _ , version := range [ ] string { "v1beta1" , "v1beta2" } {
conv , err := NewStackConverter ( version )
assert . NilError ( t , err )
s , err := conv . FromCompose ( ioutil . Discard , "test" , testData )
assert . NilError ( t , err )
assert . Equal ( t , len ( s . Spec . Services [ 0 ] . InternalPorts ) , 0 )
}
}
func TestParseExpose ( t * testing . T ) {
testData := loadTestStackWith ( t , "expose" )
conv , err := NewStackConverter ( "v1alpha3" )
assert . NilError ( t , err )
s , err := conv . FromCompose ( ioutil . Discard , "test" , testData )
assert . NilError ( t , err )
expected := [ ] v1alpha3 . InternalPort {
{
Port : 1 ,
Protocol : v1 . ProtocolTCP ,
} ,
{
Port : 2 ,
Protocol : v1 . ProtocolTCP ,
} ,
{
Port : 3 ,
Protocol : v1 . ProtocolTCP ,
} ,
{
Port : 4 ,
Protocol : v1 . ProtocolTCP ,
} ,
{
Port : 5 ,
Protocol : v1 . ProtocolUDP ,
} ,
{
Port : 6 ,
Protocol : v1 . ProtocolUDP ,
} ,
{
Port : 7 ,
Protocol : v1 . ProtocolUDP ,
} ,
{
Port : 8 ,
Protocol : v1 . ProtocolUDP ,
} ,
}
assert . DeepEqual ( t , s . Spec . Services [ 0 ] . InternalPorts , expected )
}