Involve all targets in dynamic rollouts (#1795)
* involve targets into dynamic rollouts eagerly - doesn't wait for dynamic group to become running in order to involve devices * adds trottling for involving targes into dynamic groups * small style refactoring Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com
This commit is contained in:
@@ -72,4 +72,10 @@ public class RepositoryProperties {
|
|||||||
|
|
||||||
private List<String> skipImplicitLockForTags =
|
private List<String> skipImplicitLockForTags =
|
||||||
List.of("skip-implicit-lock", "skip_implicit_lock", "SKIP_IMPLICIT_LOCK", "SKIP-IMPLICIT-LOCK");
|
List.of("skip-implicit-lock", "skip_implicit_lock", "SKIP_IMPLICIT_LOCK", "SKIP-IMPLICIT-LOCK");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimum period (in milli-seconds) on which dynamic rollouts should make attempt to involve
|
||||||
|
* new targets
|
||||||
|
*/
|
||||||
|
private long dynamicRolloutsMinInvolvePeriodMS = 60_000;
|
||||||
}
|
}
|
||||||
@@ -13,9 +13,11 @@ import java.lang.reflect.InvocationTargetException;
|
|||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
@@ -24,6 +26,7 @@ import jakarta.persistence.EntityManager;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||||
import org.eclipse.hawkbit.repository.QuotaManagement;
|
import org.eclipse.hawkbit.repository.QuotaManagement;
|
||||||
|
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
||||||
import org.eclipse.hawkbit.repository.RolloutApprovalStrategy;
|
import org.eclipse.hawkbit.repository.RolloutApprovalStrategy;
|
||||||
import org.eclipse.hawkbit.repository.RolloutExecutor;
|
import org.eclipse.hawkbit.repository.RolloutExecutor;
|
||||||
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
|
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
|
||||||
@@ -99,51 +102,55 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
private static final List<Status> DOWNLOAD_ONLY_ACTION_TERMINATION_STATUSES = Arrays.asList(Status.ERROR,
|
private static final List<Status> DOWNLOAD_ONLY_ACTION_TERMINATION_STATUSES = Arrays.asList(Status.ERROR,
|
||||||
Status.FINISHED, Status.CANCELED, Status.DOWNLOADED);
|
Status.FINISHED, Status.CANCELED, Status.DOWNLOADED);
|
||||||
|
|
||||||
private final RolloutTargetGroupRepository rolloutTargetGroupRepository;
|
|
||||||
private final EntityManager entityManager;
|
|
||||||
private final RolloutRepository rolloutRepository;
|
|
||||||
private final ActionRepository actionRepository;
|
private final ActionRepository actionRepository;
|
||||||
private final RolloutGroupRepository rolloutGroupRepository;
|
private final RolloutGroupRepository rolloutGroupRepository;
|
||||||
private final AfterTransactionCommitExecutor afterCommit;
|
private final RolloutTargetGroupRepository rolloutTargetGroupRepository;
|
||||||
private final TenantAware tenantAware;
|
private final RolloutRepository rolloutRepository;
|
||||||
private final RolloutGroupManagement rolloutGroupManagement;
|
|
||||||
private final QuotaManagement quotaManagement;
|
|
||||||
private final DeploymentManagement deploymentManagement;
|
|
||||||
private final TargetManagement targetManagement;
|
private final TargetManagement targetManagement;
|
||||||
private final EventPublisherHolder eventPublisherHolder;
|
private final DeploymentManagement deploymentManagement;
|
||||||
private final PlatformTransactionManager txManager;
|
private final RolloutGroupManagement rolloutGroupManagement;
|
||||||
private final RolloutApprovalStrategy rolloutApprovalStrategy;
|
|
||||||
private final RolloutGroupEvaluationManager evaluationManager;
|
|
||||||
private final RolloutManagement rolloutManagement;
|
private final RolloutManagement rolloutManagement;
|
||||||
|
private final QuotaManagement quotaManagement;
|
||||||
/**
|
|
||||||
* Constructor
|
private final RolloutGroupEvaluationManager evaluationManager;
|
||||||
*/
|
private final RolloutApprovalStrategy rolloutApprovalStrategy;
|
||||||
public JpaRolloutExecutor(final RolloutTargetGroupRepository rolloutTargetGroupRepository,
|
|
||||||
final EntityManager entityManager, final RolloutRepository rolloutRepository,
|
private final EntityManager entityManager;
|
||||||
|
private final PlatformTransactionManager txManager;
|
||||||
|
private final AfterTransactionCommitExecutor afterCommit;
|
||||||
|
private final EventPublisherHolder eventPublisherHolder;
|
||||||
|
|
||||||
|
private final TenantAware tenantAware;
|
||||||
|
private final RepositoryProperties repositoryProperties;
|
||||||
|
|
||||||
|
public JpaRolloutExecutor(
|
||||||
final ActionRepository actionRepository, final RolloutGroupRepository rolloutGroupRepository,
|
final ActionRepository actionRepository, final RolloutGroupRepository rolloutGroupRepository,
|
||||||
final AfterTransactionCommitExecutor afterCommit, final TenantAware tenantAware,
|
final RolloutTargetGroupRepository rolloutTargetGroupRepository,
|
||||||
final RolloutGroupManagement rolloutGroupManagement, final QuotaManagement quotaManagement,
|
final RolloutRepository rolloutRepository, final TargetManagement targetManagement,
|
||||||
final DeploymentManagement deploymentManagement, final TargetManagement targetManagement,
|
final DeploymentManagement deploymentManagement, final RolloutGroupManagement rolloutGroupManagement,
|
||||||
final EventPublisherHolder eventPublisherHolder, final PlatformTransactionManager txManager,
|
final RolloutManagement rolloutManagement, final QuotaManagement quotaManagement,
|
||||||
final RolloutApprovalStrategy rolloutApprovalStrategy,
|
final RolloutGroupEvaluationManager evaluationManager, final RolloutApprovalStrategy rolloutApprovalStrategy,
|
||||||
final RolloutGroupEvaluationManager evaluationManager, final RolloutManagement rolloutManagement) {
|
final EntityManager entityManager, final PlatformTransactionManager txManager,
|
||||||
this.rolloutTargetGroupRepository = rolloutTargetGroupRepository;
|
final AfterTransactionCommitExecutor afterCommit, final EventPublisherHolder eventPublisherHolder,
|
||||||
this.entityManager = entityManager;
|
final TenantAware tenantAware, final RepositoryProperties repositoryProperties) {
|
||||||
this.rolloutRepository = rolloutRepository;
|
|
||||||
this.actionRepository = actionRepository;
|
this.actionRepository = actionRepository;
|
||||||
this.rolloutGroupRepository = rolloutGroupRepository;
|
this.rolloutGroupRepository = rolloutGroupRepository;
|
||||||
this.afterCommit = afterCommit;
|
this.rolloutTargetGroupRepository = rolloutTargetGroupRepository;
|
||||||
this.tenantAware = tenantAware;
|
this.rolloutRepository = rolloutRepository;
|
||||||
this.rolloutGroupManagement = rolloutGroupManagement;
|
|
||||||
this.quotaManagement = quotaManagement;
|
|
||||||
this.deploymentManagement = deploymentManagement;
|
|
||||||
this.targetManagement = targetManagement;
|
this.targetManagement = targetManagement;
|
||||||
this.eventPublisherHolder = eventPublisherHolder;
|
this.deploymentManagement = deploymentManagement;
|
||||||
this.txManager = txManager;
|
this.rolloutGroupManagement = rolloutGroupManagement;
|
||||||
this.rolloutApprovalStrategy = rolloutApprovalStrategy;
|
|
||||||
this.evaluationManager = evaluationManager;
|
|
||||||
this.rolloutManagement = rolloutManagement;
|
this.rolloutManagement = rolloutManagement;
|
||||||
|
this.quotaManagement = quotaManagement;
|
||||||
|
this.evaluationManager = evaluationManager;
|
||||||
|
this.rolloutApprovalStrategy = rolloutApprovalStrategy;
|
||||||
|
this.entityManager = entityManager;
|
||||||
|
this.txManager = txManager;
|
||||||
|
this.afterCommit = afterCommit;
|
||||||
|
this.eventPublisherHolder = eventPublisherHolder;
|
||||||
|
this.tenantAware = tenantAware;
|
||||||
|
this.repositoryProperties = repositoryProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -427,7 +434,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
|
|
||||||
// fakes getTotalTargets count to match expected for the last dynamic group
|
// fakes getTotalTargets count to match expected for the last dynamic group
|
||||||
// so the evaluation to use total targets to properly
|
// so the evaluation to use total targets to properly
|
||||||
private RolloutGroup evalProxy(final RolloutGroup group, final List<JpaRolloutGroup> rolloutGroups) {
|
private RolloutGroup evalProxy(final RolloutGroup group) {
|
||||||
if (group.isDynamic()) {
|
if (group.isDynamic()) {
|
||||||
final int expected = Math.max((int)group.getTargetPercentage(), 1);
|
final int expected = Math.max((int)group.getTargetPercentage(), 1);
|
||||||
return (RolloutGroup) Proxy.newProxyInstance(
|
return (RolloutGroup) Proxy.newProxyInstance(
|
||||||
@@ -457,7 +464,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final RolloutGroup evalProxy = rolloutGroup == rolloutGroups.get(rolloutGroups.size() - 1) ?
|
final RolloutGroup evalProxy = rolloutGroup == rolloutGroups.get(rolloutGroups.size() - 1) ?
|
||||||
evalProxy(rolloutGroup, rolloutGroups) : rolloutGroup;
|
evalProxy(rolloutGroup) : rolloutGroup;
|
||||||
// error state check, do we need to stop the whole
|
// error state check, do we need to stop the whole
|
||||||
// rollout because of error?
|
// rollout because of error?
|
||||||
final boolean isError = checkErrorState(rollout, evalProxy);
|
final boolean isError = checkErrorState(rollout, evalProxy);
|
||||||
@@ -529,7 +536,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkSuccessCondition(final Rollout rollout, final RolloutGroup rolloutGroup, final RolloutGroup evalProxy,
|
private void checkSuccessCondition(final Rollout rollout, final RolloutGroup rolloutGroup, final RolloutGroup evalProxy,
|
||||||
final RolloutGroupSuccessCondition successCondition) {
|
final RolloutGroupSuccessCondition successCondition) {
|
||||||
log.trace("Checking finish condition {} on rolloutgroup {}", successCondition, rolloutGroup);
|
log.trace("Checking finish condition {} on rolloutgroup {}", successCondition, rolloutGroup);
|
||||||
try {
|
try {
|
||||||
@@ -541,11 +548,9 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
} else {
|
} else {
|
||||||
log.debug("Rolloutgroup {} is still running", rolloutGroup);
|
log.debug("Rolloutgroup {} is still running", rolloutGroup);
|
||||||
}
|
}
|
||||||
return isFinished;
|
|
||||||
} catch (final EvaluatorNotConfiguredException e) {
|
} catch (final EvaluatorNotConfiguredException e) {
|
||||||
log.error("Something bad happened when accessing the finish condition or success action bean {}",
|
log.error("Something bad happened when accessing the finish condition or success action bean {}",
|
||||||
successCondition.name(), e);
|
successCondition.name(), e);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,32 +680,32 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final Map<Long, AtomicLong> lastDynamicGroupFill = new ConcurrentHashMap<>();
|
||||||
// return if group change is made
|
// return if group change is made
|
||||||
private boolean fillDynamicRolloutGroupsWithTargets(final JpaRollout rollout) {
|
private boolean fillDynamicRolloutGroupsWithTargets(final JpaRollout rollout) {
|
||||||
|
final AtomicLong lastFill = lastDynamicGroupFill.computeIfAbsent(rollout.getId(), id -> new AtomicLong(0));
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
if (now - lastFill.get() < repositoryProperties.getDynamicRolloutsMinInvolvePeriodMS()) {
|
||||||
|
// too early to make another dynamic involvement attempt
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
lastFill.set(now);
|
||||||
|
}
|
||||||
|
|
||||||
RolloutHelper.verifyRolloutInStatus(rollout, RolloutStatus.RUNNING);
|
RolloutHelper.verifyRolloutInStatus(rollout, RolloutStatus.RUNNING);
|
||||||
final List<RolloutGroup> rolloutGroups = rollout.getRolloutGroups();
|
final List<RolloutGroup> rolloutGroups = rollout.getRolloutGroups();
|
||||||
|
|
||||||
final JpaRolloutGroup group = (JpaRolloutGroup)rolloutGroups.get(rolloutGroups.size() - 1);
|
final JpaRolloutGroup group = (JpaRolloutGroup)rolloutGroups.get(rolloutGroups.size() - 1);
|
||||||
|
|
||||||
if (group.getStatus() == RolloutGroupStatus.FINISHED) {
|
|
||||||
createDynamicGroup(rollout, group, rolloutGroups.size(), RolloutGroupStatus.RUNNING);
|
|
||||||
return true;
|
|
||||||
} else if (group.getStatus() != RolloutGroupStatus.RUNNING) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// expected as last full group
|
|
||||||
final long expectedInGroup = Math.max((int)group.getTargetPercentage(), 1);
|
final long expectedInGroup = Math.max((int)group.getTargetPercentage(), 1);
|
||||||
|
|
||||||
final long currentlyInGroup = group.getTotalTargets();
|
final long currentlyInGroup = group.getTotalTargets();
|
||||||
if (currentlyInGroup >= expectedInGroup) {
|
if (currentlyInGroup >= expectedInGroup || group.getStatus() == RolloutGroupStatus.FINISHED) {
|
||||||
// the last one is filled. create new and start filling it
|
// the last one is full. create new and start filling it on the next iteration
|
||||||
createDynamicGroup(rollout, group, rolloutGroups.size(), RolloutGroupStatus.SCHEDULED);
|
createDynamicGroup(rollout, group, rolloutGroups.size(), RolloutGroupStatus.SCHEDULED);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// there are more to be filled for that group
|
// there are more to be filled for the last group do this until there are more matching
|
||||||
// do this until there are more matching
|
|
||||||
try {
|
try {
|
||||||
long targetsLeftToAdd = expectedInGroup - currentlyInGroup;
|
long targetsLeftToAdd = expectedInGroup - currentlyInGroup;
|
||||||
final String groupTargetFilter = RolloutHelper.getGroupTargetFilter(
|
final String groupTargetFilter = RolloutHelper.getGroupTargetFilter(
|
||||||
@@ -725,12 +730,6 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
if (newActions > 0) {
|
if (newActions > 0) {
|
||||||
updateTotalTargetCount(group, group.getTotalTargets() + newActions);
|
updateTotalTargetCount(group, group.getTotalTargets() + newActions);
|
||||||
|
|
||||||
if (targetsLeftToAdd == 0) {
|
|
||||||
// this is filled create a new one in scheduled state
|
|
||||||
createDynamicGroup(rollout, group, rolloutGroups.size(), RolloutGroupStatus.SCHEDULED);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO - try to return false and proceed with handleRunningRollout
|
// TODO - try to return false and proceed with handleRunningRollout
|
||||||
// the problem is that OptimisticLockException is thrown in that case
|
// the problem is that OptimisticLockException is thrown in that case
|
||||||
return true;
|
return true;
|
||||||
@@ -800,7 +799,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
final ActionType actionType = rollout.getActionType();
|
final ActionType actionType = rollout.getActionType();
|
||||||
final long forceTime = rollout.getForcedTime();
|
final long forceTime = rollout.getForcedTime();
|
||||||
final List<Action> newActions = createActions(targets.getContent(), distributionSet, actionType, forceTime, rollout, group);
|
final List<Action> newActions = createActions(targets.getContent(), distributionSet, actionType, forceTime, rollout, group);
|
||||||
if (!newActions.isEmpty()) {
|
if (!newActions.isEmpty() && group.getStatus() == RolloutGroupStatus.RUNNING) {
|
||||||
deploymentManagement.startScheduledActions(newActions);
|
deploymentManagement.startScheduledActions(newActions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -906,17 +905,14 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enforces the quota defining the maximum number of {@link Action}s per
|
* Enforces the quota defining the maximum number of {@link Action}s per {@link Target}.
|
||||||
* {@link Target}.
|
|
||||||
*
|
*
|
||||||
* @param target
|
* @param target the target
|
||||||
* The target
|
* @param requested number of actions to check
|
||||||
* @param requested
|
|
||||||
* number of actions to check
|
|
||||||
*/
|
*/
|
||||||
private void assertActionsPerTargetQuota(final Target target, final int requested) {
|
private void assertActionsPerTargetQuota(final Target target, final int requested) {
|
||||||
final int quota = quotaManagement.getMaxActionsPerTarget();
|
final int quota = quotaManagement.getMaxActionsPerTarget();
|
||||||
QuotaHelper.assertAssignmentQuota(target.getId(), requested, quota, Action.class, Target.class,
|
QuotaHelper.assertAssignmentQuota(target.getId(), requested, quota, Action.class, Target.class,
|
||||||
actionRepository::countByTargetId);
|
actionRepository::countByTargetId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -739,19 +739,20 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
RolloutExecutor rolloutExecutor(final RolloutTargetGroupRepository rolloutTargetGroupRepository,
|
RolloutExecutor rolloutExecutor(
|
||||||
final EntityManager entityManager, final RolloutRepository rolloutRepository,
|
|
||||||
final ActionRepository actionRepository, final RolloutGroupRepository rolloutGroupRepository,
|
final ActionRepository actionRepository, final RolloutGroupRepository rolloutGroupRepository,
|
||||||
final AfterTransactionCommitExecutor afterCommit, final TenantAware tenantAware,
|
final RolloutTargetGroupRepository rolloutTargetGroupRepository,
|
||||||
final RolloutGroupManagement rolloutGroupManagement, final QuotaManagement quotaManagement,
|
final RolloutRepository rolloutRepository, final TargetManagement targetManagement,
|
||||||
final DeploymentManagement deploymentManagement, final TargetManagement targetManagement,
|
final DeploymentManagement deploymentManagement, final RolloutGroupManagement rolloutGroupManagement,
|
||||||
final EventPublisherHolder eventPublisherHolder, final PlatformTransactionManager txManager,
|
final RolloutManagement rolloutManagement, final QuotaManagement quotaManagement,
|
||||||
final RolloutApprovalStrategy rolloutApprovalStrategy,
|
final RolloutGroupEvaluationManager evaluationManager, final RolloutApprovalStrategy rolloutApprovalStrategy,
|
||||||
final RolloutGroupEvaluationManager evaluationManager, final RolloutManagement rolloutManagement) {
|
final EntityManager entityManager, final PlatformTransactionManager txManager,
|
||||||
return new JpaRolloutExecutor(rolloutTargetGroupRepository, entityManager, rolloutRepository, actionRepository,
|
final AfterTransactionCommitExecutor afterCommit, final EventPublisherHolder eventPublisherHolder,
|
||||||
rolloutGroupRepository, afterCommit, tenantAware, rolloutGroupManagement, quotaManagement,
|
final TenantAware tenantAware, final RepositoryProperties repositoryProperties) {
|
||||||
deploymentManagement, targetManagement, eventPublisherHolder, txManager, rolloutApprovalStrategy,
|
return new JpaRolloutExecutor(actionRepository, rolloutGroupRepository, rolloutTargetGroupRepository,
|
||||||
evaluationManager, rolloutManagement);
|
rolloutRepository, targetManagement, deploymentManagement, rolloutGroupManagement, rolloutManagement,
|
||||||
|
quotaManagement, evaluationManager, rolloutApprovalStrategy, entityManager, txManager, afterCommit,
|
||||||
|
eventPublisherHolder, tenantAware, repositoryProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|||||||
@@ -24,9 +24,11 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
|||||||
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus;
|
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.context.annotation.PropertySource;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.data.domain.Sort.Direction;
|
import org.springframework.data.domain.Sort.Direction;
|
||||||
|
import org.springframework.test.context.TestPropertySource;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
@@ -38,6 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
*/
|
*/
|
||||||
@Feature("Component Tests - Repository")
|
@Feature("Component Tests - Repository")
|
||||||
@Story("Rollout Management (Flow)")
|
@Story("Rollout Management (Flow)")
|
||||||
|
@TestPropertySource(properties = { "hawkbit.server.repository.dynamicRolloutsMinInvolvePeriodMS=-1" })
|
||||||
class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
|
class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
@@ -131,7 +134,8 @@ class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// fill first and create second
|
// fill first and create second
|
||||||
testdataFactory.createTargets(targetPrefix, amountGroups * 3 + 2, 2);
|
testdataFactory.createTargets(targetPrefix, amountGroups * 3 + 2, 2);
|
||||||
rolloutHandler.handleAll(); // fill first dynamic group and create a new dynamic2
|
rolloutHandler.handleAll(); // fill first dynamic group
|
||||||
|
rolloutHandler.handleAll(); // and create a new dynamic2
|
||||||
assertRollout(rollout, true, RolloutStatus.RUNNING, amountGroups + 2, amountGroups * 3 + 3);
|
assertRollout(rollout, true, RolloutStatus.RUNNING, amountGroups + 2, amountGroups * 3 + 3);
|
||||||
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 3);
|
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 3);
|
||||||
groups = rolloutGroupManagement.findByRollout(
|
groups = rolloutGroupManagement.findByRollout(
|
||||||
@@ -142,11 +146,11 @@ class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// create scheduled actions for the dynamic2
|
// create scheduled actions for the dynamic2
|
||||||
rolloutHandler.handleAll();
|
rolloutHandler.handleAll();
|
||||||
assertRollout(rollout, true, RolloutStatus.RUNNING, amountGroups + 2, amountGroups * 3 + 3);
|
assertRollout(rollout, true, RolloutStatus.RUNNING, amountGroups + 2, amountGroups * 3 + 4);
|
||||||
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 3);
|
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 3);
|
||||||
assertGroup(dynamic2, true, RolloutGroupStatus.SCHEDULED, 0);
|
assertGroup(dynamic2, true, RolloutGroupStatus.SCHEDULED, 1);
|
||||||
assertAndGetRunning(rollout, 4); // one from the last static group and 3 from the first dynamic
|
assertAndGetRunning(rollout, 4); // one from the last static group and 3 from the first dynamic
|
||||||
assertScheduled(rollout, 0);
|
assertScheduled(rollout, 1);
|
||||||
|
|
||||||
// executes last from static and dynamic1 without 1 target
|
// executes last from static and dynamic1 without 1 target
|
||||||
assertAndGetRunning(rollout, 4)// one from the last static and 6 for the first dynamic
|
assertAndGetRunning(rollout, 4)// one from the last static and 6 for the first dynamic
|
||||||
@@ -158,15 +162,12 @@ class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
|
|||||||
assertAndGetRunning(rollout, 1); // remains on in the first dynamic
|
assertAndGetRunning(rollout, 1); // remains on in the first dynamic
|
||||||
|
|
||||||
rolloutHandler.handleAll();
|
rolloutHandler.handleAll();
|
||||||
assertRollout(rollout, true, RolloutStatus.RUNNING, amountGroups + 2, amountGroups * 3 + 3);
|
assertRollout(rollout, true, RolloutStatus.RUNNING, amountGroups + 2, amountGroups * 3 + 4);
|
||||||
assertGroup(groups.get(amountGroups - 1), false, RolloutGroupStatus.FINISHED, 3);
|
assertGroup(groups.get(amountGroups - 1), false, RolloutGroupStatus.FINISHED, 3);
|
||||||
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 3);
|
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 3);
|
||||||
assertGroup(dynamic2, true, RolloutGroupStatus.RUNNING, 0);
|
// first dynamic threshold is reached, second is started
|
||||||
|
|
||||||
rolloutHandler.handleAll(); // add 1 action to now running second dynamic
|
|
||||||
assertRollout(rollout, true, RolloutStatus.RUNNING, amountGroups + 2, amountGroups * 3 + 4);
|
|
||||||
assertAndGetRunning(rollout, 2);
|
|
||||||
assertGroup(dynamic2, true, RolloutGroupStatus.RUNNING, 1);
|
assertGroup(dynamic2, true, RolloutGroupStatus.RUNNING, 1);
|
||||||
|
assertAndGetRunning(rollout, 2);
|
||||||
|
|
||||||
testdataFactory.createTargets(targetPrefix, amountGroups * 3 + 4, 1);
|
testdataFactory.createTargets(targetPrefix, amountGroups * 3 + 4, 1);
|
||||||
rolloutManagement.pauseRollout(rollout.getId());
|
rolloutManagement.pauseRollout(rollout.getId());
|
||||||
@@ -184,6 +185,7 @@ class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
|
|||||||
// finish the second dynamic group
|
// finish the second dynamic group
|
||||||
testdataFactory.createTargets(targetPrefix, amountGroups * 3 + 5, 1);
|
testdataFactory.createTargets(targetPrefix, amountGroups * 3 + 5, 1);
|
||||||
rolloutHandler.handleAll();
|
rolloutHandler.handleAll();
|
||||||
|
rolloutHandler.handleAll(); // create next
|
||||||
assertRollout(rollout, true, RolloutStatus.RUNNING, amountGroups + 3, amountGroups * 3 + 6);
|
assertRollout(rollout, true, RolloutStatus.RUNNING, amountGroups + 3, amountGroups * 3 + 6);
|
||||||
assertAndGetRunning(rollout, 4); // one from the dynamic1 and 3 from the dynamic2
|
assertAndGetRunning(rollout, 4); // one from the dynamic1 and 3 from the dynamic2
|
||||||
assertGroup(dynamic2, true, RolloutGroupStatus.RUNNING, 3); // assign the target created when paused
|
assertGroup(dynamic2, true, RolloutGroupStatus.RUNNING, 3); // assign the target created when paused
|
||||||
@@ -249,7 +251,8 @@ class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// fill first (2) and create fill partially the second (+2 new)
|
// fill first (2) and create fill partially the second (+2 new)
|
||||||
testdataFactory.createTargets(targetPrefix, amountGroups * 3 + 4, 4);
|
testdataFactory.createTargets(targetPrefix, amountGroups * 3 + 4, 4);
|
||||||
rolloutHandler.handleAll(); // fill first dynamic group and create a new dynamic2
|
rolloutHandler.handleAll(); // fill first dynamic group
|
||||||
|
rolloutHandler.handleAll(); // and create a new dynamic2
|
||||||
assertRollout(rollout, true, RolloutStatus.RUNNING, amountGroups + 2, amountGroups * 3 + 6);
|
assertRollout(rollout, true, RolloutStatus.RUNNING, amountGroups + 2, amountGroups * 3 + 6);
|
||||||
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 6);
|
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 6);
|
||||||
groups = rolloutGroupManagement.findByRollout(
|
groups = rolloutGroupManagement.findByRollout(
|
||||||
@@ -260,11 +263,11 @@ class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// create scheduled actions for the dynamic2
|
// create scheduled actions for the dynamic2
|
||||||
rolloutHandler.handleAll();
|
rolloutHandler.handleAll();
|
||||||
assertRollout(rollout, true, RolloutStatus.RUNNING, amountGroups + 2, amountGroups * 3 + 6);
|
assertRollout(rollout, true, RolloutStatus.RUNNING, amountGroups + 2, amountGroups * 3 + 8);
|
||||||
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 6);
|
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 6);
|
||||||
assertGroup(dynamic2, true, RolloutGroupStatus.SCHEDULED, 0);
|
assertGroup(dynamic2, true, RolloutGroupStatus.SCHEDULED, 2);
|
||||||
assertAndGetRunning(rollout, 7); // one from the last static group and 6 from the first dynamic
|
assertAndGetRunning(rollout, 7); // one from the last static group and 6 from the first dynamic
|
||||||
assertScheduled(rollout, 0);
|
assertScheduled(rollout, 2);
|
||||||
|
|
||||||
// executes last from static and dynamic1 without 1 target
|
// executes last from static and dynamic1 without 1 target
|
||||||
assertAndGetRunning(rollout, 7)// one from the last static and 6 for the first dynamic
|
assertAndGetRunning(rollout, 7)// one from the last static and 6 for the first dynamic
|
||||||
@@ -276,15 +279,12 @@ class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
|
|||||||
assertAndGetRunning(rollout, 1); // remains on in the first dynamic
|
assertAndGetRunning(rollout, 1); // remains on in the first dynamic
|
||||||
|
|
||||||
rolloutHandler.handleAll();
|
rolloutHandler.handleAll();
|
||||||
assertRollout(rollout, true, RolloutStatus.RUNNING, amountGroups + 2, amountGroups * 3 + 6);
|
assertRollout(rollout, true, RolloutStatus.RUNNING, amountGroups + 2, amountGroups * 3 + 8);
|
||||||
assertGroup(groups.get(amountGroups - 1), false, RolloutGroupStatus.FINISHED, 3);
|
assertGroup(groups.get(amountGroups - 1), false, RolloutGroupStatus.FINISHED, 3);
|
||||||
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 6);
|
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 6);
|
||||||
assertGroup(dynamic2, true, RolloutGroupStatus.RUNNING, 0);
|
// first dynamic threshold is reached, second is started
|
||||||
|
|
||||||
rolloutHandler.handleAll(); // add 2 action to now running second dynamic
|
|
||||||
assertRollout(rollout, true, RolloutStatus.RUNNING, amountGroups + 2, amountGroups * 3 + 8);
|
|
||||||
assertAndGetRunning(rollout, 3);
|
|
||||||
assertGroup(dynamic2, true, RolloutGroupStatus.RUNNING, 2);
|
assertGroup(dynamic2, true, RolloutGroupStatus.RUNNING, 2);
|
||||||
|
assertAndGetRunning(rollout, 3);
|
||||||
|
|
||||||
testdataFactory.createTargets(targetPrefix, amountGroups * 3 + 8, 2);
|
testdataFactory.createTargets(targetPrefix, amountGroups * 3 + 8, 2);
|
||||||
rolloutManagement.pauseRollout(rollout.getId());
|
rolloutManagement.pauseRollout(rollout.getId());
|
||||||
@@ -339,7 +339,8 @@ class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// fill first (2) and create fill partially the second (+2 new)
|
// fill first (2) and create fill partially the second (+2 new)
|
||||||
testdataFactory.createTargets(targetPrefix, 4, 4);
|
testdataFactory.createTargets(targetPrefix, 4, 4);
|
||||||
rolloutHandler.handleAll(); // fill first dynamic group and create a new dynamic2
|
rolloutHandler.handleAll(); // fill first dynamic group
|
||||||
|
rolloutHandler.handleAll(); // and create a new dynamic2
|
||||||
assertRollout(rollout, true, RolloutStatus.RUNNING, 2, 6);
|
assertRollout(rollout, true, RolloutStatus.RUNNING, 2, 6);
|
||||||
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 6);
|
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 6);
|
||||||
groups = rolloutGroupManagement.findByRollout(
|
groups = rolloutGroupManagement.findByRollout(
|
||||||
@@ -350,25 +351,22 @@ class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
// create scheduled actions for the dynamic2
|
// create scheduled actions for the dynamic2
|
||||||
rolloutHandler.handleAll();
|
rolloutHandler.handleAll();
|
||||||
assertRollout(rollout, true, RolloutStatus.RUNNING, 2, 6);
|
assertRollout(rollout, true, RolloutStatus.RUNNING, 2, 8);
|
||||||
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 6);
|
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 6);
|
||||||
assertGroup(dynamic2, true, RolloutGroupStatus.SCHEDULED, 0);
|
assertGroup(dynamic2, true, RolloutGroupStatus.SCHEDULED, 2);
|
||||||
assertAndGetRunning(rollout, 6); // 6 from the first dynamic
|
assertAndGetRunning(rollout, 6); // 6 from the first dynamic
|
||||||
assertScheduled(rollout, 0);
|
assertScheduled(rollout, 2);
|
||||||
|
|
||||||
// executes dynamic1 without 1 target
|
// executes dynamic1 without 1 target
|
||||||
executeWithoutOneTargetFromAGroup(dynamic1, rollout, 6);
|
executeWithoutOneTargetFromAGroup(dynamic1, rollout, 6);
|
||||||
assertAndGetRunning(rollout, 1); // remains on in the first dynamic
|
assertAndGetRunning(rollout, 1); // remains on in the first dynamic
|
||||||
|
|
||||||
rolloutHandler.handleAll();
|
rolloutHandler.handleAll();
|
||||||
assertRollout(rollout, true, RolloutStatus.RUNNING, 2, 6);
|
assertRollout(rollout, true, RolloutStatus.RUNNING, 2, 8);
|
||||||
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 6);
|
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 6);
|
||||||
assertGroup(dynamic2, true, RolloutGroupStatus.RUNNING, 0);
|
// first dynamic threshold is reached, second is started
|
||||||
|
|
||||||
rolloutHandler.handleAll(); // add 2 action to now running second dynamic
|
|
||||||
assertRollout(rollout, true, RolloutStatus.RUNNING, 2, 8);
|
|
||||||
assertAndGetRunning(rollout, 3);
|
|
||||||
assertGroup(dynamic2, true, RolloutGroupStatus.RUNNING, 2);
|
assertGroup(dynamic2, true, RolloutGroupStatus.RUNNING, 2);
|
||||||
|
assertAndGetRunning(rollout, 3);
|
||||||
|
|
||||||
testdataFactory.createTargets(targetPrefix, 8, 2);
|
testdataFactory.createTargets(targetPrefix, 8, 2);
|
||||||
rolloutManagement.pauseRollout(rollout.getId());
|
rolloutManagement.pauseRollout(rollout.getId());
|
||||||
@@ -387,6 +385,8 @@ class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
|
|||||||
private void executeStaticWithoutOneTargetFromTheLastGroupAndHandleAll(
|
private void executeStaticWithoutOneTargetFromTheLastGroupAndHandleAll(
|
||||||
final List<RolloutGroup> groups,
|
final List<RolloutGroup> groups,
|
||||||
final Rollout rollout, final int amountGroups) {
|
final Rollout rollout, final int amountGroups) {
|
||||||
|
// create dynamic group if needed
|
||||||
|
rolloutHandler.handleAll();
|
||||||
// execute groups (without on of the last)
|
// execute groups (without on of the last)
|
||||||
assertThat(refresh(groups.get(0)).getStatus()).isEqualTo(RolloutGroupStatus.RUNNING);
|
assertThat(refresh(groups.get(0)).getStatus()).isEqualTo(RolloutGroupStatus.RUNNING);
|
||||||
for (int i = 0; i < amountGroups; i++) {
|
for (int i = 0; i < amountGroups; i++) {
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCond
|
|||||||
import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder;
|
import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder;
|
||||||
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
|
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
|
||||||
import org.eclipse.hawkbit.repository.test.util.RolloutTestApprovalStrategy;
|
import org.eclipse.hawkbit.repository.test.util.RolloutTestApprovalStrategy;
|
||||||
import org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch;
|
import org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch;
|
||||||
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
||||||
@@ -70,6 +69,7 @@ import org.springframework.data.domain.PageRequest;
|
|||||||
import org.springframework.data.domain.Sort.Direction;
|
import org.springframework.data.domain.Sort.Direction;
|
||||||
import org.springframework.hateoas.MediaTypes;
|
import org.springframework.hateoas.MediaTypes;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.context.TestPropertySource;
|
||||||
import org.springframework.test.web.servlet.ResultMatcher;
|
import org.springframework.test.web.servlet.ResultMatcher;
|
||||||
|
|
||||||
import io.qameta.allure.Description;
|
import io.qameta.allure.Description;
|
||||||
@@ -82,6 +82,7 @@ import io.qameta.allure.Story;
|
|||||||
*/
|
*/
|
||||||
@Feature("Component Tests - Management API")
|
@Feature("Component Tests - Management API")
|
||||||
@Story("Rollout Resource")
|
@Story("Rollout Resource")
|
||||||
|
@TestPropertySource(locations = "classpath:/mgmt-test.properties", properties = { "hawkbit.server.repository.dynamicRolloutsMinInvolvePeriodMS=-1" })
|
||||||
class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||||
|
|
||||||
private static final String HREF_ROLLOUT_PREFIX = "http://localhost/rest/v1/rollouts/";
|
private static final String HREF_ROLLOUT_PREFIX = "http://localhost/rest/v1/rollouts/";
|
||||||
@@ -256,25 +257,29 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
|||||||
.andExpect(jsonPath("content[0].totalGroups", equalTo(2)));
|
.andExpect(jsonPath("content[0].totalGroups", equalTo(2)));
|
||||||
|
|
||||||
final int amountOfDynamicTargets = 2;
|
final int amountOfDynamicTargets = 2;
|
||||||
List<Target> additionalTargets = testdataFactory.createTargets(amountOfDynamicTargets, "rollout-dynamic-addition-", "rollout");
|
testdataFactory.createTargets(amountOfDynamicTargets, "rollout-dynamic-addition-", "rollout");
|
||||||
|
|
||||||
rolloutHandler.handleAll();
|
rolloutHandler.handleAll();
|
||||||
|
|
||||||
final List<RolloutGroup> groups = rolloutGroupManagement.findByRollout(PAGE, rollout.getId()).getContent();
|
final List<RolloutGroup> groups = rolloutGroupManagement.findByRollout(PAGE, rollout.getId()).getContent();
|
||||||
groups.forEach(group -> {
|
groups.forEach(group -> {
|
||||||
if (!group.getName().contains("-dynamic")) {
|
if (!group.isDynamic()) {
|
||||||
rolloutGroupManagement.findTargetsOfRolloutGroup(PAGE, group.getId()).forEach(target -> deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).forEach(action -> {
|
rolloutGroupManagement.findTargetsOfRolloutGroup(PAGE, group.getId())
|
||||||
|
.forEach(target -> deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE)
|
||||||
|
.forEach(action -> {
|
||||||
|
deploymentManagement.cancelAction(action.getId());
|
||||||
|
awaitActionStatus(action.getId(), Status.CANCELING);
|
||||||
|
|
||||||
deploymentManagement.cancelAction(action.getId());
|
deploymentManagement.forceQuitAction(action.getId());
|
||||||
awaitActionStatus(action.getId(), Status.CANCELING);
|
awaitActionStatus(action.getId(), Status.CANCELED);
|
||||||
|
}));
|
||||||
deploymentManagement.forceQuitAction(action.getId());
|
|
||||||
awaitActionStatus(action.getId(), Status.CANCELED);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
awaitPendingDeviceInRollout(additionalTargets.get(0).getControllerId());
|
// process as much as needed to start first dynamic
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
rolloutHandler.handleAll();
|
||||||
|
}
|
||||||
|
|
||||||
mvc.perform(get("/rest/v1/rollouts?representation=full").accept(MediaType.APPLICATION_JSON))
|
mvc.perform(get("/rest/v1/rollouts?representation=full").accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
@@ -285,16 +290,16 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
|||||||
.andExpect(jsonPath("content[0].status", equalTo("running")))
|
.andExpect(jsonPath("content[0].status", equalTo("running")))
|
||||||
.andExpect(jsonPath("content[0].targetFilterQuery", equalTo("name==rollout*")))
|
.andExpect(jsonPath("content[0].targetFilterQuery", equalTo("name==rollout*")))
|
||||||
.andExpect(jsonPath("content[0].distributionSetId", equalTo(dsA.getId().intValue())))
|
.andExpect(jsonPath("content[0].distributionSetId", equalTo(dsA.getId().intValue())))
|
||||||
.andExpect(jsonPath("content[0].totalTargets", equalTo(11)))
|
.andExpect(jsonPath("content[0].totalTargets", equalTo(amountTargets + amountOfDynamicTargets)))
|
||||||
.andExpect(jsonPath("content[0].totalTargetsPerStatus").exists())
|
.andExpect(jsonPath("content[0].totalTargetsPerStatus").exists())
|
||||||
.andExpect(jsonPath("content[0].totalTargetsPerStatus.running", equalTo(1)))
|
.andExpect(jsonPath("content[0].totalTargetsPerStatus.running", equalTo(1)))
|
||||||
.andExpect(jsonPath("content[0].totalTargetsPerStatus.notstarted", equalTo(0)))
|
.andExpect(jsonPath("content[0].totalTargetsPerStatus.notstarted", equalTo(0)))
|
||||||
.andExpect(jsonPath("content[0].totalTargetsPerStatus.scheduled", equalTo(0)))
|
.andExpect(jsonPath("content[0].totalTargetsPerStatus.scheduled", equalTo(1)))
|
||||||
.andExpect(jsonPath("content[0].totalTargetsPerStatus.cancelled", equalTo(10)))
|
.andExpect(jsonPath("content[0].totalTargetsPerStatus.cancelled", equalTo(10)))
|
||||||
.andExpect(jsonPath("content[0].totalTargetsPerStatus.finished", equalTo(0)))
|
.andExpect(jsonPath("content[0].totalTargetsPerStatus.finished", equalTo(0)))
|
||||||
.andExpect(jsonPath("content[0].totalTargetsPerStatus.error", equalTo(0)))
|
.andExpect(jsonPath("content[0].totalTargetsPerStatus.error", equalTo(0)))
|
||||||
.andExpect(jsonPath("content[0].deleted", equalTo(false)))
|
.andExpect(jsonPath("content[0].deleted", equalTo(false)))
|
||||||
.andExpect(jsonPath("content[0].totalGroups", equalTo(3)))
|
.andExpect(jsonPath("content[0].totalGroups", equalTo(4)))
|
||||||
.andExpect(jsonPath("content[0]._links.self.href", startsWith(HREF_ROLLOUT_PREFIX)));
|
.andExpect(jsonPath("content[0]._links.self.href", startsWith(HREF_ROLLOUT_PREFIX)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1323,22 +1328,6 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
|||||||
.getStatus().equals(status));
|
.getStatus().equals(status));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void awaitPendingDeviceInRollout(final String controllerId) {
|
|
||||||
Awaitility.await().atMost(Duration.ofMinutes(1)).pollInterval(Duration.ofMillis(100)).with()
|
|
||||||
.until(() -> {
|
|
||||||
Optional<Target> maybeTarget = SecurityContextSwitch.runAsPrivileged(() -> {
|
|
||||||
rolloutHandler.handleAll();
|
|
||||||
List<Target> targets = targetManagement.findByRsql(PAGE, "controllerId==" + controllerId).getContent();
|
|
||||||
if (targets.size() == 1) {
|
|
||||||
return Optional.of(targets.get(0));
|
|
||||||
} else {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return maybeTarget.isPresent() && maybeTarget.get().getUpdateStatus().equals(TargetUpdateStatus.PENDING);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Deletion of a rollout")
|
@Description("Deletion of a rollout")
|
||||||
void deleteRollout() throws Exception {
|
void deleteRollout() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user