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 }