Make some test timeouts (await) configurable (#2525)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2025-07-02 12:45:26 +03:00
committed by GitHub
parent bdbc658ea9
commit 8c6d56f177
77 changed files with 188 additions and 211 deletions

View File

@@ -93,10 +93,7 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio
} }
protected <T> T waitUntilIsPresent(final Callable<Optional<T>> callable) { protected <T> T waitUntilIsPresent(final Callable<Optional<T>> callable) {
await().until(() -> SecurityContextSwitch.runAsPrivileged(() -> callable.call().isPresent()));
createConditionFactory()
.until(() -> SecurityContextSwitch.runAsPrivileged(() -> callable.call().isPresent()));
try { try {
return SecurityContextSwitch.runAsPrivileged(() -> callable.call().get()); return SecurityContextSwitch.runAsPrivileged(() -> callable.call().get());
} catch (final Exception e) { } catch (final Exception e) {
@@ -105,8 +102,8 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio
} }
protected void waitUntilEventMessagesAreDispatchedToTarget(final EventTopic... eventTopics) { protected void waitUntilEventMessagesAreDispatchedToTarget(final EventTopic... eventTopics) {
createConditionFactory().untilAsserted(() -> assertThat(replyToListener.getLatestEventMessageTopics()) await().untilAsserted(() ->
.containsExactlyInAnyOrderElementsOf(Arrays.asList(eventTopics))); assertThat(replyToListener.getLatestEventMessageTopics()).containsExactlyInAnyOrderElementsOf(Arrays.asList(eventTopics)));
replyToListener.resetLatestEventMessageTopics(); replyToListener.resetLatestEventMessageTopics();
} }
@@ -188,8 +185,8 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio
} }
protected void assertDmfDownloadAndUpdateRequest(final DmfDownloadAndUpdateRequest request, protected void assertDmfDownloadAndUpdateRequest(
final Set<SoftwareModule> softwareModules, final String controllerId) { final DmfDownloadAndUpdateRequest request, final Set<SoftwareModule> softwareModules, final String controllerId) {
assertSoftwareModules(softwareModules, request.getSoftwareModules()); assertSoftwareModules(softwareModules, request.getSoftwareModules());
final Target updatedTarget = waitUntilIsPresent(() -> targetManagement.getByControllerID(controllerId)); final Target updatedTarget = waitUntilIsPresent(() -> targetManagement.getByControllerID(controllerId));
assertThat(updatedTarget).isNotNull(); assertThat(updatedTarget).isNotNull();
@@ -217,8 +214,7 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio
} }
protected void verifyReplyToListener() { protected void verifyReplyToListener() {
createConditionFactory() await().untilAsserted(() -> Mockito.verify(replyToListener, Mockito.atLeast(1)).handleMessage(Mockito.any()));
.untilAsserted(() -> Mockito.verify(replyToListener, Mockito.atLeast(1)).handleMessage(Mockito.any()));
} }
protected Long cancelAction(final Long actionId, final String controllerId) { protected Long cancelAction(final Long actionId, final String controllerId) {
@@ -369,8 +365,7 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio
protected void assertUpdateAttributes(final String controllerId, final Map<String, String> attributes) { protected void assertUpdateAttributes(final String controllerId, final Map<String, String> attributes) {
waitUntilIsPresent(() -> controllerManagement.getByControllerId(controllerId)); waitUntilIsPresent(() -> controllerManagement.getByControllerId(controllerId));
await().untilAsserted(() -> {
createConditionFactory().untilAsserted(() -> {
try { try {
final Map<String, String> controllerAttributes = SecurityContextSwitch.runAsPrivileged( final Map<String, String> controllerAttributes = SecurityContextSwitch.runAsPrivileged(
() -> targetManagement.getControllerAttributes(controllerId)); () -> targetManagement.getControllerAttributes(controllerId));
@@ -416,16 +411,14 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio
assertConfirmRequest(confirmRequest, dsModules, controllerId); assertConfirmRequest(confirmRequest, dsModules, controllerId);
} }
protected void assertConfirmRequest(final DmfConfirmRequest request, final Set<SoftwareModule> softwareModules, protected void assertConfirmRequest(final DmfConfirmRequest request, final Set<SoftwareModule> softwareModules, final String controllerId) {
final String controllerId) {
assertSoftwareModules(softwareModules, request.getSoftwareModules()); assertSoftwareModules(softwareModules, request.getSoftwareModules());
final Target updatedTarget = waitUntilIsPresent(() -> targetManagement.getByControllerID(controllerId)); final Target updatedTarget = waitUntilIsPresent(() -> targetManagement.getByControllerID(controllerId));
assertThat(updatedTarget).isNotNull(); assertThat(updatedTarget).isNotNull();
assertThat(updatedTarget.getSecurityToken()).isEqualTo(request.getTargetSecurityToken()); assertThat(updatedTarget.getSecurityToken()).isEqualTo(request.getTargetSecurityToken());
} }
private void assertAssignmentMessage(final Set<SoftwareModule> dsModules, final String controllerId, private void assertAssignmentMessage(final Set<SoftwareModule> dsModules, final String controllerId, final EventTopic topic) {
final EventTopic topic) {
final Message replyMessage = assertReplyMessageHeader(topic, controllerId); final Message replyMessage = assertReplyMessageHeader(topic, controllerId);
assertAllTargetsCount(1); assertAllTargetsCount(1);
@@ -435,7 +428,8 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio
assertDmfDownloadAndUpdateRequest(downloadAndUpdateRequest, dsModules, controllerId); assertDmfDownloadAndUpdateRequest(downloadAndUpdateRequest, dsModules, controllerId);
} }
private void registerAndAssertTargetWithExistingTenant(final String controllerId, final String name, private void registerAndAssertTargetWithExistingTenant(
final String controllerId, final String name,
final int existingTargetsAfterCreation, final TargetUpdateStatus expectedTargetStatus, final int existingTargetsAfterCreation, final TargetUpdateStatus expectedTargetStatus,
final String createdBy, final Map<String, String> attributes, final String createdBy, final Map<String, String> attributes,
final Callable<Optional<Target>> fetchTarget) { final Callable<Optional<Target>> fetchTarget) {
@@ -443,8 +437,9 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio
final Target registeredTarget = waitUntilIsPresent(fetchTarget::call); final Target registeredTarget = waitUntilIsPresent(fetchTarget::call);
assertAllTargetsCount(existingTargetsAfterCreation); assertAllTargetsCount(existingTargetsAfterCreation);
assertThat(registeredTarget).isNotNull(); assertThat(registeredTarget).isNotNull();
assertTarget(registeredTarget, name != null ? name : controllerId, expectedTargetStatus, createdBy, assertTarget(
attributes != null ? attributes : Collections.emptyMap()); registeredTarget, name != null ? name : controllerId, expectedTargetStatus,
createdBy, attributes != null ? attributes : Collections.emptyMap());
} }
private Optional<Target> findTargetBasedOnNewVersion(final String controllerId, final int version) { private Optional<Target> findTargetBasedOnNewVersion(final String controllerId, final int version) {
@@ -455,7 +450,8 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio
return Optional.empty(); return Optional.empty();
} }
private void assertTarget(final Target target, final String name, final TargetUpdateStatus updateStatus, private void assertTarget(
final Target target, final String name, final TargetUpdateStatus updateStatus,
final String createdBy, final Map<String, String> attributes) { final String createdBy, final Map<String, String> attributes) {
assertThat(target.getTenant()).isEqualTo(TENANT_EXIST); assertThat(target.getTenant()).isEqualTo(TENANT_EXIST);
assertThat(target.getName()).isEqualTo(name); assertThat(target.getName()).isEqualTo(name);
@@ -463,9 +459,7 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio
assertThat(target.getDescription()).contains(target.getControllerId()); assertThat(target.getDescription()).contains(target.getControllerId());
assertThat(target.getCreatedBy()).isEqualTo(createdBy); assertThat(target.getCreatedBy()).isEqualTo(createdBy);
assertThat(target.getUpdateStatus()).isEqualTo(updateStatus); assertThat(target.getUpdateStatus()).isEqualTo(updateStatus);
assertThat(target.getAddress()) assertThat(target.getAddress()).isEqualTo(IpUtil.createAmqpUri(getVirtualHost(), DmfTestConfiguration.REPLY_TO_EXCHANGE));
.isEqualTo(IpUtil.createAmqpUri(getVirtualHost(), DmfTestConfiguration.REPLY_TO_EXCHANGE));
assertThat(targetManagement.getControllerAttributes(target.getControllerId())).isEqualTo(attributes); assertThat(targetManagement.getControllerAttributes(target.getControllerId())).isEqualTo(attributes);
} }
} }

View File

@@ -794,7 +794,7 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
} }
private void waitUntil(final Callable<Boolean> callable) { private void waitUntil(final Callable<Boolean> callable) {
createConditionFactory().until(() -> SecurityContextSwitch.runAsPrivileged(callable)); await().until(() -> SecurityContextSwitch.runAsPrivileged(callable));
} }
private void assertLatestMultiActionMessageContainsInstallMessages(final String controllerId, private void assertLatestMultiActionMessageContainsInstallMessages(final String controllerId,

View File

@@ -1229,26 +1229,22 @@ class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegr
} }
private void assertAction(final Long actionId, final int messages, final Status... expectedActionStates) { private void assertAction(final Long actionId, final int messages, final Status... expectedActionStates) {
createConditionFactory().await().untilAsserted(() -> { await().untilAsserted(() -> {
try { try {
SecurityContextSwitch.runAsPrivileged(() -> { SecurityContextSwitch.runAsPrivileged(() -> {
final List<ActionStatus> actionStatusList = deploymentManagement final List<ActionStatus> actionStatusList = deploymentManagement.findActionStatusByAction(actionId, PAGE).getContent();
.findActionStatusByAction(actionId, PAGE).getContent();
// Check correlation ID // Check correlation ID
final List<String> messagesFromServer = actionStatusList.stream() final List<String> messagesFromServer = actionStatusList.stream()
.flatMap(actionStatus -> deploymentManagement .flatMap(actionStatus -> deploymentManagement
.findMessagesByActionStatusId(actionStatus.getId(), PAGE).getContent().stream()) .findMessagesByActionStatusId(actionStatus.getId(), PAGE).getContent().stream())
.filter(Objects::nonNull) .filter(Objects::nonNull)
.filter(message -> message .filter(message -> message.startsWith(RepositoryConstants.SERVER_MESSAGE_PREFIX + "DMF message"))
.startsWith(RepositoryConstants.SERVER_MESSAGE_PREFIX + "DMF message"))
.toList(); .toList();
assertThat(messagesFromServer).hasSize(messages) assertThat(messagesFromServer).hasSize(messages).allMatch(message -> message.endsWith(CORRELATION_ID));
.allMatch(message -> message.endsWith(CORRELATION_ID));
final List<Status> status = actionStatusList.stream().map(ActionStatus::getStatus) final List<Status> status = actionStatusList.stream().map(ActionStatus::getStatus).toList();
.toList();
assertThat(status).containsOnly(expectedActionStates); assertThat(status).containsOnly(expectedActionStates);
return null; return null;
@@ -1267,7 +1263,7 @@ class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegr
private void assertActionStatusList(final Long actionId, final int statusListCount, private void assertActionStatusList(final Long actionId, final int statusListCount,
final Status... expectedActionStates) { final Status... expectedActionStates) {
createConditionFactory().await().untilAsserted(() -> { await().untilAsserted(() -> {
try { try {
SecurityContextSwitch.runAsPrivileged(() -> { SecurityContextSwitch.runAsPrivileged(() -> {
final List<ActionStatus> actionStatusList = deploymentManagement final List<ActionStatus> actionStatusList = deploymentManagement
@@ -1302,8 +1298,8 @@ class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegr
private void verifyNumberOfDeadLetterMessages(final int numberOfInvocations) { private void verifyNumberOfDeadLetterMessages(final int numberOfInvocations) {
assertEmptyReceiverQueueCount(); assertEmptyReceiverQueueCount();
createConditionFactory().untilAsserted(() -> Mockito await().untilAsserted(
.verify(getDeadletterListener(), Mockito.times(numberOfInvocations)).handleMessage(Mockito.any())); () -> Mockito.verify(getDeadletterListener(), Mockito.times(numberOfInvocations)).handleMessage(Mockito.any()));
Mockito.reset(getDeadletterListener()); Mockito.reset(getDeadletterListener());
} }
} }

View File

@@ -40,8 +40,6 @@ import org.springframework.test.context.ContextConfiguration;
@SuppressWarnings("java:S6813") // constructor injects are not possible for test classes @SuppressWarnings("java:S6813") // constructor injects are not possible for test classes
public abstract class AbstractAmqpIntegrationTest extends AbstractIntegrationTest { public abstract class AbstractAmqpIntegrationTest extends AbstractIntegrationTest {
private static final Duration TIMEOUT = Duration.ofSeconds(5);
@Autowired @Autowired
private ConnectionFactory connectionFactory; private ConnectionFactory connectionFactory;
@Autowired @Autowired
@@ -60,8 +58,11 @@ public abstract class AbstractAmqpIntegrationTest extends AbstractIntegrationTes
return dmfClient; return dmfClient;
} }
protected ConditionFactory createConditionFactory() { private static final Duration AT_LEAST = Duration.ofMillis(Integer.getInteger("hawkbit.it.amqp.await.atLeastMs", 100));
return Awaitility.await().atMost(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS); private static final Duration POLL_INTERVAL = Duration.ofMillis(Integer.getInteger("hawkbit.it.amqp.await.pollIntervalMs", 200));
private static final Duration TIMEOUT = Duration.ofMillis(Integer.getInteger("hawkbit.it.amqp.await.timeoutMs", 5000));
protected ConditionFactory await() {
return Awaitility.await().atLeast(AT_LEAST).pollInterval(POLL_INTERVAL).atMost(TIMEOUT);
} }
protected Message createMessage(final Object payload, final MessageProperties messageProperties) { protected Message createMessage(final Object payload, final MessageProperties messageProperties) {

View File

@@ -19,14 +19,11 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.time.Duration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
import org.awaitility.Awaitility;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtActionRestApi; import org.eclipse.hawkbit.mgmt.rest.api.MgmtActionRestApi;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRepresentationMode; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRepresentationMode;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
@@ -82,7 +79,6 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
*/ */
@Test @Test
void filterActionsByStatus() throws Exception { void filterActionsByStatus() throws Exception {
// prepare test // prepare test
final DistributionSet dsA = testdataFactory.createDistributionSet(""); final DistributionSet dsA = testdataFactory.createDistributionSet("");
assignDistributionSet(dsA, Collections.singletonList(testdataFactory.createTarget("knownTargetId"))); assignDistributionSet(dsA, Collections.singletonList(testdataFactory.createTarget("knownTargetId")));
@@ -217,8 +213,7 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
controllerManagement.addUpdateActionStatus(entityFactory.actionStatus().create(action.getId()).code(200) controllerManagement.addUpdateActionStatus(entityFactory.actionStatus().create(action.getId()).code(200)
.message("Update succeeded").status(Status.FINISHED)); .message("Update succeeded").status(Status.FINISHED));
// verify that one result is returned if the actions are filtered for // verify that one result is returned if the actions are filtered for status code 200
// status code 200
final String rsqlStatusCode = "lastStatusCode==200"; final String rsqlStatusCode = "lastStatusCode==200";
mvc.perform(get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING + "?q=" + rsqlStatusCode)) mvc.perform(get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING + "?q=" + rsqlStatusCode))
.andDo(MockMvcResultPrinter.print()) .andDo(MockMvcResultPrinter.print())
@@ -227,8 +222,7 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
.andExpect(jsonPath("size", equalTo(1))) .andExpect(jsonPath("size", equalTo(1)))
.andExpect(jsonPath("content[0].status", equalTo("finished"))); .andExpect(jsonPath("content[0].status", equalTo("finished")));
// verify no result is returned if we filter for a non-existing status // verify no result is returned if we filter for a non-existing status code
// code
final String rsqlWrongStatusCode = "lastStatusCode==999"; final String rsqlWrongStatusCode = "lastStatusCode==999";
mvc.perform(get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING + "?q=" + rsqlWrongStatusCode)) mvc.perform(get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING + "?q=" + rsqlWrongStatusCode))
.andDo(MockMvcResultPrinter.print()) .andDo(MockMvcResultPrinter.print())
@@ -298,8 +292,8 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
// rollout // rollout
final Target target1 = testdataFactory.createTarget("t1"); final Target target1 = testdataFactory.createTarget("t1");
final Rollout rollout = testdataFactory.createRolloutByVariables("TestRollout", "TestDesc", 1, final Rollout rollout = testdataFactory.createRolloutByVariables(
"name==" + target1.getName(), ds, "50", "5"); "TestRollout", "TestDesc", 1, "name==" + target1.getName(), ds, "50", "5");
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
rolloutHandler.handleAll(); rolloutHandler.handleAll();
@@ -517,8 +511,8 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
} }
private static String generateActionLink(final String targetId, final Long actionId) { private static String generateActionLink(final String targetId, final Long actionId) {
return "http://localhost" + MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + targetId + "/" + return "http://localhost" + MgmtRestConstants.TARGET_V1_REQUEST_MAPPING +
MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId; "/" + targetId + "/" + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId;
} }
private static String generateTargetLink(final String targetId) { private static String generateTargetLink(final String targetId) {
@@ -526,8 +520,7 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
} }
private static String generateDistributionSetLink(final Action action) { private static String generateDistributionSetLink(final Action action) {
return "http://localhost" + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" return "http://localhost" + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + action.getDistributionSet().getId();
+ action.getDistributionSet().getId();
} }
private void verifyResultsByTargetPropertyFilter(final Target target, final DistributionSet ds, final String rsqlTargetFilter) private void verifyResultsByTargetPropertyFilter(final Target target, final DistributionSet ds, final String rsqlTargetFilter)
@@ -598,13 +591,12 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
final DistributionSet ds = testdataFactory.createDistributionSet(); final DistributionSet ds = testdataFactory.createDistributionSet();
// rollout // rollout
final Target target = testdataFactory.createTarget(knownTargetId); final Target target = testdataFactory.createTarget(knownTargetId);
final Rollout rollout = testdataFactory.createRolloutByVariables("TestRollout", "TestDesc", 1, final Rollout rollout = testdataFactory.createRolloutByVariables(
"name==" + target.getName(), ds, "50", "5"); "TestRollout", "TestDesc", 1, "name==" + target.getName(), ds, "50", "5");
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
rolloutHandler.handleAll(); rolloutHandler.handleAll();
final List<Action> actions = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE) final List<Action> actions = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).getContent();
.getContent();
assertThat(actions).hasSize(1); assertThat(actions).hasSize(1);
final String externalRef = "externalRef#123"; final String externalRef = "externalRef#123";
if (withExternalRef) { if (withExternalRef) {
@@ -625,8 +617,8 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
return generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(knownTargetId, null, null, null); return generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(knownTargetId, null, null, null);
} }
private List<Action> generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(final String knownTargetId, private List<Action> generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(
final String schedule, final String duration, final String timezone) { final String knownTargetId, final String schedule, final String duration, final String timezone) {
final Target target = testdataFactory.createTarget(knownTargetId); final Target target = testdataFactory.createTarget(knownTargetId);
final Iterator<DistributionSet> sets = testdataFactory.createDistributionSets(2).iterator(); final Iterator<DistributionSet> sets = testdataFactory.createDistributionSets(2).iterator();
@@ -639,26 +631,22 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
.getAssignedEntity().stream().map(Action::getTarget).toList(); .getAssignedEntity().stream().map(Action::getTarget).toList();
// 2nd update // 2nd update
// sleep 10ms to ensure that we can sort by reportedAt // sleep 10ms to ensure that we can sort by reportedAt
Awaitility.await().atMost(Duration.ofMillis(100)).atLeast(5, TimeUnit.MILLISECONDS) await().until(() -> updatedTargets.stream().allMatch(t -> t.getLastModifiedAt() > 0L));
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(() -> updatedTargets.stream().allMatch(t -> t.getLastModifiedAt() > 0L));
assignDistributionSet(two, updatedTargets); assignDistributionSet(two, updatedTargets);
} else { } else {
final List<Target> updatedTargets = assignDistributionSetWithMaintenanceWindow(one.getId(), final List<Target> updatedTargets =
target.getControllerId(), schedule, duration, timezone).getAssignedEntity().stream() assignDistributionSetWithMaintenanceWindow(one.getId(), target.getControllerId(), schedule, duration, timezone)
.map(Action::getTarget).toList(); .getAssignedEntity().stream()
.map(Action::getTarget)
.toList();
// 2nd update // 2nd update
// sleep 10ms to ensure that we can sort by reportedAt // sleep 10ms to ensure that we can sort by reportedAt
Awaitility.await().atMost(Duration.ofMillis(100)).atLeast(5, TimeUnit.MILLISECONDS) await().until(() -> updatedTargets.stream().allMatch(t -> t.getLastModifiedAt() > 0L));
.pollInterval(10, TimeUnit.MILLISECONDS) assignDistributionSetWithMaintenanceWindow(two.getId(), updatedTargets.get(0).getControllerId(), schedule, duration, timezone);
.until(() -> updatedTargets.stream().allMatch(t -> t.getLastModifiedAt() > 0L));
assignDistributionSetWithMaintenanceWindow(two.getId(), updatedTargets.get(0).getControllerId(), schedule,
duration, timezone);
} }
// two updates, one cancellation // two updates, one cancellation
final List<Action> actions = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE) final List<Action> actions = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).getContent();
.getContent();
assertThat(actions).hasSize(2); assertThat(actions).hasSize(2);
return actions; return actions;

View File

@@ -34,8 +34,8 @@ import java.util.Optional;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.awaitility.Awaitility; import org.awaitility.Awaitility;
import org.awaitility.core.ConditionFactory;
import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.mgmt.rest.resource.mapper.MgmtRestModelMapper; import org.eclipse.hawkbit.mgmt.rest.resource.mapper.MgmtRestModelMapper;
import org.eclipse.hawkbit.repository.RolloutGroupManagement; import org.eclipse.hawkbit.repository.RolloutGroupManagement;
@@ -1911,21 +1911,24 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
} }
private void awaitRunningState(final Long rolloutId) { private void awaitRunningState(final Long rolloutId) {
Awaitility.await().atMost(Duration.ofMinutes(1)).pollInterval(Duration.ofMillis(100)).with() awaitRollout().until(() -> SecurityContextSwitch
.until(() -> SecurityContextSwitch .runAsPrivileged(() -> rolloutManagement.get(rolloutId).orElseThrow(NoSuchElementException::new))
.runAsPrivileged(
() -> rolloutManagement.get(rolloutId).orElseThrow(NoSuchElementException::new))
.getStatus().equals(RolloutStatus.RUNNING)); .getStatus().equals(RolloutStatus.RUNNING));
} }
private void awaitActionStatus(final Long actionId, final Status status) { private void awaitActionStatus(final Long actionId, final Status status) {
Awaitility.await().atMost(Duration.ofMinutes(1)).pollInterval(Duration.ofMillis(100)).with() awaitRollout().until(() -> SecurityContextSwitch
.until(() -> SecurityContextSwitch .runAsPrivileged(() -> deploymentManagement.findAction(actionId).orElseThrow(NoSuchElementException::new))
.runAsPrivileged(
() -> deploymentManagement.findAction(actionId).orElseThrow(NoSuchElementException::new))
.getStatus().equals(status)); .getStatus().equals(status));
} }
private static final Duration ROLLOUT_AT_LEAST = Duration.ofMillis(Integer.getInteger("hawkbit.it.rest.await.rolloutAtLeastMs", 50));
private static final Duration ROLLOUT_POLL_INTERVAL = Duration.ofMillis(Integer.getInteger("hawkbit.it.rest.await.rolloutPollIntervalMs", 100));
private static final Duration ROLLOUT_TIMEOUT = Duration.ofMillis(Integer.getInteger("hawkbit.it.rest.await.rolloutTimeoutMs", 60_000));
private ConditionFactory awaitRollout() {
return Awaitility.await().atLeast(ROLLOUT_AT_LEAST).pollInterval(ROLLOUT_POLL_INTERVAL).atMost(ROLLOUT_TIMEOUT);
}
private void assertStatusIs(final Rollout rollout, final RolloutStatus expected) { private void assertStatusIs(final Rollout rollout, final RolloutStatus expected) {
final Optional<Rollout> updatedRollout = rolloutManagement.get(rollout.getId()); final Optional<Rollout> updatedRollout = rolloutManagement.get(rollout.getId());
assertThat(updatedRollout).get().extracting(Rollout::getStatus).isEqualTo(expected); assertThat(updatedRollout).get().extracting(Rollout::getStatus).isEqualTo(expected);

View File

@@ -32,16 +32,13 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.time.Duration;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.TimeUnit;
import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.JsonPath;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.awaitility.Awaitility;
import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact; import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRepresentationMode; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRepresentationMode;
@@ -249,10 +246,7 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes
.toString(); .toString();
// ensures that we are not to fast so that last modified is not set correctly // ensures that we are not to fast so that last modified is not set correctly
Awaitility.await() await().until(() -> sm.getLastModifiedAt() > 0L && sm.getLastModifiedBy() != null);
.atMost(Duration.ofMillis(100))
.pollInterval(10L, TimeUnit.MILLISECONDS)
.until(() -> sm.getLastModifiedAt() > 0L && sm.getLastModifiedBy() != null);
mvc.perform(put("/rest/v1/softwaremodules/{smId}", sm.getId()).content(body) mvc.perform(put("/rest/v1/softwaremodules/{smId}", sm.getId()).content(body)
.contentType(MediaType.APPLICATION_JSON)) .contentType(MediaType.APPLICATION_JSON))
@@ -292,10 +286,7 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes
final String body = new JSONObject().put("deleted", true).toString(); final String body = new JSONObject().put("deleted", true).toString();
// ensures that we are not to fast so that last modified is not set correctly // ensures that we are not to fast so that last modified is not set correctly
Awaitility.await() await().until(() -> sm.getLastModifiedAt() > 0L && sm.getLastModifiedBy() != null);
.atMost(Duration.ofMillis(100))
.pollInterval(10L, TimeUnit.MILLISECONDS)
.until(() -> sm.getLastModifiedAt() > 0L && sm.getLastModifiedBy() != null);
mvc.perform(put("/rest/v1/softwaremodules/{smId}", sm.getId()).content(body) mvc.perform(put("/rest/v1/softwaremodules/{smId}", sm.getId()).content(body)
.contentType(MediaType.APPLICATION_JSON)) .contentType(MediaType.APPLICATION_JSON))
@@ -323,10 +314,7 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes
entityFactory.softwareModule().create().type(osType).name("name1").version("version1")); entityFactory.softwareModule().create().type(osType).name("name1").version("version1"));
assertThat(sm.isLocked()).as("Created software module should not be locked").isFalse(); assertThat(sm.isLocked()).as("Created software module should not be locked").isFalse();
// ensures that we are not to fast so that last modified is not set correctly // ensures that we are not to fast so that last modified is not set correctly
Awaitility.await() await().until(() -> sm.getLastModifiedAt() > 0L && sm.getLastModifiedBy() != null);
.atMost(Duration.ofMillis(100))
.pollInterval(10L, TimeUnit.MILLISECONDS)
.until(() -> sm.getLastModifiedAt() > 0L && sm.getLastModifiedBy() != null);
// lock // lock
final String body = new JSONObject().put("locked", true).toString(); final String body = new JSONObject().put("locked", true).toString();
@@ -361,10 +349,7 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes
.as("Software module is locked") .as("Software module is locked")
.isTrue(); .isTrue();
// ensures that we are not to fast so that last modified is not set correctly // ensures that we are not to fast so that last modified is not set correctly
Awaitility.await() await().until(() -> sm.getLastModifiedAt() > 0L && sm.getLastModifiedBy() != null);
.atMost(Duration.ofMillis(100))
.pollInterval(10L, TimeUnit.MILLISECONDS)
.until(() -> sm.getLastModifiedAt() > 0L && sm.getLastModifiedBy() != null);
// unlock // unlock
final String body = new JSONObject().put("locked", false).toString(); final String body = new JSONObject().put("locked", false).toString();

View File

@@ -30,7 +30,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.time.Duration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@@ -40,14 +39,12 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream; import java.util.stream.Stream;
import jakarta.validation.ConstraintViolationException; import jakarta.validation.ConstraintViolationException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.JsonPath;
import org.awaitility.Awaitility;
import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.mgmt.json.model.action.MgmtActionConfirmationRequestBodyPut; import org.eclipse.hawkbit.mgmt.json.model.action.MgmtActionConfirmationRequestBodyPut;
@@ -2971,9 +2968,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
.getAssignedEntity().stream().map(Action::getTarget).toList(); .getAssignedEntity().stream().map(Action::getTarget).toList();
// 2nd update // 2nd update
// sleep 10ms to ensure that we can sort by reportedAt // sleep 10ms to ensure that we can sort by reportedAt
Awaitility.await().atMost(Duration.ofMillis(100)).atLeast(5, TimeUnit.MILLISECONDS) await().until(() -> updatedTargets.stream().allMatch(t -> t.getLastModifiedAt() > 0L));
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(() -> updatedTargets.stream().allMatch(t -> t.getLastModifiedAt() > 0L));
assignDistributionSet(two, updatedTargets); assignDistributionSet(two, updatedTargets);
} else { } else {
final List<Target> updatedTargets = assignDistributionSetWithMaintenanceWindow(one.getId(), final List<Target> updatedTargets = assignDistributionSetWithMaintenanceWindow(one.getId(),
@@ -2981,9 +2976,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
.map(Action::getTarget).toList(); .map(Action::getTarget).toList();
// 2nd update // 2nd update
// sleep 10ms to ensure that we can sort by reportedAt // sleep 10ms to ensure that we can sort by reportedAt
Awaitility.await().atMost(Duration.ofMillis(100)).atLeast(5, TimeUnit.MILLISECONDS) await().until(() -> updatedTargets.stream().allMatch(t -> t.getLastModifiedAt() > 0L));
.pollInterval(10, TimeUnit.MILLISECONDS)
.until(() -> updatedTargets.stream().allMatch(t -> t.getLastModifiedAt() > 0L));
assignDistributionSetWithMaintenanceWindow(two.getId(), updatedTargets.get(0).getControllerId(), schedule, assignDistributionSetWithMaintenanceWindow(two.getId(), updatedTargets.get(0).getControllerId(), schedule,
duration, timezone); duration, timezone);
} }

View File

@@ -67,12 +67,14 @@ class ConcurrentDistributionSetInvalidationTest extends AbstractJpaIntegrationTe
return 0; return 0;
}, tenant)).start(); }, tenant)).start();
// wait until at least one RolloutGroup is created, as this means that // wait until at least one RolloutGroup is created, as this means that the thread has started and has acquired the lock
// the thread has started and has acquired the lock Awaitility.await()
Awaitility.await().atMost(Duration.ofSeconds(5))
.pollInterval(Duration.ofMillis(100)) .pollInterval(Duration.ofMillis(100))
.until(() -> tenantAware.runAsTenant(tenant, () -> systemSecurityContext .atMost(Duration.ofSeconds(5))
.runAsSystem(() -> rolloutGroupManagement.findByRollout(rollout.getId(), PAGE).getSize() > 0))); .until(() -> tenantAware.runAsTenant(
tenant,
() -> systemSecurityContext.runAsSystem(
() -> rolloutGroupManagement.findByRollout(rollout.getId(), PAGE).getSize() > 0)));
final DistributionSetInvalidation distributionSetInvalidation = new DistributionSetInvalidation( final DistributionSetInvalidation distributionSetInvalidation = new DistributionSetInvalidation(
Collections.singletonList(distributionSet.getId()), CancelationType.SOFT, true); Collections.singletonList(distributionSet.getId()), CancelationType.SOFT, true);

View File

@@ -48,7 +48,10 @@ class ActionTest extends AbstractJpaIntegrationTest {
assertThat(timeforcedAction.isForcedOrTimeForced()).isFalse(); assertThat(timeforcedAction.isForcedOrTimeForced()).isFalse();
// wait until timeforce time is hit // wait until timeforce time is hit
Awaitility.await().atMost(Duration.ofSeconds(2)).pollInterval(Duration.ofMillis(100)).until(timeforcedAction::isForcedOrTimeForced); Awaitility.await()
.pollInterval(Duration.ofMillis(100))
.atMost(Duration.ofSeconds(2))
.until(timeforcedAction::isForcedOrTimeForced);
} }
/** /**

View File

@@ -2497,7 +2497,9 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
} }
private void awaitRunningState(final Long myRolloutId) { private void awaitRunningState(final Long myRolloutId) {
Awaitility.await().atMost(Duration.ofSeconds(10)).pollInterval(Duration.ofMillis(500)).with() Awaitility.await()
.pollInterval(Duration.ofMillis(500))
.atMost(Duration.ofSeconds(10))
.until(() -> SecurityContextSwitch .until(() -> SecurityContextSwitch
.runAsPrivileged( .runAsPrivileged(
() -> rolloutManagement.get(myRolloutId).orElseThrow(NoSuchElementException::new)) () -> rolloutManagement.get(myRolloutId).orElseThrow(NoSuchElementException::new))

View File

@@ -17,6 +17,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.nio.file.Files; import java.nio.file.Files;
import java.time.Duration;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@@ -25,9 +26,10 @@ import java.util.NoSuchElementException;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.awaitility.Awaitility;
import org.awaitility.core.ConditionFactory;
import org.eclipse.hawkbit.artifact.repository.ArtifactRepository; import org.eclipse.hawkbit.artifact.repository.ArtifactRepository;
import org.eclipse.hawkbit.artifact.repository.ArtifactStoreException; import org.eclipse.hawkbit.artifact.repository.ArtifactStoreException;
import org.eclipse.hawkbit.cache.TenantAwareCacheManager;
import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.ConfirmationManagement; import org.eclipse.hawkbit.repository.ConfirmationManagement;
import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.ControllerManagement;
@@ -74,7 +76,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.bus.ServiceMatcher; import org.springframework.cloud.bus.ServiceMatcher;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.auditing.AuditingHandler;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
@@ -263,6 +264,14 @@ public abstract class AbstractIntegrationTest {
return currentTime.getOffset().getId().replace("Z", "+00:00"); return currentTime.getOffset().getId().replace("Z", "+00:00");
} }
private static final Duration AT_LEAST = Duration.ofMillis(Integer.getInteger("hawkbit.it.rest.await.atLeastMs", 5));
private static final Duration POLL_INTERVAL = Duration.ofMillis(Integer.getInteger("hawkbit.it.rest.await.pollIntervalMs", 10));
private static final Duration TIMEOUT = Duration.ofMillis(Integer.getInteger("hawkbit.it.rest.await.timeoutMs", 200));
// default wait condition factory
protected ConditionFactory await() {
return Awaitility.await().atLeast(AT_LEAST).pollInterval(POLL_INTERVAL).atMost(TIMEOUT);
}
protected static Action getFirstAssignedAction( protected static Action getFirstAssignedAction(
final DistributionSetAssignmentResult distributionSetAssignmentResult) { final DistributionSetAssignmentResult distributionSetAssignmentResult) {
return distributionSetAssignmentResult.getAssignedEntity().stream().findFirst() return distributionSetAssignmentResult.getAssignedEntity().stream().findFirst()

View File

@@ -9,6 +9,8 @@
*/ */
package org.eclipse.hawkbit.rest; package org.eclipse.hawkbit.rest;
import java.time.Duration;
import org.eclipse.hawkbit.repository.jpa.RepositoryApplicationConfiguration; import org.eclipse.hawkbit.repository.jpa.RepositoryApplicationConfiguration;
import org.eclipse.hawkbit.repository.test.TestConfiguration; import org.eclipse.hawkbit.repository.test.TestConfiguration;
import org.eclipse.hawkbit.repository.test.util.AbstractIntegrationTest; import org.eclipse.hawkbit.repository.test.util.AbstractIntegrationTest;

View File

@@ -44,7 +44,6 @@ import com.vaadin.flow.data.renderer.ComponentRenderer;
import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route; import com.vaadin.flow.router.Route;
import com.vaadin.flow.server.streams.UploadEvent; import com.vaadin.flow.server.streams.UploadEvent;
import com.vaadin.flow.server.streams.UploadHandler;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.mgmt.json.model.PagedList; import org.eclipse.hawkbit.mgmt.json.model.PagedList;
import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact; import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact;