207 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			207 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Go
		
	
	
	
| /*
 | |
| Copyright 2021 The Flux authors
 | |
| 
 | |
| Licensed 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 controllers
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"fmt"
 | |
| 	"testing"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/fluxcd/pkg/apis/meta"
 | |
| 	"github.com/fluxcd/pkg/testserver"
 | |
| 	sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
 | |
| 	. "github.com/onsi/gomega"
 | |
| 	apimeta "k8s.io/apimachinery/pkg/api/meta"
 | |
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | |
| 	"k8s.io/apimachinery/pkg/types"
 | |
| 	"sigs.k8s.io/controller-runtime/pkg/client"
 | |
| 
 | |
| 	kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta2"
 | |
| )
 | |
| 
 | |
| func TestKustomizationReconciler_DependsOn(t *testing.T) {
 | |
| 	g := NewWithT(t)
 | |
| 	id := "dep-" + randStringRunes(5)
 | |
| 	revision := "v1.0.0"
 | |
| 
 | |
| 	err := createNamespace(id)
 | |
| 	g.Expect(err).NotTo(HaveOccurred(), "failed to create test namespace")
 | |
| 
 | |
| 	err = createKubeConfigSecret(id)
 | |
| 	g.Expect(err).NotTo(HaveOccurred(), "failed to create kubeconfig secret")
 | |
| 
 | |
| 	manifests := func(name string, data string) []testserver.File {
 | |
| 		return []testserver.File{
 | |
| 			{
 | |
| 				Name: "config.yaml",
 | |
| 				Body: fmt.Sprintf(`---
 | |
| apiVersion: v1
 | |
| kind: ConfigMap
 | |
| metadata:
 | |
|   name: %[1]s
 | |
| data:
 | |
|   key: "%[2]s"
 | |
| ---
 | |
| apiVersion: autoscaling/v2beta1
 | |
| kind: HorizontalPodAutoscaler
 | |
| metadata:
 | |
|   labels:
 | |
|   name: "v2beta1-%[1]s"
 | |
|   namespace: "%[2]s"
 | |
| spec:
 | |
|   maxReplicas: 6
 | |
|   metrics:
 | |
|   - resource:
 | |
|       name: cpu
 | |
|       targetAverageUtilization: 80
 | |
|     type: Resource
 | |
|   - resource:
 | |
|       name: memory
 | |
|       targetAverageUtilization: 80
 | |
|     type: Resource
 | |
|   minReplicas: 2
 | |
|   scaleTargetRef:
 | |
|     apiVersion: apps/v1
 | |
|     kind: Deployment
 | |
|     name: test
 | |
| ---
 | |
| apiVersion: autoscaling/v2beta2
 | |
| kind: HorizontalPodAutoscaler
 | |
| metadata:
 | |
|   name: "v2beta2-%[1]s"
 | |
|   namespace: "%[2]s"
 | |
| spec:
 | |
|   scaleTargetRef:
 | |
|     apiVersion: apps/v1
 | |
|     kind: Deployment
 | |
|     name: test
 | |
|   minReplicas: 1
 | |
|   maxReplicas: 10
 | |
|   metrics:
 | |
|   - type: Resource
 | |
|     resource:
 | |
|       name: cpu
 | |
|       target:
 | |
|         type: Utilization
 | |
|         averageUtilization: 50
 | |
|   - type: Pods
 | |
|     pods:
 | |
|       metric:
 | |
|         name: packets-per-second
 | |
|       target:
 | |
|         type: AverageValue
 | |
|         averageValue: 1k
 | |
|   - type: Object
 | |
|     object:
 | |
|       metric:
 | |
|         name: requests-per-second
 | |
|       describedObject:
 | |
|         apiVersion: networking.k8s.io/v1beta1
 | |
|         kind: Ingress
 | |
|         name: main-route
 | |
|       target:
 | |
|         type: Value
 | |
|         value: 10k
 | |
| `, name, data),
 | |
| 			},
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	artifact, err := testServer.ArtifactFromFiles(manifests(id, id))
 | |
| 	g.Expect(err).NotTo(HaveOccurred())
 | |
| 
 | |
| 	repositoryName := types.NamespacedName{
 | |
| 		Name:      fmt.Sprintf("dep-%s", randStringRunes(5)),
 | |
| 		Namespace: id,
 | |
| 	}
 | |
| 
 | |
| 	kustomizationKey := types.NamespacedName{
 | |
| 		Name:      fmt.Sprintf("dep-%s", randStringRunes(5)),
 | |
| 		Namespace: id,
 | |
| 	}
 | |
| 	kustomization := &kustomizev1.Kustomization{
 | |
| 		ObjectMeta: metav1.ObjectMeta{
 | |
| 			Name:      kustomizationKey.Name,
 | |
| 			Namespace: kustomizationKey.Namespace,
 | |
| 		},
 | |
| 		Spec: kustomizev1.KustomizationSpec{
 | |
| 			Interval: metav1.Duration{Duration: reconciliationInterval},
 | |
| 			Path:     "./",
 | |
| 			KubeConfig: &kustomizev1.KubeConfig{
 | |
| 				SecretRef: meta.SecretKeyReference{
 | |
| 					Name: "kubeconfig",
 | |
| 				},
 | |
| 			},
 | |
| 			SourceRef: kustomizev1.CrossNamespaceSourceReference{
 | |
| 				Name:      repositoryName.Name,
 | |
| 				Namespace: repositoryName.Namespace,
 | |
| 				Kind:      sourcev1.GitRepositoryKind,
 | |
| 			},
 | |
| 			TargetNamespace: id,
 | |
| 			Prune:           true,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	g.Expect(k8sClient.Create(context.Background(), kustomization)).To(Succeed())
 | |
| 
 | |
| 	resultK := &kustomizev1.Kustomization{}
 | |
| 
 | |
| 	g.Eventually(func() bool {
 | |
| 		_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
 | |
| 		return apimeta.FindStatusCondition(resultK.Status.Conditions, meta.ReadyCondition) != nil
 | |
| 	}, timeout, time.Second).Should(BeTrue())
 | |
| 
 | |
| 	t.Run("fails due to source not found", func(t *testing.T) {
 | |
| 		g.Eventually(func() bool {
 | |
| 			_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
 | |
| 			ready := apimeta.FindStatusCondition(resultK.Status.Conditions, meta.ReadyCondition)
 | |
| 			return ready.Reason == kustomizev1.ArtifactFailedReason
 | |
| 		}, timeout, time.Second).Should(BeTrue())
 | |
| 	})
 | |
| 
 | |
| 	t.Run("reconciles when source is found", func(t *testing.T) {
 | |
| 		err = applyGitRepository(repositoryName, artifact, revision)
 | |
| 		g.Expect(err).NotTo(HaveOccurred())
 | |
| 
 | |
| 		g.Eventually(func() bool {
 | |
| 			_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
 | |
| 			ready := apimeta.FindStatusCondition(resultK.Status.Conditions, meta.ReadyCondition)
 | |
| 			return ready.Reason == kustomizev1.ReconciliationSucceededReason
 | |
| 		}, timeout, time.Second).Should(BeTrue())
 | |
| 	})
 | |
| 
 | |
| 	t.Run("fails due to dependency not found", func(t *testing.T) {
 | |
| 		g.Eventually(func() error {
 | |
| 			_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
 | |
| 			resultK.Spec.DependsOn = []meta.NamespacedObjectReference{
 | |
| 				{
 | |
| 					Namespace: id,
 | |
| 					Name:      "root",
 | |
| 				},
 | |
| 			}
 | |
| 			return k8sClient.Update(context.Background(), resultK)
 | |
| 		}, timeout, time.Second).Should(BeNil())
 | |
| 
 | |
| 		g.Eventually(func() bool {
 | |
| 			_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(kustomization), resultK)
 | |
| 			ready := apimeta.FindStatusCondition(resultK.Status.Conditions, meta.ReadyCondition)
 | |
| 			return ready.Reason == kustomizev1.DependencyNotReadyReason
 | |
| 		}, timeout, time.Second).Should(BeTrue())
 | |
| 	})
 | |
| }
 |