From a05581cec3075aa48bb534342ff85e2ac52f3a58 Mon Sep 17 00:00:00 2001 From: Daman Arora Date: Thu, 8 Jan 2026 11:27:29 -0500 Subject: [PATCH] add unit tests --- ...bernetesClusterAffinityGroupMapVOTest.java | 87 ++++++++++++ .../KubernetesClusterManagerImplTest.java | 134 ++++++++++++++++++ .../KubernetesClusterActionWorkerTest.java | 99 +++++++++++++ 3 files changed, 320 insertions(+) create mode 100644 plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesClusterAffinityGroupMapVOTest.java diff --git a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesClusterAffinityGroupMapVOTest.java b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesClusterAffinityGroupMapVOTest.java new file mode 100644 index 00000000000..d0aafc7d1e5 --- /dev/null +++ b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesClusterAffinityGroupMapVOTest.java @@ -0,0 +1,87 @@ +// 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 com.cloud.kubernetes.cluster; + +import org.junit.Assert; +import org.junit.Test; + +public class KubernetesClusterAffinityGroupMapVOTest { + + @Test + public void testConstructorAndGetters() { + KubernetesClusterAffinityGroupMapVO vo = + new KubernetesClusterAffinityGroupMapVO(1L, "CONTROL", 100L); + + Assert.assertEquals(1L, vo.getClusterId()); + Assert.assertEquals("CONTROL", vo.getNodeType()); + Assert.assertEquals(100L, vo.getAffinityGroupId()); + } + + @Test + public void testDefaultConstructor() { + KubernetesClusterAffinityGroupMapVO vo = new KubernetesClusterAffinityGroupMapVO(); + Assert.assertNotNull(vo); + } + + @Test + public void testSetClusterId() { + KubernetesClusterAffinityGroupMapVO vo = new KubernetesClusterAffinityGroupMapVO(); + vo.setClusterId(2L); + Assert.assertEquals(2L, vo.getClusterId()); + } + + @Test + public void testSetNodeType() { + KubernetesClusterAffinityGroupMapVO vo = new KubernetesClusterAffinityGroupMapVO(); + vo.setNodeType("WORKER"); + Assert.assertEquals("WORKER", vo.getNodeType()); + } + + @Test + public void testSetAffinityGroupId() { + KubernetesClusterAffinityGroupMapVO vo = new KubernetesClusterAffinityGroupMapVO(); + vo.setAffinityGroupId(200L); + Assert.assertEquals(200L, vo.getAffinityGroupId()); + } + + @Test + public void testAllNodeTypes() { + KubernetesClusterAffinityGroupMapVO controlVo = + new KubernetesClusterAffinityGroupMapVO(1L, "CONTROL", 10L); + KubernetesClusterAffinityGroupMapVO workerVo = + new KubernetesClusterAffinityGroupMapVO(1L, "WORKER", 20L); + KubernetesClusterAffinityGroupMapVO etcdVo = + new KubernetesClusterAffinityGroupMapVO(1L, "ETCD", 30L); + + Assert.assertEquals("CONTROL", controlVo.getNodeType()); + Assert.assertEquals("WORKER", workerVo.getNodeType()); + Assert.assertEquals("ETCD", etcdVo.getNodeType()); + } + + @Test + public void testSettersChain() { + KubernetesClusterAffinityGroupMapVO vo = new KubernetesClusterAffinityGroupMapVO(); + + vo.setClusterId(5L); + vo.setNodeType("ETCD"); + vo.setAffinityGroupId(500L); + + Assert.assertEquals(5L, vo.getClusterId()); + Assert.assertEquals("ETCD", vo.getNodeType()); + Assert.assertEquals(500L, vo.getAffinityGroupId()); + } +} diff --git a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImplTest.java b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImplTest.java index 2a381f282de..9c5ca5fa110 100644 --- a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImplTest.java +++ b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImplTest.java @@ -26,6 +26,7 @@ import com.cloud.dc.DataCenter; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.kubernetes.cluster.actionworkers.KubernetesClusterActionWorker; +import com.cloud.kubernetes.cluster.dao.KubernetesClusterAffinityGroupMapDao; import com.cloud.kubernetes.cluster.dao.KubernetesClusterDao; import com.cloud.kubernetes.cluster.dao.KubernetesClusterVmMapDao; import com.cloud.kubernetes.version.KubernetesSupportedVersion; @@ -46,9 +47,12 @@ import com.cloud.utils.Pair; import com.cloud.utils.net.NetUtils; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.dao.VMInstanceDao; +import org.apache.cloudstack.affinity.AffinityGroupVO; +import org.apache.cloudstack.affinity.dao.AffinityGroupDao; import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.command.user.kubernetes.cluster.AddVirtualMachinesToKubernetesClusterCmd; import org.apache.cloudstack.api.command.user.kubernetes.cluster.RemoveVirtualMachinesFromKubernetesClusterCmd; +import org.apache.cloudstack.api.response.KubernetesClusterResponse; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.commons.collections.MapUtils; @@ -103,6 +107,12 @@ public class KubernetesClusterManagerImplTest { @Mock private ServiceOfferingDao serviceOfferingDao; + @Mock + private KubernetesClusterAffinityGroupMapDao kubernetesClusterAffinityGroupMapDao; + + @Mock + private AffinityGroupDao affinityGroupDao; + @Spy @InjectMocks KubernetesClusterManagerImpl kubernetesClusterManager; @@ -441,4 +451,128 @@ public class KubernetesClusterManagerImplTest { String cksClusterPreferredArch = kubernetesClusterManager.getCksClusterPreferredArch(systemVMArch, cksIso); Assert.assertEquals(CPU.CPUArch.amd64.getType(), cksClusterPreferredArch); } + + @Test + public void testSetAffinityGroupResponseForNodeTypeControl() { + KubernetesClusterResponse response = new KubernetesClusterResponse(); + long clusterId = 1L; + + AffinityGroupVO ag1 = Mockito.mock(AffinityGroupVO.class); + AffinityGroupVO ag2 = Mockito.mock(AffinityGroupVO.class); + Mockito.when(ag1.getUuid()).thenReturn("uuid-1"); + Mockito.when(ag1.getName()).thenReturn("affinity-group-1"); + Mockito.when(ag2.getUuid()).thenReturn("uuid-2"); + Mockito.when(ag2.getName()).thenReturn("affinity-group-2"); + + Mockito.when(kubernetesClusterAffinityGroupMapDao.listAffinityGroupIdsByClusterIdAndNodeType(clusterId, CONTROL.name())) + .thenReturn(Arrays.asList(1L, 2L)); + Mockito.when(affinityGroupDao.findById(1L)).thenReturn(ag1); + Mockito.when(affinityGroupDao.findById(2L)).thenReturn(ag2); + + kubernetesClusterManager.setAffinityGroupResponseForNodeType(response, clusterId, CONTROL.name()); + + Mockito.verify(kubernetesClusterAffinityGroupMapDao).listAffinityGroupIdsByClusterIdAndNodeType(clusterId, CONTROL.name()); + Mockito.verify(affinityGroupDao).findById(1L); + Mockito.verify(affinityGroupDao).findById(2L); + } + + @Test + public void testSetAffinityGroupResponseForNodeTypeWorker() { + KubernetesClusterResponse response = new KubernetesClusterResponse(); + long clusterId = 1L; + + AffinityGroupVO ag = Mockito.mock(AffinityGroupVO.class); + Mockito.when(ag.getUuid()).thenReturn("worker-uuid"); + Mockito.when(ag.getName()).thenReturn("worker-affinity"); + + Mockito.when(kubernetesClusterAffinityGroupMapDao.listAffinityGroupIdsByClusterIdAndNodeType(clusterId, WORKER.name())) + .thenReturn(Arrays.asList(10L)); + Mockito.when(affinityGroupDao.findById(10L)).thenReturn(ag); + + kubernetesClusterManager.setAffinityGroupResponseForNodeType(response, clusterId, WORKER.name()); + + Mockito.verify(kubernetesClusterAffinityGroupMapDao).listAffinityGroupIdsByClusterIdAndNodeType(clusterId, WORKER.name()); + Mockito.verify(affinityGroupDao).findById(10L); + } + + @Test + public void testSetAffinityGroupResponseForNodeTypeEtcd() { + KubernetesClusterResponse response = new KubernetesClusterResponse(); + long clusterId = 1L; + + AffinityGroupVO ag = Mockito.mock(AffinityGroupVO.class); + Mockito.when(ag.getUuid()).thenReturn("etcd-uuid"); + Mockito.when(ag.getName()).thenReturn("etcd-affinity"); + + Mockito.when(kubernetesClusterAffinityGroupMapDao.listAffinityGroupIdsByClusterIdAndNodeType(clusterId, ETCD.name())) + .thenReturn(Arrays.asList(20L)); + Mockito.when(affinityGroupDao.findById(20L)).thenReturn(ag); + + kubernetesClusterManager.setAffinityGroupResponseForNodeType(response, clusterId, ETCD.name()); + + Mockito.verify(kubernetesClusterAffinityGroupMapDao).listAffinityGroupIdsByClusterIdAndNodeType(clusterId, ETCD.name()); + Mockito.verify(affinityGroupDao).findById(20L); + } + + @Test + public void testSetAffinityGroupResponseForNodeTypeEmptyList() { + KubernetesClusterResponse response = new KubernetesClusterResponse(); + long clusterId = 1L; + + Mockito.when(kubernetesClusterAffinityGroupMapDao.listAffinityGroupIdsByClusterIdAndNodeType(clusterId, CONTROL.name())) + .thenReturn(Collections.emptyList()); + + kubernetesClusterManager.setAffinityGroupResponseForNodeType(response, clusterId, CONTROL.name()); + + Mockito.verify(affinityGroupDao, Mockito.never()).findById(Mockito.anyLong()); + } + + @Test + public void testSetAffinityGroupResponseForNodeTypeNullList() { + KubernetesClusterResponse response = new KubernetesClusterResponse(); + long clusterId = 1L; + + Mockito.when(kubernetesClusterAffinityGroupMapDao.listAffinityGroupIdsByClusterIdAndNodeType(clusterId, ETCD.name())) + .thenReturn(null); + + kubernetesClusterManager.setAffinityGroupResponseForNodeType(response, clusterId, ETCD.name()); + + Mockito.verify(affinityGroupDao, Mockito.never()).findById(Mockito.anyLong()); + } + + @Test + public void testSetAffinityGroupResponseForNodeTypeNullAffinityGroup() { + KubernetesClusterResponse response = new KubernetesClusterResponse(); + long clusterId = 1L; + + AffinityGroupVO ag1 = Mockito.mock(AffinityGroupVO.class); + Mockito.when(ag1.getUuid()).thenReturn("uuid-1"); + Mockito.when(ag1.getName()).thenReturn("affinity-group-1"); + + Mockito.when(kubernetesClusterAffinityGroupMapDao.listAffinityGroupIdsByClusterIdAndNodeType(clusterId, CONTROL.name())) + .thenReturn(Arrays.asList(1L, 2L)); + Mockito.when(affinityGroupDao.findById(1L)).thenReturn(ag1); + Mockito.when(affinityGroupDao.findById(2L)).thenReturn(null); + + kubernetesClusterManager.setAffinityGroupResponseForNodeType(response, clusterId, CONTROL.name()); + + Mockito.verify(affinityGroupDao).findById(1L); + Mockito.verify(affinityGroupDao).findById(2L); + } + + @Test + public void testSetNodeTypeAffinityGroupResponse() { + KubernetesClusterResponse response = new KubernetesClusterResponse(); + long clusterId = 1L; + + Mockito.when(kubernetesClusterAffinityGroupMapDao.listAffinityGroupIdsByClusterIdAndNodeType(Mockito.eq(clusterId), Mockito.anyString())) + .thenReturn(Collections.emptyList()); + + kubernetesClusterManager.setNodeTypeAffinityGroupResponse(response, clusterId); + + Mockito.verify(kubernetesClusterAffinityGroupMapDao).listAffinityGroupIdsByClusterIdAndNodeType(clusterId, CONTROL.name()); + Mockito.verify(kubernetesClusterAffinityGroupMapDao).listAffinityGroupIdsByClusterIdAndNodeType(clusterId, WORKER.name()); + Mockito.verify(kubernetesClusterAffinityGroupMapDao).listAffinityGroupIdsByClusterIdAndNodeType(clusterId, ETCD.name()); + } + } diff --git a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterActionWorkerTest.java b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterActionWorkerTest.java index 1eb55808e09..a25ec55cc04 100644 --- a/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterActionWorkerTest.java +++ b/plugins/integrations/kubernetes-service/src/test/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterActionWorkerTest.java @@ -16,8 +16,14 @@ // under the License. package com.cloud.kubernetes.cluster.actionworkers; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.UUID; +import org.apache.cloudstack.affinity.AffinityGroupVO; +import org.apache.cloudstack.affinity.dao.AffinityGroupDao; import org.apache.cloudstack.api.ApiConstants; import org.junit.Assert; import org.junit.Before; @@ -30,6 +36,8 @@ import org.mockito.junit.MockitoJUnitRunner; import com.cloud.kubernetes.cluster.KubernetesCluster; import com.cloud.kubernetes.cluster.KubernetesClusterDetailsVO; import com.cloud.kubernetes.cluster.KubernetesClusterManagerImpl; +import com.cloud.kubernetes.cluster.KubernetesServiceHelper.KubernetesClusterNodeType; +import com.cloud.kubernetes.cluster.dao.KubernetesClusterAffinityGroupMapDao; import com.cloud.kubernetes.cluster.dao.KubernetesClusterDao; import com.cloud.kubernetes.cluster.dao.KubernetesClusterDetailsDao; import com.cloud.kubernetes.cluster.dao.KubernetesClusterVmMapDao; @@ -60,6 +68,12 @@ public class KubernetesClusterActionWorkerTest { @Mock IPAddressDao ipAddressDao; + @Mock + KubernetesClusterAffinityGroupMapDao kubernetesClusterAffinityGroupMapDao; + + @Mock + AffinityGroupDao affinityGroupDao; + KubernetesClusterActionWorker actionWorker = null; final static Long DEFAULT_ID = 1L; @@ -70,10 +84,12 @@ public class KubernetesClusterActionWorkerTest { kubernetesClusterManager.kubernetesSupportedVersionDao = kubernetesSupportedVersionDao; kubernetesClusterManager.kubernetesClusterDetailsDao = kubernetesClusterDetailsDao; kubernetesClusterManager.kubernetesClusterVmMapDao = kubernetesClusterVmMapDao; + kubernetesClusterManager.kubernetesClusterAffinityGroupMapDao = kubernetesClusterAffinityGroupMapDao; KubernetesCluster kubernetesCluster = Mockito.mock(KubernetesCluster.class); Mockito.when(kubernetesCluster.getId()).thenReturn(DEFAULT_ID); actionWorker = new KubernetesClusterActionWorker(kubernetesCluster, kubernetesClusterManager); actionWorker.ipAddressDao = ipAddressDao; + actionWorker.affinityGroupDao = affinityGroupDao; } @Test @@ -130,4 +146,87 @@ public class KubernetesClusterActionWorkerTest { IpAddress result = actionWorker.getVpcTierKubernetesPublicIp(mockNetworkForGetVpcTierKubernetesPublicIpTest()); Assert.assertNotNull(result); } + + @Test + public void testGetAffinityGroupIdsForNodeTypeReturnsIds() { + Mockito.when(kubernetesClusterAffinityGroupMapDao.listAffinityGroupIdsByClusterIdAndNodeType(DEFAULT_ID, "CONTROL")) + .thenReturn(Arrays.asList(1L, 2L)); + + List result = actionWorker.getAffinityGroupIdsForNodeType(KubernetesClusterNodeType.CONTROL); + + Assert.assertEquals(2, result.size()); + Assert.assertTrue(result.containsAll(Arrays.asList(1L, 2L))); + } + + @Test + public void testGetAffinityGroupIdsForNodeTypeReturnsEmptyList() { + Mockito.when(kubernetesClusterAffinityGroupMapDao.listAffinityGroupIdsByClusterIdAndNodeType(DEFAULT_ID, "WORKER")) + .thenReturn(Collections.emptyList()); + + List result = actionWorker.getAffinityGroupIdsForNodeType(KubernetesClusterNodeType.WORKER); + + Assert.assertTrue(result.isEmpty()); + } + + @Test + public void testGetMergedAffinityGroupIdsWithExplicitDedication() { + Mockito.when(kubernetesClusterAffinityGroupMapDao.listAffinityGroupIdsByClusterIdAndNodeType(DEFAULT_ID, "CONTROL")) + .thenReturn(new ArrayList<>(Arrays.asList(1L))); + + AffinityGroupVO explicitGroup = Mockito.mock(AffinityGroupVO.class); + Mockito.when(explicitGroup.getId()).thenReturn(99L); + Mockito.when(affinityGroupDao.findByAccountAndType(Mockito.anyLong(), Mockito.eq("ExplicitDedication"))) + .thenReturn(explicitGroup); + + List result = actionWorker.getMergedAffinityGroupIds(KubernetesClusterNodeType.CONTROL, 1L, 1L); + + Assert.assertEquals(2, result.size()); + Assert.assertTrue(result.contains(1L)); + Assert.assertTrue(result.contains(99L)); + } + + @Test + public void testGetMergedAffinityGroupIdsNoExplicitDedication() { + Mockito.when(kubernetesClusterAffinityGroupMapDao.listAffinityGroupIdsByClusterIdAndNodeType(DEFAULT_ID, "WORKER")) + .thenReturn(new ArrayList<>(Arrays.asList(1L, 2L))); + Mockito.when(affinityGroupDao.findByAccountAndType(Mockito.anyLong(), Mockito.eq("ExplicitDedication"))) + .thenReturn(null); + Mockito.when(affinityGroupDao.findDomainLevelGroupByType(Mockito.anyLong(), Mockito.eq("ExplicitDedication"))) + .thenReturn(null); + + List result = actionWorker.getMergedAffinityGroupIds(KubernetesClusterNodeType.WORKER, 1L, 1L); + + Assert.assertEquals(2, result.size()); + } + + @Test + public void testGetMergedAffinityGroupIdsReturnsNullWhenEmpty() { + Mockito.when(kubernetesClusterAffinityGroupMapDao.listAffinityGroupIdsByClusterIdAndNodeType(DEFAULT_ID, "ETCD")) + .thenReturn(new ArrayList<>()); + Mockito.when(affinityGroupDao.findByAccountAndType(Mockito.anyLong(), Mockito.anyString())) + .thenReturn(null); + Mockito.when(affinityGroupDao.findDomainLevelGroupByType(Mockito.anyLong(), Mockito.anyString())) + .thenReturn(null); + + List result = actionWorker.getMergedAffinityGroupIds(KubernetesClusterNodeType.ETCD, 1L, 1L); + + Assert.assertNull(result); + } + + @Test + public void testGetMergedAffinityGroupIdsExplicitDedicationAlreadyInList() { + Mockito.when(kubernetesClusterAffinityGroupMapDao.listAffinityGroupIdsByClusterIdAndNodeType(DEFAULT_ID, "CONTROL")) + .thenReturn(new ArrayList<>(Arrays.asList(99L, 2L))); + + AffinityGroupVO explicitGroup = Mockito.mock(AffinityGroupVO.class); + Mockito.when(explicitGroup.getId()).thenReturn(99L); + Mockito.when(affinityGroupDao.findByAccountAndType(Mockito.anyLong(), Mockito.eq("ExplicitDedication"))) + .thenReturn(explicitGroup); + + List result = actionWorker.getMergedAffinityGroupIds(KubernetesClusterNodeType.CONTROL, 1L, 1L); + + Assert.assertEquals(2, result.size()); + Assert.assertTrue(result.contains(99L)); + Assert.assertTrue(result.contains(2L)); + } }