Code format hawkbit-repository-jpa (#1928)
Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -14,6 +14,8 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.eclipse.hawkbit.event.BusProtoStuffMessageConverter;
|
||||
import org.eclipse.hawkbit.repository.event.TenantAwareEvent;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
@@ -32,9 +34,6 @@ import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
*/
|
||||
@@ -56,6 +55,23 @@ public abstract class AbstractRemoteEventTest extends AbstractJpaIntegrationTest
|
||||
|
||||
}
|
||||
|
||||
protected Message<?> createMessageWithImmutableHeader(final TenantAwareEvent event) {
|
||||
final Map<String, Object> headers = new LinkedHashMap<>();
|
||||
return busProtoStuffMessageConverter.toMessage(event, new MessageHeaders(headers));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T extends TenantAwareEvent> T createJacksonEvent(final T event) {
|
||||
final Message<String> message = createJsonMessage(event);
|
||||
return (T) jacksonMessageConverter.fromMessage(message, event.getClass());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T extends TenantAwareEvent> T createProtoStuffEvent(final T event) {
|
||||
final Message<?> message = createProtoStuffMessage(event);
|
||||
return (T) busProtoStuffMessageConverter.fromMessage(message, event.getClass());
|
||||
}
|
||||
|
||||
private Message<?> createProtoStuffMessage(final TenantAwareEvent event) {
|
||||
final Map<String, Object> headers = new LinkedHashMap<>();
|
||||
headers.put(MessageHeaders.CONTENT_TYPE, BusProtoStuffMessageConverter.APPLICATION_BINARY_PROTOSTUFF);
|
||||
@@ -74,21 +90,4 @@ public abstract class AbstractRemoteEventTest extends AbstractJpaIntegrationTest
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Message<?> createMessageWithImmutableHeader(final TenantAwareEvent event) {
|
||||
final Map<String, Object> headers = new LinkedHashMap<>();
|
||||
return busProtoStuffMessageConverter.toMessage(event, new MessageHeaders(headers));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T extends TenantAwareEvent> T createJacksonEvent(final T event) {
|
||||
final Message<String> message = createJsonMessage(event);
|
||||
return (T) jacksonMessageConverter.fromMessage(message, event.getClass());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T extends TenantAwareEvent> T createProtoStuffEvent(final T event) {
|
||||
final Message<?> message = createProtoStuffMessage(event);
|
||||
return (T) busProtoStuffMessageConverter.fromMessage(message, event.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,8 @@ import java.util.Arrays;
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,6 +15,9 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
@@ -23,10 +26,6 @@ import org.eclipse.hawkbit.repository.model.ActionProperties;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("RemoteTenantAwareEvent Tests")
|
||||
public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
|
||||
@@ -53,16 +52,6 @@ public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
|
||||
assertThat(remoteAssignEventJackson.getControllerIds()).containsExactlyElementsOf(controllerIds);
|
||||
}
|
||||
|
||||
private Action createAction(final String controllerId) {
|
||||
long id = 1;
|
||||
final JpaAction generateAction = new JpaAction();
|
||||
generateAction.setId(id++);
|
||||
generateAction.setActionType(ActionType.FORCED);
|
||||
generateAction.setTarget(testdataFactory.createTarget(controllerId));
|
||||
generateAction.setStatus(Status.RUNNING);
|
||||
return generateAction;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that a MultiActionCancelEvent can be properly serialized and deserialized")
|
||||
public void testMultiActionCancelEvent() {
|
||||
@@ -148,6 +137,16 @@ public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
|
||||
assertCancelTargetAssignmentEvent(action, remoteEventJackson);
|
||||
}
|
||||
|
||||
private Action createAction(final String controllerId) {
|
||||
long id = 1;
|
||||
final JpaAction generateAction = new JpaAction();
|
||||
generateAction.setId(id++);
|
||||
generateAction.setActionType(ActionType.FORCED);
|
||||
generateAction.setTarget(testdataFactory.createTarget(controllerId));
|
||||
generateAction.setStatus(Status.RUNNING);
|
||||
return generateAction;
|
||||
}
|
||||
|
||||
private void assertTargetAssignDistributionSetEvent(final Action action,
|
||||
final TargetAssignDistributionSetEvent underTest) {
|
||||
|
||||
|
||||
@@ -15,10 +15,9 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.eclipse.hawkbit.repository.event.remote.AbstractRemoteEventTest;
|
||||
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.event.remote.AbstractRemoteEventTest;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
|
||||
@@ -11,7 +11,9 @@ package org.eclipse.hawkbit.repository.event.remote.entity;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
@@ -20,10 +22,6 @@ import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
*/
|
||||
|
||||
@@ -9,11 +9,10 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.event.remote.entity;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,12 +9,11 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.event.remote.entity;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
|
||||
@@ -9,12 +9,11 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.event.remote.entity;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
|
||||
@@ -11,6 +11,9 @@ package org.eclipse.hawkbit.repository.event.remote.entity;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition;
|
||||
@@ -18,10 +21,6 @@ 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;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
*/
|
||||
|
||||
@@ -14,6 +14,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import java.util.Collections;
|
||||
import java.util.UUID;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||
@@ -22,10 +25,6 @@ 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;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
*/
|
||||
|
||||
@@ -9,12 +9,11 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.event.remote.entity;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
|
||||
@@ -9,14 +9,11 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.event.remote.entity;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
|
||||
@@ -9,12 +9,11 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.event.remote.entity;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Test the remote entity events.
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -46,13 +48,11 @@ import org.eclipse.hawkbit.repository.jpa.repository.TenantMetaDataRepository;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.model.TargetType;
|
||||
import org.eclipse.hawkbit.repository.model.TargetTypeAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.test.TestConfiguration;
|
||||
@@ -69,8 +69,6 @@ import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ContextConfiguration(classes = {
|
||||
RepositoryApplicationConfiguration.class, TestConfiguration.class })
|
||||
@Import(TestChannelBinderConfiguration.class)
|
||||
@@ -141,6 +139,34 @@ public abstract class AbstractJpaIntegrationTest extends AbstractIntegrationTest
|
||||
@Autowired
|
||||
private JpaProperties jpaProperties;
|
||||
|
||||
protected static void verifyThrownExceptionBy(final ThrowingCallable tc, final String objectType) {
|
||||
Assertions.assertThatExceptionOfType(EntityNotFoundException.class).isThrownBy(tc)
|
||||
.withMessageContaining(NOT_EXIST_ID).withMessageContaining(objectType);
|
||||
}
|
||||
|
||||
protected static <T> List<T> toList(final Iterable<? extends T> it) {
|
||||
return StreamSupport.stream(it.spliterator(), false).map(e -> (T) e).toList();
|
||||
}
|
||||
|
||||
protected static <T> T[] toArray(final Iterable<? extends T> it, final Class<T> type) {
|
||||
final List<T> list = toList(it);
|
||||
final T[] array = (T[]) Array.newInstance(type, list.size());
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] = list.get(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
// just increase the opt lock revision if the instance in order to match it against locked db instance - not really locking
|
||||
protected static void implicitLock(final DistributionSet set) {
|
||||
((JpaDistributionSet) set).setOptLockRevision(set.getOptLockRevision() + 1);
|
||||
}
|
||||
|
||||
// just increase the opt lock revision if the instance in order to match it against locked db instance - not really locking
|
||||
protected static void implicitLock(final SoftwareModule module) {
|
||||
((JpaSoftwareModule) module).setOptLockRevision(module.getOptLockRevision() + 1);
|
||||
}
|
||||
|
||||
protected Database getDatabase() {
|
||||
return jpaProperties.getDatabase();
|
||||
}
|
||||
@@ -150,15 +176,11 @@ public abstract class AbstractJpaIntegrationTest extends AbstractIntegrationTest
|
||||
return toList(actionRepository.findByRolloutIdAndStatus(PAGE, rollout.getId(), actionStatus));
|
||||
}
|
||||
|
||||
protected static void verifyThrownExceptionBy(final ThrowingCallable tc, final String objectType) {
|
||||
Assertions.assertThatExceptionOfType(EntityNotFoundException.class).isThrownBy(tc)
|
||||
.withMessageContaining(NOT_EXIST_ID).withMessageContaining(objectType);
|
||||
}
|
||||
|
||||
protected List<Target> assignTag(final Collection<Target> targets, final TargetTag tag) {
|
||||
return targetManagement.assignTag(
|
||||
targets.stream().map(Target::getControllerId).collect(Collectors.toList()), tag.getId());
|
||||
}
|
||||
|
||||
protected List<Target> unassignTag(final Collection<Target> targets, final TargetTag tag) {
|
||||
return targetManagement.unassignTag(
|
||||
targets.stream().map(Target::getControllerId).collect(Collectors.toList()), tag.getId());
|
||||
@@ -169,6 +191,7 @@ public abstract class AbstractJpaIntegrationTest extends AbstractIntegrationTest
|
||||
return distributionSetManagement.assignTag(
|
||||
sets.stream().map(DistributionSet::getId).collect(Collectors.toList()), tag.getId());
|
||||
}
|
||||
|
||||
protected List<DistributionSet> unassignTag(final Collection<DistributionSet> sets,
|
||||
final DistributionSetTag tag) {
|
||||
return distributionSetManagement.unassignTag(
|
||||
@@ -180,7 +203,8 @@ public abstract class AbstractJpaIntegrationTest extends AbstractIntegrationTest
|
||||
targets.stream().map(Target::getControllerId).collect(Collectors.toList()), type.getId());
|
||||
}
|
||||
|
||||
protected void assertRollout(final Rollout rollout, final boolean dynamic, final Rollout.RolloutStatus status, final int groupCreated, final long totalTargets) {
|
||||
protected void assertRollout(final Rollout rollout, final boolean dynamic, final Rollout.RolloutStatus status, final int groupCreated,
|
||||
final long totalTargets) {
|
||||
final Rollout refreshed = refresh(rollout);
|
||||
assertThat(refreshed.isDynamic()).as("Is dynamic").isEqualTo(dynamic);
|
||||
assertThat(refreshed.getStatus()).as("Status").isEqualTo(status);
|
||||
@@ -188,7 +212,8 @@ public abstract class AbstractJpaIntegrationTest extends AbstractIntegrationTest
|
||||
assertThat(refreshed.getTotalTargets()).as("Total targets").isEqualTo(totalTargets);
|
||||
}
|
||||
|
||||
protected void assertGroup(final RolloutGroup group, final boolean dynamic, final RolloutGroup.RolloutGroupStatus status, final long totalTargets) {
|
||||
protected void assertGroup(final RolloutGroup group, final boolean dynamic, final RolloutGroup.RolloutGroupStatus status,
|
||||
final long totalTargets) {
|
||||
final RolloutGroup refreshed = refresh(group);
|
||||
assertThat(refreshed.isDynamic()).as("Is dynamic").isEqualTo(dynamic);
|
||||
assertThat(refreshed.getStatus()).as("Status").isEqualTo(status);
|
||||
@@ -215,34 +240,11 @@ public abstract class AbstractJpaIntegrationTest extends AbstractIntegrationTest
|
||||
return targetManagement.getTagsByControllerId(controllerId);
|
||||
}
|
||||
|
||||
private JpaRollout refresh(final Rollout rollout) {
|
||||
return rolloutRepository.findById(rollout.getId()).get();
|
||||
}
|
||||
|
||||
protected JpaRolloutGroup refresh(final RolloutGroup group) {
|
||||
return rolloutGroupRepository.findById(group.getId()).get();
|
||||
}
|
||||
|
||||
protected static <T> List<T> toList(final Iterable<? extends T> it) {
|
||||
return StreamSupport.stream(it.spliterator(), false).map(e -> (T)e).toList();
|
||||
}
|
||||
|
||||
protected static <T> T[] toArray(final Iterable<? extends T> it, final Class<T> type) {
|
||||
final List<T> list = toList(it);
|
||||
final T[] array = (T[])Array.newInstance(type, list.size());
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] = list.get(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
// just increase the opt lock revision if the instance in order to match it against locked db instance - not really locking
|
||||
protected static void implicitLock(final DistributionSet set) {
|
||||
((JpaDistributionSet) set).setOptLockRevision(set.getOptLockRevision() + 1);
|
||||
}
|
||||
|
||||
// just increase the opt lock revision if the instance in order to match it against locked db instance - not really locking
|
||||
protected static void implicitLock(final SoftwareModule module) {
|
||||
((JpaSoftwareModule) module).setOptLockRevision(module.getOptLockRevision() + 1);
|
||||
private JpaRollout refresh(final Rollout rollout) {
|
||||
return rolloutRepository.findById(rollout.getId()).get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.awaitility.Awaitility;
|
||||
import org.eclipse.hawkbit.repository.exception.StopRolloutException;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
|
||||
@@ -40,21 +43,59 @@ import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
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")
|
||||
@ContextConfiguration(classes = ConcurrentDistributionSetInvalidationTest.Config.class)
|
||||
@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();
|
||||
final Rollout rollout = createRollout(distributionSet);
|
||||
final String tenant = tenantAware.getCurrentTenant();
|
||||
|
||||
// run in new Thread so that the invalidation can be executed in
|
||||
// parallel
|
||||
new Thread(() -> systemSecurityContext.runAsSystemAsTenant(() -> {
|
||||
rolloutHandler.handleAll();
|
||||
return 0;
|
||||
}, tenant)).start();
|
||||
|
||||
// wait until at least one RolloutGroup is created, as this means that
|
||||
// the thread has started and has acquired the lock
|
||||
Awaitility.await().atMost(Duration.ofSeconds(5))
|
||||
.pollInterval(Duration.ofMillis(100))
|
||||
.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)));
|
||||
}
|
||||
|
||||
private Rollout createRollout(final DistributionSet distributionSet) {
|
||||
testdataFactory.createTargets(
|
||||
quotaManagement.getMaxTargetsPerRolloutGroup() * quotaManagement.getMaxRolloutGroupsPerRollout(),
|
||||
"verifyInvalidateDistributionSetWithLargeRolloutThrowsException");
|
||||
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults()
|
||||
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, "50")
|
||||
.errorCondition(RolloutGroupErrorCondition.THRESHOLD, "80")
|
||||
.errorAction(RolloutGroupErrorAction.PAUSE, null).build();
|
||||
|
||||
return rolloutManagement.create(entityFactory.rollout().create()
|
||||
.name("verifyInvalidateDistributionSetWithLargeRolloutThrowsException").description("desc")
|
||||
.targetFilterQuery("name==*").distributionSetId(distributionSet).actionType(ActionType.FORCED),
|
||||
quotaManagement.getMaxRolloutGroupsPerRollout(), false, conditions);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
@@ -80,47 +121,4 @@ public class ConcurrentDistributionSetInvalidationTest extends AbstractJpaIntegr
|
||||
}
|
||||
}
|
||||
|
||||
@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();
|
||||
final Rollout rollout = createRollout(distributionSet);
|
||||
final String tenant = tenantAware.getCurrentTenant();
|
||||
|
||||
// run in new Thread so that the invalidation can be executed in
|
||||
// parallel
|
||||
new Thread(() -> systemSecurityContext.runAsSystemAsTenant(() -> {
|
||||
rolloutHandler.handleAll();
|
||||
return 0;
|
||||
}, tenant)).start();
|
||||
|
||||
// wait until at least one RolloutGroup is created, as this means that
|
||||
// the thread has started and has acquired the lock
|
||||
Awaitility.await().atMost(Duration.ofSeconds(5))
|
||||
.pollInterval(Duration.ofMillis(100))
|
||||
.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)));
|
||||
}
|
||||
|
||||
private Rollout createRollout(final DistributionSet distributionSet) {
|
||||
testdataFactory.createTargets(
|
||||
quotaManagement.getMaxTargetsPerRolloutGroup() * quotaManagement.getMaxRolloutGroupsPerRollout(),
|
||||
"verifyInvalidateDistributionSetWithLargeRolloutThrowsException");
|
||||
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults()
|
||||
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, "50")
|
||||
.errorCondition(RolloutGroupErrorCondition.THRESHOLD, "80")
|
||||
.errorAction(RolloutGroupErrorAction.PAUSE, null).build();
|
||||
|
||||
return rolloutManagement.create(entityFactory.rollout().create()
|
||||
.name("verifyInvalidateDistributionSetWithLargeRolloutThrowsException").description("desc")
|
||||
.targetFilterQuery("name==*").distributionSetId(distributionSet).actionType(ActionType.FORCED),
|
||||
quotaManagement.getMaxRolloutGroupsPerRollout(), false, conditions);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,21 +18,20 @@ import java.sql.SQLException;
|
||||
import jakarta.persistence.OptimisticLockException;
|
||||
import jakarta.persistence.PersistenceException;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.dao.ConcurrencyFailureException;
|
||||
import org.springframework.dao.UncategorizedDataAccessException;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
/**
|
||||
* Mapping tests for {@link HawkBitEclipseLinkJpaDialect}.
|
||||
*
|
||||
*/
|
||||
@Feature("Unit Tests - Repository")
|
||||
@Story("Exception handling")
|
||||
public class HawkBitEclipseLinkJpaDialectTest {
|
||||
|
||||
private final HawkBitEclipseLinkJpaDialect hawkBitEclipseLinkJpaDialectUnderTest = new HawkBitEclipseLinkJpaDialect();
|
||||
|
||||
@Test
|
||||
@@ -40,7 +39,7 @@ public class HawkBitEclipseLinkJpaDialectTest {
|
||||
public void jpaOptimisticLockExceptionIsConcurrencyFailureException() {
|
||||
assertThat(
|
||||
hawkBitEclipseLinkJpaDialectUnderTest.translateExceptionIfPossible(mock(OptimisticLockException.class)))
|
||||
.isInstanceOf(ConcurrencyFailureException.class);
|
||||
.isInstanceOf(ConcurrencyFailureException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -15,8 +15,6 @@ import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class RandomGeneratedInputStream extends InputStream {
|
||||
@@ -30,8 +28,7 @@ public class RandomGeneratedInputStream extends InputStream {
|
||||
private long index;
|
||||
|
||||
/**
|
||||
* @param size
|
||||
* target size of the stream [byte]
|
||||
* @param size target size of the stream [byte]
|
||||
*/
|
||||
public RandomGeneratedInputStream(final long size) {
|
||||
this.size = size;
|
||||
|
||||
@@ -15,6 +15,9 @@ import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.ContextAware;
|
||||
import org.eclipse.hawkbit.repository.autoassign.AutoAssignExecutor;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
@@ -26,10 +29,6 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
|
||||
@@ -38,14 +38,10 @@ public abstract class AbstractAccessControllerTest extends AbstractJpaIntegratio
|
||||
@Autowired
|
||||
protected TestAccessControlManger testAccessControlManger;
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
testAccessControlManger.deleteAllRules();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
testAccessControlManger.deleteAllRules();
|
||||
protected static <T> List<T> merge(final List<T> lists0, final List<T> list1) {
|
||||
final List<T> merge = new ArrayList<>(lists0);
|
||||
merge.addAll(list1);
|
||||
return merge;
|
||||
}
|
||||
|
||||
protected void permitAllOperations(final AccessController.Operation operation) {
|
||||
@@ -57,6 +53,16 @@ public abstract class AbstractAccessControllerTest extends AbstractJpaIntegratio
|
||||
JpaDistributionSet.class, operation, Specification.where(null), type -> true);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
testAccessControlManger.deleteAllRules();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
testAccessControlManger.deleteAllRules();
|
||||
}
|
||||
|
||||
public static class AccessControlTestConfig {
|
||||
|
||||
private final ContextAware contextAware = new SecurityContextTenantAware((tenant, username) -> List.of());
|
||||
@@ -77,7 +83,8 @@ public abstract class AbstractAccessControllerTest extends AbstractJpaIntegratio
|
||||
|
||||
@Override
|
||||
public Optional<Specification<JpaTarget>> getAccessRules(final Operation operation) {
|
||||
if (contextAware.getCurrentTenant() != null && SecurityContextTenantAware.SYSTEM_USER.equals(contextAware.getCurrentUsername())) {
|
||||
if (contextAware.getCurrentTenant() != null && SecurityContextTenantAware.SYSTEM_USER.equals(
|
||||
contextAware.getCurrentUsername())) {
|
||||
// as tenant, no restrictions
|
||||
return Optional.empty();
|
||||
}
|
||||
@@ -104,7 +111,8 @@ public abstract class AbstractAccessControllerTest extends AbstractJpaIntegratio
|
||||
|
||||
@Override
|
||||
public Optional<Specification<JpaTargetType>> getAccessRules(final Operation operation) {
|
||||
if (contextAware.getCurrentTenant() != null && SecurityContextTenantAware.SYSTEM_USER.equals(contextAware.getCurrentUsername())) {
|
||||
if (contextAware.getCurrentTenant() != null && SecurityContextTenantAware.SYSTEM_USER.equals(
|
||||
contextAware.getCurrentUsername())) {
|
||||
// as tenant, no restrictions
|
||||
return Optional.empty();
|
||||
}
|
||||
@@ -131,7 +139,8 @@ public abstract class AbstractAccessControllerTest extends AbstractJpaIntegratio
|
||||
|
||||
@Override
|
||||
public Optional<Specification<JpaDistributionSet>> getAccessRules(final Operation operation) {
|
||||
if (contextAware.getCurrentTenant() != null && SecurityContextTenantAware.SYSTEM_USER.equals(contextAware.getCurrentUsername())) {
|
||||
if (contextAware.getCurrentTenant() != null && SecurityContextTenantAware.SYSTEM_USER.equals(
|
||||
contextAware.getCurrentUsername())) {
|
||||
// as tenant, no restrictions
|
||||
return Optional.empty();
|
||||
}
|
||||
@@ -151,10 +160,4 @@ public abstract class AbstractAccessControllerTest extends AbstractJpaIntegratio
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
protected static <T> List<T> merge(final List<T> lists0, final List<T> list1) {
|
||||
final List<T> merge = new ArrayList<>(lists0);
|
||||
merge.addAll(list1);
|
||||
return merge;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,8 +139,8 @@ class DistributionSetAccessControllerTest extends AbstractAccessControllerTest {
|
||||
// verify distributionSetManagement#assignSoftwareModules
|
||||
assertThat(distributionSetManagement.assignSoftwareModules(permitted.getId(),
|
||||
Collections.singletonList(swModule.getId()))).satisfies(ds -> {
|
||||
assertThat(ds.getModules().stream().map(Identifiable::getId).toList()).contains(swModule.getId());
|
||||
});
|
||||
assertThat(ds.getModules().stream().map(Identifiable::getId).toList()).contains(swModule.getId());
|
||||
});
|
||||
assertThatThrownBy(() -> {
|
||||
distributionSetManagement.assignSoftwareModules(readOnly.getId(),
|
||||
Collections.singletonList(swModule.getId()));
|
||||
@@ -226,8 +226,8 @@ class DistributionSetAccessControllerTest extends AbstractAccessControllerTest {
|
||||
|
||||
// assignment is denied for readOnlyTarget (read, but no update permissions)
|
||||
assertThatThrownBy(() ->
|
||||
distributionSetManagement.unassignTag(Collections.singletonList(readOnly.getId()), dsTag.getId()))
|
||||
.as("Missing update permissions for target to toggle tag assignment.")
|
||||
distributionSetManagement.unassignTag(Collections.singletonList(readOnly.getId()), dsTag.getId()))
|
||||
.as("Missing update permissions for target to toggle tag assignment.")
|
||||
.isInstanceOf(InsufficientPermissionException.class);
|
||||
|
||||
// assignment is denied for readOnlyTarget (read, but no update permissions)
|
||||
@@ -296,7 +296,6 @@ class DistributionSetAccessControllerTest extends AbstractAccessControllerTest {
|
||||
}).isInstanceOf(EntityNotFoundException.class);
|
||||
}
|
||||
|
||||
|
||||
private void defineAccess(final AccessController.Operation operation, final DistributionSet... distributionSets) {
|
||||
defineAccess(operation, List.of(distributionSets));
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.FilterParams;
|
||||
import org.eclipse.hawkbit.repository.Identifiable;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
@@ -38,10 +41,6 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Access Control")
|
||||
@Story("Test Target Access Controller")
|
||||
class TargetAccessControllerTest extends AbstractAccessControllerTest {
|
||||
@@ -328,11 +327,11 @@ class TargetAccessControllerTest extends AbstractAccessControllerTest {
|
||||
assertThat(content).hasSize(updateTargets.size());
|
||||
|
||||
final List<Target> rolloutTargets = content.stream().flatMap(
|
||||
group -> rolloutGroupManagement.findTargetsOfRolloutGroup(Pageable.unpaged(), group.getId()).get())
|
||||
group -> rolloutGroupManagement.findTargetsOfRolloutGroup(Pageable.unpaged(), group.getId()).get())
|
||||
.toList();
|
||||
|
||||
assertThat(rolloutTargets).hasSize(updateTargets.size()).allMatch(
|
||||
target -> updateTargets.stream().anyMatch(readTarget -> readTarget.getId().equals(target.getId())))
|
||||
target -> updateTargets.stream().anyMatch(readTarget -> readTarget.getId().equals(target.getId())))
|
||||
.noneMatch(target -> readTargets.stream()
|
||||
.anyMatch(readTarget -> readTarget.getId().equals(target.getId())))
|
||||
.noneMatch(target -> hiddenTargets.stream()
|
||||
@@ -358,7 +357,8 @@ class TargetAccessControllerTest extends AbstractAccessControllerTest {
|
||||
"hidden5");
|
||||
|
||||
defineAccess(AccessController.Operation.UPDATE, updateTargets);
|
||||
defineAccess(AccessController.Operation.READ, merge(updateTargets, readTargets));;
|
||||
defineAccess(AccessController.Operation.READ, merge(updateTargets, readTargets));
|
||||
;
|
||||
|
||||
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement
|
||||
.create(entityFactory.targetFilterQuery().create().name("testName").query("id==*"));
|
||||
|
||||
@@ -59,7 +59,7 @@ class TargetTypeAccessControllerTest extends AbstractAccessControllerTest {
|
||||
// verify targetTypeManagement#findByName
|
||||
assertThat(targetTypeManagement.findByName(Pageable.unpaged(), permittedTargetType.getName()).getContent())
|
||||
.hasSize(1).satisfies(results ->
|
||||
assertThat(results.get(0).getId()).isEqualTo(permittedTargetType.getId()));
|
||||
assertThat(results.get(0).getId()).isEqualTo(permittedTargetType.getId()));
|
||||
assertThat(targetTypeManagement.findByName(Pageable.unpaged(), hiddenTargetType.getName())).isEmpty();
|
||||
|
||||
// verify targetTypeManagement#count
|
||||
@@ -144,7 +144,7 @@ class TargetTypeAccessControllerTest extends AbstractAccessControllerTest {
|
||||
// verify targetTypeManagement#update for readOnlyTargetType is not possible
|
||||
assertThatThrownBy(() ->
|
||||
targetTypeManagement.update(entityFactory.targetType().update(readOnlyTargetType.getId())
|
||||
.name(readOnlyTargetType.getName() + "/new").description("newDesc")))
|
||||
.name(readOnlyTargetType.getName() + "/new").description("newDesc")))
|
||||
.isInstanceOf(InsufficientPermissionException.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,6 @@ import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaBaseEntity;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaBaseEntity_;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
|
||||
public class TestAccessControlManger {
|
||||
|
||||
private final Map<AccessRuleId<?>, AccessRule<?>> accessRules = new HashMap<>();
|
||||
@@ -36,22 +34,20 @@ public class TestAccessControlManger {
|
||||
accessRules.put(new AccessRuleId<T>(ruleClass, operation), new AccessRule<T>(specification, check));
|
||||
}
|
||||
|
||||
public <T extends AbstractJpaBaseEntity> Specification<T> getAccessRule(final Class<T> ruleClass, final AccessController.Operation operation) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AccessRule<T> accessRule = (AccessRule<T>) accessRules.getOrDefault(new AccessRuleId<T>(ruleClass, operation), null);
|
||||
public <T extends AbstractJpaBaseEntity> Specification<T> getAccessRule(final Class<T> ruleClass,
|
||||
final AccessController.Operation operation) {
|
||||
@SuppressWarnings("unchecked") final AccessRule<T> accessRule = (AccessRule<T>) accessRules.getOrDefault(
|
||||
new AccessRuleId<T>(ruleClass, operation), null);
|
||||
if (accessRule == null) {
|
||||
return nop();
|
||||
} else {
|
||||
return accessRule.specification();
|
||||
}
|
||||
}
|
||||
private static <T extends AbstractJpaBaseEntity> Specification<T> nop() {
|
||||
return (targetRoot, query, cb) -> cb.equal(targetRoot.get(AbstractJpaBaseEntity_.id), -1);
|
||||
}
|
||||
|
||||
public <T> void assertOperation(final Class<T> ruleClass, final AccessController.Operation operation, final List<T> entities) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final AccessRule<T> accessRule = (AccessRule<T>) accessRules.getOrDefault(new AccessRuleId<T>(ruleClass, operation), null);
|
||||
@SuppressWarnings("unchecked") final AccessRule<T> accessRule = (AccessRule<T>) accessRules.getOrDefault(
|
||||
new AccessRuleId<T>(ruleClass, operation), null);
|
||||
if (accessRule == null) {
|
||||
throw new InsufficientPermissionException("No access define - reject all");
|
||||
} else {
|
||||
@@ -65,6 +61,11 @@ public class TestAccessControlManger {
|
||||
}
|
||||
}
|
||||
|
||||
private static <T extends AbstractJpaBaseEntity> Specification<T> nop() {
|
||||
return (targetRoot, query, cb) -> cb.equal(targetRoot.get(AbstractJpaBaseEntity_.id), -1);
|
||||
}
|
||||
|
||||
private record AccessRuleId<T>(Class<T> ruleClass, AccessController.Operation operation) {}
|
||||
private record AccessRule<T> (Specification<T> specification, Predicate<T> checker) {}
|
||||
|
||||
private record AccessRule<T>(Specification<T> specification, Predicate<T> checker) {}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,10 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
@@ -42,14 +46,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Slice;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
/**
|
||||
* Test class for {@link AutoAssignChecker}.
|
||||
*
|
||||
*/
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("Auto assign checker")
|
||||
@@ -236,14 +234,6 @@ class AutoAssignCheckerIntTest extends AbstractJpaIntegrationTest {
|
||||
verifyThatTargetsNotHaveDistributionSetAssignment(toAssignDs, targets.subList(1, 25));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> confirmationOptions() {
|
||||
return Stream.of( //
|
||||
Arguments.of(true, true, Status.WAIT_FOR_CONFIRMATION), //
|
||||
Arguments.of(true, false, Status.RUNNING), //
|
||||
Arguments.of(false, true, Status.RUNNING), //
|
||||
Arguments.of(false, false, Status.RUNNING));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test auto assignment of an incomplete DS to filtered targets, that causes failures")
|
||||
void checkAutoAssignWithFailures() {
|
||||
@@ -261,7 +251,7 @@ class AutoAssignCheckerIntTest extends AbstractJpaIntegrationTest {
|
||||
// fail
|
||||
assertThatExceptionOfType(IncompleteDistributionSetException.class).isThrownBy(() -> {
|
||||
final Long filterId = targetFilterQueryManagement.create(
|
||||
entityFactory.targetFilterQuery().create().name("filterA").query("id==" + targetDsFIdPref + "*"))
|
||||
entityFactory.targetFilterQuery().create().name("filterA").query("id==" + targetDsFIdPref + "*"))
|
||||
.getId();
|
||||
targetFilterQueryManagement
|
||||
.updateAutoAssignDS(entityFactory.targetFilterQuery().updateAutoAssign(filterId).ds(setF.getId()));
|
||||
@@ -295,71 +285,6 @@ class AutoAssignCheckerIntTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param set
|
||||
* the expected distribution set
|
||||
* @param targets
|
||||
* the targets that should have it
|
||||
*/
|
||||
@Step
|
||||
private void verifyThatTargetsHaveDistributionSetAssignment(final DistributionSet set, final List<Target> targets,
|
||||
final int count) {
|
||||
final List<Long> targetIds = targets.stream().map(Target::getId).collect(Collectors.toList());
|
||||
|
||||
final Slice<Target> targetsAll = targetManagement.findAll(PAGE);
|
||||
assertThat(targetsAll).as("Count of targets").hasSize(count);
|
||||
|
||||
for (final Target target : targetsAll) {
|
||||
if (targetIds.contains(target.getId())) {
|
||||
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId()).get())
|
||||
.as("assigned DS").isEqualTo(set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThatTargetsHaveDistributionSetAssignedAndActionStatus(final DistributionSet set,
|
||||
final List<Target> targets, final Action.Status status) {
|
||||
final List<String> targetIds = targets.stream().map(Target::getControllerId).collect(Collectors.toList());
|
||||
final List<Target> targetsWithAssignedDS = targetManagement.findByAssignedDistributionSet(PAGE, set.getId())
|
||||
.getContent();
|
||||
assertThat(targetsWithAssignedDS).isNotEmpty();
|
||||
assertThat(targetsWithAssignedDS).allMatch(target -> targetIds.contains(target.getControllerId()));
|
||||
|
||||
final List<Action> actionsByDs = findActionsByDistributionSet(PAGE, set.getId())
|
||||
.getContent();
|
||||
|
||||
assertThat(actionsByDs).hasSize(targets.size());
|
||||
assertThat(actionsByDs).allMatch(action -> action.getStatus() == status);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThatTargetsNotHaveDistributionSetAssignment(final DistributionSet set,
|
||||
final List<Target> targets) {
|
||||
final List<Long> targetIds = targets.stream().map(Target::getId).collect(Collectors.toList());
|
||||
|
||||
final Slice<Target> targetsAll = targetManagement.findAll(PAGE);
|
||||
|
||||
for (final Target target : targetsAll) {
|
||||
if (targetIds.contains(target.getId())) {
|
||||
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId())).isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThatCreatedActionsAreInitiatedByCurrentUser(final TargetFilterQuery targetFilterQuery,
|
||||
final DistributionSet distributionSet, final List<Target> targets) {
|
||||
final Set<String> targetIds = targets.stream().map(Target::getControllerId).collect(Collectors.toSet());
|
||||
|
||||
findActionsByDistributionSet(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()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test auto assignment of a distribution set with FORCED, SOFT and DOWNLOAD_ONLY action types")
|
||||
void checkAutoAssignWithDifferentActionTypes() {
|
||||
@@ -389,29 +314,6 @@ class AutoAssignCheckerIntTest extends AbstractJpaIntegrationTest {
|
||||
verifyThatTargetsHaveAssignmentActionType(ActionType.DOWNLOAD_ONLY, targetsC);
|
||||
}
|
||||
|
||||
@Step
|
||||
private List<Target> createTargetsAndAutoAssignDistSet(final String prefix, final int targetCount,
|
||||
final DistributionSet distributionSet, final ActionType actionType) {
|
||||
|
||||
final List<Target> targets = testdataFactory.createTargets(targetCount, "target" + prefix,
|
||||
prefix.concat(" description"));
|
||||
targetFilterQueryManagement.create(
|
||||
entityFactory.targetFilterQuery().create().name("filter" + prefix).query("id==target" + prefix + "*")
|
||||
.autoAssignDistributionSet(distributionSet).autoAssignActionType(actionType));
|
||||
|
||||
return targets;
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThatTargetsHaveAssignmentActionType(final ActionType actionType, final List<Target> targets) {
|
||||
final List<Action> actions = targets.stream().map(Target::getControllerId).flatMap(
|
||||
controllerId -> deploymentManagement.findActionsByTarget(controllerId, PAGE).getContent().stream())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(actions).hasSize(targets.size());
|
||||
assertThat(actions).allMatch(action -> action.getActionType().equals(actionType));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("An auto assignment target filter with weight creates actions with weights")
|
||||
void actionsWithWeightAreCreated() throws Exception {
|
||||
@@ -497,6 +399,100 @@ class AutoAssignCheckerIntTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(actionTargets).containsExactlyInAnyOrderElementsOf(compatibleTargets);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> confirmationOptions() {
|
||||
return Stream.of( //
|
||||
Arguments.of(true, true, Status.WAIT_FOR_CONFIRMATION), //
|
||||
Arguments.of(true, false, Status.RUNNING), //
|
||||
Arguments.of(false, true, Status.RUNNING), //
|
||||
Arguments.of(false, false, Status.RUNNING));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param set the expected distribution set
|
||||
* @param targets the targets that should have it
|
||||
*/
|
||||
@Step
|
||||
private void verifyThatTargetsHaveDistributionSetAssignment(final DistributionSet set, final List<Target> targets,
|
||||
final int count) {
|
||||
final List<Long> targetIds = targets.stream().map(Target::getId).collect(Collectors.toList());
|
||||
|
||||
final Slice<Target> targetsAll = targetManagement.findAll(PAGE);
|
||||
assertThat(targetsAll).as("Count of targets").hasSize(count);
|
||||
|
||||
for (final Target target : targetsAll) {
|
||||
if (targetIds.contains(target.getId())) {
|
||||
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId()).get())
|
||||
.as("assigned DS").isEqualTo(set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThatTargetsHaveDistributionSetAssignedAndActionStatus(final DistributionSet set,
|
||||
final List<Target> targets, final Action.Status status) {
|
||||
final List<String> targetIds = targets.stream().map(Target::getControllerId).collect(Collectors.toList());
|
||||
final List<Target> targetsWithAssignedDS = targetManagement.findByAssignedDistributionSet(PAGE, set.getId())
|
||||
.getContent();
|
||||
assertThat(targetsWithAssignedDS).isNotEmpty();
|
||||
assertThat(targetsWithAssignedDS).allMatch(target -> targetIds.contains(target.getControllerId()));
|
||||
|
||||
final List<Action> actionsByDs = findActionsByDistributionSet(PAGE, set.getId())
|
||||
.getContent();
|
||||
|
||||
assertThat(actionsByDs).hasSize(targets.size());
|
||||
assertThat(actionsByDs).allMatch(action -> action.getStatus() == status);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThatTargetsNotHaveDistributionSetAssignment(final DistributionSet set,
|
||||
final List<Target> targets) {
|
||||
final List<Long> targetIds = targets.stream().map(Target::getId).collect(Collectors.toList());
|
||||
|
||||
final Slice<Target> targetsAll = targetManagement.findAll(PAGE);
|
||||
|
||||
for (final Target target : targetsAll) {
|
||||
if (targetIds.contains(target.getId())) {
|
||||
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId())).isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThatCreatedActionsAreInitiatedByCurrentUser(final TargetFilterQuery targetFilterQuery,
|
||||
final DistributionSet distributionSet, final List<Target> targets) {
|
||||
final Set<String> targetIds = targets.stream().map(Target::getControllerId).collect(Collectors.toSet());
|
||||
|
||||
findActionsByDistributionSet(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()));
|
||||
}
|
||||
|
||||
@Step
|
||||
private List<Target> createTargetsAndAutoAssignDistSet(final String prefix, final int targetCount,
|
||||
final DistributionSet distributionSet, final ActionType actionType) {
|
||||
|
||||
final List<Target> targets = testdataFactory.createTargets(targetCount, "target" + prefix,
|
||||
prefix.concat(" description"));
|
||||
targetFilterQueryManagement.create(
|
||||
entityFactory.targetFilterQuery().create().name("filter" + prefix).query("id==target" + prefix + "*")
|
||||
.autoAssignDistributionSet(distributionSet).autoAssignActionType(actionType));
|
||||
|
||||
return targets;
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThatTargetsHaveAssignmentActionType(final ActionType actionType, final List<Target> targets) {
|
||||
final List<Action> actions = targets.stream().map(Target::getControllerId).flatMap(
|
||||
controllerId -> deploymentManagement.findActionsByTarget(controllerId, PAGE).getContent().stream())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(actions).hasSize(targets.size());
|
||||
assertThat(actions).allMatch(action -> action.getActionType().equals(actionType));
|
||||
}
|
||||
|
||||
private Slice<Action> findActionsByDistributionSet(final Pageable pageable, final long distributionSetId) {
|
||||
return actionRepository
|
||||
.findAll(ActionSpecifications.byDistributionSetId(distributionSetId), pageable)
|
||||
|
||||
@@ -11,13 +11,19 @@ package org.eclipse.hawkbit.repository.jpa.autoassign;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.ContextAware;
|
||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||
@@ -36,14 +42,11 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.data.domain.SliceImpl;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Unit Tests - Repository")
|
||||
@Story("Auto assign checker")
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class AutoAssignCheckerTest {
|
||||
|
||||
@Mock
|
||||
private TargetFilterQueryManagement targetFilterQueryManagement;
|
||||
@Mock
|
||||
@@ -86,13 +89,6 @@ class AutoAssignCheckerTest {
|
||||
Mockito.verifyNoMoreInteractions(deploymentManagement);
|
||||
}
|
||||
|
||||
private ArgumentMatcher<List<DeploymentRequest>> deployReqMatcher(final String target, final long ds) {
|
||||
return requests -> {
|
||||
final DeploymentRequest request = requests.get(0);
|
||||
return requests.size() == 1 && request.getDistributionSetId() == ds && request.getControllerId() == target;
|
||||
};
|
||||
}
|
||||
|
||||
private static TargetFilterQuery mockFilterQuery(final long dsId) {
|
||||
final DistributionSet ds = mock(DistributionSet.class);
|
||||
when(ds.getId()).thenReturn(dsId);
|
||||
@@ -104,12 +100,6 @@ class AutoAssignCheckerTest {
|
||||
return filter;
|
||||
}
|
||||
|
||||
private void mockRunningAsNonSystem() {
|
||||
when(contextAware.getCurrentTenant()).thenReturn(getRandomString());
|
||||
when(contextAware.runAsTenantAsUser(any(String.class), any(String.class), any(TenantAware.TenantRunner.class)))
|
||||
.thenAnswer(i -> ((TenantAware.TenantRunner)i.getArgument(2)).run());
|
||||
}
|
||||
|
||||
private static long getRandomLong() {
|
||||
return ThreadLocalRandom.current().nextLong();
|
||||
}
|
||||
@@ -118,4 +108,17 @@ class AutoAssignCheckerTest {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
private ArgumentMatcher<List<DeploymentRequest>> deployReqMatcher(final String target, final long ds) {
|
||||
return requests -> {
|
||||
final DeploymentRequest request = requests.get(0);
|
||||
return requests.size() == 1 && request.getDistributionSetId() == ds && request.getControllerId() == target;
|
||||
};
|
||||
}
|
||||
|
||||
private void mockRunningAsNonSystem() {
|
||||
when(contextAware.getCurrentTenant()).thenReturn(getRandomString());
|
||||
when(contextAware.runAsTenantAsUser(any(String.class), any(String.class), any(TenantAware.TenantRunner.class)))
|
||||
.thenAnswer(i -> ((TenantAware.TenantRunner) i.getArgument(2)).run());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@ import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationPrope
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||
@@ -25,13 +28,8 @@ import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
/**
|
||||
* Test class for {@link AutoActionCleanup}.
|
||||
*
|
||||
*/
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("Action cleanup handler")
|
||||
|
||||
@@ -14,19 +14,17 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.support.locks.LockRegistry;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
/**
|
||||
* Test class for {@link AutoCleanupScheduler}.
|
||||
*
|
||||
*/
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("Auto cleanup scheduler")
|
||||
|
||||
@@ -15,6 +15,9 @@ import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.eclipse.hawkbit.repository.event.TenantAwareEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.DistributionSetDeletedEvent;
|
||||
@@ -44,10 +47,6 @@ import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.event.EventListener;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("Entity Events")
|
||||
@SpringBootTest(classes = { RepositoryTestConfiguration.class }, webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||
|
||||
@@ -11,16 +11,15 @@ package org.eclipse.hawkbit.repository.jpa.management;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.awaitility.Awaitility;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import java.time.Duration;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
import java.time.Duration;
|
||||
import org.awaitility.Awaitility;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@Feature("Unit Tests - Repository")
|
||||
@Story("Deployment Management")
|
||||
|
||||
@@ -27,6 +27,9 @@ import java.util.concurrent.Callable;
|
||||
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
|
||||
@@ -56,10 +59,6 @@ import org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch;
|
||||
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 for {@link ArtifactManagement}.
|
||||
*/
|
||||
@@ -280,7 +279,7 @@ public class ArtifactManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
final int artifactSize = 5 * 1024;
|
||||
try (final InputStream inputStream1 = new RandomGeneratedInputStream(artifactSize);
|
||||
final InputStream inputStream2 = new RandomGeneratedInputStream(artifactSize)) {
|
||||
final InputStream inputStream2 = new RandomGeneratedInputStream(artifactSize)) {
|
||||
|
||||
final Artifact artifact1 = createArtifactForSoftwareModule("file1", sm.getId(), artifactSize, inputStream1);
|
||||
final Artifact artifact2 = createArtifactForSoftwareModule("file2", sm2.getId(), artifactSize,
|
||||
@@ -294,10 +293,10 @@ public class ArtifactManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
assertThat(
|
||||
binaryArtifactRepository.getArtifactBySha1(tenantAware.getCurrentTenant(), artifact1.getSha1Hash()))
|
||||
.isNotNull();
|
||||
.isNotNull();
|
||||
assertThat(
|
||||
binaryArtifactRepository.getArtifactBySha1(tenantAware.getCurrentTenant(), artifact2.getSha1Hash()))
|
||||
.isNotNull();
|
||||
.isNotNull();
|
||||
|
||||
artifactManagement.delete(artifact1.getId());
|
||||
|
||||
@@ -305,15 +304,15 @@ public class ArtifactManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
assertThat(
|
||||
binaryArtifactRepository.getArtifactBySha1(tenantAware.getCurrentTenant(), artifact1.getSha1Hash()))
|
||||
.isNull();
|
||||
.isNull();
|
||||
assertThat(
|
||||
binaryArtifactRepository.getArtifactBySha1(tenantAware.getCurrentTenant(), artifact2.getSha1Hash()))
|
||||
.isNotNull();
|
||||
.isNotNull();
|
||||
|
||||
artifactManagement.delete(artifact2.getId());
|
||||
assertThat(
|
||||
binaryArtifactRepository.getArtifactBySha1(tenantAware.getCurrentTenant(), artifact2.getSha1Hash()))
|
||||
.isNull();
|
||||
.isNull();
|
||||
|
||||
assertThat(artifactRepository.findAll()).hasSize(0);
|
||||
}
|
||||
@@ -345,19 +344,19 @@ public class ArtifactManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
assertThat(
|
||||
binaryArtifactRepository.getArtifactBySha1(tenantAware.getCurrentTenant(), artifact1.getSha1Hash()))
|
||||
.isNotNull();
|
||||
.isNotNull();
|
||||
|
||||
artifactManagement.delete(artifact1.getId());
|
||||
assertThat(
|
||||
binaryArtifactRepository.getArtifactBySha1(tenantAware.getCurrentTenant(), artifact1.getSha1Hash()))
|
||||
.isNotNull();
|
||||
.isNotNull();
|
||||
assertThat(artifactRepository.findAll()).hasSize(1);
|
||||
assertThat(artifactRepository.existsById(artifact1.getId())).isFalse();
|
||||
|
||||
artifactManagement.delete(artifact2.getId());
|
||||
assertThat(
|
||||
binaryArtifactRepository.getArtifactBySha1(tenantAware.getCurrentTenant(), artifact1.getSha1Hash()))
|
||||
.isNull();
|
||||
.isNull();
|
||||
assertThat(artifactRepository.findAll()).hasSize(0);
|
||||
}
|
||||
}
|
||||
@@ -422,7 +421,7 @@ public class ArtifactManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
assertThat(runAsTenant(tenant1, () -> artifactRepository
|
||||
.countBySha1HashAndTenantAndSoftwareModuleDeletedIsFalse(artifactTenant2.getSha1Hash(), tenant2)))
|
||||
.isLessThanOrEqualTo(1);
|
||||
.isLessThanOrEqualTo(1);
|
||||
runAsTenant(tenant2, () -> {
|
||||
artifactRepository.deleteById(artifactTenant2.getId());
|
||||
return null;
|
||||
@@ -579,6 +578,10 @@ public class ArtifactManagementTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] randomBytes(final int len) {
|
||||
return RandomStringUtils.randomAlphanumeric(len).getBytes();
|
||||
}
|
||||
|
||||
private DbArtifactHash calcHashes(final byte[] input) throws NoSuchAlgorithmException {
|
||||
final String sha1Hash = toBase16Hash("SHA1", input);
|
||||
final String md5Hash = toBase16Hash("MD5", input);
|
||||
@@ -606,10 +609,6 @@ public class ArtifactManagementTest extends AbstractJpaIntegrationTest {
|
||||
return artifactManagement.create(new ArtifactUpload(inputStream, moduleId, filename, false, artifactSize));
|
||||
}
|
||||
|
||||
private static byte[] randomBytes(final int len) {
|
||||
return RandomStringUtils.randomAlphanumeric(len).getBytes();
|
||||
}
|
||||
|
||||
private <T> T runAsTenant(final String tenant, final Callable<T> callable) throws Exception {
|
||||
return SecurityContextSwitch.runAs(SecurityContextSwitch.withUserAndTenantAllSpPermissions("user", tenant), callable);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.exception.AutoConfirmationAlreadyActiveException;
|
||||
import org.eclipse.hawkbit.repository.exception.InvalidConfirmationFeedbackException;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
@@ -29,10 +32,6 @@ import org.eclipse.hawkbit.repository.model.DeploymentRequestBuilder;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
@@ -40,7 +39,6 @@ import org.junit.jupiter.params.provider.MethodSource;
|
||||
/**
|
||||
* Test class testing the functionality of triggering a deployment of
|
||||
* {@link DistributionSet}s to {@link Target}s with AutoConfirmation active.
|
||||
*
|
||||
*/
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("Confirmation Management")
|
||||
@@ -140,9 +138,9 @@ class ConfirmationManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(newAction.getStatus()).isEqualTo(Status.RUNNING);
|
||||
|
||||
assertThatThrownBy(() -> confirmationManagement.confirmAction(actions.get(0).getId(), null, null))
|
||||
.isInstanceOf(InvalidConfirmationFeedbackException.class)
|
||||
.matches(e -> ((InvalidConfirmationFeedbackException) e)
|
||||
.getReason() == InvalidConfirmationFeedbackException.Reason.NOT_AWAITING_CONFIRMATION);
|
||||
.isInstanceOf(InvalidConfirmationFeedbackException.class)
|
||||
.matches(e -> ((InvalidConfirmationFeedbackException) e)
|
||||
.getReason() == InvalidConfirmationFeedbackException.Reason.NOT_AWAITING_CONFIRMATION);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -152,9 +150,9 @@ class ConfirmationManagementTest extends AbstractJpaIntegrationTest {
|
||||
final Action action = prepareFinishedUpdate();
|
||||
|
||||
assertThatThrownBy(() -> confirmationManagement.confirmAction(action.getId(), null, null))
|
||||
.isInstanceOf(InvalidConfirmationFeedbackException.class)
|
||||
.matches(e -> ((InvalidConfirmationFeedbackException) e)
|
||||
.getReason() == InvalidConfirmationFeedbackException.Reason.ACTION_CLOSED);
|
||||
.isInstanceOf(InvalidConfirmationFeedbackException.class)
|
||||
.matches(e -> ((InvalidConfirmationFeedbackException) e)
|
||||
.getReason() == InvalidConfirmationFeedbackException.Reason.ACTION_CLOSED);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -197,7 +195,7 @@ class ConfirmationManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
final List<Action> actions = assignDistributionSets(
|
||||
Arrays.asList(toDeploymentRequest(controllerId, dsId), toDeploymentRequest(controllerId, dsId2)))
|
||||
.stream().flatMap(s -> s.getAssignedEntity().stream()).collect(Collectors.toList());
|
||||
.stream().flatMap(s -> s.getAssignedEntity().stream()).collect(Collectors.toList());
|
||||
assertThat(actions).hasSize(2);
|
||||
|
||||
assertThat(confirmationManagement.findActiveActionsWaitingConfirmation(controllerId)).hasSize(2)
|
||||
@@ -276,11 +274,6 @@ class ConfirmationManagementTest extends AbstractJpaIntegrationTest {
|
||||
verifyAutoConfirmationIsDisabled(controllerId);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> getAutoConfirmationArguments() {
|
||||
return Stream.of(Arguments.of("TestUser", "TestRemark"), Arguments.of("TestUser", null),
|
||||
Arguments.of(null, "TestRemark"), Arguments.of(null, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verify activating already active auto confirmation will throw exception.")
|
||||
void verifyActivateAlreadyActiveAutoConfirmationThrowException() {
|
||||
@@ -305,13 +298,18 @@ class ConfirmationManagementTest extends AbstractJpaIntegrationTest {
|
||||
verifyAutoConfirmationIsDisabled(controllerId);
|
||||
}
|
||||
|
||||
private void verifyAutoConfirmationIsDisabled(final String controllerId) {
|
||||
assertThat(targetManagement.getByControllerID(controllerId))
|
||||
.hasValueSatisfying(target -> assertThat(target.getAutoConfirmationStatus()).isNull());
|
||||
private static Stream<Arguments> getAutoConfirmationArguments() {
|
||||
return Stream.of(Arguments.of("TestUser", "TestRemark"), Arguments.of("TestUser", null),
|
||||
Arguments.of(null, "TestRemark"), Arguments.of(null, null));
|
||||
}
|
||||
|
||||
private static DeploymentRequest toDeploymentRequest(final String controllerId, final Long distributionSetId) {
|
||||
return new DeploymentRequestBuilder(controllerId, distributionSetId).setConfirmationRequired(true).build();
|
||||
}
|
||||
|
||||
private void verifyAutoConfirmationIsDisabled(final String controllerId) {
|
||||
assertThat(targetManagement.getByControllerID(controllerId))
|
||||
.hasValueSatisfying(target -> assertThat(target.getAutoConfirmationStatus()).isNull());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -30,15 +30,18 @@ import java.util.stream.Stream;
|
||||
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.eclipse.hawkbit.repository.ActionStatusFields;
|
||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||
import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.MultiActionAssignEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.MultiActionCancelEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
|
||||
@@ -92,10 +95,6 @@ import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
/**
|
||||
* Test class testing the functionality of triggering a deployment of {@link DistributionSet}s to {@link Target}s.
|
||||
*/
|
||||
@@ -106,6 +105,44 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
private static final boolean STATE_ACTIVE = true;
|
||||
private static final boolean STATE_INACTIVE = false;
|
||||
|
||||
@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));
|
||||
|
||||
}
|
||||
|
||||
protected List<DeploymentRequest> createAssignmentRequests(final Collection<DistributionSet> distributionSets,
|
||||
final Collection<Target> targets, final int weight) {
|
||||
return createAssignmentRequests(distributionSets, targets, weight, false);
|
||||
}
|
||||
|
||||
protected List<DeploymentRequest> createAssignmentRequests(final Collection<DistributionSet> distributionSets,
|
||||
final Collection<Target> targets, final int weight, final boolean confirmationRequired) {
|
||||
final List<DeploymentRequest> deploymentRequests = new ArrayList<>();
|
||||
distributionSets.forEach(ds -> targets.forEach(target -> deploymentRequests
|
||||
.add(DeploymentManagement.deploymentRequest(target.getControllerId(), ds.getId()).setWeight(weight)
|
||||
.setConfirmationRequired(confirmationRequired).build())));
|
||||
return deploymentRequests;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that management get access react as specified on calls for non existing entities by means " +
|
||||
"of Optional not present.")
|
||||
@@ -279,7 +316,8 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
|
||||
@Expect(type = DistributionSetUpdatedEvent.class, count = 2), // implicit lock
|
||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6) }) // implicit lock })
|
||||
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6) })
|
||||
// implicit lock })
|
||||
void multiAssigmentHistoryOverMultiplePagesResultsInTwoActiveAction() {
|
||||
|
||||
final DistributionSet cancelDs = testdataFactory.createDistributionSet("Canceled DS", "1.0",
|
||||
@@ -450,24 +488,6 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
.isThrownBy(() -> deploymentManagement.forceQuitAction(assigningAction.getId()));
|
||||
}
|
||||
|
||||
private JpaAction assignSet(final Target target, final DistributionSet ds) {
|
||||
assignDistributionSet(ds.getId(), target.getControllerId());
|
||||
implicitLock(ds);
|
||||
assertThat(targetManagement.getByControllerID(target.getControllerId()).get().getUpdateStatus())
|
||||
.as("wrong update status").isEqualTo(TargetUpdateStatus.PENDING);
|
||||
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId())).as("wrong assigned ds")
|
||||
.contains(ds);
|
||||
final JpaAction action = actionRepository
|
||||
.findAll(
|
||||
(root, query, cb) ->
|
||||
cb.and(
|
||||
cb.equal(root.get(JpaAction_.target).get(JpaTarget_.id), target.getId()),
|
||||
cb.equal(root.get(JpaAction_.distributionSet).get(JpaDistributionSet_.id), ds.getId())),
|
||||
PAGE).getContent().get(0);
|
||||
assertThat(action).as("action should not be null").isNotNull();
|
||||
return action;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Simple offline deployment of a distribution set to a list of targets. Verifies that offline assigment "
|
||||
+ "is correctly executed for targets that do not have a running update already. Those are ignored.")
|
||||
@@ -617,20 +637,6 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertDsExclusivelyAssignedToTargets(targets, ds1.getId(), STATE_ACTIVE, RUNNING);
|
||||
}
|
||||
|
||||
private void assertDsExclusivelyAssignedToTargets(final List<Target> targets, final long dsId, final boolean active,
|
||||
final Status status) {
|
||||
final List<Action> assignment = findActionsByDistributionSet(PAGE, dsId).getContent();
|
||||
final String currentUsername = tenantAware.getCurrentUsername();
|
||||
|
||||
assertThat(assignment).hasSize(10).allMatch(action -> action.isActive() == active)
|
||||
.as("Is assigned to DS " + dsId).allMatch(action -> action.getDistributionSet().getId().equals(dsId))
|
||||
.as("State is " + status).allMatch(action -> action.getStatus() == status)
|
||||
.as("Initiated by " + currentUsername).allMatch(a -> a.getInitiatedBy().equals(currentUsername));
|
||||
final long[] targetIds = targets.stream().mapToLong(Target::getId).toArray();
|
||||
assertThat(targetIds).as("All targets represented in assignment").containsExactlyInAnyOrder(
|
||||
assignment.stream().mapToLong(action -> action.getTarget().getId()).toArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Assign multiple DSs to a single Target in one request in multiassignment mode.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@@ -699,20 +705,6 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
});
|
||||
}
|
||||
|
||||
protected List<DeploymentRequest> createAssignmentRequests(final Collection<DistributionSet> distributionSets,
|
||||
final Collection<Target> targets, final int weight) {
|
||||
return createAssignmentRequests(distributionSets, targets, weight, false);
|
||||
}
|
||||
|
||||
protected List<DeploymentRequest> createAssignmentRequests(final Collection<DistributionSet> distributionSets,
|
||||
final Collection<Target> targets, final int weight, final boolean confirmationRequired) {
|
||||
final List<DeploymentRequest> deploymentRequests = new ArrayList<>();
|
||||
distributionSets.forEach(ds -> targets.forEach(target -> deploymentRequests
|
||||
.add(DeploymentManagement.deploymentRequest(target.getControllerId(), ds.getId()).setWeight(weight)
|
||||
.setConfirmationRequired(confirmationRequired).build())));
|
||||
return deploymentRequests;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("A Request resulting in multiple assignments to a single target is only allowed when multiassignment is enabled.")
|
||||
void multipleAssignmentsToTargetOnlyAllowedInMultiAssignMode() {
|
||||
@@ -741,7 +733,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
final DistributionSet createdDs = testdataFactory.createDistributionSet();
|
||||
|
||||
final List<String> knownTargetIds = new ArrayList<>();
|
||||
knownTargetIds.add( "1");
|
||||
knownTargetIds.add("1");
|
||||
knownTargetIds.add("2");
|
||||
testdataFactory.createTargets(knownTargetIds.toArray(new String[0]));
|
||||
|
||||
@@ -898,16 +890,6 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
});
|
||||
}
|
||||
|
||||
private List<DistributionSetAssignmentResult> assignDistributionSetToTargets(final DistributionSet distributionSet,
|
||||
final Iterable<String> targetIds, final boolean confirmationRequired) {
|
||||
final List<DeploymentRequest> deploymentRequests = new ArrayList<>();
|
||||
for (final String controllerId : targetIds) {
|
||||
deploymentRequests.add(new DeploymentRequest(controllerId, distributionSet.getId(), ActionType.FORCED, 0,
|
||||
null, null, null, null, confirmationRequired));
|
||||
}
|
||||
return deploymentManagement.assignDistributionSets(deploymentRequests);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Duplicate Assignments are removed from a request when multiassignment is disabled, otherwise not")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@@ -936,10 +918,6 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
.isEqualTo(1);
|
||||
}
|
||||
|
||||
private int getResultingActionCount(final List<DistributionSetAssignmentResult> results) {
|
||||
return results.stream().map(DistributionSetAssignmentResult::getTotal).reduce(0, Integer::sum);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("An assignment request is not accepted if it would lead to a target exceeding the max actions per target quota.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@@ -1033,7 +1011,6 @@ 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.
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
@Description("Simple deployment or distribution set to target assignment test.")
|
||||
@@ -1319,7 +1296,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(allFoundDS.size()).as("no ds should be founded").isZero();
|
||||
|
||||
assertThat(distributionSetRepository.findAll(SpecificationsBuilder.combineWithAnd(Arrays
|
||||
.asList(DistributionSetSpecification.isDeleted(true), DistributionSetSpecification.isCompleted(true))),
|
||||
.asList(DistributionSetSpecification.isDeleted(true), DistributionSetSpecification.isCompleted(true))),
|
||||
PAGE).getContent()).as("wrong size of founded ds").hasSize(noOfDistributionSets);
|
||||
|
||||
for (final DistributionSet ds : deploymentResult.getDistributionSets()) {
|
||||
@@ -1335,7 +1312,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
allFoundDS = distributionSetManagement.findByCompleted(pageRequest, true).getContent();
|
||||
assertThat(allFoundDS.size()).as("no ds should be founded").isZero();
|
||||
assertThat(distributionSetRepository.findAll(SpecificationsBuilder.combineWithAnd(Arrays
|
||||
.asList(DistributionSetSpecification.isDeleted(true), DistributionSetSpecification.isCompleted(true))),
|
||||
.asList(DistributionSetSpecification.isDeleted(true), DistributionSetSpecification.isCompleted(true))),
|
||||
PAGE).getContent()).as("wrong size of founded ds").hasSize(noOfDistributionSets);
|
||||
|
||||
}
|
||||
@@ -1549,30 +1526,6 @@ 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));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verify that the DistributionSet assignments work for multiple targets of the same target type within the same request.")
|
||||
void verifyDSAssignmentForMultipleTargetsWithSameTargetType() {
|
||||
@@ -1661,6 +1614,52 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
.isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequests));
|
||||
}
|
||||
|
||||
private JpaAction assignSet(final Target target, final DistributionSet ds) {
|
||||
assignDistributionSet(ds.getId(), target.getControllerId());
|
||||
implicitLock(ds);
|
||||
assertThat(targetManagement.getByControllerID(target.getControllerId()).get().getUpdateStatus())
|
||||
.as("wrong update status").isEqualTo(TargetUpdateStatus.PENDING);
|
||||
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId())).as("wrong assigned ds")
|
||||
.contains(ds);
|
||||
final JpaAction action = actionRepository
|
||||
.findAll(
|
||||
(root, query, cb) ->
|
||||
cb.and(
|
||||
cb.equal(root.get(JpaAction_.target).get(JpaTarget_.id), target.getId()),
|
||||
cb.equal(root.get(JpaAction_.distributionSet).get(JpaDistributionSet_.id), ds.getId())),
|
||||
PAGE).getContent().get(0);
|
||||
assertThat(action).as("action should not be null").isNotNull();
|
||||
return action;
|
||||
}
|
||||
|
||||
private void assertDsExclusivelyAssignedToTargets(final List<Target> targets, final long dsId, final boolean active,
|
||||
final Status status) {
|
||||
final List<Action> assignment = findActionsByDistributionSet(PAGE, dsId).getContent();
|
||||
final String currentUsername = tenantAware.getCurrentUsername();
|
||||
|
||||
assertThat(assignment).hasSize(10).allMatch(action -> action.isActive() == active)
|
||||
.as("Is assigned to DS " + dsId).allMatch(action -> action.getDistributionSet().getId().equals(dsId))
|
||||
.as("State is " + status).allMatch(action -> action.getStatus() == status)
|
||||
.as("Initiated by " + currentUsername).allMatch(a -> a.getInitiatedBy().equals(currentUsername));
|
||||
final long[] targetIds = targets.stream().mapToLong(Target::getId).toArray();
|
||||
assertThat(targetIds).as("All targets represented in assignment").containsExactlyInAnyOrder(
|
||||
assignment.stream().mapToLong(action -> action.getTarget().getId()).toArray());
|
||||
}
|
||||
|
||||
private List<DistributionSetAssignmentResult> assignDistributionSetToTargets(final DistributionSet distributionSet,
|
||||
final Iterable<String> targetIds, final boolean confirmationRequired) {
|
||||
final List<DeploymentRequest> deploymentRequests = new ArrayList<>();
|
||||
for (final String controllerId : targetIds) {
|
||||
deploymentRequests.add(new DeploymentRequest(controllerId, distributionSet.getId(), ActionType.FORCED, 0,
|
||||
null, null, null, null, confirmationRequired));
|
||||
}
|
||||
return deploymentManagement.assignDistributionSets(deploymentRequests);
|
||||
}
|
||||
|
||||
private int getResultingActionCount(final List<DistributionSetAssignmentResult> results) {
|
||||
return results.stream().map(DistributionSetAssignmentResult::getTotal).reduce(0, Integer::sum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper methods that creates 2 lists of targets and a list of distribution
|
||||
* sets.
|
||||
@@ -1668,18 +1667,12 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
* <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
|
||||
* @param noOfUndeployedTargets
|
||||
* number of targets which remain undeployed
|
||||
* @param deployedTargetPrefix
|
||||
* prefix to be used as target controller prefix
|
||||
* @param noOfDeployedTargets
|
||||
* number of targets to which the created distribution sets assigned
|
||||
* @param noOfDistributionSets
|
||||
* number of distribution sets
|
||||
* @param distributionSetPrefix
|
||||
* prefix for the created distribution sets
|
||||
* @param undeployedTargetPrefix prefix to be used as target controller prefix
|
||||
* @param noOfUndeployedTargets number of targets which remain undeployed
|
||||
* @param deployedTargetPrefix prefix to be used as target controller prefix
|
||||
* @param noOfDeployedTargets number of targets to which the created distribution sets assigned
|
||||
* @param noOfDistributionSets number of distribution sets
|
||||
* @param distributionSetPrefix prefix for the created distribution sets
|
||||
* @return the {@link DeploymentResult} containing all created targets, the
|
||||
* distribution sets, the corresponding IDs for later evaluation in
|
||||
* tests
|
||||
@@ -1720,6 +1713,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
|
||||
private static class DeploymentResult {
|
||||
|
||||
final List<Long> deployedTargetIDs = new ArrayList<>();
|
||||
final List<Long> undeployedTargetIDs = new ArrayList<>();
|
||||
final List<Long> distributionSetIDs = new ArrayList<>();
|
||||
|
||||
@@ -15,9 +15,11 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
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.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||
import org.eclipse.hawkbit.repository.jpa.specifications.ActionSpecifications;
|
||||
@@ -34,16 +36,11 @@ 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;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
/**
|
||||
* Test class testing the functionality of invalidating a
|
||||
* {@link DistributionSet}
|
||||
*
|
||||
*/
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("Distribution set invalidation management")
|
||||
@@ -104,7 +101,7 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
|
||||
// if status is pending, the assignment has not been canceled
|
||||
assertThat(
|
||||
targetRepository.findById(invalidationTestData.getTargets().get(0).getId()).get().getUpdateStatus())
|
||||
.isEqualTo(TargetUpdateStatus.PENDING);
|
||||
.isEqualTo(TargetUpdateStatus.PENDING);
|
||||
assertThat(findActionsByTarget(target).size()).isEqualTo(1);
|
||||
assertThat(findActionsByTarget(target).get(0).getStatus()).isEqualTo(Status.RUNNING);
|
||||
}
|
||||
@@ -140,17 +137,6 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
@@ -196,8 +182,8 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
|
||||
void verifyInvalidateInvalidatedDistributionSetDontThrowsException() {
|
||||
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
|
||||
distributionSetInvalidationManagement.invalidateDistributionSet(
|
||||
new DistributionSetInvalidation(Collections.singletonList(distributionSet.getId()),
|
||||
CancelationType.SOFT, true));
|
||||
new DistributionSetInvalidation(Collections.singletonList(distributionSet.getId()),
|
||||
CancelationType.SOFT, true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -234,7 +220,7 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
|
||||
false));
|
||||
assertThat(
|
||||
distributionSetRepository.findById(invalidationTestData.getDistributionSet().getId()).get().isValid())
|
||||
.isFalse();
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -249,7 +235,18 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
|
||||
true));
|
||||
assertThat(
|
||||
distributionSetRepository.findById(invalidationTestData.getDistributionSet().getId()).get().isValid())
|
||||
.isFalse();
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
private InvalidationTestData createInvalidationTestData(final String testName) {
|
||||
@@ -264,7 +261,20 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
|
||||
return new InvalidationTestData(distributionSet, targets, targetFilterQuery, 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);
|
||||
}
|
||||
|
||||
private List<JpaAction> findActionsByTarget(@Param("target") Target target) { // order by id ?
|
||||
return actionRepository.findAll(ActionSpecifications.byTargetControllerId(target.getControllerId()));
|
||||
}
|
||||
|
||||
private static class InvalidationTestData {
|
||||
|
||||
private final DistributionSet distributionSet;
|
||||
private final List<Target> targets;
|
||||
private final TargetFilterQuery targetFilterQuery;
|
||||
@@ -295,16 +305,4 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
|
||||
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);
|
||||
}
|
||||
|
||||
private List<JpaAction> findActionsByTarget(@Param("target") Target target) { // order by id ?
|
||||
return actionRepository.findAll(ActionSpecifications.byTargetControllerId(target.getControllerId()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,10 @@ import java.util.stream.Stream;
|
||||
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.assertj.core.api.Condition;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
@@ -74,20 +78,16 @@ import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
/**
|
||||
* {@link DistributionSetManagement} tests.
|
||||
*
|
||||
*/
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("DistributionSet Management")
|
||||
class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
public static final String TAG1_NAME = "Tag1";
|
||||
@Autowired
|
||||
RepositoryProperties repositoryProperties;
|
||||
|
||||
@Test
|
||||
@Description("Verifies that management get access react as specified on calls for non existing entities by means "
|
||||
@@ -213,84 +213,6 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
||||
createAndUpdateDistributionSetWithInvalidVersion(set);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateDistributionSetWithInvalidDescription(final DistributionSet set) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too long description should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
||||
.version("a").description(RandomStringUtils.randomAlphanumeric(513))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with invalid description should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
||||
.version("a").description(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too long description should not be updated")
|
||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||
.description(RandomStringUtils.randomAlphanumeric(513))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with invalid characters should not be updated").isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).description(INVALID_TEXT_HTML)));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateDistributionSetWithInvalidName(final DistributionSet set) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too long name should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().version("a")
|
||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too short name should not be created").isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().version("a").name("")));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with invalid characters in name should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().version("a").name(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too long name should not be updated")
|
||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with invalid characters should not be updated").isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).name(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too short name should not be updated").isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).name("")));
|
||||
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateDistributionSetWithInvalidVersion(final DistributionSet set) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too long version should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
||||
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too short version should not be created").isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().name("a").version("")));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too long version should not be updated")
|
||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too short version should not be updated").isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).version("")));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that it is not possible to create a DS that already exists (unique constraint is on name,version for DS).")
|
||||
void createDuplicateDistributionSetsFailsWithException() {
|
||||
@@ -333,6 +255,7 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
||||
final List<DistributionSet> sets = distributionSetManagement.create(creates);
|
||||
|
||||
assertThat(sets).as("Type should be equal to default type of tenant").are(new Condition<DistributionSet>() {
|
||||
|
||||
@Override
|
||||
public boolean matches(final DistributionSet value) {
|
||||
return value.getType().equals(systemManagement.getTenantMetadata().getDefaultDsType());
|
||||
@@ -484,7 +407,7 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
||||
// update data
|
||||
assertThatThrownBy(
|
||||
() -> distributionSetManagement.assignSoftwareModules(set.getId(), Set.of(module.getId())))
|
||||
.isInstanceOf(UnsupportedSoftwareModuleForThisDistributionSetException.class);
|
||||
.isInstanceOf(UnsupportedSoftwareModuleForThisDistributionSetException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -772,223 +695,6 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
||||
validateDeletedAndCompletedAndTypeAndSearchTextAndTag(dsGroup2, dsTagA, dsGroup2Prefix);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateFindAll(final List<DistributionSet> expectedDistributionsets) {
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder(), expectedDistributionsets);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateDeleted(final DistributionSet deletedDistributionSet, final int notDeletedSize) {
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().isDeleted(Boolean.TRUE),
|
||||
singletonList(deletedDistributionSet));
|
||||
|
||||
assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
||||
DistributionSetFilter.builder().isDeleted(Boolean.FALSE), notDeletedSize, deletedDistributionSet);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateCompleted(final DistributionSet dsIncomplete, final int completedSize) {
|
||||
|
||||
assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
||||
DistributionSetFilter.builder().isComplete(Boolean.TRUE), completedSize, dsIncomplete);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().isComplete(Boolean.FALSE), singletonList(dsIncomplete));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateType(final DistributionSetType newType, final DistributionSet dsNewType,
|
||||
final int standardDsTypeSize) {
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().typeId(newType.getId()),
|
||||
singletonList(dsNewType));
|
||||
assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
||||
DistributionSetFilter.builder().typeId(standardDsType.getId()), standardDsTypeSize, dsNewType);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateSearchText(final List<DistributionSet> allDistributionSets, final String dsNamePrefix) {
|
||||
|
||||
final List<DistributionSet> withTestNamePrefix = allDistributionSets.stream()
|
||||
.filter(ds -> ds.getName().startsWith(dsNamePrefix)).collect(Collectors.toList());
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().searchText(dsNamePrefix),
|
||||
withTestNamePrefix);
|
||||
|
||||
final List<DistributionSet> withTestNameExact = withTestNamePrefix.stream()
|
||||
.filter(ds -> ds.getName().equals(dsNamePrefix)).collect(Collectors.toList());
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().searchText(dsNamePrefix + ":"), withTestNameExact);
|
||||
|
||||
final List<DistributionSet> withTestNameExactAndVersionPrefix = withTestNameExact.stream()
|
||||
.filter(ds -> ds.getVersion().startsWith("1")).collect(Collectors.toList());
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().searchText(dsNamePrefix + ":1"),
|
||||
withTestNameExactAndVersionPrefix);
|
||||
|
||||
final List<DistributionSet> dsWithExactNameAndVersion = withTestNameExactAndVersionPrefix.stream()
|
||||
.filter(ds -> ds.getVersion().equals("1.0.0")).collect(Collectors.toList());
|
||||
assertThat(dsWithExactNameAndVersion).hasSize(1);
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().searchText(dsNamePrefix + ":1.0.0"), dsWithExactNameAndVersion);
|
||||
|
||||
final List<DistributionSet> withVersionPrefix = allDistributionSets.stream()
|
||||
.filter(ds -> ds.getVersion().startsWith("1.0.")).collect(Collectors.toList());
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().searchText(":1.0."),
|
||||
withVersionPrefix);
|
||||
|
||||
final List<DistributionSet> withVersionExact = withVersionPrefix.stream()
|
||||
.filter(ds -> ds.getVersion().equals("1.0.0")).collect(Collectors.toList());
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().searchText(":1.0.0"),
|
||||
withVersionExact);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().searchText(":"),
|
||||
allDistributionSets);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().searchText(" : "),
|
||||
allDistributionSets);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateTags(final DistributionSetTag dsTagA, final DistributionSetTag dsTagB,
|
||||
final DistributionSetTag dsTagC, final List<DistributionSet> dsWithTagA,
|
||||
final List<DistributionSet> dsWithTagB) {
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().tagNames(singletonList(dsTagA.getName())), dsWithTagA);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().tagNames(singletonList(dsTagB.getName())), dsWithTagB);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().tagNames(Arrays.asList(dsTagA.getName(), dsTagB.getName())),
|
||||
dsWithTagA);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().tagNames(Arrays.asList(dsTagC.getName(), dsTagB.getName())),
|
||||
dsWithTagB);
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(
|
||||
DistributionSetFilter.builder().tagNames(singletonList(dsTagC.getName())));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateDeletedAndCompleted(final List<DistributionSet> completedStandardType,
|
||||
final DistributionSet dsNewType, final DistributionSet dsDeleted) {
|
||||
|
||||
final List<DistributionSet> completedNotDeleted = new ArrayList<>(completedStandardType);
|
||||
completedNotDeleted.add(dsNewType);
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().isComplete(Boolean.TRUE).isDeleted(Boolean.FALSE),
|
||||
completedNotDeleted);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().isComplete(Boolean.TRUE).isDeleted(Boolean.TRUE),
|
||||
singletonList(dsDeleted));
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(
|
||||
DistributionSetFilter.builder().isComplete(Boolean.FALSE).isDeleted(Boolean.TRUE));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateDeletedAndCompletedAndType(final List<DistributionSet> deletedAndCompletedAndStandardType,
|
||||
final DistributionSet dsDeleted, final DistributionSetType newType, final DistributionSet dsNewType) {
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().isDeleted(Boolean.FALSE)
|
||||
.isComplete(Boolean.TRUE).typeId(standardDsType.getId()), deletedAndCompletedAndStandardType);
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().isComplete(Boolean.TRUE)
|
||||
.typeId(standardDsType.getId()).isDeleted(Boolean.TRUE), singletonList(dsDeleted));
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(DistributionSetFilter.builder().isDeleted(Boolean.TRUE)
|
||||
.isComplete(Boolean.FALSE).typeId(standardDsType.getId()));
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().isComplete(Boolean.TRUE).typeId(newType.getId()),
|
||||
singletonList(dsNewType));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateDeletedAndCompletedAndTypeAndSearchText(
|
||||
final List<DistributionSet> completedAndStandardTypeAndSearchText, final DistributionSetType newType,
|
||||
final String text) {
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().isDeleted(Boolean.FALSE)
|
||||
.isComplete(Boolean.TRUE).typeId(standardDsType.getId()).searchText(text),
|
||||
completedAndStandardTypeAndSearchText);
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(DistributionSetFilter.builder().isComplete(Boolean.TRUE)
|
||||
.isDeleted(Boolean.TRUE).typeId(standardDsType.getId()).searchText(text + ":"));
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(
|
||||
DistributionSetFilter.builder().typeId(standardDsType.getId()).searchText(text)
|
||||
.isComplete(Boolean.FALSE).isDeleted(Boolean.FALSE));
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(DistributionSetFilter.builder().typeId(newType.getId())
|
||||
.searchText(text).isComplete(Boolean.TRUE).isDeleted(Boolean.FALSE));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateDeletedAndCompletedAndTypeAndSearchText(
|
||||
final List<DistributionSet> completedAndNotDeletedStandardTypeAndFilterString,
|
||||
final DistributionSet dsDeleted, final DistributionSet dsInComplete, final DistributionSet dsNewType,
|
||||
final DistributionSetType newType, final String filterString) {
|
||||
|
||||
final List<DistributionSet> completedAndStandardTypeAndFilterString = new ArrayList<>(
|
||||
completedAndNotDeletedStandardTypeAndFilterString);
|
||||
completedAndStandardTypeAndFilterString.add(dsDeleted);
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().isComplete(Boolean.TRUE)
|
||||
.typeId(standardDsType.getId()).searchText(filterString),
|
||||
completedAndStandardTypeAndFilterString);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().isComplete(Boolean.TRUE).isDeleted(Boolean.FALSE)
|
||||
.typeId(standardDsType.getId()).searchText(filterString),
|
||||
completedAndNotDeletedStandardTypeAndFilterString);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().isComplete(Boolean.TRUE)
|
||||
.isDeleted(Boolean.TRUE).typeId(standardDsType.getId()).searchText(filterString),
|
||||
singletonList(dsDeleted));
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().typeId(standardDsType.getId()).searchText(filterString)
|
||||
.isComplete(Boolean.FALSE).isDeleted(Boolean.FALSE),
|
||||
singletonList(dsInComplete));
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().typeId(newType.getId())
|
||||
.searchText(filterString).isComplete(Boolean.TRUE).isDeleted(Boolean.FALSE),
|
||||
singletonList(dsNewType));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateDeletedAndCompletedAndTypeAndSearchTextAndTag(
|
||||
final List<DistributionSet> completedAndStandartTypeAndSearchTextAndTagA, final DistributionSetTag dsTagA,
|
||||
final String text) {
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().isComplete(Boolean.TRUE).typeId(standardDsType.getId())
|
||||
.searchText(text).tagNames(singletonList(dsTagA.getName())),
|
||||
completedAndStandartTypeAndSearchTextAndTagA);
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(DistributionSetFilter.builder()
|
||||
.typeId(standardDsType.getId()).searchText(text).tagNames(singletonList(dsTagA.getName()))
|
||||
.isComplete(Boolean.FALSE).isDeleted(Boolean.FALSE));
|
||||
}
|
||||
|
||||
private void assertThatFilterContainsOnlyGivenDistributionSets(final DistributionSetFilterBuilder filterBuilder,
|
||||
final List<DistributionSet> distributionSets) {
|
||||
final int expectedDsSize = distributionSets.size();
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, filterBuilder.build()).getContent())
|
||||
.hasSize(expectedDsSize).containsOnly(distributionSets.toArray(new DistributionSet[expectedDsSize]));
|
||||
}
|
||||
|
||||
private void assertThatFilterDoesNotContainAnyDistributionSet(final DistributionSetFilterBuilder filterBuilder) {
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, filterBuilder.build()).getContent())
|
||||
.isEmpty();
|
||||
}
|
||||
|
||||
private void assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
||||
final DistributionSetFilterBuilder filterBuilder, final int size, final DistributionSet ds) {
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, filterBuilder.build()).getContent())
|
||||
.hasSize(size).doesNotContain(ds);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Simple DS load without the related data that should be loaded lazy.")
|
||||
void findDistributionSetsWithoutLazy() {
|
||||
@@ -1097,25 +803,24 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
||||
.isEqualTo(softwareModuleCount);
|
||||
}
|
||||
|
||||
@Autowired RepositoryProperties repositoryProperties;
|
||||
@Test
|
||||
@Description("Test implicit locks for a DS and skip tags.")
|
||||
void isImplicitLockApplicableForDistributionSet() {
|
||||
final JpaDistributionSetManagement distributionSetManagement =
|
||||
(JpaDistributionSetManagement)this.distributionSetManagement;
|
||||
(JpaDistributionSetManagement) this.distributionSetManagement;
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet("ds-non-skip");
|
||||
// assert that implicit lock is applicable for non skip tags
|
||||
assertThat(distributionSetManagement.isImplicitLockApplicable(distributionSet)).isTrue();
|
||||
|
||||
assertThat(repositoryProperties.getSkipImplicitLockForTags().size()).isNotEqualTo(0);
|
||||
final List<DistributionSetTag> skipTags = distributionSetTagManagement.create(
|
||||
repositoryProperties.getSkipImplicitLockForTags().stream()
|
||||
.map(String::toLowerCase)
|
||||
// remove same in case-insensitive terms tags
|
||||
// in of case-insensitive db's it will end up as same names and constraint violation (?)
|
||||
.distinct()
|
||||
.map(skipTag -> entityFactory.tag().create().name(skipTag))
|
||||
.toList());
|
||||
repositoryProperties.getSkipImplicitLockForTags().stream()
|
||||
.map(String::toLowerCase)
|
||||
// remove same in case-insensitive terms tags
|
||||
// in of case-insensitive db's it will end up as same names and constraint violation (?)
|
||||
.distinct()
|
||||
.map(skipTag -> entityFactory.tag().create().name(skipTag))
|
||||
.toList());
|
||||
// assert that implicit lock locks for every skip tag
|
||||
skipTags.forEach(skipTag -> {
|
||||
DistributionSet distributionSetWithSkipTag =
|
||||
@@ -1324,10 +1029,14 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(distributionSetManagement.countRolloutsByStatusForDistributionSet(ds3.getId())).isEmpty();
|
||||
|
||||
Optional<Rollout> rollout = rolloutManagement.get(rollout1.getId());
|
||||
rollout.ifPresent(value -> assertThat(Rollout.RolloutStatus.valueOf(String.valueOf(distributionSetManagement.countRolloutsByStatusForDistributionSet(ds1.getId()).get(0).getName()))).isEqualTo(value.getStatus()));
|
||||
rollout.ifPresent(value -> assertThat(Rollout.RolloutStatus.valueOf(
|
||||
String.valueOf(distributionSetManagement.countRolloutsByStatusForDistributionSet(ds1.getId()).get(0).getName()))).isEqualTo(
|
||||
value.getStatus()));
|
||||
|
||||
rollout = rolloutManagement.get(rollout2.getId());
|
||||
rollout.ifPresent(value -> assertThat(Rollout.RolloutStatus.valueOf(String.valueOf(distributionSetManagement.countRolloutsByStatusForDistributionSet(ds2.getId()).get(0).getName()))).isEqualTo(value.getStatus()));
|
||||
rollout.ifPresent(value -> assertThat(Rollout.RolloutStatus.valueOf(
|
||||
String.valueOf(distributionSetManagement.countRolloutsByStatusForDistributionSet(ds2.getId()).get(0).getName()))).isEqualTo(
|
||||
value.getStatus()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1366,6 +1075,301 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(distributionSetManagement.countAutoAssignmentsForDistributionSet(ds2.getId())).isNull();
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateDistributionSetWithInvalidDescription(final DistributionSet set) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too long description should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
||||
.version("a").description(RandomStringUtils.randomAlphanumeric(513))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with invalid description should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
||||
.version("a").description(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too long description should not be updated")
|
||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||
.description(RandomStringUtils.randomAlphanumeric(513))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with invalid characters should not be updated").isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).description(INVALID_TEXT_HTML)));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateDistributionSetWithInvalidName(final DistributionSet set) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too long name should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().version("a")
|
||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too short name should not be created").isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().version("a").name("")));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with invalid characters in name should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().version("a").name(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too long name should not be updated")
|
||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with invalid characters should not be updated").isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).name(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too short name should not be updated").isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).name("")));
|
||||
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateDistributionSetWithInvalidVersion(final DistributionSet set) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too long version should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
||||
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too short version should not be created").isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().name("a").version("")));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too long version should not be updated")
|
||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("entity with too short version should not be updated").isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).version("")));
|
||||
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateFindAll(final List<DistributionSet> expectedDistributionsets) {
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder(), expectedDistributionsets);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateDeleted(final DistributionSet deletedDistributionSet, final int notDeletedSize) {
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().isDeleted(Boolean.TRUE),
|
||||
singletonList(deletedDistributionSet));
|
||||
|
||||
assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
||||
DistributionSetFilter.builder().isDeleted(Boolean.FALSE), notDeletedSize, deletedDistributionSet);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateCompleted(final DistributionSet dsIncomplete, final int completedSize) {
|
||||
|
||||
assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
||||
DistributionSetFilter.builder().isComplete(Boolean.TRUE), completedSize, dsIncomplete);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().isComplete(Boolean.FALSE), singletonList(dsIncomplete));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateType(final DistributionSetType newType, final DistributionSet dsNewType,
|
||||
final int standardDsTypeSize) {
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().typeId(newType.getId()),
|
||||
singletonList(dsNewType));
|
||||
assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
||||
DistributionSetFilter.builder().typeId(standardDsType.getId()), standardDsTypeSize, dsNewType);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateSearchText(final List<DistributionSet> allDistributionSets, final String dsNamePrefix) {
|
||||
|
||||
final List<DistributionSet> withTestNamePrefix = allDistributionSets.stream()
|
||||
.filter(ds -> ds.getName().startsWith(dsNamePrefix)).collect(Collectors.toList());
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().searchText(dsNamePrefix),
|
||||
withTestNamePrefix);
|
||||
|
||||
final List<DistributionSet> withTestNameExact = withTestNamePrefix.stream()
|
||||
.filter(ds -> ds.getName().equals(dsNamePrefix)).collect(Collectors.toList());
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().searchText(dsNamePrefix + ":"), withTestNameExact);
|
||||
|
||||
final List<DistributionSet> withTestNameExactAndVersionPrefix = withTestNameExact.stream()
|
||||
.filter(ds -> ds.getVersion().startsWith("1")).collect(Collectors.toList());
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().searchText(dsNamePrefix + ":1"),
|
||||
withTestNameExactAndVersionPrefix);
|
||||
|
||||
final List<DistributionSet> dsWithExactNameAndVersion = withTestNameExactAndVersionPrefix.stream()
|
||||
.filter(ds -> ds.getVersion().equals("1.0.0")).collect(Collectors.toList());
|
||||
assertThat(dsWithExactNameAndVersion).hasSize(1);
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().searchText(dsNamePrefix + ":1.0.0"), dsWithExactNameAndVersion);
|
||||
|
||||
final List<DistributionSet> withVersionPrefix = allDistributionSets.stream()
|
||||
.filter(ds -> ds.getVersion().startsWith("1.0.")).collect(Collectors.toList());
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().searchText(":1.0."),
|
||||
withVersionPrefix);
|
||||
|
||||
final List<DistributionSet> withVersionExact = withVersionPrefix.stream()
|
||||
.filter(ds -> ds.getVersion().equals("1.0.0")).collect(Collectors.toList());
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().searchText(":1.0.0"),
|
||||
withVersionExact);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().searchText(":"),
|
||||
allDistributionSets);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().searchText(" : "),
|
||||
allDistributionSets);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateTags(final DistributionSetTag dsTagA, final DistributionSetTag dsTagB,
|
||||
final DistributionSetTag dsTagC, final List<DistributionSet> dsWithTagA,
|
||||
final List<DistributionSet> dsWithTagB) {
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().tagNames(singletonList(dsTagA.getName())), dsWithTagA);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().tagNames(singletonList(dsTagB.getName())), dsWithTagB);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().tagNames(Arrays.asList(dsTagA.getName(), dsTagB.getName())),
|
||||
dsWithTagA);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().tagNames(Arrays.asList(dsTagC.getName(), dsTagB.getName())),
|
||||
dsWithTagB);
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(
|
||||
DistributionSetFilter.builder().tagNames(singletonList(dsTagC.getName())));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateDeletedAndCompleted(final List<DistributionSet> completedStandardType,
|
||||
final DistributionSet dsNewType, final DistributionSet dsDeleted) {
|
||||
|
||||
final List<DistributionSet> completedNotDeleted = new ArrayList<>(completedStandardType);
|
||||
completedNotDeleted.add(dsNewType);
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().isComplete(Boolean.TRUE).isDeleted(Boolean.FALSE),
|
||||
completedNotDeleted);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().isComplete(Boolean.TRUE).isDeleted(Boolean.TRUE),
|
||||
singletonList(dsDeleted));
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(
|
||||
DistributionSetFilter.builder().isComplete(Boolean.FALSE).isDeleted(Boolean.TRUE));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateDeletedAndCompletedAndType(final List<DistributionSet> deletedAndCompletedAndStandardType,
|
||||
final DistributionSet dsDeleted, final DistributionSetType newType, final DistributionSet dsNewType) {
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().isDeleted(Boolean.FALSE)
|
||||
.isComplete(Boolean.TRUE).typeId(standardDsType.getId()), deletedAndCompletedAndStandardType);
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().isComplete(Boolean.TRUE)
|
||||
.typeId(standardDsType.getId()).isDeleted(Boolean.TRUE), singletonList(dsDeleted));
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(DistributionSetFilter.builder().isDeleted(Boolean.TRUE)
|
||||
.isComplete(Boolean.FALSE).typeId(standardDsType.getId()));
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().isComplete(Boolean.TRUE).typeId(newType.getId()),
|
||||
singletonList(dsNewType));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateDeletedAndCompletedAndTypeAndSearchText(
|
||||
final List<DistributionSet> completedAndStandardTypeAndSearchText, final DistributionSetType newType,
|
||||
final String text) {
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().isDeleted(Boolean.FALSE)
|
||||
.isComplete(Boolean.TRUE).typeId(standardDsType.getId()).searchText(text),
|
||||
completedAndStandardTypeAndSearchText);
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(DistributionSetFilter.builder().isComplete(Boolean.TRUE)
|
||||
.isDeleted(Boolean.TRUE).typeId(standardDsType.getId()).searchText(text + ":"));
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(
|
||||
DistributionSetFilter.builder().typeId(standardDsType.getId()).searchText(text)
|
||||
.isComplete(Boolean.FALSE).isDeleted(Boolean.FALSE));
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(DistributionSetFilter.builder().typeId(newType.getId())
|
||||
.searchText(text).isComplete(Boolean.TRUE).isDeleted(Boolean.FALSE));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateDeletedAndCompletedAndTypeAndSearchText(
|
||||
final List<DistributionSet> completedAndNotDeletedStandardTypeAndFilterString,
|
||||
final DistributionSet dsDeleted, final DistributionSet dsInComplete, final DistributionSet dsNewType,
|
||||
final DistributionSetType newType, final String filterString) {
|
||||
|
||||
final List<DistributionSet> completedAndStandardTypeAndFilterString = new ArrayList<>(
|
||||
completedAndNotDeletedStandardTypeAndFilterString);
|
||||
completedAndStandardTypeAndFilterString.add(dsDeleted);
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().isComplete(Boolean.TRUE)
|
||||
.typeId(standardDsType.getId()).searchText(filterString),
|
||||
completedAndStandardTypeAndFilterString);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().isComplete(Boolean.TRUE).isDeleted(Boolean.FALSE)
|
||||
.typeId(standardDsType.getId()).searchText(filterString),
|
||||
completedAndNotDeletedStandardTypeAndFilterString);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().isComplete(Boolean.TRUE)
|
||||
.isDeleted(Boolean.TRUE).typeId(standardDsType.getId()).searchText(filterString),
|
||||
singletonList(dsDeleted));
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().typeId(standardDsType.getId()).searchText(filterString)
|
||||
.isComplete(Boolean.FALSE).isDeleted(Boolean.FALSE),
|
||||
singletonList(dsInComplete));
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().typeId(newType.getId())
|
||||
.searchText(filterString).isComplete(Boolean.TRUE).isDeleted(Boolean.FALSE),
|
||||
singletonList(dsNewType));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateDeletedAndCompletedAndTypeAndSearchTextAndTag(
|
||||
final List<DistributionSet> completedAndStandartTypeAndSearchTextAndTagA, final DistributionSetTag dsTagA,
|
||||
final String text) {
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
DistributionSetFilter.builder().isComplete(Boolean.TRUE).typeId(standardDsType.getId())
|
||||
.searchText(text).tagNames(singletonList(dsTagA.getName())),
|
||||
completedAndStandartTypeAndSearchTextAndTagA);
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(DistributionSetFilter.builder()
|
||||
.typeId(standardDsType.getId()).searchText(text).tagNames(singletonList(dsTagA.getName()))
|
||||
.isComplete(Boolean.FALSE).isDeleted(Boolean.FALSE));
|
||||
}
|
||||
|
||||
private void assertThatFilterContainsOnlyGivenDistributionSets(final DistributionSetFilterBuilder filterBuilder,
|
||||
final List<DistributionSet> distributionSets) {
|
||||
final int expectedDsSize = distributionSets.size();
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, filterBuilder.build()).getContent())
|
||||
.hasSize(expectedDsSize).containsOnly(distributionSets.toArray(new DistributionSet[expectedDsSize]));
|
||||
}
|
||||
|
||||
private void assertThatFilterDoesNotContainAnyDistributionSet(final DistributionSetFilterBuilder filterBuilder) {
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, filterBuilder.build()).getContent())
|
||||
.isEmpty();
|
||||
}
|
||||
|
||||
private void assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
||||
final DistributionSetFilterBuilder filterBuilder, final int size, final DistributionSet ds) {
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, filterBuilder.build()).getContent())
|
||||
.hasSize(size).doesNotContain(ds);
|
||||
}
|
||||
|
||||
// can be removed with java-11
|
||||
private <T> T getOrThrow(final Optional<T> opt) {
|
||||
return opt.orElseThrow(NoSuchElementException::new);
|
||||
|
||||
@@ -22,6 +22,10 @@ import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetTagManagement;
|
||||
import org.eclipse.hawkbit.repository.builder.TagCreate;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagUpdatedEvent;
|
||||
@@ -33,17 +37,10 @@ import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetFilter;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.model.Tag;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.test.matcher.Expect;
|
||||
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
/**
|
||||
@@ -53,6 +50,8 @@ import org.springframework.data.domain.Pageable;
|
||||
@Story("DistributionSet Tag Management")
|
||||
public class DistributionSetTagManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
private static final Random RND = new Random();
|
||||
|
||||
@Test
|
||||
@Description("Verifies that management get access reacts as specfied on calls for non existing entities by means "
|
||||
+ "of Optional not present.")
|
||||
@@ -137,17 +136,6 @@ public class DistributionSetTagManagementTest extends AbstractJpaIntegrationTest
|
||||
Stream.of(dsCs, dsACs, dsBCs, dsABCs));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyExpectedFilteredDistributionSets(final DistributionSetFilter.DistributionSetFilterBuilder distributionSetFilterBuilder,
|
||||
final Stream<Collection<DistributionSet>> expectedFilteredDistributionSets) {
|
||||
final Collection<Long> retrievedFilteredDsIds = distributionSetManagement
|
||||
.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build()).stream()
|
||||
.map(DistributionSet::getId).collect(Collectors.toList());
|
||||
final Collection<Long> expectedFilteredDsIds = expectedFilteredDistributionSets.flatMap(Collection::stream)
|
||||
.map(DistributionSet::getId).collect(Collectors.toList());
|
||||
assertThat(retrievedFilteredDsIds).hasSameElementsAs(expectedFilteredDsIds);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies assign/unassign.")
|
||||
public void assignAndUnassignDistributionSetTags() {
|
||||
@@ -162,7 +150,9 @@ public class DistributionSetTagManagementTest extends AbstractJpaIntegrationTest
|
||||
assertThat(result).size().isEqualTo(20);
|
||||
assertThat(result).containsAll(distributionSetManagement
|
||||
.get(groupA.stream().map(DistributionSet::getId).collect(Collectors.toList())));
|
||||
assertThat(distributionSetManagement.findByTag(Pageable.unpaged(), tag.getId()).getContent().stream().map(DistributionSet::getId).sorted().toList())
|
||||
assertThat(
|
||||
distributionSetManagement.findByTag(Pageable.unpaged(), tag.getId()).getContent().stream().map(DistributionSet::getId).sorted()
|
||||
.toList())
|
||||
.isEqualTo(groupA.stream().map(DistributionSet::getId).sorted().toList());
|
||||
|
||||
final Collection<DistributionSet> groupAB = concat(groupA, groupB);
|
||||
@@ -171,7 +161,9 @@ public class DistributionSetTagManagementTest extends AbstractJpaIntegrationTest
|
||||
assertThat(result).size().isEqualTo(40);
|
||||
assertThat(result).containsAll(distributionSetManagement
|
||||
.get(groupAB.stream().map(DistributionSet::getId).collect(Collectors.toList())));
|
||||
assertThat(distributionSetManagement.findByTag(Pageable.unpaged(), tag.getId()).getContent().stream().map(DistributionSet::getId).sorted().toList())
|
||||
assertThat(
|
||||
distributionSetManagement.findByTag(Pageable.unpaged(), tag.getId()).getContent().stream().map(DistributionSet::getId).sorted()
|
||||
.toList())
|
||||
.isEqualTo(groupAB.stream().map(DistributionSet::getId).sorted().toList());
|
||||
|
||||
// toggle A+B -> both unassigned
|
||||
@@ -182,7 +174,6 @@ public class DistributionSetTagManagementTest extends AbstractJpaIntegrationTest
|
||||
assertThat(distributionSetManagement.findByTag(Pageable.unpaged(), tag.getId()).getContent()).isEmpty();
|
||||
}
|
||||
|
||||
private static final Random RND = new Random();
|
||||
@Test
|
||||
@Description("Verifies that tagging of set containing missing DS throws meaningful and correct exception.")
|
||||
public void failOnMissingDs() {
|
||||
@@ -312,6 +303,17 @@ public class DistributionSetTagManagementTest extends AbstractJpaIntegrationTest
|
||||
assertThat(distributionSetTagRepository.findAll()).as("Wrong size of tags created").hasSize(tags.size());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyExpectedFilteredDistributionSets(final DistributionSetFilter.DistributionSetFilterBuilder distributionSetFilterBuilder,
|
||||
final Stream<Collection<DistributionSet>> expectedFilteredDistributionSets) {
|
||||
final Collection<Long> retrievedFilteredDsIds = distributionSetManagement
|
||||
.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build()).stream()
|
||||
.map(DistributionSet::getId).collect(Collectors.toList());
|
||||
final Collection<Long> expectedFilteredDsIds = expectedFilteredDistributionSets.flatMap(Collection::stream)
|
||||
.map(DistributionSet::getId).collect(Collectors.toList());
|
||||
assertThat(retrievedFilteredDsIds).hasSameElementsAs(expectedFilteredDsIds);
|
||||
}
|
||||
|
||||
private List<DistributionSetTag> createDsSetsWithTags() {
|
||||
final Collection<DistributionSet> sets = testdataFactory.createDistributionSets(20);
|
||||
final Iterable<DistributionSetTag> tags = testdataFactory.createDistributionSetTags(20);
|
||||
|
||||
@@ -21,8 +21,11 @@ import java.util.Set;
|
||||
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
import org.eclipse.hawkbit.repository.builder.SoftwareModuleTypeCreate;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent;
|
||||
@@ -42,18 +45,13 @@ import org.eclipse.hawkbit.repository.test.matcher.Expect;
|
||||
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
/**
|
||||
* {@link DistributionSetManagement} tests.
|
||||
*
|
||||
*/
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("DistributionSet Management")
|
||||
public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Verifies that management get access react as specfied on calls for non existing entities by means "
|
||||
+ "of Optional not present.")
|
||||
@@ -77,13 +75,13 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
|
||||
softwareModuleTypes), "DistributionSetType");
|
||||
final List<Long> notExistingSwModuleTypeIds = Collections.singletonList(NOT_EXIST_IDL);
|
||||
verifyThrownExceptionBy(() -> distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(
|
||||
testdataFactory.findOrCreateDistributionSetType("xxx", "xxx").getId(), notExistingSwModuleTypeIds),
|
||||
testdataFactory.findOrCreateDistributionSetType("xxx", "xxx").getId(), notExistingSwModuleTypeIds),
|
||||
"SoftwareModuleType");
|
||||
|
||||
verifyThrownExceptionBy(() -> distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(NOT_EXIST_IDL,
|
||||
softwareModuleTypes), "DistributionSetType");
|
||||
verifyThrownExceptionBy(() -> distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(
|
||||
testdataFactory.findOrCreateDistributionSetType("xxx", "xxx").getId(), notExistingSwModuleTypeIds),
|
||||
testdataFactory.findOrCreateDistributionSetType("xxx", "xxx").getId(), notExistingSwModuleTypeIds),
|
||||
"SoftwareModuleType");
|
||||
|
||||
verifyThrownExceptionBy(() -> distributionSetTypeManagement.delete(NOT_EXIST_IDL), "DistributionSetType");
|
||||
@@ -106,96 +104,6 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
|
||||
createAndUpdateDistributionSetWithInvalidVersion(set);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateDistributionSetWithInvalidDescription(final DistributionSet set) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with too long description should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
||||
.version("a").description(RandomStringUtils.randomAlphanumeric(513))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set invalid description text should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
||||
.version("a").description(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with too long description should not be updated")
|
||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||
.description(RandomStringUtils.randomAlphanumeric(513))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with invalid description should not be updated").isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).description(INVALID_TEXT_HTML)));
|
||||
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateDistributionSetWithInvalidName(final DistributionSet set) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as("set with too long name should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().version("a")
|
||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as("set with invalid name should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().version("a").name(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with too short name should not be created").isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().version("a").name("")));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as("set with null name should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().version("a").name(null)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as("set with too long name should not be updated")
|
||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as("set with invalid name should not be updated")
|
||||
.isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).name(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with too short name should not be updated").isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).name("")));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateDistributionSetWithInvalidVersion(final DistributionSet set) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with too long version should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
||||
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with invalid version should not be created").isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().name("a").version(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with too short version should not be created").isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().name("a").version("")));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as("set with null version should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().name("a").version(null)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with too long version should not be updated")
|
||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with invalid version should not be updated").isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).version(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with too short version should not be updated").isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).version("")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Tests the successful module update of unused distribution set type which is in fact allowed.")
|
||||
public void updateUnassignedDistributionSetTypeModules() {
|
||||
@@ -290,16 +198,7 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
|
||||
|
||||
assertThatThrownBy(() -> distributionSetTypeManagement
|
||||
.assignMandatorySoftwareModuleTypes(nonUpdatableType.getId(), Set.of(osType.getId())))
|
||||
.isInstanceOf(EntityReadOnlyException.class);
|
||||
}
|
||||
|
||||
private DistributionSetType createDistributionSetTypeUsedByDs() {
|
||||
final DistributionSetType nonUpdatableType = distributionSetTypeManagement.create(entityFactory
|
||||
.distributionSetType().create().key("updatableType").name("to be deleted").colour("test123"));
|
||||
assertThat(distributionSetTypeManagement.getByKey("updatableType").get().getMandatoryModuleTypes()).isEmpty();
|
||||
distributionSetManagement.create(entityFactory.distributionSet().create().name("newtypesoft").version("1")
|
||||
.type(nonUpdatableType.getKey()));
|
||||
return nonUpdatableType;
|
||||
.isInstanceOf(EntityReadOnlyException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -365,4 +264,103 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
|
||||
|
||||
assertThat(jpaDistributionSetType.checkComplete(distributionSet)).isFalse();
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateDistributionSetWithInvalidDescription(final DistributionSet set) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with too long description should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
||||
.version("a").description(RandomStringUtils.randomAlphanumeric(513))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set invalid description text should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
||||
.version("a").description(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with too long description should not be updated")
|
||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||
.description(RandomStringUtils.randomAlphanumeric(513))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with invalid description should not be updated").isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).description(INVALID_TEXT_HTML)));
|
||||
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateDistributionSetWithInvalidName(final DistributionSet set) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as("set with too long name should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().version("a")
|
||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as("set with invalid name should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().version("a").name(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with too short name should not be created").isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().version("a").name("")));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as("set with null name should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().version("a").name(null)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as("set with too long name should not be updated")
|
||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as("set with invalid name should not be updated")
|
||||
.isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).name(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with too short name should not be updated").isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).name("")));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateDistributionSetWithInvalidVersion(final DistributionSet set) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with too long version should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
|
||||
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with invalid version should not be created").isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().name("a").version(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with too short version should not be created").isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().name("a").version("")));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as("set with null version should not be created")
|
||||
.isThrownBy(() -> distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().name("a").version(null)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with too long version should not be updated")
|
||||
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
|
||||
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with invalid version should not be updated").isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).version(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("set with too short version should not be updated").isThrownBy(() -> distributionSetManagement
|
||||
.update(entityFactory.distributionSet().update(set.getId()).version("")));
|
||||
}
|
||||
|
||||
private DistributionSetType createDistributionSetTypeUsedByDs() {
|
||||
final DistributionSetType nonUpdatableType = distributionSetTypeManagement.create(entityFactory
|
||||
.distributionSetType().create().key("updatableType").name("to be deleted").colour("test123"));
|
||||
assertThat(distributionSetTypeManagement.getByKey("updatableType").get().getMandatoryModuleTypes()).isEmpty();
|
||||
distributionSetManagement.create(entityFactory.distributionSet().create().name("newtypesoft").version("1")
|
||||
.type(nonUpdatableType.getKey()));
|
||||
return nonUpdatableType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
|
||||
@@ -24,10 +27,6 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("Controller Management")
|
||||
@TestPropertySource(locations = "classpath:/jpa-test.properties", properties = {
|
||||
|
||||
@@ -13,6 +13,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.event.remote.RolloutDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetUpdatedEvent;
|
||||
@@ -38,10 +41,6 @@ import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("Rollout Management")
|
||||
class RolloutGroupManagementTest extends AbstractJpaIntegrationTest {
|
||||
@@ -159,42 +158,11 @@ class RolloutGroupManagementTest extends AbstractJpaIntegrationTest {
|
||||
.hasSize((int) rolloutGroupManagement.countTargetsOfRolloutsGroup(rolloutGroup.getId()));
|
||||
|
||||
targetsWithActionStatus = rolloutGroupManagement.findAllTargetsOfRolloutGroupWithActionStatus(
|
||||
PageRequest.of(0, 500, Sort.by(Direction.DESC, "lastActionStatusCode")), rolloutGroup.getId())
|
||||
PageRequest.of(0, 500, Sort.by(Direction.DESC, "lastActionStatusCode")), rolloutGroup.getId())
|
||||
.getContent();
|
||||
assertSortedListOfActionStatus(targetsWithActionStatus, target24, 24, target0, 0);
|
||||
}
|
||||
|
||||
private void assertSortedListOfActionStatus(final List<TargetWithActionStatus> targetsWithActionStatus,
|
||||
final Target first, final Integer firstStatusCode, final Target last, final Integer lastStatusCode) {
|
||||
assertTargetAndActionStatusCode(CollectionUtils.firstElement(targetsWithActionStatus), first, firstStatusCode);
|
||||
assertTargetAndActionStatusCode(CollectionUtils.lastElement(targetsWithActionStatus), last, lastStatusCode);
|
||||
}
|
||||
|
||||
private void assertTargetAndActionStatusCode(final TargetWithActionStatus targetWithActionStatus,
|
||||
final Target target, final Integer actionStatusCode) {
|
||||
assertThat(targetWithActionStatus.getTarget().getControllerId()).isEqualTo(target.getControllerId());
|
||||
assertThat(targetWithActionStatus.getLastActionStatusCode()).isEqualTo(actionStatusCode);
|
||||
}
|
||||
|
||||
private void assertTargetNotNullAndActionStatusNullAndActionStatusCode(
|
||||
final List<TargetWithActionStatus> targetsWithActionStatus, final Integer actionStatusCode) {
|
||||
targetsWithActionStatus.forEach(targetWithActionStatus -> {
|
||||
assertThat(targetWithActionStatus.getTarget().getControllerId()).isNotNull();
|
||||
assertThat(targetWithActionStatus.getStatus()).isNull();
|
||||
assertThat(targetWithActionStatus.getLastActionStatusCode()).isEqualTo(actionStatusCode);
|
||||
});
|
||||
}
|
||||
|
||||
private void assertTargetNotNullAndActionStatusAndActionStatusCode(
|
||||
final List<TargetWithActionStatus> targetsWithActionStatus, final Status actionStatus,
|
||||
final Integer actionStatusCode) {
|
||||
targetsWithActionStatus.forEach(targetWithActionStatus -> {
|
||||
assertThat(targetWithActionStatus.getTarget().getControllerId()).isNotNull();
|
||||
assertThat(targetWithActionStatus.getStatus()).isEqualTo(actionStatus);
|
||||
assertThat(targetWithActionStatus.getLastActionStatusCode()).isEqualTo(actionStatusCode);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that Rollouts in different states are handled correctly.")
|
||||
void findAllTargetsOfRolloutGroupWithActionStatus() {
|
||||
@@ -249,6 +217,37 @@ class RolloutGroupManagementTest extends AbstractJpaIntegrationTest {
|
||||
Status.RUNNING, 100);
|
||||
}
|
||||
|
||||
private void assertSortedListOfActionStatus(final List<TargetWithActionStatus> targetsWithActionStatus,
|
||||
final Target first, final Integer firstStatusCode, final Target last, final Integer lastStatusCode) {
|
||||
assertTargetAndActionStatusCode(CollectionUtils.firstElement(targetsWithActionStatus), first, firstStatusCode);
|
||||
assertTargetAndActionStatusCode(CollectionUtils.lastElement(targetsWithActionStatus), last, lastStatusCode);
|
||||
}
|
||||
|
||||
private void assertTargetAndActionStatusCode(final TargetWithActionStatus targetWithActionStatus,
|
||||
final Target target, final Integer actionStatusCode) {
|
||||
assertThat(targetWithActionStatus.getTarget().getControllerId()).isEqualTo(target.getControllerId());
|
||||
assertThat(targetWithActionStatus.getLastActionStatusCode()).isEqualTo(actionStatusCode);
|
||||
}
|
||||
|
||||
private void assertTargetNotNullAndActionStatusNullAndActionStatusCode(
|
||||
final List<TargetWithActionStatus> targetsWithActionStatus, final Integer actionStatusCode) {
|
||||
targetsWithActionStatus.forEach(targetWithActionStatus -> {
|
||||
assertThat(targetWithActionStatus.getTarget().getControllerId()).isNotNull();
|
||||
assertThat(targetWithActionStatus.getStatus()).isNull();
|
||||
assertThat(targetWithActionStatus.getLastActionStatusCode()).isEqualTo(actionStatusCode);
|
||||
});
|
||||
}
|
||||
|
||||
private void assertTargetNotNullAndActionStatusAndActionStatusCode(
|
||||
final List<TargetWithActionStatus> targetsWithActionStatus, final Status actionStatus,
|
||||
final Integer actionStatusCode) {
|
||||
targetsWithActionStatus.forEach(targetWithActionStatus -> {
|
||||
assertThat(targetWithActionStatus.getTarget().getControllerId()).isNotNull();
|
||||
assertThat(targetWithActionStatus.getStatus()).isEqualTo(actionStatus);
|
||||
assertThat(targetWithActionStatus.getLastActionStatusCode()).isEqualTo(actionStatusCode);
|
||||
});
|
||||
}
|
||||
|
||||
private void assertThatListIsSortedByTargetName(final List<TargetWithActionStatus> targets,
|
||||
final Direction sortDirection) {
|
||||
String previousName = null;
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.management;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
@@ -24,17 +29,10 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Junit tests for RolloutManagement.
|
||||
*/
|
||||
@@ -300,7 +298,6 @@ class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
|
||||
assertGroup(dynamic2, true, RolloutGroupStatus.RUNNING, 4); // assign the target created when paused
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Description("Verifies a simple pure (no static groups) dynamic rollout flow with a dynamic group template")
|
||||
void dynamicRolloutPureFlow() {
|
||||
@@ -362,7 +359,7 @@ class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
|
||||
assertAndGetRunning(rollout, 1); // remains on in the first dynamic
|
||||
|
||||
rolloutHandler.handleAll();
|
||||
assertRollout(rollout, true, RolloutStatus.RUNNING, 2, 8);
|
||||
assertRollout(rollout, true, RolloutStatus.RUNNING, 2, 8);
|
||||
assertGroup(dynamic1, true, RolloutGroupStatus.RUNNING, 6);
|
||||
// first dynamic threshold is reached, second is started
|
||||
assertGroup(dynamic2, true, RolloutGroupStatus.RUNNING, 2);
|
||||
|
||||
@@ -29,6 +29,10 @@ import java.util.stream.Stream;
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
import jakarta.validation.ValidationException;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.assertj.core.api.Condition;
|
||||
@@ -96,11 +100,6 @@ import org.springframework.data.domain.Slice;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
/**
|
||||
* Junit tests for RolloutManagement.
|
||||
*/
|
||||
@@ -108,6 +107,68 @@ import io.qameta.allure.Story;
|
||||
@Story("Rollout Management")
|
||||
class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
/**
|
||||
* Tests static assignment aspects of the dynamic group assignment filters.
|
||||
*/
|
||||
@Test
|
||||
@Description("Dynamic group doesn't override newer static group assignments")
|
||||
public void dynamicGroupDoesntOverrideItsOrNewerStaticGroups() {
|
||||
final int amountGroups = 1; // static only
|
||||
final String targetPrefix = "controller-dynamic-rollout-";
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet("ds");
|
||||
|
||||
testdataFactory.createTargets(targetPrefix, 0, amountGroups * 2);
|
||||
final Rollout dynamicRollout = testdataFactory.createRolloutByVariables("dynamic", "static rollout", amountGroups,
|
||||
"controllerid==" + targetPrefix + "*", distributionSet, "0", "30", ActionType.FORCED, 1000, false, true);
|
||||
rolloutManagement.start(dynamicRollout.getId());
|
||||
rolloutHandler.handleAll();
|
||||
assertRollout(dynamicRollout, true, RolloutStatus.RUNNING, amountGroups + 1, amountGroups * 2);
|
||||
final List<RolloutGroup> dynamicGroups = rolloutGroupManagement.findByRollout(
|
||||
new OffsetBasedPageRequest(0, amountGroups + 10, Sort.by(Direction.ASC, "id")),
|
||||
dynamicRollout.getId()).getContent();
|
||||
for (int i = 0; i < dynamicGroups.size(); i++) {
|
||||
final RolloutGroup group = dynamicGroups.get(i);
|
||||
if (i + 1 == dynamicGroups.size()) {
|
||||
assertGroup(group, true, RolloutGroupStatus.SCHEDULED, 0);
|
||||
} else {
|
||||
assertGroup(group, false, RolloutGroupStatus.RUNNING, 2);
|
||||
}
|
||||
}
|
||||
assertAndGetRunning(dynamicRollout, 2).forEach(this::finishAction);
|
||||
rolloutHandler.handleAll();
|
||||
for (int i = 0; i < dynamicGroups.size(); i++) {
|
||||
final RolloutGroup group = dynamicGroups.get(i);
|
||||
if (i + 1 == dynamicGroups.size()) {
|
||||
assertGroup(group, true, RolloutGroupStatus.RUNNING, 0);
|
||||
} else {
|
||||
assertGroup(group, false, RolloutGroupStatus.FINISHED, 2);
|
||||
}
|
||||
}
|
||||
assertAndGetRunning(dynamicRollout, 0);
|
||||
rolloutHandler.handleAll();
|
||||
// NB: asserts that dynamic group doesn't get from its static groups (already finished action targets)
|
||||
assertGroup(dynamicGroups.get(dynamicGroups.size() - 1), true, RolloutGroupStatus.RUNNING, 0);
|
||||
assertAndGetRunning(dynamicRollout, 0);
|
||||
rolloutManagement.pauseRollout(dynamicRollout.getId());
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
testdataFactory.createTargets(targetPrefix, amountGroups * 2, amountGroups);
|
||||
final Rollout staticRollout = testdataFactory.createRolloutByVariables("static", "static rollout", amountGroups,
|
||||
"controllerid==" + targetPrefix + "*", distributionSet, "0", "30", ActionType.FORCED, 0, false, false);
|
||||
rolloutManagement.start(staticRollout.getId());
|
||||
rolloutHandler.handleAll();
|
||||
assertRollout(staticRollout, false, RolloutStatus.RUNNING, amountGroups, amountGroups * 3);
|
||||
final List<RolloutGroup> staticGroups = rolloutGroupManagement.findByRollout(
|
||||
new OffsetBasedPageRequest(0, amountGroups + 10, Sort.by(Direction.ASC, "id")),
|
||||
staticRollout.getId()).getContent();
|
||||
staticGroups.forEach(group -> assertGroup(group, false, RolloutGroupStatus.RUNNING, 3));
|
||||
|
||||
rolloutManagement.resumeRollout(dynamicRollout.getId());
|
||||
rolloutHandler.handleAll(); // resume, do not get last devices (they are assigned to a newer group, nevertheless newer is with bigger weight
|
||||
assertGroup(dynamicGroups.get(dynamicGroups.size() - 1), true, RolloutGroupStatus.RUNNING, 0);
|
||||
assertAndGetRunning(dynamicRollout, 0);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void reset() {
|
||||
this.approvalStrategy.setApprovalNeeded(false);
|
||||
@@ -176,13 +237,6 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(actionsByKnownTarget.get(0).getStatus()).isEqualTo(expectedStatus);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> simpleRolloutsPossibilities() {
|
||||
return Stream.of(Arguments.of(true, true, Status.WAIT_FOR_CONFIRMATION), //
|
||||
Arguments.of(true, false, Status.RUNNING), //
|
||||
Arguments.of(false, true, Status.RUNNING), //
|
||||
Arguments.of(false, false, Status.RUNNING));//
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that a running action is auto canceled by a rollout which assigns another distribution-set.")
|
||||
void rolloutAssignsNewDistributionSetAndAutoCloseActiveActions() {
|
||||
@@ -382,64 +436,6 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
verifyRolloutAndAllGroupsAreFinished(createdRollout);
|
||||
}
|
||||
|
||||
@Step("Finish three actions of the rollout group and delete two targets")
|
||||
private void finishActionAndDeleteTargetsOfFirstRunningGroup(final Rollout createdRollout) {
|
||||
// finish group one by finishing targets and deleting targets
|
||||
final Slice<JpaAction> runningActionsSlice = actionRepository.findByRolloutIdAndStatus(PAGE,
|
||||
createdRollout.getId(), Status.RUNNING);
|
||||
final List<JpaAction> runningActions = runningActionsSlice.getContent();
|
||||
finishAction(runningActions.get(0));
|
||||
finishAction(runningActions.get(1));
|
||||
finishAction(runningActions.get(2));
|
||||
targetManagement.delete(
|
||||
Arrays.asList(runningActions.get(3).getTarget().getId(), runningActions.get(4).getTarget().getId()));
|
||||
}
|
||||
|
||||
@Step("Check the status of the rollout groups, second group should be in running status")
|
||||
private void checkSecondGroupStatusIsRunning(final Rollout createdRollout) {
|
||||
rolloutHandler.handleAll();
|
||||
final List<RolloutGroup> runningRolloutGroups = rolloutGroupManagement
|
||||
.findByRollout(new OffsetBasedPageRequest(0, 10, Sort.by(Direction.ASC, "id")), createdRollout.getId())
|
||||
.getContent();
|
||||
assertThat(runningRolloutGroups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
|
||||
assertThat(runningRolloutGroups.get(1).getStatus()).isEqualTo(RolloutGroupStatus.RUNNING);
|
||||
assertThat(runningRolloutGroups.get(2).getStatus()).isEqualTo(RolloutGroupStatus.SCHEDULED);
|
||||
}
|
||||
|
||||
@Step("Finish one action of the rollout group and delete four targets")
|
||||
private void finishActionAndDeleteTargetsOfSecondRunningGroup(final Rollout createdRollout) {
|
||||
final Slice<JpaAction> runningActionsSlice = actionRepository.findByRolloutIdAndStatus(PAGE,
|
||||
createdRollout.getId(), Status.RUNNING);
|
||||
final List<JpaAction> runningActions = runningActionsSlice.getContent();
|
||||
finishAction(runningActions.get(0));
|
||||
targetManagement.delete(
|
||||
Arrays.asList(runningActions.get(1).getTarget().getId(), runningActions.get(2).getTarget().getId(),
|
||||
runningActions.get(3).getTarget().getId(), runningActions.get(4).getTarget().getId()));
|
||||
|
||||
}
|
||||
|
||||
@Step("Delete all targets of the rollout group")
|
||||
private void deleteAllTargetsFromThirdGroup(final Rollout createdRollout) {
|
||||
final Slice<JpaAction> runningActionsSlice = actionRepository.findByRolloutIdAndStatus(PAGE,
|
||||
createdRollout.getId(), Status.SCHEDULED);
|
||||
final List<JpaAction> runningActions = runningActionsSlice.getContent();
|
||||
targetManagement.delete(Arrays.asList(runningActions.get(0).getTarget().getId(),
|
||||
runningActions.get(1).getTarget().getId(), runningActions.get(2).getTarget().getId(),
|
||||
runningActions.get(3).getTarget().getId(), runningActions.get(4).getTarget().getId()));
|
||||
}
|
||||
|
||||
@Step("Check the status of the rollout groups and the rollout")
|
||||
private void verifyRolloutAndAllGroupsAreFinished(final Rollout createdRollout) {
|
||||
rolloutHandler.handleAll();
|
||||
final List<RolloutGroup> runningRolloutGroups = rolloutGroupManagement
|
||||
.findByRollout(PAGE, createdRollout.getId()).getContent();
|
||||
assertThat(runningRolloutGroups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
|
||||
assertThat(runningRolloutGroups.get(1).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
|
||||
assertThat(runningRolloutGroups.get(2).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
|
||||
assertThat(reloadRollout(createdRollout).getStatus()).isEqualTo(RolloutStatus.FINISHED);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifying that the error handling action of a group is executed to pause the current rollout")
|
||||
void checkErrorHitOfGroupCallsErrorActionToPauseTheRollout() {
|
||||
@@ -1491,14 +1487,6 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(myRollout.getDescription()).isEqualTo("newDesc");
|
||||
}
|
||||
|
||||
private Rollout reloadRollout(final Rollout r) {
|
||||
return getRollout(r.getId());
|
||||
}
|
||||
|
||||
private Rollout getRollout(final Long myRolloutId) {
|
||||
return rolloutManagement.get(myRolloutId).orElseThrow(NoSuchElementException::new);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verify the creation of a rollout with a groups definition.")
|
||||
void createRolloutWithGroupDefinition() throws Exception {
|
||||
@@ -1635,41 +1623,6 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
}
|
||||
|
||||
private void assertRolloutGroup(final long rolloutGroupId, final RolloutGroupStatus status,
|
||||
final boolean isConfirmationRequired, final long totalTargets, final Status actionStatusToCheck) {
|
||||
assertThat(rolloutGroupManagement.get(rolloutGroupId)).hasValueSatisfying(rolloutGroup -> {
|
||||
assertThat(rolloutGroup.getStatus()).isEqualTo(status);
|
||||
assertThat(rolloutGroup.isConfirmationRequired()).isEqualTo(isConfirmationRequired);
|
||||
assertThat(rolloutGroup.getTotalTargets()).isEqualTo(totalTargets);
|
||||
if (actionStatusToCheck != null) {
|
||||
assertAllActionOfRolloutGroupHavingStatus(rolloutGroup.getId(), actionStatusToCheck);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void assertAllActionOfRolloutGroupHavingStatus(final long rolloutGroupId, final Status status) {
|
||||
final List<Target> targets = rolloutGroupManagement.findTargetsOfRolloutGroup(PAGE, rolloutGroupId)
|
||||
.getContent();
|
||||
targets.forEach(target -> {
|
||||
final List<Action> activeActions = deploymentManagement
|
||||
.findActionsByTarget(target.getControllerId(), PAGE).getContent();
|
||||
assertThat(activeActions).hasSize(1);
|
||||
assertThat(activeActions.get(0).getStatus()).isEqualTo(status);
|
||||
});
|
||||
}
|
||||
|
||||
private void forceQuitAllActionsOfRolloutGroup(final long rolloutGroupId) {
|
||||
final List<Target> targets = rolloutGroupManagement.findTargetsOfRolloutGroup(PAGE, rolloutGroupId)
|
||||
.getContent();
|
||||
targets.forEach(target -> {
|
||||
deploymentManagement.findActiveActionsByTarget(PAGE, target.getControllerId()).getContent().stream().map(Identifiable::getId)
|
||||
.forEach(actionId -> {
|
||||
deploymentManagement.cancelAction(actionId);
|
||||
deploymentManagement.forceQuitAction(actionId);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verify rollout creation fails if group definition does not address all targets")
|
||||
void createRolloutWithGroupsNotMatchingTargets() {
|
||||
@@ -1961,8 +1914,8 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
@Description("Creating a rollout with a weight causes an error when multi assignment in disabled.")
|
||||
void weightAllowedWhenMultiAssignmentModeNotEnabled() {
|
||||
testdataFactory.createSimpleTestRolloutWithTargetsAndDistributionSet(10, 10, 2, "50",
|
||||
"80",
|
||||
ActionType.FORCED, 66);
|
||||
"80",
|
||||
ActionType.FORCED, 66);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1996,7 +1949,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
enableMultiAssignments();
|
||||
final Long rolloutId = testdataFactory
|
||||
.createSimpleTestRolloutWithTargetsAndDistributionSet(amountOfTargets, 2, amountOfTargets,
|
||||
"80", "50", null, weight).getId();
|
||||
"80", "50", null, weight).getId();
|
||||
rolloutManagement.start(rolloutId);
|
||||
rolloutHandler.handleAll();
|
||||
final List<Action> actions = deploymentManagement.findActionsAll(PAGE).getContent();
|
||||
@@ -2086,102 +2039,6 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
.doesNotContainAnyElementsOf(incompatibleTargets);
|
||||
}
|
||||
|
||||
private RolloutGroupCreate generateRolloutGroup(final int index, final Integer percentage,
|
||||
final String targetFilter) {
|
||||
return generateRolloutGroup(index, percentage, targetFilter, false);
|
||||
}
|
||||
|
||||
private RolloutGroupCreate generateRolloutGroup(final int index, final Integer percentage,
|
||||
final String targetFilter, final boolean confirmationRequired) {
|
||||
return entityFactory.rolloutGroup().create().name("Group" + index).description("Group" + index + "desc")
|
||||
.targetPercentage(Float.valueOf(percentage)).targetFilterQuery(targetFilter)
|
||||
.confirmationRequired(confirmationRequired);
|
||||
}
|
||||
|
||||
private RolloutCreate generateTargetsAndRollout(final String rolloutName, final int amountTargetsForRollout) {
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName);
|
||||
|
||||
testdataFactory.createTargets(amountTargetsForRollout, rolloutName + "-", rolloutName);
|
||||
|
||||
return entityFactory.rollout().create().name(rolloutName)
|
||||
.description("This is a test description for the rollout")
|
||||
.targetFilterQuery("controllerId==" + rolloutName + "-*").distributionSetId(distributionSet);
|
||||
}
|
||||
|
||||
private void validateRolloutGroupActionStatus(final RolloutGroup rolloutGroup,
|
||||
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus) {
|
||||
final RolloutGroup rolloutGroupWithDetail = rolloutGroupManagement.getWithDetailedStatus(rolloutGroup.getId())
|
||||
.get();
|
||||
validateStatus(rolloutGroupWithDetail.getTotalTargetCountStatus(), expectedTargetCountStatus);
|
||||
}
|
||||
|
||||
private void validateRolloutActionStatus(final Long rolloutId,
|
||||
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus) {
|
||||
final Rollout rolloutWithDetail = rolloutManagement.getWithDetailedStatus(rolloutId).get();
|
||||
validateStatus(rolloutWithDetail.getTotalTargetCountStatus(), expectedTargetCountStatus);
|
||||
}
|
||||
|
||||
private void validateStatus(final TotalTargetCountStatus totalTargetCountStatus,
|
||||
final Map<TotalTargetCountStatus.Status, Long> expectedTotalCountStates) {
|
||||
for (final Map.Entry<TotalTargetCountStatus.Status, Long> entry : expectedTotalCountStates.entrySet()) {
|
||||
final Long countReady = totalTargetCountStatus.getTotalTargetCountByStatus(entry.getKey());
|
||||
assertThat(countReady).as("targets in status " + entry.getKey()).isEqualTo(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private Rollout createTestRolloutWithTargetsAndDistributionSet(final int amountTargetsForRollout,
|
||||
final int groupSize, final String successCondition, final String errorCondition, final String rolloutName,
|
||||
final String targetPrefixName) {
|
||||
return createTestRolloutWithTargetsAndDistributionSet(amountTargetsForRollout, groupSize, successCondition,
|
||||
errorCondition, rolloutName, targetPrefixName, null);
|
||||
}
|
||||
|
||||
private Rollout createTestRolloutWithTargetsAndDistributionSet(final int amountTargetsForRollout,
|
||||
final int groupSize, final String successCondition, final String errorCondition, final String rolloutName,
|
||||
final String targetPrefixName, final Integer weight) {
|
||||
final DistributionSet dsForRolloutTwo = testdataFactory.createDistributionSet("dsFor" + rolloutName);
|
||||
testdataFactory.createTargets(amountTargetsForRollout, targetPrefixName + "-", targetPrefixName);
|
||||
return testdataFactory.createRolloutByVariables(rolloutName, rolloutName + "description", groupSize,
|
||||
"controllerId==" + targetPrefixName + "-*", dsForRolloutTwo, successCondition, errorCondition,
|
||||
Action.ActionType.FORCED, weight, false);
|
||||
}
|
||||
|
||||
private int changeStatusForAllRunningActions(final Rollout rollout, final Status status) {
|
||||
final List<Action> runningActions = findActionsByRolloutAndStatus(rollout, Status.RUNNING);
|
||||
for (final Action action : runningActions) {
|
||||
controllerManagement
|
||||
.addUpdateActionStatus(entityFactory.actionStatus().create(action.getId()).status(status));
|
||||
}
|
||||
return runningActions.size();
|
||||
}
|
||||
|
||||
private int changeStatusForRunningActions(final Rollout rollout, final Status status,
|
||||
final int amountOfTargetsToGetChanged) {
|
||||
final List<Action> runningActions = findActionsByRolloutAndStatus(rollout, Status.RUNNING);
|
||||
assertThat(runningActions.size()).isGreaterThanOrEqualTo(amountOfTargetsToGetChanged);
|
||||
for (int i = 0; i < amountOfTargetsToGetChanged; i++) {
|
||||
controllerManagement.addUpdateActionStatus(
|
||||
entityFactory.actionStatus().create(runningActions.get(i).getId()).status(status));
|
||||
}
|
||||
return runningActions.size();
|
||||
}
|
||||
|
||||
private static Map<TotalTargetCountStatus.Status, Long> createInitStatusMap() {
|
||||
final Map<TotalTargetCountStatus.Status, Long> map = new HashMap<>();
|
||||
for (final TotalTargetCountStatus.Status status : TotalTargetCountStatus.Status.values()) {
|
||||
map.put(status, 0L);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private void awaitRunningState(final Long myRolloutId) {
|
||||
Awaitility.await().atMost(Duration.ofSeconds(10)).pollInterval(Duration.ofMillis(500)).with()
|
||||
.until(() -> SecurityContextSwitch
|
||||
.runAsPrivileged(
|
||||
() -> rolloutManagement.get(myRolloutId).orElseThrow(NoSuchElementException::new))
|
||||
.getStatus().equals(RolloutStatus.RUNNING));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifying that next group is started on manual trigger next group.")
|
||||
void checkRunningRolloutsManualTriggerNextGroup() {
|
||||
@@ -2272,65 +2129,207 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
.withMessageContaining(errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests static assignment aspects of the dynamic group assignment filters.
|
||||
*/
|
||||
@Test
|
||||
@Description("Dynamic group doesn't override newer static group assignments")
|
||||
public void dynamicGroupDoesntOverrideItsOrNewerStaticGroups() {
|
||||
final int amountGroups = 1; // static only
|
||||
final String targetPrefix = "controller-dynamic-rollout-";
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet("ds");
|
||||
private static Stream<Arguments> simpleRolloutsPossibilities() {
|
||||
return Stream.of(Arguments.of(true, true, Status.WAIT_FOR_CONFIRMATION), //
|
||||
Arguments.of(true, false, Status.RUNNING), //
|
||||
Arguments.of(false, true, Status.RUNNING), //
|
||||
Arguments.of(false, false, Status.RUNNING));//
|
||||
}
|
||||
|
||||
testdataFactory.createTargets(targetPrefix, 0, amountGroups * 2);
|
||||
final Rollout dynamicRollout = testdataFactory.createRolloutByVariables("dynamic", "static rollout", amountGroups,
|
||||
"controllerid==" + targetPrefix + "*", distributionSet, "0", "30", ActionType.FORCED, 1000, false, true);
|
||||
rolloutManagement.start(dynamicRollout.getId());
|
||||
rolloutHandler.handleAll();
|
||||
assertRollout(dynamicRollout, true, RolloutStatus.RUNNING, amountGroups + 1, amountGroups * 2);
|
||||
final List<RolloutGroup> dynamicGroups = rolloutGroupManagement.findByRollout(
|
||||
new OffsetBasedPageRequest(0, amountGroups + 10, Sort.by(Direction.ASC, "id")),
|
||||
dynamicRollout.getId()).getContent();
|
||||
for (int i = 0; i < dynamicGroups.size(); i++) {
|
||||
final RolloutGroup group = dynamicGroups.get(i);
|
||||
if (i + 1 == dynamicGroups.size()) {
|
||||
assertGroup(group, true, RolloutGroupStatus.SCHEDULED, 0);
|
||||
} else {
|
||||
assertGroup(group, false, RolloutGroupStatus.RUNNING, 2);
|
||||
}
|
||||
private static Map<TotalTargetCountStatus.Status, Long> createInitStatusMap() {
|
||||
final Map<TotalTargetCountStatus.Status, Long> map = new HashMap<>();
|
||||
for (final TotalTargetCountStatus.Status status : TotalTargetCountStatus.Status.values()) {
|
||||
map.put(status, 0L);
|
||||
}
|
||||
assertAndGetRunning(dynamicRollout, 2).forEach(this::finishAction);
|
||||
return map;
|
||||
}
|
||||
|
||||
@Step("Finish three actions of the rollout group and delete two targets")
|
||||
private void finishActionAndDeleteTargetsOfFirstRunningGroup(final Rollout createdRollout) {
|
||||
// finish group one by finishing targets and deleting targets
|
||||
final Slice<JpaAction> runningActionsSlice = actionRepository.findByRolloutIdAndStatus(PAGE,
|
||||
createdRollout.getId(), Status.RUNNING);
|
||||
final List<JpaAction> runningActions = runningActionsSlice.getContent();
|
||||
finishAction(runningActions.get(0));
|
||||
finishAction(runningActions.get(1));
|
||||
finishAction(runningActions.get(2));
|
||||
targetManagement.delete(
|
||||
Arrays.asList(runningActions.get(3).getTarget().getId(), runningActions.get(4).getTarget().getId()));
|
||||
}
|
||||
|
||||
@Step("Check the status of the rollout groups, second group should be in running status")
|
||||
private void checkSecondGroupStatusIsRunning(final Rollout createdRollout) {
|
||||
rolloutHandler.handleAll();
|
||||
for (int i = 0; i < dynamicGroups.size(); i++) {
|
||||
final RolloutGroup group = dynamicGroups.get(i);
|
||||
if (i + 1 == dynamicGroups.size()) {
|
||||
assertGroup(group, true, RolloutGroupStatus.RUNNING, 0);
|
||||
} else {
|
||||
assertGroup(group, false, RolloutGroupStatus.FINISHED, 2);
|
||||
final List<RolloutGroup> runningRolloutGroups = rolloutGroupManagement
|
||||
.findByRollout(new OffsetBasedPageRequest(0, 10, Sort.by(Direction.ASC, "id")), createdRollout.getId())
|
||||
.getContent();
|
||||
assertThat(runningRolloutGroups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
|
||||
assertThat(runningRolloutGroups.get(1).getStatus()).isEqualTo(RolloutGroupStatus.RUNNING);
|
||||
assertThat(runningRolloutGroups.get(2).getStatus()).isEqualTo(RolloutGroupStatus.SCHEDULED);
|
||||
}
|
||||
|
||||
@Step("Finish one action of the rollout group and delete four targets")
|
||||
private void finishActionAndDeleteTargetsOfSecondRunningGroup(final Rollout createdRollout) {
|
||||
final Slice<JpaAction> runningActionsSlice = actionRepository.findByRolloutIdAndStatus(PAGE,
|
||||
createdRollout.getId(), Status.RUNNING);
|
||||
final List<JpaAction> runningActions = runningActionsSlice.getContent();
|
||||
finishAction(runningActions.get(0));
|
||||
targetManagement.delete(
|
||||
Arrays.asList(runningActions.get(1).getTarget().getId(), runningActions.get(2).getTarget().getId(),
|
||||
runningActions.get(3).getTarget().getId(), runningActions.get(4).getTarget().getId()));
|
||||
|
||||
}
|
||||
|
||||
@Step("Delete all targets of the rollout group")
|
||||
private void deleteAllTargetsFromThirdGroup(final Rollout createdRollout) {
|
||||
final Slice<JpaAction> runningActionsSlice = actionRepository.findByRolloutIdAndStatus(PAGE,
|
||||
createdRollout.getId(), Status.SCHEDULED);
|
||||
final List<JpaAction> runningActions = runningActionsSlice.getContent();
|
||||
targetManagement.delete(Arrays.asList(runningActions.get(0).getTarget().getId(),
|
||||
runningActions.get(1).getTarget().getId(), runningActions.get(2).getTarget().getId(),
|
||||
runningActions.get(3).getTarget().getId(), runningActions.get(4).getTarget().getId()));
|
||||
}
|
||||
|
||||
@Step("Check the status of the rollout groups and the rollout")
|
||||
private void verifyRolloutAndAllGroupsAreFinished(final Rollout createdRollout) {
|
||||
rolloutHandler.handleAll();
|
||||
final List<RolloutGroup> runningRolloutGroups = rolloutGroupManagement
|
||||
.findByRollout(PAGE, createdRollout.getId()).getContent();
|
||||
assertThat(runningRolloutGroups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
|
||||
assertThat(runningRolloutGroups.get(1).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
|
||||
assertThat(runningRolloutGroups.get(2).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
|
||||
assertThat(reloadRollout(createdRollout).getStatus()).isEqualTo(RolloutStatus.FINISHED);
|
||||
|
||||
}
|
||||
|
||||
private Rollout reloadRollout(final Rollout r) {
|
||||
return getRollout(r.getId());
|
||||
}
|
||||
|
||||
private Rollout getRollout(final Long myRolloutId) {
|
||||
return rolloutManagement.get(myRolloutId).orElseThrow(NoSuchElementException::new);
|
||||
}
|
||||
|
||||
private void assertRolloutGroup(final long rolloutGroupId, final RolloutGroupStatus status,
|
||||
final boolean isConfirmationRequired, final long totalTargets, final Status actionStatusToCheck) {
|
||||
assertThat(rolloutGroupManagement.get(rolloutGroupId)).hasValueSatisfying(rolloutGroup -> {
|
||||
assertThat(rolloutGroup.getStatus()).isEqualTo(status);
|
||||
assertThat(rolloutGroup.isConfirmationRequired()).isEqualTo(isConfirmationRequired);
|
||||
assertThat(rolloutGroup.getTotalTargets()).isEqualTo(totalTargets);
|
||||
if (actionStatusToCheck != null) {
|
||||
assertAllActionOfRolloutGroupHavingStatus(rolloutGroup.getId(), actionStatusToCheck);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void assertAllActionOfRolloutGroupHavingStatus(final long rolloutGroupId, final Status status) {
|
||||
final List<Target> targets = rolloutGroupManagement.findTargetsOfRolloutGroup(PAGE, rolloutGroupId)
|
||||
.getContent();
|
||||
targets.forEach(target -> {
|
||||
final List<Action> activeActions = deploymentManagement
|
||||
.findActionsByTarget(target.getControllerId(), PAGE).getContent();
|
||||
assertThat(activeActions).hasSize(1);
|
||||
assertThat(activeActions.get(0).getStatus()).isEqualTo(status);
|
||||
});
|
||||
}
|
||||
|
||||
private void forceQuitAllActionsOfRolloutGroup(final long rolloutGroupId) {
|
||||
final List<Target> targets = rolloutGroupManagement.findTargetsOfRolloutGroup(PAGE, rolloutGroupId)
|
||||
.getContent();
|
||||
targets.forEach(target -> {
|
||||
deploymentManagement.findActiveActionsByTarget(PAGE, target.getControllerId()).getContent().stream().map(Identifiable::getId)
|
||||
.forEach(actionId -> {
|
||||
deploymentManagement.cancelAction(actionId);
|
||||
deploymentManagement.forceQuitAction(actionId);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private RolloutGroupCreate generateRolloutGroup(final int index, final Integer percentage,
|
||||
final String targetFilter) {
|
||||
return generateRolloutGroup(index, percentage, targetFilter, false);
|
||||
}
|
||||
|
||||
private RolloutGroupCreate generateRolloutGroup(final int index, final Integer percentage,
|
||||
final String targetFilter, final boolean confirmationRequired) {
|
||||
return entityFactory.rolloutGroup().create().name("Group" + index).description("Group" + index + "desc")
|
||||
.targetPercentage(Float.valueOf(percentage)).targetFilterQuery(targetFilter)
|
||||
.confirmationRequired(confirmationRequired);
|
||||
}
|
||||
|
||||
private RolloutCreate generateTargetsAndRollout(final String rolloutName, final int amountTargetsForRollout) {
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName);
|
||||
|
||||
testdataFactory.createTargets(amountTargetsForRollout, rolloutName + "-", rolloutName);
|
||||
|
||||
return entityFactory.rollout().create().name(rolloutName)
|
||||
.description("This is a test description for the rollout")
|
||||
.targetFilterQuery("controllerId==" + rolloutName + "-*").distributionSetId(distributionSet);
|
||||
}
|
||||
|
||||
private void validateRolloutGroupActionStatus(final RolloutGroup rolloutGroup,
|
||||
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus) {
|
||||
final RolloutGroup rolloutGroupWithDetail = rolloutGroupManagement.getWithDetailedStatus(rolloutGroup.getId())
|
||||
.get();
|
||||
validateStatus(rolloutGroupWithDetail.getTotalTargetCountStatus(), expectedTargetCountStatus);
|
||||
}
|
||||
|
||||
private void validateRolloutActionStatus(final Long rolloutId,
|
||||
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus) {
|
||||
final Rollout rolloutWithDetail = rolloutManagement.getWithDetailedStatus(rolloutId).get();
|
||||
validateStatus(rolloutWithDetail.getTotalTargetCountStatus(), expectedTargetCountStatus);
|
||||
}
|
||||
|
||||
private void validateStatus(final TotalTargetCountStatus totalTargetCountStatus,
|
||||
final Map<TotalTargetCountStatus.Status, Long> expectedTotalCountStates) {
|
||||
for (final Map.Entry<TotalTargetCountStatus.Status, Long> entry : expectedTotalCountStates.entrySet()) {
|
||||
final Long countReady = totalTargetCountStatus.getTotalTargetCountByStatus(entry.getKey());
|
||||
assertThat(countReady).as("targets in status " + entry.getKey()).isEqualTo(entry.getValue());
|
||||
}
|
||||
assertAndGetRunning(dynamicRollout, 0);
|
||||
rolloutHandler.handleAll();
|
||||
// NB: asserts that dynamic group doesn't get from its static groups (already finished action targets)
|
||||
assertGroup(dynamicGroups.get(dynamicGroups.size() - 1), true, RolloutGroupStatus.RUNNING, 0);
|
||||
assertAndGetRunning(dynamicRollout, 0);
|
||||
rolloutManagement.pauseRollout(dynamicRollout.getId());
|
||||
rolloutHandler.handleAll();
|
||||
}
|
||||
|
||||
testdataFactory.createTargets(targetPrefix, amountGroups * 2, amountGroups);
|
||||
final Rollout staticRollout = testdataFactory.createRolloutByVariables("static", "static rollout", amountGroups,
|
||||
"controllerid==" + targetPrefix + "*", distributionSet, "0", "30", ActionType.FORCED, 0, false, false);
|
||||
rolloutManagement.start(staticRollout.getId());
|
||||
rolloutHandler.handleAll();
|
||||
assertRollout(staticRollout, false, RolloutStatus.RUNNING, amountGroups, amountGroups * 3);
|
||||
final List<RolloutGroup> staticGroups = rolloutGroupManagement.findByRollout(
|
||||
new OffsetBasedPageRequest(0, amountGroups + 10, Sort.by(Direction.ASC, "id")),
|
||||
staticRollout.getId()).getContent();
|
||||
staticGroups.forEach(group -> assertGroup(group, false, RolloutGroupStatus.RUNNING, 3));
|
||||
private Rollout createTestRolloutWithTargetsAndDistributionSet(final int amountTargetsForRollout,
|
||||
final int groupSize, final String successCondition, final String errorCondition, final String rolloutName,
|
||||
final String targetPrefixName) {
|
||||
return createTestRolloutWithTargetsAndDistributionSet(amountTargetsForRollout, groupSize, successCondition,
|
||||
errorCondition, rolloutName, targetPrefixName, null);
|
||||
}
|
||||
|
||||
rolloutManagement.resumeRollout(dynamicRollout.getId());
|
||||
rolloutHandler.handleAll(); // resume, do not get last devices (they are assigned to a newer group, nevertheless newer is with bigger weight
|
||||
assertGroup(dynamicGroups.get(dynamicGroups.size() - 1), true, RolloutGroupStatus.RUNNING, 0);
|
||||
assertAndGetRunning(dynamicRollout, 0);
|
||||
private Rollout createTestRolloutWithTargetsAndDistributionSet(final int amountTargetsForRollout,
|
||||
final int groupSize, final String successCondition, final String errorCondition, final String rolloutName,
|
||||
final String targetPrefixName, final Integer weight) {
|
||||
final DistributionSet dsForRolloutTwo = testdataFactory.createDistributionSet("dsFor" + rolloutName);
|
||||
testdataFactory.createTargets(amountTargetsForRollout, targetPrefixName + "-", targetPrefixName);
|
||||
return testdataFactory.createRolloutByVariables(rolloutName, rolloutName + "description", groupSize,
|
||||
"controllerId==" + targetPrefixName + "-*", dsForRolloutTwo, successCondition, errorCondition,
|
||||
Action.ActionType.FORCED, weight, false);
|
||||
}
|
||||
|
||||
private int changeStatusForAllRunningActions(final Rollout rollout, final Status status) {
|
||||
final List<Action> runningActions = findActionsByRolloutAndStatus(rollout, Status.RUNNING);
|
||||
for (final Action action : runningActions) {
|
||||
controllerManagement
|
||||
.addUpdateActionStatus(entityFactory.actionStatus().create(action.getId()).status(status));
|
||||
}
|
||||
return runningActions.size();
|
||||
}
|
||||
|
||||
private int changeStatusForRunningActions(final Rollout rollout, final Status status,
|
||||
final int amountOfTargetsToGetChanged) {
|
||||
final List<Action> runningActions = findActionsByRolloutAndStatus(rollout, Status.RUNNING);
|
||||
assertThat(runningActions.size()).isGreaterThanOrEqualTo(amountOfTargetsToGetChanged);
|
||||
for (int i = 0; i < amountOfTargetsToGetChanged; i++) {
|
||||
controllerManagement.addUpdateActionStatus(
|
||||
entityFactory.actionStatus().create(runningActions.get(i).getId()).status(status));
|
||||
}
|
||||
return runningActions.size();
|
||||
}
|
||||
|
||||
private void awaitRunningState(final Long myRolloutId) {
|
||||
Awaitility.await().atMost(Duration.ofSeconds(10)).pollInterval(Duration.ofMillis(500)).with()
|
||||
.until(() -> SecurityContextSwitch
|
||||
.runAsPrivileged(
|
||||
() -> rolloutManagement.get(myRolloutId).orElseThrow(NoSuchElementException::new))
|
||||
.getStatus().equals(RolloutStatus.RUNNING));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -23,6 +22,9 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
import org.eclipse.hawkbit.repository.builder.SoftwareModuleMetadataCreate;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
|
||||
@@ -40,9 +42,7 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Artifact;
|
||||
import org.eclipse.hawkbit.repository.model.ArtifactUpload;
|
||||
import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
@@ -54,12 +54,6 @@ import org.eclipse.hawkbit.repository.test.util.WithUser;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("Software Module Management")
|
||||
@@ -220,25 +214,6 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
||||
.isEqualTo(ah);
|
||||
}
|
||||
|
||||
private Action assignSet(final JpaTarget target, final JpaDistributionSet ds) {
|
||||
assignDistributionSet(ds.getId(), target.getControllerId());
|
||||
implicitLock(ds);
|
||||
assertThat(targetManagement.getByControllerID(target.getControllerId()).get().getUpdateStatus())
|
||||
.isEqualTo(TargetUpdateStatus.PENDING);
|
||||
final Optional<DistributionSet> assignedDistributionSet = deploymentManagement
|
||||
.getAssignedDistributionSet(target.getControllerId());
|
||||
assertThat(assignedDistributionSet).contains(ds);
|
||||
final Action action = actionRepository
|
||||
.findAll(
|
||||
(root, query, cb) ->
|
||||
cb.and(
|
||||
cb.equal(root.get(JpaAction_.target).get(JpaTarget_.id), target.getId()),
|
||||
cb.equal(root.get(JpaAction_.distributionSet).get(JpaDistributionSet_.id), ds.getId())),
|
||||
PAGE).getContent().get(0);;
|
||||
assertThat(action).isNotNull();
|
||||
return action;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Searches for software modules based on a list of IDs.")
|
||||
public void findSoftwareModulesById() {
|
||||
@@ -482,52 +457,6 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(artifactRepository.findById(artifactY.getId())).isNotNull();
|
||||
}
|
||||
|
||||
private SoftwareModule createSoftwareModuleWithArtifacts(final SoftwareModuleType type, final String name,
|
||||
final String version, final int numberArtifacts) {
|
||||
|
||||
final long countSoftwareModule = softwareModuleRepository.count();
|
||||
|
||||
// create SoftwareModule
|
||||
SoftwareModule softwareModule = softwareModuleManagement.create(entityFactory.softwareModule().create()
|
||||
.type(type).name(name).version(version).description("description of artifact " + name));
|
||||
|
||||
final int artifactSize = 5 * 1024;
|
||||
for (int i = 0; i < numberArtifacts; i++) {
|
||||
artifactManagement.create(new ArtifactUpload(new RandomGeneratedInputStream(artifactSize),
|
||||
softwareModule.getId(), "file" + (i + 1), false, artifactSize));
|
||||
}
|
||||
|
||||
// Verify correct Creation of SoftwareModule and corresponding artifacts
|
||||
softwareModule = softwareModuleManagement.get(softwareModule.getId()).get();
|
||||
assertThat(softwareModuleRepository.findAll()).hasSize((int) countSoftwareModule + 1);
|
||||
|
||||
final List<Artifact> artifacts = softwareModule.getArtifacts();
|
||||
|
||||
assertThat(artifacts).hasSize(numberArtifacts);
|
||||
if (numberArtifacts != 0) {
|
||||
assertArtifactNotNull(artifacts.toArray(new Artifact[artifacts.size()]));
|
||||
}
|
||||
|
||||
artifacts.forEach(artifact -> assertThat(artifactRepository.findById(artifact.getId())).isNotNull());
|
||||
return softwareModule;
|
||||
}
|
||||
|
||||
private void assertArtifactNotNull(final Artifact... results) {
|
||||
assertThat(artifactRepository.findAll()).hasSize(results.length);
|
||||
for (final Artifact result : results) {
|
||||
assertThat(result.getId()).isNotNull();
|
||||
assertThat(binaryArtifactRepository.getArtifactBySha1(tenantAware.getCurrentTenant(), result.getSha1Hash()))
|
||||
.isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
private void assertArtifactNull(final Artifact... results) {
|
||||
for (final Artifact result : results) {
|
||||
assertThat(binaryArtifactRepository.getArtifactBySha1(tenantAware.getCurrentTenant(), result.getSha1Hash()))
|
||||
.isNull();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verfies that all undeleted software modules are found in the repository.")
|
||||
public void countSoftwareModuleTypesAll() {
|
||||
@@ -719,103 +648,16 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
assertThat(softwareModuleManagement.findMetaDataBySoftwareModuleId(PageRequest.of(0, 10), swModule.getId())
|
||||
.getContent()).as("Contains the created metadata element").allSatisfy(metadata -> {
|
||||
assertThat(metadata.getSoftwareModule().getId()).isEqualTo(swModule.getId());
|
||||
assertThat(metadata.getKey()).isEqualTo(knownKey1);
|
||||
assertThat(metadata.getValue()).isEqualTo(knownValue1);
|
||||
});
|
||||
assertThat(metadata.getSoftwareModule().getId()).isEqualTo(swModule.getId());
|
||||
assertThat(metadata.getKey()).isEqualTo(knownKey1);
|
||||
assertThat(metadata.getValue()).isEqualTo(knownValue1);
|
||||
});
|
||||
|
||||
softwareModuleManagement.deleteMetaData(swModule.getId(), knownKey1);
|
||||
assertThat(softwareModuleManagement.findMetaDataBySoftwareModuleId(PageRequest.of(0, 10), swModule.getId())
|
||||
.getContent()).as("Metadata elements are").isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Locks a SM.")
|
||||
void lockSoftwareModule() {
|
||||
final SoftwareModule softwareModule = testdataFactory.createSoftwareModule("sm-1");
|
||||
assertThat(
|
||||
softwareModuleManagement.get(softwareModule.getId()).map(SoftwareModule::isLocked).orElse(true))
|
||||
.isFalse();
|
||||
softwareModuleManagement.lock(softwareModule.getId());
|
||||
assertThat(
|
||||
softwareModuleManagement.get(softwareModule.getId()).map(SoftwareModule::isLocked).orElse(false))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Unlocks a SM.")
|
||||
void unlockSoftwareModule() {
|
||||
final SoftwareModule softwareModule = testdataFactory.createSoftwareModule("sm-1");
|
||||
softwareModuleManagement.lock(softwareModule.getId());
|
||||
assertThat(
|
||||
softwareModuleManagement.get(softwareModule.getId()).map(SoftwareModule::isLocked).orElse(false))
|
||||
.isTrue();
|
||||
softwareModuleManagement.unlock(softwareModule.getId());
|
||||
assertThat(
|
||||
softwareModuleManagement.get(softwareModule.getId()).map(SoftwareModule::isLocked).orElse(true))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Artifacts of a locked SM can't be modified. Expected behaviour is to throw an exception and to do not modify them.")
|
||||
void lockSoftwareModuleApplied() {
|
||||
final SoftwareModule softwareModule = testdataFactory.createSoftwareModule("sm-1");
|
||||
artifactManagement.create(
|
||||
new ArtifactUpload(new ByteArrayInputStream(new byte[] {1}), softwareModule.getId(),
|
||||
"artifact1", false, 1));
|
||||
final int artifactCount = softwareModuleManagement.get(softwareModule.getId()).get().getArtifacts().size();
|
||||
assertThat(artifactCount).isNotEqualTo(0);
|
||||
softwareModuleManagement.lock(softwareModule.getId());
|
||||
assertThat(
|
||||
softwareModuleManagement.get(softwareModule.getId()).map(SoftwareModule::isLocked).orElse(false))
|
||||
.isTrue();
|
||||
|
||||
|
||||
// try add
|
||||
assertThatExceptionOfType(LockedException.class)
|
||||
.as("Attempt to modify a locked SM artifacts should throw an exception")
|
||||
.isThrownBy(() -> artifactManagement.create(
|
||||
new ArtifactUpload(new ByteArrayInputStream(new byte[] {2}), softwareModule.getId(),
|
||||
"artifact2", false, 1)));
|
||||
assertThat(softwareModuleManagement.get(softwareModule.getId()).get().getArtifacts().size())
|
||||
.as("Artifacts shall not be added to a locked SM.")
|
||||
.isEqualTo(artifactCount);
|
||||
|
||||
// try remove
|
||||
final long artifactId = softwareModuleManagement.get(softwareModule.getId()).get()
|
||||
.getArtifacts().stream().findFirst().get().getId();
|
||||
assertThatExceptionOfType(LockedException.class)
|
||||
.as("Attempt to modify a locked SM artifacts should throw an exception")
|
||||
.isThrownBy(() -> artifactManagement.delete(artifactId));
|
||||
assertThat(softwareModuleManagement.get(softwareModule.getId()).get().getArtifacts().size())
|
||||
.as("Artifact shall not be removed from a locked SM.")
|
||||
.isEqualTo(artifactCount);
|
||||
assertThat(artifactManagement.get(artifactId))
|
||||
.as("Artifact shall not be removed if belongs to a locked SM.")
|
||||
.isPresent();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Artifacts of a locked SM can't be modified. Expected behaviour is to throw an exception and to do not modify them.")
|
||||
void lockedContainingDistributionSetApplied() {
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet("ds-1");
|
||||
final List<SoftwareModule> modules = distributionSet.getModules().stream().toList();
|
||||
assertThat(modules.size()).isGreaterThan(1);
|
||||
|
||||
// try delete while DS is not locked
|
||||
softwareModuleManagement.delete(modules.get(0).getId());
|
||||
|
||||
distributionSetManagement.lock(distributionSet.getId());
|
||||
assertThat(
|
||||
distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::isLocked).orElse(false))
|
||||
.isTrue();
|
||||
|
||||
// try delete SM of a locked DS
|
||||
assertThatExceptionOfType(LockedException.class)
|
||||
.as("Attempt to delete a software module of a locked DS should throw an exception")
|
||||
.isThrownBy(() -> softwareModuleManagement.delete(modules.get(1).getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that non existing metadata find results in exception.")
|
||||
public void findSoftwareModuleMetadataFailsIfEntryDoesNotExist() {
|
||||
@@ -874,4 +716,156 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(metadataSw2.getNumberOfElements()).isZero();
|
||||
assertThat(metadataSw2.getTotalElements()).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Locks a SM.")
|
||||
void lockSoftwareModule() {
|
||||
final SoftwareModule softwareModule = testdataFactory.createSoftwareModule("sm-1");
|
||||
assertThat(
|
||||
softwareModuleManagement.get(softwareModule.getId()).map(SoftwareModule::isLocked).orElse(true))
|
||||
.isFalse();
|
||||
softwareModuleManagement.lock(softwareModule.getId());
|
||||
assertThat(
|
||||
softwareModuleManagement.get(softwareModule.getId()).map(SoftwareModule::isLocked).orElse(false))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Unlocks a SM.")
|
||||
void unlockSoftwareModule() {
|
||||
final SoftwareModule softwareModule = testdataFactory.createSoftwareModule("sm-1");
|
||||
softwareModuleManagement.lock(softwareModule.getId());
|
||||
assertThat(
|
||||
softwareModuleManagement.get(softwareModule.getId()).map(SoftwareModule::isLocked).orElse(false))
|
||||
.isTrue();
|
||||
softwareModuleManagement.unlock(softwareModule.getId());
|
||||
assertThat(
|
||||
softwareModuleManagement.get(softwareModule.getId()).map(SoftwareModule::isLocked).orElse(true))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Artifacts of a locked SM can't be modified. Expected behaviour is to throw an exception and to do not modify them.")
|
||||
void lockSoftwareModuleApplied() {
|
||||
final SoftwareModule softwareModule = testdataFactory.createSoftwareModule("sm-1");
|
||||
artifactManagement.create(
|
||||
new ArtifactUpload(new ByteArrayInputStream(new byte[] { 1 }), softwareModule.getId(),
|
||||
"artifact1", false, 1));
|
||||
final int artifactCount = softwareModuleManagement.get(softwareModule.getId()).get().getArtifacts().size();
|
||||
assertThat(artifactCount).isNotEqualTo(0);
|
||||
softwareModuleManagement.lock(softwareModule.getId());
|
||||
assertThat(
|
||||
softwareModuleManagement.get(softwareModule.getId()).map(SoftwareModule::isLocked).orElse(false))
|
||||
.isTrue();
|
||||
|
||||
// try add
|
||||
assertThatExceptionOfType(LockedException.class)
|
||||
.as("Attempt to modify a locked SM artifacts should throw an exception")
|
||||
.isThrownBy(() -> artifactManagement.create(
|
||||
new ArtifactUpload(new ByteArrayInputStream(new byte[] { 2 }), softwareModule.getId(),
|
||||
"artifact2", false, 1)));
|
||||
assertThat(softwareModuleManagement.get(softwareModule.getId()).get().getArtifacts().size())
|
||||
.as("Artifacts shall not be added to a locked SM.")
|
||||
.isEqualTo(artifactCount);
|
||||
|
||||
// try remove
|
||||
final long artifactId = softwareModuleManagement.get(softwareModule.getId()).get()
|
||||
.getArtifacts().stream().findFirst().get().getId();
|
||||
assertThatExceptionOfType(LockedException.class)
|
||||
.as("Attempt to modify a locked SM artifacts should throw an exception")
|
||||
.isThrownBy(() -> artifactManagement.delete(artifactId));
|
||||
assertThat(softwareModuleManagement.get(softwareModule.getId()).get().getArtifacts().size())
|
||||
.as("Artifact shall not be removed from a locked SM.")
|
||||
.isEqualTo(artifactCount);
|
||||
assertThat(artifactManagement.get(artifactId))
|
||||
.as("Artifact shall not be removed if belongs to a locked SM.")
|
||||
.isPresent();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Artifacts of a locked SM can't be modified. Expected behaviour is to throw an exception and to do not modify them.")
|
||||
void lockedContainingDistributionSetApplied() {
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet("ds-1");
|
||||
final List<SoftwareModule> modules = distributionSet.getModules().stream().toList();
|
||||
assertThat(modules.size()).isGreaterThan(1);
|
||||
|
||||
// try delete while DS is not locked
|
||||
softwareModuleManagement.delete(modules.get(0).getId());
|
||||
|
||||
distributionSetManagement.lock(distributionSet.getId());
|
||||
assertThat(
|
||||
distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::isLocked).orElse(false))
|
||||
.isTrue();
|
||||
|
||||
// try delete SM of a locked DS
|
||||
assertThatExceptionOfType(LockedException.class)
|
||||
.as("Attempt to delete a software module of a locked DS should throw an exception")
|
||||
.isThrownBy(() -> softwareModuleManagement.delete(modules.get(1).getId()));
|
||||
}
|
||||
|
||||
private Action assignSet(final JpaTarget target, final JpaDistributionSet ds) {
|
||||
assignDistributionSet(ds.getId(), target.getControllerId());
|
||||
implicitLock(ds);
|
||||
assertThat(targetManagement.getByControllerID(target.getControllerId()).get().getUpdateStatus())
|
||||
.isEqualTo(TargetUpdateStatus.PENDING);
|
||||
final Optional<DistributionSet> assignedDistributionSet = deploymentManagement
|
||||
.getAssignedDistributionSet(target.getControllerId());
|
||||
assertThat(assignedDistributionSet).contains(ds);
|
||||
final Action action = actionRepository
|
||||
.findAll(
|
||||
(root, query, cb) ->
|
||||
cb.and(
|
||||
cb.equal(root.get(JpaAction_.target).get(JpaTarget_.id), target.getId()),
|
||||
cb.equal(root.get(JpaAction_.distributionSet).get(JpaDistributionSet_.id), ds.getId())),
|
||||
PAGE).getContent().get(0);
|
||||
;
|
||||
assertThat(action).isNotNull();
|
||||
return action;
|
||||
}
|
||||
|
||||
private SoftwareModule createSoftwareModuleWithArtifacts(final SoftwareModuleType type, final String name,
|
||||
final String version, final int numberArtifacts) {
|
||||
|
||||
final long countSoftwareModule = softwareModuleRepository.count();
|
||||
|
||||
// create SoftwareModule
|
||||
SoftwareModule softwareModule = softwareModuleManagement.create(entityFactory.softwareModule().create()
|
||||
.type(type).name(name).version(version).description("description of artifact " + name));
|
||||
|
||||
final int artifactSize = 5 * 1024;
|
||||
for (int i = 0; i < numberArtifacts; i++) {
|
||||
artifactManagement.create(new ArtifactUpload(new RandomGeneratedInputStream(artifactSize),
|
||||
softwareModule.getId(), "file" + (i + 1), false, artifactSize));
|
||||
}
|
||||
|
||||
// Verify correct Creation of SoftwareModule and corresponding artifacts
|
||||
softwareModule = softwareModuleManagement.get(softwareModule.getId()).get();
|
||||
assertThat(softwareModuleRepository.findAll()).hasSize((int) countSoftwareModule + 1);
|
||||
|
||||
final List<Artifact> artifacts = softwareModule.getArtifacts();
|
||||
|
||||
assertThat(artifacts).hasSize(numberArtifacts);
|
||||
if (numberArtifacts != 0) {
|
||||
assertArtifactNotNull(artifacts.toArray(new Artifact[artifacts.size()]));
|
||||
}
|
||||
|
||||
artifacts.forEach(artifact -> assertThat(artifactRepository.findById(artifact.getId())).isNotNull());
|
||||
return softwareModule;
|
||||
}
|
||||
|
||||
private void assertArtifactNotNull(final Artifact... results) {
|
||||
assertThat(artifactRepository.findAll()).hasSize(results.length);
|
||||
for (final Artifact result : results) {
|
||||
assertThat(result.getId()).isNotNull();
|
||||
assertThat(binaryArtifactRepository.getArtifactBySha1(tenantAware.getCurrentTenant(), result.getSha1Hash()))
|
||||
.isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
private void assertArtifactNull(final Artifact... results) {
|
||||
for (final Artifact result : results) {
|
||||
assertThat(binaryArtifactRepository.getArtifactBySha1(tenantAware.getCurrentTenant(), result.getSha1Hash()))
|
||||
.isNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@ import java.util.List;
|
||||
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.builder.SoftwareModuleTypeCreate;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
@@ -27,10 +30,6 @@ import org.eclipse.hawkbit.repository.test.matcher.Expect;
|
||||
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("Software Module Management")
|
||||
public class SoftwareModuleTypeManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@@ -15,6 +15,9 @@ import java.io.ByteArrayInputStream;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.model.ArtifactUpload;
|
||||
@@ -27,10 +30,6 @@ import org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("System Management")
|
||||
@ExtendWith(DisposableSqlTestDatabaseExtension.class)
|
||||
@@ -135,25 +134,25 @@ public class SystemManagementTest extends AbstractJpaIntegrationTest {
|
||||
final String tenantname = "tenant" + i;
|
||||
SecurityContextSwitch.runAs(SecurityContextSwitch.withUserAndTenant("bumlux", tenantname, true, true, false,
|
||||
SpringEvalExpressions.SYSTEM_ROLE), () -> {
|
||||
systemManagement.getTenantMetadata();
|
||||
if (artifactSize > 0) {
|
||||
createTestArtifact(random);
|
||||
createDeletedTestArtifact(random);
|
||||
}
|
||||
if (targets > 0) {
|
||||
final List<Target> createdTargets = createTestTargets(targets);
|
||||
if (updates > 0) {
|
||||
for (int x = 0; x < updates; x++) {
|
||||
final DistributionSet ds = testdataFactory
|
||||
.createDistributionSet("to be deployed" + x, true);
|
||||
systemManagement.getTenantMetadata();
|
||||
if (artifactSize > 0) {
|
||||
createTestArtifact(random);
|
||||
createDeletedTestArtifact(random);
|
||||
}
|
||||
if (targets > 0) {
|
||||
final List<Target> createdTargets = createTestTargets(targets);
|
||||
if (updates > 0) {
|
||||
for (int x = 0; x < updates; x++) {
|
||||
final DistributionSet ds = testdataFactory
|
||||
.createDistributionSet("to be deployed" + x, true);
|
||||
|
||||
assignDistributionSet(ds, createdTargets);
|
||||
}
|
||||
}
|
||||
assignDistributionSet(ds, createdTargets);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
return random;
|
||||
|
||||
@@ -22,6 +22,10 @@ import java.util.List;
|
||||
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||
import org.eclipse.hawkbit.repository.builder.AutoAssignDistributionSetUpdate;
|
||||
@@ -49,14 +53,8 @@ import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Slice;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
/**
|
||||
* Test class for {@link TargetFilterQueryManagement}.
|
||||
*
|
||||
*/
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("Target Filter Query Management")
|
||||
@@ -93,7 +91,7 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
|
||||
"TargetFilterQuery");
|
||||
|
||||
verifyThrownExceptionBy(() -> targetFilterQueryManagement.updateAutoAssignDS(
|
||||
entityFactory.targetFilterQuery().updateAutoAssign(targetFilterQuery.getId()).ds(NOT_EXIST_IDL)),
|
||||
entityFactory.targetFilterQuery().updateAutoAssign(targetFilterQuery.getId()).ds(NOT_EXIST_IDL)),
|
||||
"DistributionSet");
|
||||
|
||||
verifyThrownExceptionBy(
|
||||
@@ -102,7 +100,7 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
|
||||
"TargetFilterQuery");
|
||||
|
||||
verifyThrownExceptionBy(() -> targetFilterQueryManagement.updateAutoAssignDS(
|
||||
entityFactory.targetFilterQuery().updateAutoAssign(targetFilterQuery.getId()).ds(NOT_EXIST_IDL)),
|
||||
entityFactory.targetFilterQuery().updateAutoAssign(targetFilterQuery.getId()).ds(NOT_EXIST_IDL)),
|
||||
"DistributionSet");
|
||||
}
|
||||
|
||||
@@ -214,65 +212,6 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
|
||||
verifyAutoAssignmentWithSoftDeletedDs(targetFilterQuery);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyAutoAssignmentWithDefaultActionType(final String filterName,
|
||||
final TargetFilterQuery targetFilterQuery, final DistributionSet distributionSet) {
|
||||
targetFilterQueryManagement.updateAutoAssignDS(entityFactory.targetFilterQuery()
|
||||
.updateAutoAssign(targetFilterQuery.getId()).ds(distributionSet.getId()));
|
||||
implicitLock(distributionSet);
|
||||
verifyAutoAssignDsAndActionType(filterName, distributionSet, ActionType.FORCED);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyAutoAssignmentWithSoftActionType(final String filterName,
|
||||
final TargetFilterQuery targetFilterQuery, final DistributionSet distributionSet) {
|
||||
targetFilterQueryManagement.updateAutoAssignDS(entityFactory.targetFilterQuery()
|
||||
.updateAutoAssign(targetFilterQuery.getId()).ds(distributionSet.getId()).actionType(ActionType.SOFT));
|
||||
verifyAutoAssignDsAndActionType(filterName, distributionSet, ActionType.SOFT);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyAutoAssignmentWithDownloadOnlyActionType(final String filterName,
|
||||
final TargetFilterQuery targetFilterQuery, final DistributionSet distributionSet) {
|
||||
targetFilterQueryManagement
|
||||
.updateAutoAssignDS(entityFactory.targetFilterQuery().updateAutoAssign(targetFilterQuery.getId())
|
||||
.ds(distributionSet.getId()).actionType(ActionType.DOWNLOAD_ONLY));
|
||||
verifyAutoAssignDsAndActionType(filterName, distributionSet, ActionType.DOWNLOAD_ONLY);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyAutoAssignmentWithInvalidActionType(final TargetFilterQuery targetFilterQuery,
|
||||
final DistributionSet distributionSet) {
|
||||
// assigning a distribution set with TIMEFORCED action is supposed to
|
||||
// fail as only FORCED and SOFT action types are allowed
|
||||
assertThatExceptionOfType(InvalidAutoAssignActionTypeException.class)
|
||||
.isThrownBy(() -> targetFilterQueryManagement.updateAutoAssignDS(
|
||||
entityFactory.targetFilterQuery().updateAutoAssign(targetFilterQuery.getId())
|
||||
.ds(distributionSet.getId()).actionType(ActionType.TIMEFORCED)));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyAutoAssignmentWithIncompleteDs(final TargetFilterQuery targetFilterQuery) {
|
||||
final DistributionSet incompleteDistributionSet = distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().name("incomplete").version("1")
|
||||
.type(testdataFactory.findOrCreateDefaultTestDsType()));
|
||||
|
||||
assertThatExceptionOfType(IncompleteDistributionSetException.class)
|
||||
.isThrownBy(() -> targetFilterQueryManagement.updateAutoAssignDS(entityFactory.targetFilterQuery()
|
||||
.updateAutoAssign(targetFilterQuery.getId()).ds(incompleteDistributionSet.getId())));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyAutoAssignmentWithSoftDeletedDs(final TargetFilterQuery targetFilterQuery) {
|
||||
final DistributionSet softDeletedDs = testdataFactory.createDistributionSet("softDeleted");
|
||||
assignDistributionSet(softDeletedDs, testdataFactory.createTarget("forSoftDeletedDs"));
|
||||
distributionSetManagement.delete(softDeletedDs.getId());
|
||||
|
||||
assertThatExceptionOfType(DeletedException.class)
|
||||
.isThrownBy(() -> targetFilterQueryManagement.updateAutoAssignDS(entityFactory.targetFilterQuery()
|
||||
.updateAutoAssign(targetFilterQuery.getId()).ds(softDeletedDs.getId())));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Assigns a distribution set to an existing filter query and verifies that the quota 'max targets per auto assignment' is enforced.")
|
||||
public void assignDistributionSetToTargetFilterQueryThatExceedsQuota() {
|
||||
@@ -407,39 +346,6 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
|
||||
verifyFindForAllWithAutoAssignDs(tfq, tfq2);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyFindByDistributionSetAndRsql(final DistributionSet distributionSet, final String rsql,
|
||||
final TargetFilterQuery... expectedFilterQueries) {
|
||||
final Page<TargetFilterQuery> tfqList = targetFilterQueryManagement
|
||||
.findByAutoAssignDSAndRsql(PageRequest.of(0, 500), distributionSet.getId(), rsql);
|
||||
|
||||
assertThat(tfqList.getTotalElements()).isEqualTo(expectedFilterQueries.length);
|
||||
verifyExpectedFilterQueriesInList(tfqList, expectedFilterQueries);
|
||||
}
|
||||
|
||||
private void verifyExpectedFilterQueriesInList(final Slice<TargetFilterQuery> tfqList,
|
||||
final TargetFilterQuery... expectedFilterQueries) {
|
||||
assertThat(tfqList.map(TargetFilterQuery::getId)).containsExactly(
|
||||
Arrays.stream(expectedFilterQueries).map(TargetFilterQuery::getId).toArray(Long[]::new));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyFindForAllWithAutoAssignDs(final TargetFilterQuery... expectedFilterQueries) {
|
||||
final Slice<TargetFilterQuery> tfqList = targetFilterQueryManagement
|
||||
.findWithAutoAssignDS(PageRequest.of(0, 500));
|
||||
|
||||
assertThat(tfqList.getNumberOfElements()).isEqualTo(expectedFilterQueries.length);
|
||||
verifyExpectedFilterQueriesInList(tfqList, expectedFilterQueries);
|
||||
}
|
||||
|
||||
private void verifyExpectedFilterQueriesInList(final Page<TargetFilterQuery> tfqList,
|
||||
final TargetFilterQuery... expectedFilterQueries) {
|
||||
assertThat(expectedFilterQueries).as("Target filter query count").hasSize((int) tfqList.getTotalElements());
|
||||
|
||||
assertThat(tfqList.map(TargetFilterQuery::getId)).containsExactly(
|
||||
Arrays.stream(expectedFilterQueries).map(TargetFilterQuery::getId).toArray(Long[]::new));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Creating or updating a target filter query with autoassignment and no-value weight when multi assignment in enabled.")
|
||||
public void weightNotRequiredInMultiAssignmentMode() {
|
||||
@@ -462,9 +368,9 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
|
||||
.create(entityFactory.targetFilterQuery().create().name("a").query("name==*")).getId();
|
||||
|
||||
targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create()
|
||||
.name("b").query("name==*").autoAssignDistributionSet(ds).autoAssignWeight(342));
|
||||
.name("b").query("name==*").autoAssignDistributionSet(ds).autoAssignWeight(342));
|
||||
targetFilterQueryManagement.updateAutoAssignDS(
|
||||
entityFactory.targetFilterQuery().updateAutoAssign(filterId).ds(ds.getId()).weight(343));
|
||||
entityFactory.targetFilterQuery().updateAutoAssign(filterId).ds(ds.getId()).weight(343));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -563,6 +469,98 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
|
||||
.ds(incompleteDistributionSet.getId())));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyAutoAssignmentWithDefaultActionType(final String filterName,
|
||||
final TargetFilterQuery targetFilterQuery, final DistributionSet distributionSet) {
|
||||
targetFilterQueryManagement.updateAutoAssignDS(entityFactory.targetFilterQuery()
|
||||
.updateAutoAssign(targetFilterQuery.getId()).ds(distributionSet.getId()));
|
||||
implicitLock(distributionSet);
|
||||
verifyAutoAssignDsAndActionType(filterName, distributionSet, ActionType.FORCED);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyAutoAssignmentWithSoftActionType(final String filterName,
|
||||
final TargetFilterQuery targetFilterQuery, final DistributionSet distributionSet) {
|
||||
targetFilterQueryManagement.updateAutoAssignDS(entityFactory.targetFilterQuery()
|
||||
.updateAutoAssign(targetFilterQuery.getId()).ds(distributionSet.getId()).actionType(ActionType.SOFT));
|
||||
verifyAutoAssignDsAndActionType(filterName, distributionSet, ActionType.SOFT);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyAutoAssignmentWithDownloadOnlyActionType(final String filterName,
|
||||
final TargetFilterQuery targetFilterQuery, final DistributionSet distributionSet) {
|
||||
targetFilterQueryManagement
|
||||
.updateAutoAssignDS(entityFactory.targetFilterQuery().updateAutoAssign(targetFilterQuery.getId())
|
||||
.ds(distributionSet.getId()).actionType(ActionType.DOWNLOAD_ONLY));
|
||||
verifyAutoAssignDsAndActionType(filterName, distributionSet, ActionType.DOWNLOAD_ONLY);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyAutoAssignmentWithInvalidActionType(final TargetFilterQuery targetFilterQuery,
|
||||
final DistributionSet distributionSet) {
|
||||
// assigning a distribution set with TIMEFORCED action is supposed to
|
||||
// fail as only FORCED and SOFT action types are allowed
|
||||
assertThatExceptionOfType(InvalidAutoAssignActionTypeException.class)
|
||||
.isThrownBy(() -> targetFilterQueryManagement.updateAutoAssignDS(
|
||||
entityFactory.targetFilterQuery().updateAutoAssign(targetFilterQuery.getId())
|
||||
.ds(distributionSet.getId()).actionType(ActionType.TIMEFORCED)));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyAutoAssignmentWithIncompleteDs(final TargetFilterQuery targetFilterQuery) {
|
||||
final DistributionSet incompleteDistributionSet = distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().name("incomplete").version("1")
|
||||
.type(testdataFactory.findOrCreateDefaultTestDsType()));
|
||||
|
||||
assertThatExceptionOfType(IncompleteDistributionSetException.class)
|
||||
.isThrownBy(() -> targetFilterQueryManagement.updateAutoAssignDS(entityFactory.targetFilterQuery()
|
||||
.updateAutoAssign(targetFilterQuery.getId()).ds(incompleteDistributionSet.getId())));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyAutoAssignmentWithSoftDeletedDs(final TargetFilterQuery targetFilterQuery) {
|
||||
final DistributionSet softDeletedDs = testdataFactory.createDistributionSet("softDeleted");
|
||||
assignDistributionSet(softDeletedDs, testdataFactory.createTarget("forSoftDeletedDs"));
|
||||
distributionSetManagement.delete(softDeletedDs.getId());
|
||||
|
||||
assertThatExceptionOfType(DeletedException.class)
|
||||
.isThrownBy(() -> targetFilterQueryManagement.updateAutoAssignDS(entityFactory.targetFilterQuery()
|
||||
.updateAutoAssign(targetFilterQuery.getId()).ds(softDeletedDs.getId())));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyFindByDistributionSetAndRsql(final DistributionSet distributionSet, final String rsql,
|
||||
final TargetFilterQuery... expectedFilterQueries) {
|
||||
final Page<TargetFilterQuery> tfqList = targetFilterQueryManagement
|
||||
.findByAutoAssignDSAndRsql(PageRequest.of(0, 500), distributionSet.getId(), rsql);
|
||||
|
||||
assertThat(tfqList.getTotalElements()).isEqualTo(expectedFilterQueries.length);
|
||||
verifyExpectedFilterQueriesInList(tfqList, expectedFilterQueries);
|
||||
}
|
||||
|
||||
private void verifyExpectedFilterQueriesInList(final Slice<TargetFilterQuery> tfqList,
|
||||
final TargetFilterQuery... expectedFilterQueries) {
|
||||
assertThat(tfqList.map(TargetFilterQuery::getId)).containsExactly(
|
||||
Arrays.stream(expectedFilterQueries).map(TargetFilterQuery::getId).toArray(Long[]::new));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyFindForAllWithAutoAssignDs(final TargetFilterQuery... expectedFilterQueries) {
|
||||
final Slice<TargetFilterQuery> tfqList = targetFilterQueryManagement
|
||||
.findWithAutoAssignDS(PageRequest.of(0, 500));
|
||||
|
||||
assertThat(tfqList.getNumberOfElements()).isEqualTo(expectedFilterQueries.length);
|
||||
verifyExpectedFilterQueriesInList(tfqList, expectedFilterQueries);
|
||||
}
|
||||
|
||||
private void verifyExpectedFilterQueriesInList(final Page<TargetFilterQuery> tfqList,
|
||||
final TargetFilterQuery... expectedFilterQueries) {
|
||||
assertThat(expectedFilterQueries).as("Target filter query count").hasSize((int) tfqList.getTotalElements());
|
||||
|
||||
assertThat(tfqList.map(TargetFilterQuery::getId)).containsExactly(
|
||||
Arrays.stream(expectedFilterQueries).map(TargetFilterQuery::getId).toArray(Long[]::new));
|
||||
}
|
||||
|
||||
private void verifyAutoAssignDsAndActionType(final String filterName, final DistributionSet distributionSet,
|
||||
final ActionType actionType) {
|
||||
final TargetFilterQuery tfq = targetFilterQueryManagement.getByName(filterName).get();
|
||||
|
||||
@@ -19,6 +19,10 @@ import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.FilterParams;
|
||||
import org.eclipse.hawkbit.repository.Identifiable;
|
||||
import org.eclipse.hawkbit.repository.builder.DistributionSetCreate;
|
||||
@@ -39,15 +43,32 @@ import org.springframework.data.domain.Slice;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("Target Management Searches")
|
||||
class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Verifies that targets with given target type are returned from repository.")
|
||||
public void findTargetByTargetType() {
|
||||
final TargetType testType = testdataFactory.createTargetType("testType",
|
||||
Collections.singletonList(standardDsType));
|
||||
final List<Target> unassigned = testdataFactory.createTargets(9, "unassigned");
|
||||
final List<Target> assigned = testdataFactory.createTargetsWithType(11, "assigned", testType);
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, new FilterParams(null, null, false, testType.getId())))
|
||||
.as("Contains the targets with set type").containsAll(assigned)
|
||||
.as("and that means the following expected amount").hasSize(11);
|
||||
assertThat(targetManagement.countByFilters(new FilterParams(null, null, false, testType.getId())))
|
||||
.as("Count the targets with set type").isEqualTo(11);
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, new FilterParams(null, null, true, null)))
|
||||
.as("Contains the targets without a type").containsAll(unassigned)
|
||||
.as("and that means the following expected amount").hasSize(9);
|
||||
assertThat(targetManagement.countByFilters(new FilterParams(null, null, true, null)))
|
||||
.as("Counts the targets without a type").isEqualTo(9);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Tests different parameter combinations for target search operations. "
|
||||
+ "That includes both the test itself, as a count operation with the same filters "
|
||||
@@ -178,382 +199,6 @@ class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
||||
verifyThat198TargetsAreInStatusUnknownAndOverdue(unknown, expected);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat1TargetAIsInStatusPendingAndHasDSInstalled(final DistributionSet installedSet,
|
||||
final List<TargetUpdateStatus> pending, final Target expected) {
|
||||
final FilterParams filterParams = new FilterParams(pending, null, null, installedSet.getId(), Boolean.FALSE);
|
||||
final String query = "updatestatus==pending and installedds.name==" + installedSet.getName();
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(1).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsExactly(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat200targetsWithGivenTagAreInStatusPendingorUnknown(final TargetTag targTagW,
|
||||
final List<TargetUpdateStatus> both, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(both, null, null, null, Boolean.FALSE, targTagW.getName());
|
||||
final String query = "(updatestatus==pending or updatestatus==unknown) and tag==" + targTagW.getName();
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(200).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat2TargetsWithGivenTagAreInPending(final TargetTag targTagW,
|
||||
final List<TargetUpdateStatus> pending, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(pending, null, null, null, Boolean.FALSE,
|
||||
targTagW.getName());
|
||||
final String query = "updatestatus==pending and tag==" + targTagW.getName();
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(2).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat2TargetsWithGivenTagAndDSIsInPending(final TargetTag targTagW, final DistributionSet setA,
|
||||
final List<TargetUpdateStatus> pending, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(pending, null, null, setA.getId(), Boolean.FALSE,
|
||||
targTagW.getName());
|
||||
final String query = "updatestatus==pending and (assignedds.name==" + setA.getName() + " or installedds.name=="
|
||||
+ setA.getName() + ") and tag==" + targTagW.getName();
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(2).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat1TargetWithGivenNameOrDescAndTagAndDSIsInPending(final TargetTag targTagW,
|
||||
final DistributionSet setA, final List<TargetUpdateStatus> pending, final Target expected) {
|
||||
final FilterParams filterParams = new FilterParams(pending, null, "%targ-B%", setA.getId(), Boolean.FALSE,
|
||||
targTagW.getName());
|
||||
final String query = "updatestatus==pending and (assignedds.name==" + setA.getName() + " or installedds.name=="
|
||||
+ setA.getName() + ") and (name==*targ-B* or description==*targ-B*) and tag==" + targTagW.getName();
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(1).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsExactly(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat1TargetWithGivenNameOrDescAndDSIsInPending(final DistributionSet setA,
|
||||
final List<TargetUpdateStatus> pending, final Target expected) {
|
||||
final FilterParams filterParams = new FilterParams(pending, null, "%targ-A%", setA.getId(), Boolean.FALSE);
|
||||
final String query = "updatestatus==pending and (assignedds.name==" + setA.getName() + " or installedds.name=="
|
||||
+ setA.getName() + ") and (name==*targ-A* or description==*targ-A*)";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(1).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsExactly(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat3TargetsWithGivenDSAreInPending(final DistributionSet setA,
|
||||
final List<TargetUpdateStatus> pending, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(pending, null, null, setA.getId(), Boolean.FALSE);
|
||||
final String query = "updatestatus==pending and (assignedds.name==" + setA.getName() + " or installedds.name=="
|
||||
+ setA.getName() + ")";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(3).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat4TargetsAreInStatusPending(final List<TargetUpdateStatus> pending,
|
||||
final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(pending, null, null, null, Boolean.FALSE);
|
||||
final String query = "updatestatus==pending";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(4).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat99TargetsWithGivenNameOrDescAndTagAreInStatusUnknown(final TargetTag targTagW,
|
||||
final List<TargetUpdateStatus> unknown, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(unknown, null, "%targ-B%", null, Boolean.FALSE,
|
||||
targTagW.getName());
|
||||
final String query = "updatestatus==unknown and (name==*targ-B* or description==*targ-B*) and tag=="
|
||||
+ targTagW.getName();
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(99).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat99TargetsWithNameOrDescriptionAreInGivenStatus(final List<TargetUpdateStatus> unknown,
|
||||
final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(unknown, null, "%targ-A%", null, Boolean.FALSE);
|
||||
final String query = "updatestatus==unknown and (name==*targ-A* or description==*targ-A*)";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(99).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat0TargetsAreInStatusUnknownAndHaveDSAssigned(final DistributionSet setA,
|
||||
final List<TargetUpdateStatus> unknown) {
|
||||
final FilterParams filterParams = new FilterParams(unknown, null, null, setA.getId(), Boolean.FALSE);
|
||||
final String query = "updatestatus==unknown and (assignedds.name==" + setA.getName() + " or installedds.name=="
|
||||
+ setA.getName() + ")";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(0).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and filter query returns the same result")
|
||||
.hasSize(targetManagement.findByRsql(PAGE, query).getContent().size());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat198TargetsAreInStatusUnknownAndHaveGivenTags(final TargetTag targTagY,
|
||||
final TargetTag targTagW, final List<TargetUpdateStatus> unknown, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(unknown, null, null, null, Boolean.FALSE, targTagY.getName(),
|
||||
targTagW.getName());
|
||||
final String query = "updatestatus==unknown and (tag==" + targTagY.getName() + " or tag==" + targTagW.getName()
|
||||
+ ")";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(198).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat496TargetsAreInStatusUnknown(final List<TargetUpdateStatus> unknown,
|
||||
final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(unknown, null, null, null, Boolean.FALSE);
|
||||
final String query = "updatestatus==unknown";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(496).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat198TargetsAreInStatusUnknownAndOverdue(final List<TargetUpdateStatus> unknown,
|
||||
final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(unknown, Boolean.TRUE, null, null, Boolean.FALSE);
|
||||
// be careful: simple filters are concatenated using AND-gating
|
||||
final String query = "lastcontrollerrequestat=le=${overdue_ts};updatestatus==UNKNOWN";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(198).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat1TargetWithDescOrNameHasDS(final DistributionSet setA, final Target expected) {
|
||||
final FilterParams filterParams = new FilterParams(null, null, "%targ-A%", setA.getId(), Boolean.FALSE);
|
||||
final String query = "(name==*targ-A* or description==*targ-A*) and (assignedds.name==" + setA.getName()
|
||||
+ " or installedds.name==" + setA.getName() + ")";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(1).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsExactly(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat3TargetsHaveDSAssigned(final DistributionSet setA, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(null, null, null, setA.getId(), Boolean.FALSE);
|
||||
final String query = "assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName();
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(3).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat0TargetsWithNameOrdescAndDSHaveTag(final TargetTag targTagX, final DistributionSet setA) {
|
||||
final FilterParams filterParams = new FilterParams(null, null, "%targ-C%", setA.getId(), Boolean.FALSE,
|
||||
targTagX.getName());
|
||||
final String query = "(name==*targ-C* or description==*targ-C*) and tag==" + targTagX.getName()
|
||||
+ " and (assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName() + ")";
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(0).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and filter query returns the same result")
|
||||
.hasSize(targetManagement.findByRsql(PAGE, query).getContent().size());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat0TargetsWithTagAndDescOrNameHasDS(final TargetTag targTagW, final DistributionSet setA) {
|
||||
final FilterParams filterParams = new FilterParams(null, null, "%targ-A%", setA.getId(), Boolean.FALSE,
|
||||
targTagW.getName());
|
||||
final String query = "(name==*targ-A* or description==*targ-A*) and tag==" + targTagW.getName()
|
||||
+ " and (assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName() + ")";
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(0).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and filter query returns the same result")
|
||||
.hasSize(targetManagement.findByRsql(PAGE, query).getContent().size());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat1TargetHasTagHasDescOrNameAndDs(final TargetTag targTagW, final DistributionSet setA,
|
||||
final Target expected) {
|
||||
final FilterParams filterParams = new FilterParams(null, null, "%targ-C%", setA.getId(), Boolean.FALSE,
|
||||
targTagW.getName());
|
||||
final String query = "(name==*targ-c* or description==*targ-C*) and tag==" + targTagW.getName()
|
||||
+ " and (assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName() + ")";
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(1).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsExactly(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat1TargetHasNameAndId(final String name, final String controllerId) {
|
||||
final FilterParams filterParamsByName = new FilterParams(null, null, name, null, Boolean.FALSE);
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParamsByName).getContent()).as("has number of elements")
|
||||
.hasSize(1).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParamsByName));
|
||||
|
||||
final FilterParams filterParamsByControllerId = new FilterParams(null, null, controllerId, null, Boolean.FALSE);
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParamsByControllerId).getContent())
|
||||
.as("has number of elements").hasSize(1).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParamsByControllerId));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat100TargetsContainsGivenTextAndHaveTagAssigned(final TargetTag targTagY,
|
||||
final TargetTag targTagW, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(null, null, "%targ-B%", null, Boolean.FALSE,
|
||||
targTagY.getName(), targTagW.getName());
|
||||
final String query = "(name==*targ-B* or description==*targ-B*) and (tag==" + targTagY.getName() + " or tag=="
|
||||
+ targTagW.getName() + ")";
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(100).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private List<Target> concat(final List<Target>... targets) {
|
||||
final List<Target> result = new ArrayList<>();
|
||||
Arrays.asList(targets).forEach(result::addAll);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat200TargetsHaveTagD(final TargetTag targTagD, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(null, null, null, null, Boolean.FALSE, targTagD.getName());
|
||||
final String query = "tag==" + targTagD.getName();
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("Expected number of results is")
|
||||
.hasSize(200).as("and is expected number of results is equal to ")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThatRepositoryContains500Targets() {
|
||||
final FilterParams filterParams = new FilterParams(null, null, null, null, null);
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent())
|
||||
.as("Overall we expect that many targets in the repository").hasSize(500)
|
||||
.as("which is also reflected by repository count").hasSize((int)targetManagement.count())
|
||||
.as("which is also reflected by call without specification")
|
||||
.containsAll(targetManagement.findAll(PAGE).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat1TargetHasTypeAndDSAssigned(final TargetType type, final DistributionSet set,
|
||||
final Target expected) {
|
||||
final FilterParams filterParams = new FilterParams(null, set.getId(), Boolean.FALSE, type.getId());
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(1).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsExactly(expected);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThatTargetsHasNoTypeAndDSAssignedOrInstalled(final DistributionSet set,
|
||||
final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(null, set.getId(), Boolean.TRUE, null);
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(expected.size()).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat100TargetsContainsGivenTextAndHaveTypeAssigned(final TargetType targetType,
|
||||
final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams("%targ-E%", null, Boolean.FALSE, targetType.getId());
|
||||
final List<Target> filteredTargets = targetManagement.findByFilters(PAGE, filterParams).getContent();
|
||||
assertThat(filteredTargets).as("has number of elements").hasSize(100)
|
||||
.as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams));
|
||||
// Comparing the controller ids, as one of the targets was modified, so
|
||||
// a 1:1
|
||||
// comparison of the objects is not possible
|
||||
assertThat(filteredTargets.stream().map(Target::getControllerId).collect(Collectors.toList()))
|
||||
.containsAll(expected.stream().map(Target::getControllerId).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat400TargetsContainsGivenTextAndHaveNoTypeAssigned(final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams("%targ-%", null, Boolean.TRUE, null);
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(400).as("that number is also returned by count query")
|
||||
.hasSize((int)targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Tests the correct order of targets based on selected distribution set. The system expects to have an order based on installed, assigned DS.")
|
||||
void targetSearchWithVariousFilterCombinationsAndOrderByDistributionSet() {
|
||||
@@ -624,11 +269,6 @@ class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
||||
assertThatTargetNameEquals(targetsOrderedByDistAndName, 8, notAssigned, 0);
|
||||
}
|
||||
|
||||
private void assertThatTargetNameEquals(final List<Target> targets1, final int index1, final List<Target> targets2,
|
||||
final int index2) {
|
||||
assertThat(targets1.get(index1).getName()).isEqualTo(targets2.get(index2).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Tests the correct order of targets with applied overdue filter based on selected distribution set. The system expects to have an order based on installed, assigned DS.")
|
||||
void targetSearchWithOverdueFilterAndOrderByDistributionSet() {
|
||||
@@ -794,32 +434,391 @@ class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
||||
.doesNotContainAnyElementsOf(targetsWithIncompatibleType);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat1TargetAIsInStatusPendingAndHasDSInstalled(final DistributionSet installedSet,
|
||||
final List<TargetUpdateStatus> pending, final Target expected) {
|
||||
final FilterParams filterParams = new FilterParams(pending, null, null, installedSet.getId(), Boolean.FALSE);
|
||||
final String query = "updatestatus==pending and installedds.name==" + installedSet.getName();
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(1).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsExactly(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat200targetsWithGivenTagAreInStatusPendingorUnknown(final TargetTag targTagW,
|
||||
final List<TargetUpdateStatus> both, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(both, null, null, null, Boolean.FALSE, targTagW.getName());
|
||||
final String query = "(updatestatus==pending or updatestatus==unknown) and tag==" + targTagW.getName();
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(200).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat2TargetsWithGivenTagAreInPending(final TargetTag targTagW,
|
||||
final List<TargetUpdateStatus> pending, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(pending, null, null, null, Boolean.FALSE,
|
||||
targTagW.getName());
|
||||
final String query = "updatestatus==pending and tag==" + targTagW.getName();
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(2).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat2TargetsWithGivenTagAndDSIsInPending(final TargetTag targTagW, final DistributionSet setA,
|
||||
final List<TargetUpdateStatus> pending, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(pending, null, null, setA.getId(), Boolean.FALSE,
|
||||
targTagW.getName());
|
||||
final String query = "updatestatus==pending and (assignedds.name==" + setA.getName() + " or installedds.name=="
|
||||
+ setA.getName() + ") and tag==" + targTagW.getName();
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(2).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat1TargetWithGivenNameOrDescAndTagAndDSIsInPending(final TargetTag targTagW,
|
||||
final DistributionSet setA, final List<TargetUpdateStatus> pending, final Target expected) {
|
||||
final FilterParams filterParams = new FilterParams(pending, null, "%targ-B%", setA.getId(), Boolean.FALSE,
|
||||
targTagW.getName());
|
||||
final String query = "updatestatus==pending and (assignedds.name==" + setA.getName() + " or installedds.name=="
|
||||
+ setA.getName() + ") and (name==*targ-B* or description==*targ-B*) and tag==" + targTagW.getName();
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(1).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsExactly(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat1TargetWithGivenNameOrDescAndDSIsInPending(final DistributionSet setA,
|
||||
final List<TargetUpdateStatus> pending, final Target expected) {
|
||||
final FilterParams filterParams = new FilterParams(pending, null, "%targ-A%", setA.getId(), Boolean.FALSE);
|
||||
final String query = "updatestatus==pending and (assignedds.name==" + setA.getName() + " or installedds.name=="
|
||||
+ setA.getName() + ") and (name==*targ-A* or description==*targ-A*)";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(1).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsExactly(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat3TargetsWithGivenDSAreInPending(final DistributionSet setA,
|
||||
final List<TargetUpdateStatus> pending, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(pending, null, null, setA.getId(), Boolean.FALSE);
|
||||
final String query = "updatestatus==pending and (assignedds.name==" + setA.getName() + " or installedds.name=="
|
||||
+ setA.getName() + ")";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(3).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat4TargetsAreInStatusPending(final List<TargetUpdateStatus> pending,
|
||||
final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(pending, null, null, null, Boolean.FALSE);
|
||||
final String query = "updatestatus==pending";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(4).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat99TargetsWithGivenNameOrDescAndTagAreInStatusUnknown(final TargetTag targTagW,
|
||||
final List<TargetUpdateStatus> unknown, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(unknown, null, "%targ-B%", null, Boolean.FALSE,
|
||||
targTagW.getName());
|
||||
final String query = "updatestatus==unknown and (name==*targ-B* or description==*targ-B*) and tag=="
|
||||
+ targTagW.getName();
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(99).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat99TargetsWithNameOrDescriptionAreInGivenStatus(final List<TargetUpdateStatus> unknown,
|
||||
final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(unknown, null, "%targ-A%", null, Boolean.FALSE);
|
||||
final String query = "updatestatus==unknown and (name==*targ-A* or description==*targ-A*)";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(99).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat0TargetsAreInStatusUnknownAndHaveDSAssigned(final DistributionSet setA,
|
||||
final List<TargetUpdateStatus> unknown) {
|
||||
final FilterParams filterParams = new FilterParams(unknown, null, null, setA.getId(), Boolean.FALSE);
|
||||
final String query = "updatestatus==unknown and (assignedds.name==" + setA.getName() + " or installedds.name=="
|
||||
+ setA.getName() + ")";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(0).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and filter query returns the same result")
|
||||
.hasSize(targetManagement.findByRsql(PAGE, query).getContent().size());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat198TargetsAreInStatusUnknownAndHaveGivenTags(final TargetTag targTagY,
|
||||
final TargetTag targTagW, final List<TargetUpdateStatus> unknown, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(unknown, null, null, null, Boolean.FALSE, targTagY.getName(),
|
||||
targTagW.getName());
|
||||
final String query = "updatestatus==unknown and (tag==" + targTagY.getName() + " or tag==" + targTagW.getName()
|
||||
+ ")";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(198).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat496TargetsAreInStatusUnknown(final List<TargetUpdateStatus> unknown,
|
||||
final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(unknown, null, null, null, Boolean.FALSE);
|
||||
final String query = "updatestatus==unknown";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(496).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat198TargetsAreInStatusUnknownAndOverdue(final List<TargetUpdateStatus> unknown,
|
||||
final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(unknown, Boolean.TRUE, null, null, Boolean.FALSE);
|
||||
// be careful: simple filters are concatenated using AND-gating
|
||||
final String query = "lastcontrollerrequestat=le=${overdue_ts};updatestatus==UNKNOWN";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(198).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat1TargetWithDescOrNameHasDS(final DistributionSet setA, final Target expected) {
|
||||
final FilterParams filterParams = new FilterParams(null, null, "%targ-A%", setA.getId(), Boolean.FALSE);
|
||||
final String query = "(name==*targ-A* or description==*targ-A*) and (assignedds.name==" + setA.getName()
|
||||
+ " or installedds.name==" + setA.getName() + ")";
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(1).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsExactly(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat3TargetsHaveDSAssigned(final DistributionSet setA, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(null, null, null, setA.getId(), Boolean.FALSE);
|
||||
final String query = "assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName();
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(3).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat0TargetsWithNameOrdescAndDSHaveTag(final TargetTag targTagX, final DistributionSet setA) {
|
||||
final FilterParams filterParams = new FilterParams(null, null, "%targ-C%", setA.getId(), Boolean.FALSE,
|
||||
targTagX.getName());
|
||||
final String query = "(name==*targ-C* or description==*targ-C*) and tag==" + targTagX.getName()
|
||||
+ " and (assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName() + ")";
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(0).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and filter query returns the same result")
|
||||
.hasSize(targetManagement.findByRsql(PAGE, query).getContent().size());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat0TargetsWithTagAndDescOrNameHasDS(final TargetTag targTagW, final DistributionSet setA) {
|
||||
final FilterParams filterParams = new FilterParams(null, null, "%targ-A%", setA.getId(), Boolean.FALSE,
|
||||
targTagW.getName());
|
||||
final String query = "(name==*targ-A* or description==*targ-A*) and tag==" + targTagW.getName()
|
||||
+ " and (assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName() + ")";
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(0).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and filter query returns the same result")
|
||||
.hasSize(targetManagement.findByRsql(PAGE, query).getContent().size());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat1TargetHasTagHasDescOrNameAndDs(final TargetTag targTagW, final DistributionSet setA,
|
||||
final Target expected) {
|
||||
final FilterParams filterParams = new FilterParams(null, null, "%targ-C%", setA.getId(), Boolean.FALSE,
|
||||
targTagW.getName());
|
||||
final String query = "(name==*targ-c* or description==*targ-C*) and tag==" + targTagW.getName()
|
||||
+ " and (assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName() + ")";
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(1).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsExactly(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat1TargetHasNameAndId(final String name, final String controllerId) {
|
||||
final FilterParams filterParamsByName = new FilterParams(null, null, name, null, Boolean.FALSE);
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParamsByName).getContent()).as("has number of elements")
|
||||
.hasSize(1).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParamsByName));
|
||||
|
||||
final FilterParams filterParamsByControllerId = new FilterParams(null, null, controllerId, null, Boolean.FALSE);
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParamsByControllerId).getContent())
|
||||
.as("has number of elements").hasSize(1).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParamsByControllerId));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat100TargetsContainsGivenTextAndHaveTagAssigned(final TargetTag targTagY,
|
||||
final TargetTag targTagW, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(null, null, "%targ-B%", null, Boolean.FALSE,
|
||||
targTagY.getName(), targTagW.getName());
|
||||
final String query = "(name==*targ-B* or description==*targ-B*) and (tag==" + targTagY.getName() + " or tag=="
|
||||
+ targTagW.getName() + ")";
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(100).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private List<Target> concat(final List<Target>... targets) {
|
||||
final List<Target> result = new ArrayList<>();
|
||||
Arrays.asList(targets).forEach(result::addAll);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat200TargetsHaveTagD(final TargetTag targTagD, final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(null, null, null, null, Boolean.FALSE, targTagD.getName());
|
||||
final String query = "tag==" + targTagD.getName();
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("Expected number of results is")
|
||||
.hasSize(200).as("and is expected number of results is equal to ")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected)
|
||||
.as("and filter query returns the same result")
|
||||
.containsAll(targetManagement.findByRsql(PAGE, query).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThatRepositoryContains500Targets() {
|
||||
final FilterParams filterParams = new FilterParams(null, null, null, null, null);
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent())
|
||||
.as("Overall we expect that many targets in the repository").hasSize(500)
|
||||
.as("which is also reflected by repository count").hasSize((int) targetManagement.count())
|
||||
.as("which is also reflected by call without specification")
|
||||
.containsAll(targetManagement.findAll(PAGE).getContent());
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat1TargetHasTypeAndDSAssigned(final TargetType type, final DistributionSet set,
|
||||
final Target expected) {
|
||||
final FilterParams filterParams = new FilterParams(null, set.getId(), Boolean.FALSE, type.getId());
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(1).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsExactly(expected);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThatTargetsHasNoTypeAndDSAssignedOrInstalled(final DistributionSet set,
|
||||
final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams(null, set.getId(), Boolean.TRUE, null);
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(expected.size()).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat100TargetsContainsGivenTextAndHaveTypeAssigned(final TargetType targetType,
|
||||
final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams("%targ-E%", null, Boolean.FALSE, targetType.getId());
|
||||
final List<Target> filteredTargets = targetManagement.findByFilters(PAGE, filterParams).getContent();
|
||||
assertThat(filteredTargets).as("has number of elements").hasSize(100)
|
||||
.as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams));
|
||||
// Comparing the controller ids, as one of the targets was modified, so
|
||||
// a 1:1
|
||||
// comparison of the objects is not possible
|
||||
assertThat(filteredTargets.stream().map(Target::getControllerId).collect(Collectors.toList()))
|
||||
.containsAll(expected.stream().map(Target::getControllerId).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThat400TargetsContainsGivenTextAndHaveNoTypeAssigned(final List<Target> expected) {
|
||||
final FilterParams filterParams = new FilterParams("%targ-%", null, Boolean.TRUE, null);
|
||||
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
|
||||
.hasSize(400).as("that number is also returned by count query")
|
||||
.hasSize((int) targetManagement.countByFilters(filterParams))
|
||||
.as("and contains the following elements").containsAll(expected);
|
||||
}
|
||||
|
||||
private void assertThatTargetNameEquals(final List<Target> targets1, final int index1, final List<Target> targets2,
|
||||
final int index2) {
|
||||
assertThat(targets1.get(index1).getName()).isEqualTo(targets2.get(index2).getName());
|
||||
}
|
||||
|
||||
private DistributionSet createDistSetWithType(final DistributionSetType type) {
|
||||
final DistributionSetCreate dsCreate = entityFactory.distributionSet().create().name("test-ds").version("1.0")
|
||||
.type(type);
|
||||
return distributionSetManagement.create(dsCreate);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that targets with given target type are returned from repository.")
|
||||
public void findTargetByTargetType() {
|
||||
final TargetType testType = testdataFactory.createTargetType("testType",
|
||||
Collections.singletonList(standardDsType));
|
||||
final List<Target> unassigned = testdataFactory.createTargets(9, "unassigned");
|
||||
final List<Target> assigned = testdataFactory.createTargetsWithType(11, "assigned", testType);
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, new FilterParams(null, null, false, testType.getId())))
|
||||
.as("Contains the targets with set type").containsAll(assigned)
|
||||
.as("and that means the following expected amount").hasSize(11);
|
||||
assertThat(targetManagement.countByFilters(new FilterParams(null, null, false, testType.getId())))
|
||||
.as("Count the targets with set type").isEqualTo(11);
|
||||
|
||||
assertThat(targetManagement.findByFilters(PAGE, new FilterParams(null, null, true, null)))
|
||||
.as("Contains the targets without a type").containsAll(unassigned)
|
||||
.as("and that means the following expected amount").hasSize(9);
|
||||
assertThat(targetManagement.countByFilters(new FilterParams(null, null, true, null)))
|
||||
.as("Counts the targets without a type").isEqualTo(9);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,6 +27,10 @@ import java.util.stream.Collectors;
|
||||
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.awaitility.Awaitility;
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||
@@ -82,11 +86,6 @@ import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Slice;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("Target Management")
|
||||
class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
@@ -252,136 +251,6 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
createAndUpdateTargetWithInvalidAddress(target);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTargetWithInvalidDescription(final Target target) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long description should not be created")
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a")
|
||||
.description(RandomStringUtils.randomAlphanumeric(513))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with invalid description should not be created").isThrownBy(() -> targetManagement
|
||||
.create(entityFactory.target().create().controllerId("a").description(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long description should not be updated")
|
||||
.isThrownBy(() -> targetManagement.update(entityFactory.target().update(target.getControllerId())
|
||||
.description(RandomStringUtils.randomAlphanumeric(513))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with invalid description should not be updated").isThrownBy(() -> targetManagement.update(
|
||||
entityFactory.target().update(target.getControllerId()).description(INVALID_TEXT_HTML)));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTargetWithInvalidName(final Target target) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long name should not be created")
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a")
|
||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with invalid name should not be created").isThrownBy(() -> targetManagement
|
||||
.create(entityFactory.target().create().controllerId("a").name(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long name should not be updated")
|
||||
.isThrownBy(() -> targetManagement.update(entityFactory.target().update(target.getControllerId())
|
||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with invalid name should not be updated").isThrownBy(() -> targetManagement
|
||||
.update(entityFactory.target().update(target.getControllerId()).name(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too short name should not be updated").isThrownBy(() -> targetManagement
|
||||
.update(entityFactory.target().update(target.getControllerId()).name("")));
|
||||
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTargetWithInvalidSecurityToken(final Target target) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long token should not be created")
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a")
|
||||
.securityToken(RandomStringUtils.randomAlphanumeric(Target.SECURITY_TOKEN_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with invalid token should not be created").isThrownBy(() -> targetManagement
|
||||
.create(entityFactory.target().create().controllerId("a").securityToken(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long token should not be updated")
|
||||
.isThrownBy(() -> targetManagement.update(entityFactory.target().update(target.getControllerId())
|
||||
.securityToken(RandomStringUtils.randomAlphanumeric(Target.SECURITY_TOKEN_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with invalid token should not be updated").isThrownBy(() -> targetManagement.update(
|
||||
entityFactory.target().update(target.getControllerId()).securityToken(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too short token should not be updated").isThrownBy(() -> targetManagement
|
||||
.update(entityFactory.target().update(target.getControllerId()).securityToken("")));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTargetWithInvalidAddress(final Target target) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long address should not be created")
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a")
|
||||
.address(RandomStringUtils.randomAlphanumeric(513))));
|
||||
|
||||
assertThatExceptionOfType(InvalidTargetAddressException.class).as("target with invalid should not be created")
|
||||
.isThrownBy(() -> targetManagement
|
||||
.create(entityFactory.target().create().controllerId("a").address(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long address should not be updated")
|
||||
.isThrownBy(() -> targetManagement.update(entityFactory.target().update(target.getControllerId())
|
||||
.address(RandomStringUtils.randomAlphanumeric(513))));
|
||||
|
||||
assertThatExceptionOfType(InvalidTargetAddressException.class)
|
||||
.as("target with invalid address should not be updated").isThrownBy(() -> targetManagement
|
||||
.update(entityFactory.target().update(target.getControllerId()).address(INVALID_TEXT_HTML)));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createTargetWithInvalidControllerId() {
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with empty controller id should not be created")
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("")));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with null controller id should not be created")
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(null)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long controller id should not be created")
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create()
|
||||
.controllerId(RandomStringUtils.randomAlphanumeric(Target.CONTROLLER_ID_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with invalid controller id should not be created").isThrownBy(
|
||||
() -> targetManagement.create(entityFactory.target().create().controllerId(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as(WHITESPACE_ERROR)
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(" ")));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as(WHITESPACE_ERROR)
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a b")));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as(WHITESPACE_ERROR)
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(" ")));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as(WHITESPACE_ERROR)
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("aaa bbb")));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that targets can assigned and unassigned to a target tag. Not exists target will be ignored for the assignment.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 4),
|
||||
@@ -450,18 +319,6 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(targetManagement.count()).as("target count is wrong").isZero();
|
||||
}
|
||||
|
||||
private Target createTargetWithAttributes(final String controllerId) {
|
||||
final Map<String, String> testData = new HashMap<>();
|
||||
testData.put("test1", "testdata1");
|
||||
|
||||
targetManagement.create(entityFactory.target().create().controllerId(controllerId));
|
||||
final Target target = controllerManagement.updateControllerAttributes(controllerId, testData, null);
|
||||
|
||||
assertThat(targetManagement.getControllerAttributes(controllerId)).as("Controller Attributes are wrong")
|
||||
.isEqualTo(testData);
|
||||
return target;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Finds a target by given ID and checks if all data is in the response (including the data defined as lazy).")
|
||||
@ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 2),
|
||||
@@ -554,50 +411,6 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* verifies, that all {@link TargetTag} of parameter. NOTE: it's accepted
|
||||
* that the target have additional tags assigned to them which are not
|
||||
* contained within parameter tags.
|
||||
*
|
||||
* @param strict
|
||||
* if true, the given targets MUST contain EXACTLY ALL given
|
||||
* tags, AND NO OTHERS. If false, the given targets MUST contain
|
||||
* ALL given tags, BUT MAY CONTAIN FURTHER ONE
|
||||
* @param targets
|
||||
* targets to be verified
|
||||
* @param tags
|
||||
* are contained within tags of all targets.
|
||||
*/
|
||||
private void checkTargetHasTags(final boolean strict, final Iterable<Target> targets, final TargetTag... tags) {
|
||||
_target: for (final Target tl : targets) {
|
||||
for (final Tag tt : getTargetTags(tl.getControllerId())) {
|
||||
for (final Tag tag : tags) {
|
||||
if (tag.getName().equals(tt.getName())) {
|
||||
continue _target;
|
||||
}
|
||||
}
|
||||
if (strict) {
|
||||
fail("Target does not contain all tags");
|
||||
}
|
||||
}
|
||||
fail("Target does not contain any tags or the expected tag was not found");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkTargetHasNotTags(final Iterable<Target> targets, final TargetTag... tags) {
|
||||
for (final Target tl : targets) {
|
||||
targetManagement.getByControllerID(tl.getControllerId()).get();
|
||||
|
||||
for (final Tag tag : tags) {
|
||||
for (final Tag tt : getTargetTags(tl.getControllerId())) {
|
||||
if (tag.getName().equals(tt.getName())) {
|
||||
fail("Target should have no tags");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUser(allSpPermissions = true)
|
||||
@Description("Creates and updates a target and verifies the changes in the repository.")
|
||||
@@ -662,7 +475,8 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// verify that all entries are found
|
||||
_founds: for (final Target foundTarget : allFound) {
|
||||
_founds:
|
||||
for (final Target foundTarget : allFound) {
|
||||
for (final Target changedTarget : firstList) {
|
||||
if (changedTarget.getControllerId().equals(foundTarget.getControllerId())) {
|
||||
assertThat(changedTarget.getDescription())
|
||||
@@ -970,13 +784,6 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(createdMetadata.getValue()).isEqualTo(knownValue);
|
||||
}
|
||||
|
||||
private JpaTargetMetadata insertTargetMetadata(final String knownKey, final String knownValue,
|
||||
final Target target) {
|
||||
final JpaTargetMetadata metadata = new JpaTargetMetadata(knownKey, knownValue, target);
|
||||
return (JpaTargetMetadata) targetManagement
|
||||
.createMetaData(target.getControllerId(), Collections.singletonList(metadata)).get(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies the enforcement of the metadata quota per target.")
|
||||
void createTargetMetadataUntilQuotaIsExceeded() {
|
||||
@@ -1163,16 +970,6 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
checkTargetsHaveType(typeATargets, typeB);
|
||||
}
|
||||
|
||||
private void checkTargetsHaveType(final List<Target> targets, final TargetType type) {
|
||||
final List<JpaTarget> foundTargets = targetRepository
|
||||
.findAllById(targets.stream().map(Identifiable::getId).collect(Collectors.toList()));
|
||||
for (final Target target : foundTargets) {
|
||||
if (!type.getName().equals(type.getName())) {
|
||||
fail(String.format("Target %s is not of type %s.", target, type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Queries and loads the metadata related to a given target.")
|
||||
void findAllTargetMetadataByControllerId() {
|
||||
@@ -1193,26 +990,6 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(metadataOfTarget2.getTotalElements()).isEqualTo(8);
|
||||
}
|
||||
|
||||
private Target createTargetWithMetadata(final String controllerId, final int count) {
|
||||
final Target target = testdataFactory.createTarget(controllerId);
|
||||
|
||||
for (int index = 1; index <= count; index++) {
|
||||
insertTargetMetadata("key" + index, controllerId + "-value" + index, target);
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
private Target createTargetWithTargetTypeAndMetadata(final String controllerId, final long targetTypeId, final int count) {
|
||||
final Target target = testdataFactory.createTarget(controllerId, controllerId, targetTypeId);
|
||||
|
||||
for (int index = 1; index <= count; index++) {
|
||||
insertTargetMetadata("key" + index, controllerId + "-value" + index, target);
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUser(allSpPermissions = true)
|
||||
@Description("Checks that target type is not assigned to target if invalid.")
|
||||
@@ -1411,7 +1188,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
createAction(targets.get(8), rolloutNewer, 20, Status.DOWNLOADED, distributionSet);
|
||||
|
||||
final Slice<Target> matching = targetManagement.findByNotInGEGroupAndNotInActiveActionGEWeightOrInRolloutAndTargetFilterQueryAndCompatibleAndUpdatable(
|
||||
PAGE, rollout.getId(), 10, Long.MAX_VALUE,"controllerid==dyn_action_filter_*", distributionSet.getType());
|
||||
PAGE, rollout.getId(), 10, Long.MAX_VALUE, "controllerid==dyn_action_filter_*", distributionSet.getType());
|
||||
|
||||
assertThat(matching.getNumberOfElements()).isEqualTo(5);
|
||||
assertThat(matching.stream()
|
||||
@@ -1421,7 +1198,239 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
.sorted()
|
||||
.toList()).isEqualTo(List.of(0, 1, 2, 5, 6));
|
||||
}
|
||||
private void createAction(final Target target, final Rollout rollout, final Integer weight, final Action.Status status, final DistributionSet distributionSet) {
|
||||
|
||||
@Test
|
||||
@Description("Target matches filter for not existing DS.")
|
||||
void matchesFilterDsNotExists() {
|
||||
final String target = testdataFactory.createTarget().getControllerId();
|
||||
|
||||
assertThatExceptionOfType(EntityNotFoundException.class).isThrownBy(
|
||||
() -> targetManagement.isTargetMatchingQueryAndDSNotAssignedAndCompatibleAndUpdatable(target, 123, "name==*"));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTargetWithInvalidDescription(final Target target) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long description should not be created")
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a")
|
||||
.description(RandomStringUtils.randomAlphanumeric(513))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with invalid description should not be created").isThrownBy(() -> targetManagement
|
||||
.create(entityFactory.target().create().controllerId("a").description(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long description should not be updated")
|
||||
.isThrownBy(() -> targetManagement.update(entityFactory.target().update(target.getControllerId())
|
||||
.description(RandomStringUtils.randomAlphanumeric(513))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with invalid description should not be updated").isThrownBy(() -> targetManagement.update(
|
||||
entityFactory.target().update(target.getControllerId()).description(INVALID_TEXT_HTML)));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTargetWithInvalidName(final Target target) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long name should not be created")
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a")
|
||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with invalid name should not be created").isThrownBy(() -> targetManagement
|
||||
.create(entityFactory.target().create().controllerId("a").name(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long name should not be updated")
|
||||
.isThrownBy(() -> targetManagement.update(entityFactory.target().update(target.getControllerId())
|
||||
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with invalid name should not be updated").isThrownBy(() -> targetManagement
|
||||
.update(entityFactory.target().update(target.getControllerId()).name(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too short name should not be updated").isThrownBy(() -> targetManagement
|
||||
.update(entityFactory.target().update(target.getControllerId()).name("")));
|
||||
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTargetWithInvalidSecurityToken(final Target target) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long token should not be created")
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a")
|
||||
.securityToken(RandomStringUtils.randomAlphanumeric(Target.SECURITY_TOKEN_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with invalid token should not be created").isThrownBy(() -> targetManagement
|
||||
.create(entityFactory.target().create().controllerId("a").securityToken(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long token should not be updated")
|
||||
.isThrownBy(() -> targetManagement.update(entityFactory.target().update(target.getControllerId())
|
||||
.securityToken(RandomStringUtils.randomAlphanumeric(Target.SECURITY_TOKEN_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with invalid token should not be updated").isThrownBy(() -> targetManagement.update(
|
||||
entityFactory.target().update(target.getControllerId()).securityToken(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too short token should not be updated").isThrownBy(() -> targetManagement
|
||||
.update(entityFactory.target().update(target.getControllerId()).securityToken("")));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTargetWithInvalidAddress(final Target target) {
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long address should not be created")
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a")
|
||||
.address(RandomStringUtils.randomAlphanumeric(513))));
|
||||
|
||||
assertThatExceptionOfType(InvalidTargetAddressException.class).as("target with invalid should not be created")
|
||||
.isThrownBy(() -> targetManagement
|
||||
.create(entityFactory.target().create().controllerId("a").address(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long address should not be updated")
|
||||
.isThrownBy(() -> targetManagement.update(entityFactory.target().update(target.getControllerId())
|
||||
.address(RandomStringUtils.randomAlphanumeric(513))));
|
||||
|
||||
assertThatExceptionOfType(InvalidTargetAddressException.class)
|
||||
.as("target with invalid address should not be updated").isThrownBy(() -> targetManagement
|
||||
.update(entityFactory.target().update(target.getControllerId()).address(INVALID_TEXT_HTML)));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createTargetWithInvalidControllerId() {
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with empty controller id should not be created")
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("")));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with null controller id should not be created")
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(null)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with too long controller id should not be created")
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create()
|
||||
.controllerId(RandomStringUtils.randomAlphanumeric(Target.CONTROLLER_ID_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("target with invalid controller id should not be created").isThrownBy(
|
||||
() -> targetManagement.create(entityFactory.target().create().controllerId(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as(WHITESPACE_ERROR)
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(" ")));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as(WHITESPACE_ERROR)
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a b")));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as(WHITESPACE_ERROR)
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(" ")));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as(WHITESPACE_ERROR)
|
||||
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("aaa bbb")));
|
||||
|
||||
}
|
||||
|
||||
private Target createTargetWithAttributes(final String controllerId) {
|
||||
final Map<String, String> testData = new HashMap<>();
|
||||
testData.put("test1", "testdata1");
|
||||
|
||||
targetManagement.create(entityFactory.target().create().controllerId(controllerId));
|
||||
final Target target = controllerManagement.updateControllerAttributes(controllerId, testData, null);
|
||||
|
||||
assertThat(targetManagement.getControllerAttributes(controllerId)).as("Controller Attributes are wrong")
|
||||
.isEqualTo(testData);
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* verifies, that all {@link TargetTag} of parameter. NOTE: it's accepted
|
||||
* that the target have additional tags assigned to them which are not
|
||||
* contained within parameter tags.
|
||||
*
|
||||
* @param strict if true, the given targets MUST contain EXACTLY ALL given
|
||||
* tags, AND NO OTHERS. If false, the given targets MUST contain
|
||||
* ALL given tags, BUT MAY CONTAIN FURTHER ONE
|
||||
* @param targets targets to be verified
|
||||
* @param tags are contained within tags of all targets.
|
||||
*/
|
||||
private void checkTargetHasTags(final boolean strict, final Iterable<Target> targets, final TargetTag... tags) {
|
||||
_target:
|
||||
for (final Target tl : targets) {
|
||||
for (final Tag tt : getTargetTags(tl.getControllerId())) {
|
||||
for (final Tag tag : tags) {
|
||||
if (tag.getName().equals(tt.getName())) {
|
||||
continue _target;
|
||||
}
|
||||
}
|
||||
if (strict) {
|
||||
fail("Target does not contain all tags");
|
||||
}
|
||||
}
|
||||
fail("Target does not contain any tags or the expected tag was not found");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkTargetHasNotTags(final Iterable<Target> targets, final TargetTag... tags) {
|
||||
for (final Target tl : targets) {
|
||||
targetManagement.getByControllerID(tl.getControllerId()).get();
|
||||
|
||||
for (final Tag tag : tags) {
|
||||
for (final Tag tt : getTargetTags(tl.getControllerId())) {
|
||||
if (tag.getName().equals(tt.getName())) {
|
||||
fail("Target should have no tags");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private JpaTargetMetadata insertTargetMetadata(final String knownKey, final String knownValue,
|
||||
final Target target) {
|
||||
final JpaTargetMetadata metadata = new JpaTargetMetadata(knownKey, knownValue, target);
|
||||
return (JpaTargetMetadata) targetManagement
|
||||
.createMetaData(target.getControllerId(), Collections.singletonList(metadata)).get(0);
|
||||
}
|
||||
|
||||
private void checkTargetsHaveType(final List<Target> targets, final TargetType type) {
|
||||
final List<JpaTarget> foundTargets = targetRepository
|
||||
.findAllById(targets.stream().map(Identifiable::getId).collect(Collectors.toList()));
|
||||
for (final Target target : foundTargets) {
|
||||
if (!type.getName().equals(type.getName())) {
|
||||
fail(String.format("Target %s is not of type %s.", target, type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Target createTargetWithMetadata(final String controllerId, final int count) {
|
||||
final Target target = testdataFactory.createTarget(controllerId);
|
||||
|
||||
for (int index = 1; index <= count; index++) {
|
||||
insertTargetMetadata("key" + index, controllerId + "-value" + index, target);
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
private Target createTargetWithTargetTypeAndMetadata(final String controllerId, final long targetTypeId, final int count) {
|
||||
final Target target = testdataFactory.createTarget(controllerId, controllerId, targetTypeId);
|
||||
|
||||
for (int index = 1; index <= count; index++) {
|
||||
insertTargetMetadata("key" + index, controllerId + "-value" + index, target);
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
private void createAction(final Target target, final Rollout rollout, final Integer weight, final Action.Status status,
|
||||
final DistributionSet distributionSet) {
|
||||
final JpaAction action = new JpaAction();
|
||||
action.setActionType(Action.ActionType.FORCED);
|
||||
action.setTarget(target);
|
||||
@@ -1437,15 +1446,6 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
actionRepository.save(action);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Target matches filter for not existing DS.")
|
||||
void matchesFilterDsNotExists() {
|
||||
final String target = testdataFactory.createTarget().getControllerId();
|
||||
|
||||
assertThatExceptionOfType(EntityNotFoundException.class).isThrownBy(
|
||||
() -> targetManagement.isTargetMatchingQueryAndDSNotAssignedAndCompatibleAndUpdatable(target, 123, "name==*"));
|
||||
}
|
||||
|
||||
private void validateFoundTargetsByRsql(final String rsqlFilter, final String... controllerIds) {
|
||||
final Slice<Target> foundTargetsByMetadataAndControllerId = targetManagement.findByRsql(PAGE, rsqlFilter);
|
||||
final long foundTargetsByMetadataAndControllerIdCount = targetManagement.countByRsql(rsqlFilter);
|
||||
|
||||
@@ -23,6 +23,10 @@ import java.util.stream.Collectors;
|
||||
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.eclipse.hawkbit.repository.TargetTagManagement;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagUpdatedEvent;
|
||||
@@ -32,21 +36,13 @@ import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||
import org.eclipse.hawkbit.repository.model.NamedEntity;
|
||||
import org.eclipse.hawkbit.repository.model.Tag;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||
import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.test.matcher.Expect;
|
||||
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
/**
|
||||
@@ -56,129 +52,8 @@ import org.springframework.data.domain.Pageable;
|
||||
@Story("Target Tag Management")
|
||||
class TargetTagManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Verifies that management get access reacts as specfied on calls for non existing entities by means " +
|
||||
"of Optional not present.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||
void nonExistingEntityAccessReturnsNotPresent() {
|
||||
assertThat(targetTagManagement.getByName(NOT_EXIST_ID)).isNotPresent();
|
||||
assertThat(targetTagManagement.get(NOT_EXIST_IDL)).isNotPresent();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that management queries react as specfied on calls for non existing entities " +
|
||||
" by means of throwing EntityNotFoundException.")
|
||||
@ExpectEvents({ @Expect(type = DistributionSetTagUpdatedEvent.class), @Expect(type = TargetTagUpdatedEvent.class) })
|
||||
void entityQueriesReferringToNotExistingEntitiesThrowsException() {
|
||||
verifyThrownExceptionBy(() -> targetTagManagement.delete(NOT_EXIST_ID), "TargetTag");
|
||||
verifyThrownExceptionBy(() -> targetTagManagement.update(entityFactory.tag().update(NOT_EXIST_IDL)), "TargetTag");
|
||||
verifyThrownExceptionBy(() -> getTargetTags(NOT_EXIST_ID), "Target");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verify that a tag with with invalid properties cannot be created or updated")
|
||||
void createAndUpdateTagWithInvalidFields() {
|
||||
final TargetTag tag = targetTagManagement.create(entityFactory.tag().create().name("tag1").description("tagdesc1"));
|
||||
createAndUpdateTagWithInvalidDescription(tag);
|
||||
createAndUpdateTagWithInvalidColour(tag);
|
||||
createAndUpdateTagWithInvalidName(tag);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTagWithInvalidDescription(final Tag tag) {
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with too long description should not be created")
|
||||
.isThrownBy(() -> targetTagManagement.create(
|
||||
entityFactory.tag().create().name("a").description(RandomStringUtils.randomAlphanumeric(513))));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with invalid description should not be created").isThrownBy(() -> targetTagManagement
|
||||
.create(entityFactory.tag().create().name("a").description(INVALID_TEXT_HTML)));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with too long description should not be updated")
|
||||
.isThrownBy(() -> targetTagManagement.update(
|
||||
entityFactory.tag().update(tag.getId())
|
||||
.description(RandomStringUtils.randomAlphanumeric(513))));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with invalid description should not be updated")
|
||||
.isThrownBy(() -> targetTagManagement
|
||||
.update(entityFactory.tag().update(tag.getId()).description(INVALID_TEXT_HTML)));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTagWithInvalidColour(final Tag tag) {
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with too long colour should not be created")
|
||||
.isThrownBy(() -> targetTagManagement.create(
|
||||
entityFactory.tag().create().name("a").colour(RandomStringUtils.randomAlphanumeric(17))));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with invalid colour should not be created").isThrownBy(() -> targetTagManagement
|
||||
.create(entityFactory.tag().create().name("a").colour(INVALID_TEXT_HTML)));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with too long colour should not be updated")
|
||||
.isThrownBy(() -> targetTagManagement.update(
|
||||
entityFactory.tag().update(tag.getId()).colour(RandomStringUtils.randomAlphanumeric(17))));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with invalid colour should not be updated").isThrownBy(() -> targetTagManagement
|
||||
.update(entityFactory.tag().update(tag.getId()).colour(INVALID_TEXT_HTML)));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTagWithInvalidName(final Tag tag) {
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with too long name should not be created")
|
||||
.isThrownBy(() -> targetTagManagement
|
||||
.create(entityFactory.tag().create().name(RandomStringUtils.randomAlphanumeric(
|
||||
NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with invalidname should not be created")
|
||||
.isThrownBy(() -> targetTagManagement.create(entityFactory.tag().create().name(INVALID_TEXT_HTML)));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with too long name should not be updated")
|
||||
.isThrownBy(() -> targetTagManagement
|
||||
.update(entityFactory.tag().update(tag.getId()).name(RandomStringUtils.randomAlphanumeric(
|
||||
NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as("tag with invalid name should not be updated")
|
||||
.isThrownBy(() -> targetTagManagement
|
||||
.update(entityFactory.tag().update(tag.getId()).name(INVALID_TEXT_HTML)));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with too short name should not be updated")
|
||||
.isThrownBy(() -> targetTagManagement.update(entityFactory.tag().update(tag.getId()).name("")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies assign/unassign.")
|
||||
void assignAndUnassignTargetTags() {
|
||||
final List<Target> groupA = testdataFactory.createTargets(20);
|
||||
final List<Target> groupB = testdataFactory.createTargets(20, "groupb", "groupb");
|
||||
|
||||
final TargetTag tag = targetTagManagement.create(entityFactory.tag().create().name("tag1").description("tagdesc1"));
|
||||
|
||||
// toggle A only -> A is now assigned
|
||||
List<Target> result = assignTag(groupA, tag);
|
||||
assertThat(result).size().isEqualTo(20);
|
||||
assertThat(result).containsAll(
|
||||
targetManagement.getByControllerID(groupA.stream().map(Target::getControllerId).collect(Collectors.toList())));
|
||||
assertThat(targetManagement.findByTag(Pageable.unpaged(), tag.getId()).getContent().stream().map(Target::getControllerId).sorted().toList())
|
||||
.isEqualTo(groupA.stream().map(Target::getControllerId).sorted().toList());
|
||||
|
||||
// toggle A+B -> A is still assigned and B is assigned as well
|
||||
final Collection<Target> groupAB = concat(groupA, groupB);
|
||||
result = assignTag(groupAB, tag);
|
||||
assertThat(result).size().isEqualTo(40);
|
||||
assertThat(result).containsAll(
|
||||
targetManagement.getByControllerID(groupAB.stream().map(Target::getControllerId).collect(Collectors.toList())));
|
||||
assertThat(targetManagement.findByTag(Pageable.unpaged(), tag.getId()).getContent().stream().map(Target::getControllerId).sorted().toList())
|
||||
.isEqualTo(groupAB.stream().map(Target::getControllerId).sorted().toList());
|
||||
|
||||
// toggle A+B -> both unassigned
|
||||
result = unassignTag(groupAB, tag);
|
||||
assertThat(result).size().isEqualTo(40);
|
||||
assertThat(result).containsAll(
|
||||
targetManagement.getByControllerID(groupAB.stream().map(Target::getControllerId).collect(Collectors.toList())));
|
||||
assertThat(targetManagement.findByTag(Pageable.unpaged(), tag.getId()).getContent()).isEmpty();
|
||||
}
|
||||
|
||||
private static final Random RND = new Random();
|
||||
|
||||
@Test
|
||||
@Description("Verifies that tagging of set containing missing DS throws meaningful and correct exception.")
|
||||
public void failOnMissingDs() {
|
||||
@@ -212,11 +87,67 @@ class TargetTagManagementTest extends AbstractJpaIntegrationTest {
|
||||
});
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private <T> Collection<T> concat(final Collection<T>... targets) {
|
||||
final List<T> result = new ArrayList<>();
|
||||
Arrays.asList(targets).forEach(result::addAll);
|
||||
return result;
|
||||
@Test
|
||||
@Description("Verifies that management get access reacts as specfied on calls for non existing entities by means " +
|
||||
"of Optional not present.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
|
||||
void nonExistingEntityAccessReturnsNotPresent() {
|
||||
assertThat(targetTagManagement.getByName(NOT_EXIST_ID)).isNotPresent();
|
||||
assertThat(targetTagManagement.get(NOT_EXIST_IDL)).isNotPresent();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that management queries react as specfied on calls for non existing entities " +
|
||||
" by means of throwing EntityNotFoundException.")
|
||||
@ExpectEvents({ @Expect(type = DistributionSetTagUpdatedEvent.class), @Expect(type = TargetTagUpdatedEvent.class) })
|
||||
void entityQueriesReferringToNotExistingEntitiesThrowsException() {
|
||||
verifyThrownExceptionBy(() -> targetTagManagement.delete(NOT_EXIST_ID), "TargetTag");
|
||||
verifyThrownExceptionBy(() -> targetTagManagement.update(entityFactory.tag().update(NOT_EXIST_IDL)), "TargetTag");
|
||||
verifyThrownExceptionBy(() -> getTargetTags(NOT_EXIST_ID), "Target");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verify that a tag with with invalid properties cannot be created or updated")
|
||||
void createAndUpdateTagWithInvalidFields() {
|
||||
final TargetTag tag = targetTagManagement.create(entityFactory.tag().create().name("tag1").description("tagdesc1"));
|
||||
createAndUpdateTagWithInvalidDescription(tag);
|
||||
createAndUpdateTagWithInvalidColour(tag);
|
||||
createAndUpdateTagWithInvalidName(tag);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies assign/unassign.")
|
||||
void assignAndUnassignTargetTags() {
|
||||
final List<Target> groupA = testdataFactory.createTargets(20);
|
||||
final List<Target> groupB = testdataFactory.createTargets(20, "groupb", "groupb");
|
||||
|
||||
final TargetTag tag = targetTagManagement.create(entityFactory.tag().create().name("tag1").description("tagdesc1"));
|
||||
|
||||
// toggle A only -> A is now assigned
|
||||
List<Target> result = assignTag(groupA, tag);
|
||||
assertThat(result).size().isEqualTo(20);
|
||||
assertThat(result).containsAll(
|
||||
targetManagement.getByControllerID(groupA.stream().map(Target::getControllerId).collect(Collectors.toList())));
|
||||
assertThat(targetManagement.findByTag(Pageable.unpaged(), tag.getId()).getContent().stream().map(Target::getControllerId).sorted()
|
||||
.toList())
|
||||
.isEqualTo(groupA.stream().map(Target::getControllerId).sorted().toList());
|
||||
|
||||
// toggle A+B -> A is still assigned and B is assigned as well
|
||||
final Collection<Target> groupAB = concat(groupA, groupB);
|
||||
result = assignTag(groupAB, tag);
|
||||
assertThat(result).size().isEqualTo(40);
|
||||
assertThat(result).containsAll(
|
||||
targetManagement.getByControllerID(groupAB.stream().map(Target::getControllerId).collect(Collectors.toList())));
|
||||
assertThat(targetManagement.findByTag(Pageable.unpaged(), tag.getId()).getContent().stream().map(Target::getControllerId).sorted()
|
||||
.toList())
|
||||
.isEqualTo(groupAB.stream().map(Target::getControllerId).sorted().toList());
|
||||
|
||||
// toggle A+B -> both unassigned
|
||||
result = unassignTag(groupAB, tag);
|
||||
assertThat(result).size().isEqualTo(40);
|
||||
assertThat(result).containsAll(
|
||||
targetManagement.getByControllerID(groupAB.stream().map(Target::getControllerId).collect(Collectors.toList())));
|
||||
assertThat(targetManagement.findByTag(Pageable.unpaged(), tag.getId()).getContent()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -302,6 +233,74 @@ class TargetTagManagementTest extends AbstractJpaIntegrationTest {
|
||||
.isThrownBy(() -> targetTagManagement.update(entityFactory.tag().update(tag.getId()).name("A")));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTagWithInvalidDescription(final Tag tag) {
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with too long description should not be created")
|
||||
.isThrownBy(() -> targetTagManagement.create(
|
||||
entityFactory.tag().create().name("a").description(RandomStringUtils.randomAlphanumeric(513))));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with invalid description should not be created").isThrownBy(() -> targetTagManagement
|
||||
.create(entityFactory.tag().create().name("a").description(INVALID_TEXT_HTML)));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with too long description should not be updated")
|
||||
.isThrownBy(() -> targetTagManagement.update(
|
||||
entityFactory.tag().update(tag.getId())
|
||||
.description(RandomStringUtils.randomAlphanumeric(513))));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with invalid description should not be updated")
|
||||
.isThrownBy(() -> targetTagManagement
|
||||
.update(entityFactory.tag().update(tag.getId()).description(INVALID_TEXT_HTML)));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTagWithInvalidColour(final Tag tag) {
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with too long colour should not be created")
|
||||
.isThrownBy(() -> targetTagManagement.create(
|
||||
entityFactory.tag().create().name("a").colour(RandomStringUtils.randomAlphanumeric(17))));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with invalid colour should not be created").isThrownBy(() -> targetTagManagement
|
||||
.create(entityFactory.tag().create().name("a").colour(INVALID_TEXT_HTML)));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with too long colour should not be updated")
|
||||
.isThrownBy(() -> targetTagManagement.update(
|
||||
entityFactory.tag().update(tag.getId()).colour(RandomStringUtils.randomAlphanumeric(17))));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with invalid colour should not be updated").isThrownBy(() -> targetTagManagement
|
||||
.update(entityFactory.tag().update(tag.getId()).colour(INVALID_TEXT_HTML)));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTagWithInvalidName(final Tag tag) {
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with too long name should not be created")
|
||||
.isThrownBy(() -> targetTagManagement
|
||||
.create(entityFactory.tag().create().name(RandomStringUtils.randomAlphanumeric(
|
||||
NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with invalidname should not be created")
|
||||
.isThrownBy(() -> targetTagManagement.create(entityFactory.tag().create().name(INVALID_TEXT_HTML)));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with too long name should not be updated")
|
||||
.isThrownBy(() -> targetTagManagement
|
||||
.update(entityFactory.tag().update(tag.getId()).name(RandomStringUtils.randomAlphanumeric(
|
||||
NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class).as("tag with invalid name should not be updated")
|
||||
.isThrownBy(() -> targetTagManagement
|
||||
.update(entityFactory.tag().update(tag.getId()).name(INVALID_TEXT_HTML)));
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("tag with too short name should not be updated")
|
||||
.isThrownBy(() -> targetTagManagement.update(entityFactory.tag().update(tag.getId()).name("")));
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private <T> Collection<T> concat(final Collection<T>... targets) {
|
||||
final List<T> result = new ArrayList<>();
|
||||
Arrays.asList(targets).forEach(result::addAll);
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<JpaTargetTag> createTargetsWithTags() {
|
||||
final List<Target> targets = testdataFactory.createTargets(20);
|
||||
final Iterable<TargetTag> tags = testdataFactory.createTargetTags(20, "");
|
||||
|
||||
@@ -18,6 +18,10 @@ import java.util.Optional;
|
||||
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTypeCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTypeUpdatedEvent;
|
||||
@@ -32,11 +36,6 @@ import org.eclipse.hawkbit.repository.test.matcher.Expect;
|
||||
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("Target Type Management")
|
||||
class TargetTypeManagementTest extends AbstractJpaIntegrationTest {
|
||||
@@ -98,70 +97,6 @@ class TargetTypeManagementTest extends AbstractJpaIntegrationTest {
|
||||
.update(entityFactory.targetType().update(targetType.getId()).description(INVALID_TEXT_HTML)));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTargetTypeWithInvalidColour(final TargetType targetType) {
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with too long colour should not be created")
|
||||
.isThrownBy(() -> targetTypeManagement.create(
|
||||
entityFactory.targetType().create().name("a")
|
||||
.colour(RandomStringUtils.randomAlphanumeric(TargetType.COLOUR_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with invalid colour should not be created").isThrownBy(() -> targetTypeManagement
|
||||
.create(entityFactory.targetType().create().name("a").colour(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with too long colour should not be updated")
|
||||
.isThrownBy(() -> targetTypeManagement.update(
|
||||
entityFactory.targetType().update(targetType.getId())
|
||||
.colour(RandomStringUtils.randomAlphanumeric(TargetType.COLOUR_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with invalid colour should not be updated").isThrownBy(() -> targetTypeManagement
|
||||
.update(entityFactory.targetType().update(targetType.getId()).colour(INVALID_TEXT_HTML)));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createTargetTypeWithInvalidKey() {
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with too long key should not be created")
|
||||
.isThrownBy(() -> targetTypeManagement
|
||||
.create(entityFactory.targetType().create().name(RandomStringUtils.randomAlphanumeric(
|
||||
Type.KEY_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with invalid key should not be created").isThrownBy(
|
||||
() -> targetTypeManagement.create(entityFactory.targetType().create().name(INVALID_TEXT_HTML)));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTargetTypeWithInvalidName(final TargetType targetType) {
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with too long name should not be created")
|
||||
.isThrownBy(() -> targetTypeManagement
|
||||
.create(entityFactory.targetType().create().name(RandomStringUtils.randomAlphanumeric(
|
||||
NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with invalid name should not be created").isThrownBy(
|
||||
() -> targetTypeManagement.create(entityFactory.targetType().create().name(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with too long name should not be updated")
|
||||
.isThrownBy(() -> targetTypeManagement
|
||||
.update(entityFactory.targetType().update(targetType.getId()).name(RandomStringUtils.randomAlphanumeric(
|
||||
NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with invalid name should not be updated").isThrownBy(() -> targetTypeManagement
|
||||
.update(entityFactory.targetType().update(targetType.getId()).name(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with too short name should not be updated").isThrownBy(() -> targetTypeManagement
|
||||
.update(entityFactory.targetType().update(targetType.getId()).name("")));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Tests the successful assignment of compatible distribution set types to a target type")
|
||||
void assignCompatibleDistributionSetTypesToTargetType() {
|
||||
@@ -189,7 +124,7 @@ class TargetTypeManagementTest extends AbstractJpaIntegrationTest {
|
||||
Optional<JpaTargetType> targetTypeWithDsTypes = targetTypeRepository.findById(targetType.getId());
|
||||
assertThat(targetTypeWithDsTypes).isPresent();
|
||||
assertThat(targetTypeWithDsTypes.get().getCompatibleDistributionSetTypes()).extracting("key").contains("testDst1");
|
||||
targetTypeManagement.unassignDistributionSetType(targetType.getId(),distributionSetType.getId());
|
||||
targetTypeManagement.unassignDistributionSetType(targetType.getId(), distributionSetType.getId());
|
||||
Optional<JpaTargetType> targetTypeWithDsTypes1 = targetTypeRepository.findById(targetType.getId());
|
||||
assertThat(targetTypeWithDsTypes1).isPresent();
|
||||
assertThat(targetTypeWithDsTypes1.get().getCompatibleDistributionSetTypes()).isEmpty();
|
||||
@@ -260,7 +195,8 @@ class TargetTypeManagementTest extends AbstractJpaIntegrationTest {
|
||||
@Description("Ensures that a target type cannot be created if one exists already with that name (expects EntityAlreadyExistsException).")
|
||||
void failedDuplicateTargetTypeNameException() {
|
||||
targetTypeManagement.create(entityFactory.targetType().create().name("targettype123"));
|
||||
assertThrows(EntityAlreadyExistsException.class, () -> targetTypeManagement.create(entityFactory.targetType().create().name("targettype123")));
|
||||
assertThrows(EntityAlreadyExistsException.class,
|
||||
() -> targetTypeManagement.create(entityFactory.targetType().create().name("targettype123")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -268,7 +204,72 @@ class TargetTypeManagementTest extends AbstractJpaIntegrationTest {
|
||||
void failedDuplicateTargetTypeNameExceptionAfterUpdate() {
|
||||
targetTypeManagement.create(entityFactory.targetType().create().name("targettype1234"));
|
||||
TargetType targetType = targetTypeManagement.create(entityFactory.targetType().create().name("targettype12345"));
|
||||
assertThrows(EntityAlreadyExistsException.class, () -> targetTypeManagement.update(entityFactory.targetType().update(targetType.getId()).name("targettype1234")));
|
||||
assertThrows(EntityAlreadyExistsException.class,
|
||||
() -> targetTypeManagement.update(entityFactory.targetType().update(targetType.getId()).name("targettype1234")));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTargetTypeWithInvalidColour(final TargetType targetType) {
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with too long colour should not be created")
|
||||
.isThrownBy(() -> targetTypeManagement.create(
|
||||
entityFactory.targetType().create().name("a")
|
||||
.colour(RandomStringUtils.randomAlphanumeric(TargetType.COLOUR_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with invalid colour should not be created").isThrownBy(() -> targetTypeManagement
|
||||
.create(entityFactory.targetType().create().name("a").colour(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with too long colour should not be updated")
|
||||
.isThrownBy(() -> targetTypeManagement.update(
|
||||
entityFactory.targetType().update(targetType.getId())
|
||||
.colour(RandomStringUtils.randomAlphanumeric(TargetType.COLOUR_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with invalid colour should not be updated").isThrownBy(() -> targetTypeManagement
|
||||
.update(entityFactory.targetType().update(targetType.getId()).colour(INVALID_TEXT_HTML)));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createTargetTypeWithInvalidKey() {
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with too long key should not be created")
|
||||
.isThrownBy(() -> targetTypeManagement
|
||||
.create(entityFactory.targetType().create().name(RandomStringUtils.randomAlphanumeric(
|
||||
Type.KEY_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with invalid key should not be created").isThrownBy(
|
||||
() -> targetTypeManagement.create(entityFactory.targetType().create().name(INVALID_TEXT_HTML)));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void createAndUpdateTargetTypeWithInvalidName(final TargetType targetType) {
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with too long name should not be created")
|
||||
.isThrownBy(() -> targetTypeManagement
|
||||
.create(entityFactory.targetType().create().name(RandomStringUtils.randomAlphanumeric(
|
||||
NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with invalid name should not be created").isThrownBy(
|
||||
() -> targetTypeManagement.create(entityFactory.targetType().create().name(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with too long name should not be updated")
|
||||
.isThrownBy(() -> targetTypeManagement
|
||||
.update(entityFactory.targetType().update(targetType.getId()).name(RandomStringUtils.randomAlphanumeric(
|
||||
NamedEntity.NAME_MAX_SIZE + 1))));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with invalid name should not be updated").isThrownBy(() -> targetTypeManagement
|
||||
.update(entityFactory.targetType().update(targetType.getId()).name(INVALID_TEXT_HTML)));
|
||||
|
||||
assertThatExceptionOfType(ConstraintViolationException.class)
|
||||
.as("targetType with too short name should not be updated").isThrownBy(() -> targetTypeManagement
|
||||
.update(entityFactory.targetType().update(targetType.getId()).name("")));
|
||||
|
||||
}
|
||||
|
||||
private Optional<JpaTargetType> findByName(final String name) {
|
||||
|
||||
@@ -17,6 +17,9 @@ import java.time.Duration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.exception.InvalidTenantConfigurationKeyException;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||
@@ -28,10 +31,6 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("Tenant Configuration Management")
|
||||
public class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest implements EnvironmentAware {
|
||||
@@ -101,9 +100,11 @@ public class TenantConfigurationManagementTest extends AbstractJpaIntegrationTes
|
||||
|
||||
// add value first
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration(configuration);
|
||||
assertThat(tenantConfigurationManagement.getConfigurationValue(TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, String.class).getValue())
|
||||
assertThat(tenantConfigurationManagement.getConfigurationValue(TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY,
|
||||
String.class).getValue())
|
||||
.isEqualTo("token_123");
|
||||
assertThat(tenantConfigurationManagement.getConfigurationValue(TenantConfigurationKey.ROLLOUT_APPROVAL_ENABLED, Boolean.class).getValue())
|
||||
assertThat(
|
||||
tenantConfigurationManagement.getConfigurationValue(TenantConfigurationKey.ROLLOUT_APPROVAL_ENABLED, Boolean.class).getValue())
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@@ -149,9 +150,12 @@ public class TenantConfigurationManagementTest extends AbstractJpaIntegrationTes
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration(configuration);
|
||||
fail("should not have worked as type is wrong");
|
||||
} catch (final TenantConfigurationValidatorException e) {
|
||||
assertThat(tenantConfigurationManagement.getConfigurationValue(TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, String.class).getValue())
|
||||
assertThat(
|
||||
tenantConfigurationManagement.getConfigurationValue(TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY,
|
||||
String.class).getValue())
|
||||
.isNotEqualTo("token_123");
|
||||
assertThat(tenantConfigurationManagement.getConfigurationValue(TenantConfigurationKey.ROLLOUT_APPROVAL_ENABLED, Boolean.class).getValue())
|
||||
assertThat(tenantConfigurationManagement.getConfigurationValue(TenantConfigurationKey.ROLLOUT_APPROVAL_ENABLED, Boolean.class)
|
||||
.getValue())
|
||||
.isNotEqualTo(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,15 +11,14 @@ package org.eclipse.hawkbit.repository.jpa.model;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.jpa.EntityInterceptor;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EntityInterceptorHolder;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -131,6 +130,7 @@ public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
|
||||
private static class PrePersistEntityListener extends AbstractEntityListener {
|
||||
|
||||
@Override
|
||||
public void prePersist(final Object entity) {
|
||||
setEntity(entity);
|
||||
@@ -138,6 +138,7 @@ public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
|
||||
private static class PostPersistEntityListener extends AbstractEntityListener {
|
||||
|
||||
@Override
|
||||
public void postPersist(final Object entity) {
|
||||
setEntity(entity);
|
||||
@@ -146,6 +147,7 @@ public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
|
||||
private static class PostLoadEntityListener extends AbstractEntityListener {
|
||||
|
||||
@Override
|
||||
public void postLoad(final Object entity) {
|
||||
setEntity(entity);
|
||||
@@ -154,6 +156,7 @@ public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
|
||||
private static class PreUpdateEntityListener extends AbstractEntityListener {
|
||||
|
||||
@Override
|
||||
public void preUpdate(final Object entity) {
|
||||
setEntity(entity);
|
||||
@@ -161,6 +164,7 @@ public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
|
||||
private static class PostUpdateEntityListener extends AbstractEntityListener {
|
||||
|
||||
@Override
|
||||
public void postUpdate(final Object entity) {
|
||||
setEntity(entity);
|
||||
@@ -168,6 +172,7 @@ public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
|
||||
private static class PreRemoveEntityListener extends AbstractEntityListener {
|
||||
|
||||
@Override
|
||||
public void preRemove(final Object entity) {
|
||||
setEntity(entity);
|
||||
@@ -175,6 +180,7 @@ public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
|
||||
private static class PostRemoveEntityListener extends AbstractEntityListener {
|
||||
|
||||
@Override
|
||||
public void postRemove(final Object entity) {
|
||||
setEntity(entity);
|
||||
|
||||
@@ -11,13 +11,12 @@ package org.eclipse.hawkbit.repository.jpa.model;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@Feature("Unit Tests - Repository")
|
||||
@Story("Repository Model")
|
||||
|
||||
@@ -12,6 +12,9 @@ package org.eclipse.hawkbit.repository.jpa.rsql;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.ActionFields;
|
||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
@@ -28,10 +31,6 @@ import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import org.springframework.orm.jpa.vendor.Database;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("RSQL filter actions")
|
||||
public class RSQLActionFieldsTest extends AbstractJpaIntegrationTest {
|
||||
@@ -51,25 +50,6 @@ public class RSQLActionFieldsTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
}
|
||||
|
||||
private @NotNull JpaAction newJpaAction(final DistributionSet dsA, final boolean active, final String extRef) {
|
||||
final JpaAction newAction = new JpaAction();
|
||||
newAction.setActionType(ActionType.SOFT);
|
||||
newAction.setDistributionSet(dsA);
|
||||
newAction.setActive(active);
|
||||
newAction.setStatus(Status.RUNNING);
|
||||
newAction.setTarget(target);
|
||||
newAction.setWeight(45);
|
||||
newAction.setInitiatedBy(tenantAware.getCurrentUsername());
|
||||
if (extRef != null) {
|
||||
newAction.setExternalRef(extRef);
|
||||
}
|
||||
actionRepository.save(newAction);
|
||||
|
||||
target.addAction(action);
|
||||
|
||||
return newAction;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test filter action by id")
|
||||
public void testFilterByParameterId() {
|
||||
@@ -104,6 +84,7 @@ public class RSQLActionFieldsTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test action by status")
|
||||
public void testFilterByParameterExtRef() {
|
||||
@@ -112,6 +93,25 @@ public class RSQLActionFieldsTest extends AbstractJpaIntegrationTest {
|
||||
assertRSQLQuery(ActionFields.EXTERNALREF.name() + "==extRef*", 10);
|
||||
}
|
||||
|
||||
private @NotNull JpaAction newJpaAction(final DistributionSet dsA, final boolean active, final String extRef) {
|
||||
final JpaAction newAction = new JpaAction();
|
||||
newAction.setActionType(ActionType.SOFT);
|
||||
newAction.setDistributionSet(dsA);
|
||||
newAction.setActive(active);
|
||||
newAction.setStatus(Status.RUNNING);
|
||||
newAction.setTarget(target);
|
||||
newAction.setWeight(45);
|
||||
newAction.setInitiatedBy(tenantAware.getCurrentUsername());
|
||||
if (extRef != null) {
|
||||
newAction.setExternalRef(extRef);
|
||||
}
|
||||
actionRepository.save(newAction);
|
||||
|
||||
target.addAction(action);
|
||||
|
||||
return newAction;
|
||||
}
|
||||
|
||||
private void assertRSQLQuery(final String rsqlParam, final long expectedEntities) {
|
||||
final Slice<Action> findEntity = deploymentManagement.findActionsByTarget(rsqlParam, target.getControllerId(),
|
||||
PageRequest.of(0, 100));
|
||||
|
||||
@@ -16,6 +16,9 @@ import static org.junit.jupiter.api.Assertions.fail;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetFields;
|
||||
import org.eclipse.hawkbit.repository.SoftwareModuleFields;
|
||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
||||
@@ -31,10 +34,6 @@ import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.orm.jpa.vendor.Database;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("RSQL filter distribution set")
|
||||
public class RSQLDistributionSetFieldTest extends AbstractJpaIntegrationTest {
|
||||
@@ -47,7 +46,7 @@ public class RSQLDistributionSetFieldTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
sm = testdataFactory.createSoftwareModuleApp("SM");
|
||||
|
||||
ds = testdataFactory.createDistributionSet(Collections.singletonList(sm),"DS");
|
||||
ds = testdataFactory.createDistributionSet(Collections.singletonList(sm), "DS");
|
||||
ds = distributionSetManagement.update(entityFactory.distributionSet().update(ds.getId()).description("DS"));
|
||||
createDistributionSetMetadata(ds.getId(), entityFactory.generateDsMetadata("metaKey", "metaValue"));
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetMetadataFields;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
@@ -25,10 +28,6 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("RSQL filter distribution set metadata")
|
||||
public class RSQLDistributionSetMetadataFieldsTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@@ -15,31 +15,28 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.TargetFields;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.rsql.RsqlValidationOracle;
|
||||
import org.eclipse.hawkbit.repository.rsql.SuggestToken;
|
||||
import org.eclipse.hawkbit.repository.rsql.ValidationOracleContext;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("RSQL filter suggestion")
|
||||
public class RSQLParserValidationOracleTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private RsqlValidationOracle rsqlValidationOracle;
|
||||
|
||||
private static final String[] OP_SUGGESTIONS = new String[] { "==", "!=", "=ge=", "=le=", "=gt=", "=lt=", "=in=",
|
||||
"=out=" };
|
||||
private static final String[] FIELD_SUGGESTIONS = Arrays.stream(TargetFields.values())
|
||||
.map(field -> field.name().toLowerCase()).toArray(String[]::new);
|
||||
private static final String[] AND_OR_SUGGESTIONS = new String[] { "and", "or" };
|
||||
private static final String[] NAME_VERSION_SUGGESTIONS = new String[] { "name", "version" };
|
||||
@Autowired
|
||||
private RsqlValidationOracle rsqlValidationOracle;
|
||||
|
||||
@Test
|
||||
@Description("Verifies that suggestions contains all possible field names")
|
||||
|
||||
@@ -11,6 +11,9 @@ package org.eclipse.hawkbit.repository.jpa.rsql;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.RolloutGroupFields;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
@@ -24,10 +27,6 @@ import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.orm.jpa.vendor.Database;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("RSQL filter rollout group")
|
||||
public class RSQLRolloutGroupFieldTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@@ -11,6 +11,9 @@ package org.eclipse.hawkbit.repository.jpa.rsql;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.SoftwareModuleFields;
|
||||
import org.eclipse.hawkbit.repository.builder.SoftwareModuleMetadataCreate;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
@@ -18,16 +21,11 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.orm.jpa.vendor.Database;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("RSQL filter software module")
|
||||
public class RSQLSoftwareModuleFieldTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@@ -14,6 +14,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields;
|
||||
import org.eclipse.hawkbit.repository.builder.SoftwareModuleMetadataCreate;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
@@ -25,10 +28,6 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("RSQL filter software module metadata")
|
||||
public class RSQLSoftwareModuleMetadataFieldsTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@@ -11,6 +11,9 @@ package org.eclipse.hawkbit.repository.jpa.rsql;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.Constants;
|
||||
import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
@@ -20,10 +23,6 @@ import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.orm.jpa.vendor.Database;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("RSQL filter software module test type")
|
||||
public class RSQLSoftwareModuleTypeFieldsTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@@ -11,6 +11,9 @@ package org.eclipse.hawkbit.repository.jpa.rsql;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.TagFields;
|
||||
import org.eclipse.hawkbit.repository.builder.TagCreate;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
@@ -21,10 +24,6 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("RSQL filter target and distribution set tags")
|
||||
public class RSQLTagFieldsTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@@ -17,6 +17,9 @@ import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.assertj.core.util.Maps;
|
||||
import org.eclipse.hawkbit.repository.TargetFields;
|
||||
import org.eclipse.hawkbit.repository.TargetTypeFields;
|
||||
@@ -31,22 +34,17 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.domain.Slice;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("RSQL filter target")
|
||||
class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
private static final String OR = ",";
|
||||
private static final String AND = ";";
|
||||
private Target target;
|
||||
private Target target2;
|
||||
private TargetType targetType1;
|
||||
private TargetType targetType2;
|
||||
|
||||
private static final String OR = ",";
|
||||
private static final String AND = ";";
|
||||
|
||||
@BeforeEach
|
||||
void setupBeforeTest() {
|
||||
|
||||
|
||||
@@ -12,6 +12,9 @@ package org.eclipse.hawkbit.repository.jpa.rsql;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryFields;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
@@ -23,10 +26,6 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.orm.jpa.vendor.Database;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("RSQL filter target filter query")
|
||||
public class RSQLTargetFilterQueryFieldsTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@@ -15,6 +15,9 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.TargetMetadataFields;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.model.MetaData;
|
||||
@@ -25,13 +28,10 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("RSQL filter target metadata")
|
||||
public class RSQLTargetMetadataFieldsTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
private String controllerId;
|
||||
|
||||
@BeforeEach
|
||||
|
||||
@@ -13,12 +13,14 @@ import cz.jirutka.rsql.parser.RSQLParser;
|
||||
import cz.jirutka.rsql.parser.ast.Node;
|
||||
import cz.jirutka.rsql.parser.ast.RSQLOperators;
|
||||
import cz.jirutka.rsql.parser.ast.RSQLVisitor;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.TypedQuery;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
|
||||
import org.eclipse.hawkbit.repository.RsqlQueryField;
|
||||
import org.eclipse.hawkbit.repository.rsql.RsqlConfigHolder;
|
||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||
@@ -39,11 +41,13 @@ public class RSQLToSQL {
|
||||
this.entityManager = entityManager;
|
||||
}
|
||||
|
||||
public <T, A extends Enum<A> & RsqlQueryField> String toSQL(final Class<T> domainClass, final Class<A> fieldsClass, final String rsql, final boolean legacyRsqlVisitor) {
|
||||
public <T, A extends Enum<A> & RsqlQueryField> String toSQL(final Class<T> domainClass, final Class<A> fieldsClass, final String rsql,
|
||||
final boolean legacyRsqlVisitor) {
|
||||
return createDbQuery(domainClass, fieldsClass, rsql, legacyRsqlVisitor).getSQLString();
|
||||
}
|
||||
|
||||
public <T, A extends Enum<A> & RsqlQueryField> DatabaseQuery createDbQuery(final Class<T> domainClass, final Class<A> fieldsClass, final String rsql, final boolean legacyRsqlVisitor) {
|
||||
public <T, A extends Enum<A> & RsqlQueryField> DatabaseQuery createDbQuery(final Class<T> domainClass, final Class<A> fieldsClass,
|
||||
final String rsql, final boolean legacyRsqlVisitor) {
|
||||
final CriteriaQuery<T> query = createQuery(domainClass, fieldsClass, rsql, legacyRsqlVisitor);
|
||||
final TypedQuery<?> typedQuery = entityManager.createQuery(query);
|
||||
// executes the query - otherwise the SQL string is not generated
|
||||
@@ -52,13 +56,14 @@ public class RSQLToSQL {
|
||||
return typedQuery.unwrap(JpaQuery.class).getDatabaseQuery();
|
||||
}
|
||||
|
||||
private <T, A extends Enum<A> & RsqlQueryField> CriteriaQuery<T> createQuery(final Class<T> domainClass, final Class<A> fieldsClass, final String rsql, final boolean legacyRsqlVisitor) {
|
||||
private <T, A extends Enum<A> & RsqlQueryField> CriteriaQuery<T> createQuery(final Class<T> domainClass, final Class<A> fieldsClass,
|
||||
final String rsql, final boolean legacyRsqlVisitor) {
|
||||
final CriteriaQuery<T> query = entityManager.getCriteriaBuilder().createQuery(domainClass);
|
||||
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||
return query.where(
|
||||
RsqlConfigHolder.getInstance().isLegacyRsqlVisitor() == legacyRsqlVisitor ?
|
||||
// use directly
|
||||
RSQLUtility.<A, T>buildRsqlSpecification(rsql, fieldsClass, null, DATABASE)
|
||||
RSQLUtility.<A, T> buildRsqlSpecification(rsql, fieldsClass, null, DATABASE)
|
||||
.toPredicate(query.from(domainClass), cb.createQuery(domainClass), cb) :
|
||||
toPredicate(rsql, fieldsClass, null,
|
||||
query.from(domainClass), cb.createQuery(domainClass), cb, legacyRsqlVisitor)
|
||||
@@ -80,10 +85,10 @@ public class RSQLToSQL {
|
||||
virtualPropertyReplacer, DATABASE, query,
|
||||
!RsqlConfigHolder.getInstance().isCaseInsensitiveDB() && RsqlConfigHolder.getInstance().isIgnoreCase())
|
||||
:
|
||||
new JpaQueryRsqlVisitorG2<>(
|
||||
fieldsClass, root, query, cb,
|
||||
DATABASE, virtualPropertyReplacer,
|
||||
!RsqlConfigHolder.getInstance().isCaseInsensitiveDB() && RsqlConfigHolder.getInstance().isIgnoreCase());
|
||||
new JpaQueryRsqlVisitorG2<>(
|
||||
fieldsClass, root, query, cb,
|
||||
DATABASE, virtualPropertyReplacer,
|
||||
!RsqlConfigHolder.getInstance().isCaseInsensitiveDB() && RsqlConfigHolder.getInstance().isIgnoreCase());
|
||||
final List<Predicate> accept = rootNode.accept(jpqQueryRSQLVisitor);
|
||||
|
||||
if (CollectionUtils.isEmpty(accept)) {
|
||||
|
||||
@@ -9,8 +9,11 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.rsql;
|
||||
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
|
||||
import org.eclipse.hawkbit.repository.RsqlQueryField;
|
||||
import org.eclipse.hawkbit.repository.TargetFields;
|
||||
import org.eclipse.hawkbit.repository.jpa.RepositoryApplicationConfiguration;
|
||||
@@ -24,10 +27,8 @@ import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE;
|
||||
|
||||
@ActiveProfiles("test")
|
||||
@SpringBootTest(webEnvironment=NONE, properties = {
|
||||
@SpringBootTest(webEnvironment = NONE, properties = {
|
||||
"hawkbit.rsql.caseInsensitiveDB=true",
|
||||
"spring.main.allow-bean-definition-overriding=true",
|
||||
"spring.main.banner-mode=off",
|
||||
@@ -39,11 +40,6 @@ public class RSQLToSQLTest {
|
||||
|
||||
private RSQLToSQL rsqlToSQL;
|
||||
|
||||
@PersistenceContext
|
||||
private void setEntityManager(final EntityManager entityManager) {
|
||||
rsqlToSQL = new RSQLToSQL(entityManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void print() {
|
||||
print(JpaTarget.class, TargetFields.class, "tag==tag1 and tag==tag2");
|
||||
@@ -58,6 +54,15 @@ public class RSQLToSQLTest {
|
||||
printFrom(JpaTarget.class, TargetFields.class, "tag==TAG1 and tag!=TAG2");
|
||||
}
|
||||
|
||||
private static String from(final String sql) {
|
||||
return sql.substring(sql.indexOf("FROM"));
|
||||
}
|
||||
|
||||
@PersistenceContext
|
||||
private void setEntityManager(final EntityManager entityManager) {
|
||||
rsqlToSQL = new RSQLToSQL(entityManager);
|
||||
}
|
||||
|
||||
private <T, A extends Enum<A> & RsqlQueryField> void print(final Class<T> domainClass, final Class<A> fieldsClass, final String rsql) {
|
||||
System.out.println(rsql);
|
||||
System.out.println("\tlegacy:\n" +
|
||||
@@ -73,7 +78,4 @@ public class RSQLToSQLTest {
|
||||
System.out.println("\tG2:\n" +
|
||||
"\t\t" + from(rsqlToSQL.toSQL(domainClass, fieldsClass, rsql, false)));
|
||||
}
|
||||
private static String from(final String sql) {
|
||||
return sql.substring(sql.indexOf("FROM"));
|
||||
}
|
||||
}
|
||||
@@ -33,10 +33,13 @@ import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import jakarta.persistence.criteria.Subquery;
|
||||
import jakarta.persistence.metamodel.Attribute;
|
||||
|
||||
import jakarta.persistence.metamodel.EntityType;
|
||||
import jakarta.persistence.metamodel.SingularAttribute;
|
||||
import jakarta.persistence.metamodel.Type;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetFields;
|
||||
import org.eclipse.hawkbit.repository.RsqlQueryField;
|
||||
import org.eclipse.hawkbit.repository.SoftwareModuleFields;
|
||||
@@ -48,8 +51,8 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||
import org.eclipse.hawkbit.repository.model.helper.SystemSecurityContextHolder;
|
||||
import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder;
|
||||
import org.eclipse.hawkbit.repository.rsql.RsqlVisitorFactory;
|
||||
import org.eclipse.hawkbit.repository.rsql.RsqlConfigHolder;
|
||||
import org.eclipse.hawkbit.repository.rsql.RsqlVisitorFactory;
|
||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyResolver;
|
||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
@@ -66,10 +69,6 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.orm.jpa.vendor.Database;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("RSQL search utility")
|
||||
@@ -77,58 +76,31 @@ import io.qameta.allure.Story;
|
||||
// method name as short text
|
||||
public class RSQLUtilityTest {
|
||||
|
||||
@Spy
|
||||
private final VirtualPropertyResolver macroResolver = new VirtualPropertyResolver();
|
||||
|
||||
@MockBean
|
||||
private TenantConfigurationManagement confMgmt;
|
||||
|
||||
@MockBean
|
||||
private SystemSecurityContext securityContext;
|
||||
|
||||
@MockBean
|
||||
private RsqlVisitorFactory rsqlVisitorFactory;
|
||||
|
||||
@Mock
|
||||
private Root<Object> baseSoftwareModuleRootMock;
|
||||
|
||||
@Mock
|
||||
private CriteriaQuery<SoftwareModule> criteriaQueryMock;
|
||||
@Mock
|
||||
private CriteriaBuilder criteriaBuilderMock;
|
||||
|
||||
@Mock
|
||||
private Subquery<SoftwareModule> subqueryMock;
|
||||
@Mock
|
||||
private Root<SoftwareModule> subqueryRootMock;
|
||||
|
||||
private final Database testDb = Database.H2;
|
||||
|
||||
@Mock
|
||||
private Attribute attribute;
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
@Bean
|
||||
TenantConfigurationManagementHolder tenantConfigurationManagementHolder() {
|
||||
return TenantConfigurationManagementHolder.getInstance();
|
||||
}
|
||||
|
||||
@Bean
|
||||
SystemSecurityContextHolder systemSecurityContextHolder() {
|
||||
return SystemSecurityContextHolder.getInstance();
|
||||
}
|
||||
|
||||
@Bean
|
||||
RsqlConfigHolder rsqlVisitorFactoryHolder() {
|
||||
return RsqlConfigHolder.getInstance();
|
||||
}
|
||||
}
|
||||
|
||||
private static final TenantConfigurationValue<String> TEST_POLLING_TIME_INTERVAL = TenantConfigurationValue
|
||||
.<String> builder().value("00:05:00").build();
|
||||
private static final TenantConfigurationValue<String> TEST_POLLING_OVERDUE_TIME_INTERVAL = TenantConfigurationValue
|
||||
.<String> builder().value("00:07:37").build();
|
||||
@Spy
|
||||
private final VirtualPropertyResolver macroResolver = new VirtualPropertyResolver();
|
||||
private final Database testDb = Database.H2;
|
||||
@MockBean
|
||||
private TenantConfigurationManagement confMgmt;
|
||||
@MockBean
|
||||
private SystemSecurityContext securityContext;
|
||||
@MockBean
|
||||
private RsqlVisitorFactory rsqlVisitorFactory;
|
||||
@Mock
|
||||
private Root<Object> baseSoftwareModuleRootMock;
|
||||
@Mock
|
||||
private CriteriaQuery<SoftwareModule> criteriaQueryMock;
|
||||
@Mock
|
||||
private CriteriaBuilder criteriaBuilderMock;
|
||||
@Mock
|
||||
private Subquery<SoftwareModule> subqueryMock;
|
||||
@Mock
|
||||
private Root<SoftwareModule> subqueryRootMock;
|
||||
@Mock
|
||||
private Attribute attribute;
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach() {
|
||||
@@ -555,6 +527,34 @@ public class RSQLUtilityTest {
|
||||
return (Path<Y>) path;
|
||||
}
|
||||
|
||||
private void validateRsqlForTestFields(final String rsql) {
|
||||
when(rsqlVisitorFactory.validationRsqlVisitor(eq(TestFieldEnum.class))).thenReturn(
|
||||
new FieldValidationRsqlVisitor<>(TestFieldEnum.class));
|
||||
RSQLUtility.validateRsqlFor(rsql, TestFieldEnum.class);
|
||||
}
|
||||
|
||||
private void reset0(final Object... mocks) {
|
||||
reset(mocks);
|
||||
if (Arrays.asList(mocks).contains(baseSoftwareModuleRootMock)) {
|
||||
setupRoot(baseSoftwareModuleRootMock);
|
||||
}
|
||||
if (Arrays.asList(mocks).contains(subqueryRootMock)) {
|
||||
setupRoot(subqueryRootMock);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private void setupRoot(final Root<?> root) {
|
||||
final Type type = Mockito.mock(Type.class);
|
||||
when(type.getPersistenceType()).thenReturn(Type.PersistenceType.BASIC);
|
||||
final SingularAttribute singularAttribute = Mockito.mock(SingularAttribute.class);
|
||||
when(singularAttribute.getType()).thenReturn(type);
|
||||
final EntityType entityType = Mockito.mock(EntityType.class);
|
||||
when(entityType.getAttribute(any())).thenReturn(singularAttribute);
|
||||
when(entityType.getPersistenceType()).thenReturn(Type.PersistenceType.BASIC);
|
||||
when(root.getModel()).thenReturn(entityType);
|
||||
}
|
||||
|
||||
private enum TestFieldEnum implements RsqlQueryField {
|
||||
TESTFIELD("testfield"), TESTFIELD_WITH_SUB_ENTITIES("testfieldWithSubEntities", "subentity11", "subentity22");
|
||||
|
||||
@@ -581,34 +581,26 @@ public class RSQLUtilityTest {
|
||||
}
|
||||
}
|
||||
|
||||
private void validateRsqlForTestFields(final String rsql) {
|
||||
when(rsqlVisitorFactory.validationRsqlVisitor(eq(TestFieldEnum.class))).thenReturn(new FieldValidationRsqlVisitor<>(TestFieldEnum.class));
|
||||
RSQLUtility.validateRsqlFor(rsql, TestFieldEnum.class);
|
||||
}
|
||||
|
||||
private void reset0(final Object... mocks) {
|
||||
reset(mocks);
|
||||
if (Arrays.asList(mocks).contains(baseSoftwareModuleRootMock)) {
|
||||
setupRoot(baseSoftwareModuleRootMock);
|
||||
}
|
||||
if (Arrays.asList(mocks).contains(subqueryRootMock)) {
|
||||
setupRoot(subqueryRootMock);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private void setupRoot(final Root<?> root) {
|
||||
final Type type = Mockito.mock(Type.class);
|
||||
when(type.getPersistenceType()).thenReturn(Type.PersistenceType.BASIC);
|
||||
final SingularAttribute singularAttribute = Mockito.mock(SingularAttribute.class);
|
||||
when(singularAttribute.getType()).thenReturn(type);
|
||||
final EntityType entityType = Mockito.mock(EntityType.class);
|
||||
when(entityType.getAttribute(any())).thenReturn(singularAttribute);
|
||||
when(entityType.getPersistenceType()).thenReturn(Type.PersistenceType.BASIC);
|
||||
when(root.getModel()).thenReturn(entityType);
|
||||
}
|
||||
|
||||
private enum TestValueEnum {
|
||||
BUMLUX;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
TenantConfigurationManagementHolder tenantConfigurationManagementHolder() {
|
||||
return TenantConfigurationManagementHolder.getInstance();
|
||||
}
|
||||
|
||||
@Bean
|
||||
SystemSecurityContextHolder systemSecurityContextHolder() {
|
||||
return SystemSecurityContextHolder.getInstance();
|
||||
}
|
||||
|
||||
@Bean
|
||||
RsqlConfigHolder rsqlVisitorFactoryHolder() {
|
||||
return RsqlConfigHolder.getInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,9 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.apache.commons.lang3.text.StrSubstitutor;
|
||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||
@@ -34,43 +37,22 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@Feature("Unit Tests - Repository")
|
||||
@Story("Placeholder resolution for virtual properties")
|
||||
public class VirtualPropertyResolverTest {
|
||||
|
||||
@Spy
|
||||
private final VirtualPropertyResolver resolverUnderTest = new VirtualPropertyResolver();
|
||||
|
||||
@MockBean
|
||||
private TenantConfigurationManagement confMgmt;
|
||||
|
||||
@MockBean
|
||||
private SystemSecurityContext securityContext;
|
||||
|
||||
private StrSubstitutor substitutor;
|
||||
|
||||
private static final TenantConfigurationValue<String> TEST_POLLING_TIME_INTERVAL = TenantConfigurationValue
|
||||
.<String> builder().value("00:05:00").build();
|
||||
private static final TenantConfigurationValue<String> TEST_POLLING_OVERDUE_TIME_INTERVAL = TenantConfigurationValue
|
||||
.<String> builder().value("00:07:37").build();
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
@Bean
|
||||
TenantConfigurationManagementHolder tenantConfigurationManagementHolder() {
|
||||
return TenantConfigurationManagementHolder.getInstance();
|
||||
}
|
||||
|
||||
@Bean
|
||||
SystemSecurityContextHolder systemSecurityContextHolder() {
|
||||
return SystemSecurityContextHolder.getInstance();
|
||||
}
|
||||
}
|
||||
@Spy
|
||||
private final VirtualPropertyResolver resolverUnderTest = new VirtualPropertyResolver();
|
||||
@MockBean
|
||||
private TenantConfigurationManagement confMgmt;
|
||||
@MockBean
|
||||
private SystemSecurityContext securityContext;
|
||||
private StrSubstitutor substitutor;
|
||||
|
||||
@BeforeEach
|
||||
public void before() {
|
||||
@@ -83,18 +65,6 @@ public class VirtualPropertyResolverTest {
|
||||
StrSubstitutor.DEFAULT_SUFFIX, StrSubstitutor.DEFAULT_ESCAPE);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "${NOW_TS}", "${OVERDUE_TS}", "${overdue_ts}" })
|
||||
@Description("Tests resolution of NOW_TS by using a StrSubstitutor configured with the VirtualPropertyResolver.")
|
||||
void resolveNowTimestampPlaceholder(final String placeholder) {
|
||||
when(securityContext.runAsSystem(Mockito.any())).thenAnswer(a -> ((Callable<?>) a.getArgument(0)).call());
|
||||
final String testString = "lhs=lt=" + placeholder;
|
||||
|
||||
final String resolvedPlaceholders = substitutor.replace(testString);
|
||||
assertThat(resolvedPlaceholders).as("'%s' placeholder was not replaced", placeholder)
|
||||
.doesNotContain(placeholder);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Tests VirtualPropertyResolver with a placeholder unknown to VirtualPropertyResolver.")
|
||||
public void handleUnknownPlaceholder() {
|
||||
@@ -115,4 +85,30 @@ public class VirtualPropertyResolverTest {
|
||||
final String resolvedPlaceholders = substitutor.replace(testString);
|
||||
assertThat(resolvedPlaceholders).as("Escaped OVERDUE_TS should not be resolved!").contains(placeholder);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "${NOW_TS}", "${OVERDUE_TS}", "${overdue_ts}" })
|
||||
@Description("Tests resolution of NOW_TS by using a StrSubstitutor configured with the VirtualPropertyResolver.")
|
||||
void resolveNowTimestampPlaceholder(final String placeholder) {
|
||||
when(securityContext.runAsSystem(Mockito.any())).thenAnswer(a -> ((Callable<?>) a.getArgument(0)).call());
|
||||
final String testString = "lhs=lt=" + placeholder;
|
||||
|
||||
final String resolvedPlaceholders = substitutor.replace(testString);
|
||||
assertThat(resolvedPlaceholders).as("'%s' placeholder was not replaced", placeholder)
|
||||
.doesNotContain(placeholder);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
TenantConfigurationManagementHolder tenantConfigurationManagementHolder() {
|
||||
return TenantConfigurationManagementHolder.getInstance();
|
||||
}
|
||||
|
||||
@Bean
|
||||
SystemSecurityContextHolder systemSecurityContextHolder() {
|
||||
return SystemSecurityContextHolder.getInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,12 +27,11 @@ import jakarta.persistence.criteria.Path;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
|
||||
@Feature("Unit Tests - Repository")
|
||||
@Story("Specifications builder")
|
||||
|
||||
@@ -16,6 +16,9 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
@@ -27,15 +30,10 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.data.domain.Slice;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
/**
|
||||
* Multi-Tenancy tests which testing the CRUD operations of entities that all
|
||||
* CRUD-Operations are tenant aware and cannot access or delete entities not
|
||||
* belonging to the current tenant.
|
||||
*
|
||||
*/
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("Multi Tenancy")
|
||||
@@ -110,7 +108,7 @@ public class MultiTenancyEntityTest extends AbstractJpaIntegrationTest {
|
||||
// autogenerated
|
||||
assertThat(distributionSetTypeManagement.findAll(PAGE)).isEmpty();
|
||||
SecurityContextSwitch.runAsPrivileged(() ->
|
||||
assertThat(systemManagement.createTenantMetadata("mytenant").getTenant().toUpperCase()).isEqualTo("mytenant".toUpperCase()));
|
||||
assertThat(systemManagement.createTenantMetadata("mytenant").getTenant().toUpperCase()).isEqualTo("mytenant".toUpperCase()));
|
||||
|
||||
assertThat(distributionSetTypeManagement.findAll(PAGE)).isNotEmpty();
|
||||
|
||||
@@ -119,7 +117,7 @@ public class MultiTenancyEntityTest extends AbstractJpaIntegrationTest {
|
||||
// mytenant
|
||||
assertThat(SecurityContextSwitch.runAs(SecurityContextSwitch.withUserAndTenantAllSpPermissions("user", "bumlux"),
|
||||
() -> systemManagement.getTenantMetadata().getTenant().toUpperCase()))
|
||||
.isEqualTo("bumlux".toUpperCase());
|
||||
.isEqualTo("bumlux".toUpperCase());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0
|
||||
#
|
||||
|
||||
# Debug utility functions - START
|
||||
logging.level.org.eclipse.persistence=ERROR
|
||||
#incomment to see the debug of persistence, e.g. to see the generated SQLs
|
||||
@@ -16,6 +15,5 @@ spring.jpa.properties.eclipselink.logging.level=FINE
|
||||
spring.jpa.properties.eclipselink.logging.level.sql=FINE
|
||||
spring.jpa.properties.eclipselink.logging.parameters=true
|
||||
# Debug utility functions - END
|
||||
|
||||
# enable / disable case sensitiveness of the DB when playing around
|
||||
#hawkbit.rsql.caseInsensitiveDB=true
|
||||
|
||||
Reference in New Issue
Block a user