github.com/docker/compose-on-kubernetes@v0.5.0/internal/registry/strategyvalidate_test.go (about)

     1  package registry
     2  
     3  import (
     4  	"testing"
     5  
     6  	composelabels "github.com/docker/compose-on-kubernetes/api/labels"
     7  	iv "github.com/docker/compose-on-kubernetes/internal/internalversion"
     8  	. "github.com/docker/compose-on-kubernetes/internal/test/builders"
     9  	"github.com/stretchr/testify/assert"
    10  	appsv1 "k8s.io/api/apps/v1"
    11  	apiv1 "k8s.io/api/core/v1"
    12  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    13  	kubefake "k8s.io/client-go/kubernetes/fake"
    14  )
    15  
    16  func TestValidateCollisionsExistingServiceHeadlessOnly(t *testing.T) {
    17  	s := Stack("test",
    18  		WithService("redis",
    19  			Image("redis:alpine")))
    20  
    21  	fake := kubefake.NewSimpleClientset(&apiv1.Service{
    22  		ObjectMeta: metav1.ObjectMeta{
    23  			Name: "redis",
    24  		},
    25  	}, &apiv1.Service{
    26  		ObjectMeta: metav1.ObjectMeta{
    27  			Name: "redis-published",
    28  		},
    29  	}, &apiv1.Service{
    30  		ObjectMeta: metav1.ObjectMeta{
    31  			Name: "redis-random-ports",
    32  		},
    33  	})
    34  	stack := iv.Stack{
    35  		Spec: iv.StackSpec{
    36  			Stack: s.Spec,
    37  		},
    38  	}
    39  
    40  	err := validateCollisions(fake.CoreV1(), fake.AppsV1())(nil, &stack)
    41  	assert.Len(t, err, 1)
    42  }
    43  
    44  func TestValidateCollisionsExistingServicePublished(t *testing.T) {
    45  	s := Stack("test",
    46  		WithService("redis",
    47  			Image("redis:alpine"),
    48  			WithPort(8080, Published(8080))))
    49  
    50  	fake := kubefake.NewSimpleClientset(&apiv1.Service{
    51  		ObjectMeta: metav1.ObjectMeta{
    52  			Name: "redis",
    53  		},
    54  	}, &apiv1.Service{
    55  		ObjectMeta: metav1.ObjectMeta{
    56  			Name: "redis-published",
    57  		},
    58  	}, &apiv1.Service{
    59  		ObjectMeta: metav1.ObjectMeta{
    60  			Name: "redis-random-ports",
    61  		},
    62  	})
    63  	stack := iv.Stack{
    64  		Spec: iv.StackSpec{
    65  			Stack: s.Spec,
    66  		},
    67  	}
    68  
    69  	err := validateCollisions(fake.CoreV1(), fake.AppsV1())(nil, &stack)
    70  	assert.Len(t, err, 2)
    71  }
    72  func TestValidateCollisionsExistingServicePublishedAndRandom(t *testing.T) {
    73  	s := Stack("test",
    74  		WithService("redis",
    75  			Image("redis:alpine"),
    76  			WithPort(8080, Published(8080)),
    77  			WithPort(22)))
    78  
    79  	fake := kubefake.NewSimpleClientset(&apiv1.Service{
    80  		ObjectMeta: metav1.ObjectMeta{
    81  			Name: "redis",
    82  		},
    83  	}, &apiv1.Service{
    84  		ObjectMeta: metav1.ObjectMeta{
    85  			Name: "redis-published",
    86  		},
    87  	}, &apiv1.Service{
    88  		ObjectMeta: metav1.ObjectMeta{
    89  			Name: "redis-random-ports",
    90  		},
    91  	})
    92  	stack := iv.Stack{
    93  		Spec: iv.StackSpec{
    94  			Stack: s.Spec,
    95  		},
    96  	}
    97  
    98  	err := validateCollisions(fake.CoreV1(), fake.AppsV1())(nil, &stack)
    99  	assert.Len(t, err, 3)
   100  }
   101  
   102  func TestValidateCollisionsExistingServicesCorrectLabels(t *testing.T) {
   103  	s := Stack("test",
   104  		WithService("redis",
   105  			Image("redis:alpine"),
   106  			WithPort(8080, Published(8080)),
   107  			WithPort(22)))
   108  
   109  	fake := kubefake.NewSimpleClientset(&apiv1.Service{
   110  		ObjectMeta: metav1.ObjectMeta{
   111  			Name: "redis",
   112  			Labels: map[string]string{
   113  				composelabels.ForStackName: "test",
   114  			},
   115  		},
   116  	}, &apiv1.Service{
   117  		ObjectMeta: metav1.ObjectMeta{
   118  			Name: "redis-published",
   119  			Labels: map[string]string{
   120  				composelabels.ForStackName: "test",
   121  			},
   122  		},
   123  	}, &apiv1.Service{
   124  		ObjectMeta: metav1.ObjectMeta{
   125  			Name: "redis-random-ports",
   126  			Labels: map[string]string{
   127  				composelabels.ForStackName: "test",
   128  			},
   129  		},
   130  	})
   131  	stack := iv.Stack{
   132  		ObjectMeta: metav1.ObjectMeta{Name: "test"},
   133  		Spec: iv.StackSpec{
   134  			Stack: s.Spec,
   135  		},
   136  	}
   137  
   138  	err := validateCollisions(fake.CoreV1(), fake.AppsV1())(nil, &stack)
   139  	assert.Len(t, err, 0)
   140  }
   141  
   142  func TestValidateCollisionsExistingServicesIncorrectLabels(t *testing.T) {
   143  	s := Stack("test",
   144  		WithService("redis",
   145  			Image("redis:alpine"),
   146  			WithPort(8080, Published(8080)),
   147  			WithPort(22)))
   148  
   149  	fake := kubefake.NewSimpleClientset(&apiv1.Service{
   150  		ObjectMeta: metav1.ObjectMeta{
   151  			Name: "redis",
   152  			Labels: map[string]string{
   153  				composelabels.ForStackName: "test2",
   154  			},
   155  		},
   156  	}, &apiv1.Service{
   157  		ObjectMeta: metav1.ObjectMeta{
   158  			Name: "redis-published",
   159  			Labels: map[string]string{
   160  				composelabels.ForStackName: "test2",
   161  			},
   162  		},
   163  	}, &apiv1.Service{
   164  		ObjectMeta: metav1.ObjectMeta{
   165  			Name: "redis-random-ports",
   166  			Labels: map[string]string{
   167  				composelabels.ForStackName: "test2",
   168  			},
   169  		},
   170  	})
   171  	stack := iv.Stack{
   172  		ObjectMeta: metav1.ObjectMeta{Name: "test"},
   173  		Spec: iv.StackSpec{
   174  			Stack: s.Spec,
   175  		},
   176  	}
   177  
   178  	err := validateCollisions(fake.CoreV1(), fake.AppsV1())(nil, &stack)
   179  	assert.Len(t, err, 3)
   180  }
   181  
   182  func TestValidateCollisionsExistingDeployment(t *testing.T) {
   183  	s := Stack("test",
   184  		WithService("redis",
   185  			Image("redis:alpine")))
   186  
   187  	fake := kubefake.NewSimpleClientset(&appsv1.Deployment{
   188  		ObjectMeta: metav1.ObjectMeta{
   189  			Name: "redis",
   190  		},
   191  	})
   192  	stack := iv.Stack{
   193  		Spec: iv.StackSpec{
   194  			Stack: s.Spec,
   195  		},
   196  	}
   197  
   198  	err := validateCollisions(fake.CoreV1(), fake.AppsV1())(nil, &stack)
   199  	assert.Len(t, err, 1)
   200  }
   201  
   202  func TestValidateCollisionsExistingStatefulset(t *testing.T) {
   203  	s := Stack("test",
   204  		WithService("redis",
   205  			Image("redis:alpine"),
   206  			WithVolume(
   207  				Source("dbdata"),
   208  				Target("/var/lib/postgresql/data"),
   209  				Volume,
   210  			)))
   211  
   212  	fake := kubefake.NewSimpleClientset(&appsv1.StatefulSet{
   213  		ObjectMeta: metav1.ObjectMeta{
   214  			Name: "redis",
   215  		},
   216  	})
   217  	stack := iv.Stack{
   218  		Spec: iv.StackSpec{
   219  			Stack: s.Spec,
   220  		},
   221  	}
   222  
   223  	err := validateCollisions(fake.CoreV1(), fake.AppsV1())(nil, &stack)
   224  	assert.Len(t, err, 1)
   225  }
   226  
   227  func TestValidateCollisionsExistingDaemonset(t *testing.T) {
   228  	s := Stack("test",
   229  		WithService("redis",
   230  			Image("redis:alpine"),
   231  			Deploy(ModeGlobal)))
   232  
   233  	fake := kubefake.NewSimpleClientset(&appsv1.DaemonSet{
   234  		ObjectMeta: metav1.ObjectMeta{
   235  			Name: "redis",
   236  		},
   237  	})
   238  	stack := iv.Stack{
   239  		Spec: iv.StackSpec{
   240  			Stack: s.Spec,
   241  		},
   242  	}
   243  
   244  	err := validateCollisions(fake.CoreV1(), fake.AppsV1())(nil, &stack)
   245  	assert.Len(t, err, 1)
   246  }
   247  
   248  func TestValidateServiceName(t *testing.T) {
   249  	s := Stack("test",
   250  		WithService("redis:test",
   251  			Image("redis:alpine")))
   252  
   253  	stack := iv.Stack{
   254  		Spec: iv.StackSpec{
   255  			Stack: s.Spec,
   256  		},
   257  	}
   258  	err := validateObjectNames()(nil, &stack)
   259  	assert.Len(t, err, 1)
   260  }
   261  func TestValidateVolumeName(t *testing.T) {
   262  	s := Stack("test",
   263  		WithService("redis",
   264  			Image("redis:alpine"),
   265  			WithVolume(
   266  				Source("dbdata:test"),
   267  				Target("/var/lib/postgresql/data"),
   268  				Volume,
   269  			)))
   270  
   271  	stack := iv.Stack{
   272  		Spec: iv.StackSpec{
   273  			Stack: s.Spec,
   274  		},
   275  	}
   276  	err := validateObjectNames()(nil, &stack)
   277  	assert.Len(t, err, 1)
   278  }
   279  
   280  func TestValidateSecretName(t *testing.T) {
   281  	s := Stack("test",
   282  		WithService("redis",
   283  			Image("redis:alpine")),
   284  		WithSecretConfig("secret:test"))
   285  
   286  	stack := iv.Stack{
   287  		Spec: iv.StackSpec{
   288  			Stack: s.Spec,
   289  		},
   290  	}
   291  	err := validateObjectNames()(nil, &stack)
   292  	assert.Len(t, err, 1)
   293  }
   294  
   295  func TestValidateDryRunOk(t *testing.T) {
   296  	s := Stack("test",
   297  		WithService("redis",
   298  			Image("redis:alpine")))
   299  	stack := iv.Stack{
   300  		Spec: iv.StackSpec{
   301  			Stack: s.Spec,
   302  		},
   303  	}
   304  	err := validateDryRun()(nil, &stack)
   305  	assert.Len(t, err, 0)
   306  }
   307  func TestValidateDryRunFail(t *testing.T) {
   308  	s := Stack("test",
   309  		WithService("redis",
   310  			Deploy(ModeGlobal),
   311  			Image("redis:alpine"),
   312  			WithVolume(
   313  				Source("dbdata"),
   314  				Target("/var/lib/postgresql/data"),
   315  				Volume,
   316  			)))
   317  	stack := iv.Stack{
   318  		Spec: iv.StackSpec{
   319  			Stack: s.Spec,
   320  		},
   321  	}
   322  	err := validateDryRun()(nil, &stack)
   323  	assert.Len(t, err, 1)
   324  }
   325  
   326  func TestValidateCreationStatusNil(t *testing.T) {
   327  	stack := iv.Stack{}
   328  	err := validateCreationStatus()(nil, &stack)
   329  	assert.Len(t, err, 0)
   330  }
   331  
   332  func TestValidateCreationStatusSuccess(t *testing.T) {
   333  	stack := iv.Stack{
   334  		Status: &iv.StackStatus{
   335  			Phase: iv.StackAvailable,
   336  		},
   337  	}
   338  	err := validateCreationStatus()(nil, &stack)
   339  	assert.Len(t, err, 0)
   340  }
   341  
   342  func TestValidateCreationStatusFailed(t *testing.T) {
   343  	stack := iv.Stack{
   344  		Status: &iv.StackStatus{
   345  			Phase:   iv.StackFailure,
   346  			Message: "error",
   347  		},
   348  	}
   349  	err := validateCreationStatus()(nil, &stack)
   350  	assert.Len(t, err, 1)
   351  }
   352  
   353  func TestValidateStackNotNilWithStatus(t *testing.T) {
   354  	stack := iv.Stack{
   355  		Status: &iv.StackStatus{
   356  			Phase:   iv.StackFailure,
   357  			Message: "test",
   358  		},
   359  	}
   360  	err := validateStackNotNil()(nil, &stack)
   361  	assert.Len(t, err, 1)
   362  }
   363  
   364  func TestValidateStackNotNilWithoutStatus(t *testing.T) {
   365  	stack := iv.Stack{}
   366  	err := validateStackNotNil()(nil, &stack)
   367  	assert.Len(t, err, 1)
   368  }
   369  
   370  func TestValidateInvalidPullPolicy(t *testing.T) {
   371  	s := Stack("test",
   372  		WithService("redis",
   373  			Image("redis"),
   374  			PullPolicy("Invalid")))
   375  	stack := iv.Stack{
   376  		Spec: iv.StackSpec{
   377  			Stack: s.Spec,
   378  		},
   379  	}
   380  	err := validateDryRun()(nil, &stack)
   381  	assert.Len(t, err, 1)
   382  	assert.Contains(t, err[0].Error(), `invalid pull policy "Invalid", must be "Always", "IfNotPresent" or "Never"`)
   383  }