Skip to content

Commit 4b59937

Browse files
committed
Update E2ETests
1 parent 886051f commit 4b59937

6 files changed

Lines changed: 108 additions & 19 deletions

File tree

e2e-tests/src/main/java/gov/nasa/jpl/aerie/e2e/procedural/scheduling/procedures/FruitThresholdConstraint.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public Violations run(@NotNull Plan plan, @NotNull SimulationResults simResults)
1919
return Violations.on(
2020
fruit.lessThan(upperBound).and(fruit.greaterThan(lowerBound)),
2121
false
22-
);
22+
).withDefaultMessage("Fruit count is outside of boundaries: [%d, %d]".formatted(lowerBound, upperBound));
2323
}
2424

2525
@WithDefaults
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package gov.nasa.jpl.aerie.e2e.procedural.scheduling.procedures;
2+
3+
import gov.nasa.ammos.aerie.procedural.constraints.Constraint;
4+
import gov.nasa.ammos.aerie.procedural.constraints.Violations;
5+
import gov.nasa.ammos.aerie.procedural.constraints.annotations.ConstraintProcedure;
6+
import gov.nasa.ammos.aerie.procedural.scheduling.annotations.WithDefaults;
7+
import gov.nasa.ammos.aerie.procedural.timeline.collections.profiles.Real;
8+
import gov.nasa.ammos.aerie.procedural.timeline.plan.Plan;
9+
import gov.nasa.ammos.aerie.procedural.timeline.plan.SimulationResults;
10+
import org.jetbrains.annotations.NotNull;
11+
12+
/**
13+
* Equivalent to FruitThresholdConstraint, except it does not include a message in the violations
14+
*/
15+
@ConstraintProcedure
16+
public record NoMessageConstraint(int lowerBound, int upperBound) implements Constraint {
17+
@NotNull
18+
@Override
19+
public Violations run(@NotNull Plan plan, @NotNull SimulationResults simResults) {
20+
final var fruit = simResults.resource("/fruit", Real.deserializer());
21+
22+
return Violations.on(
23+
fruit.lessThan(upperBound).and(fruit.greaterThan(lowerBound)),
24+
false
25+
);
26+
}
27+
28+
@WithDefaults
29+
public static class Template{
30+
public int lowerBound = 5;
31+
}
32+
}

e2e-tests/src/test/java/gov/nasa/jpl/aerie/e2e/procedural/constraints/BasicConstraintTests.java

Lines changed: 68 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,35 @@
1818
import static org.junit.jupiter.api.Assertions.assertTrue;
1919

2020
public class BasicConstraintTests extends ProceduralSchedulingSetup {
21-
private ConstraintInvocationId fruitTresholdConstraintId;
21+
private ConstraintInvocationId fruitThresholdConstraintId;
22+
private ConstraintInvocationId noMessageConstraintId;
2223

2324
@BeforeEach
2425
void localBeforeEach() throws IOException {
2526
try (final var gateway = new GatewayRequests(playwright)) {
26-
final int fruitTresholdConstraintJarId = gateway.uploadJarFile("build/libs/FruitThresholdConstraint.jar");
27-
// Add Scheduling Procedure
28-
fruitTresholdConstraintId = hasura.createConstraintSpecProcedure(
29-
"Test Constraint Procedure 1",
30-
fruitTresholdConstraintJarId,
27+
final int fruitThresholdConstraintJarId = gateway.uploadJarFile("build/libs/FruitThresholdConstraint.jar");
28+
final int noMessageConstraintJarId = gateway.uploadJarFile("build/libs/NoMessageConstraint.jar");
29+
// Add Constraint Procedures
30+
fruitThresholdConstraintId = hasura.createConstraintSpecProcedure(
31+
"Fruit Threshold Constraint",
32+
fruitThresholdConstraintJarId,
3133
planId
3234
);
35+
noMessageConstraintId = hasura.createConstraintSpecProcedure(
36+
"No Message Constraint",
37+
noMessageConstraintJarId,
38+
planId
39+
);
40+
41+
// Disable the noMessageConstraint by default
42+
hasura.updatePlanConstraintSpecEnabled(noMessageConstraintId.invocationId(), false);
3343
}
3444
}
3545

3646
@AfterEach
3747
void localAfterEach() throws IOException {
38-
hasura.deleteConstraint(fruitTresholdConstraintId.id());
48+
hasura.deleteConstraint(fruitThresholdConstraintId.id());
49+
hasura.deleteConstraint(noMessageConstraintId.id());
3950
}
4051

4152
/**
@@ -47,8 +58,15 @@ void executeConstraintRunWithoutArguments() throws IOException {
4758
hasura.awaitSimulation(planId);
4859
final var resp = hasura.checkConstraints(planId);
4960
assertEquals(1, resp.constraintsRun().size());
50-
assertEquals(1, resp.constraintsRun().getFirst().errors().size());
51-
assertTrue(resp.constraintsRun().getFirst().errors().getFirst().message().contains("gov.nasa.jpl.aerie.merlin.protocol.types.InstantiationException: Invalid arguments for input type \"FruitThresholdConstraint\": extraneous arguments: [], unconstructable arguments: [], missing arguments: [MissingArgument[parameterName=upperBound, schema=IntSchema[]]], valid arguments: [ValidArgument[parameterName=lowerBound, serializedValue=NumericValue[value=5]]]"));
61+
final var constraint = resp.constraintsRun().getFirst();
62+
assertEquals(1, constraint.errors().size());
63+
assertTrue(constraint.errors().getFirst().message().contains(
64+
"gov.nasa.jpl.aerie.merlin.protocol.types.InstantiationException: Invalid arguments for input type "
65+
+ "\"FruitThresholdConstraint\": "
66+
+ "extraneous arguments: [], "
67+
+ "unconstructable arguments: [], "
68+
+ "missing arguments: [MissingArgument[parameterName=upperBound, schema=IntSchema[]]], "
69+
+ "valid arguments: [ValidArgument[parameterName=lowerBound, serializedValue=NumericValue[value=5]]]"));
5270
}
5371

5472
/**
@@ -57,7 +75,7 @@ void executeConstraintRunWithoutArguments() throws IOException {
5775
@Test
5876
void executeConstraintRunWithArguments() throws IOException {
5977
final var args = Json.createObjectBuilder().add("upperBound", 10).build();
60-
hasura.updateConstraintArguments(fruitTresholdConstraintId.invocationId(), args);
78+
hasura.updateConstraintArguments(fruitThresholdConstraintId.invocationId(), args);
6179
hasura.awaitSimulation(planId);
6280
final var resp = hasura.checkConstraints(planId);
6381
assertTrue(resp.constraintsRun().getFirst().success());
@@ -68,20 +86,55 @@ void executeConstraintRunWithArguments() throws IOException {
6886
assertEquals(violation.windows(), List.of(new ConstraintResult.Interval(0, Duration.hours(48).micros())));
6987
}
7088

89+
/**
90+
* Test that constraints with a violation message include said violation message.
91+
*/
92+
@Test
93+
void messageReturnedIfPresent() throws IOException {
94+
// Enable the NoMessageConstraint
95+
hasura.updatePlanConstraintSpecEnabled(noMessageConstraintId.invocationId(), true);
96+
97+
// Assign args to the constraints
98+
final var args = Json.createObjectBuilder().add("upperBound", 10).build();
99+
hasura.updateConstraintArguments(fruitThresholdConstraintId.invocationId(), args);
100+
hasura.updateConstraintArguments(noMessageConstraintId.invocationId(), args);
101+
102+
// Get Constraint Results
103+
hasura.awaitSimulation(planId);
104+
final var resp = hasura.checkConstraints(planId);
105+
106+
assertEquals(2, resp.constraintsRun().size());
107+
108+
final var firstConstraint = resp.constraintsRun().getFirst();
109+
assertEquals(fruitThresholdConstraintId.invocationId(), firstConstraint.constraintInvocationId());
110+
assertTrue(firstConstraint.success());
111+
assertEquals(1, firstConstraint.result().get().violations().size());
112+
final var firstConstraintViolation = firstConstraint.result().get().violations().getFirst();
113+
assertTrue(firstConstraintViolation.message().isPresent());
114+
assertEquals("Fruit count is outside of boundaries: [5, 10]", firstConstraintViolation.message().get());
115+
116+
final var secondConstraint = resp.constraintsRun().getLast();
117+
assertEquals(noMessageConstraintId.invocationId(), firstConstraint.constraintInvocationId());
118+
assertTrue(secondConstraint.success());
119+
assertEquals(1, secondConstraint.result().get().violations().size());
120+
final var secondConstraintViolation = secondConstraint.result().get().violations().getFirst();
121+
assertTrue(secondConstraintViolation.message().isEmpty());
122+
}
123+
71124
/**
72125
* Queries the procedural constraints arguments.
73126
*/
74127
@Test
75128
void effectiveArgumentsQuery() throws IOException {
76129
final var effectiveArgs = hasura.getEffectiveProceduralConstraintsArgumentsBulk(
77-
List.of(Pair.of(fruitTresholdConstraintId.id(), Json.createObjectBuilder().add("upperBound", 10).build())));
130+
List.of(Pair.of(fruitThresholdConstraintId.id(), Json.createObjectBuilder().add("upperBound", 10).build())));
78131
assertEquals(1, effectiveArgs.size());
79-
assertTrue(effectiveArgs.get(0).success());
80-
assertTrue(effectiveArgs.get(0).arguments().isPresent());
81-
assertTrue(effectiveArgs.get(0).errors().isEmpty());
132+
assertTrue(effectiveArgs.getFirst().success());
133+
assertTrue(effectiveArgs.getFirst().arguments().isPresent());
134+
assertTrue(effectiveArgs.getFirst().errors().isEmpty());
82135

83136
// Check returned Arguments
84-
final var args = effectiveArgs.get(0).arguments().get();
137+
final var args = effectiveArgs.getFirst().arguments().get();
85138
assertEquals(2, args.size());
86139
assertEquals(10, args.getInt("upperBound"));
87140
assertEquals(5, args.getInt("lowerBound"));

e2e-tests/src/test/java/gov/nasa/jpl/aerie/e2e/types/ConstraintResult.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,23 @@
44
import javax.json.JsonObject;
55
import javax.json.JsonString;
66
import java.util.List;
7+
import java.util.Optional;
78

89
public record ConstraintResult(
910
List<String> resourceIds,
1011
List<ConstraintResult.ConstraintViolation> violations,
1112
List<ConstraintResult.Interval> gaps
1213
) {
13-
public record ConstraintViolation(List<Integer> activityInstanceIds, List<Interval> windows) {
14+
public record ConstraintViolation(List<Integer> activityInstanceIds, List<Interval> windows, Optional<String> message) {
1415

1516
public static ConstraintViolation fromJSON(JsonObject json) {
1617
return new ConstraintViolation(
1718
json.getJsonArray("activityInstanceIds")
1819
.getValuesAs(JsonNumber::intValue),
1920
json.getJsonArray("windows")
20-
.getValuesAs(Interval::fromJSON));
21+
.getValuesAs(Interval::fromJSON),
22+
Optional.ofNullable(json.getString("message", null))
23+
);
2124
}
2225
}
2326

e2e-tests/src/test/java/gov/nasa/jpl/aerie/e2e/utils/GQL.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ query checkConstraints($planId: Int!, $simulationDatasetId: Int) {
6868
start
6969
}
7070
violations {
71+
message
7172
activityInstanceIds
7273
windows {
7374
end

e2e-tests/src/test/java/gov/nasa/jpl/aerie/e2e/utils/HasuraRequests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public class HasuraRequests implements AutoCloseable {
3737
public HasuraRequests(Playwright playwright) {
3838
request = playwright.request().newContext(
3939
new APIRequest.NewContextOptions()
40-
.setBaseURL(BaseURL.HASURA.url));
40+
.setBaseURL(BaseURL.HASURA.url).setTimeout(0));
4141
}
4242

4343
@Override

0 commit comments

Comments
 (0)