github.com/verrazzano/verrazzano-monitoring-operator@v0.0.30/pkg/resources/deployments/deployment_test.go (about) 1 // Copyright (C) 2020, 2022, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package deployments 5 6 import ( 7 "fmt" 8 "strings" 9 "testing" 10 11 "github.com/stretchr/testify/assert" 12 vmcontrollerv1 "github.com/verrazzano/verrazzano-monitoring-operator/pkg/apis/vmcontroller/v1" 13 "github.com/verrazzano/verrazzano-monitoring-operator/pkg/config" 14 "github.com/verrazzano/verrazzano-monitoring-operator/pkg/constants" 15 "github.com/verrazzano/verrazzano-monitoring-operator/pkg/resources" 16 "github.com/verrazzano/verrazzano-monitoring-operator/pkg/resources/nodes" 17 appsv1 "k8s.io/api/apps/v1" 18 "k8s.io/apimachinery/pkg/api/resource" 19 v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 20 "k8s.io/client-go/kubernetes/fake" 21 ) 22 23 func TestVMOEmptyDeploymentSize(t *testing.T) { 24 vmo := &vmcontrollerv1.VerrazzanoMonitoringInstance{} 25 operatorConfig := &config.OperatorConfig{} 26 expected, err := New(vmo, fake.NewSimpleClientset(), operatorConfig, map[string]string{}) 27 if err != nil { 28 t.Error(err) 29 } 30 deployments := expected.Deployments 31 assert.Equal(t, 1, len(deployments), "Length of generated deployments") 32 } 33 34 func TestVMOFullDeploymentSize(t *testing.T) { 35 vmo := &vmcontrollerv1.VerrazzanoMonitoringInstance{ 36 Spec: vmcontrollerv1.VerrazzanoMonitoringInstanceSpec{ 37 CascadingDelete: true, 38 Grafana: vmcontrollerv1.Grafana{ 39 Enabled: true, 40 }, 41 Kibana: vmcontrollerv1.Kibana{ 42 Enabled: true, 43 }, 44 Elasticsearch: vmcontrollerv1.Elasticsearch{ 45 Enabled: true, 46 IngestNode: vmcontrollerv1.ElasticsearchNode{Replicas: 1}, 47 MasterNode: vmcontrollerv1.ElasticsearchNode{Replicas: 1}, 48 DataNode: vmcontrollerv1.ElasticsearchNode{Replicas: 1}, 49 }, 50 }, 51 } 52 expected, err := New(vmo, fake.NewSimpleClientset(), &config.OperatorConfig{}, map[string]string{}) 53 if err != nil { 54 t.Error(err) 55 } 56 deployments := expected.Deployments 57 deployments = append(deployments, NewOpenSearchDashboardsDeployment(vmo)) 58 assert.Equal(t, 5, len(deployments), "Length of generated deployments") 59 assert.Equal(t, constants.VMOKind, deployments[0].ObjectMeta.OwnerReferences[0].Kind, "OwnerReferences is not set by default") 60 } 61 62 func TestVMODevProfileFullDeploymentSize(t *testing.T) { 63 64 vmo := &vmcontrollerv1.VerrazzanoMonitoringInstance{ 65 Spec: vmcontrollerv1.VerrazzanoMonitoringInstanceSpec{ 66 CascadingDelete: true, 67 Grafana: vmcontrollerv1.Grafana{ 68 Enabled: true, 69 }, 70 Kibana: vmcontrollerv1.Kibana{ 71 Enabled: true, 72 }, 73 Elasticsearch: vmcontrollerv1.Elasticsearch{ 74 Enabled: true, 75 IngestNode: vmcontrollerv1.ElasticsearchNode{Replicas: 0}, 76 MasterNode: vmcontrollerv1.ElasticsearchNode{ 77 Replicas: 1, 78 Roles: []vmcontrollerv1.NodeRole{ 79 vmcontrollerv1.MasterRole, 80 vmcontrollerv1.IngestRole, 81 vmcontrollerv1.DataRole, 82 }, 83 }, 84 DataNode: vmcontrollerv1.ElasticsearchNode{Replicas: 0}, 85 }, 86 }, 87 } 88 assert.True(t, nodes.IsSingleNodeCluster(vmo), "Single node ES setup, expected IsDevProfile to be true") 89 expected, err := New(vmo, fake.NewSimpleClientset(), &config.OperatorConfig{}, map[string]string{}) 90 if err != nil { 91 t.Error(err) 92 } 93 deployments := expected.Deployments 94 deployments = append(deployments, NewOpenSearchDashboardsDeployment(vmo)) 95 assert.Equal(t, 3, len(deployments), "Length of generated deployments") 96 assert.Equal(t, constants.VMOKind, deployments[0].ObjectMeta.OwnerReferences[0].Kind, "OwnerReferences is not set by default") 97 } 98 99 func TestVMODevProfileInvalidESTopology(t *testing.T) { 100 101 vmo := &vmcontrollerv1.VerrazzanoMonitoringInstance{ 102 Spec: vmcontrollerv1.VerrazzanoMonitoringInstanceSpec{ 103 CascadingDelete: true, 104 Grafana: vmcontrollerv1.Grafana{ 105 Enabled: true, 106 }, 107 Kibana: vmcontrollerv1.Kibana{ 108 Enabled: true, 109 }, 110 Elasticsearch: vmcontrollerv1.Elasticsearch{ 111 Enabled: true, 112 IngestNode: vmcontrollerv1.ElasticsearchNode{Replicas: 0}, 113 MasterNode: vmcontrollerv1.ElasticsearchNode{Replicas: 0}, 114 DataNode: vmcontrollerv1.ElasticsearchNode{Replicas: 0}, 115 }, 116 }, 117 } 118 assert.False(t, nodes.IsSingleNodeCluster(vmo), "Invalid single node ES setup, expected IsDevProfile to be false") 119 _, err := New(vmo, fake.NewSimpleClientset(), &config.OperatorConfig{}, map[string]string{}) 120 assert.Nil(t, err) 121 } 122 123 func TestVMOWithCascadingDelete(t *testing.T) { 124 // With CascadingDelete 125 vmo := &vmcontrollerv1.VerrazzanoMonitoringInstance{ 126 Spec: vmcontrollerv1.VerrazzanoMonitoringInstanceSpec{ 127 CascadingDelete: true, 128 Grafana: vmcontrollerv1.Grafana{ 129 Enabled: true, 130 }, 131 Kibana: vmcontrollerv1.Kibana{ 132 Enabled: true, 133 }, 134 Elasticsearch: vmcontrollerv1.Elasticsearch{ 135 Enabled: true, 136 MasterNode: vmcontrollerv1.ElasticsearchNode{Replicas: 1}, 137 }, 138 }, 139 } 140 expected, err := New(vmo, fake.NewSimpleClientset(), &config.OperatorConfig{}, map[string]string{}) 141 if err != nil { 142 t.Error(err) 143 } 144 deployments := expected.Deployments 145 assert.True(t, len(deployments) > 0, "Non-zero length generated deployments") 146 for _, deployment := range deployments { 147 assert.Equal(t, 1, len(deployment.ObjectMeta.OwnerReferences), "OwnerReferences is not set with CascadingDelete true") 148 } 149 150 // Without CascadingDelete 151 vmo.Spec.CascadingDelete = false 152 expected, err = New(vmo, fake.NewSimpleClientset(), &config.OperatorConfig{}, map[string]string{}) 153 if err != nil { 154 t.Error(err) 155 } 156 deployments = expected.Deployments 157 assert.True(t, len(deployments) > 0, "Non-zero length generated deployments") 158 for _, deployment := range deployments { 159 assert.Equal(t, 0, len(deployment.ObjectMeta.OwnerReferences), "OwnerReferences is set even with CascadingDelete false") 160 } 161 } 162 163 func TestVMOWithResourceConstraints(t *testing.T) { 164 vmo := &vmcontrollerv1.VerrazzanoMonitoringInstance{ 165 ObjectMeta: v1.ObjectMeta{ 166 Name: "system", 167 }, 168 Spec: vmcontrollerv1.VerrazzanoMonitoringInstanceSpec{ 169 Grafana: vmcontrollerv1.Grafana{ 170 Enabled: true, 171 Resources: vmcontrollerv1.Resources{ 172 LimitCPU: "500m", 173 LimitMemory: "120Mi", 174 RequestCPU: "200m", 175 RequestMemory: "60Mi", 176 }, 177 }, 178 Kibana: vmcontrollerv1.Kibana{ 179 Enabled: true, 180 Resources: vmcontrollerv1.Resources{ 181 LimitCPU: "0.53", 182 LimitMemory: "123M", 183 RequestCPU: "0.23", 184 RequestMemory: "63M", 185 }, 186 }, 187 Elasticsearch: vmcontrollerv1.Elasticsearch{ 188 Enabled: true, 189 IngestNode: vmcontrollerv1.ElasticsearchNode{ 190 Name: config.ElasticsearchIngest.Name, 191 Replicas: 1, 192 Resources: vmcontrollerv1.Resources{ 193 LimitCPU: "0.54", 194 LimitMemory: "124M", 195 RequestCPU: "0.24", 196 RequestMemory: "64M", 197 }, 198 Roles: []vmcontrollerv1.NodeRole{vmcontrollerv1.IngestRole}, 199 }, 200 DataNode: vmcontrollerv1.ElasticsearchNode{ 201 Name: config.ElasticsearchData.Name, 202 Replicas: 1, 203 Roles: []vmcontrollerv1.NodeRole{vmcontrollerv1.DataRole}, 204 }, 205 MasterNode: vmcontrollerv1.ElasticsearchNode{Replicas: 1}, 206 }, 207 }, 208 } 209 expected, err := New(vmo, fake.NewSimpleClientset(), &config.OperatorConfig{}, map[string]string{}) 210 if err != nil { 211 t.Error(err) 212 } 213 214 for _, deployment := range expected.Deployments { 215 esDataName := resources.GetMetaName(vmo.Name, config.ElasticsearchData.Name) 216 if deployment.Name == resources.GetMetaName(vmo.Name, config.Grafana.Name) { 217 assert.Equal(t, resource.MustParse("500m"), *deployment.Spec.Template.Spec.Containers[0].Resources.Limits.Cpu(), "Granfana Limit CPU") 218 assert.Equal(t, resource.MustParse("120Mi"), *deployment.Spec.Template.Spec.Containers[0].Resources.Limits.Memory(), "Granfana Limit Memory") 219 assert.Equal(t, resource.MustParse("200m"), *deployment.Spec.Template.Spec.Containers[0].Resources.Requests.Cpu(), "Granfana Request CPU") 220 assert.Equal(t, resource.MustParse("60Mi"), *deployment.Spec.Template.Spec.Containers[0].Resources.Requests.Memory(), "Granfana Request Memory") 221 } else if deployment.Name == resources.GetMetaName(vmo.Name, config.Kibana.Name) { 222 assert.Equal(t, resource.MustParse("0.53"), *deployment.Spec.Template.Spec.Containers[0].Resources.Limits.Cpu(), "Granfana Limit CPU") 223 assert.Equal(t, resource.MustParse("123M"), *deployment.Spec.Template.Spec.Containers[0].Resources.Limits.Memory(), "Granfana Limit Memory") 224 assert.Equal(t, resource.MustParse("0.23"), *deployment.Spec.Template.Spec.Containers[0].Resources.Requests.Cpu(), "Granfana Request CPU") 225 assert.Equal(t, resource.MustParse("63M"), *deployment.Spec.Template.Spec.Containers[0].Resources.Requests.Memory(), "Granfana Request Memory") 226 } else if deployment.Name == resources.GetMetaName(vmo.Name, config.ElasticsearchIngest.Name) { 227 assert.Equal(t, resource.MustParse("0.54"), *deployment.Spec.Template.Spec.Containers[0].Resources.Limits.Cpu(), "Granfana Limit CPU") 228 assert.Equal(t, resource.MustParse("124M"), *deployment.Spec.Template.Spec.Containers[0].Resources.Limits.Memory(), "Granfana Limit Memory") 229 assert.Equal(t, resource.MustParse("0.24"), *deployment.Spec.Template.Spec.Containers[0].Resources.Requests.Cpu(), "Granfana Request CPU") 230 assert.Equal(t, resource.MustParse("64M"), *deployment.Spec.Template.Spec.Containers[0].Resources.Requests.Memory(), "Granfana Request Memory") 231 } else if deployment.Name == resources.GetMetaName(vmo.Name, config.ElasticsearchMaster.Name) { 232 // No resources specified on this endpoint 233 } else if strings.Contains(deployment.Name, resources.GetMetaName(vmo.Name, config.ElasticsearchData.Name)) { 234 // No resources specified on this endpoint 235 } else if deployment.Name == resources.GetMetaName(vmo.Name, config.API.Name) { 236 // No resources specified on API endpoint 237 } else if deployment.Name == resources.OidcProxyMetaName(vmo.Name, config.ElasticsearchIngest.Name) { 238 // No resources specified on OIDC proxy 239 } else { 240 t.Log("ESDataName: " + esDataName) 241 t.Error("Unknown Deployment Name: " + deployment.Name) 242 } 243 } 244 } 245 246 func TestVMOWithReplicas(t *testing.T) { 247 vmo := &vmcontrollerv1.VerrazzanoMonitoringInstance{ 248 Spec: vmcontrollerv1.VerrazzanoMonitoringInstanceSpec{ 249 API: vmcontrollerv1.API{ 250 Replicas: 2, 251 }, 252 Kibana: vmcontrollerv1.Kibana{ 253 Enabled: true, 254 Replicas: 4, 255 }, 256 }, 257 } 258 expected, err := New(vmo, fake.NewSimpleClientset(), &config.OperatorConfig{}, map[string]string{}) 259 if err != nil { 260 t.Error(err) 261 } 262 deployments := expected.Deployments 263 deployments = append(deployments, NewOpenSearchDashboardsDeployment(vmo)) 264 assert.Equal(t, 2, len(deployments), "Length of generated deployments") 265 for _, deployment := range deployments { 266 if deployment.Name == resources.GetMetaName(vmo.Name, config.API.Name) { 267 assert.Equal(t, *resources.NewVal(2), *deployment.Spec.Replicas, "Api replicas") 268 } else if deployment.Name == resources.GetMetaName(vmo.Name, config.OpenSearchDashboards.Name) { 269 assert.Equal(t, *resources.NewVal(4), *deployment.Spec.Replicas, "Kibana replicas") 270 } 271 } 272 } 273 274 func TestGetAdForPvcIndex(t *testing.T) { 275 m1 := map[string]string{} 276 m2 := map[string]string{"pvc1": "ad1", "pvc2": "ad2"} 277 s1 := vmcontrollerv1.Storage{ 278 Size: "50Gi", 279 PvcNames: []string{"pvc1", "pvc2", "pvc3"}, 280 } 281 assert.Equal(t, "", getAvailabilityDomainForPvcIndex(nil, m1, 0), "With nil storage") 282 assert.Equal(t, "", getAvailabilityDomainForPvcIndex(nil, m2, 0), "With nil storage") 283 assert.Equal(t, "", getAvailabilityDomainForPvcIndex(&s1, m1, 0), "With empty AD map") 284 assert.Equal(t, "ad1", getAvailabilityDomainForPvcIndex(&s1, m2, 0), "With valid PVC") 285 assert.Equal(t, "ad2", getAvailabilityDomainForPvcIndex(&s1, m2, 1), "With valid PVC") 286 assert.Equal(t, "", getAvailabilityDomainForPvcIndex(&s1, m2, 2), "With non-existent PVC") 287 assert.Equal(t, "", getAvailabilityDomainForPvcIndex(&s1, m2, 3), "With PVC index out of bounds") 288 } 289 290 func TestAPIWithNatGatewayIPs(t *testing.T) { 291 vmo := &vmcontrollerv1.VerrazzanoMonitoringInstance{ 292 ObjectMeta: v1.ObjectMeta{ 293 Name: "my-vmo", 294 }, 295 Spec: vmcontrollerv1.VerrazzanoMonitoringInstanceSpec{ 296 NatGatewayIPs: []string{"1.1.1.1", "2.1.1.1"}, 297 }, 298 } 299 expected, err := New(vmo, fake.NewSimpleClientset(), &config.OperatorConfig{}, map[string]string{}) 300 if err != nil { 301 t.Error(err) 302 } 303 deployments := expected.Deployments 304 apiDeployment, err := getDeploymentByName(constants.VMOServiceNamePrefix+"my-vmo-api", deployments) 305 if err != nil { 306 t.Error(err) 307 } 308 assert.Equal(t, []string{"--natGatewayIPs=1.1.1.1,2.1.1.1"}, apiDeployment.Spec.Template.Spec.Containers[0].Args, "API args with NAT GW") 309 } 310 311 // Returns the deployment with the given name from the given list of deployments, returning an error if not found 312 func getDeploymentByName(deploymentName string, deploymentList []*appsv1.Deployment) (*appsv1.Deployment, error) { 313 for _, deployment := range deploymentList { 314 if deployment.Name == deploymentName { 315 return deployment, nil 316 } 317 } 318 return nil, fmt.Errorf("deployment %s not found", deploymentName) 319 }