1919import com .cloud .kubernetes .cluster .KubernetesCluster ;
2020import com .cloud .kubernetes .cluster .KubernetesClusterVmMapVO ;
2121import com .cloud .kubernetes .cluster .KubernetesClusterManagerImpl ;
22+ import com .cloud .kubernetes .cluster .KubernetesClusterVO ;
2223import com .cloud .kubernetes .cluster .dao .KubernetesClusterVmMapDao ;
2324import com .cloud .offering .ServiceOffering ;
25+ import com .cloud .network .Network ;
2426import com .cloud .service .ServiceOfferingVO ;
2527import com .cloud .service .dao .ServiceOfferingDao ;
2628import com .cloud .utils .Pair ;
2729import com .cloud .vm .UserVmVO ;
30+ import com .cloud .vm .UserVmManager ;
2831import com .cloud .vm .dao .UserVmDao ;
2932import org .junit .Assert ;
3033import org .junit .Before ;
3437import org .mockito .Mock ;
3538import org .mockito .Mockito ;
3639import org .mockito .junit .MockitoJUnitRunner ;
40+ import org .springframework .test .util .ReflectionTestUtils ;
3741
3842import java .util .Arrays ;
43+ import java .util .ArrayList ;
44+ import java .util .Collections ;
3945import java .util .List ;
4046
4147import static com .cloud .kubernetes .cluster .KubernetesServiceHelper .KubernetesClusterNodeType .CONTROL ;
4248import static com .cloud .kubernetes .cluster .KubernetesServiceHelper .KubernetesClusterNodeType .DEFAULT ;
49+ import static com .cloud .kubernetes .cluster .KubernetesServiceHelper .KubernetesClusterNodeType .WORKER ;
4350
4451@ RunWith (MockitoJUnitRunner .class )
4552public class KubernetesClusterScaleWorkerTest {
@@ -54,6 +61,8 @@ public class KubernetesClusterScaleWorkerTest {
5461 private KubernetesClusterVmMapDao kubernetesClusterVmMapDao ;
5562 @ Mock
5663 private UserVmDao userVmDao ;
64+ @ Mock
65+ private UserVmManager userVmManager ;
5766
5867 private KubernetesClusterScaleWorker worker ;
5968
@@ -67,6 +76,123 @@ public void setUp() {
6776 worker .userVmDao = userVmDao ;
6877 }
6978
79+ @ Test
80+ public void testNodeIdsScaleInPreservesMixedOfferingsAndRemovesSelectedWorker () {
81+ assertScaleInPreservesOfferings (true , false );
82+ }
83+
84+ @ Test
85+ public void testCountOnlyScaleInPreservesMixedOfferings () {
86+ assertScaleInPreservesOfferings (false , false );
87+ }
88+
89+ @ Test
90+ public void testNodeIdsScaleInPreservesLegacyGlobalOffering () {
91+ assertScaleInPreservesOfferings (true , true );
92+ }
93+
94+ private void assertScaleInPreservesOfferings (boolean selectedNode , boolean legacyOffering ) {
95+ Mockito .when (kubernetesCluster .getId ()).thenReturn (7L );
96+ Mockito .when (kubernetesCluster .getState ()).thenReturn (KubernetesCluster .State .Running );
97+ Mockito .when (kubernetesCluster .getNodeCount ()).thenReturn (2L );
98+ Mockito .when (kubernetesCluster .getTotalNodeCount ()).thenReturn (3L );
99+ Mockito .when (kubernetesCluster .getServiceOfferingId ()).thenReturn (defaultOfferingId );
100+ Mockito .when (kubernetesCluster .getMinSize ()).thenReturn (null );
101+ Mockito .when (kubernetesCluster .getMaxSize ()).thenReturn (null );
102+ Mockito .when (kubernetesCluster .getCores ()).thenReturn (legacyOffering ? 6L : 9L );
103+ Mockito .when (kubernetesCluster .getMemory ()).thenReturn (legacyOffering ? 6144L : 11264L );
104+ ServiceOfferingVO legacy = Mockito .mock (ServiceOfferingVO .class );
105+ if (legacyOffering ) {
106+ Mockito .when (legacy .getCpu ()).thenReturn (2 );
107+ Mockito .when (legacy .getRamSize ()).thenReturn (2048 );
108+ }
109+ Mockito .when (serviceOfferingDao .findById (defaultOfferingId )).thenReturn (legacy );
110+ long workerOfferingId = legacyOffering ? defaultOfferingId : 12L ;
111+ Mockito .when (kubernetesCluster .getWorkerNodeServiceOfferingId ()).thenReturn (legacyOffering ? null : workerOfferingId );
112+ if (!legacyOffering ) {
113+ ServiceOfferingVO workerOffering = Mockito .mock (ServiceOfferingVO .class );
114+ Mockito .when (workerOffering .getCpu ()).thenReturn (3 );
115+ Mockito .when (workerOffering .getRamSize ()).thenReturn (4096 );
116+ Mockito .when (serviceOfferingDao .findById (workerOfferingId )).thenReturn (workerOffering );
117+ }
118+ KubernetesClusterVmMapVO control = Mockito .mock (KubernetesClusterVmMapVO .class );
119+ KubernetesClusterVmMapVO retained = Mockito .mock (KubernetesClusterVmMapVO .class );
120+ KubernetesClusterVmMapVO removed = Mockito .mock (KubernetesClusterVmMapVO .class );
121+ Mockito .when (retained .getVmId ()).thenReturn (100L );
122+ UserVmVO retainedVm = Mockito .mock (UserVmVO .class );
123+ Mockito .when (retainedVm .getServiceOfferingId ()).thenReturn (workerOfferingId );
124+ Mockito .when (userVmDao .findById (100L )).thenReturn (retainedVm );
125+ Mockito .when (kubernetesClusterVmMapDao .listByClusterId (7L )).thenReturn (Arrays .asList (control , retained , removed ));
126+ Mockito .when (kubernetesClusterVmMapDao .listByClusterIdAndVmType (7L , WORKER )).thenReturn (Arrays .asList (retained , removed ));
127+ KubernetesClusterScaleWorker scaleWorker = Mockito .spy (new KubernetesClusterScaleWorker (kubernetesCluster ,
128+ Collections .emptyMap (), selectedNode ? null : 1L , selectedNode ? List .of (101L ) : null , null , null , null , clusterManager ));
129+ scaleWorker .serviceOfferingDao = serviceOfferingDao ;
130+ scaleWorker .kubernetesClusterVmMapDao = kubernetesClusterVmMapDao ;
131+ scaleWorker .userVmDao = userVmDao ;
132+ scaleWorker .userVmManager = userVmManager ;
133+ Network network = Mockito .mock (Network .class );
134+ ReflectionTestUtils .setField (scaleWorker , "network" , network );
135+ Mockito .doNothing ().when (scaleWorker ).init ();
136+ Mockito .doReturn (new Pair <>("192.0.2.1" , 2222 )).when (scaleWorker ).getKubernetesClusterServerIpSshPort (null );
137+ Mockito .doReturn ("192.0.2.1" ).when (scaleWorker ).resolveApiPublicIpAddress (network );
138+ Mockito .doReturn (true ).when (scaleWorker ).stateTransitTo (Mockito .anyLong (), Mockito .any ());
139+ if (selectedNode ) {
140+ Mockito .doReturn (new ArrayList <>(List .of (removed ))).when (scaleWorker ).getKubernetesClusterVMMapsForNodes (List .of (101L ));
141+ } else {
142+ Mockito .doReturn (new ArrayList <>(List .of (removed ))).when (scaleWorker ).getWorkerNodesToRemove ();
143+ }
144+ Mockito .doNothing ().when (scaleWorker ).removeNodesFromCluster (Mockito .anyList ());
145+ KubernetesClusterVO updatedCluster = Mockito .mock (KubernetesClusterVO .class );
146+ Mockito .doReturn (updatedCluster ).when (scaleWorker ).updateKubernetesClusterEntry (Mockito .any (), Mockito .any (), Mockito .any (),
147+ Mockito .any (), Mockito .any (), Mockito .any (), Mockito .any (), Mockito .any (), Mockito .anyBoolean (), Mockito .anyBoolean ());
148+
149+ Assert .assertTrue (scaleWorker .scaleCluster ());
150+
151+ Mockito .verify (scaleWorker ).removeNodesFromCluster (List .of (removed ));
152+ Mockito .verify (scaleWorker ).updateKubernetesClusterEntry (legacyOffering ? 4L : 6L , legacyOffering ? 4096L : 7168L ,
153+ 1L , null , false , null , null , WORKER , false , false );
154+ Mockito .verifyNoInteractions (userVmManager );
155+ Mockito .verify (kubernetesClusterVmMapDao , Mockito .never ()).listByClusterIdAndVmType (7L , CONTROL );
156+ }
157+
158+ @ Test
159+ public void testAutoscalingOnlyEnablePreservesOfferings () {
160+ assertAutoscalingPreservesOfferings (false , true , false );
161+ }
162+
163+ @ Test
164+ public void testAutoscalingOnlyDisablePreservesOfferings () {
165+ assertAutoscalingPreservesOfferings (true , false , false );
166+ }
167+
168+ @ Test
169+ public void testAutoscalingBoundsOnlyChangePreservesOfferings () {
170+ assertAutoscalingPreservesOfferings (true , true , true );
171+ }
172+
173+ private void assertAutoscalingPreservesOfferings (boolean existingEnabled , boolean requestedEnabled , boolean boundsChange ) {
174+ Mockito .when (kubernetesCluster .getState ()).thenReturn (KubernetesCluster .State .Running );
175+ Mockito .when (kubernetesCluster .getAutoscalingEnabled ()).thenReturn (existingEnabled );
176+ if (boundsChange ) {
177+ Mockito .when (kubernetesCluster .getMinSize ()).thenReturn (1L );
178+ }
179+ KubernetesClusterScaleWorker scaleWorker = Mockito .spy (new KubernetesClusterScaleWorker (kubernetesCluster ,
180+ Collections .emptyMap (), null , null , requestedEnabled , 2L , 5L , clusterManager ));
181+ scaleWorker .serviceOfferingDao = serviceOfferingDao ;
182+ scaleWorker .userVmManager = userVmManager ;
183+ ServiceOfferingVO existingOffering = Mockito .mock (ServiceOfferingVO .class );
184+ Mockito .when (serviceOfferingDao .findById (12L )).thenReturn (existingOffering );
185+ Mockito .doNothing ().when (scaleWorker ).init ();
186+ Mockito .doReturn (12L ).when (scaleWorker ).getExistingOfferingIdForNodeType (WORKER , kubernetesCluster );
187+ Mockito .doReturn (true ).when (scaleWorker ).autoscaleCluster (requestedEnabled , 2L , 5L );
188+ Mockito .doReturn (true ).when (scaleWorker ).stateTransitTo (Mockito .anyLong (), Mockito .any ());
189+
190+ Assert .assertTrue (scaleWorker .scaleCluster ());
191+
192+ Mockito .verify (scaleWorker ).autoscaleCluster (requestedEnabled , 2L , 5L );
193+ Mockito .verifyNoInteractions (userVmManager );
194+ }
195+
70196 @ Test
71197 public void testCalculateNewClusterCountAndCapacityAllNodesScaleSize () {
72198 long controlNodes = 3L ;
0 commit comments