This is an automated email from the ASF dual-hosted git repository. aldettinger pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel-k.git
The following commit(s) were added to refs/heads/master by this push: new f292de4 Added unit tests for the prometheus trait #255 f292de4 is described below commit f292de4e0fc6df6c331e4e98b012bd3da93217b8 Author: aldettinger <aldettin...@gmail.com> AuthorDate: Fri Dec 13 19:52:24 2019 +0100 Added unit tests for the prometheus trait #255 --- pkg/trait/prometheus_test.go | 215 ++++++++++++++++++++++++++++++++++++++ pkg/util/kubernetes/collection.go | 19 ++++ 2 files changed, 234 insertions(+) diff --git a/pkg/trait/prometheus_test.go b/pkg/trait/prometheus_test.go new file mode 100644 index 0000000..78addd4 --- /dev/null +++ b/pkg/trait/prometheus_test.go @@ -0,0 +1,215 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package trait + +import ( + "context" + "testing" + + "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" + "github.com/apache/camel-k/pkg/util/kubernetes" + "github.com/apache/camel-k/pkg/util/test" + + "github.com/stretchr/testify/assert" + + monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestConfigurePrometheusTraitInRightPhaseDoesSucceed(t *testing.T) { + trait, environment := createNominalPrometheusTest() + + configured, err := trait.Configure(environment) + + assert.Nil(t, err) + assert.True(t, configured) +} + +func TestConfigurePrometheusTraitInWrongPhaseDoesNotSucceed(t *testing.T) { + trait, environment := createNominalPrometheusTest() + environment.Integration.Status.Phase = v1alpha1.IntegrationPhaseResolvingKit + + configured, err := trait.Configure(environment) + + assert.Nil(t, err) + assert.False(t, configured) +} + +func TestApplyNominalPrometheusTraitDoesSucceed(t *testing.T) { + trait, environment := createNominalPrometheusTest() + + err := trait.Apply(environment) + + assert.Nil(t, err) + + container := environment.Resources.GetContainerByName(defaultContainerName) + assert.NotNil(t, container) + test.EnvVarHasValue(t, container.Env, "AB_PROMETHEUS_PORT", "9779") + ports := container.Ports + assert.Len(t, ports, 1) + assert.Equal(t, "prometheus", ports[0].Name) + assert.Equal(t, int32(9779), ports[0].ContainerPort) + assert.Equal(t, corev1.ProtocolTCP, ports[0].Protocol) + + service := environment.Resources.GetService(func(service *corev1.Service) bool { + return service.Name == "integration-name" + }) + assert.NotNil(t, service) + assert.Len(t, service.Spec.Ports, 1) + + serviceMonitor := environment.Resources.GetServiceMonitor(func(service *monitoringv1.ServiceMonitor) bool { + return service.Name == "integration-name" + }) + assert.NotNil(t, serviceMonitor) + + assert.Len(t, environment.Integration.Status.Conditions, 1) + condition := environment.Integration.Status.Conditions[0] + assert.Equal(t, v1alpha1.IntegrationConditionPrometheusAvailable, condition.Type) + assert.Equal(t, corev1.ConditionTrue, condition.Status) +} + +func TestApplyPrometheusTraitWithoutContainerDoesNotSucceed(t *testing.T) { + trait, environment := createNominalPrometheusTest() + environment.Resources = kubernetes.NewCollection() + + err := trait.Apply(environment) + + assert.Nil(t, err) + + assert.Len(t, environment.Integration.Status.Conditions, 1) + condition := environment.Integration.Status.Conditions[0] + assert.Equal(t, v1alpha1.IntegrationConditionPrometheusAvailable, condition.Type) + assert.Equal(t, corev1.ConditionFalse, condition.Status) +} + +func TestApplyPrometheusTraitWithServiceDoesNotSucceed(t *testing.T) { + trait, environment := createNominalPrometheusTest() + environment.Resources = kubernetes.NewCollection( + &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: defaultContainerName, + }, + }, + }, + }, + }, + }, + &corev1.Service{ + TypeMeta: metav1.TypeMeta{ + Kind: "Service", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "service-name", + Namespace: "namespace", + Labels: map[string]string{ + "camel.apache.org/integration": "integration-name", + "camel.apache.org/service.type": v1alpha1.ServiceTypeUser, + }, + }, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{}, + Selector: map[string]string{ + "camel.apache.org/integration": "integration-name", + }, + }, + }) + + err := trait.Apply(environment) + + assert.Nil(t, err) + + assert.Len(t, environment.Integration.Status.Conditions, 1) + condition := environment.Integration.Status.Conditions[0] + assert.Equal(t, v1alpha1.IntegrationConditionServiceNotAvailableReason, condition.Reason) + assert.Equal(t, corev1.ConditionFalse, condition.Status) +} + +func TestApplyDisabledPrometheusTraitShouldDeactivateJavaAgent(t *testing.T) { + trait, environment := createNominalPrometheusTest() + trait.Enabled = new(bool) + + err := trait.Apply(environment) + + assert.Nil(t, err) + + container := environment.Resources.GetContainerByName(defaultContainerName) + assert.NotNil(t, container) + test.EnvVarHasValue(t, container.Env, "AB_PROMETHEUS_OFF", "true") +} + +func TestPrometheusTraitGetServiceMonitor(t *testing.T) { + trait, environment := createNominalPrometheusTest() + + serviceMonitor, err := trait.getServiceMonitorFor(environment) + + assert.Nil(t, err) + + assert.NotNil(t, serviceMonitor) + assert.Equal(t, "ServiceMonitor", serviceMonitor.Kind) + assert.Equal(t, "monitoring.coreos.com/v1", serviceMonitor.APIVersion) + assert.Equal(t, "integration-name", serviceMonitor.Name) + assert.Equal(t, "integration-namespace", serviceMonitor.Namespace) + assert.Equal(t, "integration-name", serviceMonitor.Labels["camel.apache.org/integration"]) + assert.Equal(t, "integration-name", serviceMonitor.Spec.Selector.MatchLabels["camel.apache.org/integration"]) + assert.Len(t, serviceMonitor.Spec.Endpoints, 1) + assert.Equal(t, "prometheus", serviceMonitor.Spec.Endpoints[0].Port) +} + +func createNominalPrometheusTest() (*prometheusTrait, *Environment) { + trait := newPrometheusTrait() + enabled := true + trait.Enabled = &enabled + + environment := &Environment{ + Catalog: NewCatalog(context.TODO(), nil), + Integration: &v1alpha1.Integration{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "integration-namespace", + Name: "integration-name", + }, + Status: v1alpha1.IntegrationStatus{ + Phase: v1alpha1.IntegrationPhaseDeploying, + }, + }, + Resources: kubernetes.NewCollection( + &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: defaultContainerName, + }, + }, + }, + }, + }, + }, + ), + } + + return trait, environment +} diff --git a/pkg/util/kubernetes/collection.go b/pkg/util/kubernetes/collection.go index d825a78..9ba325b 100644 --- a/pkg/util/kubernetes/collection.go +++ b/pkg/util/kubernetes/collection.go @@ -19,6 +19,7 @@ package kubernetes import ( "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" + monitoringv1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1" routev1 "github.com/openshift/api/route/v1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -348,3 +349,21 @@ func (c *Collection) Remove(selector func(runtime.Object) bool) runtime.Object { } return nil } + +func (c *Collection) VisitServiceMonitor(visitor func(*monitoringv1.ServiceMonitor)) { + c.Visit(func(res runtime.Object) { + if conv, ok := res.(*monitoringv1.ServiceMonitor); ok { + visitor(conv) + } + }) +} + +func (c *Collection) GetServiceMonitor(filter func(*monitoringv1.ServiceMonitor) bool) *monitoringv1.ServiceMonitor { + var retValue *monitoringv1.ServiceMonitor + c.VisitServiceMonitor(func(serviceMonitor *monitoringv1.ServiceMonitor) { + if filter(serviceMonitor) { + retValue = serviceMonitor + } + }) + return retValue +}