Skip to content

Commit 8792ae7

Browse files
yesamermanstis
authored andcommitted
[Drools-3838] Improve error reporting in scenario result (apache#2335)
* [DROOLS-3838] BackEnd part import * [DROOLS-3838] Cleanup * Unify assertion framework (#1)
1 parent eebde29 commit 8792ae7

File tree

16 files changed

+140
-76
lines changed

16 files changed

+140
-76
lines changed

drools-scenario-simulation/drools-scenario-simulation-api/src/main/java/org/drools/scenariosimulation/api/model/FactMappingValue.java

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ public class FactMappingValue {
2828
private ExpressionIdentifier expressionIdentifier;
2929
private Object rawValue;
3030
@XStreamOmitField
31-
private boolean error = false;
31+
private FactMappingValueStatus status = FactMappingValueStatus.SUCCESS;
32+
@XStreamOmitField
33+
private Object errorValue;
34+
@XStreamOmitField
35+
private String exceptionMessage;
3236

3337
public FactMappingValue() {
3438
}
@@ -63,11 +67,31 @@ FactMappingValue cloneFactMappingValue() {
6367
return cloned;
6468
}
6569

66-
public boolean isError() {
67-
return error;
70+
public FactMappingValueStatus getStatus() {
71+
return status;
72+
}
73+
74+
public Object getErrorValue() {
75+
return errorValue;
76+
}
77+
78+
public void setErrorValue(Object errorValue) {
79+
this.errorValue = errorValue;
80+
this.status = FactMappingValueStatus.FAILED_WITH_ERROR;
81+
}
82+
83+
public String getExceptionMessage() {
84+
return exceptionMessage;
85+
}
86+
87+
public void setExceptionMessage(String exceptionMessage) {
88+
this.exceptionMessage = exceptionMessage;
89+
this.status = FactMappingValueStatus.FAILED_WITH_EXCEPTION;
6890
}
6991

70-
public void setError(boolean error) {
71-
this.error = error;
92+
public void resetStatus() {
93+
this.status = FactMappingValueStatus.SUCCESS;
94+
this.exceptionMessage = null;
95+
this.errorValue = null;
7296
}
7397
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
/*
3+
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.drools.scenariosimulation.api.model;
18+
19+
public enum FactMappingValueStatus {
20+
21+
SUCCESS,
22+
FAILED_WITH_ERROR,
23+
FAILED_WITH_EXCEPTION
24+
}

drools-scenario-simulation/drools-scenario-simulation-api/src/main/java/org/drools/scenariosimulation/api/model/Scenario.java

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ public class Scenario {
3434
*/
3535
private final List<FactMappingValue> factMappingValues = new ArrayList<>();
3636

37+
/**
38+
* Not used, to be removed.
39+
*/
40+
@Deprecated
3741
private SimulationDescriptor simulationDescriptor = new SimulationDescriptor();
3842

3943
public Scenario() {
@@ -46,11 +50,7 @@ public Scenario(SimulationDescriptor simulationDescriptor) {
4650
/**
4751
* Returns an <b>unmodifiable</b> list wrapping the backed one
4852
* <p>
49-
* NOTE: list order could not be aligned to factMapping order. Use {@link Scenario#sort()} before call this method
50-
* to ensure the order.
51-
* Best way to have ordered factMappingValues is to iterate over {@link SimulationDescriptor#factMappings} and use
52-
* {@link #getFactMappingValue(FactIdentifier, ExpressionIdentifier)}
53-
* @return not modifiable list of FactMappingValues
53+
* NOTE: list order could not be aligned to factMapping order.
5454
*/
5555
public List<FactMappingValue> getUnmodifiableFactMappingValues() {
5656
return Collections.unmodifiableList(factMappingValues);
@@ -88,15 +88,8 @@ public Optional<FactMappingValue> getFactMappingValue(FactIdentifier factIdentif
8888
e.getExpressionIdentifier().equals(expressionIdentifier)).findFirst();
8989
}
9090

91-
public Optional<FactMappingValue> getFactMappingValueByIndex(int index) {
92-
FactMapping factMappingByIndex;
93-
try {
94-
factMappingByIndex = simulationDescriptor.getFactMappingByIndex(index);
95-
} catch (IndexOutOfBoundsException e) {
96-
throw new IllegalArgumentException(
97-
new StringBuilder().append("Impossible to retrieve FactMapping at index ").append(index).toString(), e);
98-
}
99-
return getFactMappingValue(factMappingByIndex.getFactIdentifier(), factMappingByIndex.getExpressionIdentifier());
91+
public Optional<FactMappingValue> getFactMappingValue(FactMapping factMapping) {
92+
return getFactMappingValue(factMapping.getFactIdentifier(), factMapping.getExpressionIdentifier());
10093
}
10194

10295
public List<FactMappingValue> getFactMappingValuesByFactIdentifier(FactIdentifier factIdentifier) {
@@ -120,16 +113,8 @@ public Collection<String> getFactNames() {
120113
return factMappingValues.stream().map(e -> e.getFactIdentifier().getName()).collect(toSet());
121114
}
122115

123-
public void sort() {
124-
factMappingValues.sort((a, b) -> {
125-
Integer aIndex = simulationDescriptor.getIndexByIdentifier(a.getFactIdentifier(), a.getExpressionIdentifier());
126-
Integer bIndex = simulationDescriptor.getIndexByIdentifier(b.getFactIdentifier(), b.getExpressionIdentifier());
127-
return aIndex.compareTo(bIndex);
128-
});
129-
}
130-
131116
public void resetErrors() {
132-
factMappingValues.forEach(elem -> elem.setError(false));
117+
factMappingValues.forEach(elem -> elem.resetStatus());
133118
}
134119

135120
Scenario cloneScenario() {

drools-scenario-simulation/drools-scenario-simulation-api/src/main/java/org/drools/scenariosimulation/api/model/Simulation.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,6 @@ public void clearScenarios() {
112112
scenarios.clear();
113113
}
114114

115-
public void sort() {
116-
scenarios.forEach(Scenario::sort);
117-
}
118-
119115
public void resetErrors() {
120116
scenarios.forEach(Scenario::resetErrors);
121117
}

drools-scenario-simulation/drools-scenario-simulation-api/src/test/java/org/drools/scenariosimulation/api/model/FactMappingValueTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import org.junit.Test;
2020

21+
import static org.assertj.core.api.Assertions.assertThat;
2122
import static org.assertj.core.api.Assertions.assertThatThrownBy;
2223

2324
public class FactMappingValueTest {
@@ -32,4 +33,33 @@ public void emptyFactMappingValue() {
3233
.isInstanceOf(NullPointerException.class)
3334
.hasMessage("ExpressionIdentifier has to be not null");
3435
}
36+
37+
@Test
38+
public void resetStatus() {
39+
FactMappingValue value = new FactMappingValue();
40+
value.resetStatus();
41+
assertThat(value.getStatus()).isEqualTo(FactMappingValueStatus.SUCCESS);
42+
assertThat(value.getExceptionMessage()).isNull();
43+
assertThat(value.getErrorValue()).isNull();
44+
}
45+
46+
@Test
47+
public void setErrorValue() {
48+
String errorValue = "value";
49+
FactMappingValue value = new FactMappingValue();
50+
value.setErrorValue(errorValue);
51+
assertThat(value.getStatus()).isEqualTo(FactMappingValueStatus.FAILED_WITH_ERROR);
52+
assertThat(value.getExceptionMessage()).isNull();
53+
assertThat(value.getErrorValue()).isEqualTo(errorValue);
54+
}
55+
56+
@Test
57+
public void setExceptionMessage() {
58+
String exceptionValue = "Exception";
59+
FactMappingValue value = new FactMappingValue();
60+
value.setExceptionMessage(exceptionValue);
61+
assertThat(value.getStatus()).isEqualTo(FactMappingValueStatus.FAILED_WITH_EXCEPTION);
62+
assertThat(value.getExceptionMessage()).isEqualTo(exceptionValue);
63+
assertThat(value.getErrorValue()).isNull();
64+
}
3565
}

drools-scenario-simulation/drools-scenario-simulation-api/src/test/java/org/drools/scenariosimulation/api/model/ScenarioTest.java

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
import static org.junit.Assert.assertEquals;
2424
import static org.junit.Assert.assertFalse;
25-
import static org.junit.Assert.assertNotEquals;
2625
import static org.junit.Assert.assertTrue;
2726

2827
public class ScenarioTest {
@@ -92,19 +91,4 @@ public void addOrUpdateMappingValue() {
9291
assertEquals(factMappingValue, factMappingValue1);
9392
assertEquals(factMappingValue1.getRawValue(), value2);
9493
}
95-
96-
@Test
97-
public void sortTest() {
98-
ExpressionIdentifier expressionIdentifier2 = ExpressionIdentifier.create("Test expression 2", FactMappingType.GIVEN);
99-
simulationDescriptor.addFactMapping(factIdentifier, expressionIdentifier);
100-
simulationDescriptor.addFactMapping(factIdentifier, expressionIdentifier2);
101-
scenario.addMappingValue(factIdentifier, expressionIdentifier2, "Test 2");
102-
FactMappingValue factMappingValue1 = scenario.addMappingValue(factIdentifier, this.expressionIdentifier, "Test");
103-
104-
assertEquals(scenario.getUnmodifiableFactMappingValues().get(1), factMappingValue1);
105-
106-
scenario.sort();
107-
assertNotEquals(scenario.getUnmodifiableFactMappingValues().get(1), factMappingValue1);
108-
assertEquals(scenario.getUnmodifiableFactMappingValues().get(0), factMappingValue1);
109-
}
11094
}

drools-scenario-simulation/drools-scenario-simulation-backend/src/main/java/org/drools/scenariosimulation/backend/fluent/ValidateFactCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public Void execute(Context context) {
3939
if (objects.size() > 0) {
4040
factToCheck.forEach(fact -> fact.getScenarioResult().setResult(true));
4141
} else {
42-
factToCheck.forEach(fact -> fact.getScenarioResult().getFactMappingValue().setError(true));
42+
factToCheck.forEach(fact -> fact.getScenarioResult().getFactMappingValue().setExceptionMessage("There is no instance which satisfies the expected conditions"));
4343
}
4444
return null;
4545
}

drools-scenario-simulation/drools-scenario-simulation-backend/src/main/java/org/drools/scenariosimulation/backend/runner/AbstractRunnerHelper.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public ResultWrapper<Object> getDirectMapping(Map<List<String>, Object> params)
108108
return ResultWrapper.createResult(entry.getValue());
109109
}
110110
}
111-
return ResultWrapper.createErrorResult();
111+
return ResultWrapper.createErrorResult(null, null);
112112
}
113113

114114
public List<ScenarioExpect> extractExpectedValues(List<FactMappingValue> factMappingValues) {
@@ -179,7 +179,7 @@ public Map<List<String>, Object> getParamsForBean(SimulationDescriptor simulatio
179179
factMappingValue.getRawValue());
180180
paramsForBean.put(pathToField, value);
181181
} catch (IllegalArgumentException e) {
182-
factMappingValue.setError(true);
182+
factMappingValue.setExceptionMessage(e.getMessage());
183183
throw new ScenarioException(e.getMessage(), e);
184184
}
185185
}
@@ -203,7 +203,12 @@ public void validateAssertion(List<ScenarioResult> scenarioResults, Scenario sce
203203
protected ScenarioResult fillResult(FactMappingValue expectedResult, FactIdentifier factIdentifier, Supplier<ResultWrapper<?>> resultSupplier) {
204204
ResultWrapper<?> resultValue = resultSupplier.get();
205205

206-
expectedResult.setError(!resultValue.isSatisfied());
206+
if (!resultValue.isSatisfied()) {
207+
expectedResult.setErrorValue(resultValue.getResult());
208+
209+
} else {
210+
expectedResult.resetStatus();
211+
}
207212

208213
return new ScenarioResult(factIdentifier, expectedResult, resultValue.getResult()).setResult(resultValue.isSatisfied());
209214
}

drools-scenario-simulation/drools-scenario-simulation-backend/src/main/java/org/drools/scenariosimulation/backend/runner/DMNScenarioRunnerHelper.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,9 @@ protected ResultWrapper getSingleFactValueResult(FactMapping factMapping,
120120
DMNDecisionResult decisionResult,
121121
ExpressionEvaluator expressionEvaluator) {
122122
Object resultRaw = decisionResult.getResult();
123-
124-
if (!SUCCEEDED.equals(decisionResult.getEvaluationStatus())) {
125-
return createErrorResult();
123+
final DMNDecisionResult.DecisionEvaluationStatus evaluationStatus = decisionResult.getEvaluationStatus();
124+
if (!SUCCEEDED.equals(evaluationStatus)) {
125+
return createErrorResult(SUCCEEDED, evaluationStatus);
126126
}
127127

128128
for (ExpressionElement expressionElement : factMapping.getExpressionElementsWithoutClass()) {
@@ -135,12 +135,13 @@ protected ResultWrapper getSingleFactValueResult(FactMapping factMapping,
135135

136136
Class<?> resultClass = resultRaw != null ? resultRaw.getClass() : null;
137137

138+
Object expectedResultRaw = expectedResult.getRawValue();
138139
try {
139-
return expressionEvaluator.evaluateUnaryExpression(expectedResult.getRawValue(), resultRaw, resultClass) ?
140+
return expressionEvaluator.evaluateUnaryExpression(expectedResultRaw, resultRaw, resultClass) ?
140141
createResult(resultRaw) :
141-
createErrorResult();
142+
createErrorResult(resultRaw, expectedResultRaw);
142143
} catch (Exception e) {
143-
expectedResult.setError(true);
144+
expectedResult.setExceptionMessage(e.getMessage());
144145
throw new ScenarioException(e.getMessage(), e);
145146
}
146147
}

drools-scenario-simulation/drools-scenario-simulation-backend/src/main/java/org/drools/scenariosimulation/backend/runner/RuleScenarioRunnerHelper.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,13 +140,13 @@ protected Function<Object, ResultWrapper> createExtractorFunction(ExpressionEval
140140
List<String> pathToValue = factMapping.getExpressionElementsWithoutClass().stream().map(ExpressionElement::getStep).collect(toList());
141141
ScenarioBeanWrapper<?> scenarioBeanWrapper = ScenarioBeanUtil.navigateToObject(objectToCheck, pathToValue, false);
142142
Object resultValue = scenarioBeanWrapper.getBean();
143-
143+
Object expectedResultValue = expectedResult.getRawValue();
144144
try {
145-
return expressionEvaluator.evaluateUnaryExpression(expectedResult.getRawValue(), resultValue, scenarioBeanWrapper.getBeanClass()) ?
145+
return expressionEvaluator.evaluateUnaryExpression(expectedResultValue, resultValue, scenarioBeanWrapper.getBeanClass()) ?
146146
createResult(resultValue) :
147-
createErrorResult();
147+
createErrorResult(resultValue, expectedResultValue);
148148
} catch (Exception e) {
149-
expectedResult.setError(true);
149+
expectedResult.setExceptionMessage(e.getMessage());
150150
throw new ScenarioException(e.getMessage(), e);
151151
}
152152
};

0 commit comments

Comments
 (0)