Remove allure (phase2) (#2483)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2025-06-20 15:51:06 +03:00
committed by GitHub
parent 39593fc6b6
commit cb7f1107fe
406 changed files with 6993 additions and 5863 deletions

View File

@@ -30,9 +30,6 @@ import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.qameta.allure.Story;
import org.eclipse.hawkbit.ddi.rest.resource.DdiArtifactDownloadTest.DownloadTestConfiguration;
import org.eclipse.hawkbit.repository.event.remote.DownloadProgressEvent;
import org.eclipse.hawkbit.repository.model.Artifact;
@@ -53,9 +50,10 @@ import org.springframework.test.web.servlet.MvcResult;
/**
* Test artifact downloads from the controller.
* <p/>
* Feature: Component Tests - Direct Device Integration API<br/>
* Story: Artifact Download Resource
*/
@Feature("Component Tests - Direct Device Integration API")
@Story("Artifact Download Resource")
@SpringBootTest(classes = { DownloadTestConfiguration.class })
class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
@@ -69,9 +67,10 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
}
@Test
@Description("Tests non allowed requests on the artifact ressource, e.g. invalid URI, wrong if-match, wrong command.")
void invalidRequestsOnArtifactResource() throws Exception {
/**
* Tests non allowed requests on the artifact ressource, e.g. invalid URI, wrong if-match, wrong command.
*/
@Test void invalidRequestsOnArtifactResource() throws Exception {
// create target
final Target target = testdataFactory.createTarget();
final List<Target> targets = Collections.singletonList(target);
@@ -157,9 +156,11 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
.andExpect(status().isMethodNotAllowed());
}
/**
* Tests valid downloads through the artifact resource by identifying the artifact not by ID but file name.
*/
@Test
@WithUser(principal = "4712", authorities = "ROLE_CONTROLLER", allSpPermissions = true)
@Description("Tests valid downloads through the artifact resource by identifying the artifact not by ID but file name.")
void downloadArtifactThroughFileName() throws Exception {
downloadProgress = 1;
shippedBytes = 0;
@@ -203,9 +204,10 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
assertThat(shippedBytes).isEqualTo(artifactSize);
}
@Test
@Description("Tests valid MD5SUm file downloads through the artifact resource by identifying the artifact by ID.")
void downloadMd5sumThroughControllerApi() throws Exception {
/**
* Tests valid MD5SUm file downloads through the artifact resource by identifying the artifact by ID.
*/
@Test void downloadMd5sumThroughControllerApi() throws Exception {
// create target
final Target target = testdataFactory.createTarget();
@@ -233,9 +235,11 @@ class DdiArtifactDownloadTest extends AbstractDDiApiIntegrationTest {
.isEqualTo((artifact.getMd5Hash() + " " + artifact.getFilename()).getBytes(StandardCharsets.US_ASCII));
}
/**
* Test various HTTP range requests for artifact download, e.g. chunk download or download resume.
*/
@Test
@WithUser(principal = TestdataFactory.DEFAULT_CONTROLLER_ID, authorities = "ROLE_CONTROLLER", allSpPermissions = true)
@Description("Test various HTTP range requests for artifact download, e.g. chunk download or download resume.")
void rangeDownloadArtifact() throws Exception {
// create target
final Target target = testdataFactory.createTarget();

View File

@@ -25,9 +25,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.qameta.allure.Story;
import org.eclipse.hawkbit.ddi.json.model.DdiResult;
import org.eclipse.hawkbit.ddi.json.model.DdiStatus;
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
@@ -46,17 +43,19 @@ import org.springframework.integration.json.JsonPathUtils;
/**
* Test cancel action from the controller.
* <p/>
* Feature: Component Tests - Direct Device Integration API<br/>
* Story: Cancel Action Resource
*/
@Feature("Component Tests - Direct Device Integration API")
@Story("Cancel Action Resource")
class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
@Autowired
ActionStatusRepository actionStatusRepository;
@Test
@Description("Tests that the cancel action resource can be used with CBOR.")
void cancelActionCbor() throws Exception {
/**
* Tests that the cancel action resource can be used with CBOR.
*/
@Test void cancelActionCbor() throws Exception {
final DistributionSet ds = testdataFactory.createDistributionSet("");
testdataFactory.createTarget();
final Long actionId = getFirstAssignedActionId(
@@ -87,9 +86,10 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
.andExpect(status().isOk());
}
@Test
@Description("Test of the controller can continue a started update even after a cancel command if it so desires.")
void rootRsCancelActionButContinueAnyway() throws Exception {
/**
* Test of the controller can continue a started update even after a cancel command if it so desires.
*/
@Test void rootRsCancelActionButContinueAnyway() throws Exception {
// prepare test data
final DistributionSet ds = testdataFactory.createDistributionSet("");
final Target savedTarget = testdataFactory.createTarget();
@@ -147,9 +147,10 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
}
@Test
@Description("Test for cancel operation of a update action.")
void rootRsCancelAction() throws Exception {
/**
* Test for cancel operation of a update action.
*/
@Test void rootRsCancelAction() throws Exception {
final DistributionSet ds = testdataFactory.createDistributionSet("");
final Target savedTarget = testdataFactory.createTarget();
@@ -228,9 +229,10 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
}
@Test
@Description("Tests various bad requests and if the server handles them as expected.")
void badCancelAction() throws Exception {
/**
* Tests various bad requests and if the server handles them as expected.
*/
@Test void badCancelAction() throws Exception {
// not allowed methods
mvc.perform(post("/{tenant}/controller/v1/" + TestdataFactory.DEFAULT_CONTROLLER_ID + "/cancelAction/1",
@@ -264,9 +266,10 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
}
@Test
@Description("Tests the feedback channel of the cancel operation.")
void rootRsCancelActionFeedback() throws Exception {
/**
* Tests the feedback channel of the cancel operation.
*/
@Test void rootRsCancelActionFeedback() throws Exception {
final DistributionSet ds = testdataFactory.createDistributionSet("");
@@ -344,9 +347,10 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget.getControllerId(), PAGE)).isEmpty();
}
@Test
@Description("Tests the feeback chanel of for multiple open cancel operations on the same target.")
void multipleCancelActionFeedback() throws Exception {
/**
* Tests the feeback chanel of for multiple open cancel operations on the same target.
*/
@Test void multipleCancelActionFeedback() throws Exception {
final DistributionSet ds = testdataFactory.createDistributionSet("", true);
final DistributionSet ds2 = testdataFactory.createDistributionSet("2", true);
final DistributionSet ds3 = testdataFactory.createDistributionSet("3", true);
@@ -475,9 +479,10 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
assertThat(deploymentManagement.countActionsByTarget(savedTarget.getControllerId())).isEqualTo(3);
}
@Test
@Description("Tests the feeback channel closing for too many feedbacks, i.e. denial of service prevention.")
void tooMuchCancelActionFeedback() throws Exception {
/**
* Tests the feeback channel closing for too many feedbacks, i.e. denial of service prevention.
*/
@Test void tooMuchCancelActionFeedback() throws Exception {
testdataFactory.createTarget();
final DistributionSet ds = testdataFactory.createDistributionSet("");
@@ -503,9 +508,10 @@ class DdiCancelActionTest extends AbstractDDiApiIntegrationTest {
.andExpect(status().isForbidden());
}
@Test
@Description("test the correct rejection of various invalid feedback requests")
void badCancelActionFeedback() throws Exception {
/**
* test the correct rejection of various invalid feedback requests
*/
@Test void badCancelActionFeedback() throws Exception {
final Action cancelAction = createCancelAction(TestdataFactory.DEFAULT_CONTROLLER_ID);
createCancelAction("4715");

View File

@@ -28,10 +28,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.qameta.allure.Step;
import io.qameta.allure.Story;
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
@@ -48,8 +44,10 @@ import org.springframework.test.context.ActiveProfiles;
* Test config data from the controller.
*/
@ActiveProfiles({ "im", "test" })
@Feature("Component Tests - Direct Device Integration API")
@Story("Config Data Resource")
/**
* Feature: Component Tests - Direct Device Integration API<br/>
* Story: Config Data Resource
*/
class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
private static final String TARGET1_ID = "4717";
@@ -57,9 +55,10 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
private static final String TARGET2_ID = "4718";
private static final String TARGET2_CONFIG_DATA_PATH = "/{tenant}/controller/v1/" + TARGET2_ID + "/configData";
@Test
@Description("Verify that config data can be uploaded as CBOR")
void putConfigDataAsCbor() throws Exception {
/**
* Verify that config data can be uploaded as CBOR
*/
@Test void putConfigDataAsCbor() throws Exception {
testdataFactory.createTarget(TARGET1_ID);
final Map<String, String> attributes = new HashMap<>();
@@ -73,9 +72,11 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
assertThat(targetManagement.getControllerAttributes(TARGET1_ID)).isEqualTo(attributes);
}
@Test
@Description("We verify that the config data (i.e. device attributes like serial number, hardware revision etc.) " +
"are requested only once from the device.")
/**
* We verify that the config data (i.e. device attributes like serial number, hardware revision etc.) are requested only once from the device.")
*/
@SuppressWarnings("squid:S2925")
void requestConfigDataIfEmpty() throws Exception {
final Target savedTarget = testdataFactory.createTarget("4712");
@@ -111,9 +112,11 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
.andExpect(jsonPath("$._links.configData.href").doesNotExist());
}
/**
* We verify that the config data (i.e. device attributes like serial number, hardware revision etc.)
* can be uploaded correctly by the controller.
*/
@Test
@Description("We verify that the config data (i.e. device attributes like serial number, hardware revision etc.) " +
"can be uploaded correctly by the controller.")
void putConfigData() throws Exception {
testdataFactory.createTarget(TARGET1_ID);
@@ -136,10 +139,11 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
assertThat(targetManagement.getControllerAttributes(TARGET1_ID)).isEqualTo(attributes);
}
/**
* We verify that the config data (i.e. device attributes like serial number, hardware revision etc.)
* upload quota is enforced to protect the server from malicious attempts.""")
*/
@Test
@Description("""
We verify that the config data (i.e. device attributes like serial number, hardware revision etc.)
upload quota is enforced to protect the server from malicious attempts.""")
void putTooMuchConfigData() throws Exception {
testdataFactory.createTarget(TARGET1_ID);
@@ -161,9 +165,11 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
.andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey())));
}
/**
* We verify that the config data (i.e. device attributes like serial number, hardware revision etc.)
* resource behaves as expected in case of invalid request attempts.
*/
@Test
@Description("We verify that the config data (i.e. device attributes like serial number, hardware revision etc.) "
+ "resource behaves as expected in case of invalid request attempts.")
void badConfigData() throws Exception {
testdataFactory.createTarget("4712");
@@ -200,18 +206,20 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
.andExpect(status().isBadRequest());
}
@Test
@Description("Verifies that invalid config data attributes are handled correctly.")
void putConfigDataWithInvalidAttributes() throws Exception {
/**
* Verifies that invalid config data attributes are handled correctly.
*/
@Test void putConfigDataWithInvalidAttributes() throws Exception {
// create a target
testdataFactory.createTarget(TARGET2_ID);
putAndVerifyConfigDataWithKeyTooLong();
putAndVerifyConfigDataWithValueTooLong();
}
@Test
@Description("Verify that config data (device attributes) can be updated by the controller using different update modes (merge, replace, remove).")
void putConfigDataWithDifferentUpdateModes() throws Exception {
/**
* Verify that config data (device attributes) can be updated by the controller using different update modes (merge, replace, remove).
*/
@Test void putConfigDataWithDifferentUpdateModes() throws Exception {
// create a target
testdataFactory.createTarget(TARGET1_ID);
@@ -231,7 +239,6 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
putConfigDataWithInvalidUpdateMode();
}
@Step
private void putAndVerifyConfigDataWithKeyTooLong() throws Exception {
final Map<String, String> attributes = Collections.singletonMap(ATTRIBUTE_KEY_TOO_LONG, ATTRIBUTE_VALUE_VALID);
mvc.perform(put(DdiConfigDataTest.TARGET2_CONFIG_DATA_PATH, tenantAware.getCurrentTenant())
@@ -241,7 +248,6 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
.andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_TARGET_ATTRIBUTES_INVALID.getKey())));
}
@Step
private void putAndVerifyConfigDataWithValueTooLong() throws Exception {
final Map<String, String> attributes = Collections.singletonMap(ATTRIBUTE_KEY_VALID, ATTRIBUTE_VALUE_TOO_LONG);
mvc.perform(put(DdiConfigDataTest.TARGET2_CONFIG_DATA_PATH, tenantAware.getCurrentTenant())
@@ -251,7 +257,6 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
.andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_TARGET_ATTRIBUTES_INVALID.getKey())));
}
@Step
private void putConfigDataWithInvalidUpdateMode() throws Exception {
// create some attriutes
final Map<String, String> attributes = Map.of(
@@ -266,7 +271,6 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
.andExpect(status().isBadRequest());
}
@Step
private void putConfigDataWithUpdateModeRemove() throws Exception {
// get the current attributes
final int previousSize = targetManagement.getControllerAttributes(DdiConfigDataTest.TARGET1_ID).size();
@@ -290,7 +294,6 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
}
@Step
private void putConfigDataWithUpdateModeMerge() throws Exception {
// get the current attributes
final Map<String, String> attributes = new HashMap<>(targetManagement.getControllerAttributes(DdiConfigDataTest.TARGET1_ID));
@@ -313,7 +316,6 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
attributes.keySet().forEach(assertThat(updatedAttributes)::containsKey);
}
@Step
private void putConfigDataWithUpdateModeReplace() throws Exception {
// get the current attributes
final Map<String, String> attributes = new HashMap<>(targetManagement.getControllerAttributes(DdiConfigDataTest.TARGET1_ID));
@@ -337,7 +339,6 @@ class DdiConfigDataTest extends AbstractDDiApiIntegrationTest {
attributes.entrySet().forEach(assertThat(updatedAttributes)::doesNotContain);
}
@Step
private void putConfigDataWithoutUpdateMode() throws Exception {
// create some attributes
final Map<String, String> attributes = Map.of(

View File

@@ -23,10 +23,6 @@ import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.qameta.allure.Step;
import io.qameta.allure.Story;
import org.eclipse.hawkbit.ddi.json.model.DdiActivateAutoConfirmation;
import org.eclipse.hawkbit.ddi.json.model.DdiConfirmationFeedback;
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
@@ -63,16 +59,18 @@ import org.springframework.test.web.servlet.ResultActions;
/**
* Test confirmation base from the controller.
* <p/>
* Feature: Component Tests - Direct Device Integration API<br/>
* Story: Confirmation Action Resource
*/
@Feature("Component Tests - Direct Device Integration API")
@Story("Confirmation Action Resource")
class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
private static final String DEFAULT_CONTROLLER_ID = "4747";
@Test
@Description("Forced deployment to a controller. Checks if the confirmation resource response payload for a given deployment is as expected.")
void verifyConfirmationReferencesInControllerBase(@Autowired ActionStatusRepository actionStatusRepository) throws Exception {
/**
* Forced deployment to a controller. Checks if the confirmation resource response payload for a given deployment is as expected.
*/
@Test void verifyConfirmationReferencesInControllerBase(@Autowired ActionStatusRepository actionStatusRepository) throws Exception {
enableConfirmationFlow();
// Prepare test data
final DistributionSet ds = testdataFactory.createDistributionSet("", true);
@@ -134,9 +132,10 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
.allMatch(status -> status.getStatus() == Action.Status.WAIT_FOR_CONFIRMATION);
}
@Test
@Description("Ensure that the deployment resource is available as CBOR")
void confirmationResourceCbor() throws Exception {
/**
* Ensure that the deployment resource is available as CBOR
*/
@Test void confirmationResourceCbor() throws Exception {
enableConfirmationFlow();
final Target target = testdataFactory.createTarget();
final DistributionSet distributionSet = testdataFactory.createDistributionSet("");
@@ -158,9 +157,10 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
String.valueOf(softwareModuleId));
}
@Test
@Description("Ensure that the confirmation endpoint is not available.")
void confirmationEndpointNotExposed() throws Exception {
/**
* Ensure that the confirmation endpoint is not available.
*/
@Test void confirmationEndpointNotExposed() throws Exception {
final DistributionSet ds = testdataFactory.createDistributionSet("");
Target savedTarget = testdataFactory.createTarget("988");
savedTarget = getFirstAssignedTarget(assignDistributionSet(ds.getId(), savedTarget.getControllerId()));
@@ -179,9 +179,10 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(status().isNotFound());
}
@Test
@Description("Ensure that the deploymentBase endpoint is not available for action ins WFC state.")
void deploymentEndpointNotAccessibleForActionsWFC() throws Exception {
/**
* Ensure that the deploymentBase endpoint is not available for action ins WFC state.
*/
@Test void deploymentEndpointNotAccessibleForActionsWFC() throws Exception {
enableConfirmationFlow();
final DistributionSet ds = testdataFactory.createDistributionSet("");
@@ -208,9 +209,10 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(status().isNotFound());
}
@Test
@Description("Ensure that the confirmation endpoints are still available after deactivating the confirmation flow.")
void verifyConfirmationBaseEndpointsArePresentAfterDisablingConfirmationFlow() throws Exception {
/**
* Ensure that the confirmation endpoints are still available after deactivating the confirmation flow.
*/
@Test void verifyConfirmationBaseEndpointsArePresentAfterDisablingConfirmationFlow() throws Exception {
enableConfirmationFlow();
final DistributionSet ds = testdataFactory.createDistributionSet("");
@@ -244,9 +246,10 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
verifyActionInDeploymentBaseState(controllerId, savedAction.getId());
}
@Test
@Description("Controller sends a confirmed action state.")
@ExpectEvents({
/**
* Controller sends a confirmed action state.
*/
@Test @ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@@ -279,9 +282,10 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
verifyActionInDeploymentBaseState(controllerId, savedAction.getId());
}
@Test
@Description("Confirmation base provides right values if auto-confirm not active.")
void getConfirmationBaseProvidesAutoConfirmStatusNotActive() throws Exception {
/**
* Confirmation base provides right values if auto-confirm not active.
*/
@Test void getConfirmationBaseProvidesAutoConfirmStatusNotActive() throws Exception {
enableConfirmationFlow();
final String controllerId = testdataFactory.createTarget("989").getControllerId();
@@ -305,9 +309,11 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(jsonPath("$._links.deactivateAutoConfirm").doesNotExist());
}
/**
* Confirmation base provides right values if auto-confirm is active.
*/
@ParameterizedTest
@MethodSource("possibleActiveStates")
@Description("Confirmation base provides right values if auto-confirm is active.")
void getConfirmationBaseProvidesAutoConfirmStatusActive(final String initiator, final String remark) throws Exception {
final String controllerId = testdataFactory.createTarget("988").getControllerId();
@@ -331,9 +337,11 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(jsonPath("$._links.activateAutoConfirm").doesNotExist());
}
/**
* Verify auto-confirm activation is handled correctly.
*/
@ParameterizedTest
@MethodSource("possibleActiveStates")
@Description("Verify auto-confirm activation is handled correctly.")
void activateAutoConfirmation(final String initiator, final String remark) throws Exception {
final String controllerId = testdataFactory.createTarget("988").getControllerId();
@@ -351,9 +359,10 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
});
}
@Test
@Description("Verify auto-confirm deactivation is handled correctly.")
void deactivateAutoConfirmation() throws Exception {
/**
* Verify auto-confirm deactivation is handled correctly.
*/
@Test void deactivateAutoConfirmation() throws Exception {
final String controllerId = testdataFactory.createTarget("988").getControllerId();
confirmationManagement.activateAutoConfirmation(controllerId, null, null);
@@ -365,9 +374,10 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
assertThat(confirmationManagement.getStatus(controllerId)).isEmpty();
}
@Test
@Description("Controller sends a denied action state.")
@ExpectEvents({
/**
* Controller sends a denied action state.
*/
@Test @ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@@ -410,9 +420,10 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(status().isNotFound());
}
@Test
@Description("Test to verify that only a specific count of messages are returned based on the input actionHistory for getControllerDeploymentActionFeedback endpoint.")
@ExpectEvents({
/**
* Test to verify that only a specific count of messages are returned based on the input actionHistory for getControllerDeploymentActionFeedback endpoint.
*/
@Test @ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@@ -464,7 +475,6 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
Arguments.of(null, null));
}
@Step
private void verifyActionInDeploymentBaseState(final String controllerId, final long actionId) throws Exception {
final String expectedDeploymentBaseLink = String.format(
"/%s/controller/v1/%s/deploymentBase/%d",
@@ -482,7 +492,6 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(status().isOk());
}
@Step
private void verifyActionInConfirmationBaseState(final String controllerId, final long actionId) throws Exception {
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), controllerId).accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print())

View File

@@ -26,9 +26,6 @@ import java.util.Optional;
import java.util.concurrent.TimeUnit;
import com.jayway.jsonpath.JsonPath;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.qameta.allure.Story;
import org.assertj.core.api.Condition;
import org.eclipse.hawkbit.ddi.json.model.DdiResult;
import org.eclipse.hawkbit.ddi.json.model.DdiStatus;
@@ -70,9 +67,10 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
/**
* Test deployment base from the controller.
* <p/>
* Feature: Component Tests - Direct Device Integration API<br/>
* Story: Deployment Action Resource
*/
@Feature("Component Tests - Direct Device Integration API")
@Story("Deployment Action Resource")
class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
private static final String DEFAULT_CONTROLLER_ID = "4712";
@@ -82,9 +80,10 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
@Autowired
private ActionStatusRepository actionStatusRepository;
@Test
@Description("Ensure that the deployment resource is available as CBOR")
void deploymentResourceCbor() throws Exception {
/**
* Ensure that the deployment resource is available as CBOR
*/
@Test void deploymentResourceCbor() throws Exception {
final Target target = testdataFactory.createTarget();
final DistributionSet distributionSet = testdataFactory.createDistributionSet("");
@@ -109,17 +108,19 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
status().isOk());
}
@Test
@Description("Ensures that artifacts are not found, when software module does not exists.")
void artifactsNotFound() throws Exception {
/**
* Ensures that artifacts are not found, when software module does not exists.
*/
@Test void artifactsNotFound() throws Exception {
final Target target = testdataFactory.createTarget();
performGet(SOFTWARE_MODULE_ARTIFACTS, MediaType.APPLICATION_JSON, status().isNotFound(), tenantAware.getCurrentTenant(),
target.getControllerId(), "1");
}
@Test
@Description("Ensures that artifacts are found, when software module exists.")
void artifactsExists() throws Exception {
/**
* Ensures that artifacts are found, when software module exists.
*/
@Test void artifactsExists() throws Exception {
final Target target = testdataFactory.createTarget();
final DistributionSet distributionSet = testdataFactory.createDistributionSet("");
@@ -136,9 +137,10 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(jsonPath("$.[?(@.filename=='filename2')]", hasSize(1)));
}
@Test
@Description("Forced deployment to a controller. Checks if the resource response payload for a given deployment is as expected.")
void deploymentForceAction() throws Exception {
/**
* Forced deployment to a controller. Checks if the resource response payload for a given deployment is as expected.
*/
@Test void deploymentForceAction() throws Exception {
// Prepare test data
final DistributionSet ds = testdataFactory.createDistributionSet("", true);
final DistributionSet ds2 = testdataFactory.createDistributionSet("2", true);
@@ -193,9 +195,10 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
assertThat(actionStatusMessage.getStatus()).isEqualTo(Status.RETRIEVED);
}
@Test
@Description("Checks that the deploymentBase URL changes when the action is switched from soft to forced in TIMEFORCED case.")
void changeEtagIfActionSwitchesFromSoftToForced() throws Exception {
/**
* Checks that the deploymentBase URL changes when the action is switched from soft to forced in TIMEFORCED case.
*/
@Test void changeEtagIfActionSwitchesFromSoftToForced() throws Exception {
// Prepare test data
final Target target = testdataFactory.createTarget(DEFAULT_CONTROLLER_ID);
final DistributionSet ds = testdataFactory.createDistributionSet("", true);
@@ -229,9 +232,10 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
.toString()).isNotEqualTo(urlBeforeSwitch);
}
@Test
@Description("Attempt/soft deployment to a controller. Checks if the resource response payload for a given deployment is as expected.")
void deploymentAttemptAction() throws Exception {
/**
* Attempt/soft deployment to a controller. Checks if the resource response payload for a given deployment is as expected.
*/
@Test void deploymentAttemptAction() throws Exception {
// Prepare test data
final DistributionSet ds = testdataFactory.createDistributionSet("", true);
final DistributionSet ds2 = testdataFactory.createDistributionSet("2", true);
@@ -292,9 +296,10 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
assertThat(actionStatusMessage.getStatus()).isEqualTo(Status.RETRIEVED);
}
@Test
@Description("Attempt/soft deployment to a controller including automated switch to hard. Checks if the resource response payload for a given deployment is as expected.")
void deploymentAutoForceAction() throws Exception {
/**
* Attempt/soft deployment to a controller including automated switch to hard. Checks if the resource response payload for a given deployment is as expected.
*/
@Test void deploymentAutoForceAction() throws Exception {
// Prepare test data
final DistributionSet ds = testdataFactory.createDistributionSet("", true);
final DistributionSet ds2 = testdataFactory.createDistributionSet("2", true);
@@ -350,9 +355,10 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
assertThat(actionStatusMessage.getStatus()).isEqualTo(Status.RETRIEVED);
}
@Test
@Description("Test download-only (forced + skip) deployment to a controller. Checks if the resource response payload for a given deployment is as expected.")
void deploymentDownloadOnlyAction() throws Exception {
/**
* Test download-only (forced + skip) deployment to a controller. Checks if the resource response payload for a given deployment is as expected.
*/
@Test void deploymentDownloadOnlyAction() throws Exception {
// Prepare test data
final DistributionSet ds = testdataFactory.createDistributionSet("", true);
final DistributionSet ds2 = testdataFactory.createDistributionSet("2", true);
@@ -411,9 +417,10 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
assertThat(actionStatusMessage.getStatus()).isEqualTo(Status.RETRIEVED);
}
@Test
@Description("Test various invalid access attempts to the deployment resource und the expected behaviour of the server.")
void badDeploymentAction() throws Exception {
/**
* Test various invalid access attempts to the deployment resource und the expected behaviour of the server.
*/
@Test void badDeploymentAction() throws Exception {
final Target target = testdataFactory.createTarget(DEFAULT_CONTROLLER_ID);
// not allowed methods
@@ -455,9 +462,11 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(status().isNotAcceptable());
}
/**
* The server protects itself against to many feedback upload attempts. The test verifies that
* it is not possible to exceed the configured maximum number of feedback uploads.
*/
@Test
@Description("The server protects itself against to many feedback upload attempts. The test verifies that " +
"it is not possible to exceed the configured maximum number of feedback uploads.")
void tooMuchDeploymentActionFeedback() throws Exception {
final Target target = testdataFactory.createTarget(DEFAULT_CONTROLLER_ID);
final DistributionSet ds = testdataFactory.createDistributionSet("");
@@ -474,9 +483,11 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, action.getId(), feedback, status().isForbidden());
}
/**
* The server protects itself against too large feedback bodies. The test verifies that
* it is not possible to exceed the configured maximum number of feedback details.
*/
@Test
@Description("The server protects itself against too large feedback bodies. The test verifies that " +
"it is not possible to exceed the configured maximum number of feedback details.")
void tooMuchDeploymentActionMessagesInFeedback() throws Exception {
final Target target = testdataFactory.createTarget(DEFAULT_CONTROLLER_ID);
final DistributionSet ds = testdataFactory.createDistributionSet("");
@@ -493,9 +504,10 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
postDeploymentFeedback(DEFAULT_CONTROLLER_ID, action.getId(), feedback, status().isForbidden());
}
@Test
@Description("Multiple uploads of deployment status feedback to the server.")
void multipleDeploymentActionFeedback() throws Exception {
/**
* Multiple uploads of deployment status feedback to the server.
*/
@Test void multipleDeploymentActionFeedback() throws Exception {
testdataFactory.createTarget(DEFAULT_CONTROLLER_ID);
testdataFactory.createTarget("4713");
testdataFactory.createTarget("4714");
@@ -533,9 +545,10 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
assertStatusMessagesCount(6);
}
@Test
@Description("Verifies that an update action is correctly set to error if the controller provides error feedback.")
void rootRsSingleDeploymentActionWithErrorFeedback() throws Exception {
/**
* Verifies that an update action is correctly set to error if the controller provides error feedback.
*/
@Test void rootRsSingleDeploymentActionWithErrorFeedback() throws Exception {
DistributionSet ds = testdataFactory.createDistributionSet("");
final Target savedTarget = testdataFactory.createTarget(DEFAULT_CONTROLLER_ID);
@@ -569,9 +582,10 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
.haveAtLeast(1, new ActionStatusCondition(Status.FINISHED));
}
@Test
@Description("Verifies that the controller can provided as much feedback entries as necessary as long as it is in the configured limits.")
void rootRsSingleDeploymentActionFeedback() throws Exception {
/**
* Verifies that the controller can provided as much feedback entries as necessary as long as it is in the configured limits.
*/
@Test void rootRsSingleDeploymentActionFeedback() throws Exception {
final DistributionSet ds = testdataFactory.createDistributionSet("");
final Long actionId = getFirstAssignedActionId(
assignDistributionSet(ds,
@@ -609,9 +623,10 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
assertThat(targetManagement.findByAssignedDistributionSet(ds.getId(), PAGE)).hasSize(1);
}
@Test
@Description("Various forbidden request attempts on the feedback resource. Ensures correct answering behaviour as expected to these kind of errors.")
void badDeploymentActionFeedback() throws Exception {
/**
* Various forbidden request attempts on the feedback resource. Ensures correct answering behaviour as expected to these kind of errors.
*/
@Test void badDeploymentActionFeedback() throws Exception {
final DistributionSet savedSet = testdataFactory.createDistributionSet("");
final DistributionSet savedSet2 = testdataFactory.createDistributionSet("1");
@@ -647,9 +662,10 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(status().isMethodNotAllowed());
}
@Test
@Description("Ensures that an invalid id in feedback body returns a bad request.")
@ExpectEvents({
/**
* Ensures that an invalid id in feedback body returns a bad request.
*/
@Test @ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@@ -668,9 +684,10 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
postDeploymentFeedback("1080", action.getId(), invalidFeedback, status().isBadRequest());
}
@Test
@Description("Ensures that a missing feedback result in feedback body returns a bad request.")
@ExpectEvents({
/**
* Ensures that a missing feedback result in feedback body returns a bad request.
*/
@Test @ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@@ -693,9 +710,10 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(jsonPath("$.exceptionClass", equalTo(MessageNotReadableException.class.getName())));
}
@Test
@Description("Ensures that a missing finished result in feedback body returns a bad request.")
@ExpectEvents({
/**
* Ensures that a missing finished result in feedback body returns a bad request.
*/
@Test @ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),

View File

@@ -27,9 +27,6 @@ import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.qameta.allure.Story;
import org.eclipse.hawkbit.ddi.json.model.DdiResult;
import org.eclipse.hawkbit.ddi.json.model.DdiStatus;
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
@@ -66,9 +63,10 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
/**
* Test installed base from the controller.
* <p/>
* Feature: Component Tests - Direct Device Integration API<br/>
* Story: Installed Base Resource
*/
@Feature("Component Tests - Direct Device Integration API")
@Story("Installed Base Resource")
class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
@Autowired
@@ -76,9 +74,10 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
private static final int ARTIFACT_SIZE = 5 * 1024;
private static final String CONTROLLER_ID = "4715";
@Test
@Description("Ensure that the installed base resource is available as CBOR")
void installedBaseResourceCbor() throws Exception {
/**
* Ensure that the installed base resource is available as CBOR
*/
@Test void installedBaseResourceCbor() throws Exception {
final Target target = testdataFactory.createTarget();
final DistributionSet ds = testdataFactory.createDistributionSet("");
@@ -98,9 +97,10 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
String.valueOf(softwareModuleId));
}
@Test
@Description("Ensure that assigned version is self assigned version")
void installedVersion() throws Exception {
/**
* Ensure that assigned version is self assigned version
*/
@Test void installedVersion() throws Exception {
final Target target = createTargetAndAssertNoActiveActions();
final DistributionSet ds = testdataFactory.createDistributionSet("");
@@ -113,9 +113,10 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
putInstalledBase(target.getControllerId(), getJsonInstalledBase(ds.getName(), ds.getVersion()), status().isOk());
}
@Test
@Description("Ensure that installedVersion is version self assigned")
void installedVersionNotExist() throws Exception {
/**
* Ensure that installedVersion is version self assigned
*/
@Test void installedVersionNotExist() throws Exception {
final Target target = createTargetAndAssertNoActiveActions();
final String dsName = "unknown";
final String dsVersion = "1.0.0";
@@ -126,9 +127,10 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId()).isEmpty()).isTrue();
}
@Test
@Description("Test several deployments to a controller. Checks that action is represented as installedBase after installation.")
void deploymentSeveralActionsInInstalledBase() throws Exception {
/**
* Test several deployments to a controller. Checks that action is represented as installedBase after installation.
*/
@Test void deploymentSeveralActionsInInstalledBase() throws Exception {
// Prepare test data
final Target target = createTargetAndAssertNoActiveActions();
@@ -194,9 +196,10 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
actionId1, ds1.findFirstModuleByType(osType).get().getId(), Action.ActionType.SOFT);
}
@Test
@Description("Test several deployments of same ds to a controller. Checks that cancelled action in history is not linked as installedBase.")
void deploymentActionsOfSameDsWithCancelledActionInHistory() throws Exception {
/**
* Test several deployments of same ds to a controller. Checks that cancelled action in history is not linked as installedBase.
*/
@Test void deploymentActionsOfSameDsWithCancelledActionInHistory() throws Exception {
// Prepare test data
final Target target = createTargetAndAssertNoActiveActions();
@@ -250,9 +253,10 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(status().isNotFound());
}
@Test
@Description("Test several deployments of same ds to a controller. Checks that latest cancelled action does not override actual installed ds.")
void deploymentActionsOfSameDsWithCancelledAction() throws Exception {
/**
* Test several deployments of same ds to a controller. Checks that latest cancelled action does not override actual installed ds.
*/
@Test void deploymentActionsOfSameDsWithCancelledAction() throws Exception {
// Prepare test data
final Target target = createTargetAndAssertNoActiveActions();
@@ -307,9 +311,10 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(status().isNotFound());
}
@Test
@Description("Test several deployments of same ds to a controller. Checks that latest running action does not override actual installed ds.")
void deploymentActionsOfSameDsWithRunningAction() throws Exception {
/**
* Test several deployments of same ds to a controller. Checks that latest running action does not override actual installed ds.
*/
@Test void deploymentActionsOfSameDsWithRunningAction() throws Exception {
// Prepare test data
final Target target = createTargetAndAssertNoActiveActions();
@@ -360,9 +365,10 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(status().isNotFound());
}
@Test
@Description("Test open deployment to a controller. Checks that installedBase returns 404 for a pending action.")
void installedBaseReturns404ForPendingAction() throws Exception {
/**
* Test open deployment to a controller. Checks that installedBase returns 404 for a pending action.
*/
@Test void installedBaseReturns404ForPendingAction() throws Exception {
// Prepare test data
final Target target = createTargetAndAssertNoActiveActions();
final DistributionSet ds = testdataFactory.createDistributionSet("");
@@ -383,9 +389,10 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(status().isNotFound());
}
@Test
@Description("Ensures that artifacts are found, after the action was already closed.")
void artifactsOfInstalledActionExist() throws Exception {
/**
* Ensures that artifacts are found, after the action was already closed.
*/
@Test void artifactsOfInstalledActionExist() throws Exception {
final Target target = createTargetAndAssertNoActiveActions();
final DistributionSet ds = testdataFactory.createDistributionSet("");
@@ -404,9 +411,11 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(jsonPath("$.[?(@.filename=='filename2')]", hasSize(1)));
}
/**
* Test forced deployment to a controller. Checks that action is represented as installedBase after installation.
*/
@ParameterizedTest
@MethodSource("org.eclipse.hawkbit.ddi.rest.resource.DdiInstalledBaseTest#actionTypeForDeployment")
@Description("Test forced deployment to a controller. Checks that action is represented as installedBase after installation.")
@ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@@ -458,9 +467,10 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
assertThat(actionStatusMessage.getStatus()).isEqualTo(Action.Status.FINISHED);
}
@Test
@Description("Test download-only deployment to a controller. Checks that download-only is not represented as installedBase.")
@ExpectEvents({
/**
* Test download-only deployment to a controller. Checks that download-only is not represented as installedBase.
*/
@Test @ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@@ -498,9 +508,11 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(jsonPath("$._links.installedBase.href").doesNotExist());
}
/**
* Test a failed deployment to a controller. Checks that closed action is not represented as installedBase.
*/
@ParameterizedTest
@MethodSource("org.eclipse.hawkbit.ddi.rest.resource.DdiInstalledBaseTest#actionTypeForDeployment")
@Description("Test a failed deployment to a controller. Checks that closed action is not represented as installedBase.")
void deploymentActionFailedNotInInstalledBase(final Action.ActionType actionType) throws Exception {
// Prepare test data
final Target target = testdataFactory.createTarget();
@@ -532,9 +544,10 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(jsonPath("$._links.installedBase.href").doesNotExist());
}
@Test
@Description("Test to verify that only a specific count of messages are returned based on the input actionHistory for getControllerInstalledAction endpoint.")
void testActionHistoryCount() throws Exception {
/**
* Test to verify that only a specific count of messages are returned based on the input actionHistory for getControllerInstalledAction endpoint.
*/
@Test void testActionHistoryCount() throws Exception {
final DistributionSet ds = testdataFactory.createDistributionSet("");
Target savedTarget = testdataFactory.createTarget("911");
savedTarget = getFirstAssignedTarget(assignDistributionSet(ds.getId(), savedTarget.getControllerId()));
@@ -583,9 +596,10 @@ class DdiInstalledBaseTest extends AbstractDDiApiIntegrationTest {
.andExpect(jsonPath("$.actionHistory.messages", hasItem(containsString("Installation scheduled"))));
}
@Test
@Description("Test various invalid access attempts to the installed resource und the expected behaviour of the server.")
void badInstalledAction() throws Exception {
/**
* Test various invalid access attempts to the installed resource und the expected behaviour of the server.
*/
@Test void badInstalledAction() throws Exception {
final Target target = testdataFactory.createTarget(CONTROLLER_ID);
// not allowed methods

View File

@@ -31,10 +31,6 @@ import java.util.Collections;
import java.util.Map;
import java.util.UUID;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.qameta.allure.Step;
import io.qameta.allure.Story;
import org.eclipse.hawkbit.ddi.json.model.DdiResult;
import org.eclipse.hawkbit.ddi.json.model.DdiStatus;
import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
@@ -73,9 +69,10 @@ import org.springframework.test.web.servlet.ResultActions;
/**
* Test the root controller resources.
* <p/>
* Feature: Component Tests - Direct Device Integration API<br/>
* Story: Root Poll Resource
*/
@Feature("Component Tests - Direct Device Integration API")
@Story("Root Poll Resource")
class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
private static final String TARGET_COMPLETED_INSTALLATION_MSG = "Target completed installation.";
@@ -85,18 +82,20 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
@Autowired
private HawkbitSecurityProperties securityProperties;
@Test
@Description("Ensure that the root poll resource is available as CBOR")
void rootPollResourceCbor() throws Exception {
/**
* Ensure that the root poll resource is available as CBOR
*/
@Test void rootPollResourceCbor() throws Exception {
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), 4711).accept(DdiRestConstants.MEDIA_TYPE_CBOR))
.andDo(MockMvcResultPrinter.print())
.andExpect(content().contentType(DdiRestConstants.MEDIA_TYPE_CBOR))
.andExpect(status().isOk());
}
@Test
@Description("Ensures that the API returns JSON when no Accept header is specified by the client.")
void apiReturnsJSONByDefault() throws Exception {
/**
* Ensures that the API returns JSON when no Accept header is specified by the client.
*/
@Test void apiReturnsJSONByDefault() throws Exception {
final MvcResult result = mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), 4711))
.andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk())
@@ -107,9 +106,10 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
assertThat(result.getRequest().getHeader("Accept")).isNull();
}
@Test
@Description("Ensures that target poll request does not change audit data on the entity.")
@WithUser(principal = "knownPrincipal", authorities = { SpPermission.READ_TARGET, SpPermission.UPDATE_TARGET, SpPermission.CREATE_TARGET })
/**
* Ensures that target poll request does not change audit data on the entity.
*/
@Test @WithUser(principal = "knownPrincipal", authorities = { SpPermission.READ_TARGET, SpPermission.UPDATE_TARGET, SpPermission.CREATE_TARGET })
@ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1),
@@ -139,18 +139,20 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
assertThat(targetVerify.getLastModifiedAt()).isEqualTo(findTargetByControllerID.getLastModifiedAt());
}
@Test
@Description("Ensures that server returns a not found response in case of empty controller ID.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
/**
* Ensures that server returns a not found response in case of empty controller ID.
*/
@Test @ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
void rootRsWithoutId() throws Exception {
mvc.perform(get("/controller/v1/"))
.andDo(MockMvcResultPrinter.print())
.andExpect(status().isNotFound());
}
@Test
@Description("Ensures that the system creates a new target in plug and play manner, i.e. target is authenticated but does not exist yet.")
@ExpectEvents({
/**
* Ensures that the system creates a new target in plug and play manner, i.e. target is authenticated but does not exist yet.
*/
@Test @ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 1) })
void rootRsPlugAndPlay() throws Exception {
@@ -183,9 +185,10 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
.andExpect(status().isMethodNotAllowed());
}
@Test
@Description("Ensures that tenant specific polling time, which is saved in the db, is delivered to the controller.")
@WithUser(principal = "knownpricipal", allSpPermissions = false)
/**
* Ensures that tenant specific polling time, which is saved in the db, is delivered to the controller.
*/
@Test @WithUser(principal = "knownpricipal", allSpPermissions = false)
@ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 1),
@@ -207,9 +210,10 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
});
}
@Test
@Description("Ensures that etag check results in not modified response if provided etag by client is identical to entity in repository.")
@ExpectEvents({
/**
* Ensures that etag check results in not modified response if provided etag by client is identical to entity in repository.
*/
@Test @ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 6),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2),
@@ -304,9 +308,11 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
}
/**
* Ensures that the target state machine of a precomissioned target switches from
* UNKNOWN to REGISTERED when the target polls for the first time.
*/
@Test
@Description("Ensures that the target state machine of a precomissioned target switches from "
+ "UNKNOWN to REGISTERED when the target polls for the first time.")
@ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1),
@@ -333,9 +339,10 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
.isEqualTo(TargetUpdateStatus.REGISTERED);
}
@Test
@Description("Ensures that the source IP address of the polling target is correctly stored in repository")
@ExpectEvents({
/**
* Ensures that the source IP address of the polling target is correctly stored in repository
*/
@Test @ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 1) })
void rootRsPlugAndPlayIpAddress() throws Exception {
@@ -361,9 +368,10 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
assertThat(target.getLastModifiedAt()).isGreaterThanOrEqualTo(create);
}
@Test
@Description("Ensures that the source IP address of the polling target is not stored in repository if disabled")
@ExpectEvents({
/**
* Ensures that the source IP address of the polling target is not stored in repository if disabled
*/
@Test @ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 1) })
void rootRsIpAddressNotStoredIfDisabled() throws Exception {
@@ -382,9 +390,10 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
securityProperties.getClients().setTrackRemoteIp(true);
}
@Test
@Description("Controller trys to finish an update process after it has been finished by an error action status.")
@ExpectEvents({
/**
* Controller trys to finish an update process after it has been finished by an error action status.
*/
@Test @ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@@ -413,9 +422,10 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
.andExpect(status().isGone());
}
@Test
@Description("Controller sends attribute update request after device successfully closed software update.")
@ExpectEvents({
/**
* Controller sends attribute update request after device successfully closed software update.
*/
@Test @ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@@ -443,9 +453,10 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
assertAttributesUpdateRequestedAfterSuccessfulDeployment(savedTarget, ds);
}
@Test
@Description("Test to verify that only a specific count of messages are returned based on the input actionHistory for getControllerDeploymentActionFeedback endpoint.")
@ExpectEvents({
/**
* Test to verify that only a specific count of messages are returned based on the input actionHistory for getControllerDeploymentActionFeedback endpoint.
*/
@Test @ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@@ -487,9 +498,10 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
not(hasItem(containsString(TARGET_SCHEDULED_INSTALLATION_MSG)))));
}
@Test
@Description("Test to verify that a zero input value of actionHistory results in no action history appended for getControllerDeploymentActionFeedback endpoint.")
@ExpectEvents({
/**
* Test to verify that a zero input value of actionHistory results in no action history appended for getControllerDeploymentActionFeedback endpoint.
*/
@Test @ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@@ -531,9 +543,10 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
.andExpect(jsonPath("$.actionHistory.messages").doesNotExist());
}
@Test
@Description("Test to verify that entire action history is returned if the input value for actionHistory is -1, for getControllerDeploymentActionFeedback endpoint.")
@ExpectEvents({
/**
* Test to verify that entire action history is returned if the input value for actionHistory is -1, for getControllerDeploymentActionFeedback endpoint.
*/
@Test @ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@@ -575,9 +588,10 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
hasItem(containsString(TARGET_COMPLETED_INSTALLATION_MSG))));
}
@Test
@Description("Test the polling time based on different maintenance window start and end time.")
void sleepTimeResponseForDifferentMaintenanceWindowParameters() throws Exception {
/**
* Test the polling time based on different maintenance window start and end time.
*/
@Test void sleepTimeResponseForDifferentMaintenanceWindowParameters() throws Exception {
final DistributionSet ds = testdataFactory.createDistributionSet("");
SecurityContextSwitch.runAs(SecurityContextSwitch.withUser("tenantadmin", TENANT_CONFIGURATION),
@@ -625,9 +639,10 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
.andExpect(jsonPath("$.config.polling.sleep", equalTo("00:05:00")));
}
@Test
@Description("Test download and update values before maintenance window start time.")
void downloadAndUpdateStatusBeforeMaintenanceWindowStartTime() throws Exception {
/**
* Test download and update values before maintenance window start time.
*/
@Test void downloadAndUpdateStatusBeforeMaintenanceWindowStartTime() throws Exception {
Target savedTarget = testdataFactory.createTarget("1911");
final DistributionSet ds = testdataFactory.createDistributionSet("");
savedTarget = getFirstAssignedTarget(assignDistributionSetWithMaintenanceWindow(ds.getId(),
@@ -647,9 +662,10 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
.andExpect(jsonPath("$.deployment.maintenanceWindow", equalTo("unavailable")));
}
@Test
@Description("Test download and update values after maintenance window start time.")
void downloadAndUpdateStatusDuringMaintenanceWindow() throws Exception {
/**
* Test download and update values after maintenance window start time.
*/
@Test void downloadAndUpdateStatusDuringMaintenanceWindow() throws Exception {
Target savedTarget = testdataFactory.createTarget("1911");
final DistributionSet ds = testdataFactory.createDistributionSet("");
savedTarget = getFirstAssignedTarget(assignDistributionSetWithMaintenanceWindow(ds.getId(),
@@ -669,9 +685,10 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
.andExpect(jsonPath("$.deployment.maintenanceWindow", equalTo("available")));
}
@Test
@Description("Assign multiple DS in multi-assignment mode. The earliest active Action is exposed to the controller.")
void earliestActionIsExposedToControllerInMultiAssignMode() throws Exception {
/**
* Assign multiple DS in multi-assignment mode. The earliest active Action is exposed to the controller.
*/
@Test void earliestActionIsExposedToControllerInMultiAssignMode() throws Exception {
enableMultiAssignments();
final Target target = testdataFactory.createTarget();
final DistributionSet ds1 = testdataFactory.createDistributionSet(UUID.randomUUID().toString());
@@ -684,15 +701,15 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
assertDeploymentActionIsExposedToTarget(target.getControllerId(), action2Id);
}
@Test
@Description("The system should not create a new target because of a too long controller id.")
void rootRsWithInvalidControllerId() throws Exception {
/**
* The system should not create a new target because of a too long controller id.
*/
@Test void rootRsWithInvalidControllerId() throws Exception {
final String invalidControllerId = randomString(Target.CONTROLLER_ID_MAX_SIZE + 1);
mvc.perform(get(CONTROLLER_BASE, tenantAware.getCurrentTenant(), invalidControllerId))
.andExpect(status().isBadRequest());
}
@Step
private void assertAttributesUpdateNotRequestedAfterFailedDeployment(Target target, final DistributionSet ds) throws Exception {
target = getFirstAssignedTarget(assignDistributionSet(ds.getId(), target.getControllerId()));
final Action action = deploymentManagement.findActiveActionsByTarget(target.getControllerId(), PAGE).getContent().get(0);
@@ -701,7 +718,6 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
assertThatAttributesUpdateIsNotRequested(target.getControllerId());
}
@Step
private void assertAttributesUpdateRequestedAfterSuccessfulDeployment(Target target, final DistributionSet ds) throws Exception {
target = getFirstAssignedTarget(assignDistributionSet(ds.getId(), target.getControllerId()));
final Action action = deploymentManagement.findActiveActionsByTarget(target.getControllerId(), PAGE).getContent().get(0);

View File

@@ -17,9 +17,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import java.util.Collections;
import java.util.List;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.qameta.allure.Story;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Target;
@@ -37,8 +34,10 @@ import org.springframework.web.context.WebApplicationContext;
* Test potential DOS attack scenarios and check if the filter prevents them.
*/
@ActiveProfiles({ "test" })
@Feature("Component Tests - REST Security")
@Story("Denial of Service protection filter")
/**
* Feature: Component Tests - REST Security<br/>
* Story: Denial of Service protection filter
*/
class DosFilterTest extends AbstractDDiApiIntegrationTest {
private static final String X_FORWARDED_FOR = HawkbitSecurityProperties.Clients.X_FORWARDED_FOR;
@@ -49,17 +48,19 @@ class DosFilterTest extends AbstractDDiApiIntegrationTest {
new DosFilter(null, 10, 10, "127\\.0\\.0\\.1|\\[0:0:0:0:0:0:0:1\\]", "(^192\\.168\\.)", "X-Forwarded-For"));
}
@Test
@Description("Ensures that clients that are on the blacklist are forbidden")
void blackListedClientIsForbidden() throws Exception {
/**
* Ensures that clients that are on the blacklist are forbidden
*/
@Test void blackListedClientIsForbidden() throws Exception {
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
.header(X_FORWARDED_FOR, "192.168.0.4 , 10.0.0.1 "))
.andExpect(status().isForbidden());
}
@Test
@Description("Ensures that a READ DoS attempt is blocked ")
void getFloodingAttackThatIsPrevented() throws Exception {
/**
* Ensures that a READ DoS attempt is blocked
*/
@Test void getFloodingAttackThatIsPrevented() throws Exception {
int requests = 0;
MvcResult result;
do {
@@ -76,9 +77,10 @@ class DosFilterTest extends AbstractDDiApiIntegrationTest {
assertThat(requests).isGreaterThanOrEqualTo(10);
}
@Test
@Description("Ensures that an assumed READ DoS attempt is not blocked as the client (with IPv4 address) is on a whitelist")
void unacceptableGetLoadButOnWhitelistIPv4() throws Exception {
/**
* Ensures that an assumed READ DoS attempt is not blocked as the client (with IPv4 address) is on a whitelist
*/
@Test void unacceptableGetLoadButOnWhitelistIPv4() throws Exception {
for (int i = 0; i < 100; i++) {
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
.header(X_FORWARDED_FOR, "127.0.0.1"))
@@ -86,9 +88,10 @@ class DosFilterTest extends AbstractDDiApiIntegrationTest {
}
}
@Test
@Description("Ensures that an assumed READ DoS attempt is not blocked as the client (with IPv6 address) is on a whitelist")
void unacceptableGetLoadButOnWhitelistIPv6() throws Exception {
/**
* Ensures that an assumed READ DoS attempt is not blocked as the client (with IPv6 address) is on a whitelist
*/
@Test void unacceptableGetLoadButOnWhitelistIPv6() throws Exception {
for (int i = 0; i < 100; i++) {
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())
.header(X_FORWARDED_FOR, "0:0:0:0:0:0:0:1"))
@@ -96,9 +99,10 @@ class DosFilterTest extends AbstractDDiApiIntegrationTest {
}
}
@Test
@Description("Ensures that a relatively high number of READ requests is allowed if it is below the DoS detection threshold")
// No idea how to get rid of the Thread.sleep here
/**
* Ensures that a relatively high number of READ requests is allowed if it is below the DoS detection threshold
*/
@Test // No idea how to get rid of the Thread.sleep here
@SuppressWarnings("squid:S2925")
void acceptableGetLoad() throws Exception {
for (int x = 0; x < 3; x++) {
@@ -112,9 +116,10 @@ class DosFilterTest extends AbstractDDiApiIntegrationTest {
}
}
@Test
@Description("Ensures that a WRITE DoS attempt is blocked ")
void putPostFloddingAttackThatisPrevented() throws Exception {
/**
* Ensures that a WRITE DoS attempt is blocked
*/
@Test void putPostFloddingAttackThatisPrevented() throws Exception {
final Long actionId = prepareDeploymentBase();
final String feedback = getJsonProceedingDeploymentActionFeedback();
@@ -135,9 +140,10 @@ class DosFilterTest extends AbstractDDiApiIntegrationTest {
assertThat(requests).isGreaterThanOrEqualTo(10);
}
@Test
@Description("Ensures that a relatively high number of WRITE requests is allowed if it is below the DoS detection threshold")
// No idea how to get rid of the Thread.sleep here
/**
* Ensures that a relatively high number of WRITE requests is allowed if it is below the DoS detection threshold
*/
@Test // No idea how to get rid of the Thread.sleep here
@SuppressWarnings("squid:S2925")
void acceptablePutPostLoad() throws Exception {
final Long actionId = prepareDeploymentBase();