Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed Defect in Test case for Biceps:R5025 #125

Merged
merged 13 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- report duplication issue in biceps:C11-C15, biceps:C5, biceps:R5046_0, biceps:B-284_0 as well as biceps:R5003.
- biceps:5-4-7 tests confusing changes made by SetComponentActivation manipulations with changes made by SetMetricStatus.
- glue:R0036_0 test can be blocked by long-running t2iapi RPCs.
- biceps:5025_0 test case could not be satisfied by devices that do not support inserting and removing descriptors.

## [7.0.1] - 2023-03-17

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ this case in order to minimize the risk of such an invalid application going unn
| C-14 | TriggerReport |
| C-15 | TriggerReport |
| R5024 | TriggerReport |
| R5025_0 | GetRemovableDescriptorsOfClass, RemoveDescriptor, InsertDescriptor |
| R5025_0 | GetRemovableDescriptorsOfClass, RemoveDescriptor, InsertDescriptor, TriggerDescriptorUpdate |
| R5046_0 | GetRemovableDescriptorsOfClass, RemoveDescriptor, InsertDescriptor |
| R5051 | GetRemovableDescriptorsOfClass, RemoveDescriptor, InsertDescriptor |
| R5052 | TriggerAnyDescriptorUpdate |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,19 @@ public void close() {}
return interactionResult ? ResponseTypes.Result.RESULT_SUCCESS : ResponseTypes.Result.RESULT_FAIL;
}

@Override
public ResponseTypes.Result triggerDescriptorUpdate(final List<String> handles) {
final var triggerReportString = "Trigger a descriptor update for handles %s";
final var interactionMessage = String.format(triggerReportString, String.join(", ", handles));
final var interactionResult = interactionFactory
.createUserInteraction(new FilterInputStream(System.in) {
@Override
public void close() {}
})
.displayYesNoUserInteraction(interactionMessage);
return interactionResult ? ResponseTypes.Result.RESULT_SUCCESS : ResponseTypes.Result.RESULT_FAIL;
}

@Override
public ResponseTypes.Result triggerAnyDescriptorUpdate() {
final var interactionMessage = "Trigger a descriptor update for some descriptor";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,15 +294,21 @@ public ResponseTypes.Result setMetricStatus(

@Override
public ResponseTypes.Result triggerDescriptorUpdate(final String handle) {
final var message =
BasicRequests.BasicHandleRequest.newBuilder().setHandle(handle).build();
return triggerDescriptorUpdate(List.of(handle));
}

belagertem marked this conversation as resolved.
Show resolved Hide resolved
@Override
public ResponseTypes.Result triggerDescriptorUpdate(final List<String> handles) {
final var message = DeviceRequests.TriggerDescriptorUpdateRequest.newBuilder()
.addAllHandle(handles)
.build();

return performCallWrapper(
v -> deviceStub.triggerDescriptorUpdate(message),
v -> fallback.triggerDescriptorUpdate(handle),
v -> fallback.triggerDescriptorUpdate(handles),
BasicResponses.BasicResponse::getResult,
BasicResponses.BasicResponse::getResult,
ManipulationParameterUtil.buildHandleManipulationParameterData(handle));
ManipulationParameterUtil.buildTriggerDescriptorUpdateParameterData(handles));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,14 @@ ResponseTypes.Result setMetricStatus(
*/
ResponseTypes.Result triggerDescriptorUpdate(String handle);

/**
* Trigger a descriptor update for the provided descriptor handles.
*
* @param handles list of descriptor handles to trigger an update for.
* @return the result of the manipulation
*/
ResponseTypes.Result triggerDescriptorUpdate(List<String> handles);

/**
* Trigger a descriptor update for some descriptor (chosen by the device).
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -461,11 +461,11 @@ static boolean manipulation(final Injector injector) {
}

// all options exhausted and the goal is still not reached
LOG.error("Unable to find any MdsDescriptors using the GetRemovableDescriptorsOfType() manipulation "
LOG.error("Unable to find any MdsDescriptors using the GetRemovableDescriptorsOfClass() manipulation "
+ "that can be inserted, updated and removed (at least one for each is required for the test "
+ "applying this precondition). "
+ "Please check if the test case applying this precondition is applicable to your device and if the "
+ "GetRemovableDescriptorsOfType, InsertDescriptor, RemoveDescriptor, and TriggerDescriptorUpdate "
+ "GetRemovableDescriptorsOfClass, InsertDescriptor, RemoveDescriptor, and TriggerDescriptorUpdate "
+ "manipulations have been implemented correctly.");
return false;
}
Expand Down Expand Up @@ -660,15 +660,17 @@ static boolean manipulation(final Injector injector) {
* Precondition which checks whether DescriptionModificationReport messages containing an insertion
* or deletion have been received, triggering description changes otherwise.
*/
public static class DescriptionChangedPrecondition extends SimplePrecondition {
public static class DescriptionModificationCrtOrDelPrecondition extends SimplePrecondition {

private static final Logger LOG = LogManager.getLogger(DescriptionChangedPrecondition.class);
private static final Logger LOG = LogManager.getLogger(DescriptionModificationCrtOrDelPrecondition.class);

/**
* Creates a description changed precondition check.
* Creates a description modification crt or del precondition check.
*/
public DescriptionChangedPrecondition() {
super(DescriptionChangedPrecondition::preconditionCheck, DescriptionChangedPrecondition::manipulation);
public DescriptionModificationCrtOrDelPrecondition() {
super(
DescriptionModificationCrtOrDelPrecondition::preconditionCheck,
DescriptionModificationCrtOrDelPrecondition::manipulation);
}

static boolean preconditionCheck(final Injector injector) throws PreconditionException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.draeger.medical.sdccc.configuration.TestSuiteConfig;
import com.draeger.medical.sdccc.manipulation.Manipulations;
import com.draeger.medical.sdccc.manipulation.precondition.ManipulationPrecondition;
import com.draeger.medical.sdccc.manipulation.precondition.PreconditionException;
import com.draeger.medical.sdccc.sdcri.testclient.TestClient;
import com.draeger.medical.sdccc.tests.util.ImpliedValueUtil;
import com.draeger.medical.sdccc.util.TestRunObserver;
Expand All @@ -29,6 +30,7 @@
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.somda.sdc.biceps.common.MdibEntity;
Expand All @@ -38,6 +40,7 @@
import org.somda.sdc.biceps.common.event.ContextStateModificationMessage;
import org.somda.sdc.biceps.model.participant.AbstractAlertState;
import org.somda.sdc.biceps.model.participant.AbstractContextState;
import org.somda.sdc.biceps.model.participant.AbstractDescriptor;
import org.somda.sdc.biceps.model.participant.AbstractDeviceComponentDescriptor;
import org.somda.sdc.biceps.model.participant.AbstractDeviceComponentState;
import org.somda.sdc.biceps.model.participant.AbstractMetricDescriptor;
Expand All @@ -55,6 +58,7 @@
import org.somda.sdc.biceps.model.participant.ContextAssociation;
import org.somda.sdc.biceps.model.participant.LocationContextDescriptor;
import org.somda.sdc.biceps.model.participant.LocationContextState;
import org.somda.sdc.biceps.model.participant.MdsDescriptor;
import org.somda.sdc.biceps.model.participant.MetricCategory;
import org.somda.sdc.biceps.model.participant.PatientContextDescriptor;
import org.somda.sdc.biceps.model.participant.PatientContextState;
Expand Down Expand Up @@ -114,6 +118,114 @@ private static boolean manipulateMetricStatus(
return manipulationResults.contains(ResponseTypes.Result.RESULT_SUCCESS);
}

private static boolean removeAndReinsertDescriptors(final Injector injector, final Logger log) {
final var manipulations = injector.getInstance(Manipulations.class);
final var testClient = injector.getInstance(TestClient.class);
final var testRunObserver = injector.getInstance(TestRunObserver.class);

final MdibAccess mdibAccess;
final SdcRemoteDevice remoteDevice;

remoteDevice = testClient.getSdcRemoteDevice();
if (remoteDevice == null) {
testRunObserver.invalidateTestRun("Remote device could not be accessed, likely due to a disconnect");
return false;
}

mdibAccess = remoteDevice.getMdibAccess();

final var modifiableDescriptors = manipulations.getRemovableDescriptorsOfClass();
if (modifiableDescriptors.isEmpty()) {
log.info("No modifiable descriptors available for manipulation");
return false;
}

final var manipulationResults = new HashSet<ResponseTypes.Result>();
for (String handle : modifiableDescriptors) {
// determine if descriptor is currently present
var descriptorEntity = mdibAccess.getEntity(handle);
log.debug("Descriptor {} presence: {}", handle, descriptorEntity.isPresent());

// if the descriptor is not present, insert it first
if (descriptorEntity.isEmpty()) {
manipulationResults.add(manipulations.insertDescriptor(handle));
descriptorEntity = mdibAccess.getEntity(handle);
if (descriptorEntity.isEmpty()) {
manipulationResults.add(ResponseTypes.Result.RESULT_FAIL);
}
log.debug("Descriptor {} presence: {}", handle, descriptorEntity.isPresent());
}

// remove descriptor
manipulationResults.add(manipulations.removeDescriptor(handle));
descriptorEntity = mdibAccess.getEntity(handle);
if (descriptorEntity.isPresent()) {
manipulationResults.add(ResponseTypes.Result.RESULT_FAIL);
}
log.debug("Descriptor {} presence: {}", handle, descriptorEntity.isPresent());

// reinsert descriptor
manipulationResults.add(manipulations.insertDescriptor(handle));
descriptorEntity = mdibAccess.getEntity(handle);
if (descriptorEntity.isEmpty()) {
manipulationResults.add(ResponseTypes.Result.RESULT_FAIL);
}
log.debug("Descriptor {} presence: {}", handle, descriptorEntity.isPresent());

if (manipulationResults.contains(ResponseTypes.Result.RESULT_FAIL)) {
testRunObserver.invalidateTestRun(String.format(
"Could not successfully modify descriptor %s, stopping the precondition", handle));
break;
}
}

return !manipulationResults.contains(ResponseTypes.Result.RESULT_FAIL)
&& !manipulationResults.contains(ResponseTypes.Result.RESULT_NOT_IMPLEMENTED)
&& manipulationResults.contains(ResponseTypes.Result.RESULT_SUCCESS);
}

private static boolean descriptionUpdateWithParentChildRelationshipManipulation(
final Injector injector, final Logger log) {
final Pair<String, String> descriptorHandles = findFirstDescriptorHandleWithChildren(injector, log);
if (descriptorHandles == null) {
log.error("Could not trigger a descriptor update with parent child relationship as there are no "
+ "descriptors with children in the mdib.");
return false;
}
final String parentDescriptorHandle = descriptorHandles.getLeft();
final String childDescriptorHandle = descriptorHandles.getRight();
final var manipulations = injector.getInstance(Manipulations.class);

final ResponseTypes.Result manipulationResult =
manipulations.triggerDescriptorUpdate(List.of(childDescriptorHandle, parentDescriptorHandle));

return ResponseTypes.Result.RESULT_SUCCESS.equals(manipulationResult);
}

private static Pair<String, String> findFirstDescriptorHandleWithChildren(
final Injector injector, final Logger log) {
final var testClient = injector.getInstance(TestClient.class);

final var remoteDevice = testClient.getSdcRemoteDevice();
if (remoteDevice == null) {
log.error("remote device could not be accessed, likely due to a disconnect");
return null;
}
final var mdibAccess = remoteDevice.getMdibAccess();

final Collection<MdibEntity> entities = mdibAccess.findEntitiesByType(AbstractDescriptor.class);
for (MdibEntity entity : entities) {
if (entity.getDescriptor() instanceof MdsDescriptor) {
continue; // we are not interested in MdsDescriptors as many Devices do not support modifying them.
}
final List<String> children = entity.getChildren();
if (!children.isEmpty()) {
return Pair.of(entity.getHandle(), children.get(0));
}
}
return null;
}

/**
* Associates two <em>new</em> patients for every available PatientContextDescriptor present in the provider mdib.
*/
Expand Down Expand Up @@ -1607,69 +1719,37 @@ public RemoveAndReinsertDescriptorManipulation() {
* @return true if successful, false otherwise
*/
static boolean manipulation(final Injector injector) {
final var manipulations = injector.getInstance(Manipulations.class);
final var testClient = injector.getInstance(TestClient.class);
final var testRunObserver = injector.getInstance(TestRunObserver.class);

final MdibAccess mdibAccess;
final SdcRemoteDevice remoteDevice;

remoteDevice = testClient.getSdcRemoteDevice();
if (remoteDevice == null) {
testRunObserver.invalidateTestRun("Remote device could not be accessed, likely due to a disconnect");
return false;
}

mdibAccess = remoteDevice.getMdibAccess();

final var modifiableDescriptors = manipulations.getRemovableDescriptorsOfClass();
if (modifiableDescriptors.isEmpty()) {
LOG.info("No modifiable descriptors available for manipulation");
return false;
}

final var manipulationResults = new HashSet<ResponseTypes.Result>();
for (String handle : modifiableDescriptors) {
// determine if descriptor is currently present
var descriptorEntity = mdibAccess.getEntity(handle);
LOG.debug("Descriptor {} presence: {}", handle, descriptorEntity.isPresent());

// if the descriptor is not present, insert it first
if (descriptorEntity.isEmpty()) {
manipulationResults.add(manipulations.insertDescriptor(handle));
descriptorEntity = mdibAccess.getEntity(handle);
if (descriptorEntity.isEmpty()) {
manipulationResults.add(ResponseTypes.Result.RESULT_FAIL);
}
LOG.debug("Descriptor {} presence: {}", handle, descriptorEntity.isPresent());
}
return removeAndReinsertDescriptors(injector, LOG);
}
}

// remove descriptor
manipulationResults.add(manipulations.removeDescriptor(handle));
descriptorEntity = mdibAccess.getEntity(handle);
if (descriptorEntity.isPresent()) {
manipulationResults.add(ResponseTypes.Result.RESULT_FAIL);
}
LOG.debug("Descriptor {} presence: {}", handle, descriptorEntity.isPresent());
/**
* Precondition which triggers all possible description changes with parent-child relationships.
*/
public static class DescriptionModificationAllWithParentChildRelationshipPrecondition
extends ManipulationPrecondition {

// reinsert descriptor
manipulationResults.add(manipulations.insertDescriptor(handle));
descriptorEntity = mdibAccess.getEntity(handle);
if (descriptorEntity.isEmpty()) {
manipulationResults.add(ResponseTypes.Result.RESULT_FAIL);
}
LOG.debug("Descriptor {} presence: {}", handle, descriptorEntity.isPresent());
private static final Logger LOG =
LogManager.getLogger(DescriptionModificationAllWithParentChildRelationshipPrecondition.class);

if (manipulationResults.contains(ResponseTypes.Result.RESULT_FAIL)) {
testRunObserver.invalidateTestRun(String.format(
"Could not successfully modify descriptor %s, stopping the precondition", handle));
break;
}
}
/**
* Creates a description modification all with parent child relationship precondition check.
*/
public DescriptionModificationAllWithParentChildRelationshipPrecondition() {
super(DescriptionModificationAllWithParentChildRelationshipPrecondition::manipulation);
}

return !manipulationResults.contains(ResponseTypes.Result.RESULT_FAIL)
&& !manipulationResults.contains(ResponseTypes.Result.RESULT_NOT_IMPLEMENTED)
&& manipulationResults.contains(ResponseTypes.Result.RESULT_SUCCESS);
/**
* Performs the removal, reinsertion and update of all modifiable descriptors in the mdib to trigger reports.
*
* @param injector to analyze mdib on
* @return true if successful, false otherwise
* @throws PreconditionException on errors
*/
static boolean manipulation(final Injector injector) {
final boolean result1 = removeAndReinsertDescriptors(injector, LOG);
final boolean result2 = descriptionUpdateWithParentChildRelationshipManipulation(injector, LOG);
return result1 || result2;
}
}
}
Loading