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 Glue:R0036_0. #136

1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- local address resolver sometimes giving a wrong address
- local address resolver doing a probe which may not be tolerated by some peers
- potential NullPointerException in DescriptionModificationUptPrecondition
- the test case for Glue:R0036_0 not accepting a SOAPFault as a valid answer for Subscribe messages

## [8.0.1] - 2023-09-13

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* This Source Code Form is subject to the terms of the MIT License.
* Copyright (c) 2023 Draegerwerk AG & Co. KGaA.
* Copyright (c) 2023, 2024 Draegerwerk AG & Co. KGaA.
*
* SPDX-License-Identifier: MIT
*/
Expand Down Expand Up @@ -145,7 +145,7 @@ void testRequirementR0034() {
final var hostedServices = testClient.getHostingServiceProxy().getHostedServices();
final var serviceIds = hostedServices.values().stream()
.map(hostedServiceProxy -> hostedServiceProxy.getType().getServiceId())
.collect(Collectors.toList());
.toList();
if (hostedServices.values().size() != new HashSet<>(serviceIds).size()) {
fail(String.format("Some Hosted Services share the same service id: %s, test failed.", serviceIds));
}
Expand Down Expand Up @@ -596,7 +596,17 @@ public void onNotification(final NotificationObject message) {
reportTestData.setSubscription(result);
reportTestData.setEventSink(eventSink);
} catch (InterruptedException | ExecutionException e) {
fail("encountered exception while subscribing to " + reportTestData.getReportName(), e);
if (e instanceof ExecutionException && e.getCause() instanceof SoapFaultException) {
// according to WS-Eventing, answering a Subscribe with a SOAPFault is a normal way of
// declining a subscription. We hence interpret it as "Report is not supported" and do
// not fail the test case.
LOG.warn(
"Subscription was answered by SOAPFault. The Device seems not to support "
+ reportTestData.getReportName(),
e);
} else {
fail("encountered exception while subscribing to " + reportTestData.getReportName(), e);
}
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* This Source Code Form is subject to the terms of the MIT License.
* Copyright (c) 2023 Draegerwerk AG & Co. KGaA.
* Copyright (c) 2023, 2024 Draegerwerk AG & Co. KGaA.
*
* SPDX-License-Identifier: MIT
*/
Expand Down Expand Up @@ -50,6 +50,7 @@
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
Expand Down Expand Up @@ -357,7 +358,7 @@ public void testRequirementR00360Good() throws Exception {
ActionConstants.ACTION_EPISODIC_METRIC_REPORT,
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));
testDeviceForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
testDeviceForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
}

/**
Expand All @@ -376,7 +377,7 @@ public void testRequirementR00360GoodNoLocationContext() throws Exception {
ActionConstants.ACTION_EPISODIC_METRIC_REPORT,
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));
setupTestScenarioForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
setupTestScenarioForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
cancelledReports = new HashSet<>();

testUnderTest.testRequirementR00360();
Expand All @@ -398,7 +399,7 @@ public void testRequirementR00360BadTooManyCancelledSubscriptionsOperationInvoke
ActionConstants.ACTION_EPISODIC_METRIC_REPORT,
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));
testDeviceForR00360(true, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
testDeviceForR00360(true, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
}

/**
Expand All @@ -418,7 +419,7 @@ public void testRequirementR00360BadTooManyCancelledSubscriptionsDescriptionModi
ActionConstants.ACTION_EPISODIC_METRIC_REPORT,
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));
testDeviceForR00360(true, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
testDeviceForR00360(true, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
}

/**
Expand All @@ -437,7 +438,7 @@ public void testRequirementR00360BadTooManyCancelledSubscriptionsEpisodicAlertRe
ActionConstants.ACTION_EPISODIC_METRIC_REPORT,
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));
testDeviceForR00360(true, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
testDeviceForR00360(true, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
}

/**
Expand All @@ -456,7 +457,7 @@ public void testRequirementR00360BadTooManyCancelledSubscriptionsEpisodicCompone
ActionConstants.ACTION_EPISODIC_METRIC_REPORT,
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));
testDeviceForR00360(true, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
testDeviceForR00360(true, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
}

/**
Expand All @@ -475,7 +476,7 @@ public void testRequirementR00360BadTooManyCancelledSubscriptionsEpisodicMetricR
ActionConstants.ACTION_EPISODIC_METRIC_REPORT,
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));
testDeviceForR00360(true, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
testDeviceForR00360(true, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
}

/**
Expand All @@ -495,7 +496,7 @@ public void testRequirementR00360BadTooManyCancelledSubscriptionsEpisodicOperati
ActionConstants.ACTION_EPISODIC_METRIC_REPORT,
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));
testDeviceForR00360(true, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
testDeviceForR00360(true, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
}

/**
Expand All @@ -512,7 +513,7 @@ public void testRequirementR0036NoSupportForEpisodicAlertReport() throws Excepti
ActionConstants.ACTION_EPISODIC_METRIC_REPORT,
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));
testDeviceForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
testDeviceForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
}

// NOTE: the test does not work when the Device does not support EpisodicContextReport.
Expand All @@ -531,7 +532,25 @@ public void testRequirementR00360NoSupportForOperationInvokedReport() throws Exc
ActionConstants.ACTION_EPISODIC_METRIC_REPORT,
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));
testDeviceForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
testDeviceForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
}

/**
* Tests whether a device that indicates that it does not support the OperationInvokedReport
* by sending a SOAPFault can still pass the test.
*/
@Test
public void testRequirementR00360GoodNoSupportForOperationInvokedReportSOAPFault() throws Exception {
reportsToCancel = new HashSet<>(Set.of(ActionConstants.ACTION_EPISODIC_CONTEXT_REPORT));
supportedReports = new HashSet<>(Set.of(
ActionConstants.ACTION_EPISODIC_CONTEXT_REPORT,
ActionConstants.ACTION_DESCRIPTION_MODIFICATION_REPORT,
ActionConstants.ACTION_EPISODIC_ALERT_REPORT,
ActionConstants.ACTION_EPISODIC_COMPONENT_REPORT,
ActionConstants.ACTION_EPISODIC_METRIC_REPORT,
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));
testDeviceForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, true);
}

/**
Expand All @@ -548,7 +567,7 @@ public void testRequirementR0036NoSupportForDescriptionModificationReport() thro
ActionConstants.ACTION_EPISODIC_METRIC_REPORT,
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));
testDeviceForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
testDeviceForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
}

/**
Expand All @@ -565,7 +584,7 @@ public void testRequirementR00360NoSupportForDescriptionModificationReport() thr
ActionConstants.ACTION_EPISODIC_METRIC_REPORT,
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));
testDeviceForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
testDeviceForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
}

/**
Expand All @@ -582,7 +601,7 @@ public void testRequirementR0036NoSupportForEpisodicComponentReport() throws Exc
ActionConstants.ACTION_EPISODIC_METRIC_REPORT,
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));
testDeviceForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
testDeviceForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
}

/**
Expand All @@ -599,7 +618,7 @@ public void testRequirementR00360NoSupportForEpisodicMetricReport() throws Excep
ActionConstants.ACTION_EPISODIC_COMPONENT_REPORT,
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));
testDeviceForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
testDeviceForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
}

/**
Expand All @@ -616,7 +635,7 @@ public void testRequirementR00360NoSupportForEpisodicOperationalStateReport() th
ActionConstants.ACTION_EPISODIC_COMPONENT_REPORT,
ActionConstants.ACTION_EPISODIC_METRIC_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));
testDeviceForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
testDeviceForR00360(false, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
}

/**
Expand All @@ -633,7 +652,8 @@ public void testRequirementR0036NoSupportForSystemErrorReport() throws Exception
ActionConstants.ACTION_EPISODIC_COMPONENT_REPORT,
ActionConstants.ACTION_EPISODIC_METRIC_REPORT,
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT));
testDeviceForR00360(false, INSIGNIFICANT_DELAY_IN_SECONDS, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
testDeviceForR00360(
false, INSIGNIFICANT_DELAY_IN_SECONDS, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
}

/**
Expand All @@ -646,7 +666,7 @@ public void testRequirementR0036NoSupportForSystemErrorReport() throws Exception
public void testRequirementR00360NoReports() throws Exception {
reportsToCancel = new HashSet<>(Set.of(ActionConstants.ACTION_EPISODIC_CONTEXT_REPORT));
supportedReports = new HashSet<>(Set.of());
testDeviceForR00360(true, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, NoTestData.class);
testDeviceForR00360(true, 0, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false, NoTestData.class);
}

/**
Expand All @@ -664,7 +684,7 @@ public void testRequirementR00360WithStronglyDelayedCancellations() throws Excep
ActionConstants.ACTION_EPISODIC_METRIC_REPORT,
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));
testDeviceForR00360(true, SIGNIFICANT_DELAY_IN_SECONDS, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
testDeviceForR00360(true, SIGNIFICANT_DELAY_IN_SECONDS, true, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
}

/**
Expand All @@ -683,7 +703,7 @@ public void testRequirementR00360BadSilentCancellation() throws Exception {
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));

testDeviceForR00360(true, 0, false, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED);
testDeviceForR00360(true, 0, false, SUBSCRIPTION_END_STATUS_DELIVERY_FAILED, false);
}

/**
Expand All @@ -702,27 +722,33 @@ public void testRequirementR00360BadCancellationWrongStatus() throws Exception {
ActionConstants.ACTION_EPISODIC_OPERATIONAL_STATE_REPORT,
ActionConstants.ACTION_SYSTEM_ERROR_REPORT));

testDeviceForR00360(true, 0, true, SUBSCRIPTION_END_STATUS_CANCELLED);
testDeviceForR00360(true, 0, true, SUBSCRIPTION_END_STATUS_CANCELLED, false);
}

/**
* Does all the work for the Tests for Requirement R0036_0.
* @param expectFailure - should the test expect Failure?
*
* @param expectFailure - should the test expect Failure?
* @param delayBeforeCancellingInSeconds - time (in seconds) to wait before cancelling the subscriptions.
* @param sendSubscriptionEnd - true if a SubscriptionEnd Message should be send when a subscription is cancelled,
* @param subscriptionEndStatus - Status to set in the SubscriptionEnd message.
* @param sendSubscriptionEnd - true if a SubscriptionEnd Message should be send when a subscription is cancelled,
* @param subscriptionEndStatus - Status to set in the SubscriptionEnd message.
* @param faultOnUnsupportedSubscription - should an unsupported Subscription be answered with a SOAPFault?
* when false, the subscription is answered with an empty
* SubscriptionResponse instead.
*/
private void testDeviceForR00360(
final boolean expectFailure,
final int delayBeforeCancellingInSeconds,
final boolean sendSubscriptionEnd,
final String subscriptionEndStatus)
final String subscriptionEndStatus,
final boolean faultOnUnsupportedSubscription)
throws Exception {
testDeviceForR00360(
expectFailure,
delayBeforeCancellingInSeconds,
sendSubscriptionEnd,
subscriptionEndStatus,
faultOnUnsupportedSubscription,
AssertionError.class);
}

Expand All @@ -731,10 +757,16 @@ private void testDeviceForR00360(
final int delayBeforeCancellingInSeconds,
final boolean sendSubscriptionEnd,
final String subscriptionEndStatus,
final boolean faultOnUnsupportedSubscription,
final Class<? extends Throwable> exceptionClass)
throws Exception {
// given
setupTestScenarioForR00360(true, delayBeforeCancellingInSeconds, sendSubscriptionEnd, subscriptionEndStatus);
setupTestScenarioForR00360(
true,
delayBeforeCancellingInSeconds,
sendSubscriptionEnd,
subscriptionEndStatus,
faultOnUnsupportedSubscription);
this.cancelledReports = new HashSet<>();

// when & then
Expand Down Expand Up @@ -762,7 +794,8 @@ private void setupTestScenarioForR00360(
final boolean hasLocationContextState,
final int delayBeforeCancellingInSeconds,
final boolean sendSubscriptionEnd,
final String subscriptionEndStatus)
final String subscriptionEndStatus,
final boolean faultOnUnsupportedSubscription)
throws Exception {
final Map<String, HostedServiceProxy> hostedServices = new HashMap<>();

Expand Down Expand Up @@ -841,7 +874,19 @@ private void setupTestScenarioForR00360(
lastSubscriptionId.addAndGet(1);
return createListenableFuture(new SubscribeResult(subscriptionId, Duration.ofSeconds(60)));
} else {
return createListenableFuture(null);
if (faultOnUnsupportedSubscription) {
final var unsupportedActions = actions.stream()
.filter((action) -> !this.supportedReports.contains(action))
.toList();
final var message = soapFaultFactory.createReceiverFault(
String.join(", ", unsupportedActions) + " not supported");
final var e = new SoapFaultException(message);
return createListenableFutureThatExecutes(() -> {
throw new ExecutionException(e);
});
} else {
return createListenableFuture(null);
}
}
});

Expand Down Expand Up @@ -987,6 +1032,38 @@ public T get(final long timeout, final TimeUnit unit) {
};
}

private <T> ListenableFuture<T> createListenableFutureThatExecutes(final CallbackReturningT<T> callback) {
return new ListenableFuture<>() {
@Override
public void addListener(final Runnable runnable, final Executor executor) {}

@Override
public boolean cancel(final boolean mayInterruptIfRunning) {
return false;
}

@Override
public boolean isCancelled() {
return false;
}

@Override
public boolean isDone() {
return false;
}

@Override
public T get() throws ExecutionException {
return callback.execute();
}

@Override
public T get(final long timeout, final TimeUnit unit) throws ExecutionException {
return get();
}
};
}

private HostedServiceProxy setupServiceMock(
final QName portTypeContextQname, final RequestResponseClient requestResponseClient) {
final HostedServiceProxy service = mock(HostedServiceProxy.class);
Expand All @@ -997,6 +1074,10 @@ private HostedServiceProxy setupServiceMock(
return service;
}

interface CallbackReturningT<T> {
T execute() throws ExecutionException;
}

/**
* Calls all ReportInterceptors with an EpisodicContextReport and - if one of them throws an Exception,
* waits for the given delay to pass and then delivers a SubscriptionEnd Message to all SubscriptionEndInterceptors.
Expand Down
Loading