Introduce basic functionality for invalidation of distributionsets (#1179)

* Basic DS invalidation functionality

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Add checks for valid/complete DS

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Stop rollouts + auto assignments when invalidating a DS

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Add methods to count AAs + rollouts for invalidation

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Small refactoring for DS management

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Add invalidation functionality to REST API

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Fix update stopped rollouts status

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Add various tests

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Introduce countActionsForInvalidation

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Fix event tests with incomplete DS

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Add H2 migration script

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Fix action count method

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Fix REST documentation tests

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Change flyway version number

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Add lock for DS invalidation + adapt tests

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Move concurrency test to own class

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Handle possible InterruptedException

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Fix concurrency test

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Use one transaction for all invalidations

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Add invalidate endpoint to REST docu

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Execute invalidation in transaction when actions are cancelled

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Check that distribution set is valid when editing/creating metadata

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Remove all changes in UI

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Add DB migration files for all databases

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Implement review findings

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Move DS invalidation to own class to check permissions for single steps

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Move invalidation count methods to management classes

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>

* Fix failing tests

Signed-off-by: Sebastian Firsching <sebastian.firsching@bosch-si.com>
This commit is contained in:
Sebastian Firsching
2021-09-30 15:26:36 +02:00
committed by GitHub
parent b25e118e6c
commit 825cb64448
66 changed files with 2413 additions and 511 deletions

View File

@@ -8,10 +8,13 @@
*/
package org.eclipse.hawkbit.repository.event.remote.entity;
import java.util.Collections;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition;
import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.junit.jupiter.api.Test;
import io.qameta.allure.Description;
@@ -34,8 +37,11 @@ public class RolloutEventTest extends AbstractRemoteEntityEventTest<Rollout> {
@Override
protected Rollout createEntity() {
testdataFactory.createTarget("12345");
final DistributionSet ds = distributionSetManagement.create(entityFactory.distributionSet()
.create().name("incomplete").version("2").description("incomplete").type("os"));
final SoftwareModule module = softwareModuleManagement.create(
entityFactory.softwareModule().create().name("swm").version("2").description("desc").type("os"));
final DistributionSet ds = distributionSetManagement
.create(entityFactory.distributionSet().create().name("complete").version("2").description("complete")
.type("os").modules(Collections.singletonList(module.getId())));
return rolloutManagement.create(
entityFactory.rollout().create().name("exampleRollout").targetFilterQuery("controllerId==*").set(ds),

View File

@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.event.remote.entity;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Collections;
import java.util.UUID;
import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -17,6 +18,7 @@ import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition;
import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.junit.jupiter.api.Test;
import io.qameta.allure.Description;
@@ -75,9 +77,11 @@ public class RolloutGroupEventTest extends AbstractRemoteEntityEventTest<Rollout
@Override
protected RolloutGroup createEntity() {
testdataFactory.createTarget(UUID.randomUUID().toString());
final DistributionSet ds = distributionSetManagement.create(entityFactory.distributionSet().create()
.name("incomplete").version("2").description("incomplete").type("os"));
final SoftwareModule module = softwareModuleManagement.create(
entityFactory.softwareModule().create().name("swm").version("2").description("desc").type("os"));
final DistributionSet ds = distributionSetManagement
.create(entityFactory.distributionSet().create().name("complete").version("2").description("complete")
.type("os").modules(Collections.singletonList(module.getId())));
final Rollout entity = rolloutManagement.create(
entityFactory.rollout().create().name("exampleRollout").targetFilterQuery("controllerId==*").set(ds),

View File

@@ -0,0 +1,79 @@
/**
* Copyright (c) 2021 Bosch.IO GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import java.util.Collections;
import org.awaitility.Awaitility;
import org.eclipse.hawkbit.repository.exception.StopRolloutException;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidation;
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidation.CancelationType;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupErrorAction;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupErrorCondition;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition;
import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder;
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
import org.junit.jupiter.api.Test;
import org.springframework.test.context.TestPropertySource;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.qameta.allure.Story;
/**
* Test class testing the invalidation of a {@link DistributionSet} while the
* handle rollouts is ongoing.
*
*/
@Feature("Component Tests - Repository")
@Story("Concurrent Distribution Set invalidation")
@TestPropertySource(properties = "hawkbit.server.repository.dsInvalidationLockTimeout=1")
public class ConcurrentDistributionSetInvalidationTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify that a large rollout causes a timeout when trying to invalidate a distribution set")
public void verifyInvalidateDistributionSetWithLargeRolloutThrowsException() throws Exception {
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
testdataFactory.createTargets(10000, "verifyInvalidateDistributionSetWithLargeRolloutThrowsException");
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults()
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, "50")
.errorCondition(RolloutGroupErrorCondition.THRESHOLD, "80")
.errorAction(RolloutGroupErrorAction.PAUSE, null).build();
final Rollout rollout = rolloutManagement.create(entityFactory.rollout().create()
.name("verifyInvalidateDistributionSetWithLargeRolloutThrowsException").description("desc")
.targetFilterQuery("name==*").set(distributionSet).actionType(ActionType.FORCED), 20, conditions);
final String tenant = tenantAware.getCurrentTenant();
// run in new Thread so that the invalidation can be executed in
// parallel
final Thread handleRolloutsThread = new Thread(() -> {
tenantAware.runAsTenant(tenant, () -> systemSecurityContext.runAsSystem(() -> {
rolloutManagement.handleRollouts();
return 0;
}));
});
handleRolloutsThread.start();
// wait until at least one RolloutGroup is created, as this means that
// the thread has started and has acquired the lock
Awaitility.await().until(() -> tenantAware.runAsTenant(tenant, () -> systemSecurityContext
.runAsSystem(() -> rolloutGroupManagement.findByRollout(PAGE, rollout.getId()).getSize() > 0)));
assertThatExceptionOfType(StopRolloutException.class)
.as("Invalidation of distributionSet should throw an exception")
.isThrownBy(() -> distributionSetInvalidationManagement.invalidateDistributionSet(
new DistributionSetInvalidation(Collections.singletonList(distributionSet.getId()),
CancelationType.SOFT, true)));
}
}

View File

@@ -43,6 +43,7 @@ import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.ForceQuitActionNotAllowedException;
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
import org.eclipse.hawkbit.repository.exception.InvalidDistributionSetException;
import org.eclipse.hawkbit.repository.exception.MultiAssignmentIsNotEnabledException;
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
@@ -844,8 +845,8 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
/**
* test a simple deployment by calling the
* {@link TargetRepository#assignDistributionSet(DistributionSet, Iterable)} and
* checking the active action and the action history of the targets.
* {@link TargetRepository#assignDistributionSet(DistributionSet, Iterable)}
* and checking the active action and the action history of the targets.
*
*/
@Test
@@ -1088,9 +1089,10 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
}
/**
* test the deletion of {@link DistributionSet}s including exception in case of
* {@link Target}s are assigned by {@link Target#getAssignedDistributionSet()}
* or {@link Target#getInstalledDistributionSet()}
* test the deletion of {@link DistributionSet}s including exception in case
* of {@link Target}s are assigned by
* {@link Target#getAssignedDistributionSet()} or
* {@link Target#getInstalledDistributionSet()}
*/
@Test
@Description("Deletes distribution set. Expected behaviour is that a soft delete is performed "
@@ -1357,12 +1359,36 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
assertThat(distributionSetRepository.findAll()).hasSize(1);
}
@Test
@Description("Tests that an exception is thrown when a target is assigned to an incomplete distribution set")
public void verifyAssignTargetsToIncompleteDistribution() {
final DistributionSet distributionSet = testdataFactory.createIncompleteDistributionSet();
final Target target = testdataFactory.createTarget();
assertThatExceptionOfType(IncompleteDistributionSetException.class)
.as("Incomplete distributionSet should throw an exception")
.isThrownBy(() -> assignDistributionSet(distributionSet, target));
}
@Test
@Description("Tests that an exception is thrown when a target is assigned to an invalidated distribution set")
public void verifyAssignTargetsToInvalidDistribution() {
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
final Target target = testdataFactory.createTarget();
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception")
.isThrownBy(() -> assignDistributionSet(distributionSet, target));
}
/**
* Helper methods that creates 2 lists of targets and a list of distribution
* sets.
* <p>
* <b>All created distribution sets are assigned to all targets of the target
* list deployedTargets.</b>
* <b>All created distribution sets are assigned to all targets of the
* target list deployedTargets.</b>
*
* @param undeployedTargetPrefix
* prefix to be used as target controller prefix
@@ -1371,7 +1397,8 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
* @param deployedTargetPrefix
* prefix to be used as target controller prefix
* @param noOfDeployedTargets
* number of targets to which the created distribution sets assigned
* number of targets to which the created distribution sets
* assigned
* @param noOfDistributionSets
* number of distribution sets
* @param distributionSetPrefix

View File

@@ -0,0 +1,304 @@
/**
* Copyright (c) 2021 Bosch.IO GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import java.util.Collections;
import java.util.List;
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException;
import org.eclipse.hawkbit.repository.exception.InvalidDistributionSetException;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidation;
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidation.CancelationType;
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidationCount;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.test.util.WithUser;
import org.junit.jupiter.api.Test;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.qameta.allure.Story;
/**
* Test class testing the functionality of invalidating a
* {@link DistributionSet}
*
*/
@Feature("Component Tests - Repository")
@Story("Distribution set invalidation management")
class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify invalidation of distribution sets that only removes distribution sets from auto assignments")
void verifyInvalidateDistributionSetStopAutoAssignment() {
final InvalidationTestData invalidationTestData = createInvalidationTestData(
"verifyInvalidateDistributionSetStopAutoAssignment");
final DistributionSetInvalidation distributionSetInvalidation = new DistributionSetInvalidation(
Collections.singletonList(invalidationTestData.getDistributionSet().getId()), CancelationType.NONE,
false);
final DistributionSetInvalidationCount distributionSetInvalidationCount = distributionSetInvalidationManagement
.countEntitiesForInvalidation(distributionSetInvalidation);
assertDistributionSetInvalidationCount(distributionSetInvalidationCount, 1, 0, 0);
distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation);
rolloutManagement.handleRollouts();
assertThat(targetFilterQueryManagement.get(invalidationTestData.getTargetFilterQuery().getId()).get()
.getAutoAssignDistributionSet()).isNull();
assertThat(rolloutRepository.findById(invalidationTestData.getRollout().getId()).get().getStatus())
.isNotIn(RolloutStatus.STOPPING, RolloutStatus.FINISHED);
for (final Target target : invalidationTestData.getTargets()) {
// if status is pending, the assignment has not been canceled
assertThat(targetRepository.findById(target.getId()).get().getUpdateStatus())
.isEqualTo(TargetUpdateStatus.PENDING);
assertThat(actionRepository.findByTarget(target).size()).isEqualTo(1);
assertThat(actionRepository.findByTarget(target).get(0).getStatus()).isEqualTo(Status.RUNNING);
}
}
@Test
@Description("Verify invalidation of distribution sets that removes distribution sets from auto assignments and stops rollouts")
void verifyInvalidateDistributionSetStopRollouts() {
final InvalidationTestData invalidationTestData = createInvalidationTestData(
"verifyInvalidateDistributionSetStopRollouts");
final DistributionSetInvalidation distributionSetInvalidation = new DistributionSetInvalidation(
Collections.singletonList(invalidationTestData.getDistributionSet().getId()), CancelationType.NONE,
true);
final DistributionSetInvalidationCount distributionSetInvalidationCount = distributionSetInvalidationManagement
.countEntitiesForInvalidation(distributionSetInvalidation);
assertDistributionSetInvalidationCount(distributionSetInvalidationCount, 1, 0, 1);
distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation);
rolloutManagement.handleRollouts();
assertThat(targetFilterQueryManagement.get(invalidationTestData.getTargetFilterQuery().getId()).get()
.getAutoAssignDistributionSet()).isNull();
assertThat(rolloutRepository.findById(invalidationTestData.getRollout().getId()).get().getStatus())
.isEqualTo(RolloutStatus.FINISHED);
assertNoScheduledActionsExist(invalidationTestData.getRollout());
assertRolloutGroupsAreFinished(invalidationTestData.getRollout());
for (final Target target : invalidationTestData.getTargets()) {
// if status is pending, the assignment has not been canceled
assertThat(
targetRepository.findById(invalidationTestData.getTargets().get(0).getId()).get().getUpdateStatus())
.isEqualTo(TargetUpdateStatus.PENDING);
assertThat(actionRepository.findByTarget(target).size()).isEqualTo(1);
assertThat(actionRepository.findByTarget(target).get(0).getStatus()).isEqualTo(Status.RUNNING);
}
}
@Test
@Description("Verify invalidation of distribution sets that removes distribution sets from auto assignments, stops rollouts and force cancels assignments")
void verifyInvalidateDistributionSetStopAllAndForceCancel() {
final InvalidationTestData invalidationTestData = createInvalidationTestData(
"verifyInvalidateDistributionSetStopAllAndForceCancel");
final DistributionSetInvalidation distributionSetInvalidation = new DistributionSetInvalidation(
Collections.singletonList(invalidationTestData.getDistributionSet().getId()), CancelationType.FORCE,
true);
final DistributionSetInvalidationCount distributionSetInvalidationCount = distributionSetInvalidationManagement
.countEntitiesForInvalidation(distributionSetInvalidation);
assertDistributionSetInvalidationCount(distributionSetInvalidationCount, 1, 5, 1);
distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation);
rolloutManagement.handleRollouts();
assertThat(targetFilterQueryManagement.get(invalidationTestData.getTargetFilterQuery().getId()).get()
.getAutoAssignDistributionSet()).isNull();
assertThat(rolloutRepository.findById(invalidationTestData.getRollout().getId()).get().getStatus())
.isEqualTo(RolloutStatus.FINISHED);
assertNoScheduledActionsExist(invalidationTestData.getRollout());
assertRolloutGroupsAreFinished(invalidationTestData.getRollout());
for (final Target target : invalidationTestData.getTargets()) {
assertThat(targetRepository.findById(target.getId()).get().getUpdateStatus())
.isEqualTo(TargetUpdateStatus.IN_SYNC);
assertThat(actionRepository.findByTarget(target).size()).isEqualTo(1);
assertThat(actionRepository.findByTarget(target).get(0).getStatus()).isEqualTo(Status.CANCELED);
}
}
private void assertNoScheduledActionsExist(final Rollout rollout) {
assertThat(
actionRepository.findByRolloutIdAndStatus(PAGE, rollout.getId(), Status.SCHEDULED).getTotalElements())
.isZero();
}
private void assertRolloutGroupsAreFinished(final Rollout rollout) {
assertThat(rolloutGroupRepository.findByRolloutId(rollout.getId(), PAGE))
.allMatch(rolloutGroup -> rolloutGroup.getStatus().equals(RolloutGroupStatus.FINISHED));
}
@Test
@Description("Verify invalidation of distribution sets that removes distribution sets from auto assignments, stops rollouts and cancels assignments")
void verifyInvalidateDistributionSetStopAll() {
final InvalidationTestData invalidationTestData = createInvalidationTestData(
"verifyInvalidateDistributionSetStopAll");
final DistributionSetInvalidation distributionSetInvalidation = new DistributionSetInvalidation(
Collections.singletonList(invalidationTestData.getDistributionSet().getId()), CancelationType.SOFT,
true);
final DistributionSetInvalidationCount distributionSetInvalidationCount = distributionSetInvalidationManagement
.countEntitiesForInvalidation(distributionSetInvalidation);
assertDistributionSetInvalidationCount(distributionSetInvalidationCount, 1, 5, 1);
distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation);
assertThat(targetFilterQueryManagement.get(invalidationTestData.getTargetFilterQuery().getId()).get()
.getAutoAssignDistributionSet()).isNull();
assertThat(rolloutRepository.findById(invalidationTestData.getRollout().getId()).get().getStatus())
.isIn(RolloutStatus.STOPPING, RolloutStatus.FINISHED);
for (final Target target : invalidationTestData.getTargets()) {
assertThat(targetRepository.findById(target.getId()).get().getUpdateStatus())
.isEqualTo(TargetUpdateStatus.PENDING);
assertThat(actionRepository.findByTarget(target).size()).isEqualTo(1);
assertThat(actionRepository.findByTarget(target).get(0).getStatus()).isEqualTo(Status.CANCELING);
}
}
@Test
@Description("Verify that invalidating an incomplete distribution set throws an exception")
void verifyInvalidateIncompleteDistributionSetThrowsException() {
final DistributionSet distributionSet = testdataFactory.createIncompleteDistributionSet();
assertThatExceptionOfType(IncompleteDistributionSetException.class)
.as("Incomplete distributionSet should throw an exception")
.isThrownBy(() -> distributionSetInvalidationManagement.invalidateDistributionSet(
new DistributionSetInvalidation(Collections.singletonList(distributionSet.getId()),
CancelationType.SOFT, true)));
}
@Test
@Description("Verify that invalidating an invalidated distribution set throws an exception")
void verifyInvalidateInvalidatedDistributionSetThrowsException() {
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception")
.isThrownBy(() -> distributionSetInvalidationManagement.invalidateDistributionSet(
new DistributionSetInvalidation(Collections.singletonList(distributionSet.getId()),
CancelationType.SOFT, true)));
}
@Test
@Description("Verify that a user that has authority READ_REPOSITORY and UPDATE_REPOSITORY is not allowed to invalidate a distribution set")
@WithUser(authorities = { "READ_REPOSITORY", "UPDATE_REPOSITORY" })
void verifyInvalidateWithReadAndUpdateRepoAuthority() {
final InvalidationTestData invalidationTestData = systemSecurityContext
.runAsSystem(() -> createInvalidationTestData("verifyInvalidateWithUpdateRepoAuthority"));
assertThatExceptionOfType(InsufficientPermissionException.class)
.as("Insufficient permission exception expected")
.isThrownBy(() -> distributionSetInvalidationManagement
.invalidateDistributionSet(new DistributionSetInvalidation(
Collections.singletonList(invalidationTestData.getDistributionSet().getId()),
CancelationType.NONE, false)));
}
@Test
@Description("Verify that a user that has authority READ_REPOSITORY, UPDATE_REPOSITORY and UPDATE_TARGET is allowed to invalidate a distribution set only without canceling rollouts")
@WithUser(authorities = { "READ_REPOSITORY", "UPDATE_REPOSITORY", "UPDATE_TARGET" })
void verifyInvalidateWithReadAndUpdateRepoAndUpdateTargetAuthority() {
final InvalidationTestData invalidationTestData = systemSecurityContext.runAsSystem(
() -> createInvalidationTestData("verifyInvalidateWithUpdateRepoAndUpdateTargetAuthority"));
assertThatExceptionOfType(InsufficientPermissionException.class)
.as("Insufficient permission exception expected")
.isThrownBy(() -> distributionSetInvalidationManagement
.invalidateDistributionSet(new DistributionSetInvalidation(
Collections.singletonList(invalidationTestData.getDistributionSet().getId()),
CancelationType.SOFT, true)));
distributionSetInvalidationManagement.invalidateDistributionSet(new DistributionSetInvalidation(
Collections.singletonList(invalidationTestData.getDistributionSet().getId()), CancelationType.NONE,
false));
assertThat(
distributionSetRepository.findById(invalidationTestData.getDistributionSet().getId()).get().isValid())
.isFalse();
}
@Test
@Description("Verify that a user that has authority READ_REPOSITORY, UPDATE_REPOSITORY, UPDATE_ROLLOUT and UPDATE_TARGET is allowed to invalidate a distribution")
@WithUser(authorities = { "READ_REPOSITORY", "UPDATE_REPOSITORY", "UPDATE_TARGET", "UPDATE_ROLLOUT" })
void verifyInvalidateWithReadAndUpdateRepoAndUpdateTargetAndUpdateRolloutAuthority() {
final InvalidationTestData invalidationTestData = systemSecurityContext.runAsSystem(
() -> createInvalidationTestData("verifyInvalidateWithUpdateRepoAndUpdateTargetAuthority"));
distributionSetInvalidationManagement.invalidateDistributionSet(new DistributionSetInvalidation(
Collections.singletonList(invalidationTestData.getDistributionSet().getId()), CancelationType.SOFT,
true));
assertThat(
distributionSetRepository.findById(invalidationTestData.getDistributionSet().getId()).get().isValid())
.isFalse();
}
private InvalidationTestData createInvalidationTestData(final String testName) {
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
final List<Target> targets = testdataFactory.createTargets(5, testName);
assignDistributionSet(distributionSet, targets);
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement.create(entityFactory.targetFilterQuery()
.create().name(testName).query("name==*").autoAssignDistributionSet(distributionSet));
final Rollout rollout = testdataFactory.createRolloutByVariables(testName, "desc", 2, "name==*",
distributionSet, "50", "80");
return new InvalidationTestData(distributionSet, targets, targetFilterQuery, rollout);
}
private static class InvalidationTestData {
private final DistributionSet distributionSet;
private final List<Target> targets;
private final TargetFilterQuery targetFilterQuery;
private final Rollout rollout;
public InvalidationTestData(final DistributionSet distributionSet, final List<Target> targets,
final TargetFilterQuery targetFilterQuery, final Rollout rollout) {
super();
this.distributionSet = distributionSet;
this.targets = targets;
this.targetFilterQuery = targetFilterQuery;
this.rollout = rollout;
}
public DistributionSet getDistributionSet() {
return distributionSet;
}
public List<Target> getTargets() {
return targets;
}
public TargetFilterQuery getTargetFilterQuery() {
return targetFilterQuery;
}
public Rollout getRollout() {
return rollout;
}
}
private void assertDistributionSetInvalidationCount(
final DistributionSetInvalidationCount distributionSetInvalidationCount,
final long expectedAutoAssignmentCount, final long expectedActionCount, final long expectedRolloutCount) {
assertThat(distributionSetInvalidationCount.getAutoAssignmentCount()).isEqualTo(expectedAutoAssignmentCount);
assertThat(distributionSetInvalidationCount.getActionCount()).isEqualTo(expectedActionCount);
assertThat(distributionSetInvalidationCount.getRolloutsCount()).isEqualTo(expectedRolloutCount);
}
}

View File

@@ -31,16 +31,20 @@ import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreated
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetUpdatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
import org.eclipse.hawkbit.repository.exception.InvalidDistributionSetException;
import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder;
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidation;
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidation.CancelationType;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
@@ -174,6 +178,13 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
verifyThrownExceptionBy(() -> distributionSetManagement.updateMetaData(set.getId(),
entityFactory.generateDsMetadata(NOT_EXIST_ID, "xxx")), "DistributionSetMetadata");
verifyThrownExceptionBy(() -> distributionSetManagement.getOrElseThrowException(NOT_EXIST_IDL),
"DistributionSet");
verifyThrownExceptionBy(() -> distributionSetManagement.getValidAndComplete(NOT_EXIST_IDL), "DistributionSet");
verifyThrownExceptionBy(() -> distributionSetManagement.getValid(NOT_EXIST_IDL), "DistributionSet");
}
@Test
@@ -493,6 +504,16 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
assertThat(ds.isRequiredMigrationStep()).isTrue();
}
@Test
@Description("Verifies that an exception is thrown when trying to update an invalid distribution set")
public void updateInvalidDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception").isThrownBy(() -> distributionSetManagement
.update(entityFactory.distributionSet().update(distributionSet.getId()).name("new_name")));
}
@Test
@Description("Verifies the enforcement of the software module quota per distribution set.")
public void assignSoftwareModulesUntilQuotaIsExceeded() {
@@ -533,6 +554,33 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
}
@Test
@Description("Verifies that an exception is thrown when trying to assign software modules to an invalidated distribution set.")
public void verifyAssignSoftwareModulesToInvalidDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
final SoftwareModule softwareModule = testdataFactory.createSoftwareModuleOs();
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception")
.isThrownBy(() -> distributionSetManagement.assignSoftwareModules(distributionSet.getId(),
Collections.singletonList(softwareModule.getId())));
}
@Test
@Description("Verifies that an exception is thrown when trying to unassign a software module from an invalidated distribution set.")
public void verifyUnassignSoftwareModulesToInvalidDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
final SoftwareModule softwareModule = testdataFactory.createSoftwareModuleOs();
distributionSetManagement.assignSoftwareModules(distributionSet.getId(),
Collections.singletonList(softwareModule.getId()));
distributionSetInvalidationManagement.invalidateDistributionSet(new DistributionSetInvalidation(
Collections.singletonList(distributionSet.getId()), CancelationType.NONE, false));
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception").isThrownBy(() -> distributionSetManagement
.unassignSoftwareModule(distributionSet.getId(), softwareModule.getId()));
}
@Test
@WithUser(allSpPermissions = true)
@Description("Checks that metadata for a distribution set can be updated.")
@@ -937,6 +985,24 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
assertThat(distributionSetManagement.findByCompleted(PAGE, true).getTotalElements()).isEqualTo(1);
}
@Test
@Description("Deletes an invalid distribution set")
public void deleteInvalidDistributionSet() {
final DistributionSet set = testdataFactory.createAndInvalidateDistributionSet();
assertThat(distributionSetRepository.findById(set.getId())).isNotEmpty();
distributionSetManagement.delete(set.getId());
assertThat(distributionSetRepository.findById(set.getId())).isEmpty();
}
@Test
@Description("Deletes an incomplete distribution set")
public void deleteIncompleteDistributionSet() {
final DistributionSet set = testdataFactory.createIncompleteDistributionSet();
assertThat(distributionSetRepository.findById(set.getId())).isNotEmpty();
distributionSetManagement.delete(set.getId());
assertThat(distributionSetRepository.findById(set.getId())).isEmpty();
}
@Test
@Description("Queries and loads the metadata related to a given software module.")
public void findAllDistributionSetMetadataByDsId() {
@@ -1013,4 +1079,54 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
assertThat(collect).containsAll(searchIds);
}
@Test
@Description("Verify that an exception is thrown when trying to get an invalid distribution set")
public void verifyGetValid() {
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception")
.isThrownBy(() -> distributionSetManagement.getValid(distributionSet.getId()));
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception")
.isThrownBy(() -> distributionSetManagement.getValidAndComplete(distributionSet.getId()));
}
@Test
@Description("Verify that an exception is thrown when trying to get an incomplete distribution set")
public void verifyGetValidAndComplete() {
final DistributionSet distributionSet = testdataFactory.createIncompleteDistributionSet();
assertThatExceptionOfType(IncompleteDistributionSetException.class)
.as("Incomplete distributionSet should throw an exception")
.isThrownBy(() -> distributionSetManagement.getValidAndComplete(distributionSet.getId()));
}
@Test
@Description("Verify that an exception is thrown when trying to create or update metadata for an invalid distribution set.")
public void createMetadataForInvalidDistributionSet() {
final String knownKey1 = "myKnownKey1";
final String knownKey2 = "myKnownKey2";
final String knownValue = "myKnownValue";
final String knownUpdateValue = "knownUpdateValue";
final DistributionSet ds = testdataFactory.createDistributionSet();
distributionSetManagement.createMetaData(ds.getId(),
Collections.singletonList(entityFactory.generateDsMetadata(knownKey1, knownValue)));
distributionSetInvalidationManagement.invalidateDistributionSet(
new DistributionSetInvalidation(Arrays.asList(ds.getId()), CancelationType.NONE, false));
// assert that no new metadata can be created
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception")
.isThrownBy(() -> distributionSetManagement.createMetaData(ds.getId(),
Collections.singletonList(entityFactory.generateDsMetadata(knownKey2, knownValue))));
// assert that an existing metadata can not be updated
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception").isThrownBy(() -> distributionSetManagement
.updateMetaData(ds.getId(), entityFactory.generateDsMetadata(knownKey1, knownUpdateValue)));
}
}

View File

@@ -46,6 +46,8 @@ import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
import org.eclipse.hawkbit.repository.exception.InvalidDistributionSetException;
import org.eclipse.hawkbit.repository.exception.MultiAssignmentIsNotEnabledException;
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
@@ -72,7 +74,6 @@ import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
import org.eclipse.hawkbit.repository.test.matcher.Expect;
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.data.domain.Page;
@@ -243,8 +244,9 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(firstGroup.getStatus()).isEqualTo(RolloutGroupStatus.RUNNING);
// verify other groups are scheduled
final List<RolloutGroup> scheduledGroups = rolloutGroupManagement.findByRollout(
new OffsetBasedPageRequest(1, 100, Sort.by(Direction.ASC, "id")), createdRollout.getId()).getContent();
final List<RolloutGroup> scheduledGroups = rolloutGroupManagement
.findByRollout(new OffsetBasedPageRequest(1, 100, Sort.by(Direction.ASC, "id")), createdRollout.getId())
.getContent();
scheduledGroups.forEach(group -> assertThat(group.getStatus()).isEqualTo(RolloutGroupStatus.SCHEDULED)
.as("group which should be in scheduled state is in " + group.getStatus() + " state"));
// verify that the first group actions has been started and are in state
@@ -436,8 +438,9 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(errorGroup.get(0).getStatus()).isEqualTo(RolloutGroupStatus.ERROR);
// all other groups should still be in scheduled state
final List<RolloutGroup> scheduleGroups = rolloutGroupManagement.findByRollout(
new OffsetBasedPageRequest(1, 100, Sort.by(Direction.ASC, "id")), createdRollout.getId()).getContent();
final List<RolloutGroup> scheduleGroups = rolloutGroupManagement
.findByRollout(new OffsetBasedPageRequest(1, 100, Sort.by(Direction.ASC, "id")), createdRollout.getId())
.getContent();
scheduleGroups.forEach(group -> assertThat(group.getStatus()).isEqualTo(RolloutGroupStatus.SCHEDULED));
}
@@ -470,8 +473,9 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(rollout.getStatus()).isEqualTo(RolloutStatus.PAUSED);
// all other groups should still be in scheduled state
final List<RolloutGroup> scheduleGroups = rolloutGroupManagement.findByRollout(
new OffsetBasedPageRequest(1, 100, Sort.by(Direction.ASC, "id")), createdRollout.getId()).getContent();
final List<RolloutGroup> scheduleGroups = rolloutGroupManagement
.findByRollout(new OffsetBasedPageRequest(1, 100, Sort.by(Direction.ASC, "id")), createdRollout.getId())
.getContent();
scheduleGroups.forEach(group -> assertThat(group.getStatus()).isEqualTo(RolloutGroupStatus.SCHEDULED));
// resume the rollout again after it gets paused by error action
@@ -521,8 +525,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
// verify all groups are in finished state
rolloutGroupManagement
.findByRollout(new OffsetBasedPageRequest(0, 100, Sort.by(Direction.ASC, "id")),
createdRollout.getId())
.findByRollout(new OffsetBasedPageRequest(0, 100, Sort.by(Direction.ASC, "id")), createdRollout.getId())
.forEach(group -> assertThat(group.getStatus()).isEqualTo(RolloutGroupStatus.FINISHED));
// verify that rollout itself is in finished state
@@ -1823,6 +1826,56 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(actions).allMatch(action -> !action.getWeight().isPresent());
}
@Test
@Description("Verifies that an exception is thrown when trying to create a rollout with an invalidated distribution set.")
public void createRolloutWithInvalidDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception")
.isThrownBy(() -> testdataFactory.createRolloutByVariables("createRolloutWithInvalidDistributionSet",
"desc", 2, "name==*", distributionSet, "50", "80"));
}
@Test
@Description("Verifies that an exception is thrown when trying to create a rollout with an incomplete distribution set.")
public void createRolloutWithIncompleteDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createIncompleteDistributionSet();
assertThatExceptionOfType(IncompleteDistributionSetException.class)
.as("Incomplete distributionSet should throw an exception")
.isThrownBy(() -> testdataFactory.createRolloutByVariables("createRolloutWithIncompleteDistributionSet",
"desc", 2, "name==*", distributionSet, "50", "80"));
}
@Test
@Description("Verifies that an exception is thrown when trying to update a rollout with an invalidated distribution set.")
public void updateRolloutWithInvalidDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
testdataFactory.createTarget();
final Rollout rollout = testdataFactory.createRolloutByVariables("updateRolloutWithInvalidDistributionSet",
"desc", 2, "name==*", distributionSet, "50", "80");
final DistributionSet invalidDistributionSet = testdataFactory.createAndInvalidateDistributionSet();
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception").isThrownBy(() -> rolloutManagement
.update(entityFactory.rollout().update(rollout.getId()).set(invalidDistributionSet.getId())));
}
@Test
@Description("Verifies that an exception is thrown when trying to update a rollout with an incomplete distribution set.")
public void updateRolloutWithIncompleteDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
testdataFactory.createTarget();
final Rollout rollout = testdataFactory.createRolloutByVariables("updateRolloutWithIncompleteDistributionSet",
"desc", 2, "name==*", distributionSet, "50", "80");
final DistributionSet incompleteDistributionSet = testdataFactory.createIncompleteDistributionSet();
assertThatExceptionOfType(IncompleteDistributionSetException.class)
.as("Incomplete distributionSet should throw an exception").isThrownBy(() -> rolloutManagement.update(
entityFactory.rollout().update(rollout.getId()).set(incompleteDistributionSet.getId())));
}
private RolloutGroupCreate generateRolloutGroup(final int index, final Integer percentage,
final String targetFilter) {
return entityFactory.rolloutGroup().create().name("Group" + index).description("Group" + index + "desc")

View File

@@ -23,14 +23,17 @@ import javax.validation.ConstraintViolationException;
import org.assertj.core.api.Assertions;
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
import org.eclipse.hawkbit.repository.builder.AutoAssignDistributionSetUpdate;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetFilterQueryCreatedEvent;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignActionTypeException;
import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignDistributionSetException;
import org.eclipse.hawkbit.repository.exception.InvalidDistributionSetException;
import org.eclipse.hawkbit.repository.exception.MultiAssignmentIsNotEnabledException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.model.Action;
@@ -51,7 +54,7 @@ import io.qameta.allure.Story;
/**
* Test class for {@link TargetFilterQueryManagement}.
*
*
*/
@Feature("Component Tests - Repository")
@Story("Target Filter Query Management")
@@ -252,7 +255,7 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
.create(entityFactory.distributionSet().create().name("incomplete").version("1")
.type(testdataFactory.findOrCreateDefaultTestDsType()));
assertThatExceptionOfType(InvalidAutoAssignDistributionSetException.class)
assertThatExceptionOfType(IncompleteDistributionSetException.class)
.isThrownBy(() -> targetFilterQueryManagement.updateAutoAssignDS(entityFactory.targetFilterQuery()
.updateAutoAssign(targetFilterQuery.getId()).ds(incompleteDistributionSet.getId())));
}
@@ -263,7 +266,7 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
assignDistributionSet(softDeletedDs, testdataFactory.createTarget("forSoftDeletedDs"));
distributionSetManagement.delete(softDeletedDs.getId());
assertThatExceptionOfType(InvalidAutoAssignDistributionSetException.class)
assertThatExceptionOfType(EntityNotFoundException.class)
.isThrownBy(() -> targetFilterQueryManagement.updateAutoAssignDS(entityFactory.targetFilterQuery()
.updateAutoAssign(targetFilterQuery.getId()).ds(softDeletedDs.getId())));
}
@@ -502,4 +505,60 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
assertThat(targetFilterQueryManagement.get(filterId).get().getAutoAssignWeight().get())
.isEqualTo(Action.WEIGHT_MIN);
}
@Test
@Description("Verifies that an exception is thrown when trying to create a target filter with an invalidated distribution set.")
public void createTargetFilterWithInvalidDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception")
.isThrownBy(() -> targetFilterQueryManagement.create(
entityFactory.targetFilterQuery().create().name("createTargetFilterWithInvalidDistributionSet")
.query("name==*").autoAssignDistributionSet(distributionSet)));
}
@Test
@Description("Verifies that an exception is thrown when trying to create a target filter with an incomplete distribution set.")
public void createTargetFilterWithIncompleteDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createIncompleteDistributionSet();
assertThatExceptionOfType(IncompleteDistributionSetException.class)
.as("Incomplete distributionSet should throw an exception")
.isThrownBy(() -> targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create()
.name("createTargetFilterWithIncompleteDistributionSet").query("name==*")
.autoAssignDistributionSet(distributionSet)));
}
@Test
@Description("Verifies that an exception is thrown when trying to update a target filter with an invalidated distribution set.")
public void updateAutoAssignDsWithInvalidDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement
.create(entityFactory.targetFilterQuery().create().name("updateAutoAssignDsWithInvalidDistributionSet")
.query("name==*").autoAssignDistributionSet(distributionSet));
final DistributionSet invalidDistributionSet = testdataFactory.createAndInvalidateDistributionSet();
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception")
.isThrownBy(() -> targetFilterQueryManagement
.updateAutoAssignDS(new AutoAssignDistributionSetUpdate(targetFilterQuery.getId())
.ds(invalidDistributionSet.getId())));
}
@Test
@Description("Verifies that an exception is thrown when trying to update a target filter with an incomplete distribution set.")
public void updateAutoAssignDsWithIncompleteDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement.create(
entityFactory.targetFilterQuery().create().name("updateAutoAssignDsWithIncompleteDistributionSet")
.query("name==*").autoAssignDistributionSet(distributionSet));
final DistributionSet incompleteDistributionSet = testdataFactory.createIncompleteDistributionSet();
assertThatExceptionOfType(IncompleteDistributionSetException.class)
.as("Incomplete distributionSet should throw an exception")
.isThrownBy(() -> targetFilterQueryManagement
.updateAutoAssignDS(new AutoAssignDistributionSetUpdate(targetFilterQuery.getId())
.ds(incompleteDistributionSet.getId())));
}
}

View File

@@ -15,7 +15,7 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignDistributionSetException;
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.eclipse.hawkbit.repository.jpa.ActionRepository;
import org.eclipse.hawkbit.repository.model.Action;
@@ -105,11 +105,11 @@ public class AutoAssignCheckerTest extends AbstractJpaIntegrationTest {
final DistributionSet setB = testdataFactory.createDistributionSet("dsB");
// target filter query that matches all targets
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement.updateAutoAssignDS(
entityFactory.targetFilterQuery()
.updateAutoAssign(targetFilterQueryManagement.create(
entityFactory.targetFilterQuery().create().name("filterA").query("name==*")).getId())
.ds(setA.getId()));
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement.updateAutoAssignDS(entityFactory
.targetFilterQuery()
.updateAutoAssign(targetFilterQueryManagement
.create(entityFactory.targetFilterQuery().create().name("filterA").query("name==*")).getId())
.ds(setA.getId()));
final String targetDsAIdPref = "targ";
final List<Target> targets = testdataFactory.createTargets(100, targetDsAIdPref,
@@ -159,7 +159,7 @@ public class AutoAssignCheckerTest extends AbstractJpaIntegrationTest {
// target filter query that matches first bunch of targets, that should
// fail
assertThatExceptionOfType(InvalidAutoAssignDistributionSetException.class).isThrownBy(() -> {
assertThatExceptionOfType(IncompleteDistributionSetException.class).isThrownBy(() -> {
final Long filterId = targetFilterQueryManagement.create(
entityFactory.targetFilterQuery().create().name("filterA").query("id==" + targetDsFIdPref + "*"))
.getId();
@@ -221,10 +221,10 @@ public class AutoAssignCheckerTest extends AbstractJpaIntegrationTest {
final DistributionSet distributionSet, final List<Target> targets) {
final Set<String> targetIds = targets.stream().map(Target::getControllerId).collect(Collectors.toSet());
actionRepository.findByDistributionSetId(Pageable.unpaged(), distributionSet.getId())
.stream().filter(a -> targetIds.contains(a.getTarget().getControllerId()))
.forEach(a -> assertThat(a.getInitiatedBy()).as(
"Action should be initiated by the user who initiated the auto assignment")
actionRepository.findByDistributionSetId(Pageable.unpaged(), distributionSet.getId()).stream()
.filter(a -> targetIds.contains(a.getTarget().getControllerId()))
.forEach(a -> assertThat(a.getInitiatedBy())
.as("Action should be initiated by the user who initiated the auto assignment")
.isEqualTo(targetFilterQuery.getAutoAssignInitiatedBy()));
}