Skip to content

Commit

Permalink
Changed autoscaler label content to contain operation id and added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
MNoeva authored and boyan-velinov committed Oct 25, 2024
1 parent 0047f78 commit 5c6f428
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,7 @@ public class Messages {
public static final String SERVICE_TYPE = "{0}/{1}";
public static final String PARSE_NULL_STRING_ERROR = "Cannot parse null string";
public static final String INVALID_BOOLEAN_VALUE = "Invalid boolean value: must be 'true' or 'false'";
public static final String DISABLE_AUTOSCALER_LABEL_CONTENT = "Disabled_by_MTA_operation_{0}";

protected Messages() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ private void addMetadataAutoscalerLabel() {
boolean shouldApplyIncrementalInstancesUpdate = context.getVariable(Variables.SHOULD_APPLY_INCREMENTAL_INSTANCES_UPDATE);
if (shouldApplyIncrementalInstancesUpdate) {
UUID applicationId = client.getApplicationGuid(app.getName());
disableAutoscaling(client, applicationId);
disableAutoscaling(context, client, applicationId);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ protected StepPhase executeAsyncStep(ProcessContext context) throws Exception {
return scaleUpNewAppToTheRequiredInstances(context, application, client);
}
UUID oldApplicationGuid = client.getApplicationGuid(oldApplication.getName());
disableAutoscaling(client, oldApplicationGuid);
disableAutoscaling(context, client, oldApplicationGuid);

UUID applicationId = client.getApplicationGuid(application.getName());
checkWhetherLiveAppNeedsPolling(context, client, oldApplication);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,11 @@ public static void setAsJsonBinary(VariableScope scope, String name, Object valu
scope.setVariable(name, jsonBinary);
}

public static void disableAutoscaling(CloudControllerClient client, UUID uuid) {
public static void disableAutoscaling(ProcessContext context, CloudControllerClient client, UUID uuid) {
String correlationId = context.getVariable(Variables.CORRELATION_ID);
Metadata metadata = Metadata.builder()
.label(MtaMetadataLabels.AUTOSCALER_LABEL, String.valueOf(true))
.label(MtaMetadataLabels.AUTOSCALER_LABEL,
MessageFormat.format(Messages.DISABLE_AUTOSCALER_LABEL_CONTENT, correlationId))
.build();
client.updateApplicationMetadata(uuid, metadata);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package org.cloudfoundry.multiapps.controller.process.steps;

import static org.cloudfoundry.multiapps.controller.process.steps.StepsTestUtil.prepareDisablingAutoscaler;
import static org.cloudfoundry.multiapps.controller.process.steps.StepsTestUtil.testIfEnabledOrDisabledAutoscaler;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.text.MessageFormat;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Stream;

import org.cloudfoundry.multiapps.common.SLException;
Expand Down Expand Up @@ -45,26 +49,37 @@ class CreateOrUpdateAppStepTest extends SyncFlowableStepTest<CreateOrUpdateAppSt
private static final String SERVICE_KEY_ENV_NAME = "test-service-key-env";
private static final Staging DEFAULT_STAGING = ImmutableStaging.builder()
.build();
private static final UUID APP_TO_PROCESS_GUID = UUID.randomUUID();

static Stream<Arguments> testHandleApplicationAttributes() {
return Stream.of(
//@formatter:off
// (1) Everything is specified properly:
// (1) Everything is specified properly and should apply incremental instances update:
Arguments.of(ImmutableStaging.builder().command("command1").healthCheckType("none").addBuildpack("buildpackUrl").build(),
128, 256, TestData.routeSet("example.com", "foo-bar.xyz"), Map.of("env-key", "env-value")),
// (2) Disk quota is 0:
Arguments.of(DEFAULT_STAGING, 0, 256, Collections.emptySet(), Collections.emptyMap()),
// (3) Memory is 0:
Arguments.of(DEFAULT_STAGING, 1024, 0, Collections.emptySet(), Collections.emptyMap())
128, 256, TestData.routeSet("example.com", "foo-bar.xyz"), Map.of("env-key", "env-value"), true),
// (2) Disk quota is 0 and should apply incremental instances update:
Arguments.of(DEFAULT_STAGING, 0, 256, Collections.emptySet(), Collections.emptyMap(), true),
// (3) Memory is 0 and should apply incremental instances update:
Arguments.of(DEFAULT_STAGING, 1024, 0, Collections.emptySet(), Collections.emptyMap(), true),
// (4) Everything is specified properly and should not apply incremental instances update:
Arguments.of(ImmutableStaging.builder().command("command1").healthCheckType("none").addBuildpack("buildpackUrl").build(),
128, 256, TestData.routeSet("example.com", "foo-bar.xyz"), Map.of("env-key", "env-value"), false),
// (5) Disk quota is 0 and should not apply incremental instances update:
Arguments.of(DEFAULT_STAGING, 0, 256, Collections.emptySet(), Collections.emptyMap(), false),
// (6) Memory is 0 and should not apply incremental instances update:
Arguments.of(DEFAULT_STAGING, 1024, 0, Collections.emptySet(), Collections.emptyMap(), false)
//@formatter:on
);
}

@ParameterizedTest
@MethodSource
void testHandleApplicationAttributes(Staging staging, int diskQuota, int memory, Set<CloudRoute> routes, Map<String, String> env) {
void testHandleApplicationAttributes(Staging staging, int diskQuota, int memory, Set<CloudRoute> routes, Map<String, String> env,
boolean shouldApplyIncrementalInstancesUpdate) {
CloudApplicationExtended application = buildApplication(staging, diskQuota, memory, routes, env);
context.setVariable(Variables.APP_TO_PROCESS, application);
context.setVariable(Variables.SHOULD_APPLY_INCREMENTAL_INSTANCES_UPDATE, shouldApplyIncrementalInstancesUpdate);
prepareDisablingAutoscaler(context, client, application, APP_TO_PROCESS_GUID);

step.execute(execution);

Expand All @@ -80,6 +95,12 @@ void testHandleApplicationAttributes(Staging staging, int diskQuota, int memory,
.env(env)
.build();
verify(client).createApplication(applicationToCreateDto);

if (shouldApplyIncrementalInstancesUpdate) {
testIfEnabledOrDisabledAutoscaler(client, MessageFormat.format(Messages.DISABLE_AUTOSCALER_LABEL_CONTENT, ""),
APP_TO_PROCESS_GUID);
}

assertTrue(context.getVariable(Variables.VCAP_APP_PROPERTIES_CHANGED));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package org.cloudfoundry.multiapps.controller.process.steps;

import static org.cloudfoundry.multiapps.controller.process.steps.StepsTestUtil.prepareDisablingAutoscaler;
import static org.cloudfoundry.multiapps.controller.process.steps.StepsTestUtil.testIfEnabledOrDisabledAutoscaler;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.text.MessageFormat;
import java.time.Duration;
import java.util.List;
import java.util.UUID;
Expand All @@ -20,6 +23,7 @@
import org.cloudfoundry.multiapps.controller.core.model.IncrementalAppInstanceUpdateConfiguration;
import org.cloudfoundry.multiapps.controller.core.model.SupportedParameters;
import org.cloudfoundry.multiapps.controller.core.security.token.TokenService;
import org.cloudfoundry.multiapps.controller.process.Messages;
import org.cloudfoundry.multiapps.controller.process.variables.Variables;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -68,6 +72,7 @@ private void prepareAppToProcess(int instancesCount) {
InstancesInfo instancesInfo = buildInstancesInfo(InstanceState.RUNNING);
when(client.getApplicationInstances(APP_TO_PROCESS_GUID)).thenReturn(instancesInfo);
context.setVariable(Variables.APP_TO_PROCESS, cloudApplication);
when(client.getApplicationGuid(cloudApplication.getName())).thenReturn(APP_TO_PROCESS_GUID);
}

private CloudApplicationExtended buildAppToProcessApplication(int instancesCount) {
Expand All @@ -92,6 +97,7 @@ void executeStepWithRunningOldApplication() {
assertEquals(1, incrementalAppInstanceUpdateConfiguration.getOldApplicationInstanceCount());
assertEquals(1, incrementalAppInstanceUpdateConfiguration.getOldApplicationInitialInstanceCount());
assertExecutionStepStatus(StepPhase.POLL.toString());
testIfEnabledOrDisabledAutoscaler(client, MessageFormat.format(Messages.DISABLE_AUTOSCALER_LABEL_CONTENT, ""), APP_TO_PROCESS_GUID);
}

private void prepareRunningOldApplication() {
Expand All @@ -100,6 +106,7 @@ private void prepareRunningOldApplication() {
InstancesInfo instancesInfo = buildInstancesInfo(InstanceState.RUNNING);
context.setVariable(Variables.DEPLOYED_MTA, deployedMta);
when(client.getApplicationInstances(deployedMtaApplication)).thenReturn(instancesInfo);
prepareDisablingAutoscaler(context, client, deployedMtaApplication, APP_TO_PROCESS_GUID);
}

private InstancesInfo buildInstancesInfo(InstanceState state) {
Expand Down Expand Up @@ -132,6 +139,7 @@ void executeStepWithFailingOldApplication() {
assertEquals(1, incrementalAppInstanceUpdateConfiguration.getOldApplicationInstanceCount());
assertEquals(1, incrementalAppInstanceUpdateConfiguration.getOldApplicationInitialInstanceCount());
assertExecutionStepStatus(StepPhase.POLL.toString());
testIfEnabledOrDisabledAutoscaler(client, MessageFormat.format(Messages.DISABLE_AUTOSCALER_LABEL_CONTENT, ""), APP_TO_PROCESS_GUID);
}

private void prepareFailingOldApplication() {
Expand All @@ -140,6 +148,7 @@ private void prepareFailingOldApplication() {
InstancesInfo instancesInfo = buildInstancesInfo(InstanceState.CRASHED);
context.setVariable(Variables.DEPLOYED_MTA, deployedMta);
when(client.getApplicationInstances(deployedMtaApplication)).thenReturn(instancesInfo);
prepareDisablingAutoscaler(context, client, deployedMtaApplication, APP_TO_PROCESS_GUID);
}

@Test
Expand All @@ -153,6 +162,8 @@ void executeStepWithAlreadyScaledApplication() {
assertEquals(1, incrementalAppInstanceUpdateConfiguration.getOldApplicationInstanceCount());
assertEquals(1, incrementalAppInstanceUpdateConfiguration.getOldApplicationInitialInstanceCount());
assertExecutionStepStatus(StepPhase.DONE.toString());
testIfEnabledOrDisabledAutoscaler(client, MessageFormat.format(Messages.DISABLE_AUTOSCALER_LABEL_CONTENT, ""), APP_TO_PROCESS_GUID);
testIfEnabledOrDisabledAutoscaler(client, null, APP_TO_PROCESS_GUID);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.cloudfoundry.multiapps.controller.process.steps;

import static org.cloudfoundry.multiapps.controller.process.steps.StepsTestUtil.testIfEnabledOrDisabledAutoscaler;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
Expand Down Expand Up @@ -40,12 +41,14 @@ void executeStepWhenTheApplicationIsAlreadyScaled() {
prepareIncrementalAppInstanceUpdateConfiguration(3, 3);
expectedAsyncExecutionState = AsyncExecutionState.FINISHED;
testExecuteOperations();
testIfEnabledOrDisabledAutoscaler(client, null, APP_TO_PROCESS_GUID);
}

private void prepareAppToProcess(int instances, CloudApplication.State state) {
CloudApplicationExtended cloudApplicationExtended = buildCloudApplicationToProcess(instances, state);
context.setVariable(Variables.APP_TO_PROCESS, cloudApplicationExtended);
when(client.getApplication(cloudApplicationExtended.getName())).thenReturn(cloudApplicationExtended);
when(client.getApplicationGuid(cloudApplicationExtended.getName())).thenReturn(APP_TO_PROCESS_GUID);
}

private CloudApplicationExtended buildCloudApplicationToProcess(int instances, CloudApplication.State state) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.cloudfoundry.multiapps.controller.process.steps;

import static org.cloudfoundry.multiapps.controller.process.steps.StepsTestUtil.testIfEnabledOrDisabledAutoscaler;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
Expand Down Expand Up @@ -73,6 +74,7 @@ private void prepareAppToProcess(CloudApplicationExtended cloudApplicationExtend
when(client.getApplicationInstances(any(CloudApplication.class))).thenReturn(instancesInfo);
context.setVariable(Variables.EXISTING_APP_TO_POLL, cloudApplicationExtended);
context.setVariable(Variables.APP_TO_PROCESS, cloudApplicationExtended);
when(client.getApplicationGuid(LIVE_APP_NAME)).thenReturn(LIVE_APP_GUID);
}

private IncrementalAppInstanceUpdateConfiguration buildConfigWithoutOldApp(CloudApplicationExtended cloudApplicationExtended) {
Expand All @@ -98,6 +100,7 @@ void testRollbackWhenOldApplicationWasDownscaled() {
testExecuteOperations();
verify(client).updateApplicationInstances(APP_TO_PROCESS_NAME, 1);
verify(client).updateApplicationInstances(LIVE_APP_NAME, 10);
testIfEnabledOrDisabledAutoscaler(client, null, LIVE_APP_GUID);
}

private DeployedMtaApplication buildDeployedMtaApplication() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,42 @@
package org.cloudfoundry.multiapps.controller.process.steps;

import java.util.List;
import java.util.UUID;

import com.sap.cloudfoundry.client.facade.CloudControllerClient;
import com.sap.cloudfoundry.client.facade.domain.CloudApplication;
import org.cloudfoundry.client.v3.Metadata;
import org.cloudfoundry.multiapps.common.util.JsonUtil;
import org.cloudfoundry.multiapps.controller.client.lib.domain.CloudApplicationExtended;
import org.cloudfoundry.multiapps.controller.core.cf.metadata.MtaMetadataLabels;
import org.cloudfoundry.multiapps.controller.process.variables.Variables;
import org.flowable.engine.delegate.DelegateExecution;
import org.mockito.Mockito;

import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class StepsTestUtil {

public static void mockApplicationsToDeploy(List<CloudApplicationExtended> applications, DelegateExecution execution) {
if (applications == null || applications.isEmpty()) {
return;
}
var stubbing = Mockito.when(execution.getVariable(Variables.APP_TO_PROCESS.getName()));
var stubbing = when(execution.getVariable(Variables.APP_TO_PROCESS.getName()));
for (var app : applications) {
stubbing = stubbing.thenReturn(JsonUtil.toJson(app));
}
}

public static void prepareDisablingAutoscaler(ProcessContext context, CloudControllerClient client, CloudApplication application,
UUID uid) {
context.setVariable(Variables.CORRELATION_ID, "");
when(client.getApplicationGuid(application.getName())).thenReturn(uid);
}

public static void testIfEnabledOrDisabledAutoscaler(CloudControllerClient client, String labelValue, UUID uid) {
Metadata metadata = Metadata.builder()
.label(MtaMetadataLabels.AUTOSCALER_LABEL, labelValue)
.build();
verify(client).updateApplicationMetadata(uid, metadata);
}
}

0 comments on commit 5c6f428

Please sign in to comment.