Feature/fix sonar warnings (#1226)

* Fixed sonar warnings

- "Cognitive Complexity"
- "Do not use replaceAll when not using a regex"
- java:S5869 - Character classes in regular expressions should not contain the same character twice
- Improved bad name
- Typos
- reduced code duplications
- Replaced hand-made wait-utility with Awaitility
- Log messages
- Duplicate code
- Typos
- Removed Thread.sleep, instead relaxed check condition
- Removed use of deprecated API
- Removed use of deprecated API
- Added supress-warnings as I do not see a better way to write the tests
- Removed Thread.sleep / redundant functionality to Awaitility
- Fixed other warnings (use isZero, isEmpty, hasToString)
- Removed/Reduced duplicate code
- Added generics
- Fixed asserts
- removed: field.setAccessible(true) actually should not be needed for public static fields!
- Too long constructor passes arguments in wrong order - how surprisingly...
- Clean-up use of varargs arguments
- Fixed regex
- Fixed typos and other minor stuff
- Making public constructors protected in abstract classes
- Swapped expected and asserted argument
- volatile not enough for syncing threads
- volatile not enough for syncing threads
- out-commented code
- Made regex not-greedy, added tests for verification
- Avoid exposure of thread-local member var

Signed-off-by: Peter Vigier <Peter.Vigier@bosch.io>

* Fixed Sonar warnings

* License header fix

Signed-off-by: Peter Vigier <Peter.Vigier@bosch.io>

* License header fix #2

Signed-off-by: Peter Vigier <Peter.Vigier@bosch.io>

* Fixing review findings

Signed-off-by: Peter Vigier <Peter.Vigier@bosch.io>

* Fixing tests

- Fixed '&' usage in javadoc and typos
- Fixing some warnings

Signed-off-by: Peter Vigier <Peter.Vigier@bosch.io>
This commit is contained in:
Peter Vigier
2022-01-31 21:59:46 +01:00
committed by GitHub
parent 5443b5df9c
commit 44a85f20eb
98 changed files with 2583 additions and 2702 deletions

View File

@@ -8,15 +8,15 @@
*/
package org.eclipse.hawkbit.repository.event.remote;
import org.eclipse.hawkbit.repository.Identifiable;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Target;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.Identifiable;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Target;
/**
* Generic deployment event for the Multi-Assignments feature. The event payload
* holds a list of controller IDs identifying the targets which are affected by
@@ -33,7 +33,7 @@ public abstract class MultiActionEvent extends RemoteTenantAwareEvent implements
/**
* Default constructor.
*/
public MultiActionEvent() {
protected MultiActionEvent() {
// for serialization libs like jackson
}
@@ -47,7 +47,7 @@ public abstract class MultiActionEvent extends RemoteTenantAwareEvent implements
* @param actions
* the actions involved
*/
public MultiActionEvent(String tenant, String applicationId, List<Action> actions) {
protected MultiActionEvent(String tenant, String applicationId, List<Action> actions) {
super(applicationId, tenant, applicationId);
this.controllerIds.addAll(getControllerIdsFromActions(actions));
this.actionIds.addAll(getIdsFromActions(actions));

View File

@@ -8,6 +8,8 @@
*/
package org.eclipse.hawkbit.repository.event.remote.entity;
import java.util.Objects;
import org.eclipse.hawkbit.repository.model.Action;
/**
@@ -16,15 +18,18 @@ import org.eclipse.hawkbit.repository.model.Action;
public abstract class AbstractActionEvent extends RemoteEntityEvent<Action> {
private static final long serialVersionUID = 1L;
private Long targetId;
private Long rolloutId;
private Long rolloutGroupId;
private final Long targetId;
private final Long rolloutId;
private final Long rolloutGroupId;
/**
* Default constructor.
*/
public AbstractActionEvent() {
protected AbstractActionEvent() {
// for serialization libs like jackson
this.targetId = null;
this.rolloutId = null;
this.rolloutGroupId = null;
}
/**
@@ -41,7 +46,7 @@ public abstract class AbstractActionEvent extends RemoteEntityEvent<Action> {
* @param applicationId
* the origin application id
*/
public AbstractActionEvent(final Action action, final Long targetId, final Long rolloutId,
protected AbstractActionEvent(final Action action, final Long targetId, final Long rolloutId,
final Long rolloutGroupId, final String applicationId) {
super(action, applicationId);
this.targetId = targetId;
@@ -61,4 +66,21 @@ public abstract class AbstractActionEvent extends RemoteEntityEvent<Action> {
return rolloutGroupId;
}
@Override
public boolean equals(final Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
if (!super.equals(o))
return false;
final AbstractActionEvent that = (AbstractActionEvent) o;
return Objects.equals(targetId, that.targetId) && Objects.equals(rolloutId, that.rolloutId)
&& Objects.equals(rolloutGroupId, that.rolloutGroupId);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), targetId, rolloutId, rolloutGroupId);
}
}

View File

@@ -8,26 +8,28 @@
*/
package org.eclipse.hawkbit.repository.event.remote.entity;
import java.util.Objects;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
/**
* TenantAwareEvent definition which is been published in case a rollout group
* has been created for a specific rollout or updated.
*
* Event which is published in case a {@linkplain RolloutGroup} is created or
* updated
*/
public abstract class AbstractRolloutGroupEvent extends RemoteEntityEvent<RolloutGroup> {
private static final long serialVersionUID = 1L;
private Long rolloutId;
private final Long rolloutId;
/**
* Default constructor.
*/
public AbstractRolloutGroupEvent() {
protected AbstractRolloutGroupEvent() {
// for serialization libs like jackson
this.rolloutId = null;
}
public AbstractRolloutGroupEvent(final RolloutGroup rolloutGroup, final Long rolloutId,
protected AbstractRolloutGroupEvent(final RolloutGroup rolloutGroup, final Long rolloutId,
final String applicationId) {
super(rolloutGroup, applicationId);
this.rolloutId = rolloutId;
@@ -37,4 +39,20 @@ public abstract class AbstractRolloutGroupEvent extends RemoteEntityEvent<Rollou
return rolloutId;
}
@Override
public boolean equals(final Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
if (!super.equals(o))
return false;
final AbstractRolloutGroupEvent that = (AbstractRolloutGroupEvent) o;
return Objects.equals(rolloutId, that.rolloutId);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), rolloutId);
}
}

View File

@@ -33,7 +33,7 @@ public abstract class AbstractAssignmentResult<T extends BaseEntity> {
* @param unassignedEntity
* {@link List} of unassigned entity.
*/
public AbstractAssignmentResult(final int alreadyAssigned, final List<? extends T> assignedEntity,
protected AbstractAssignmentResult(final int alreadyAssigned, final List<? extends T> assignedEntity,
final List<? extends T> unassignedEntity) {
this.alreadyAssigned = alreadyAssigned;
this.assignedEntity = assignedEntity;

View File

@@ -156,12 +156,15 @@ public interface Action extends TenantAwareBaseEntity {
}
/**
* Check if action type is either forced or time-forced <i>and</i> force-time is
* exceeded.
*
* @return {@code true} if either the {@link #getActionType()} is
* {@link ActionType#FORCED} or {@link ActionType#TIMEFORCED} but
* then if the {@link #getForcedTime()} has been exceeded otherwise
* always {@code false}
* {@link ActionType#FORCED} or {@link ActionType#TIMEFORCED} but then
* if the {@link #getForcedTime()} has been exceeded otherwise always
* {@code false}
*/
default boolean isForce() {
default boolean isForcedOrTimeForced() {
switch (getActionType()) {
case FORCED:
return true;

View File

@@ -14,6 +14,8 @@ import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.cache.TenancyCacheManager;
import org.eclipse.hawkbit.cache.TenantAwareCacheManager;
import org.eclipse.hawkbit.repository.event.remote.RolloutDeletedEvent;
@@ -74,9 +76,7 @@ public class RolloutStatusCache {
* @return map of cached entries
*/
public Map<Long, List<TotalTargetCountActionStatus>> getRolloutStatus(final List<Long> rollouts) {
final Cache cache = cacheManager.getCache(CACHE_RO_NAME);
return retrieveFromCache(rollouts, cache);
return retrieveFromCache(rollouts, getRolloutStatusCache());
}
/**
@@ -88,9 +88,7 @@ public class RolloutStatusCache {
* @return map of cached entries
*/
public List<TotalTargetCountActionStatus> getRolloutStatus(final Long rolloutId) {
final Cache cache = cacheManager.getCache(CACHE_RO_NAME);
return retrieveFromCache(rolloutId, cache);
return retrieveFromCache(rolloutId, getRolloutStatusCache());
}
/**
@@ -102,9 +100,7 @@ public class RolloutStatusCache {
* @return map of cached entries
*/
public Map<Long, List<TotalTargetCountActionStatus>> getRolloutGroupStatus(final List<Long> rolloutGroups) {
final Cache cache = cacheManager.getCache(CACHE_GR_NAME);
return retrieveFromCache(rolloutGroups, cache);
return retrieveFromCache(rolloutGroups, getGroupStatusCache());
}
/**
@@ -116,9 +112,7 @@ public class RolloutStatusCache {
* @return map of cached entries
*/
public List<TotalTargetCountActionStatus> getRolloutGroupStatus(final Long groupId) {
final Cache cache = cacheManager.getCache(CACHE_GR_NAME);
return retrieveFromCache(groupId, cache);
return retrieveFromCache(groupId, getGroupStatusCache());
}
/**
@@ -129,8 +123,7 @@ public class RolloutStatusCache {
* map of cached entries
*/
public void putRolloutStatus(final Map<Long, List<TotalTargetCountActionStatus>> put) {
final Cache cache = cacheManager.getCache(CACHE_RO_NAME);
putIntoCache(put, cache);
putIntoCache(put, getRolloutStatusCache());
}
/**
@@ -144,10 +137,10 @@ public class RolloutStatusCache {
*
*/
public void putRolloutStatus(final Long rolloutId, final List<TotalTargetCountActionStatus> status) {
final Cache cache = cacheManager.getCache(CACHE_RO_NAME);
putIntoCache(rolloutId, status, cache);
putIntoCache(rolloutId, status, getRolloutStatusCache());
}
/**
* Put {@link TotalTargetCountActionStatus} for multiple
* {@link RolloutGroup}s into cache.
@@ -156,8 +149,7 @@ public class RolloutStatusCache {
* map of cached entries
*/
public void putRolloutGroupStatus(final Map<Long, List<TotalTargetCountActionStatus>> put) {
final Cache cache = cacheManager.getCache(CACHE_GR_NAME);
putIntoCache(put, cache);
putIntoCache(put, getGroupStatusCache());
}
/**
@@ -170,17 +162,17 @@ public class RolloutStatusCache {
* list to cache
*/
public void putRolloutGroupStatus(final Long groupId, final List<TotalTargetCountActionStatus> status) {
final Cache cache = cacheManager.getCache(CACHE_GR_NAME);
putIntoCache(groupId, status, cache);
putIntoCache(groupId, status, getGroupStatusCache());
}
private Map<Long, List<TotalTargetCountActionStatus>> retrieveFromCache(final List<Long> ids, final Cache cache) {
private Map<Long, List<TotalTargetCountActionStatus>> retrieveFromCache(final List<Long> ids,
@NotNull final Cache cache) {
return ids.stream().map(id -> cache.get(id, CachedTotalTargetCountActionStatus.class)).filter(Objects::nonNull)
.collect(Collectors.toMap(CachedTotalTargetCountActionStatus::getId,
CachedTotalTargetCountActionStatus::getStatus));
}
private List<TotalTargetCountActionStatus> retrieveFromCache(final Long id, final Cache cache) {
private List<TotalTargetCountActionStatus> retrieveFromCache(final Long id, @NotNull final Cache cache) {
final CachedTotalTargetCountActionStatus cacheItem = cache.get(id, CachedTotalTargetCountActionStatus.class);
if (cacheItem == null) {
@@ -190,17 +182,17 @@ public class RolloutStatusCache {
return cacheItem.getStatus();
}
private void putIntoCache(final Long id, final List<TotalTargetCountActionStatus> status, final Cache cache) {
private void putIntoCache(final Long id, final List<TotalTargetCountActionStatus> status,
@NotNull final Cache cache) {
cache.put(id, new CachedTotalTargetCountActionStatus(id, status));
}
private void putIntoCache(final Map<Long, List<TotalTargetCountActionStatus>> put, final Cache cache) {
put.entrySet().forEach(entry -> cache.put(entry.getKey(),
new CachedTotalTargetCountActionStatus(entry.getKey(), entry.getValue())));
private void putIntoCache(final Map<Long, List<TotalTargetCountActionStatus>> put, @NotNull final Cache cache) {
put.forEach((k, v) -> cache.put(k, new CachedTotalTargetCountActionStatus(k, v)));
}
@EventListener(classes = AbstractActionEvent.class)
void invalidateCachedTotalTargetCountActionStatus(final AbstractActionEvent event) {
public void invalidateCachedTotalTargetCountActionStatus(final AbstractActionEvent event) {
if (event.getRolloutId() != null) {
final Cache cache = tenantAware.runAsTenant(event.getTenant(), () -> cacheManager.getCache(CACHE_RO_NAME));
cache.evict(event.getRolloutId());
@@ -213,19 +205,19 @@ public class RolloutStatusCache {
}
@EventListener(classes = RolloutDeletedEvent.class)
void invalidateCachedTotalTargetCountOnRolloutDelete(final RolloutDeletedEvent event) {
public void invalidateCachedTotalTargetCountOnRolloutDelete(final RolloutDeletedEvent event) {
final Cache cache = tenantAware.runAsTenant(event.getTenant(), () -> cacheManager.getCache(CACHE_RO_NAME));
cache.evict(event.getEntityId());
}
@EventListener(classes = RolloutGroupDeletedEvent.class)
void invalidateCachedTotalTargetCountOnRolloutGroupDelete(final RolloutGroupDeletedEvent event) {
public void invalidateCachedTotalTargetCountOnRolloutGroupDelete(final RolloutGroupDeletedEvent event) {
final Cache cache = tenantAware.runAsTenant(event.getTenant(), () -> cacheManager.getCache(CACHE_GR_NAME));
cache.evict(event.getEntityId());
}
@EventListener(classes = RolloutStoppedEvent.class)
void invalidateCachedTotalTargetCountOnRolloutStopped(final RolloutStoppedEvent event) {
public void invalidateCachedTotalTargetCountOnRolloutStopped(final RolloutStoppedEvent event) {
final Cache cache = tenantAware.runAsTenant(event.getTenant(), () -> cacheManager.getCache(CACHE_RO_NAME));
cache.evict(event.getRolloutId());
@@ -247,6 +239,14 @@ public class RolloutStatusCache {
cacheManager.evictCaches(tenant);
}
private @NotNull Cache getRolloutStatusCache() {
return Objects.requireNonNull(cacheManager.getCache(CACHE_RO_NAME), "Cache '" + CACHE_RO_NAME + "' is null!");
}
private @NotNull Cache getGroupStatusCache() {
return Objects.requireNonNull(cacheManager.getCache(CACHE_GR_NAME), "Cache '" + CACHE_RO_NAME + "' is null!");
}
private static final class CachedTotalTargetCountActionStatus {
private final long id;
private final List<TotalTargetCountActionStatus> status;

View File

@@ -14,6 +14,7 @@ import javax.persistence.PersistenceException;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
import org.springframework.lang.NonNull;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect;
@@ -53,13 +54,12 @@ public class HawkBitEclipseLinkJpaDialect extends EclipseLinkJpaDialect {
private static final SQLStateSQLExceptionTranslator SQLSTATE_EXCEPTION_TRANSLATOR = new SQLStateSQLExceptionTranslator();
@Override
public DataAccessException translateExceptionIfPossible(final RuntimeException ex) {
public DataAccessException translateExceptionIfPossible(@NonNull final RuntimeException ex) {
final DataAccessException dataAccessException = super.translateExceptionIfPossible(ex);
if (dataAccessException == null) {
return searchAndTranslateSqlException(ex);
}
return translateJpaSystemExceptionIfPossible(dataAccessException);
}
@@ -69,22 +69,19 @@ public class HawkBitEclipseLinkJpaDialect extends EclipseLinkJpaDialect {
return accessException;
}
final DataAccessException sql = searchAndTranslateSqlException(accessException);
if (sql == null) {
final DataAccessException sqlException = searchAndTranslateSqlException(accessException);
if (sqlException == null) {
return accessException;
}
return sql;
return sqlException;
}
private static DataAccessException searchAndTranslateSqlException(final RuntimeException ex) {
final SQLException sqlException = findSqlException(ex);
if (sqlException == null) {
return null;
}
return SQLSTATE_EXCEPTION_TRANSLATOR.translate(null, null, sqlException);
return SQLSTATE_EXCEPTION_TRANSLATOR.translate("", null, sqlException);
}
private static SQLException findSqlException(final RuntimeException jpaSystemException) {

View File

@@ -767,7 +767,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
final JpaAction action = actionRepository.findById(actionId)
.orElseThrow(() -> new EntityNotFoundException(Action.class, actionId));
if (!action.isForce()) {
if (!action.isForcedOrTimeForced()) {
action.setActionType(ActionType.FORCED);
return actionRepository.save(action);
}

View File

@@ -9,7 +9,6 @@
package org.eclipse.hawkbit.repository.jpa;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@@ -25,7 +24,6 @@ import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
import org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantMetaData;
import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
@@ -202,11 +200,11 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
// Create if it does not exist
if (result == null) {
try {
currentTenantCacheKeyGenerator.getCreateInitialTenant().set(tenant);
currentTenantCacheKeyGenerator.setTenantInCreation(tenant);
return createInitialTenantMetaData(tenant);
} finally {
currentTenantCacheKeyGenerator.getCreateInitialTenant().remove();
currentTenantCacheKeyGenerator.removeTenantInCreation();
}
}
return result;
@@ -276,20 +274,17 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
if (tenantAware.getCurrentTenant() == null) {
throw new IllegalStateException("Tenant not set");
}
return getTenantMetadata(tenantAware.getCurrentTenant());
}
@Override
@Cacheable(value = "currentTenant", keyGenerator = "currentTenantKeyGenerator", cacheManager = "directCacheManager", unless = "#result == null")
public String currentTenant() {
final String initialTenantCreation = currentTenantCacheKeyGenerator.getCreateInitialTenant().get();
if (initialTenantCreation == null) {
return currentTenantCacheKeyGenerator.getTenantInCreation().orElseGet(() -> {
final TenantMetaData findByTenant = tenantMetaDataRepository
.findByTenantIgnoreCase(tenantAware.getCurrentTenant());
return findByTenant != null ? findByTenant.getTenant() : null;
}
return initialTenantCreation;
});
}
@Override
@@ -312,7 +307,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
Integer.MAX_VALUE));
final SoftwareModuleType os = softwareModuleTypeRepository.save(new JpaSoftwareModuleType(
org.eclipse.hawkbit.repository.Constants.SMT_DEFAULT_OS_KEY,
org.eclipse.hawkbit.repository.Constants.SMT_DEFAULT_OS_NAME, "Core firmware or operationg system", 1));
org.eclipse.hawkbit.repository.Constants.SMT_DEFAULT_OS_NAME, "Core firmware or operation system", 1));
// make sure the module types get their IDs
entityManager.flush();

View File

@@ -9,6 +9,10 @@
package org.eclipse.hawkbit.repository.jpa;
import java.lang.reflect.Method;
import java.util.Objects;
import java.util.Optional;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.beans.factory.annotation.Autowired;
@@ -18,7 +22,6 @@ import org.springframework.context.annotation.Bean;
/**
* Implementation of {@link CurrentTenantCacheKeyGenerator}.
*
*/
public class SystemManagementCacheKeyGenerator implements CurrentTenantCacheKeyGenerator {
@@ -28,25 +31,17 @@ public class SystemManagementCacheKeyGenerator implements CurrentTenantCacheKeyG
private final ThreadLocal<String> createInitialTenant = new ThreadLocal<>();
/**
* A implementation of the {@link KeyGenerator} to generate a key based on
* An implementation of the {@link KeyGenerator} to generate a key based on
* either the {@code createInitialTenant} thread local and the
* {@link TenantAware}, but in case we are in a tenant creation with its
* default types we need to use the tenant the current tenant which is
* currently created and not the one currently in the {@link TenantAware}.
*
* {@link TenantAware}, but in case we are in a tenant creation with its default
* types we need to use as the tenant the current tenant which is currently
* created and not the one currently in the {@link TenantAware}.
*/
public class CurrentTenantKeyGenerator implements KeyGenerator {
@Override
// Exception squid:S923 - override
@SuppressWarnings({ "squid:S923" })
public Object generate(final Object target, final Method method, final Object... params) {
final String initialTenantCreation = createInitialTenant.get();
if (initialTenantCreation == null) {
return SimpleKeyGenerator.generateKey(tenantAware.getCurrentTenant().toUpperCase(),
tenantAware.getCurrentTenant().toUpperCase());
}
return SimpleKeyGenerator.generateKey(initialTenantCreation.toUpperCase(),
initialTenantCreation.toUpperCase());
String tenant = getTenantInCreation().orElseGet(() -> tenantAware.getCurrentTenant()).toUpperCase();
return SimpleKeyGenerator.generateKey(tenant, tenant);
}
}
@@ -56,8 +51,33 @@ public class SystemManagementCacheKeyGenerator implements CurrentTenantCacheKeyG
return new CurrentTenantKeyGenerator();
}
ThreadLocal<String> getCreateInitialTenant() {
return createInitialTenant;
/**
* Get the tenant which overwrites the actual tenant used by the
* {@linkplain #currentTenantKeyGenerator()}.
*
* @return A present optional in case that there is a tenant in the progress of
* creation.
*/
public Optional<String> getTenantInCreation() {
return Optional.ofNullable(createInitialTenant.get());
}
/**
* Overwrite the tenant used by the key generator in case that the tenant is in
* the process of creation.
*
* @param tenant
* the tenant which should be used instead of the actual one.
*/
public void setTenantInCreation(@NotNull String tenant) {
createInitialTenant.set(Objects.requireNonNull(tenant));
}
/**
* Removes the tenant overwriting the standard one used by the
* {@linkplain #currentTenantKeyGenerator()}.
*/
public void removeTenantInCreation() {
createInitialTenant.remove();
}
}

View File

@@ -8,7 +8,10 @@
*/
package org.eclipse.hawkbit.repository.jpa.configuration;
import java.util.Objects;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.transaction.Transaction;
import org.eclipse.hawkbit.tenancy.TenantAware;
@@ -37,8 +40,10 @@ public class MultiTenantJpaTransactionManager extends JpaTransactionManager {
final String currentTenant = tenantAware.getCurrentTenant();
if (currentTenant != null) {
final EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager
.getResource(getEntityManagerFactory());
final EntityManagerFactory emFactory = Objects.requireNonNull(getEntityManagerFactory());
final EntityManagerHolder emHolder = Objects.requireNonNull(
(EntityManagerHolder) TransactionSynchronizationManager.getResource(emFactory),
"No EntityManagerHolder provided by TransactionSynchronizationManager");
final EntityManager em = emHolder.getEntityManager();
em.setProperty(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, currentTenant.toUpperCase());
}

View File

@@ -55,34 +55,34 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
/**
* Default constructor needed for JPA entities.
*/
public AbstractJpaBaseEntity() {
protected AbstractJpaBaseEntity() {
// Default constructor needed for JPA entities.
}
@Override
@Access(AccessType.PROPERTY)
@Column(name = "created_at", insertable = true, updatable = false, nullable = false)
@Column(name = "created_at", updatable = false, nullable = false)
public long getCreatedAt() {
return createdAt;
}
@Override
@Access(AccessType.PROPERTY)
@Column(name = "created_by", insertable = true, updatable = false, nullable = false, length = USERNAME_FIELD_LENGTH)
@Column(name = "created_by", updatable = false, nullable = false, length = USERNAME_FIELD_LENGTH)
public String getCreatedBy() {
return createdBy;
}
@Override
@Access(AccessType.PROPERTY)
@Column(name = "last_modified_at", insertable = true, updatable = true, nullable = false)
@Column(name = "last_modified_at", nullable = false)
public long getLastModifiedAt() {
return lastModifiedAt;
}
@Override
@Access(AccessType.PROPERTY)
@Column(name = "last_modified_by", insertable = true, updatable = true, nullable = false, length = USERNAME_FIELD_LENGTH)
@Column(name = "last_modified_by", nullable = false, length = USERNAME_FIELD_LENGTH)
public String getLastModifiedBy() {
return lastModifiedBy;
}

View File

@@ -8,6 +8,8 @@
*/
package org.eclipse.hawkbit.repository.jpa.model;
import java.util.Objects;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Id;
@@ -36,12 +38,12 @@ public abstract class AbstractJpaMetaData implements MetaData {
@Basic
private String value;
public AbstractJpaMetaData(final String key, final String value) {
protected AbstractJpaMetaData(final String key, final String value) {
this.key = key;
this.value = value;
}
public AbstractJpaMetaData() {
protected AbstractJpaMetaData() {
// Default constructor needed for JPA entities
}
@@ -64,41 +66,17 @@ public abstract class AbstractJpaMetaData implements MetaData {
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((key == null) ? 0 : key.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
public boolean equals(final Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
final AbstractJpaMetaData that = (AbstractJpaMetaData) o;
return Objects.equals(key, that.key) && Objects.equals(value, that.value);
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(this.getClass().isInstance(obj))) {
return false;
}
final AbstractJpaMetaData other = (AbstractJpaMetaData) obj;
if (key == null) {
if (other.key != null) {
return false;
}
} else if (!key.equals(other.key)) {
return false;
}
if (value == null) {
if (other.value != null) {
return false;
}
} else if (!value.equals(other.value)) {
return false;
}
return true;
public int hashCode() {
return Objects.hash(key, value);
}
}

View File

@@ -32,14 +32,14 @@ public abstract class AbstractJpaNamedEntity extends AbstractJpaTenantAwareBaseE
@NotNull
private String name;
@Column(name = "description", nullable = true, length = NamedEntity.DESCRIPTION_MAX_SIZE)
@Column(name = "description", length = NamedEntity.DESCRIPTION_MAX_SIZE)
@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE)
private String description;
/**
* Default constructor.
*/
public AbstractJpaNamedEntity() {
protected AbstractJpaNamedEntity() {
// Default constructor needed for JPA entities
}

View File

@@ -40,7 +40,7 @@ public abstract class AbstractJpaTenantAwareBaseEntity extends AbstractJpaBaseEn
/**
* Default constructor needed for JPA entities.
*/
public AbstractJpaTenantAwareBaseEntity() {
protected AbstractJpaTenantAwareBaseEntity() {
// Default constructor needed for JPA entities.
}

View File

@@ -299,22 +299,10 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
}
}
public boolean removeModule(final SoftwareModule softwareModule) {
if (modules == null) {
return false;
}
final Optional<SoftwareModule> found = modules.stream()
.filter(module -> module.getId().equals(softwareModule.getId())).findAny();
if (found.isPresent()) {
modules.remove(found.get());
public void removeModule(final SoftwareModule softwareModule) {
if (modules != null && modules.removeIf(m -> m.getId().equals(softwareModule.getId()))) {
complete = type.checkComplete(this);
return true;
}
return false;
}
@Override
@@ -371,11 +359,11 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
private static boolean isSoftDeleted(final DescriptorEvent event) {
final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet();
final List<DirectToFieldChangeRecord> changes = changeSet.getChanges().stream()
.filter(record -> record instanceof DirectToFieldChangeRecord)
.map(record -> (DirectToFieldChangeRecord) record).collect(Collectors.toList());
.filter(DirectToFieldChangeRecord.class::isInstance).map(DirectToFieldChangeRecord.class::cast)
.collect(Collectors.toList());
return changes.stream().filter(record -> DELETED_PROPERTY.equals(record.getAttribute())
&& Boolean.parseBoolean(record.getNewValue().toString())).count() > 0;
return changes.stream().anyMatch(changeRecord -> DELETED_PROPERTY.equals(changeRecord.getAttribute())
&& Boolean.parseBoolean(changeRecord.getNewValue().toString()));
}
}

View File

@@ -278,11 +278,11 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event
private static boolean isSoftDeleted(final DescriptorEvent event) {
final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet();
final List<DirectToFieldChangeRecord> changes = changeSet.getChanges().stream()
.filter(record -> record instanceof DirectToFieldChangeRecord)
.map(record -> (DirectToFieldChangeRecord) record).collect(Collectors.toList());
.filter(DirectToFieldChangeRecord.class::isInstance).map(DirectToFieldChangeRecord.class::cast)
.collect(Collectors.toList());
return changes.stream().filter(record -> DELETED_PROPERTY.equals(record.getAttribute())
&& Boolean.parseBoolean(record.getNewValue().toString())).count() > 0;
return changes.stream().anyMatch(changeRecord -> DELETED_PROPERTY.equals(changeRecord.getAttribute())
&& Boolean.parseBoolean(changeRecord.getNewValue().toString()));
}
@Override

View File

@@ -258,11 +258,11 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
private static boolean isSoftDeleted(final DescriptorEvent event) {
final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet();
final List<DirectToFieldChangeRecord> changes = changeSet.getChanges().stream()
.filter(record -> record instanceof DirectToFieldChangeRecord)
.map(record -> (DirectToFieldChangeRecord) record).collect(Collectors.toList());
.filter(DirectToFieldChangeRecord.class::isInstance).map(DirectToFieldChangeRecord.class::cast)
.collect(Collectors.toList());
return changes.stream().filter(record -> DELETED_PROPERTY.equals(record.getAttribute())
&& Boolean.parseBoolean(record.getNewValue().toString())).count() > 0;
return changes.stream().anyMatch(changeRecord -> DELETED_PROPERTY.equals(changeRecord.getAttribute())
&& Boolean.parseBoolean(changeRecord.getNewValue().toString()));
}
@Override

View File

@@ -96,7 +96,7 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAw
@Column(name = "controller_id", length = Target.CONTROLLER_ID_MAX_SIZE, updatable = false, nullable = false)
@Size(min = 1, max = Target.CONTROLLER_ID_MAX_SIZE)
@NotNull
@Pattern(regexp = "[.\\S]*", message = "has whitespaces which are not allowed")
@Pattern(regexp = "[\\S]*", message = "has whitespaces which are not allowed")
private String controllerId;
@CascadeOnDelete
@@ -243,34 +243,28 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAw
if (rolloutTargetGroup == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(rolloutTargetGroup);
}
/**
* @param tag
* tag
* @return boolean true or false
* to be added
*/
public boolean addTag(final TargetTag tag) {
public void addTag(final TargetTag tag) {
if (tags == null) {
tags = new HashSet<>();
}
return tags.add(tag);
tags.add(tag);
}
/**
* @param tag
* tag
* @return boolean true or false
* the tag to be removed from the target
*/
public boolean removeTag(final TargetTag tag) {
if (tags == null) {
return false;
public void removeTag(final TargetTag tag) {
if (tags != null) {
tags.remove(tag);
}
return tags.remove(tag);
}
/**
@@ -303,14 +297,12 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Target, EventAw
/**
* @param action
* Action
* @return boolean true or false
*/
public boolean addAction(final Action action) {
public void addAction(final Action action) {
if (actions == null) {
actions = new ArrayList<>();
}
return actions.add((JpaAction) action);
actions.add((JpaAction) action);
}
/**

View File

@@ -12,6 +12,8 @@ import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.FieldNameProvider;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.slf4j.Logger;
@@ -25,7 +27,7 @@ public abstract class AbstractFieldNameRSQLVisitor<A extends Enum<A> & FieldName
private final Class<A> fieldNameProvider;
public AbstractFieldNameRSQLVisitor(final Class<A> fieldNameProvider) {
protected AbstractFieldNameRSQLVisitor(final Class<A> fieldNameProvider) {
this.fieldNameProvider = fieldNameProvider;
}
@@ -51,7 +53,7 @@ public abstract class AbstractFieldNameRSQLVisitor<A extends Enum<A> & FieldName
// sub entity need minimum 1 dot
if (!propertyEnum.getSubEntityAttributes().isEmpty() && graph.length < 2) {
throw createRSQLParameterUnsupportedException(node);
throw createRSQLParameterUnsupportedException(node, null);
}
final StringBuilder fieldNameBuilder = new StringBuilder(propertyEnum.getFieldName());
@@ -67,7 +69,7 @@ public abstract class AbstractFieldNameRSQLVisitor<A extends Enum<A> & FieldName
}
if (!propertyEnum.containsSubEntityAttribute(propertyField)) {
throw createRSQLParameterUnsupportedException(node);
throw createRSQLParameterUnsupportedException(node, null);
}
}
@@ -93,30 +95,21 @@ public abstract class AbstractFieldNameRSQLVisitor<A extends Enum<A> & FieldName
}
}
/**
* @param node
* current processing node
* @param rootException
* in case there is a cause otherwise {@code null}
* @return Exception with prepared message extracted from the comparison node.
*/
protected RSQLParameterUnsupportedFieldException createRSQLParameterUnsupportedException(
final ComparisonNode node) {
return createRSQLParameterUnsupportedException(node, new Exception());
}
protected RSQLParameterUnsupportedFieldException createRSQLParameterUnsupportedException(final ComparisonNode node,
@NotNull final ComparisonNode node,
final Exception rootException) {
return createRSQLParameterUnsupportedException(String.format(
return new RSQLParameterUnsupportedFieldException(String.format(
"The given search parameter field {%s} does not exist, must be one of the following fields %s",
node.getSelector(), getExpectedFieldList()), rootException);
}
protected RSQLParameterUnsupportedFieldException createRSQLParameterUnsupportedException(final String message) {
return createRSQLParameterUnsupportedException(message, null);
}
protected RSQLParameterUnsupportedFieldException createRSQLParameterUnsupportedException(final String message,
final Exception rootException) {
return new RSQLParameterUnsupportedFieldException(message, rootException);
}
// Exception squid:S2095 - see
// https://jira.sonarsource.com/browse/SONARJAVA-1478
@SuppressWarnings({ "squid:S2095" })
private List<String> getExpectedFieldList() {
final List<String> expectedFieldList = Arrays.stream(fieldNameProvider.getEnumConstants())
.filter(enumField -> enumField.getSubEntityAttributes().isEmpty()).map(enumField -> {

View File

@@ -181,7 +181,7 @@ public class JpaQueryRsqlVisitor<A extends Enum<A> & FieldNameProvider, T> exten
private Path<Object> getFieldPath(final A enumField, final String finalProperty) {
return (Path<Object>) getFieldPath(root, enumField.getSubAttributes(finalProperty), enumField.isMap(),
this::getJoinFieldPath).orElseThrow(
() -> createRSQLParameterUnsupportedException("RSQL field path cannot be empty", null));
() -> new RSQLParameterUnsupportedFieldException("RSQL field path cannot be empty", null));
}
@SuppressWarnings("unchecked")
@@ -279,7 +279,7 @@ public class JpaQueryRsqlVisitor<A extends Enum<A> & FieldNameProvider, T> exten
private Object convertFieldConverterValue(final ComparisonNode node, final A fieldName, final String value) {
final Object convertedValue = ((FieldValueConverter) fieldName).convertValue(fieldName, value);
if (convertedValue == null) {
throw createRSQLParameterUnsupportedException(
throw new RSQLParameterUnsupportedFieldException(
"field {" + node.getSelector() + "} must be one of the following values {"
+ Arrays.toString(((FieldValueConverter) fieldName).possibleValues(fieldName)) + "}",
null);

View File

@@ -11,7 +11,7 @@ package org.eclipse.hawkbit.repository.jpa.rsql;
import java.lang.reflect.Field;
import java.util.Arrays;
import com.google.common.base.Throwables;
import org.springframework.util.ReflectionUtils;
import cz.jirutka.rsql.parser.ParseException;
@@ -24,13 +24,7 @@ import cz.jirutka.rsql.parser.ParseException;
*/
public class ParseExceptionWrapper {
private static final String FIELD_EXPECTED_TOKEN_SEQ = "expectedTokenSequences";
private static final String FIELD_CURRENT_TOKEN = "currentToken";
private final ParseException parseException;
private final Class<? extends ParseException> parseExceptionClass;
private Field expectedTokenSequenceField;
private Field currentTokenField;
/**
* Constructor.
@@ -41,33 +35,24 @@ public class ParseExceptionWrapper {
*/
public ParseExceptionWrapper(final ParseException parseException) {
this.parseException = parseException;
parseExceptionClass = parseException.getClass();
try {
expectedTokenSequenceField = getAccessibleField(parseExceptionClass, FIELD_EXPECTED_TOKEN_SEQ);
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
expectedTokenSequenceField = null;
}
try {
currentTokenField = getAccessibleField(parseExceptionClass, FIELD_CURRENT_TOKEN);
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
currentTokenField = null;
}
}
public int[][] getExpectedTokenSequence() {
if (expectedTokenSequenceField == null) {
return new int[0][0];
}
return (int[][]) getValue(expectedTokenSequenceField, parseException);
return (parseException.expectedTokenSequences != null) // unclear if this can happen
? parseException.expectedTokenSequences
: new int[0][0];
}
/**
* Get the current token
*
* @return the current token or {@code null} if there is non.
*/
public TokenWrapper getCurrentToken() {
if (currentTokenField == null) {
return null;
}
return new TokenWrapper(getValue(currentTokenField, parseException));
return (parseException.currentToken != null) // unclear if this can happen
? new TokenWrapper(parseException.currentToken)
: null;
}
@Override
@@ -76,19 +61,6 @@ public class ParseExceptionWrapper {
+ ", getCurrentToken()=" + getCurrentToken() + "]";
}
private static Field getAccessibleField(final Class<?> clazz, final String field) throws NoSuchFieldException {
final Field declaredField = clazz.getDeclaredField(field);
declaredField.setAccessible(true);
return declaredField;
}
private static Object getValue(final Field field, final Object instance) {
try {
return field.get(instance);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw Throwables.propagate(e);
}
}
/**
* A {@link TokenWrapper} which wraps the
@@ -115,37 +87,37 @@ public class ParseExceptionWrapper {
this.tokenInstance = tokenField;
try {
nextTokenField = getAccessibleField(tokenField.getClass(), FIELD_NEXT);
nextTokenField = getAccessibleField(FIELD_NEXT);
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
nextTokenField = null;
}
try {
kindTokenField = getAccessibleField(tokenField.getClass(), FIELD_KIND);
kindTokenField = getAccessibleField(FIELD_KIND);
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
kindTokenField = null;
}
try {
imageTokenField = getAccessibleField(tokenField.getClass(), FIELD_IMAGE);
imageTokenField = getAccessibleField(FIELD_IMAGE);
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
imageTokenField = null;
}
try {
beginColumnTokenField = getAccessibleField(tokenField.getClass(), FIELD_BEGIN_COL);
beginColumnTokenField = getAccessibleField(FIELD_BEGIN_COL);
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
beginColumnTokenField = null;
}
try {
endColumnTokenField = getAccessibleField(tokenField.getClass(), FIELD_END_COL);
endColumnTokenField = getAccessibleField(FIELD_END_COL);
} catch (@SuppressWarnings("squid:S1166") final NoSuchFieldException e) {
endColumnTokenField = null;
}
}
public TokenWrapper getNext() {
final Object nextToken = getValue(nextTokenField, tokenInstance);
final Object nextToken = getValue(nextTokenField);
return nextToken != null ? new TokenWrapper(nextToken) : null;
}
@@ -154,28 +126,42 @@ public class ParseExceptionWrapper {
if (kindTokenField == null) {
return 0;
}
return (int) getValue(kindTokenField, tokenInstance);
return (int) getValue(kindTokenField);
}
public String getImage() {
if (imageTokenField == null) {
return null;
}
return (String) getValue(imageTokenField, tokenInstance);
return (String) getValue(imageTokenField);
}
public int getBeginColumn() {
if (beginColumnTokenField == null) {
return 0;
}
return (int) getValue(beginColumnTokenField, tokenInstance);
return (int) getValue(beginColumnTokenField);
}
public int getEndColumn() {
if (endColumnTokenField == null) {
return 0;
}
return (int) getValue(endColumnTokenField, tokenInstance);
return (int) getValue(endColumnTokenField);
}
private Field getAccessibleField(final String field) throws NoSuchFieldException {
final Field declaredField = tokenInstance.getClass().getDeclaredField(field);
ReflectionUtils.makeAccessible(declaredField);
return declaredField;
}
private Object getValue(final Field field) {
try {
return field.get(tokenInstance);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalFieldAccessExeption(e);
}
}
@Override
@@ -185,4 +171,11 @@ public class ParseExceptionWrapper {
+ ", getEndColumn()=" + getEndColumn() + "]";
}
}
static class IllegalFieldAccessExeption extends RuntimeException {
public IllegalFieldAccessExeption(Throwable e) {
super(e);
}
}
}

View File

@@ -116,7 +116,7 @@ public class RsqlParserValidationOracle implements RsqlValidationOracle {
private static List<SuggestToken> getNextTokens(final ParseException parseException) {
final List<SuggestToken> listTokens = new ArrayList<>();
final ParseExceptionWrapper parseExceptionWrapper = new ParseExceptionWrapper(parseException);
final int[][] expectedTokenSequence = parseExceptionWrapper.getExpectedTokenSequence();
final int[][] expectedTokenSequence = parseException.expectedTokenSequences;
final TokenWrapper currentToken = parseExceptionWrapper.getCurrentToken();
if (currentToken == null) {
return Collections.emptyList();
@@ -243,8 +243,8 @@ public class RsqlParserValidationOracle implements RsqlValidationOracle {
}
builder = builder.replace('\r', ' ');
builder = builder.replace('\n', ' ');
builder = builder.replaceAll(">", " ");
builder = builder.replaceAll("<", " ");
builder = builder.replace(">", " ");
builder = builder.replace("<", " ");
return builder;
}

View File

@@ -10,6 +10,8 @@ package org.eclipse.hawkbit.repository.jpa;
import static org.assertj.core.api.Assertions.assertThat;
import org.awaitility.Awaitility;
import org.awaitility.Duration;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.junit.jupiter.api.Test;
@@ -24,7 +26,7 @@ public class ActionTest {
@Test
@Description("Ensures that timeforced moded switch from soft to forces after defined timeframe.")
public void timeforcedHitNewHasCodeIsGenerated() throws InterruptedException {
public void timeforcedHitNewHasCodeIsGenerated() {
// current time + 1 seconds
final long sleepTime = 1000;
@@ -32,10 +34,10 @@ public class ActionTest {
final JpaAction timeforcedAction = new JpaAction();
timeforcedAction.setActionType(ActionType.TIMEFORCED);
timeforcedAction.setForcedTime(timeForceTimeAt);
assertThat(timeforcedAction.isForce()).isFalse();
assertThat(timeforcedAction.isForcedOrTimeForced()).isFalse();
// wait until timeforce time is hit
Thread.sleep(sleepTime + 100);
assertThat(timeforcedAction.isForce()).isTrue();
Awaitility.await().atMost(Duration.TWO_SECONDS).pollInterval(Duration.ONE_HUNDRED_MILLISECONDS)
.until(timeforcedAction::isForcedOrTimeForced);
}
}

View File

@@ -50,11 +50,11 @@ import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedE
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleUpdatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.InvalidTargetAttributeException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.Status;
@@ -69,6 +69,7 @@ import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.test.matcher.Expect;
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
import org.eclipse.hawkbit.repository.test.util.TargetTestData;
import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
@@ -85,7 +86,7 @@ import io.qameta.allure.Story;
@Feature("Component Tests - Repository")
@Story("Controller Management")
public class ControllerManagementTest extends AbstractJpaIntegrationTest {
class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Autowired
private RepositoryProperties repositoryProperties;
@@ -95,7 +96,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
+ "of Optional not present.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 1) })
public void nonExistingEntityAccessReturnsNotPresent() {
void nonExistingEntityAccessReturnsNotPresent() {
final Target target = testdataFactory.createTarget();
final SoftwareModule module = testdataFactory.createSoftwareModuleOs();
@@ -116,7 +117,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
+ " by means of throwing EntityNotFoundException.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 1) })
public void entityQueriesReferringToNotExistingEntitiesThrowsException() throws URISyntaxException {
void entityQueriesReferringToNotExistingEntitiesThrowsException() throws URISyntaxException {
final Target target = testdataFactory.createTarget();
final SoftwareModule module = testdataFactory.createSoftwareModuleOs();
@@ -157,7 +158,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void controllerConfirmsUpdateWithFinished() {
void controllerConfirmsUpdateWithFinished() {
final Long actionId = createTargetAndAssignDs();
simulateIntermediateStatusOnUpdate(actionId);
@@ -178,7 +179,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void controllerConfirmationFailsWithInvalidMessages() {
void controllerConfirmationFailsWithInvalidMessages() {
final Long actionId = createTargetAndAssignDs();
simulateIntermediateStatusOnUpdate(actionId);
@@ -209,7 +210,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void controllerConfirmsUpdateWithFinishedAndIgnoresCancellationWithThat() {
void controllerConfirmsUpdateWithFinishedAndIgnoresCancellationWithThat() {
final Long actionId = createTargetAndAssignDs();
deploymentManagement.cancelAction(actionId);
@@ -229,7 +230,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void cancellationFeedbackRejectedIfActionIsNotInCanceling() {
void cancellationFeedbackRejectedIfActionIsNotInCanceling() {
final Long actionId = createTargetAndAssignDs();
assertThatExceptionOfType(CancelActionNotAllowedException.class)
@@ -253,7 +254,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void controllerConfirmsActionCancellationWithFinished() {
void controllerConfirmsActionCancellationWithFinished() {
final Long actionId = createTargetAndAssignDs();
deploymentManagement.cancelAction(actionId);
@@ -280,7 +281,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void controllerConfirmsActionCancellationWithCanceled() {
void controllerConfirmsActionCancellationWithCanceled() {
final Long actionId = createTargetAndAssignDs();
deploymentManagement.cancelAction(actionId);
@@ -308,7 +309,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void controllerRejectsActionCancellationWithReject() {
void controllerRejectsActionCancellationWithReject() {
final Long actionId = createTargetAndAssignDs();
deploymentManagement.cancelAction(actionId);
@@ -336,7 +337,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void controllerRejectsActionCancellationWithError() {
void controllerRejectsActionCancellationWithError() {
final Long actionId = createTargetAndAssignDs();
deploymentManagement.cancelAction(actionId);
@@ -472,7 +473,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 2) })
public void hasTargetArtifactAssignedIsTrueWithMultipleArtifacts() {
void hasTargetArtifactAssignedIsTrueWithMultipleArtifacts() {
final int artifactSize = 5 * 1024;
final byte[] random = RandomUtils.nextBytes(artifactSize);
@@ -503,7 +504,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Description("Register a controller which does not exist")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 2) })
public void findOrRegisterTargetIfItDoesNotExist() {
void findOrRegisterTargetIfItDoesNotExist() {
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST);
assertThat(target).as("target should not be null").isNotNull();
@@ -516,7 +517,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Description("Register a controller with name which does not exist and update its name")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 2), @Expect(type = TargetUpdatedEvent.class, count = 1) })
public void findOrRegisterTargetIfItDoesNotExistWithName() {
void findOrRegisterTargetIfItDoesNotExistWithName() {
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST, "TestName");
final Target sameTarget = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST,
"ChangedTestName");
@@ -528,7 +529,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Tries to register a target with an invalid controller id")
public void findOrRegisterTargetIfItDoesNotExistThrowsExceptionForInvalidControllerIdParam() {
void findOrRegisterTargetIfItDoesNotExistThrowsExceptionForInvalidControllerIdParam() {
assertThatExceptionOfType(ConstraintViolationException.class)
.as("register target with null as controllerId should fail")
.isThrownBy(() -> controllerManagement.findOrRegisterTargetIfItDoesNotExist(null, LOCALHOST));
@@ -550,7 +551,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Register a controller which does not exist, when a ConcurrencyFailureException is raised, the "
+ "exception is rethrown after max retries")
public void findOrRegisterTargetIfItDoesNotExistThrowsExceptionAfterMaxRetries() {
void findOrRegisterTargetIfItDoesNotExistThrowsExceptionAfterMaxRetries() {
final TargetRepository mockTargetRepository = Mockito.mock(TargetRepository.class);
when(mockTargetRepository.findOne(any())).thenThrow(ConcurrencyFailureException.class);
((JpaControllerManagement) controllerManagement).setTargetRepository(mockTargetRepository);
@@ -572,7 +573,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
+ "exception is not rethrown when the max retries are not yet reached")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 1) })
public void findOrRegisterTargetIfItDoesNotExistDoesNotThrowExceptionBeforeMaxRetries() {
void findOrRegisterTargetIfItDoesNotExistDoesNotThrowExceptionBeforeMaxRetries() {
final TargetRepository mockTargetRepository = Mockito.mock(TargetRepository.class);
((JpaControllerManagement) controllerManagement).setTargetRepository(mockTargetRepository);
@@ -598,7 +599,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Description("Register a controller which does not exist, then update the controller twice, first time by providing a name property and second time without a new name")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 3), @Expect(type = TargetUpdatedEvent.class, count = 1) })
public void findOrRegisterTargetIfItDoesNotExistDoesUpdateNameOnExistingTargetProperly() {
void findOrRegisterTargetIfItDoesNotExistDoesUpdateNameOnExistingTargetProperly() {
final String controllerId = "12345";
final String targetName = "UpdatedName";
@@ -620,7 +621,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Register a controller which does not exist, if a EntityAlreadyExistsException is raised, the "
+ "exception is rethrown and no further retries will be attempted")
public void findOrRegisterTargetIfItDoesNotExistDoesntRetryWhenEntityAlreadyExistsException() {
void findOrRegisterTargetIfItDoesNotExistDoesntRetryWhenEntityAlreadyExistsException() {
final TargetRepository mockTargetRepository = Mockito.mock(TargetRepository.class);
((JpaControllerManagement) controllerManagement).setTargetRepository(mockTargetRepository);
@@ -643,7 +644,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Retry is aborted when an unchecked exception is thrown and the exception should also be "
+ "rethrown")
public void recoverFindOrRegisterTargetIfItDoesNotExistIsNotInvokedForOtherExceptions() {
void recoverFindOrRegisterTargetIfItDoesNotExistIsNotInvokedForOtherExceptions() {
final TargetRepository mockTargetRepository = Mockito.mock(TargetRepository.class);
((JpaControllerManagement) controllerManagement).setTargetRepository(mockTargetRepository);
@@ -666,7 +667,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6) })
public void findTargetVisibleMetaDataBySoftwareModuleId() {
void findTargetVisibleMetaDataBySoftwareModuleId() {
final DistributionSet set = testdataFactory.createDistributionSet();
testdataFactory.addSoftwareModuleMetadata(set);
@@ -682,7 +683,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Description("Verify that controller registration does not result in a TargetPollEvent if feature is disabled")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 0) })
public void targetPollEventNotSendIfDisabled() {
void targetPollEventNotSendIfDisabled() {
repositoryProperties.setPublishTargetPollEvent(false);
controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST);
repositoryProperties.setPublishTargetPollEvent(true);
@@ -696,7 +697,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = TargetUpdatedEvent.class, count = 2),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void tryToFinishWithErrorUpdateProcessMoreThanOnce() {
void tryToFinishWithErrorUpdateProcessMoreThanOnce() {
final Long actionId = createTargetAndAssignDs();
// test and verify
@@ -743,7 +744,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void tryToFinishUpdateProcessMoreThanOnce() {
void tryToFinishUpdateProcessMoreThanOnce() {
final Long actionId = prepareFinishedUpdate().getId();
// try with disabled late feedback
@@ -780,7 +781,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void sendUpdatesForFinishUpdateProcessDroppedIfDisabled() {
void sendUpdatesForFinishUpdateProcessDroppedIfDisabled() {
repositoryProperties.setRejectActionStatusForClosedAction(true);
final Action action = prepareFinishedUpdate();
@@ -807,7 +808,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void sendUpdatesForFinishUpdateProcessAcceptedIfEnabled() {
void sendUpdatesForFinishUpdateProcessAcceptedIfEnabled() {
repositoryProperties.setRejectActionStatusForClosedAction(false);
Action action = prepareFinishedUpdate();
@@ -828,7 +829,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Description("Ensures that target attribute update is reflected by the repository.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 3) })
public void updateTargetAttributes() throws Exception {
void updateTargetAttributes() throws Exception {
final String controllerId = "test123";
final Target target = testdataFactory.createTarget(controllerId);
@@ -884,7 +885,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Description("Ensures that target attributes can be updated using different update modes.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 4) })
public void updateTargetAttributesWithDifferentUpdateModes() {
void updateTargetAttributesWithDifferentUpdateModes() {
final String controllerId = "testCtrl";
testdataFactory.createTarget(controllerId);
@@ -1027,33 +1028,28 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Checks if invalid values of attribute-key and attribute-value are handled correctly")
public void updateTargetAttributesFailsForInvalidAttributes() {
final String keyTooLong = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_KEY_SIZE + 1);
final String keyValid = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_KEY_SIZE);
final String valueTooLong = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE + 1);
final String valueValid = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE);
final String keyNull = null;
final String controllerId = "targetId123";
testdataFactory.createTarget(controllerId);
assertThatExceptionOfType(InvalidTargetAttributeException.class)
.as("Attribute with key too long should not be created")
.isThrownBy(() -> controllerManagement.updateControllerAttributes(controllerId,
Collections.singletonMap(keyTooLong, valueValid), null));
Collections.singletonMap(TargetTestData.ATTRIBUTE_KEY_TOO_LONG, TargetTestData.ATTRIBUTE_VALUE_VALID), null));
assertThatExceptionOfType(InvalidTargetAttributeException.class)
.as("Attribute with key too long and value too long should not be created")
.isThrownBy(() -> controllerManagement.updateControllerAttributes(controllerId,
Collections.singletonMap(keyTooLong, valueTooLong), null));
Collections.singletonMap(TargetTestData.ATTRIBUTE_KEY_TOO_LONG, TargetTestData.ATTRIBUTE_VALUE_TOO_LONG), null));
assertThatExceptionOfType(InvalidTargetAttributeException.class)
.as("Attribute with value too long should not be created")
.isThrownBy(() -> controllerManagement.updateControllerAttributes(controllerId,
Collections.singletonMap(keyValid, valueTooLong), null));
Collections.singletonMap(TargetTestData.ATTRIBUTE_KEY_VALID, TargetTestData.ATTRIBUTE_VALUE_TOO_LONG), null));
assertThatExceptionOfType(InvalidTargetAttributeException.class)
.as("Attribute with key NULL should not be created").isThrownBy(() -> controllerManagement
.updateControllerAttributes(controllerId, Collections.singletonMap(keyNull, valueValid), null));
.updateControllerAttributes(controllerId,
Collections.singletonMap(null, TargetTestData.ATTRIBUTE_VALUE_VALID), null));
}
@Test
@@ -1198,7 +1194,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = ActionUpdatedEvent.class, count = 1),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void controllerReportsDownloadedForDownloadOnlyAction() {
void controllerReportsDownloadedForDownloadOnlyAction() {
testdataFactory.createTarget();
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
assertThat(actionId).isNotNull();
@@ -1221,7 +1217,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = ActionUpdatedEvent.class, count = 2),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void controllerReportsActionFinishedForDownloadOnlyActionThatIsNotActive() {
void controllerReportsActionFinishedForDownloadOnlyActionThatIsNotActive() {
testdataFactory.createTarget();
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
assertThat(actionId).isNotNull();
@@ -1244,7 +1240,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = ActionUpdatedEvent.class, count = 1),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void controllerReportsMultipleDownloadedForDownloadOnlyAction() {
void controllerReportsMultipleDownloadedForDownloadOnlyAction() {
testdataFactory.createTarget();
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
assertThat(actionId).isNotNull();
@@ -1269,7 +1265,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = TargetAttributesRequestedEvent.class, count = 9),
@Expect(type = ActionUpdatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void quotaExceptionWhencontrollerReportsTooManyDownloadedMessagesForDownloadOnlyAction() {
void quotaExceptionWhencontrollerReportsTooManyDownloadedMessagesForDownloadOnlyAction() {
final int maxMessages = quotaManagement.getMaxMessagesPerActionStatus();
testdataFactory.createTarget();
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
@@ -1289,7 +1285,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = ActionUpdatedEvent.class, count = 1),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void quotaExceededExceptionWhenControllerReportsTooManyUpdateActionStatusMessagesForDownloadOnlyAction() {
void quotaExceededExceptionWhenControllerReportsTooManyUpdateActionStatusMessagesForDownloadOnlyAction() {
final int maxMessages = quotaManagement.getMaxMessagesPerActionStatus();
testdataFactory.createTarget();
final Long actionId = createAndAssignDsAsDownloadOnly("downloadOnlyDs", DEFAULT_CONTROLLER_ID);
@@ -1318,7 +1314,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 1),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void quotaExceededExceptionWhenControllerReportsTooManyUpdateActionStatusMessagesForForced() {
void quotaExceededExceptionWhenControllerReportsTooManyUpdateActionStatusMessagesForForced() {
final int maxMessages = quotaManagement.getMaxMessagesPerActionStatus();
final Long actionId = createTargetAndAssignDs();
assertThat(actionId).isNotNull();
@@ -1341,7 +1337,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify that the attaching externalRef to an action is properly stored")
public void updatedExternalRefOnActionIsReallyUpdated() {
void updatedExternalRefOnActionIsReallyUpdated() {
final List<String> allExternalRef = new ArrayList<>();
final List<Long> allActionId = new ArrayList<>();
final int numberOfActions = 3;
@@ -1369,7 +1365,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify that getting a single action using externalRef works")
public void getActionUsingSingleExternalRef() {
void getActionUsingSingleExternalRef() {
final String knownControllerId = "controllerId";
final String knownExternalRef = "externalRefId";
@@ -1392,7 +1388,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify that a null externalRef cannot be assigned to an action")
public void externalRefCannotBeNull() {
void externalRefCannotBeNull() {
assertThatExceptionOfType(ConstraintViolationException.class)
.as("No ConstraintViolationException thrown when a null externalRef was set on an action")
.isThrownBy(() -> controllerManagement.updateActionExternalRef(1L, null));
@@ -1408,7 +1404,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = TargetAttributesRequestedEvent.class, count = 6),
@Expect(type = ActionUpdatedEvent.class, count = 8),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 12) })
public void targetCanAlwaysReportFinishedOrErrorAfterActionIsClosedForDownloadOnlyAssignments() {
void targetCanAlwaysReportFinishedOrErrorAfterActionIsClosedForDownloadOnlyAssignments() {
testdataFactory.createTarget();
@@ -1459,7 +1455,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = ActionUpdatedEvent.class, count = 3),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6) })
public void controllerReportsFinishedForOldDownloadOnlyActionAfterSuccessfulForcedAssignment() {
void controllerReportsFinishedForOldDownloadOnlyActionAfterSuccessfulForcedAssignment() {
testdataFactory.createTarget();
final DistributionSet downloadOnlyDs = testdataFactory.createDistributionSet("downloadOnlyDs1");
@@ -1495,7 +1491,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Actions are exposed according to thier weight in multi assignment mode.")
public void actionsAreExposedAccordingToTheirWeight() {
void actionsAreExposedAccordingToTheirWeight() {
final String targetId = testdataFactory.createTarget().getControllerId();
final DistributionSet ds = testdataFactory.createDistributionSet();
final Long actionWeightNull = assignDistributionSet(ds.getId(), targetId).getAssignedEntity().get(0).getId();
@@ -1552,7 +1548,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Description("Delete a target on requested target deletion from client side")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 1), @Expect(type = TargetDeletedEvent.class, count = 1) })
public void deleteTargetWithValidThingId() {
void deleteTargetWithValidThingId() {
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST);
assertThat(target).as("target should not be null").isNotNull();
assertThat(targetRepository.count()).as("target exists and is ready for deletion").isEqualTo(1L);
@@ -1565,7 +1561,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Delete a target with a non existing thingId")
@ExpectEvents({ @Expect(type = TargetDeletedEvent.class, count = 0) })
public void deleteTargetWithInvalidThingId() {
void deleteTargetWithInvalidThingId() {
assertThatExceptionOfType(EntityNotFoundException.class)
.as("No EntityNotFoundException thrown when deleting a non-existing target")
.isThrownBy(() -> controllerManagement.deleteExistingTarget("BB"));
@@ -1576,7 +1572,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Description("Delete a target after it has been deleted already")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 1), @Expect(type = TargetDeletedEvent.class, count = 1) })
public void deleteTargetAfterItWasDeleted() {
void deleteTargetAfterItWasDeleted() {
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST);
assertThat(target).as("target should not be null").isNotNull();
assertThat(targetRepository.count()).as("target exists and is ready for deletion").isEqualTo(1L);

View File

@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -18,6 +19,8 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -74,14 +77,16 @@ import io.qameta.allure.Story;
*/
@Feature("Component Tests - Repository")
@Story("DistributionSet Management")
public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
public static final String TAG1_NAME = "Tag1";
@Test
@Description("Verifies that management get access react as specfied on calls for non existing entities by means "
@Description("Verifies that management get access react as specified on calls for non existing entities by means "
+ "of Optional not present.")
@ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
public void nonExistingEntityAccessReturnsNotPresent() {
void nonExistingEntityAccessReturnsNotPresent() {
final DistributionSet set = testdataFactory.createDistributionSet();
assertThat(distributionSetManagement.get(NOT_EXIST_IDL)).isNotPresent();
assertThat(distributionSetManagement.getWithDetails(NOT_EXIST_IDL)).isNotPresent();
@@ -95,16 +100,16 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = DistributionSetTagCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 4) })
public void entityQueriesReferringToNotExistingEntitiesThrowsException() {
void entityQueriesReferringToNotExistingEntitiesThrowsException() {
final DistributionSet set = testdataFactory.createDistributionSet();
final DistributionSetTag dsTag = testdataFactory.createDistributionSetTags(1).get(0);
final SoftwareModule module = testdataFactory.createSoftwareModuleApp();
verifyThrownExceptionBy(
() -> distributionSetManagement.assignSoftwareModules(NOT_EXIST_IDL, Arrays.asList(module.getId())),
() -> distributionSetManagement.assignSoftwareModules(NOT_EXIST_IDL, singletonList(module.getId())),
"DistributionSet");
verifyThrownExceptionBy(
() -> distributionSetManagement.assignSoftwareModules(set.getId(), Arrays.asList(NOT_EXIST_IDL)),
() -> distributionSetManagement.assignSoftwareModules(set.getId(), singletonList(NOT_EXIST_IDL)),
"SoftwareModule");
verifyThrownExceptionBy(() -> distributionSetManagement.countByTypeId(NOT_EXIST_IDL), "DistributionSet");
@@ -114,10 +119,10 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
verifyThrownExceptionBy(() -> distributionSetManagement.unassignSoftwareModule(set.getId(), NOT_EXIST_IDL),
"SoftwareModule");
verifyThrownExceptionBy(() -> distributionSetManagement.assignTag(Arrays.asList(set.getId()), NOT_EXIST_IDL),
verifyThrownExceptionBy(() -> distributionSetManagement.assignTag(singletonList(set.getId()), NOT_EXIST_IDL),
"DistributionSetTag");
verifyThrownExceptionBy(() -> distributionSetManagement.assignTag(Arrays.asList(NOT_EXIST_IDL), dsTag.getId()),
verifyThrownExceptionBy(() -> distributionSetManagement.assignTag(singletonList(NOT_EXIST_IDL), dsTag.getId()),
"DistributionSet");
verifyThrownExceptionBy(() -> distributionSetManagement.findByTag(PAGE, NOT_EXIST_IDL), "DistributionSetTag");
@@ -125,10 +130,10 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
"DistributionSetTag");
verifyThrownExceptionBy(
() -> distributionSetManagement.toggleTagAssignment(Arrays.asList(NOT_EXIST_IDL), dsTag.getName()),
() -> distributionSetManagement.toggleTagAssignment(singletonList(NOT_EXIST_IDL), dsTag.getName()),
"DistributionSet");
verifyThrownExceptionBy(
() -> distributionSetManagement.toggleTagAssignment(Arrays.asList(set.getId()), NOT_EXIST_ID),
() -> distributionSetManagement.toggleTagAssignment(singletonList(set.getId()), NOT_EXIST_ID),
"DistributionSetTag");
verifyThrownExceptionBy(() -> distributionSetManagement.unAssignTag(set.getId(), NOT_EXIST_IDL),
@@ -143,9 +148,9 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
"DistributionSetType");
verifyThrownExceptionBy(() -> distributionSetManagement.createMetaData(NOT_EXIST_IDL,
Arrays.asList(entityFactory.generateDsMetadata("123", "123"))), "DistributionSet");
singletonList(entityFactory.generateDsMetadata("123", "123"))), "DistributionSet");
verifyThrownExceptionBy(() -> distributionSetManagement.delete(Arrays.asList(NOT_EXIST_IDL)),
verifyThrownExceptionBy(() -> distributionSetManagement.delete(singletonList(NOT_EXIST_IDL)),
"DistributionSet");
verifyThrownExceptionBy(() -> distributionSetManagement.delete(NOT_EXIST_IDL), "DistributionSet");
verifyThrownExceptionBy(() -> distributionSetManagement.deleteMetaData(NOT_EXIST_IDL, "xxx"),
@@ -191,8 +196,8 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Description("Verify that a DistributionSet with invalid properties cannot be created or updated")
@ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = DistributionSetUpdatedEvent.class, count = 0) })
public void createAndUpdateDistributionSetWithInvalidFields() {
@Expect(type = DistributionSetUpdatedEvent.class) })
void createAndUpdateDistributionSetWithInvalidFields() {
final DistributionSet set = testdataFactory.createDistributionSet();
createAndUpdateDistributionSetWithInvalidDescription(set);
@@ -204,57 +209,57 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
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))))
.as("entity with too long description should not be created");
.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)))
.as("entity with invalid description should not be created");
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))))
.as("entity with too long description should not be updated");
.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)))
.as("entity with invalid characters should not be updated");
.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))))
.as("entity with too long name should not be created");
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
() -> distributionSetManagement.create(entityFactory.distributionSet().create().version("a").name("")))
.as("entity with too short name should not be created");
.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)))
.as("entity with invalid characters in name should not be created");
.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))))
.as("entity with too long name should not be updated");
.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)))
.as("entity with invalid characters should not be updated");
.update(entityFactory.distributionSet().update(set.getId()).name(INVALID_TEXT_HTML)));
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId()).name("")))
.as("entity with too short name should not be updated");
assertThatExceptionOfType(ConstraintViolationException.class)
.as("entity with too short name should not be updated").isThrownBy(() -> distributionSetManagement
.update(entityFactory.distributionSet().update(set.getId()).name("")));
}
@@ -262,28 +267,28 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
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))))
.as("entity with too long version should not be created");
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a").version("")))
.as("entity with too short version should not be created");
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))));
assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId())
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))))
.as("entity with too long version should not be updated");
.as("entity with too short version should not be created").isThrownBy(() -> distributionSetManagement
.create(entityFactory.distributionSet().create().name("a").version("")));
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId()).version("")))
.as("entity with too short version should not be updated");
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).")
public void createDuplicateDistributionSetsFailsWithException() {
void createDuplicateDistributionSetsFailsWithException() {
testdataFactory.createDistributionSet("a");
assertThatThrownBy(() -> testdataFactory.createDistributionSet("a"))
@@ -292,7 +297,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that a DS is of default type if not specified explicitly at creation time.")
public void createDistributionSetWithImplicitType() {
void createDistributionSetWithImplicitType() {
final DistributionSet set = distributionSetManagement
.create(entityFactory.distributionSet().create().name("newtypesoft").version("1"));
@@ -303,7 +308,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that a DS cannot be created if another DS with same name and version exists.")
public void createDistributionSetWithDuplicateNameAndVersionFails() {
void createDistributionSetWithDuplicateNameAndVersionFails() {
distributionSetManagement.create(entityFactory.distributionSet().create().name("newtypesoft").version("1"));
assertThatExceptionOfType(EntityAlreadyExistsException.class).isThrownBy(() -> distributionSetManagement
@@ -313,7 +318,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that multiple DS are of default type if not specified explicitly at creation time.")
public void createMultipleDistributionSetsWithImplicitType() {
void createMultipleDistributionSetsWithImplicitType() {
final List<DistributionSetCreate> creates = Lists.newArrayListWithExpectedSize(10);
for (int i = 0; i < 10; i++) {
@@ -333,7 +338,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Checks that metadata for a distribution set can be created.")
public void createDistributionSetMetadata() {
void createDistributionSetMetadata() {
final String knownKey = "dsMetaKnownKey";
final String knownValue = "dsMetaKnownValue";
@@ -351,7 +356,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies the enforcement of the metadata quota per distribution set.")
public void createDistributionSetMetadataUntilQuotaIsExceeded() {
void createDistributionSetMetadataUntilQuotaIsExceeded() {
// add meta data one by one
final DistributionSet ds1 = testdataFactory.createDistributionSet("ds1");
@@ -378,7 +383,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
// add some meta data entries
final DistributionSet ds3 = testdataFactory.createDistributionSet("ds3");
final int firstHalf = Math.round(maxMetaData / 2);
final int firstHalf = Math.round(((float) maxMetaData) / 2.f);
for (int i = 0; i < firstHalf; ++i) {
createDistributionSetMetadata(ds3.getId(), new JpaDistributionSetMetadata("k" + i, ds3, "v" + i));
}
@@ -396,20 +401,21 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Ensures that distribution sets can assigned and unassigned to a distribution set tag.")
public void assignAndUnassignDistributionSetToTag() {
void assignAndUnassignDistributionSetToTag() {
final List<Long> assignDS = Lists.newArrayListWithExpectedSize(4);
for (int i = 0; i < 4; i++) {
assignDS.add(testdataFactory.createDistributionSet("DS" + i, "1.0", Collections.emptyList()).getId());
}
final DistributionSetTag tag = distributionSetTagManagement.create(entityFactory.tag().create().name("Tag1"));
final DistributionSetTag tag = distributionSetTagManagement
.create(entityFactory.tag().create().name(TAG1_NAME));
final List<DistributionSet> assignedDS = distributionSetManagement.assignTag(assignDS, tag.getId());
assertThat(assignedDS.size()).as("assigned ds has wrong size").isEqualTo(4);
assignedDS.stream().map(c -> (JpaDistributionSet) c)
.forEach(ds -> assertThat(ds.getTags().size()).as("ds has wrong tag size").isEqualTo(1));
DistributionSetTag findDistributionSetTag = distributionSetTagManagement.getByName("Tag1").get();
DistributionSetTag findDistributionSetTag = getOrThrow(distributionSetTagManagement.getByName(TAG1_NAME));
assertThat(assignedDS.size()).as("assigned ds has wrong size")
.isEqualTo(distributionSetManagement.findByTag(PAGE, tag.getId()).getNumberOfElements());
@@ -417,20 +423,20 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
final JpaDistributionSet unAssignDS = (JpaDistributionSet) distributionSetManagement
.unAssignTag(assignDS.get(0), findDistributionSetTag.getId());
assertThat(unAssignDS.getId()).as("unassigned ds is wrong").isEqualTo(assignDS.get(0));
assertThat(unAssignDS.getTags().size()).as("unassigned ds has wrong tag size").isEqualTo(0);
findDistributionSetTag = distributionSetTagManagement.getByName("Tag1").get();
assertThat(unAssignDS.getTags().size()).as("unassigned ds has wrong tag size").isZero();
assertThat(distributionSetTagManagement.getByName(TAG1_NAME)).isPresent();
assertThat(distributionSetManagement.findByTag(PAGE, tag.getId()).getNumberOfElements())
.as("ds tag ds has wrong ds size").isEqualTo(3);
assertThat(distributionSetManagement.findByRsqlAndTag(PAGE, "name==" + unAssignDS.getName(), tag.getId())
.getNumberOfElements()).as("ds tag ds has wrong ds size").isEqualTo(0);
.getNumberOfElements()).as("ds tag ds has wrong ds size").isZero();
assertThat(distributionSetManagement.findByRsqlAndTag(PAGE, "name!=" + unAssignDS.getName(), tag.getId())
.getNumberOfElements()).as("ds tag ds has wrong ds size").isEqualTo(3);
}
@Test
@Description("Ensures that updates concerning the internal software structure of a DS are not possible if the DS is already assigned.")
public void updateDistributionSetForbiddedWithIllegalUpdate() {
void updateDistributionSetForbiddenWithIllegalUpdate() {
// prepare data
final Target target = testdataFactory.createTarget();
@@ -444,7 +450,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
// assign target
assignDistributionSet(ds.getId(), target.getControllerId());
ds = distributionSetManagement.getWithDetails(ds.getId()).get();
ds = getOrThrow(distributionSetManagement.getWithDetails(ds.getId()));
final Long dsId = ds.getId();
// not allowed as it is assigned now
@@ -452,20 +458,20 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
.isInstanceOf(EntityReadOnlyException.class);
// not allowed as it is assigned now
final Long appId = ds.findFirstModuleByType(appType).get().getId();
final Long appId = getOrThrow(ds.findFirstModuleByType(appType)).getId();
assertThatThrownBy(() -> distributionSetManagement.unassignSoftwareModule(dsId, appId))
.isInstanceOf(EntityReadOnlyException.class);
}
@Test
@Description("Ensures that it is not possible to add a software module that is not defined of the DS's type.")
public void updateDistributionSetUnsupportedModuleFails() {
void updateDistributionSetUnsupportedModuleFails() {
final DistributionSet set = distributionSetManagement
.create(entityFactory
.distributionSet().create().name("agent-hub2").version(
"1.0.5")
.type(distributionSetTypeManagement.create(entityFactory.distributionSetType().create()
.key("test").name("test").mandatory(Arrays.asList(osType.getId()))).getKey()));
.key("test").name("test").mandatory(singletonList(osType.getId()))).getKey()));
final SoftwareModule module = softwareModuleManagement.create(
entityFactory.softwareModule().create().name("agent-hub2").version("1.0.5").type(appType.getKey()));
@@ -478,7 +484,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Legal updates of a DS, e.g. name or description and module addition, removal while still unassigned.")
public void updateDistributionSet() {
void updateDistributionSet() {
// prepare data
DistributionSet ds = testdataFactory.createDistributionSet("");
final SoftwareModule os = testdataFactory.createSoftwareModuleOs();
@@ -486,18 +492,19 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
// update data
// legal update of module addition
distributionSetManagement.assignSoftwareModules(ds.getId(), Sets.newHashSet(os.getId()));
ds = distributionSetManagement.getWithDetails(ds.getId()).get();
assertThat(ds.findFirstModuleByType(osType).get()).isEqualTo(os);
ds = getOrThrow(distributionSetManagement.getWithDetails(ds.getId()));
assertThat(getOrThrow(ds.findFirstModuleByType(osType))).isEqualTo(os);
// legal update of module removal
distributionSetManagement.unassignSoftwareModule(ds.getId(), ds.findFirstModuleByType(appType).get().getId());
ds = distributionSetManagement.getWithDetails(ds.getId()).get();
assertThat(ds.findFirstModuleByType(appType).isPresent()).isFalse();
distributionSetManagement.unassignSoftwareModule(ds.getId(),
getOrThrow(ds.findFirstModuleByType(appType)).getId());
ds = getOrThrow(distributionSetManagement.getWithDetails(ds.getId()));
assertThat(ds.findFirstModuleByType(appType)).isNotPresent();
// Update description
distributionSetManagement.update(entityFactory.distributionSet().update(ds.getId()).name("a new name")
.description("a new description").version("a new version").requiredMigrationStep(true));
ds = distributionSetManagement.getWithDetails(ds.getId()).get();
ds = getOrThrow(distributionSetManagement.getWithDetails(ds.getId()));
assertThat(ds.getDescription()).isEqualTo("a new description");
assertThat(ds.getName()).isEqualTo("a new name");
assertThat(ds.getVersion()).isEqualTo("a new version");
@@ -506,7 +513,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that an exception is thrown when trying to update an invalid distribution set")
public void updateInvalidDistributionSet() {
void updateInvalidDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
assertThatExceptionOfType(InvalidDistributionSetException.class)
@@ -516,7 +523,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies the enforcement of the software module quota per distribution set.")
public void assignSoftwareModulesUntilQuotaIsExceeded() {
void assignSoftwareModulesUntilQuotaIsExceeded() {
// create some software modules
final int maxModules = quotaManagement.getMaxSoftwareModulesPerDistributionSet();
@@ -528,13 +535,11 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
// assign software modules one by one
final DistributionSet ds1 = testdataFactory.createDistributionSetWithNoSoftwareModules("ds1", "1.0");
for (int i = 0; i < maxModules; ++i) {
distributionSetManagement.assignSoftwareModules(ds1.getId(), Collections.singletonList(modules.get(i)));
distributionSetManagement.assignSoftwareModules(ds1.getId(), singletonList(modules.get(i)));
}
// add one more to cause the quota to be exceeded
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> {
distributionSetManagement.assignSoftwareModules(ds1.getId(),
Collections.singletonList(modules.get(maxModules)));
});
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> distributionSetManagement
.assignSoftwareModules(ds1.getId(), singletonList(modules.get(maxModules))));
// assign all software modules at once
final DistributionSet ds2 = testdataFactory.createDistributionSetWithNoSoftwareModules("ds2", "1.0");
@@ -544,9 +549,9 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
// assign some software modules
final DistributionSet ds3 = testdataFactory.createDistributionSetWithNoSoftwareModules("ds3", "1.0");
final int firstHalf = Math.round(maxModules / 2);
final int firstHalf = Math.round(((float) maxModules) / 2.f);
for (int i = 0; i < firstHalf; ++i) {
distributionSetManagement.assignSoftwareModules(ds3.getId(), Collections.singletonList(modules.get(i)));
distributionSetManagement.assignSoftwareModules(ds3.getId(), singletonList(modules.get(i)));
}
// assign the remaining modules to cause the quota to be exceeded
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> distributionSetManagement
@@ -556,25 +561,25 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that an exception is thrown when trying to assign software modules to an invalidated distribution set.")
public void verifyAssignSoftwareModulesToInvalidDistributionSet() {
void verifyAssignSoftwareModulesToInvalidDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
final SoftwareModule softwareModule = testdataFactory.createSoftwareModuleOs();
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception")
.isThrownBy(() -> distributionSetManagement.assignSoftwareModules(distributionSet.getId(),
Collections.singletonList(softwareModule.getId())));
singletonList(softwareModule.getId())));
}
@Test
@Description("Verifies that an exception is thrown when trying to unassign a software module from an invalidated distribution set.")
public void verifyUnassignSoftwareModulesToInvalidDistributionSet() {
void verifyUnassignSoftwareModulesToInvalidDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
final SoftwareModule softwareModule = testdataFactory.createSoftwareModuleOs();
distributionSetManagement.assignSoftwareModules(distributionSet.getId(),
Collections.singletonList(softwareModule.getId()));
singletonList(softwareModule.getId()));
distributionSetInvalidationManagement.invalidateDistributionSet(new DistributionSetInvalidation(
Collections.singletonList(distributionSet.getId()), CancelationType.NONE, false));
singletonList(distributionSet.getId()), CancelationType.NONE, false));
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception").isThrownBy(() -> distributionSetManagement
@@ -584,7 +589,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@WithUser(allSpPermissions = true)
@Description("Checks that metadata for a distribution set can be updated.")
public void updateDistributionSetMetadata() throws InterruptedException {
void updateDistributionSetMetadata() {
final String knownKey = "myKnownKey";
final String knownValue = "myKnownValue";
final String knownUpdateValue = "myNewUpdatedValue";
@@ -597,20 +602,17 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
// create an DS meta data entry
createDistributionSetMetadata(ds.getId(), new JpaDistributionSetMetadata(knownKey, ds, knownValue));
DistributionSet changedLockRevisionDS = distributionSetManagement.get(ds.getId()).get();
final DistributionSet changedLockRevisionDS = getOrThrow(distributionSetManagement.get(ds.getId()));
assertThat(changedLockRevisionDS.getOptLockRevision()).isEqualTo(2);
Thread.sleep(100);
// update the DS metadata
final JpaDistributionSetMetadata updated = (JpaDistributionSetMetadata) distributionSetManagement
.updateMetaData(ds.getId(), entityFactory.generateDsMetadata(knownKey, knownUpdateValue));
// we are updating the sw meta data so also modifying the base software
// module so opt lock
// revision must be three
changedLockRevisionDS = distributionSetManagement.get(ds.getId()).get();
assertThat(changedLockRevisionDS.getOptLockRevision()).isEqualTo(3);
assertThat(changedLockRevisionDS.getLastModifiedAt()).isGreaterThan(0L);
// we are updating the sw metadata so also modifying the base software
// module so opt lock revision must be three
final DistributionSet reloadedDS = getOrThrow(distributionSetManagement.get(ds.getId()));
assertThat(reloadedDS.getOptLockRevision()).isEqualTo(3);
assertThat(reloadedDS.getLastModifiedAt()).isPositive();
// verify updated meta data contains the updated value
assertThat(updated).isNotNull();
@@ -621,7 +623,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Tests that a DS queue is possible where the result is ordered by the target assignment, i.e. assigned first in the list.")
public void findDistributionSetsAllOrderedByLinkTarget() {
void findDistributionSetsAllOrderedByLinkTarget() {
final List<DistributionSet> buildDistributionSets = testdataFactory.createDistributionSets("dsOrder", 10);
@@ -641,7 +643,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
assignDistributionSet(dsThree.getId(), tFirst.getControllerId());
// set installed
testdataFactory.sendUpdateActionStatusToTargets(Collections.singleton(tSecond), Status.FINISHED,
Arrays.asList("some message"));
singletonList("some message"));
assignDistributionSet(dsFour.getId(), tSecond.getControllerId());
@@ -669,7 +671,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("searches for distribution sets based on the various filter options, e.g. name, version, desc., tags.")
public void searchDistributionSetsOnFilters() {
void searchDistributionSetsOnFilters() {
DistributionSetTag dsTagA = distributionSetTagManagement
.create(entityFactory.tag().create().name("DistributionSetTag-A"));
final DistributionSetTag dsTagB = distributionSetTagManagement
@@ -689,7 +691,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
.create(entityFactory.distributionSetType().create().key("foo").name("bar").description("test"));
distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(newType.getId(),
Arrays.asList(osType.getId()));
singletonList(osType.getId()));
newType = distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(newType.getId(),
Arrays.asList(appType.getId(), runtimeType.getId()));
@@ -699,14 +701,14 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
assignDistributionSet(dsDeleted, testdataFactory.createTargets(5));
distributionSetManagement.delete(dsDeleted.getId());
dsDeleted = distributionSetManagement.get(dsDeleted.getId()).get();
dsDeleted = getOrThrow(distributionSetManagement.get(dsDeleted.getId()));
dsGroup1 = toggleTagAssignment(dsGroup1, dsTagA).getAssignedEntity();
dsTagA = distributionSetTagRepository.findByNameEquals(dsTagA.getName()).get();
dsTagA = getOrThrow(distributionSetTagRepository.findByNameEquals(dsTagA.getName()));
dsGroup1 = toggleTagAssignment(dsGroup1, dsTagB).getAssignedEntity();
dsTagA = distributionSetTagRepository.findByNameEquals(dsTagA.getName()).get();
dsTagA = getOrThrow(distributionSetTagRepository.findByNameEquals(dsTagA.getName()));
dsGroup2 = toggleTagAssignment(dsGroup2, dsTagA).getAssignedEntity();
dsTagA = distributionSetTagRepository.findByNameEquals(dsTagA.getName()).get();
dsTagA = getOrThrow(distributionSetTagRepository.findByNameEquals(dsTagA.getName()));
final List<DistributionSet> allDistributionSets = Stream
.of(dsGroup1, dsGroup2, Arrays.asList(dsDeleted, dsInComplete, dsNewType)).flatMap(Collection::stream)
@@ -743,7 +745,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
private void validateDeleted(final DistributionSet deletedDistributionSet, final int notDeletedSize) {
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsDeleted(Boolean.TRUE),
Arrays.asList(deletedDistributionSet));
singletonList(deletedDistributionSet));
assertThatFilterHasSizeAndDoesNotContainDistributionSet(
getDistributionSetFilterBuilder().setIsDeleted(Boolean.FALSE), notDeletedSize, deletedDistributionSet);
@@ -756,7 +758,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE), completedSize, dsIncomplete);
assertThatFilterContainsOnlyGivenDistributionSets(
getDistributionSetFilterBuilder().setIsComplete(Boolean.FALSE), Arrays.asList(dsIncomplete));
getDistributionSetFilterBuilder().setIsComplete(Boolean.FALSE), singletonList(dsIncomplete));
}
@Step
@@ -764,7 +766,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
final int standardDsTypeSize) {
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setType(newType),
Arrays.asList(dsNewType));
singletonList(dsNewType));
assertThatFilterHasSizeAndDoesNotContainDistributionSet(
getDistributionSetFilterBuilder().setType(standardDsType), standardDsTypeSize, dsNewType);
@@ -772,7 +774,6 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Step
private void validateSearchText(final List<DistributionSet> withText, final String text) {
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setSearchText(text),
withText);
}
@@ -825,10 +826,10 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
final List<DistributionSet> dsWithTagB) {
assertThatFilterContainsOnlyGivenDistributionSets(
getDistributionSetFilterBuilder().setTagNames(Arrays.asList(dsTagA.getName())), dsWithTagA);
getDistributionSetFilterBuilder().setTagNames(singletonList(dsTagA.getName())), dsWithTagA);
assertThatFilterContainsOnlyGivenDistributionSets(
getDistributionSetFilterBuilder().setTagNames(Arrays.asList(dsTagB.getName())), dsWithTagB);
getDistributionSetFilterBuilder().setTagNames(singletonList(dsTagB.getName())), dsWithTagB);
assertThatFilterContainsOnlyGivenDistributionSets(
getDistributionSetFilterBuilder().setTagNames(Arrays.asList(dsTagA.getName(), dsTagB.getName())),
@@ -839,7 +840,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
dsWithTagB);
assertThatFilterDoesNotContainAnyDistributionSet(
getDistributionSetFilterBuilder().setTagNames(Arrays.asList(dsTagC.getName())));
getDistributionSetFilterBuilder().setTagNames(singletonList(dsTagC.getName())));
}
@Step
@@ -854,7 +855,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
assertThatFilterContainsOnlyGivenDistributionSets(
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setIsDeleted(Boolean.TRUE),
Arrays.asList(dsDeleted));
singletonList(dsDeleted));
assertThatFilterDoesNotContainAnyDistributionSet(
getDistributionSetFilterBuilder().setIsComplete(Boolean.FALSE).setIsDeleted(Boolean.TRUE));
@@ -868,14 +869,14 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
.setIsComplete(Boolean.TRUE).setType(standardDsType), deletedAndCompletedAndStandardType);
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setType(standardDsType).setIsDeleted(Boolean.TRUE), Arrays.asList(dsDeleted));
.setType(standardDsType).setIsDeleted(Boolean.TRUE), singletonList(dsDeleted));
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder().setIsDeleted(Boolean.TRUE)
.setIsComplete(Boolean.FALSE).setType(standardDsType));
assertThatFilterContainsOnlyGivenDistributionSets(
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setType(newType),
Arrays.asList(dsNewType));
singletonList(dsNewType));
}
@Step
@@ -915,15 +916,15 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setIsDeleted(Boolean.TRUE).setType(standardDsType).setFilterString(filterString),
Arrays.asList(dsDeleted));
singletonList(dsDeleted));
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setType(standardDsType)
.setFilterString(filterString).setIsComplete(Boolean.FALSE).setIsDeleted(Boolean.FALSE),
Arrays.asList(dsInComplete));
singletonList(dsInComplete));
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setType(newType)
.setFilterString(filterString).setIsComplete(Boolean.TRUE).setIsDeleted(Boolean.FALSE),
Arrays.asList(dsNewType));
singletonList(dsNewType));
}
@Step
@@ -933,11 +934,11 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
assertThatFilterContainsOnlyGivenDistributionSets(
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setType(standardDsType)
.setSearchText(text).setTagNames(Arrays.asList(dsTagA.getName())),
.setSearchText(text).setTagNames(singletonList(dsTagA.getName())),
completedAndStandartTypeAndSearchTextAndTagA);
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder().setType(standardDsType)
.setSearchText(text).setTagNames(Arrays.asList(dsTagA.getName())).setIsComplete(Boolean.FALSE)
.setSearchText(text).setTagNames(singletonList(dsTagA.getName())).setIsComplete(Boolean.FALSE)
.setIsDeleted(Boolean.FALSE));
}
@@ -954,7 +955,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
private void assertThatFilterDoesNotContainAnyDistributionSet(final DistributionSetFilterBuilder filterBuilder) {
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, filterBuilder.build()).getContent())
.hasSize(0);
.isEmpty();
}
private void assertThatFilterHasSizeAndDoesNotContainDistributionSet(
@@ -965,7 +966,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Simple DS load without the related data that should be loaded lazy.")
public void findDistributionSetsWithoutLazy() {
void findDistributionSetsWithoutLazy() {
testdataFactory.createDistributionSets(20);
assertThat(distributionSetManagement.findByCompleted(PAGE, true)).hasSize(20);
@@ -973,7 +974,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Deltes a DS that is no in use. Expected behaviour is a hard delete on the database.")
public void deleteUnassignedDistributionSet() {
void deleteUnassignedDistributionSet() {
final DistributionSet ds1 = testdataFactory.createDistributionSet("ds-1");
testdataFactory.createDistributionSet("ds-2");
@@ -987,7 +988,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Deletes an invalid distribution set")
public void deleteInvalidDistributionSet() {
void deleteInvalidDistributionSet() {
final DistributionSet set = testdataFactory.createAndInvalidateDistributionSet();
assertThat(distributionSetRepository.findById(set.getId())).isNotEmpty();
distributionSetManagement.delete(set.getId());
@@ -996,7 +997,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Deletes an incomplete distribution set")
public void deleteIncompleteDistributionSet() {
void deleteIncompleteDistributionSet() {
final DistributionSet set = testdataFactory.createIncompleteDistributionSet();
assertThat(distributionSetRepository.findById(set.getId())).isNotEmpty();
distributionSetManagement.delete(set.getId());
@@ -1005,7 +1006,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Queries and loads the metadata related to a given software module.")
public void findAllDistributionSetMetadataByDsId() {
void findAllDistributionSetMetadataByDsId() {
// create a DS
final DistributionSet ds1 = testdataFactory.createDistributionSet("testDs1");
final DistributionSet ds2 = testdataFactory.createDistributionSet("testDs2");
@@ -1036,7 +1037,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Deletes a DS that is in use by either target assignment or rollout. Expected behaviour is a soft delete on the database, i.e. only marked as "
+ "deleted, kept as reference but unavailable for future use..")
public void deleteAssignedDistributionSet() {
void deleteAssignedDistributionSet() {
testdataFactory.createDistributionSet("ds-1");
testdataFactory.createDistributionSet("ds-2");
final DistributionSet dsToTargetAssigned = testdataFactory.createDistributionSet("ds-3");
@@ -1062,7 +1063,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Description("Verify that the find all by ids contains the entities which are looking for")
@ExpectEvents({ @Expect(type = DistributionSetCreatedEvent.class, count = 12),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 36) })
public void verifyFindDistributionSetAllById() {
void verifyFindDistributionSetAllById() {
final List<Long> searchIds = new ArrayList<>();
searchIds.add(testdataFactory.createDistributionSet("ds-4").getId());
searchIds.add(testdataFactory.createDistributionSet("ds-5").getId());
@@ -1081,7 +1082,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify that an exception is thrown when trying to get an invalid distribution set")
public void verifyGetValid() {
void verifyGetValid() {
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
assertThatExceptionOfType(InvalidDistributionSetException.class)
@@ -1094,7 +1095,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify that an exception is thrown when trying to get an incomplete distribution set")
public void verifyGetValidAndComplete() {
void verifyGetValidAndComplete() {
final DistributionSet distributionSet = testdataFactory.createIncompleteDistributionSet();
assertThatExceptionOfType(IncompleteDistributionSetException.class)
@@ -1104,7 +1105,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify that an exception is thrown when trying to create or update metadata for an invalid distribution set.")
public void createMetadataForInvalidDistributionSet() {
void createMetadataForInvalidDistributionSet() {
final String knownKey1 = "myKnownKey1";
final String knownKey2 = "myKnownKey2";
final String knownValue = "myKnownValue";
@@ -1112,16 +1113,16 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
final DistributionSet ds = testdataFactory.createDistributionSet();
distributionSetManagement.createMetaData(ds.getId(),
Collections.singletonList(entityFactory.generateDsMetadata(knownKey1, knownValue)));
singletonList(entityFactory.generateDsMetadata(knownKey1, knownValue)));
distributionSetInvalidationManagement.invalidateDistributionSet(
new DistributionSetInvalidation(Arrays.asList(ds.getId()), CancelationType.NONE, false));
new DistributionSetInvalidation(singletonList(ds.getId()), CancelationType.NONE, false));
// assert that no new metadata can be created
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception")
.isThrownBy(() -> distributionSetManagement.createMetaData(ds.getId(),
Collections.singletonList(entityFactory.generateDsMetadata(knownKey2, knownValue))));
singletonList(entityFactory.generateDsMetadata(knownKey2, knownValue))));
// assert that an existing metadata can not be updated
assertThatExceptionOfType(InvalidDistributionSetException.class)
@@ -1129,4 +1130,8 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
.updateMetaData(ds.getId(), entityFactory.generateDsMetadata(knownKey1, knownUpdateValue)));
}
// can be removed with java-11
private <T> T getOrThrow(Optional<T> opt) {
return opt.orElseThrow(NoSuchElementException::new);
}
}

View File

@@ -13,9 +13,9 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import javax.validation.ConstraintViolationException;
@@ -27,8 +27,8 @@ import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreated
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTypeCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetUpdatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
@@ -70,16 +70,19 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
@Expect(type = DistributionSetTypeCreatedEvent.class, count = 1) })
public void entityQueriesReferringToNotExistingEntitiesThrowsException() {
final List<Long> softwareModuleTypes = Collections.singletonList(osType.getId());
verifyThrownExceptionBy(() -> distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(NOT_EXIST_IDL,
Arrays.asList(osType.getId())), "DistributionSetType");
softwareModuleTypes), "DistributionSetType");
final List<Long> notExistingSwModuleTypeIds = Collections.singletonList(NOT_EXIST_IDL);
verifyThrownExceptionBy(() -> distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(
testdataFactory.findOrCreateDistributionSetType("xxx", "xxx").getId(), Arrays.asList(NOT_EXIST_IDL)),
testdataFactory.findOrCreateDistributionSetType("xxx", "xxx").getId(), notExistingSwModuleTypeIds),
"SoftwareModuleType");
verifyThrownExceptionBy(() -> distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(NOT_EXIST_IDL,
Arrays.asList(osType.getId())), "DistributionSetType");
softwareModuleTypes), "DistributionSetType");
verifyThrownExceptionBy(() -> distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(
testdataFactory.findOrCreateDistributionSetType("xxx", "xxx").getId(), Arrays.asList(NOT_EXIST_IDL)),
testdataFactory.findOrCreateDistributionSetType("xxx", "xxx").getId(), notExistingSwModuleTypeIds),
"SoftwareModuleType");
verifyThrownExceptionBy(() -> distributionSetTypeManagement.delete(NOT_EXIST_IDL), "DistributionSetType");
@@ -106,99 +109,91 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
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))))
.as("set with too long description should not be created");
.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)))
.as("set invalid description text should not be created");
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))))
.as("set with too long description should not be updated");
.description(RandomStringUtils.randomAlphanumeric(513))));
assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> distributionSetManagement
.update(entityFactory.distributionSet().update(set.getId()).description(INVALID_TEXT_HTML)))
.as("set with invalid description should not be updated");
.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)
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))))
.as("set with too long name should not be created");
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
assertThatExceptionOfType(ConstraintViolationException.class)
assertThatExceptionOfType(ConstraintViolationException.class).as("set with invalid name should not be created")
.isThrownBy(() -> distributionSetManagement
.create(entityFactory.distributionSet().create().version("a").name(INVALID_TEXT_HTML)))
.as("set with invalid name should not be created");
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
() -> distributionSetManagement.create(entityFactory.distributionSet().create().version("a").name("")))
.as("set with too short name should not be created");
.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)))
.as("set with null name should not be created");
.create(entityFactory.distributionSet().create().version("a").name(null)));
assertThatExceptionOfType(ConstraintViolationException.class)
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))))
.as("set with too long name should not be updated");
.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)
.isThrownBy(() -> distributionSetManagement
.update(entityFactory.distributionSet().update(set.getId()).name(INVALID_TEXT_HTML)))
.as("set with invalid name should not be updated");
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId()).name("")))
.as("set with too short name should not be updated");
.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))))
.as("set with too long version should not be created");
.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(INVALID_TEXT_HTML)))
.as("set with invalid version should not be created");
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a").version("")))
.as("set with too short version should not be created");
assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> distributionSetManagement
.create(entityFactory.distributionSet().create().name("a").version(null)))
.as("set with null version should not be created");
.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))))
.as("set with too long version should not be updated");
.version(RandomStringUtils.randomAlphanumeric(NamedVersionedEntity.VERSION_MAX_SIZE + 1))));
assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> distributionSetManagement
.update(entityFactory.distributionSet().update(set.getId()).version(INVALID_TEXT_HTML)))
.as("set with invalid version should not be updated");
.as("set with invalid version should not be updated").isThrownBy(() -> distributionSetManagement
.update(entityFactory.distributionSet().update(set.getId()).version(INVALID_TEXT_HTML)));
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
() -> distributionSetManagement.update(entityFactory.distributionSet().update(set.getId()).version("")))
.as("set with too short version should not be updated");
assertThatExceptionOfType(ConstraintViolationException.class)
.as("set with too short version should not be updated").isThrownBy(() -> distributionSetManagement
.update(entityFactory.distributionSet().update(set.getId()).version("")));
}
@Test
@@ -278,11 +273,7 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
@Test
@Description("Tests the successfull update of used distribution set type meta data which is in fact allowed.")
public void updateAssignedDistributionSetTypeMetaData() {
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()));
final DistributionSetType nonUpdatableType = createDistributionSetTypeUsedByDs();
distributionSetTypeManagement.update(
entityFactory.distributionSetType().update(nonUpdatableType.getId()).description("a new description"));
@@ -295,17 +286,22 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
@Test
@Description("Tests the unsuccessfull update of used distribution set type (module addition).")
public void addModuleToAssignedDistributionSetTypeFails() {
final DistributionSetType nonUpdatableType = distributionSetTypeManagement
.create(entityFactory.distributionSetType().create().key("updatableType").name("to be deleted"));
assertThat(distributionSetTypeManagement.getByKey("updatableType").get().getMandatoryModuleTypes()).isEmpty();
distributionSetManagement.create(entityFactory.distributionSet().create().name("newtypesoft").version("1")
.type(nonUpdatableType.getKey()));
final DistributionSetType nonUpdatableType = createDistributionSetTypeUsedByDs();
assertThatThrownBy(() -> distributionSetTypeManagement
.assignMandatorySoftwareModuleTypes(nonUpdatableType.getId(), Sets.newHashSet(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;
}
@Test
@Description("Tests the unsuccessfull update of used distribution set type (module removal).")
public void removeModuleToAssignedDistributionSetTypeFails() {
@@ -338,15 +334,17 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes
@Test
@Description("Tests the successfull deletion of used (soft delete) distribution set types.")
public void deleteAssignedDistributionSetType() {
final JpaDistributionSetType softDelete = (JpaDistributionSetType) distributionSetTypeManagement
final JpaDistributionSetType toBeDeleted = (JpaDistributionSetType) distributionSetTypeManagement
.create(entityFactory.distributionSetType().create().key("softdeleted").name("to be deleted"));
assertThat(distributionSetTypeRepository.findAll()).contains(softDelete);
assertThat(distributionSetTypeRepository.findAll()).contains(toBeDeleted);
distributionSetManagement.create(
entityFactory.distributionSet().create().name("softdeleted").version("1").type(softDelete.getKey()));
entityFactory.distributionSet().create().name("softdeleted").version("1").type(toBeDeleted.getKey()));
distributionSetTypeManagement.delete(softDelete.getId());
assertThat(distributionSetTypeManagement.getByKey("softdeleted").get().isDeleted()).isEqualTo(true);
distributionSetTypeManagement.delete(toBeDeleted.getId());
final Optional<DistributionSetType> softdeleted = distributionSetTypeManagement.getByKey("softdeleted");
assertThat(softdeleted).isPresent();
assertThat(softdeleted.get().isDeleted()).isTrue();
}
@Test

View File

@@ -17,17 +17,18 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import org.assertj.core.api.Assertions;
import org.assertj.core.api.Condition;
import org.awaitility.Awaitility;
import org.awaitility.Duration;
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
import org.eclipse.hawkbit.repository.builder.RolloutCreate;
import org.eclipse.hawkbit.repository.builder.RolloutGroupCreate;
@@ -54,8 +55,6 @@ import org.eclipse.hawkbit.repository.exception.MultiAssignmentIsNotEnabledExcep
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.jpa.utils.MultipleInvokeHelper;
import org.eclipse.hawkbit.repository.jpa.utils.SuccessCondition;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.Action.Status;
@@ -76,6 +75,7 @@ import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
import org.eclipse.hawkbit.repository.test.matcher.Expect;
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -138,9 +138,9 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that a running action is auto canceled by a rollout which assigns another distribution-set.")
void rolloutAssignesNewDistributionSetAndAutoCloseActiveActions() {
tenantConfigurationManagement
.addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, true);
void rolloutAssignsNewDistributionSetAndAutoCloseActiveActions() {
tenantConfigurationManagement.addOrUpdateConfiguration(
TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, true);
try {
// manually assign distribution set to target
@@ -182,7 +182,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that management get access reacts as specified on calls for non existing entities by means "
+ "of Optional not present.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
void nonExistingEntityAccessReturnsNotPresent() {
assertThat(rolloutManagement.get(NOT_EXIST_IDL)).isNotPresent();
assertThat(rolloutManagement.getByName(NOT_EXIST_ID)).isNotPresent();
@@ -192,7 +192,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that management queries react as specified on calls for non existing entities "
+ " by means of throwing EntityNotFoundException.")
@ExpectEvents({ @Expect(type = RolloutDeletedEvent.class, count = 0),
@ExpectEvents({ @Expect(type = RolloutDeletedEvent.class),
@Expect(type = RolloutGroupCreatedEvent.class, count = 10),
@Expect(type = RolloutGroupUpdatedEvent.class, count = 10),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@@ -225,7 +225,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// verify the split of the target and targetGroup
final Page<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, createdRollout.getId());
// we have total of #amountTargetsForRollout in rollouts splitted in
// we have total of #amountTargetsForRollout in rollouts split in
// group size #groupSize
assertThat(rolloutGroups).hasSize(amountGroups);
}
@@ -254,11 +254,10 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
scheduledGroups.forEach(group -> assertThat(group.getStatus())
.as("group which should be in scheduled state is in " + group.getStatus() + " state")
.isEqualTo(RolloutGroupStatus.SCHEDULED));
// verify that the first group actions has been started and are in state
// running
// verify that the first group actions has been started and are in state running
final List<Action> runningActions = findActionsByRolloutAndStatus(createdRollout, Status.RUNNING);
assertThat(runningActions).hasSize(amountTargetsForRollout / amountGroups);
assertThat(runningActions).as("Created actions are initiated by rollout creator")
assertThat(runningActions).hasSize(amountTargetsForRollout / amountGroups)
.as("Created actions are initiated by rollout creator")
.allMatch(a -> a.getInitiatedBy().equals(createdRollout.getCreatedBy()));
// the rest targets are only scheduled
assertThat(findActionsByRolloutAndStatus(createdRollout, Status.SCHEDULED))
@@ -308,7 +307,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Test
// @Title("Deleting targets of a rollout")
@Description("Verfiying that next group is started when targets of the group have been deleted.")
@Description("Verifying that next group is started when targets of the group have been deleted.")
void checkRunningRolloutsStartsNextGroupIfTargetsDeleted() {
final int amountTargetsForRollout = 15;
@@ -342,7 +341,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts();
return rolloutManagement.get(createdRollout.getId()).get();
return reloadRollout(createdRollout);
}
@Step("Finish three actions of the rollout group and delete two targets")
@@ -399,7 +398,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
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(rolloutManagement.get(createdRollout.getId()).get().getStatus()).isEqualTo(RolloutStatus.FINISHED);
assertThat(reloadRollout(createdRollout).getStatus()).isEqualTo(RolloutStatus.FINISHED);
}
@@ -409,7 +408,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
}
@Test
@Description("Verfiying that the error handling action of a group is executed to pause the current rollout")
@Description("Verifying that the error handling action of a group is executed to pause the current rollout")
void checkErrorHitOfGroupCallsErrorActionToPauseTheRollout() {
final int amountTargetsForRollout = 10;
final int amountOtherTargets = 15;
@@ -433,7 +432,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// and should execute the error action
rolloutManagement.handleRollouts();
final Rollout rollout = rolloutManagement.get(createdRollout.getId()).get();
final Rollout rollout = reloadRollout(createdRollout);
// the rollout itself should be in paused based on the error action
assertThat(rollout.getStatus()).isEqualTo(RolloutStatus.PAUSED);
@@ -452,7 +451,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
}
@Test
@Description("Verfiying a paused rollout in case of error action hit can be resumed again")
@Description("Verifying a paused rollout in case of error action hit can be resumed again")
void errorActionPausesRolloutAndRolloutGetsResumedStartsNextScheduledGroup() {
final int amountTargetsForRollout = 10;
final int amountOtherTargets = 15;
@@ -475,7 +474,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// and should execute the error action
rolloutManagement.handleRollouts();
final Rollout rollout = rolloutManagement.get(createdRollout.getId()).get();
final Rollout rollout = reloadRollout(createdRollout);
// the rollout itself should be in paused based on the error action
assertThat(rollout.getStatus()).isEqualTo(RolloutStatus.PAUSED);
@@ -489,7 +488,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.resumeRollout(createdRollout.getId());
// the rollout should be running again
assertThat(rolloutManagement.get(createdRollout.getId()).get().getStatus()).isEqualTo(RolloutStatus.RUNNING);
assertThat(reloadRollout(createdRollout).getStatus()).isEqualTo(RolloutStatus.RUNNING);
// checking rollouts again
rolloutManagement.handleRollouts();
@@ -503,7 +502,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
}
@Test
@Description("Verfiying that the rollout is starting group after group and gets finished at the end")
@Description("Verifying that the rollout is starting group after group and gets finished at the end")
void rolloutStartsGroupAfterGroupAndGetsFinished() {
final int amountTargetsForRollout = 10;
final int amountOtherTargets = 15;
@@ -522,7 +521,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.handleRollouts();
// finish running actions, 2 actions should be finished
assertThat(changeStatusForAllRunningActions(createdRollout, Status.FINISHED)).isEqualTo(2);
assertThat(rolloutManagement.get(createdRollout.getId()).get().getStatus())
assertThat(getRollout(createdRollout.getId()).getStatus())
.isEqualTo(RolloutStatus.RUNNING);
}
@@ -536,7 +535,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
.forEach(group -> assertThat(group.getStatus()).isEqualTo(RolloutGroupStatus.FINISHED));
// verify that rollout itself is in finished state
final Rollout findRolloutById = rolloutManagement.get(createdRollout.getId()).get();
final Rollout findRolloutById = reloadRollout(createdRollout);
assertThat(findRolloutById.getStatus()).isEqualTo(RolloutStatus.FINISHED);
}
@@ -726,7 +725,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// round(7/3)=2 targets running (Group 3)
// round(5/2)=3 targets SCHEDULED (Group 3)
// round(2/1)=2 targets SCHEDULED (Group 4)
createdRollout = rolloutManagement.get(createdRollout.getId()).get();
createdRollout = reloadRollout(createdRollout);
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, createdRollout.getId())
.getContent();
@@ -761,7 +760,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
successCondition, errorCondition);
final DistributionSet ds = createdRollout.getDistributionSet();
createdRollout = rolloutManagement.get(createdRollout.getId()).get();
createdRollout = reloadRollout(createdRollout);
// 5 targets are running
final List<Action> runningActions = findActionsByRolloutAndStatus(createdRollout, Status.RUNNING);
assertThat(runningActions.size()).isEqualTo(5);
@@ -803,7 +802,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
Rollout rolloutOne = createAndStartRollout(amountTargetsForRollout, amountOtherTargets, amountGroups,
successCondition, errorCondition);
rolloutOne = rolloutManagement.get(rolloutOne.getId()).get();
rolloutOne = reloadRollout(rolloutOne);
final DistributionSet dsForRolloutTwo = testdataFactory.createDistributionSet("dsForRolloutTwo");
@@ -834,7 +833,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify that error status of DistributionSet installation during rollout can get rerun with second rollout so that all targets have some DistributionSet installed at the end.")
void startSecondRolloutAfterFristRolloutEndenWithErrors() {
void startSecondRolloutAfterFirstRolloutEndsWithErrors() {
final int amountTargetsForRollout = 15;
final int amountOtherTargets = 0;
@@ -845,7 +844,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
successCondition, errorCondition);
final DistributionSet distributionSet = rolloutOne.getDistributionSet();
rolloutOne = rolloutManagement.get(rolloutOne.getId()).get();
rolloutOne = reloadRollout(rolloutOne);
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
rolloutManagement.handleRollouts();
@@ -862,7 +861,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.ERROR, 6L);
validateRolloutActionStatus(rolloutOne.getId(), expectedTargetCountStatus);
// rollout is finished
rolloutOne = rolloutManagement.get(rolloutOne.getId()).get();
rolloutOne = reloadRollout(rolloutOne);
assertThat(rolloutOne.getStatus()).isEqualTo(RolloutStatus.FINISHED);
final int amountGroupsForRolloutTwo = 1;
@@ -875,7 +874,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts();
rolloutTwo = rolloutManagement.get(rolloutTwo.getId()).get();
rolloutTwo = reloadRollout(rolloutTwo);
// 6 error targets are now running
expectedTargetCountStatus = createInitStatusMap();
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 6L);
@@ -902,21 +901,21 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
Rollout rolloutOne = createAndStartRollout(amountTargetsForRollout, amountOtherTargets, amountGroups,
successCondition, errorCondition);
rolloutOne = rolloutManagement.get(rolloutOne.getId()).get();
rolloutOne = reloadRollout(rolloutOne);
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
rolloutManagement.handleRollouts();
// verify: 40% error but 60% finished -> should move to next group
final List<RolloutGroup> rolloutGruops = rolloutGroupManagement.findByRollout(PAGE, rolloutOne.getId())
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, rolloutOne.getId())
.getContent();
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 5L);
validateRolloutGroupActionStatus(rolloutGruops.get(1), expectedTargetCountStatus);
validateRolloutGroupActionStatus(rolloutGroups.get(1), expectedTargetCountStatus);
}
@Test
@Description("Verify that the rollout does not move to the next group when the sucess condition was not achieved.")
@Description("Verify that the rollout does not move to the next group when the success condition was not achieved.")
void successConditionNotAchieved() {
final int amountTargetsForRollout = 10;
@@ -927,7 +926,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
Rollout rolloutOne = createAndStartRollout(amountTargetsForRollout, amountOtherTargets, amountGroups,
successCondition, errorCondition);
rolloutOne = rolloutManagement.get(rolloutOne.getId()).get();
rolloutOne = reloadRollout(rolloutOne);
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
rolloutManagement.handleRollouts();
@@ -952,12 +951,12 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
Rollout rolloutOne = createAndStartRollout(amountTargetsForRollout, amountOtherTargets, amountGroups,
successCondition, errorCondition);
rolloutOne = rolloutManagement.get(rolloutOne.getId()).get();
rolloutOne = reloadRollout(rolloutOne);
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
rolloutManagement.handleRollouts();
// verify: 40% error -> should pause because errorCondition is 20%
rolloutOne = rolloutManagement.get(rolloutOne.getId()).get();
rolloutOne = reloadRollout(rolloutOne);
assertThat(rolloutOne.getStatus()).isEqualTo(RolloutStatus.PAUSED);
}
@@ -1138,7 +1137,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
changeStatusForRunningActions(myRollout, Status.FINISHED, 2);
rolloutManagement.handleRollouts();
myRollout = rolloutManagement.get(myRollout.getId()).get();
myRollout = reloadRollout(myRollout);
float percent = rolloutGroupManagement
.getWithDetailedStatus(
@@ -1191,7 +1190,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
final Condition<String> targetBelongsInRollout = new Condition<>(s -> s.startsWith(rolloutName),
"Target belongs into rollout");
myRollout = rolloutManagement.get(myRollout.getId()).get();
myRollout = reloadRollout(myRollout);
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, myRollout.getId())
.getContent();
@@ -1258,22 +1257,22 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify the creation and the start of a Rollout with more groups than targets.")
void createAndStartRolloutWithEmptyGroups() throws Exception {
void createAndStartRolloutWithEmptyGroups() {
final int amountTargetsForRollout = 3;
final int amountGroups = 5;
final String successCondition = "50";
final String errorCondition = "80";
final String rolloutName = "rolloutTestG";
final String targetPrefixName = rolloutName;
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName);
testdataFactory.createTargets(amountTargetsForRollout, targetPrefixName + "-", targetPrefixName);
testdataFactory.createTargets(amountTargetsForRollout, rolloutName + "-", rolloutName);
Rollout myRollout = testdataFactory.createRolloutByVariables(rolloutName, "desc", amountGroups,
"controllerId==" + targetPrefixName + "-*", distributionSet, successCondition, errorCondition);
"controllerId==" + rolloutName + "-*", distributionSet, successCondition, errorCondition);
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
final List<RolloutGroup> groups = rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()).getContent();
final Long myRolloutId = myRollout.getId();
final List<RolloutGroup> groups = rolloutGroupManagement.findByRollout(PAGE, myRolloutId).getContent();
assertThat(groups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.READY);
assertThat(groups.get(0).getTotalTargets()).isEqualTo(1);
@@ -1286,69 +1285,62 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(groups.get(4).getStatus()).isEqualTo(RolloutGroupStatus.READY);
assertThat(groups.get(4).getTotalTargets()).isZero();
rolloutManagement.start(myRollout.getId());
rolloutManagement.start(myRolloutId);
// Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts();
final SuccessConditionRolloutStatus conditionRolloutStatus = new SuccessConditionRolloutStatus(
RolloutStatus.RUNNING);
assertThat(MultipleInvokeHelper.doWithTimeout(new RolloutStatusCallable(myRollout.getId()),
conditionRolloutStatus, 15000, 500)).as("Rollout status").isNotNull();
awaitRunningState(myRolloutId);
myRollout = rolloutManagement.get(myRollout.getId()).get();
myRollout = getRollout(myRolloutId);
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.RUNNING);
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 1L);
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.SCHEDULED, 2L);
validateRolloutActionStatus(myRollout.getId(), expectedTargetCountStatus);
validateRolloutActionStatus(myRolloutId, expectedTargetCountStatus);
}
@Test
@Description("Verify the creation and the start of a rollout.")
void createAndStartRollout() throws Exception {
void createAndStartRollout() {
final int amountTargetsForRollout = 50;
final int amountGroups = 5;
final String successCondition = "50";
final String errorCondition = "80";
final String rolloutName = "rolloutTest";
final String targetPrefixName = rolloutName;
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName);
testdataFactory.createTargets(amountTargetsForRollout, targetPrefixName + "-", targetPrefixName);
testdataFactory.createTargets(amountTargetsForRollout, rolloutName + "-", rolloutName);
Rollout myRollout = testdataFactory.createRolloutByVariables(rolloutName, "desc", amountGroups,
"controllerId==" + targetPrefixName + "-*", distributionSet, successCondition, errorCondition);
"controllerId==" + rolloutName + "-*", distributionSet, successCondition, errorCondition);
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
rolloutManagement.handleRollouts();
myRollout = rolloutManagement.get(myRollout.getId()).get();
final Long myRolloutId = myRollout.getId();
myRollout = getRollout(myRolloutId);
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
rolloutManagement.start(myRollout.getId());
rolloutManagement.start(myRolloutId);
// Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts();
final SuccessConditionRolloutStatus conditionRolloutTargetCount = new SuccessConditionRolloutStatus(
RolloutStatus.RUNNING);
assertThat(MultipleInvokeHelper.doWithTimeout(new RolloutStatusCallable(myRollout.getId()),
conditionRolloutTargetCount, 15000, 500)).as("Rollout status").isNotNull();
awaitRunningState(myRolloutId);
myRollout = rolloutManagement.get(myRollout.getId()).get();
myRollout = reloadRollout(myRollout);
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.RUNNING);
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 10L);
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.SCHEDULED, 40L);
validateRolloutActionStatus(myRollout.getId(), expectedTargetCountStatus);
validateRolloutActionStatus(myRolloutId, expectedTargetCountStatus);
}
@Test
@Description("Verify that a rollout cannot be created if the 'max targets per rollout group' quota is violated.")
void createRolloutFailsIfQuotaGroupQuotaIsViolated() throws Exception {
void createRolloutFailsIfQuotaGroupQuotaIsViolated() {
final int maxTargets = quotaManagement.getMaxTargetsPerRolloutGroup();
@@ -1375,15 +1367,14 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify that a rollout cannot be created based on group definitions if the 'max targets per rollout group' quota is violated for one of the groups.")
void createRolloutWithGroupDefinitionsFailsIfQuotaGroupQuotaIsViolated() throws Exception {
void createRolloutWithGroupDefinitionsFailsIfQuotaGroupQuotaIsViolated() {
final int maxTargets = quotaManagement.getMaxTargetsPerRolloutGroup();
final int amountTargetsForRollout = maxTargets * 2 + 2;
final String rolloutName = "rolloutTest";
final String targetPrefixName = rolloutName;
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName);
testdataFactory.createTargets(amountTargetsForRollout, targetPrefixName + "-", targetPrefixName);
testdataFactory.createTargets(amountTargetsForRollout, rolloutName + "-", rolloutName);
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults().build();
@@ -1395,9 +1386,12 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// group1 exceeds the quota
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> rolloutManagement.create(
entityFactory.rollout().create().name(rolloutName).description(rolloutName)
.targetFilterQuery("controllerId==" + targetPrefixName + "-*").set(distributionSet),
Arrays.asList(group1, group2), conditions));
entityFactory.rollout()
.create()
.name(rolloutName)
.description(rolloutName)
.targetFilterQuery("controllerId==" + rolloutName + "-*")
.set(distributionSet), Arrays.asList(group1, group2), conditions));
// create group definitions
final RolloutGroupCreate group3 = entityFactory.rolloutGroup().create().conditions(conditions).name("group3")
@@ -1407,74 +1401,93 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// group4 exceeds the quota
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> rolloutManagement.create(
entityFactory.rollout().create().name(rolloutName).description(rolloutName)
.targetFilterQuery("controllerId==" + targetPrefixName + "-*").set(distributionSet),
Arrays.asList(group3, group4), conditions));
entityFactory.rollout()
.create()
.name(rolloutName)
.description(rolloutName)
.targetFilterQuery("controllerId==" + rolloutName + "-*")
.set(distributionSet), Arrays.asList(group3, group4), conditions));
// create group definitions
final RolloutGroupCreate group5 = entityFactory.rolloutGroup().create().conditions(conditions).name("group5")
final RolloutGroupCreate group5 = entityFactory.rolloutGroup()
.create()
.conditions(conditions)
.name("group5")
.targetPercentage(33.3F);
final RolloutGroupCreate group6 = entityFactory.rolloutGroup().create().conditions(conditions).name("group6")
final RolloutGroupCreate group6 = entityFactory.rolloutGroup()
.create()
.conditions(conditions)
.name("group6")
.targetPercentage(66.6F);
final RolloutGroupCreate group7 = entityFactory.rolloutGroup().create().conditions(conditions).name("group7")
final RolloutGroupCreate group7 = entityFactory.rolloutGroup()
.create()
.conditions(conditions)
.name("group7")
.targetPercentage(100.0F);
// should work fine
assertThat(rolloutManagement.create(
entityFactory.rollout().create().name(rolloutName).description(rolloutName)
.targetFilterQuery("controllerId==" + targetPrefixName + "-*").set(distributionSet),
Arrays.asList(group5, group6, group7), conditions)).isNotNull();
assertThat(rolloutManagement.create(entityFactory.rollout()
.create()
.name(rolloutName)
.description(rolloutName)
.targetFilterQuery("controllerId==" + rolloutName + "-*")
.set(distributionSet), Arrays.asList(group5, group6, group7), conditions)).isNotNull();
}
@Test
@Description("Verify the creation and the automatic start of a rollout.")
void createAndAutoStartRollout() throws Exception {
void createAndAutoStartRollout() {
final int amountTargetsForRollout = 50;
final int amountGroups = 5;
final String successCondition = "50";
final String errorCondition = "80";
final String rolloutName = "rolloutTest8";
final String targetPrefixName = rolloutName;
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName);
testdataFactory.createTargets(amountTargetsForRollout, targetPrefixName + "-", targetPrefixName);
testdataFactory.createTargets(amountTargetsForRollout, rolloutName + "-", rolloutName);
Rollout myRollout = testdataFactory.createRolloutByVariables(rolloutName, "desc", amountGroups,
"controllerId==" + targetPrefixName + "-*", distributionSet, successCondition, errorCondition);
"controllerId==" + rolloutName + "-*", distributionSet, successCondition, errorCondition);
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
// schedule rollout auto start into the future
final Long myRolloutId = myRollout.getId();
rolloutManagement
.update(entityFactory.rollout().update(myRollout.getId()).startAt(System.currentTimeMillis() + 60000));
.update(entityFactory.rollout().update(myRolloutId).startAt(System.currentTimeMillis() + 60000));
rolloutManagement.handleRollouts();
// rollout should not have been started
myRollout = rolloutManagement.get(myRollout.getId()).get();
myRollout = getRollout(myRolloutId);
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
// schedule to now
rolloutManagement.update(entityFactory.rollout().update(myRollout.getId()).startAt(System.currentTimeMillis()));
rolloutManagement.update(entityFactory.rollout().update(myRolloutId).startAt(System.currentTimeMillis()));
rolloutManagement.handleRollouts();
myRollout = rolloutManagement.get(myRollout.getId()).get();
myRollout = getRollout(myRolloutId);
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.STARTING);
// Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts();
final SuccessConditionRolloutStatus conditionRolloutTargetCount = new SuccessConditionRolloutStatus(
RolloutStatus.RUNNING);
assertThat(MultipleInvokeHelper.doWithTimeout(new RolloutStatusCallable(myRollout.getId()),
conditionRolloutTargetCount, 15000, 500)).as("Rollout status").isNotNull();
awaitRunningState(myRolloutId);
myRollout = rolloutManagement.get(myRollout.getId()).get();
myRollout = getRollout(myRolloutId);
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.RUNNING);
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 10L);
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.SCHEDULED, 40L);
validateRolloutActionStatus(myRollout.getId(), expectedTargetCountStatus);
validateRolloutActionStatus(myRolloutId, expectedTargetCountStatus);
}
private Rollout reloadRollout(final Rollout r) {
return getRollout(r.getId());
}
private Rollout getRollout(final Long myRolloutId) {
return rolloutManagement.get(myRolloutId).orElseThrow(NoSuchElementException::new);
}
@Test
@@ -1506,7 +1519,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutGroups.add(generateRolloutGroup(2, percentTargetsInGroup3, null));
Rollout myRollout = rolloutManagement.create(rolloutcreate, rolloutGroups, conditions);
myRollout = rolloutManagement.get(myRollout.getId()).get();
myRollout = getRollout(myRollout.getId());
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.CREATING);
for (final RolloutGroup group : rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()).getContent()) {
@@ -1520,7 +1533,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.handleRollouts();
myRollout = rolloutManagement.get(myRollout.getId()).get();
myRollout = getRollout(myRollout.getId());
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
assertThat(myRollout.getTotalTargets()).isEqualTo(amountTargetsInGroup1and2 + amountTargetsInGroup1);
@@ -1539,7 +1552,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify rollout creation fails if group definition does not address all targets")
void createRolloutWithGroupsNotMatchingTargets() throws Exception {
void createRolloutWithGroupsNotMatchingTargets() {
final String rolloutName = "rolloutTest4";
final int amountTargetsForRollout = 500;
final int percentTargetsInGroup1 = 20;
@@ -1560,7 +1573,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify rollout creation fails if group definition specifies illegal target percentage")
void createRolloutWithIllegalPercentage() throws Exception {
void createRolloutWithIllegalPercentage() {
final String rolloutName = "rolloutTest6";
final int amountTargetsForRollout = 10;
final int percentTargetsInGroup1 = 101;
@@ -1581,7 +1594,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify rollout creation fails if the 'max rollout groups per rollout' quota is violated.")
void createRolloutWithIllegalAmountOfGroups() throws Exception {
void createRolloutWithIllegalAmountOfGroups() {
final String rolloutName = "rolloutTest5";
final int targets = 10;
final int maxGroups = quotaManagement.getMaxRolloutGroupsPerRollout();
@@ -1589,34 +1602,33 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults().build();
final RolloutCreate rollout = generateTargetsAndRollout(rolloutName, targets);
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> rolloutManagement.create(rollout, maxGroups + 1, conditions))
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(
() -> rolloutManagement.create(rollout, maxGroups + 1, conditions))
.withMessageContaining("not be greater than " + maxGroups);
}
@Test
@Description("Verify the start of a Rollout does not work during creation phase.")
void createAndStartRolloutDuringCreationFails() throws Exception {
void createAndStartRolloutDuringCreationFails() {
final int amountTargetsForRollout = 3;
final int amountGroups = 5;
final String successCondition = "50";
final String errorCondition = "80";
final String rolloutName = "rolloutTestGC";
final String targetPrefixName = rolloutName;
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName);
testdataFactory.createTargets(amountTargetsForRollout, targetPrefixName + "-", targetPrefixName);
testdataFactory.createTargets(amountTargetsForRollout, rolloutName + "-", rolloutName);
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults()
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, successCondition)
.errorCondition(RolloutGroupErrorCondition.THRESHOLD, errorCondition)
.errorAction(RolloutGroupErrorAction.PAUSE, null).build();
final RolloutCreate rolloutToCreate = entityFactory.rollout().create().name(rolloutName)
.description("some description").targetFilterQuery("id==" + targetPrefixName + "-*")
.description("some description").targetFilterQuery("id==" + rolloutName + "-*")
.set(distributionSet);
Rollout myRollout = rolloutManagement.create(rolloutToCreate, amountGroups, conditions);
myRollout = rolloutManagement.get(myRollout.getId()).get();
myRollout = getRollout(myRollout.getId());
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.CREATING);
@@ -1640,7 +1652,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
}
@Test
@Description("Creating a rollout without approver role and approval enabled leads to transition to "
@Description("Creating a rollout without approve role and approval enabled leads to transition to "
+ "WAITING_FOR_APPROVAL state.")
void createdRolloutWithoutApprovalRoleTransitionsToWaitingForApprovalState() {
approvalStrategy.setApprovalNeeded(true);
@@ -1770,7 +1782,9 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Description("Creating a rollout without weight value when multi assignment in enabled.")
void weightNotRequiredInMultiAssignmentMode() {
enableMultiAssignments();
createSimpleTestRolloutWithTargetsAndDistributionSet(10, 10, 2, "50", "80", ActionType.FORCED, null);
final Rollout rollout = createSimpleTestRolloutWithTargetsAndDistributionSet(
10, 10, 2, "50", "80", ActionType.FORCED, null);
assertThat(rollout).isNotNull();
}
@Test
@@ -1805,7 +1819,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
}
@Test
@Description("A Rollout with weight creats actions with weights")
@Description("A Rollout with weight creates actions with weights")
void actionsWithWeightAreCreated() {
final int amountOfTargets = 5;
final int weight = 99;
@@ -1815,8 +1829,9 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.start(rolloutId);
rolloutManagement.handleRollouts();
final List<Action> actions = deploymentManagement.findActionsAll(PAGE).getContent();
assertThat(actions).hasSize(amountOfTargets);
assertThat(actions).allMatch(action -> action.getWeight().get() == weight);
assertThat(actions) //
.hasSize(amountOfTargets) //
.allMatch(action -> action.getWeight().get() == weight);
}
@Test
@@ -1830,57 +1845,58 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.start(rolloutId);
rolloutManagement.handleRollouts();
final List<Action> actions = deploymentManagement.findActionsAll(PAGE).getContent();
assertThat(actions).hasSize(amountOfTargets);
assertThat(actions).allMatch(action -> !action.getWeight().isPresent());
assertThat(actions).hasSize(amountOfTargets).allMatch(action -> !action.getWeight().isPresent());
}
@Test
@Description("Verifies that an exception is thrown when trying to create a rollout with an invalidated distribution set.")
public void createRolloutWithInvalidDistributionSet() {
void createRolloutWithInvalidDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception")
assertThatExceptionOfType(InvalidDistributionSetException.class).as(
"Invalid distributionSet should throw an exception")
.isThrownBy(() -> testdataFactory.createRolloutByVariables("createRolloutWithInvalidDistributionSet",
"desc", 2, "name==*", distributionSet, "50", "80"));
}
@Test
@Description("Verifies that an exception is thrown when trying to create a rollout with an incomplete distribution set.")
public void createRolloutWithIncompleteDistributionSet() {
void createRolloutWithIncompleteDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createIncompleteDistributionSet();
assertThatExceptionOfType(IncompleteDistributionSetException.class)
.as("Incomplete distributionSet should throw an exception")
assertThatExceptionOfType(IncompleteDistributionSetException.class).as(
"Incomplete distributionSet should throw an exception")
.isThrownBy(() -> testdataFactory.createRolloutByVariables("createRolloutWithIncompleteDistributionSet",
"desc", 2, "name==*", distributionSet, "50", "80"));
}
@Test
@Description("Verifies that an exception is thrown when trying to update a rollout with an invalidated distribution set.")
public void updateRolloutWithInvalidDistributionSet() {
void updateRolloutWithInvalidDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
testdataFactory.createTarget();
final Rollout rollout = testdataFactory.createRolloutByVariables("updateRolloutWithInvalidDistributionSet",
"desc", 2, "name==*", distributionSet, "50", "80");
final DistributionSet invalidDistributionSet = testdataFactory.createAndInvalidateDistributionSet();
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception").isThrownBy(() -> rolloutManagement
.update(entityFactory.rollout().update(rollout.getId()).set(invalidDistributionSet.getId())));
assertThatExceptionOfType(InvalidDistributionSetException.class).as(
"Invalid distributionSet should throw an exception")
.isThrownBy(() -> rolloutManagement.update(
entityFactory.rollout().update(rollout.getId()).set(invalidDistributionSet.getId())));
}
@Test
@Description("Verifies that an exception is thrown when trying to update a rollout with an incomplete distribution set.")
public void updateRolloutWithIncompleteDistributionSet() {
void updateRolloutWithIncompleteDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
testdataFactory.createTarget();
final Rollout rollout = testdataFactory.createRolloutByVariables("updateRolloutWithIncompleteDistributionSet",
"desc", 2, "name==*", distributionSet, "50", "80");
final DistributionSet incompleteDistributionSet = testdataFactory.createIncompleteDistributionSet();
assertThatExceptionOfType(IncompleteDistributionSetException.class)
.as("Incomplete distributionSet should throw an exception").isThrownBy(() -> rolloutManagement.update(
assertThatExceptionOfType(IncompleteDistributionSetException.class).as(
"Incomplete distributionSet should throw an exception")
.isThrownBy(() -> rolloutManagement.update(
entityFactory.rollout().update(rollout.getId()).set(incompleteDistributionSet.getId())));
}
@@ -1903,27 +1919,31 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
targets.addAll(targetsWithoutType);
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults().build();
final RolloutCreate rolloutToCreate = entityFactory.rollout().create().name(rolloutName)
.targetFilterQuery("name==*").set(testDs);
final RolloutCreate rolloutToCreate = entityFactory.rollout()
.create()
.name(rolloutName)
.targetFilterQuery("name==*")
.set(testDs);
final Rollout createdRollout = rolloutManagement.create(rolloutToCreate, 1, conditions);
// Let the executor handle created Rollout
rolloutManagement.handleRollouts();
final Rollout testRollout = rolloutManagement.get(createdRollout.getId()).get();
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement
.findByRollout(Pageable.unpaged(), testRollout.getId()).getContent();
final Rollout testRollout = reloadRollout(createdRollout);
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(Pageable.unpaged(),
testRollout.getId()).getContent();
assertThat(testRollout.getStatus()).isEqualTo(RolloutStatus.READY);
assertThat(testRollout.getTotalTargets()).isEqualTo(targets.size());
assertThat(rolloutGroups).hasSize(1);
assertThat(rolloutGroups.get(0).getTotalTargets()).isEqualTo(targets.size());
final List<Target> rolloutGroupTargets = rolloutGroupManagement
.findTargetsOfRolloutGroup(Pageable.unpaged(), rolloutGroups.get(0).getId()).getContent();
final List<Target> rolloutGroupTargets = rolloutGroupManagement.findTargetsOfRolloutGroup(Pageable.unpaged(),
rolloutGroups.get(0).getId()).getContent();
assertThat(rolloutGroupTargets).hasSize(targets.size()).containsExactlyInAnyOrderElementsOf(targets)
assertThat(rolloutGroupTargets).hasSize(targets.size())
.containsExactlyInAnyOrderElementsOf(targets)
.doesNotContainAnyElementsOf(incompatibleTargets);
}
@@ -2027,35 +2047,14 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
return map;
}
private static class SuccessConditionRolloutStatus implements SuccessCondition<RolloutStatus> {
private final RolloutStatus rolloutStatus;
public SuccessConditionRolloutStatus(final RolloutStatus rolloutStatus) {
this.rolloutStatus = rolloutStatus;
}
@Override
public boolean success(final RolloutStatus result) {
return result.equals(rolloutStatus);
}
private void awaitRunningState(final Long myRolloutId) {
Awaitility.await()
.atMost(Duration.TEN_SECONDS)
.pollInterval(Duration.FIVE_HUNDRED_MILLISECONDS)
.with()
.until(() -> WithSpringAuthorityRule.runAsPrivileged(
() -> rolloutManagement.get(myRolloutId).orElseThrow(NoSuchElementException::new))
.getStatus()
.equals(RolloutStatus.RUNNING));
}
private class RolloutStatusCallable implements Callable<RolloutStatus> {
final Long rolloutId;
RolloutStatusCallable(final Long rolloutId) {
this.rolloutId = rolloutId;
}
@Override
public RolloutStatus call() throws Exception {
final Rollout myRollout = rolloutManagement.get(rolloutId).get();
return myRollout.getStatus();
}
}
}

View File

@@ -16,8 +16,10 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import org.apache.commons.lang3.RandomUtils;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleMetadataCreate;
@@ -57,7 +59,7 @@ import io.qameta.allure.Story;
public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that management get access reacts as specfied on calls for non existing entities by means "
@Description("Verifies that management get access reacts as specified on calls for non existing entities by means "
+ "of Optional not present.")
@ExpectEvents({ @Expect(type = SoftwareModuleCreatedEvent.class, count = 1) })
public void nonExistingEntityAccessReturnsNotPresent() {
@@ -80,7 +82,8 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
verifyThrownExceptionBy(
() -> softwareModuleManagement
.create(Arrays.asList(entityFactory.softwareModule().create().name("xxx").type(NOT_EXIST_ID))),
.create(Collections
.singletonList(entityFactory.softwareModule().create().name("xxx").type(NOT_EXIST_ID))),
"SoftwareModuleType");
verifyThrownExceptionBy(
() -> softwareModuleManagement
@@ -92,12 +95,13 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
entityFactory.softwareModuleMetadata().create(NOT_EXIST_IDL).key("xxx").value("xxx")),
"SoftwareModule");
verifyThrownExceptionBy(
() -> softwareModuleManagement.createMetaData(Arrays
.asList(entityFactory.softwareModuleMetadata().create(NOT_EXIST_IDL).key("xxx").value("xxx"))),
() -> softwareModuleManagement.createMetaData(Collections.singletonList(
entityFactory.softwareModuleMetadata().create(NOT_EXIST_IDL).key("xxx").value("xxx"))),
"SoftwareModule");
verifyThrownExceptionBy(() -> softwareModuleManagement.delete(NOT_EXIST_IDL), "SoftwareModule");
verifyThrownExceptionBy(() -> softwareModuleManagement.delete(Arrays.asList(NOT_EXIST_IDL)), "SoftwareModule");
verifyThrownExceptionBy(() -> softwareModuleManagement.delete(Collections.singletonList(NOT_EXIST_IDL)),
"SoftwareModule");
verifyThrownExceptionBy(() -> softwareModuleManagement.deleteMetaData(NOT_EXIST_IDL, "xxx"), "SoftwareModule");
verifyThrownExceptionBy(() -> softwareModuleManagement.deleteMetaData(module.getId(), NOT_EXIST_ID),
"SoftwareModuleMetadata");
@@ -141,13 +145,13 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
.update(entityFactory.softwareModule().update(ah.getId()));
assertThat(updated.getOptLockRevision())
.as("Expected version number of updated entitity to be equal to created version")
.as("Expected version number of updated entity to be equal to created version")
.isEqualTo(ah.getOptLockRevision());
}
@Test
@Description("Calling update for changed fields results in change in the repository.")
public void updateSoftareModuleFieldsToNewValue() {
public void updateSoftwareModuleFieldsToNewValue() {
final SoftwareModule ah = testdataFactory.createSoftwareModuleOs();
final SoftwareModule updated = softwareModuleManagement
@@ -213,7 +217,9 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
assignDistributionSet(ds.getId(), target.getControllerId());
assertThat(targetManagement.getByControllerID(target.getControllerId()).get().getUpdateStatus())
.isEqualTo(TargetUpdateStatus.PENDING);
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId()).get()).isEqualTo(ds);
final Optional<DistributionSet> assignedDistributionSet = deploymentManagement
.getAssignedDistributionSet(target.getControllerId());
assertThat(assignedDistributionSet).contains(ds);
final Action action = actionRepository.findByTargetAndDistributionSet(PAGE, target, ds).getContent().get(0);
assertThat(action).isNotNull();
return action;
@@ -273,13 +279,13 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
// [VERIFY EXPECTED RESULT]:
// verify: SoftwareModule is deleted
assertThat(softwareModuleRepository.findAll()).hasSize(0);
assertThat(softwareModuleRepository.findAll()).isEmpty();
assertThat(softwareModuleManagement.get(unassignedModule.getId())).isNotPresent();
// verify: binary data of artifact is deleted
assertArtifactNull(artifact1, artifact2);
// verify: meta data of artifact is deleted
// verify: metadata of artifact is deleted
assertThat(artifactRepository.findById(artifact1.getId())).isNotPresent();
assertThat(artifactRepository.findById(artifact2.getId())).isNotPresent();
}
@@ -301,7 +307,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
// verify: assignedModule is marked as deleted
assignedModule = softwareModuleManagement.get(assignedModule.getId()).get();
assertTrue(assignedModule.isDeleted(), "The module should be flagged as deleted");
assertThat(softwareModuleManagement.findAll(PAGE)).hasSize(0);
assertThat(softwareModuleManagement.findAll(PAGE)).isEmpty();
assertThat(softwareModuleRepository.findAll()).hasSize(1);
// verify: binary data is deleted
@@ -329,7 +335,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
final DistributionSet disSet = testdataFactory.createDistributionSet(Sets.newHashSet(assignedModule));
// [STEP3]: Assign DistributionSet to a Device
assignDistributionSet(disSet, Arrays.asList(target));
assignDistributionSet(disSet, Collections.singletonList(target));
// [STEP4]: Delete the DistributionSet
distributionSetManagement.delete(disSet.getId());
@@ -341,7 +347,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
// verify: assignedModule is marked as deleted
assignedModule = softwareModuleManagement.get(assignedModule.getId()).get();
assertTrue(assignedModule.isDeleted(), "The found module should be flagged deleted");
assertThat(softwareModuleManagement.findAll(PAGE)).hasSize(0);
assertThat(softwareModuleManagement.findAll(PAGE)).isEmpty();
assertThat(softwareModuleRepository.findAll()).hasSize(1);
// verify: binary data is deleted
@@ -356,8 +362,8 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
}
@Test
@Description("Delete an softwaremodule with an artifact, which is alsoused by another softwaremodule.")
public void deleteSoftwareModulesWithSharedArtifact() throws IOException {
@Description("Delete an software module with an artifact, which is also used by another software module.")
public void deleteSoftwareModulesWithSharedArtifact() {
// Init artifact binary data, target and DistributionSets
final int artifactSize = 1024;
@@ -428,11 +434,11 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
// [STEP3]: Assign SoftwareModuleX to DistributionSetX and to target
final DistributionSet disSetX = testdataFactory.createDistributionSet(Sets.newHashSet(moduleX), "X");
assignDistributionSet(disSetX, Arrays.asList(target));
assignDistributionSet(disSetX, Collections.singletonList(target));
// [STEP4]: Assign SoftwareModuleY to DistributionSet and to target
final DistributionSet disSetY = testdataFactory.createDistributionSet(Sets.newHashSet(moduleY), "Y");
assignDistributionSet(disSetY, Arrays.asList(target));
assignDistributionSet(disSetY, Collections.singletonList(target));
// [STEP5]: Delete SoftwareModuleX
softwareModuleManagement.delete(moduleX.getId());
@@ -444,12 +450,12 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
moduleX = softwareModuleManagement.get(moduleX.getId()).get();
moduleY = softwareModuleManagement.get(moduleY.getId()).get();
// verify: SoftwareModuleX and SofwtareModule are marked as deleted
// verify: SoftwareModuleX and SoftwareModule are marked as deleted
assertThat(moduleX).isNotNull();
assertThat(moduleY).isNotNull();
assertTrue(moduleX.isDeleted(), "The module should be flagged deleted");
assertTrue(moduleY.isDeleted(), "The module should be flagged deleted");
assertThat(softwareModuleManagement.findAll(PAGE)).hasSize(0);
assertThat(softwareModuleManagement.findAll(PAGE)).isEmpty();
assertThat(softwareModuleRepository.findAll()).hasSize(2);
// verify: binary data of artifact is deleted
@@ -506,7 +512,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
}
@Test
@Description("Test verfies that results are returned based on given filter parameters and in the specified order.")
@Description("Test verifies that results are returned based on given filter parameters and in the specified order.")
public void findSoftwareModuleOrderByDistributionModuleNameAscModuleVersionAsc() {
// test meta data
final SoftwareModuleType testType = softwareModuleTypeManagement
@@ -515,9 +521,9 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
.create(entityFactory.distributionSetType().create().key("key").name("name"));
distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(testDsType.getId(),
Arrays.asList(osType.getId()));
Collections.singletonList(osType.getId()));
testDsType = distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(testDsType.getId(),
Arrays.asList(testType.getId()));
Collections.singletonList(testType.getId()));
// found in test
final SoftwareModule unassigned = testdataFactory.createSoftwareModule("thetype", "unassignedfound", false);
@@ -567,9 +573,9 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
.create(entityFactory.distributionSetType().create().key("key").name("name"));
distributionSetTypeManagement.assignMandatorySoftwareModuleTypes(testDsType.getId(),
Arrays.asList(osType.getId()));
Collections.singletonList(osType.getId()));
testDsType = distributionSetTypeManagement.assignOptionalSoftwareModuleTypes(testDsType.getId(),
Arrays.asList(testType.getId()));
Collections.singletonList(testType.getId()));
// found in test
testdataFactory.createSoftwareModule("thetype", "unassignedfound", false);
@@ -602,7 +608,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
// one soft deleted
final SoftwareModule deleted = testdataFactory.createSoftwareModuleApp();
testdataFactory.createDistributionSet(Arrays.asList(deleted));
testdataFactory.createDistributionSet(Collections.singletonList(deleted));
softwareModuleManagement.delete(deleted.getId());
assertThat(softwareModuleManagement.count()).as("Number of undeleted modules").isEqualTo(1);
@@ -610,7 +616,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
}
@Test
@Description("Verfies that software modules are resturned that are assigned to given DS.")
@Description("Verfies that software modules are returned that are assigned to given DS.")
public void findSoftwareModuleByAssignedTo() {
// test modules
final SoftwareModule one = testdataFactory.createSoftwareModuleOs();
@@ -688,7 +694,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
// add some meta data entries
final SoftwareModule module3 = testdataFactory.createSoftwareModuleApp("m3");
final int firstHalf = Math.round(maxMetaData / 2);
final int firstHalf = Math.round(((float) maxMetaData) / 2.f);
for (int i = 0; i < firstHalf; ++i) {
softwareModuleManagement.createMetaData(
entityFactory.softwareModuleMetadata().create(module3.getId()).key("k" + i).value("v" + i));
@@ -735,7 +741,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
@Test
@WithUser(allSpPermissions = true)
@Description("Checks that metadata for a software module can be updated.")
public void updateSoftwareModuleMetadata() throws InterruptedException {
public void updateSoftwareModuleMetadata() {
final String knownKey = "myKnownKey";
final String knownValue = "myKnownValue";
final String knownUpdateValue = "myNewUpdatedValue";
@@ -752,18 +758,16 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
assertThat(softwareModuleMetadata.getValue()).isEqualTo(knownValue);
// base software module should have now the opt lock revision one
// because we are modifying the
// base software module
// because we are modifying the base software module
SoftwareModule changedLockRevisionModule = softwareModuleManagement.get(ah.getId()).get();
assertThat(changedLockRevisionModule.getOptLockRevision()).isEqualTo(2);
// update the software module metadata
Thread.sleep(100);
final SoftwareModuleMetadata updated = softwareModuleManagement.updateMetaData(entityFactory
.softwareModuleMetadata().update(ah.getId(), knownKey).value(knownUpdateValue).targetVisible(true));
// we are updating the sw meta data so also modiying the base software
// module so opt lock
// revision must be two
// we are updating the sw metadata so also modifying the base software
// module so opt lock revision must be two
changedLockRevisionModule = softwareModuleManagement.get(ah.getId()).get();
assertThat(changedLockRevisionModule.getOptLockRevision()).isEqualTo(3);
@@ -776,7 +780,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
}
@Test
@Description("Verfies that existing metadata can be deleted.")
@Description("Verifies that existing metadata can be deleted.")
public void deleteSoftwareModuleMetadata() {
final String knownKey1 = "myKnownKey1";
final String knownValue1 = "myKnownValue1";
@@ -796,11 +800,11 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
softwareModuleManagement.deleteMetaData(ah.getId(), knownKey1);
assertThat(
softwareModuleManagement.findMetaDataBySoftwareModuleId(PageRequest.of(0, 10), ah.getId()).getContent())
.as("Metadata elemenets are").isEmpty();
.as("Metadata elements are").isEmpty();
}
@Test
@Description("Verfies that non existing metadata find results in exception.")
@Description("Verifies that non existing metadata find results in exception.")
public void findSoftwareModuleMetadataFailsIfEntryDoesNotExist() {
final String knownKey1 = "myKnownKey1";
final String knownValue1 = "myKnownValue1";
@@ -854,7 +858,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
assertThat(metadataSw1.getNumberOfElements()).isEqualTo(metadataCountSw1);
assertThat(metadataSw1.getTotalElements()).isEqualTo(metadataCountSw1);
assertThat(metadataSw2.getNumberOfElements()).isEqualTo(0);
assertThat(metadataSw2.getTotalElements()).isEqualTo(0);
assertThat(metadataSw2.getNumberOfElements()).isZero();
assertThat(metadataSw2.getTotalElements()).isZero();
}
}

View File

@@ -20,12 +20,14 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.validation.ConstraintViolationException;
import org.apache.commons.lang3.RandomStringUtils;
import org.awaitility.Awaitility;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.repository.FilterParams;
import org.eclipse.hawkbit.repository.Identifiable;
@@ -77,7 +79,7 @@ import io.qameta.allure.Story;
@Feature("Component Tests - Repository")
@Story("Target Management")
public class TargetManagementTest extends AbstractJpaIntegrationTest {
class TargetManagementTest extends AbstractJpaIntegrationTest {
private static final String WHITESPACE_ERROR = "target with whitespaces in controller id should not be created";
@@ -85,7 +87,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Description("Verifies that management get access react as specified on calls for non existing entities by means "
+ "of Optional not present.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1) })
public void nonExistingEntityAccessReturnsNotPresent() {
void nonExistingEntityAccessReturnsNotPresent() {
final Target target = testdataFactory.createTarget();
assertThat(targetManagement.getByControllerID(NOT_EXIST_ID)).isNotPresent();
assertThat(targetManagement.get(NOT_EXIST_IDL)).isNotPresent();
@@ -97,7 +99,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
+ " by means of throwing EntityNotFoundException.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetTagCreatedEvent.class, count = 1) })
public void entityQueriesReferringToNotExistingEntitiesThrowsException() {
void entityQueriesReferringToNotExistingEntitiesThrowsException() {
final TargetTag tag = targetTagManagement.create(entityFactory.tag().create().name("A"));
final Target target = testdataFactory.createTarget();
@@ -153,14 +155,15 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
verifyThrownExceptionBy(() -> targetManagement.update(entityFactory.target().update(NOT_EXIST_ID)), "Target");
verifyThrownExceptionBy(() -> targetManagement.createMetaData(NOT_EXIST_ID,
Arrays.asList(entityFactory.generateTargetMetadata("123", "123"))), "Target");
Collections.singletonList(entityFactory.generateTargetMetadata("123", "123"))), "Target");
verifyThrownExceptionBy(() -> targetManagement.deleteMetaData(NOT_EXIST_ID, "xxx"), "Target");
verifyThrownExceptionBy(() -> targetManagement.deleteMetaData(target.getControllerId(), NOT_EXIST_ID),
"TargetMetadata");
verifyThrownExceptionBy(() -> targetManagement.getMetaDataByControllerId(NOT_EXIST_ID, "xxx"), "Target");
verifyThrownExceptionBy(() -> targetManagement.findMetaDataByControllerId(PAGE, NOT_EXIST_ID), "Target");
verifyThrownExceptionBy(() -> targetManagement.findMetaDataByControllerIdAndRsql(PAGE, NOT_EXIST_ID, "key==*"),
verifyThrownExceptionBy(() -> targetManagement.findMetaDataByControllerId(PAGE, NOT_EXIST_ID),
"Target");
verifyThrownExceptionBy(
() -> targetManagement.findMetaDataByControllerIdAndRsql(PAGE, NOT_EXIST_ID, "key==*"), "Target");
verifyThrownExceptionBy(
() -> targetManagement.updateMetadata(NOT_EXIST_ID, entityFactory.generateTargetMetadata("xxx", "xxx")),
"Target");
@@ -171,7 +174,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Ensures that retrieving the target security is only permitted with the necessary permissions.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1) })
public void getTargetSecurityTokenOnlyWithCorrectPermission() throws Exception {
void getTargetSecurityTokenOnlyWithCorrectPermission() throws Exception {
final Target createdTarget = targetManagement
.create(entityFactory.target().create().controllerId("targetWithSecurityToken").securityToken("token"));
@@ -197,8 +200,8 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Ensures that targets cannot be created e.g. in plug'n play scenarios when tenant does not exists.")
@WithUser(tenantId = "tenantWhichDoesNotExists", allSpPermissions = true, autoCreateTenant = false)
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
public void createTargetForTenantWhichDoesNotExistThrowsTenantNotExistException() {
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
void createTargetForTenantWhichDoesNotExistThrowsTenantNotExistException() {
try {
targetManagement.create(entityFactory.target().create().controllerId("targetId123"));
fail("should not be possible as the tenant does not exist");
@@ -210,7 +213,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify that a target with same controller ID than another device cannot be created.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1) })
public void createTargetThatViolatesUniqueConstraintFails() {
void createTargetThatViolatesUniqueConstraintFails() {
targetManagement.create(entityFactory.target().create().controllerId("123"));
assertThatExceptionOfType(EntityAlreadyExistsException.class)
@@ -220,8 +223,8 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify that a target with with invalid properties cannot be created or updated")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 0) })
public void createAndUpdateTargetWithInvalidFields() {
@Expect(type = TargetUpdatedEvent.class) })
void createAndUpdateTargetWithInvalidFields() {
final Target target = testdataFactory.createTarget();
createTargetWithInvalidControllerId();
@@ -235,54 +238,53 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
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))))
.as("target with too long description should not be created");
.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)))
.as("target with invalid description should not be created");
.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))))
.as("target with too long description should not be updated");
.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)))
.as("target with invalid description should not be updated");
.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))))
.as("target with too long name should not be created");
.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)))
.as("target with invalid name should not be created");
.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))))
.as("target with too long name should not be updated");
.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)))
.as("target with invalid name should not be updated");
.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("")))
.as("target with too short name should not be updated");
() -> targetManagement.update(entityFactory.target().update(target.getControllerId()).name("")));
}
@@ -290,90 +292,90 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
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))))
.as("target with too long token should not be created");
.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)))
.as("target with invalid token should not be created");
.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))))
.as("target with too long token should not be updated");
.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)))
.as("target with invalid token should not be updated");
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("")))
.as("target with too short token should not be updated");
.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))))
.as("target with too long address should not be created");
.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)))
.as("target with invalid should not be created");
.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))))
.as("target with too long address should not be updated");
.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)))
.as("target with invalid address should not be updated");
.update(entityFactory.target().update(target.getControllerId()).address(INVALID_TEXT_HTML)));
}
@Step
private void createTargetWithInvalidControllerId() {
assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("")))
.as("target with empty controller id should not be created");
.as("target with empty controller id should not be created")
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("")));
assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(null)))
.as("target with null controller id should not be created");
.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))))
.as("target with too long controller id should not be created");
.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)))
.as("target with invalid controller id should not be created");
() -> targetManagement.create(entityFactory.target().create().controllerId(INVALID_TEXT_HTML)));
assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(" ")))
.as(WHITESPACE_ERROR);
.as(WHITESPACE_ERROR)
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(" ")));
assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a b")))
.as(WHITESPACE_ERROR);
.as(WHITESPACE_ERROR)
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a b")));
assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(" ")))
.as(WHITESPACE_ERROR);
.as(WHITESPACE_ERROR)
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(" ")));
assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("aaa bbb")))
.as(WHITESPACE_ERROR);
.as(WHITESPACE_ERROR)
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("aaa bbb")));
}
@@ -382,7 +384,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 4),
@Expect(type = TargetTagCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 5) })
public void assignAndUnassignTargetsToTag() {
void assignAndUnassignTargetsToTag() {
final List<String> assignTarget = new ArrayList<>();
assignTarget.add(
targetManagement.create(entityFactory.target().create().controllerId("targetId123")).getControllerId());
@@ -400,7 +402,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
assignedTargets.forEach(target -> assertThat(
targetTagManagement.findByTarget(PAGE, target.getControllerId()).getNumberOfElements()).isEqualTo(1));
TargetTag findTargetTag = targetTagManagement.getByName("Tag1").get();
TargetTag findTargetTag = targetTagManagement.getByName("Tag1").orElseThrow(IllegalStateException::new);
assertThat(assignedTargets.size()).as("Assigned targets are wrong")
.isEqualTo(targetManagement.findByTag(PAGE, targetTag.getId()).getNumberOfElements());
@@ -408,7 +410,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
assertThat(unAssignTarget.getControllerId()).as("Controller id is wrong").isEqualTo("targetId123");
assertThat(targetTagManagement.findByTarget(PAGE, unAssignTarget.getControllerId())).as("Tag size is wrong")
.isEmpty();
findTargetTag = targetTagManagement.getByName("Tag1").get();
targetTagManagement.getByName("Tag1").orElseThrow(NoSuchElementException::new);
assertThat(targetManagement.findByTag(PAGE, targetTag.getId())).as("Assigned targets are wrong").hasSize(3);
assertThat(targetManagement.findByRsqlAndTag(PAGE, "controllerId==targetId123", targetTag.getId()))
.as("Assigned targets are wrong").isEmpty();
@@ -421,17 +423,17 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Description("Ensures that targets can deleted e.g. test all cascades")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 12),
@Expect(type = TargetDeletedEvent.class, count = 12), @Expect(type = TargetUpdatedEvent.class, count = 6) })
public void deleteAndCreateTargets() {
void deleteAndCreateTargets() {
Target target = targetManagement.create(entityFactory.target().create().controllerId("targetId123"));
assertThat(targetManagement.count()).as("target count is wrong").isEqualTo(1);
targetManagement.delete(Collections.singletonList(target.getId()));
assertThat(targetManagement.count()).as("target count is wrong").isEqualTo(0);
assertThat(targetManagement.count()).as("target count is wrong").isZero();
target = createTargetWithAttributes("4711");
assertThat(targetManagement.count()).as("target count is wrong").isEqualTo(1);
assertThat(targetManagement.existsByControllerId("4711")).isTrue();
targetManagement.delete(Collections.singletonList(target.getId()));
assertThat(targetManagement.count()).as("target count is wrong").isEqualTo(0);
assertThat(targetManagement.count()).as("target count is wrong").isZero();
assertThat(targetManagement.existsByControllerId("4711")).isFalse();
final List<Long> targets = new ArrayList<>();
@@ -442,7 +444,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
}
assertThat(targetManagement.count()).as("target count is wrong").isEqualTo(10);
targetManagement.delete(targets);
assertThat(targetManagement.count()).as("target count is wrong").isEqualTo(0);
assertThat(targetManagement.count()).as("target count is wrong").isZero();
}
private Target createTargetWithAttributes(final String controllerId) {
@@ -466,60 +468,72 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 1) })
public void findTargetByControllerIDWithDetails() {
final DistributionSet set = testdataFactory.createDistributionSet("test");
final DistributionSet set2 = testdataFactory.createDistributionSet("test2");
void findTargetByControllerIDWithDetails() {
final DistributionSet testDs1 = testdataFactory.createDistributionSet("test");
final DistributionSet testDs2 = testdataFactory.createDistributionSet("test2");
assertThat(targetManagement.countByAssignedDistributionSet(set.getId())).as("Target count is wrong")
.isEqualTo(0);
assertThat(targetManagement.countByInstalledDistributionSet(set.getId())).as("Target count is wrong")
.isEqualTo(0);
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(set.getId())).as("Target count is wrong")
assertThat(targetManagement.countByAssignedDistributionSet(testDs1.getId()))
.as("For newly created distributions sets the assigned target count should be zero")
.isZero();
assertThat(targetManagement.countByInstalledDistributionSet(testDs1.getId()))
.as("For newly created distributions sets the installed target count should be zero")
.isZero();
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(testDs1.getId()))
.as("Exists assigned or installed query should return false for new distribution sets")
.isFalse();
assertThat(targetManagement.countByAssignedDistributionSet(set2.getId())).as("Target count is wrong")
.isEqualTo(0);
assertThat(targetManagement.countByInstalledDistributionSet(set2.getId())).as("Target count is wrong")
.isEqualTo(0);
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(set2.getId()))
.as("Target count is wrong").isFalse();
assertThat(targetManagement.countByAssignedDistributionSet(testDs2.getId()))
.as("For newly created distributions sets the assigned target count should be zero")
.isZero();
assertThat(targetManagement.countByInstalledDistributionSet(testDs2.getId()))
.as("For newly created distributions sets the installed target count should be zero")
.isZero();
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(testDs2.getId()))
.as("For newly created distributions sets the assigned target count should be zero").isFalse();
Target target = createTargetWithAttributes("4711");
final long current = System.currentTimeMillis();
controllerManagement.findOrRegisterTargetIfItDoesNotExist("4711", LOCALHOST);
final DistributionSetAssignmentResult result = assignDistributionSet(set.getId(), "4711");
final DistributionSetAssignmentResult result = assignDistributionSet(testDs1.getId(), "4711");
controllerManagement.addUpdateActionStatus(
entityFactory.actionStatus().create(getFirstAssignedActionId(result)).status(Status.FINISHED));
assignDistributionSet(set2.getId(), "4711");
assignDistributionSet(testDs2.getId(), "4711");
target = targetManagement.getByControllerID("4711").get();
target = targetManagement.getByControllerID("4711").orElseThrow(IllegalStateException::new);
// read data
assertThat(targetManagement.countByAssignedDistributionSet(set.getId())).as("Target count is wrong")
.isEqualTo(0);
assertThat(targetManagement.countByInstalledDistributionSet(set.getId())).as("Target count is wrong")
assertThat(targetManagement.countByAssignedDistributionSet(testDs1.getId())).as("Target count is wrong")
.isZero();
assertThat(targetManagement.countByInstalledDistributionSet(testDs1.getId())).as("Target count is wrong")
.isEqualTo(1);
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(set.getId())).as("Target count is wrong")
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(testDs1.getId())).as("Target count is wrong")
.isTrue();
assertThat(targetManagement.countByAssignedDistributionSet(set2.getId())).as("Target count is wrong")
assertThat(targetManagement.countByAssignedDistributionSet(testDs2.getId())).as("Target count is wrong")
.isEqualTo(1);
assertThat(targetManagement.countByInstalledDistributionSet(set2.getId())).as("Target count is wrong")
.isEqualTo(0);
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(set2.getId()))
assertThat(targetManagement.countByInstalledDistributionSet(testDs2.getId())).as("Target count is wrong")
.isZero();
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(testDs2.getId()))
.as("Target count is wrong").isTrue();
assertThat(target.getLastTargetQuery()).as("Target query is not work").isGreaterThanOrEqualTo(current);
assertThat(deploymentManagement.getAssignedDistributionSet("4711").get()).as("Assigned ds size is wrong")
.isEqualTo(set2);
assertThat(deploymentManagement.getInstalledDistributionSet("4711").get()).as("Installed ds is wrong")
.isEqualTo(set);
final DistributionSet assignedDs = deploymentManagement.getAssignedDistributionSet("4711")
.orElseThrow(NoSuchElementException::new);
assertThat(assignedDs).as("Assigned ds size is wrong")
.isEqualTo(testDs2);
final DistributionSet installedDs = deploymentManagement.getInstalledDistributionSet("4711")
.orElseThrow(NoSuchElementException::new);
assertThat(installedDs)
.as("Installed ds is wrong")
.isEqualTo(testDs1);
}
@Test
@Description("Checks if the EntityAlreadyExistsException is thrown if the targets with the same controller ID are created twice.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 5) })
public void createMultipleTargetsDuplicate() {
void createMultipleTargetsDuplicate() {
testdataFactory.createTargets(5, "mySimpleTargs", "my simple targets");
try {
testdataFactory.createTargets(5, "mySimpleTargs", "my simple targets");
@@ -532,7 +546,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Checks if the EntityAlreadyExistsException is thrown if a single target with the same controller ID are created twice.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1) })
public void createTargetDuplicate() {
void createTargetDuplicate() {
targetManagement.create(entityFactory.target().create().controllerId("4711"));
try {
targetManagement.create(entityFactory.target().create().controllerId("4711"));
@@ -554,8 +568,6 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
* targets to be verified
* @param tags
* are contained within tags of all targets.
* @param tags
* to be found in the tags of the targets
*/
private void checkTargetHasTags(final boolean strict, final Iterable<Target> targets, final TargetTag... tags) {
_target: for (final Target tl : targets) {
@@ -592,34 +604,29 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Description("Creates and updates a target and verifies the changes in the repository.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1) })
public void singleTargetIsInsertedIntoRepo() throws Exception {
void singleTargetIsInsertedIntoRepo() throws Exception {
final String myCtrlID = "myCtrlID";
Target savedTarget = testdataFactory.createTarget(myCtrlID);
assertThat(savedTarget).isNotNull().as("The target should not be null");
final Long createdAt = savedTarget.getCreatedAt();
Long modifiedAt = savedTarget.getLastModifiedAt();
assertThat(savedTarget).as("The target should not be null").isNotNull();
final long createdAt = savedTarget.getCreatedAt();
long modifiedAt = savedTarget.getLastModifiedAt();
assertThat(createdAt).as("CreatedAt compared with modifiedAt").isEqualTo(modifiedAt);
assertThat(savedTarget.getCreatedAt()).isNotNull()
.as("The createdAt attribute of the target should no be null");
assertThat(savedTarget.getLastModifiedAt()).isNotNull()
.as("The lastModifiedAt attribute of the target should no be null");
Thread.sleep(1);
Awaitility.await().until( () -> System.currentTimeMillis() > createdAt + 1);
savedTarget = targetManagement.update(
entityFactory.target().update(savedTarget.getControllerId()).description("changed description"));
assertThat(savedTarget.getLastModifiedAt()).isNotNull()
.as("The lastModifiedAt attribute of the target should not be null");
assertThat(createdAt).as("CreatedAt compared with saved modifiedAt")
.isNotEqualTo(savedTarget.getLastModifiedAt());
assertThat(modifiedAt).as("ModifiedAt compared with saved modifiedAt")
.isNotEqualTo(savedTarget.getLastModifiedAt());
modifiedAt = savedTarget.getLastModifiedAt();
final Target foundTarget = targetManagement.getByControllerID(savedTarget.getControllerId()).get();
assertThat(foundTarget).isNotNull().as("The target should not be null");
final Target foundTarget = targetManagement.getByControllerID(savedTarget.getControllerId()).orElseThrow(IllegalStateException::new);
assertThat(foundTarget).as("The target should not be null").isNotNull();
assertThat(myCtrlID).as("ControllerId compared with saved controllerId")
.isEqualTo(foundTarget.getControllerId());
assertThat(savedTarget).as("Target compared with saved target").isEqualTo(foundTarget);
@@ -634,7 +641,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 101),
@Expect(type = TargetUpdatedEvent.class, count = 100),
@Expect(type = TargetDeletedEvent.class, count = 51) })
public void bulkTargetCreationAndDelete() throws Exception {
void bulkTargetCreationAndDelete() {
final String myCtrlID = "myCtrlID";
List<Target> firstList = testdataFactory.createTargets(100, myCtrlID, "first description");
@@ -699,7 +706,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 2),
@Expect(type = TargetTagCreatedEvent.class, count = 7),
@Expect(type = TargetUpdatedEvent.class, count = 7) })
public void targetTagAssignment() {
void targetTagAssignment() {
final Target t1 = testdataFactory.createTarget("id-1");
final int noT2Tags = 4;
final int noT1Tags = 3;
@@ -711,13 +718,13 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
final List<TargetTag> t2Tags = testdataFactory.createTargetTags(noT2Tags, "tag2");
t2Tags.forEach(tag -> targetManagement.assignTag(Collections.singletonList(t2.getControllerId()), tag.getId()));
final Target t11 = targetManagement.getByControllerID(t1.getControllerId()).get();
final Target t11 = targetManagement.getByControllerID(t1.getControllerId()).orElseThrow(IllegalStateException::new);
assertThat(targetTagManagement.findByTarget(PAGE, t11.getControllerId()).getContent()).as("Tag size is wrong")
.hasSize(noT1Tags).containsAll(t1Tags);
assertThat(targetTagManagement.findByTarget(PAGE, t11.getControllerId()).getContent()).as("Tag size is wrong")
.hasSize(noT1Tags).doesNotContain(Iterables.toArray(t2Tags, TargetTag.class));
final Target t21 = targetManagement.getByControllerID(t2.getControllerId()).get();
final Target t21 = targetManagement.getByControllerID(t2.getControllerId()).orElseThrow(IllegalStateException::new);
assertThat(targetTagManagement.findByTarget(PAGE, t21.getControllerId()).getContent()).as("Tag size is wrong")
.hasSize(noT2Tags).containsAll(t2Tags);
assertThat(targetTagManagement.findByTarget(PAGE, t21.getControllerId()).getContent()).as("Tag size is wrong")
@@ -729,7 +736,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 50),
@Expect(type = TargetTagCreatedEvent.class, count = 4),
@Expect(type = TargetUpdatedEvent.class, count = 80) })
public void targetTagBulkAssignments() {
void targetTagBulkAssignments() {
final List<Target> tagATargets = testdataFactory.createTargets(10, "tagATargets", "first description");
final List<Target> tagBTargets = testdataFactory.createTargets(10, "tagBTargets", "first description");
final List<Target> tagCTargets = testdataFactory.createTargets(10, "tagCTargets", "first description");
@@ -756,7 +763,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
toggleTagAssignment(tagABCTargets, tagC);
assertThat(targetManagement.countByFilters(new FilterParams(null, null, null, null, Boolean.FALSE, "X")))
.as("Target count is wrong").isEqualTo(0);
.as("Target count is wrong").isZero();
// search for targets with tag tagA
final List<Target> targetWithTagA = new ArrayList<>();
@@ -798,7 +805,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 3),
@Expect(type = TargetCreatedEvent.class, count = 109),
@Expect(type = TargetUpdatedEvent.class, count = 227) })
public void targetTagBulkUnassignments() {
void targetTagBulkUnassignments() {
final TargetTag targTagA = targetTagManagement.create(entityFactory.tag().create().name("Targ-A-Tag"));
final TargetTag targTagB = targetTagManagement.create(entityFactory.tag().create().name("Targ-B-Tag"));
final TargetTag targTagC = targetTagManagement.create(entityFactory.tag().create().name("Targ-C-Tag"));
@@ -856,7 +863,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 1),
@Expect(type = TargetCreatedEvent.class, count = 50),
@Expect(type = TargetUpdatedEvent.class, count = 25) })
public void findTargetsWithNoTag() {
void findTargetsWithNoTag() {
final TargetTag targTagA = targetTagManagement.create(entityFactory.tag().create().name("Targ-A-Tag"));
final List<Target> targAs = testdataFactory.createTargets(25, "target-id-A", "first description");
@@ -868,8 +875,8 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
final List<Target> targetsListWithNoTag = targetManagement
.findByFilters(PAGE, new FilterParams(null, null, null, null, Boolean.TRUE, tagNames)).getContent();
assertThat(50L).as("Total targets").isEqualTo(targetManagement.count());
assertThat(25).as("Targets with no tag").isEqualTo(targetsListWithNoTag.size());
assertThat(targetManagement.count()).as("Total targets").isEqualTo(50L);
assertThat(targetsListWithNoTag.size()).as("Targets with no tag").isEqualTo(25);
}
@@ -877,12 +884,13 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Description("Tests the a target can be read with only the read target permission")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 1) })
public void targetCanBeReadWithOnlyReadTargetPermission() throws Exception {
void targetCanBeReadWithOnlyReadTargetPermission() throws Exception {
final String knownTargetControllerId = "readTarget";
controllerManagement.findOrRegisterTargetIfItDoesNotExist(knownTargetControllerId, new URI("http://127.0.0.1"));
WithSpringAuthorityRule.runAs(WithSpringAuthorityRule.withUser("bumlux", "READ_TARGET"), () -> {
final Target findTargetByControllerID = targetManagement.getByControllerID(knownTargetControllerId).get();
final Target findTargetByControllerID = targetManagement.getByControllerID(knownTargetControllerId)
.orElseThrow(IllegalStateException::new);
assertThat(findTargetByControllerID).isNotNull();
assertThat(findTargetByControllerID.getPollStatus()).isNotNull();
return null;
@@ -892,7 +900,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Test that RSQL filter finds targets with tags or specific ids.")
public void findTargetsWithTagOrId() {
void findTargetsWithTagOrId() {
final String rsqlFilter = "tag==Targ-A-Tag,id==target-id-B-00001,id==target-id-B-00008";
final TargetTag targTagA = targetTagManagement.create(entityFactory.tag().create().name("Targ-A-Tag"));
final List<String> targAs = testdataFactory.createTargets(25, "target-id-A", "first description").stream()
@@ -910,7 +918,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify that the find all targets by ids method contains the entities that we are looking for")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 12) })
public void verifyFindTargetAllById() {
void verifyFindTargetAllById() {
final List<Long> searchIds = Arrays.asList(testdataFactory.createTarget("target-4").getId(),
testdataFactory.createTarget("target-5").getId(), testdataFactory.createTarget("target-6").getId());
for (int i = 0; i < 9; i++) {
@@ -927,7 +935,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify that the flag for requesting controller attributes is set correctly.")
public void verifyRequestControllerAttributes() {
void verifyRequestControllerAttributes() {
final String knownControllerId = "KnownControllerId";
final Target target = createTargetWithAttributes(knownControllerId);
@@ -945,7 +953,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Checks that metadata for a target can be created.")
public void createTargetMetadata() {
void createTargetMetadata() {
final String knownKey = "targetMetaKnownKey";
final String knownValue = "targetMetaKnownValue";
@@ -968,7 +976,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies the enforcement of the metadata quota per target.")
public void createTargetMetadataUntilQuotaIsExceeded() {
void createTargetMetadataUntilQuotaIsExceeded() {
// add meta data one by one
final Target target1 = testdataFactory.createTarget("target1");
@@ -1012,7 +1020,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@WithUser(allSpPermissions = true)
@Description("Checks that metadata for a target can be updated.")
public void updateTargetMetadata() throws InterruptedException {
void updateTargetMetadata() throws InterruptedException {
final String knownKey = "myKnownKey";
final String knownValue = "myKnownValue";
final String knownUpdateValue = "myNewUpdatedValue";
@@ -1025,21 +1033,20 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
// create target meta data entry
insertTargetMetadata(knownKey, knownValue, target);
Target changedLockRevisionTarget = targetManagement.get(target.getId()).get();
Target changedLockRevisionTarget = targetManagement.get(target.getId()).orElseThrow(NoSuchElementException::new);
assertThat(changedLockRevisionTarget.getOptLockRevision()).isEqualTo(2);
Thread.sleep(100);
// Unsure if needed maybe to wait for a db flush?
// Thread.sleep(100);
// update the target metadata
final JpaTargetMetadata updated = (JpaTargetMetadata) targetManagement.updateMetadata(target.getControllerId(),
entityFactory.generateTargetMetadata(knownKey, knownUpdateValue));
// we are updating the target meta data so also modifying the base
// software
// module so opt lock
// revision must be three
changedLockRevisionTarget = targetManagement.get(target.getId()).get();
// software module so opt lock revision must be three
changedLockRevisionTarget = targetManagement.get(target.getId()).orElseThrow(NoSuchElementException::new);
assertThat(changedLockRevisionTarget.getOptLockRevision()).isEqualTo(3);
assertThat(changedLockRevisionTarget.getLastModifiedAt()).isGreaterThan(0L);
assertThat(changedLockRevisionTarget.getLastModifiedAt()).isPositive();
// verify updated meta data contains the updated value
assertThat(updated).isNotNull();
@@ -1052,7 +1059,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@WithUser(allSpPermissions = true)
@Description("Checks that target type for a target can be created, updated and unassigned.")
public void createAndUpdateTargetTypeInTarget() {
void createAndUpdateTargetTypeInTarget() {
// create a target type
final List<TargetType> targetTypes = testdataFactory.createTargetTypes("targettype", 2);
assertThat(targetTypes).hasSize(2);
@@ -1088,7 +1095,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@WithUser(allSpPermissions = true)
@Description("Checks that target type to a target can be assigned.")
public void assignTargetTypeInTarget() {
void assignTargetTypeInTarget() {
// create a target
final Target target = testdataFactory.createTarget("target1", "testtarget");
// initial opt lock revision must be one
@@ -1117,7 +1124,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 20),
@Expect(type = TargetTypeCreatedEvent.class, count = 2),
@Expect(type = TargetUpdatedEvent.class, count = 29), @Expect(type = TargetDeletedEvent.class, count = 1) })
public void targetTypeBulkAssignments() {
void targetTypeBulkAssignments() {
final List<Target> typeATargets = testdataFactory.createTargets(10, "typeATargets", "first description");
final List<Target> typeBTargets = testdataFactory.createTargets(10, "typeBTargets", "first description");
@@ -1163,7 +1170,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Queries and loads the metadata related to a given target.")
public void findAllTargetMetadataByControllerId() {
void findAllTargetMetadataByControllerId() {
// create targets
final Target target1 = createTargetWithMetadata("target1", 10);
final Target target2 = createTargetWithMetadata("target2", 8);
@@ -1194,7 +1201,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@WithUser(allSpPermissions = true)
@Description("Checks that target type is not assigned to target if invalid.")
public void assignInvalidTargetTypeToTarget() {
void assignInvalidTargetTypeToTarget() {
// create a target
final Target target = testdataFactory.createTarget("target1", "testtarget");
// initial opt lock revision must be one
@@ -1205,12 +1212,12 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
// assign target type to target
assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> targetManagement.assignType(targetFound.get().getControllerId(), null))
.as("target type with id=null cannot be assigned");
.as("target type with id=null cannot be assigned")
.isThrownBy(() -> targetManagement.assignType(targetFound.get().getControllerId(), null));
assertThatExceptionOfType(EntityNotFoundException.class)
.isThrownBy(() -> targetManagement.assignType(targetFound.get().getControllerId(), 114L))
.as("target type with id that does not exists cannot be assigned");
.as("target type with id that does not exists cannot be assigned")
.isThrownBy(() -> targetManagement.assignType(targetFound.get().getControllerId(), 114L));
// opt lock revision is not changed
Optional<JpaTarget> targetFound1 = targetRepository.findById(target.getId());
@@ -1221,7 +1228,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@WithUser(allSpPermissions = true)
@Description("Checks that target type can be unassigned from target.")
public void unAssignTargetTypeFromTarget() {
void unAssignTargetTypeFromTarget() {
// create a target type
TargetType targetType = testdataFactory.findOrCreateTargetType("targettype");
assertThat(targetType).isNotNull();
@@ -1245,7 +1252,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Test that RSQL filter finds targets with metadata and/or controllerId.")
public void findTargetsByRsqlWithMetadata() {
void findTargetsByRsqlWithMetadata() {
final String controllerId1 = "target1";
final String controllerId2 = "target2";
createTargetWithMetadata(controllerId1, 2);

View File

@@ -10,7 +10,6 @@ package org.eclipse.hawkbit.repository.jpa;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.junit.jupiter.api.Assertions.fail;
import java.util.ArrayList;
import java.util.Arrays;
@@ -34,12 +33,12 @@ 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.junit.jupiter.api.Test;
/**
* Test class for {@link TargetTagManagement}.
@@ -47,13 +46,13 @@ import org.junit.jupiter.api.Test;
*/
@Feature("Component Tests - Repository")
@Story("Target Tag Management")
public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
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, count = 0) })
public void nonExistingEntityAccessReturnsNotPresent() {
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class) })
void nonExistingEntityAccessReturnsNotPresent() {
assertThat(targetTagManagement.getByName(NOT_EXIST_ID)).isNotPresent();
assertThat(targetTagManagement.get(NOT_EXIST_IDL)).isNotPresent();
}
@@ -61,9 +60,8 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
@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, count = 0),
@Expect(type = TargetTagUpdatedEvent.class, count = 0) })
public void entityQueriesReferringToNotExistingEntitiesThrowsException() {
@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)),
@@ -74,7 +72,7 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify that a tag with with invalid properties cannot be created or updated")
public void createAndUpdateTagWithInvalidFields() {
void createAndUpdateTagWithInvalidFields() {
final TargetTag tag = targetTagManagement
.create(entityFactory.tag().create().name("tag1").description("tagdesc1"));
@@ -87,80 +85,81 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
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))))
.as("tag with too long description should not be created");
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
() -> targetTagManagement.create(entityFactory.tag().create().name("a").description(INVALID_TEXT_HTML)))
.as("tag with invalid description should not be created");
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))))
.as("tag with too long description should not be updated");
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)))
.as("tag with invalid description should not be updated");
.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))))
.as("tag with too long colour should not be created");
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
() -> targetTagManagement.create(entityFactory.tag().create().name("a").colour(INVALID_TEXT_HTML)))
.as("tag with invalid colour should not be created");
entityFactory.tag().create().name("a").colour(RandomStringUtils.randomAlphanumeric(17))));
assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> targetTagManagement.update(
entityFactory.tag().update(tag.getId()).colour(RandomStringUtils.randomAlphanumeric(17))))
.as("tag with too long colour should not be updated");
.as("tag with invalid colour should not be created").isThrownBy(() -> targetTagManagement
.create(entityFactory.tag().create().name("a").colour(INVALID_TEXT_HTML)));
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
() -> targetTagManagement.update(entityFactory.tag().update(tag.getId()).colour(INVALID_TEXT_HTML)))
.as("tag with invalid colour should not be updated");
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))))
.as("tag with too long name should not be created");
NamedEntity.NAME_MAX_SIZE + 1))));
assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> targetTagManagement.create(entityFactory.tag().create().name(INVALID_TEXT_HTML)))
.as("tag with invalidname should not be created");
.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))))
.as("tag with too long name should not be updated");
NamedEntity.NAME_MAX_SIZE + 1))));
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
() -> targetTagManagement.update(entityFactory.tag().update(tag.getId()).name(INVALID_TEXT_HTML)))
.as("tag with invalid name should not be updated");
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)
.isThrownBy(() -> targetTagManagement.update(entityFactory.tag().update(tag.getId()).name("")))
.as("tag with too short name should not be updated");
.as("tag with too short name should not be updated")
.isThrownBy(() -> targetTagManagement.update(entityFactory.tag().update(tag.getId()).name("")));
}
@Test
@Description("Verifies the toogle mechanism by means on assigning tag if at least on target in the list does not have"
+ "the tag yet. Unassign if all of them have the tag already.")
public void assignAndUnassignTargetTags() {
void assignAndUnassignTargetTags() {
final List<Target> groupA = testdataFactory.createTargets(20);
final List<Target> groupB = testdataFactory.createTargets(20, "groupb", "groupb");
@@ -169,11 +168,11 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
// toggle A only -> A is now assigned
TargetTagAssignmentResult result = toggleTagAssignment(groupA, tag);
assertThat(result.getAlreadyAssigned()).isEqualTo(0);
assertThat(result.getAlreadyAssigned()).isZero();
assertThat(result.getAssigned()).isEqualTo(20);
assertThat(result.getAssignedEntity()).containsAll(targetManagement
.getByControllerID(groupA.stream().map(Target::getControllerId).collect(Collectors.toList())));
assertThat(result.getUnassigned()).isEqualTo(0);
assertThat(result.getUnassigned()).isZero();
assertThat(result.getUnassignedEntity()).isEmpty();
assertThat(result.getTargetTag()).isEqualTo(tag);
@@ -183,14 +182,14 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
assertThat(result.getAssigned()).isEqualTo(20);
assertThat(result.getAssignedEntity()).containsAll(targetManagement
.getByControllerID(groupB.stream().map(Target::getControllerId).collect(Collectors.toList())));
assertThat(result.getUnassigned()).isEqualTo(0);
assertThat(result.getUnassigned()).isZero();
assertThat(result.getUnassignedEntity()).isEmpty();
assertThat(result.getTargetTag()).isEqualTo(tag);
// toggle A+B -> both unassigned
result = toggleTagAssignment(concat(groupA, groupB), tag);
assertThat(result.getAlreadyAssigned()).isEqualTo(0);
assertThat(result.getAssigned()).isEqualTo(0);
assertThat(result.getAlreadyAssigned()).isZero();
assertThat(result.getAssigned()).isZero();
assertThat(result.getAssignedEntity()).isEmpty();
assertThat(result.getUnassigned()).isEqualTo(40);
assertThat(result.getUnassignedEntity()).containsAll(targetManagement.getByControllerID(
@@ -208,7 +207,7 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Ensures that all tags are retrieved through repository.")
public void findAllTargetTags() {
void findAllTargetTags() {
final List<JpaTargetTag> tags = createTargetsWithTags();
assertThat(targetTagRepository.findAll()).isEqualTo(targetTagRepository.findAll()).isEqualTo(tags)
@@ -217,7 +216,7 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Ensures that a created tag is persisted in the repository as defined.")
public void createTargetTag() {
void createTargetTag() {
final Tag tag = targetTagManagement
.create(entityFactory.tag().create().name("kai1").description("kai2").colour("colour"));
@@ -229,7 +228,7 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Ensures that a deleted tag is removed from the repository as defined.")
public void deleteTargetTags() {
void deleteTargetTags() {
// create test data
final Iterable<JpaTargetTag> tags = createTargetsWithTags();
@@ -254,7 +253,7 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Tests the name update of a target tag.")
public void updateTargetTag() {
void updateTargetTag() {
final List<JpaTargetTag> tags = createTargetsWithTags();
// change data
@@ -273,29 +272,20 @@ public class TargetTagManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Ensures that a tag cannot be created if one exists already with that name (ecpects EntityAlreadyExistsException).")
public void failedDuplicateTargetTagNameException() {
void failedDuplicateTargetTagNameException() {
targetTagManagement.create(entityFactory.tag().create().name("A"));
try {
targetTagManagement.create(entityFactory.tag().create().name("A"));
fail("should not have worked as tag already exists");
} catch (final EntityAlreadyExistsException e) {
}
assertThatExceptionOfType(EntityAlreadyExistsException.class)
.isThrownBy(() -> targetTagManagement.create(entityFactory.tag().create().name("A")));
}
@Test
@Description("Ensures that a tag cannot be updated to a name that already exists on another tag (ecpects EntityAlreadyExistsException).")
public void failedDuplicateTargetTagNameExceptionAfterUpdate() {
void failedDuplicateTargetTagNameExceptionAfterUpdate() {
targetTagManagement.create(entityFactory.tag().create().name("A"));
final TargetTag tag = targetTagManagement.create(entityFactory.tag().create().name("B"));
try {
targetTagManagement.update(entityFactory.tag().update(tag.getId()).name("A"));
fail("should not have worked as tag already exists");
} catch (final EntityAlreadyExistsException e) {
}
assertThatExceptionOfType(EntityAlreadyExistsException.class)
.isThrownBy(() -> targetTagManagement.update(entityFactory.tag().update(tag.getId()).name("A")));
}
private List<JpaTargetTag> createTargetsWithTags() {

View File

@@ -8,10 +8,15 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.qameta.allure.Step;
import io.qameta.allure.Story;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.util.Collections;
import java.util.Optional;
import javax.validation.ConstraintViolationException;
import org.apache.commons.lang3.RandomStringUtils;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTypeCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTypeUpdatedEvent;
@@ -24,23 +29,20 @@ import org.eclipse.hawkbit.repository.test.matcher.Expect;
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
import org.junit.jupiter.api.Test;
import javax.validation.ConstraintViolationException;
import java.util.Collections;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.junit.jupiter.api.Assertions.assertThrows;
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")
public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
class TargetTypeManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that management get access react as specified on calls for non existing entities by means "
+ "of Optional not present.")
@ExpectEvents({ @Expect(type = TargetTypeCreatedEvent.class, count = 0) })
public void nonExistingEntityAccessReturnsNotPresent() {
@ExpectEvents({ @Expect(type = TargetTypeCreatedEvent.class) })
void nonExistingEntityAccessReturnsNotPresent() {
assertThat(targetTypeManagement.get(NOT_EXIST_IDL)).isNotPresent();
assertThat(targetTypeManagement.getByName(NOT_EXIST_ID)).isNotPresent();
}
@@ -48,8 +50,8 @@ public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
@Test
@Description("Verifies that management queries react as specified on calls for non existing entities "
+ " by means of throwing EntityNotFoundException.")
@ExpectEvents({ @Expect(type = TargetTypeUpdatedEvent.class, count = 0) })
public void entityQueriesReferringToNotExistingEntitiesThrowsException() {
@ExpectEvents({ @Expect(type = TargetTypeUpdatedEvent.class) })
void entityQueriesReferringToNotExistingEntitiesThrowsException() {
verifyThrownExceptionBy(() -> targetTypeManagement.delete(NOT_EXIST_IDL), "TargetType");
verifyThrownExceptionBy(() -> targetTypeManagement.update(entityFactory.targetType().update(NOT_EXIST_IDL)),
"TargetType");
@@ -57,7 +59,7 @@ public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
@Test
@Description("Verify that a target type with invalid properties cannot be created or updated")
public void createAndUpdateTargetTypeWithInvalidFields() {
void createAndUpdateTargetTypeWithInvalidFields() {
final TargetType targetType = targetTypeManagement
.create(entityFactory.targetType().create().name("targettype1").description("targettypedes1"));
@@ -67,82 +69,86 @@ public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
}
@Step
private void createAndUpdateTargetTypeWithInvalidDescription(final TargetType targetType) {
void createAndUpdateTargetTypeWithInvalidDescription(final TargetType targetType) {
assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with too long description should not be created")
.isThrownBy(() -> targetTypeManagement.create(
entityFactory.targetType().create().name("a").description(RandomStringUtils.randomAlphanumeric(TargetType.DESCRIPTION_MAX_SIZE + 1))))
.as("targetType with too long description should not be created");
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
() -> targetTypeManagement.create(entityFactory.targetType().create().name("a").description(INVALID_TEXT_HTML)))
.as("targetType with invalid description should not be created");
entityFactory.targetType().create().name("a").description(
RandomStringUtils.randomAlphanumeric(TargetType.DESCRIPTION_MAX_SIZE + 1))));
assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with invalid description should not be created").isThrownBy(() -> targetTypeManagement
.create(entityFactory.targetType().create().name("a").description(INVALID_TEXT_HTML)));
assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with too long description should not be updated")
.isThrownBy(() -> targetTypeManagement.update(
entityFactory.targetType().update(targetType.getId()).description(RandomStringUtils.randomAlphanumeric(TargetType.DESCRIPTION_MAX_SIZE + 1))))
.as("targetType with too long description should not be updated");
entityFactory.targetType().update(targetType.getId()).description(
RandomStringUtils.randomAlphanumeric(TargetType.DESCRIPTION_MAX_SIZE + 1))));
assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with invalid description should not be updated")
.isThrownBy(() -> targetTypeManagement
.update(entityFactory.targetType().update(targetType.getId()).description(INVALID_TEXT_HTML)))
.as("targetType with invalid description should not be updated");
.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))))
.as("targetType with too long colour should not be created");
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
() -> targetTypeManagement.create(entityFactory.targetType().create().name("a").colour(INVALID_TEXT_HTML)))
.as("targetType with invalid colour should not be created");
entityFactory.targetType().create().name("a")
.colour(RandomStringUtils.randomAlphanumeric(TargetType.COLOUR_MAX_SIZE + 1))));
assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> targetTypeManagement.update(
entityFactory.targetType().update(targetType.getId()).colour(RandomStringUtils.randomAlphanumeric(TargetType.COLOUR_MAX_SIZE + 1))))
.as("targetType with too long colour should not be updated");
.as("targetType with invalid colour should not be created").isThrownBy(() -> targetTypeManagement
.create(entityFactory.targetType().create().name("a").colour(INVALID_TEXT_HTML)));
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
() -> targetTypeManagement.update(entityFactory.targetType().update(targetType.getId()).colour(INVALID_TEXT_HTML)))
.as("targetType with invalid colour should not be updated");
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 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))))
.as("targetType with too long name should not be created");
NamedEntity.NAME_MAX_SIZE + 1))));
assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> targetTypeManagement.create(entityFactory.targetType().create().name(INVALID_TEXT_HTML)))
.as("targetType with invalid name should not be created");
.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))))
.as("targetType with too long name should not be updated");
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
() -> targetTypeManagement.update(entityFactory.targetType().update(targetType.getId()).name(INVALID_TEXT_HTML)))
.as("targetType with invalid name should not be updated");
NamedEntity.NAME_MAX_SIZE + 1))));
assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> targetTypeManagement.update(entityFactory.targetType().update(targetType.getId()).name("")))
.as("targetType with too short name should not be updated");
.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")
public void assignCompatibleDistributionSetTypesToTargetType(){
void assignCompatibleDistributionSetTypesToTargetType() {
final TargetType targetType = targetTypeManagement
.create(entityFactory.targetType().create().name("targettype1").description("targettypedes1"));
DistributionSetType distributionSetType = testdataFactory.findOrCreateDistributionSetType("testDst", "dst1");
@@ -155,7 +161,7 @@ public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
@Test
@Description("Tests the successful removal of compatible distribution set types to a target type")
public void unassignCompatibleDistributionSetTypesToTargetType(){
void unassignCompatibleDistributionSetTypesToTargetType() {
final TargetType targetType = targetTypeManagement
.create(entityFactory.targetType().create().name("targettype11").description("targettypedes11"));
DistributionSetType distributionSetType = testdataFactory.findOrCreateDistributionSetType("testDst1", "dst11");
@@ -166,19 +172,19 @@ public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
targetTypeManagement.unassignDistributionSetType(targetType.getId(),distributionSetType.getId());
Optional<JpaTargetType> targetTypeWithDsTypes1 = targetTypeRepository.findById(targetType.getId());
assertThat(targetTypeWithDsTypes1).isPresent();
assertThat(targetTypeWithDsTypes1.get().getCompatibleDistributionSetTypes()).hasSize(0);
assertThat(targetTypeWithDsTypes1.get().getCompatibleDistributionSetTypes()).isEmpty();
}
@Test
@Description("Ensures that all types are retrieved through repository.")
public void findAllTargetTypes() {
void findAllTargetTypes() {
testdataFactory.createTargetTypes("targettype", 10);
assertThat(targetTypeRepository.findAll()).as("Target type size").hasSize(10);
}
@Test
@Description("Ensures that a created target type is persisted in the repository as defined.")
public void createTargetType() {
void createTargetType() {
final TargetType targetType = targetTypeManagement
.create(entityFactory.targetType().create().name("targettype1").description("targettypedes1").colour("colour1"));
@@ -190,7 +196,7 @@ public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
@Test
@Description("Ensures that a deleted target type is removed from the repository as defined.")
public void deleteTargetType() {
void deleteTargetType() {
// create test data
final TargetType targetType = targetTypeManagement
.create(entityFactory.targetType().create().name("targettype11").description("targettypedes11"));
@@ -203,7 +209,7 @@ public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
@Test
@Description("Tests the name update of a target type.")
public void updateTargetType() {
void updateTargetType() {
final TargetType targetType = targetTypeManagement
.create(entityFactory.targetType().create().name("targettype111").description("targettypedes111"));
assertThat(targetTypeRepository.findByName("targettype111").get().getDescription()).as("type found")
@@ -214,14 +220,14 @@ public class TargetTypeManagementTest extends AbstractJpaIntegrationTest{
@Test
@Description("Ensures that a target type cannot be created if one exists already with that name (expects EntityAlreadyExistsException).")
public void failedDuplicateTargetTypeNameException() {
void failedDuplicateTargetTypeNameException() {
targetTypeManagement.create(entityFactory.targetType().create().name("targettype123"));
assertThrows(EntityAlreadyExistsException.class, () -> targetTypeManagement.create(entityFactory.targetType().create().name("targettype123")));
}
@Test
@Description("Ensures that a target type cannot be updated to a name that already exists (expects EntityAlreadyExistsException).")
public void failedDuplicateTargetTypeNameExceptionAfterUpdate() {
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")));

View File

@@ -36,7 +36,7 @@ import io.qameta.allure.Story;
@Feature("Component Tests - Repository")
@Story("RSQL filter target")
public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
private Target target;
private Target target2;
@@ -47,7 +47,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
private static final String AND = ";";
@BeforeEach
public void setupBeforeTest() throws InterruptedException {
void setupBeforeTest() {
final DistributionSet ds = testdataFactory.createDistributionSet("AssignedDs");
@@ -63,7 +63,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
target2 = targetManagement
.create(entityFactory.target().create().controllerId("targetId1234").description("targetId1234"));
attributes.put("revision", "1.2");
Thread.sleep(1);
target2 = controllerManagement.updateControllerAttributes(target2.getControllerId(), attributes, null);
target2 = controllerManagement.findOrRegisterTargetIfItDoesNotExist(target2.getControllerId(), LOCALHOST);
createTargetMetadata(target2.getControllerId(), entityFactory.generateTargetMetadata("metaKey", "value"));
@@ -97,7 +97,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
@Test
@Description("Test filter target by (controller) id")
public void testFilterByParameterId() {
void testFilterByParameterId() {
assertRSQLQuery(TargetFields.ID.name() + "==targetId123", 1);
assertRSQLQuery(TargetFields.ID.name() + "==target*", 5);
assertRSQLQuery(TargetFields.ID.name() + "==noExist*", 0);
@@ -108,7 +108,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
@Test
@Description("Test filter target by name")
public void testFilterByParameterName() {
void testFilterByParameterName() {
assertRSQLQuery(TargetFields.NAME.name() + "==targetName123", 1);
assertRSQLQuery(TargetFields.NAME.name() + "==target*", 5);
assertRSQLQuery(TargetFields.NAME.name() + "==noExist*", 0);
@@ -119,7 +119,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
@Test
@Description("Test filter target by description")
public void testFilterByParameterDescription() {
void testFilterByParameterDescription() {
assertRSQLQuery(TargetFields.DESCRIPTION.name() + "==''", 3);
assertRSQLQuery(TargetFields.DESCRIPTION.name() + "!=''", 2);
assertRSQLQuery(TargetFields.DESCRIPTION.name() + "==targetDesc123", 1);
@@ -132,7 +132,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
@Test
@Description("Test filter target by controller id")
public void testFilterByParameterControllerId() {
void testFilterByParameterControllerId() {
assertRSQLQuery(TargetFields.CONTROLLERID.name() + "==targetId123", 1);
assertRSQLQuery(TargetFields.CONTROLLERID.name() + "==target*", 5);
assertRSQLQuery(TargetFields.CONTROLLERID.name() + "==noExist*", 0);
@@ -143,7 +143,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
@Test
@Description("Test filter target by status")
public void testFilterByParameterUpdateStatus() {
void testFilterByParameterUpdateStatus() {
assertRSQLQuery(TargetFields.UPDATESTATUS.name() + "==pending", 1);
assertRSQLQuery(TargetFields.UPDATESTATUS.name() + "!=pending", 4);
try {
@@ -158,8 +158,9 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
@Test
@Description("Test filter target by attribute")
public void testFilterByAttribute() {
createTargetWithAttributes("test.dot", "value.dot");
void testFilterByAttribute() {
controllerManagement.updateControllerAttributes(testdataFactory.createTarget().getControllerId(),
Maps.newHashMap("test.dot", "value.dot"), null);
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".revision==1.1", 1);
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".revision!=1.1", 1);
@@ -174,17 +175,14 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".key*==value.dot", 0);
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".*==value.dot", 0);
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + "..==value.dot", 0);
assertRSQLQueryThrowsException(TargetFields.ATTRIBUTE.name() + ".==value.dot",
RSQLParameterUnsupportedFieldException.class);
assertRSQLQueryThrowsException(TargetFields.ATTRIBUTE.name() + "*==value.dot",
RSQLParameterUnsupportedFieldException.class);
assertRSQLQueryThrowsException(TargetFields.ATTRIBUTE.name() + "==value.dot",
RSQLParameterUnsupportedFieldException.class);
assertRSQLQueryThrowsException(TargetFields.ATTRIBUTE.name() + ".==value.dot");
assertRSQLQueryThrowsException(TargetFields.ATTRIBUTE.name() + "*==value.dot");
assertRSQLQueryThrowsException(TargetFields.ATTRIBUTE.name() + "==value.dot");
}
@Test
@Description("Test filter target by assigned ds name")
public void testFilterByAssignedDsName() {
void testFilterByAssignedDsName() {
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".name==AssignedDs", 1);
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".name==A*", 1);
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".name==noExist*", 0);
@@ -194,7 +192,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
@Test
@Description("Test filter target by assigned ds version")
public void testFilterByAssignedDsVersion() {
void testFilterByAssignedDsVersion() {
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".version==" + TestdataFactory.DEFAULT_VERSION, 1);
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".version==*1*", 1);
assertRSQLQuery(TargetFields.ASSIGNEDDS.name() + ".version==noExist*", 0);
@@ -206,7 +204,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
@Test
@Description("Test filter target by tag name")
public void testFilterByTag() {
void testFilterByTag() {
assertRSQLQuery(TargetFields.TAG.name() + "==Tag1", 2);
assertRSQLQuery(TargetFields.TAG.name() + "!=Tag1", 3);
assertRSQLQuery(TargetFields.TAG.name() + "==T*", 4);
@@ -226,7 +224,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
@Test
@Description("Test filter target by lastTargetQuery")
public void testFilterByLastTargetQuery() throws InterruptedException {
void testFilterByLastTargetQuery() {
assertRSQLQuery(TargetFields.LASTCONTROLLERREQUESTAT.name() + "==" + target.getLastTargetQuery(), 1);
assertRSQLQuery(TargetFields.LASTCONTROLLERREQUESTAT.name() + "!=" + target.getLastTargetQuery(), 4);
assertRSQLQuery(TargetFields.LASTCONTROLLERREQUESTAT.name() + "=lt=" + target.getLastTargetQuery(), 0);
@@ -239,8 +237,9 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
@Test
@Description("Test filter target by metadata")
public void testFilterByMetadata() {
createTargetWithMetadata("key.dot", "value.dot");
void testFilterByMetadata() {
createTargetMetadata(testdataFactory.createTarget().getControllerId(),
entityFactory.generateTargetMetadata("key.dot", "value.dot"));
assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey==metaValue", 1);
assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey==*v*", 2);
@@ -258,17 +257,14 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
assertRSQLQuery(TargetFields.METADATA.name() + ".key*==value.dot", 0);
assertRSQLQuery(TargetFields.METADATA.name() + ".*==value.dot", 0);
assertRSQLQuery(TargetFields.METADATA.name() + "..==value.dot", 0);
assertRSQLQueryThrowsException(TargetFields.METADATA.name() + ".==value.dot",
RSQLParameterUnsupportedFieldException.class);
assertRSQLQueryThrowsException(TargetFields.METADATA.name() + "*==value.dot",
RSQLParameterUnsupportedFieldException.class);
assertRSQLQueryThrowsException(TargetFields.METADATA.name() + "==value.dot",
RSQLParameterUnsupportedFieldException.class);
assertRSQLQueryThrowsException(TargetFields.METADATA.name() + ".==value.dot");
assertRSQLQueryThrowsException(TargetFields.METADATA.name() + "*==value.dot");
assertRSQLQueryThrowsException(TargetFields.METADATA.name() + "==value.dot");
}
@Test
@Description("Test filter based on more complex RSQL queries")
public void testFilterByComplexQueries() {
void testFilterByComplexQueries() {
assertRSQLQuery(
TargetFields.NAME.name() + "!=targetName123" + AND + TargetFields.METADATA.name() + ".metaKey!=value",
0);
@@ -278,7 +274,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
@Test
@Description("Testing allowed RSQL keys based on TargetFields definition")
public void rsqlValidTargetFields() {
void rsqlValidTargetFields() {
final String rsql1 = "ID == '0123' and NAME == abcd and DESCRIPTION == absd"
+ " and CREATEDAT =lt= 0123 and LASTMODIFIEDAT =gt= 0123"
+ " and CONTROLLERID == 0123 and UPDATESTATUS == PENDING"
@@ -308,7 +304,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
@Test
@Description("Test filter by target type")
public void shouldFilterTargetsByTypeIdNameAndDescription() {
void shouldFilterTargetsByTypeIdNameAndDescription() {
assertRSQLQuery("targettype." + TargetTypeFields.NAME.name() + "==" + targetType1.getName(), 1);
assertRSQLQuery("targettype." + TargetTypeFields.NAME.name() + "==*1", 1);
assertRSQLQuery("targettype." + TargetTypeFields.NAME.name() + "!=" + targetType2.getName(), 4);
@@ -327,23 +323,8 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
assertThat(countTargetsAll).isEqualTo(expectedTargets);
}
private <T extends Throwable> void assertRSQLQueryThrowsException(final String rsqlParam,
final Class<T> expectedException) {
assertThatExceptionOfType(expectedException)
private void assertRSQLQueryThrowsException(final String rsqlParam) {
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
.isThrownBy(() -> RSQLUtility.validateRsqlFor(rsqlParam, TargetFields.class));
}
private Target createTargetWithMetadata(final String metadataKeyName, final String metadataValue) {
final Target target = testdataFactory.createTarget();
createTargetMetadata(target.getControllerId(),
entityFactory.generateTargetMetadata(metadataKeyName, metadataValue));
return target;
}
private Target createTargetWithAttributes(final String attributeName, final String attributeValue) {
final Target target = testdataFactory.createTarget();
controllerManagement.updateControllerAttributes(target.getControllerId(),
Maps.newHashMap(attributeName, attributeValue), null);
return target;
}
}

View File

@@ -8,10 +8,7 @@
*/
package org.eclipse.hawkbit.repository.jpa.rsql;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import org.apache.commons.lang3.text.StrSubstitutor;
@@ -23,6 +20,8 @@ import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.T
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.Spy;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Bean;
@@ -70,34 +69,15 @@ public class VirtualPropertyResolverTest {
StrSubstitutor.DEFAULT_SUFFIX, StrSubstitutor.DEFAULT_ESCAPE);
}
@Test
@ParameterizedTest
@ValueSource(strings = { "${NOW_TS}", "${OVERDUE_TS}", "${overdue_ts}" })
@Description("Tests resolution of NOW_TS by using a StrSubstitutor configured with the VirtualPropertyResolver.")
public void resolveNowTimestampPlaceholder() {
final String placeholder = "${NOW_TS}";
void resolveNowTimestampPlaceholder(final String placeholder) {
final String testString = "lhs=lt=" + placeholder;
final String resolvedPlaceholders = substitutor.replace(testString);
assertThat("NOW_TS has to be resolved!", resolvedPlaceholders, not(containsString(placeholder)));
}
@Test
@Description("Tests resolution of OVERDUE_TS by using a StrSubstitutor configured with the VirtualPropertyResolver.")
public void resolveOverdueTimestampPlaceholder() {
final String placeholder = "${OVERDUE_TS}";
final String testString = "lhs=lt=" + placeholder;
final String resolvedPlaceholders = substitutor.replace(testString);
assertThat("OVERDUE_TS has to be resolved!", resolvedPlaceholders, not(containsString(placeholder)));
}
@Test
@Description("Tests case insensititity of VirtualPropertyResolver.")
public void resolveOverdueTimestampPlaceholderLowerCase() {
final String placeholder = "${overdue_ts}";
final String testString = "lhs=lt=" + placeholder;
final String resolvedPlaceholders = substitutor.replace(testString);
assertThat("overdue_ts has to be resolved!", resolvedPlaceholders, not(containsString(placeholder)));
assertThat(resolvedPlaceholders).as("'%s' placeholder was not replaced", placeholder)
.doesNotContain(placeholder);
}
@Test
@@ -107,7 +87,7 @@ public class VirtualPropertyResolverTest {
final String testString = "lhs=lt=" + placeholder;
final String resolvedPlaceholders = substitutor.replace(testString);
assertThat("unknown should not be resolved!", resolvedPlaceholders, containsString(placeholder));
assertThat(resolvedPlaceholders).as("unknown should not be resolved!").contains(placeholder);
}
@Test
@@ -118,6 +98,6 @@ public class VirtualPropertyResolverTest {
final String testString = "lhs=lt=" + escaptedPlaceholder;
final String resolvedPlaceholders = substitutor.replace(testString);
assertThat("Escaped OVERDUE_TS should not be resolved!", resolvedPlaceholders, containsString(placeholder));
assertThat(resolvedPlaceholders).as("Escaped OVERDUE_TS should not be resolved!").contains(placeholder);
}
}

View File

@@ -1,94 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.utils;
import java.util.concurrent.Callable;
/**
* Helper to call a request multiple times regarding a given condition until
* timeout is reached.
*
*/
public final class MultipleInvokeHelper {
/**
* Call with timeout until result is not null.
*
* @param callable
* class
* @param timeout
* value
* @param pollInterval
* value
* @return
* @throws Exception
*/
public static <T> T doWithTimeoutUntilResultIsNotNull(final Callable<T> callable, final long timeout,
final long pollInterval) throws Exception // NOPMD
{
return doWithTimeout(callable, new SuccessCondition<T>() {
@Override
public boolean success(final T result) {
return result != null;
};
}, timeout, pollInterval);
}
/**
* Call with timeout.
*
* @param callable
* class
* @param successCondition
* class
* @param timeout
* value
* @param pollInterval
* value
* @return
* @throws Exception
*/
public static <T> T doWithTimeout(final Callable<T> callable, final SuccessCondition<T> successCondition,
final long timeout, final long pollInterval) throws Exception // NOPMD
{
if (pollInterval < 0) {
throw new IllegalArgumentException("pollInterval must non negative");
}
long duration = 0;
Exception exception = null;
T returnValue = null;
while (untilTimeoutReached(timeout, duration)) {
try {
returnValue = callable.call();
// clear exception
exception = null;
} catch (final Exception ex) {
exception = ex;
}
Thread.sleep(pollInterval);
duration += pollInterval > 0 ? pollInterval : 1;
if (exception == null && successCondition.success(returnValue)) {
return returnValue;
} else {
returnValue = null;
}
}
if (exception != null) {
throw exception;
}
return returnValue;
}
private static boolean untilTimeoutReached(final long timeout, final long duration) {
return duration <= timeout || timeout < 0;
}
}

View File

@@ -1,27 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.utils;
/**
* SuccessCondition Interface.
*
* @param <T>
* type of the value to get verified
*/
public interface SuccessCondition<T> {
/**
* The implementation of the success condition.
*
* @param result
* @return
*/
boolean success(final T result);
}

View File

@@ -17,11 +17,10 @@ import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
import java.util.NoSuchElementException;
import java.util.stream.Collectors;
import org.apache.commons.io.FileUtils;
@@ -59,7 +58,6 @@ import org.eclipse.hawkbit.repository.model.MetaData;
import org.eclipse.hawkbit.repository.model.RepositoryModelConstants;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetMetadata;
import org.eclipse.hawkbit.repository.test.TestConfiguration;
import org.eclipse.hawkbit.repository.test.matcher.EventVerifier;
import org.eclipse.hawkbit.security.SystemSecurityContext;
@@ -103,7 +101,7 @@ import org.springframework.test.context.TestPropertySource;
// Cleaning repository will fire "delete" events. We won't count them to the
// test execution. So, the order execution between EventVerifier and Cleanup is
// important!
@TestExecutionListeners(inheritListeners = true, listeners = { EventVerifier.class, CleanupTestExecutionListener.class,
@TestExecutionListeners(listeners = { EventVerifier.class, CleanupTestExecutionListener.class,
MySqlTestDatabase.class, MsSqlTestDatabase.class,
PostgreSqlTestDatabase.class }, mergeMode = MergeMode.MERGE_WITH_DEFAULTS)
@TestPropertySource(properties = "spring.main.allow-bean-definition-overriding=true")
@@ -302,7 +300,7 @@ public abstract class AbstractIntegrationTest {
}
protected DistributionSetAssignmentResult assignDistributionSet(final DistributionSet pset, final Target target) {
return assignDistributionSet(pset, Arrays.asList(target));
return assignDistributionSet(pset, Collections.singletonList(target));
}
protected DistributionSetAssignmentResult assignDistributionSet(final long dsId, final String targetId,
@@ -322,16 +320,16 @@ public abstract class AbstractIntegrationTest {
return distributionSetManagement.createMetaData(dsId, md);
}
protected TargetMetadata createTargetMetadata(final String controllerId, final MetaData md) {
return createTargetMetadata(controllerId, Collections.singletonList(md)).get(0);
protected void createTargetMetadata(final String controllerId, final MetaData md) {
createTargetMetadata(controllerId, Collections.singletonList(md));
}
protected List<TargetMetadata> createTargetMetadata(final String controllerId, final List<MetaData> md) {
return targetManagement.createMetaData(controllerId, md);
private void createTargetMetadata(final String controllerId, final List<MetaData> md) {
targetManagement.createMetaData(controllerId, md);
}
protected Long getOsModule(final DistributionSet ds) {
return ds.findFirstModuleByType(osType).get().getId();
return ds.findFirstModuleByType(osType).orElseThrow(NoSuchElementException::new).getId();
}
protected Action prepareFinishedUpdate() {
@@ -386,7 +384,7 @@ public abstract class AbstractIntegrationTest {
}
private static String artifactDirectory = createTempDir();
private static final String ARTIFACT_DIRECTORY = createTempDir();
private static String createTempDir() {
try {
@@ -398,9 +396,9 @@ public abstract class AbstractIntegrationTest {
@AfterEach
public void cleanUp() {
if (new File(artifactDirectory).exists()) {
if (new File(ARTIFACT_DIRECTORY).exists()) {
try {
FileUtils.cleanDirectory(new File(artifactDirectory));
FileUtils.cleanDirectory(new File(ARTIFACT_DIRECTORY));
} catch (final IOException | IllegalArgumentException e) {
LOG.warn("Cannot cleanup file-directory", e);
}
@@ -409,14 +407,14 @@ public abstract class AbstractIntegrationTest {
@BeforeAll
public static void beforeClass() {
System.setProperty("org.eclipse.hawkbit.repository.file.path", artifactDirectory);
System.setProperty("org.eclipse.hawkbit.repository.file.path", ARTIFACT_DIRECTORY);
}
@AfterAll
public static void afterClass() {
if (new File(artifactDirectory).exists()) {
if (new File(ARTIFACT_DIRECTORY).exists()) {
try {
FileUtils.deleteDirectory(new File(artifactDirectory));
FileUtils.deleteDirectory(new File(ARTIFACT_DIRECTORY));
} catch (final IOException | IllegalArgumentException e) {
LOG.warn("Cannot delete file-directory", e);
}
@@ -449,20 +447,6 @@ public abstract class AbstractIntegrationTest {
return currentTime.getOffset().getId().replace("Z", "+00:00");
}
protected static String generateRandomStringWithLength(final int length) {
final StringBuilder randomStringBuilder = new StringBuilder(length);
final Random rand = new Random();
final int lowercaseACode = 97;
final int lowercaseZCode = 122;
for (int i = 0; i < length; i++) {
final char randomCharacter = (char) (rand.nextInt(lowercaseZCode - lowercaseACode + 1) + lowercaseACode);
randomStringBuilder.append(randomCharacter);
}
return randomStringBuilder.toString();
}
protected static Action getFirstAssignedAction(
final DistributionSetAssignmentResult distributionSetAssignmentResult) {
return distributionSetAssignmentResult.getAssignedEntity().stream().findFirst()

View File

@@ -0,0 +1,44 @@
/**
* Copyright (c) 2022 Bosch.IO GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.test.util;
import java.util.Random;
import org.eclipse.hawkbit.repository.model.Target;
public class TargetTestData {
public static final String ATTRIBUTE_KEY_TOO_LONG;
public static final String ATTRIBUTE_KEY_VALID;
public static final String ATTRIBUTE_VALUE_TOO_LONG;
public static final String ATTRIBUTE_VALUE_VALID;
static {
final Random rand = new Random();
ATTRIBUTE_KEY_TOO_LONG = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_KEY_SIZE + 1, rand);
ATTRIBUTE_KEY_VALID = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_KEY_SIZE, rand);
ATTRIBUTE_VALUE_TOO_LONG = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE + 1, rand);
ATTRIBUTE_VALUE_VALID = generateRandomStringWithLength(Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE, rand);
}
private static String generateRandomStringWithLength(final int length, final Random rand) {
final StringBuilder randomStringBuilder = new StringBuilder(length);
final int lowercaseACode = 97;
final int lowercaseZCode = 122;
for (int i = 0; i < length; i++) {
final char randomCharacter = (char) (rand.nextInt(lowercaseZCode - lowercaseACode + 1) + lowercaseACode);
randomStringBuilder.append(randomCharacter);
}
return randomStringBuilder.toString();
}
private TargetTestData() {
// nothing to do here
}
}

View File

@@ -9,9 +9,7 @@
package org.eclipse.hawkbit.repository.test.util;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
@@ -29,6 +27,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
public class WithSpringAuthorityRule implements BeforeEachCallback, AfterEachCallback {
public static final String DEFAULT_TENANT = "default";
private SecurityContext oldContext;
@Override
@@ -64,7 +63,7 @@ public class WithSpringAuthorityRule implements BeforeEachCallback, AfterEachCal
@Override
public void setAuthentication(final Authentication authentication) {
// nothing todo
// nothing to do
}
@Override
@@ -85,35 +84,14 @@ public class WithSpringAuthorityRule implements BeforeEachCallback, AfterEachCal
}
private String[] getAllAuthorities(final String[] additionalAuthorities, final String[] notInclude) {
final List<String> allPermissions = new ArrayList<>();
final Field[] declaredFields = SpPermission.class.getDeclaredFields();
for (final Field field : declaredFields) {
if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) {
field.setAccessible(true);
try {
boolean addPermission = true;
final String permissionName = (String) field.get(null);
if (notInclude != null) {
for (final String notInlcudePerm : notInclude) {
if (permissionName.equals(notInlcudePerm)) {
addPermission = false;
break;
}
}
}
if (addPermission) {
allPermissions.add(permissionName);
}
// don't want to log this exceptions.
} catch (@SuppressWarnings("squid:S1166") IllegalArgumentException | IllegalAccessException e) {
// nope
}
}
final List<String> permissions = SpPermission.getAllAuthorities();
if (notInclude != null) {
permissions.removeAll(Arrays.asList(notInclude));
}
for (final String authority : additionalAuthorities) {
allPermissions.add(authority);
if (additionalAuthorities != null) {
permissions.addAll(Arrays.asList(additionalAuthorities));
}
return allPermissions.toArray(new String[allPermissions.size()]);
return permissions.toArray(new String[0]);
}
});
}
@@ -146,23 +124,23 @@ public class WithSpringAuthorityRule implements BeforeEachCallback, AfterEachCal
}
public static WithUser withController(final String principal, final String... authorities) {
return withUserAndTenant(principal, "default", true, true, true, authorities);
return withUserAndTenant(principal, DEFAULT_TENANT, true, true, true, authorities);
}
public static WithUser withUser(final String principal, final String... authorities) {
return withUserAndTenant(principal, "default", true, true, false, authorities);
return withUserAndTenant(principal, DEFAULT_TENANT, true, true, false, authorities);
}
public static WithUser withUser(final String principal, final boolean allSpPermision, final String... authorities) {
return withUserAndTenant(principal, "default", true, allSpPermision, false, authorities);
return withUserAndTenant(principal, DEFAULT_TENANT, true, allSpPermision, false, authorities);
}
public static WithUser withUser(final boolean autoCreateTenant) {
return withUserAndTenant("bumlux", "default", autoCreateTenant, true, false, new String[] {});
return withUserAndTenant("bumlux", DEFAULT_TENANT, autoCreateTenant, true, false);
}
public static WithUser withUserAndTenant(final String principal, final String tenant, final String... authorities) {
return withUserAndTenant(principal, tenant, true, true, false, new String[] {});
return withUserAndTenant(principal, tenant, true, true, false, authorities);
}
public static WithUser withUserAndTenant(final String principal, final String tenant,
@@ -172,8 +150,7 @@ public class WithSpringAuthorityRule implements BeforeEachCallback, AfterEachCal
}
private static WithUser privilegedUser() {
return createWithUser("bumlux", "default", true, true, false,
new String[] { "ROLE_CONTROLLER", "ROLE_SYSTEM_CODE" });
return createWithUser("bumlux", DEFAULT_TENANT, true, true, false, "ROLE_CONTROLLER", "ROLE_SYSTEM_CODE");
}
private static WithUser createWithUser(final String principal, final String tenant, final boolean autoCreateTenant,