github.com/argoproj/argo-events@v1.9.1/controllers/sensor/resource_test.go (about) 1 /* 2 Copyright 2020 BlackRock, Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package sensor 18 19 import ( 20 "context" 21 "testing" 22 23 "github.com/stretchr/testify/assert" 24 appv1 "k8s.io/api/apps/v1" 25 corev1 "k8s.io/api/core/v1" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "sigs.k8s.io/controller-runtime/pkg/client" 28 "sigs.k8s.io/controller-runtime/pkg/client/fake" 29 30 "github.com/argoproj/argo-events/common" 31 "github.com/argoproj/argo-events/common/logging" 32 apicommon "github.com/argoproj/argo-events/pkg/apis/common" 33 eventbusv1alpha1 "github.com/argoproj/argo-events/pkg/apis/eventbus/v1alpha1" 34 "github.com/argoproj/argo-events/pkg/apis/sensor/v1alpha1" 35 ) 36 37 const ( 38 testNamespace = "test-ns" 39 ) 40 41 var ( 42 testLabels = map[string]string{"controller": "test-controller"} 43 44 sensorObj = &v1alpha1.Sensor{ 45 ObjectMeta: metav1.ObjectMeta{ 46 Name: "fake-sensor", 47 Namespace: testNamespace, 48 }, 49 Spec: v1alpha1.SensorSpec{ 50 Template: &v1alpha1.Template{ 51 ServiceAccountName: "fake-sa", 52 ImagePullSecrets: []corev1.LocalObjectReference{ 53 { 54 Name: "test", 55 }, 56 }, 57 Container: &corev1.Container{ 58 VolumeMounts: []corev1.VolumeMount{ 59 { 60 MountPath: "/test-data", 61 Name: "test-data", 62 }, 63 }, 64 }, 65 Volumes: []corev1.Volume{ 66 { 67 Name: "test-data", 68 VolumeSource: corev1.VolumeSource{ 69 EmptyDir: &corev1.EmptyDirVolumeSource{}, 70 }, 71 }, 72 }, 73 PriorityClassName: "test-class", 74 }, 75 Triggers: []v1alpha1.Trigger{ 76 { 77 Template: &v1alpha1.TriggerTemplate{ 78 Name: "fake-trigger", 79 K8s: &v1alpha1.StandardK8STrigger{ 80 Operation: "create", 81 Source: &v1alpha1.ArtifactLocation{}, 82 }, 83 }, 84 }, 85 }, 86 Dependencies: []v1alpha1.EventDependency{ 87 { 88 Name: "fake-dep", 89 EventSourceName: "fake-source", 90 EventName: "fake-one", 91 }, 92 }, 93 }, 94 } 95 96 fakeEventBus = &eventbusv1alpha1.EventBus{ 97 TypeMeta: metav1.TypeMeta{ 98 APIVersion: eventbusv1alpha1.SchemeGroupVersion.String(), 99 Kind: "EventBus", 100 }, 101 ObjectMeta: metav1.ObjectMeta{ 102 Namespace: testNamespace, 103 Name: common.DefaultEventBusName, 104 }, 105 Spec: eventbusv1alpha1.EventBusSpec{ 106 NATS: &eventbusv1alpha1.NATSBus{ 107 Native: &eventbusv1alpha1.NativeStrategy{ 108 Auth: &eventbusv1alpha1.AuthStrategyToken, 109 }, 110 }, 111 }, 112 Status: eventbusv1alpha1.EventBusStatus{ 113 Config: eventbusv1alpha1.BusConfig{ 114 NATS: &eventbusv1alpha1.NATSConfig{ 115 URL: "nats://xxxx", 116 Auth: &eventbusv1alpha1.AuthStrategyToken, 117 AccessSecret: &corev1.SecretKeySelector{ 118 Key: "test-key", 119 LocalObjectReference: corev1.LocalObjectReference{ 120 Name: "test-name", 121 }, 122 }, 123 }, 124 }, 125 }, 126 } 127 128 fakeEventBusJetstream = &eventbusv1alpha1.EventBus{ 129 TypeMeta: metav1.TypeMeta{ 130 APIVersion: eventbusv1alpha1.SchemeGroupVersion.String(), 131 Kind: "EventBus", 132 }, 133 ObjectMeta: metav1.ObjectMeta{ 134 Namespace: testNamespace, 135 Name: common.DefaultEventBusName, 136 }, 137 Spec: eventbusv1alpha1.EventBusSpec{ 138 JetStream: &eventbusv1alpha1.JetStreamBus{ 139 Version: "x.x.x", 140 }, 141 }, 142 Status: eventbusv1alpha1.EventBusStatus{ 143 Config: eventbusv1alpha1.BusConfig{ 144 JetStream: &eventbusv1alpha1.JetStreamConfig{ 145 URL: "nats://xxxx", 146 }, 147 }, 148 }, 149 } 150 151 fakeEventBusKafka = &eventbusv1alpha1.EventBus{ 152 TypeMeta: metav1.TypeMeta{ 153 APIVersion: eventbusv1alpha1.SchemeGroupVersion.String(), 154 Kind: "EventBus", 155 }, 156 ObjectMeta: metav1.ObjectMeta{ 157 Namespace: testNamespace, 158 Name: common.DefaultEventBusName, 159 }, 160 Spec: eventbusv1alpha1.EventBusSpec{ 161 Kafka: &eventbusv1alpha1.KafkaBus{ 162 URL: "localhost:9092", 163 }, 164 }, 165 Status: eventbusv1alpha1.EventBusStatus{ 166 Config: eventbusv1alpha1.BusConfig{ 167 Kafka: &eventbusv1alpha1.KafkaBus{ 168 URL: "localhost:9092", 169 }, 170 }, 171 }, 172 } 173 ) 174 175 func Test_BuildDeployment(t *testing.T) { 176 t.Run("test build with eventbus", func(t *testing.T) { 177 args := &AdaptorArgs{ 178 Image: testImage, 179 Sensor: sensorObj, 180 Labels: testLabels, 181 } 182 deployment, err := buildDeployment(args, fakeEventBus) 183 assert.Nil(t, err) 184 assert.NotNil(t, deployment) 185 volumes := deployment.Spec.Template.Spec.Volumes 186 assert.True(t, len(volumes) > 0) 187 hasAuthVolume := false 188 hasTmpVolume := false 189 for _, vol := range volumes { 190 if vol.Name == "auth-volume" { 191 hasAuthVolume = true 192 } 193 if vol.Name == "tmp" { 194 hasTmpVolume = true 195 } 196 } 197 assert.True(t, hasAuthVolume) 198 assert.True(t, hasTmpVolume) 199 assert.True(t, len(deployment.Spec.Template.Spec.ImagePullSecrets) > 0) 200 assert.Equal(t, deployment.Spec.Template.Spec.PriorityClassName, "test-class") 201 assert.Nil(t, deployment.Spec.RevisionHistoryLimit) 202 }) 203 t.Run("test revisionHistoryLimit", func(t *testing.T) { 204 sensorWithRevisionHistoryLimit := sensorObj.DeepCopy() 205 sensorWithRevisionHistoryLimit.Spec.RevisionHistoryLimit = func() *int32 { i := int32(3); return &i }() 206 args := &AdaptorArgs{ 207 Image: testImage, 208 Sensor: sensorWithRevisionHistoryLimit, 209 Labels: testLabels, 210 } 211 deployment, err := buildDeployment(args, fakeEventBus) 212 assert.Nil(t, err) 213 assert.NotNil(t, deployment) 214 assert.Equal(t, int32(3), *deployment.Spec.RevisionHistoryLimit) 215 }) 216 217 t.Run("test kafka eventbus secrets attached", func(t *testing.T) { 218 args := &AdaptorArgs{ 219 Image: testImage, 220 Sensor: sensorObj, 221 Labels: testLabels, 222 } 223 224 // add secrets to kafka eventbus 225 testBus := fakeEventBusKafka.DeepCopy() 226 testBus.Spec.Kafka.TLS = &apicommon.TLSConfig{ 227 CACertSecret: &corev1.SecretKeySelector{Key: "cert", LocalObjectReference: corev1.LocalObjectReference{Name: "tls-secret"}}, 228 } 229 testBus.Spec.Kafka.SASL = &apicommon.SASLConfig{ 230 Mechanism: "SCRAM-SHA-512", 231 UserSecret: &corev1.SecretKeySelector{Key: "username", LocalObjectReference: corev1.LocalObjectReference{Name: "sasl-secret"}}, 232 PasswordSecret: &corev1.SecretKeySelector{Key: "password", LocalObjectReference: corev1.LocalObjectReference{Name: "sasl-secret"}}, 233 } 234 235 deployment, err := buildDeployment(args, testBus) 236 assert.Nil(t, err) 237 assert.NotNil(t, deployment) 238 239 hasSASLSecretVolume := false 240 hasSASLSecretVolumeMount := false 241 hasTLSSecretVolume := false 242 hasTLSSecretVolumeMount := false 243 for _, volume := range deployment.Spec.Template.Spec.Volumes { 244 if volume.Name == "secret-sasl-secret" { 245 hasSASLSecretVolume = true 246 } 247 if volume.Name == "secret-tls-secret" { 248 hasTLSSecretVolume = true 249 } 250 } 251 for _, volumeMount := range deployment.Spec.Template.Spec.Containers[0].VolumeMounts { 252 if volumeMount.Name == "secret-sasl-secret" { 253 hasSASLSecretVolumeMount = true 254 } 255 if volumeMount.Name == "secret-tls-secret" { 256 hasTLSSecretVolumeMount = true 257 } 258 } 259 260 assert.True(t, hasSASLSecretVolume) 261 assert.True(t, hasSASLSecretVolumeMount) 262 assert.True(t, hasTLSSecretVolume) 263 assert.True(t, hasTLSSecretVolumeMount) 264 }) 265 266 t.Run("test secret volume and volumemount order deterministic", func(t *testing.T) { 267 args := &AdaptorArgs{ 268 Image: testImage, 269 Sensor: sensorObj, 270 Labels: testLabels, 271 } 272 273 wantVolumeNames := []string{"test-data", "auth-volume", "tmp"} 274 wantVolumeMountNames := []string{"test-data", "auth-volume", "tmp"} 275 276 deployment, err := buildDeployment(args, fakeEventBus) 277 assert.Nil(t, err) 278 assert.NotNil(t, deployment) 279 gotVolumes := deployment.Spec.Template.Spec.Volumes 280 gotVolumeMounts := deployment.Spec.Template.Spec.Containers[0].VolumeMounts 281 282 var gotVolumeNames []string 283 var gotVolumeMountNames []string 284 285 for _, v := range gotVolumes { 286 gotVolumeNames = append(gotVolumeNames, v.Name) 287 } 288 for _, v := range gotVolumeMounts { 289 gotVolumeMountNames = append(gotVolumeMountNames, v.Name) 290 } 291 292 assert.Equal(t, len(gotVolumes), len(wantVolumeNames)) 293 assert.Equal(t, len(gotVolumeMounts), len(wantVolumeMountNames)) 294 295 for i := range gotVolumeNames { 296 assert.Equal(t, gotVolumeNames[i], wantVolumeNames[i]) 297 } 298 for i := range gotVolumeMountNames { 299 assert.Equal(t, gotVolumeMountNames[i], wantVolumeMountNames[i]) 300 } 301 }) 302 } 303 304 func TestResourceReconcile(t *testing.T) { 305 t.Run("test resource reconcile without eventbus", func(t *testing.T) { 306 cl := fake.NewClientBuilder().Build() 307 args := &AdaptorArgs{ 308 Image: testImage, 309 Sensor: sensorObj, 310 Labels: testLabels, 311 } 312 err := Reconcile(cl, nil, args, logging.NewArgoEventsLogger()) 313 assert.Error(t, err) 314 assert.False(t, sensorObj.Status.IsReady()) 315 }) 316 317 for _, eb := range []*eventbusv1alpha1.EventBus{fakeEventBus, fakeEventBusJetstream, fakeEventBusKafka} { 318 testBus := eb.DeepCopy() 319 320 t.Run("test resource reconcile with eventbus", func(t *testing.T) { 321 ctx := context.TODO() 322 cl := fake.NewClientBuilder().Build() 323 testBus.Status.MarkDeployed("test", "test") 324 testBus.Status.MarkConfigured() 325 err := cl.Create(ctx, testBus) 326 assert.Nil(t, err) 327 args := &AdaptorArgs{ 328 Image: testImage, 329 Sensor: sensorObj, 330 Labels: testLabels, 331 } 332 err = Reconcile(cl, testBus, args, logging.NewArgoEventsLogger()) 333 assert.Nil(t, err) 334 assert.True(t, sensorObj.Status.IsReady()) 335 336 deployList := &appv1.DeploymentList{} 337 err = cl.List(ctx, deployList, &client.ListOptions{ 338 Namespace: testNamespace, 339 }) 340 assert.NoError(t, err) 341 assert.Equal(t, 1, len(deployList.Items)) 342 343 svcList := &corev1.ServiceList{} 344 err = cl.List(ctx, svcList, &client.ListOptions{ 345 Namespace: testNamespace, 346 }) 347 assert.NoError(t, err) 348 assert.Equal(t, 0, len(svcList.Items)) 349 }) 350 } 351 }