diff --git a/internal/olm/operator/registry/configmap/deployment_test.go b/internal/olm/operator/registry/configmap/deployment_test.go new file mode 100644 index 0000000000..5b73cdf976 --- /dev/null +++ b/internal/olm/operator/registry/configmap/deployment_test.go @@ -0,0 +1,268 @@ +// Copyright 2020 The Operator-SDK 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 configmap + +import ( + "fmt" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var _ = Describe("Deployment", func() { + + Describe("getRegistryServerName", func() { + It("should return the formatted servername", func() { + Expect(getRegistryServerName("pkgName")).Should(Equal("pkgName-registry-server")) + // This checks if all the special characters are handled correctly + Expect(getRegistryServerName("$abc.foo$@(&#(&!*)@&#")).Should(Equal("-abc-foo--registry-server")) + }) + }) + + Describe("getRegistryDeploymentLabels", func() { + It("should return the deployment labels for the given package name", func() { + labels := map[string]string{ + "owner": "operator-sdk", + "package-name": "$abc.foo$@(&#(&!*)@&#", + "server-name": "-abc-foo--registry-server", + } + + Expect(getRegistryDeploymentLabels("$abc.foo$@(&#(&!*)@&#")).Should(Equal(labels)) + }) + }) + + Describe("applyToDeploymentPodSpec", func() { + It("should apply f to dep's pod template spec", func() { + var res corev1.PodSpec + dep := &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Replicas: nil, + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + NodeName: "testNode", + }, + }, + }, + } + applyToDeploymentPodSpec(dep, func(spec *corev1.PodSpec) { + res = *spec + }) + + Expect(res.NodeName).Should(Equal(dep.Spec.Template.Spec.NodeName)) + }) + }) + + Describe("withConfigMapVolume", func() { + It("should apply f to dep's pod template spec and apply volumes", func() { + dep := &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Replicas: nil, + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + NodeName: "testNode", + }, + }, + }, + } + expecteddep := &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Replicas: nil, + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + NodeName: "testNode2", + }, + }, + }, + } + volume := corev1.Volume{ + Name: "testVolName", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "testCmName", + }, + }, + }, + } + expecteddep.Spec.Template.Spec.Volumes = append(expecteddep.Spec.Template.Spec.Volumes, volume) + f := withConfigMapVolume("testVolName", "testCmName") + f(dep) + + Expect(dep.Spec.Template.Spec.Volumes).Should(Equal(expecteddep.Spec.Template.Spec.Volumes)) + }) + }) + + Describe("withContainerVolumeMounts", func() { + It("should apply f to dep's pod template spec and apply volumemounts", func() { + paths := []string{"testPath1", "testPath2"} + dep := &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Replicas: nil, + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + NodeName: "testNode", + Containers: []corev1.Container{ + corev1.Container{}, + corev1.Container{}, + }, + }, + }, + }, + } + expecteddep := &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Replicas: nil, + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + NodeName: "testNode2", + Containers: []corev1.Container{ + corev1.Container{}, + corev1.Container{}, + }, + }, + }, + }, + } + volumeMounts := []corev1.VolumeMount{} + for _, p := range paths { + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: "testVolName", + MountPath: p, + }) + } + for i := range expecteddep.Spec.Template.Spec.Containers { + expecteddep.Spec.Template.Spec.Containers[i].VolumeMounts = append(expecteddep.Spec.Template.Spec.Containers[i].VolumeMounts, volumeMounts...) + } + f := withContainerVolumeMounts("testVolName", paths...) + f(dep) + + Expect(dep.Spec.Template.Spec.Containers).Should(Equal(expecteddep.Spec.Template.Spec.Containers)) + }) + }) + + Describe("getDBContainerCmd", func() { + It("should apply f to dep's pod template spec and apply volumes", func() { + initCmd := "/bin/initializer -o /path/to/database.db -m /registry/manifests" + srvCmd := "/bin/registry-server -d /path/to/database.db -t /var/log/temp.log" + + Expect(getDBContainerCmd("/path/to/database.db", "/var/log/temp.log")).Should(Equal(fmt.Sprintf("%s && %s", initCmd, srvCmd))) + }) + }) + + Describe("withRegistryGRPCContainer", func() { + It("should apply f to dep's pod template spec and append contaiers", func() { + container := corev1.Container{ + Name: getRegistryServerName("testPkg"), + Image: registryBaseImage, + WorkingDir: "/tmp", + Command: []string{"/bin/sh"}, + Args: []string{ + "-c", + getDBContainerCmd(registryDBName, registryLogFile), + }, + Ports: []corev1.ContainerPort{ + {Name: "registry-grpc", ContainerPort: registryGRPCPort}, + }, + } + dep := &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Replicas: nil, + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + NodeName: "testNode", + Containers: nil, + }, + }, + }, + } + expecteddep := &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Replicas: nil, + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + NodeName: "testNode2", + Containers: nil, + }, + }, + }, + } + + expecteddep.Spec.Template.Spec.Containers = append(expecteddep.Spec.Template.Spec.Containers, container) + f := withRegistryGRPCContainer("testPkg") + f(dep) + + Expect(dep.Spec.Template.Spec.Containers).Should(Equal(expecteddep.Spec.Template.Spec.Containers)) + }) + }) + + Describe("newRegistryDeployment", func() { + var ( + replicas int32 + dep *appsv1.Deployment + ) + BeforeEach(func() { + replicas = 1 + dep = &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + APIVersion: appsv1.SchemeGroupVersion.String(), + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: getRegistryServerName("testPkg"), + Namespace: "testns", + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: getRegistryDeploymentLabels("testPkg"), + }, + Replicas: &replicas, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: getRegistryDeploymentLabels("testPkg"), + }, + }, + }, + } + }) + It("should return a dployment", func() { + f := withRegistryGRPCContainer("testPkg") + f(dep) + + Expect(dep).Should(Equal(newRegistryDeployment("testPkg", "testns", f))) + }) + It("should return a dployment for a custom made function", func() { + f := func(d *appsv1.Deployment) { + d.ObjectMeta.Namespace = "testns2" + } + f(dep) + + Expect(dep).Should(Equal(newRegistryDeployment("testPkg", "testns", f))) + }) + It("should return a dployment for a multiple functions", func() { + f1 := withRegistryGRPCContainer("testPkg") + f1(dep) + + f2 := func(d *appsv1.Deployment) { + d.ObjectMeta.Namespace = "testns2" + } + f2(dep) + + Expect(dep).Should(Equal(newRegistryDeployment("testPkg", "testns", f1, f2))) + }) + }) +})