Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import gov.nasa.jpl.aerie.merlin.framework.resources.real.RealResource;
import gov.nasa.jpl.aerie.merlin.protocol.types.RealDynamics;

public final class Accumulator implements RealResource {
public final class Accumulator extends NamedResource<RealDynamics> implements RealResource {
private final CellRef<LinearAccumulationEvent, LinearIntegrationCell> ref;

public final Rate rate = new Rate();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package gov.nasa.jpl.aerie.contrib.models;

import gov.nasa.jpl.aerie.merlin.framework.resources.NameableResource;

/**
* Provides a field for setting the string name of the resource.
*/
public abstract class NamedResource<D> implements NameableResource<D> {
private String name = "ERROR: Name was not set during model construction";

@Override
public String getName() {
return name;
}

@Override
public void setName(final String name) {
this.name = name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public void slew(final Vector3D target, final Duration duration) {
addRate(previousRate); // Reset rate to previous rate
}

public static final class Component implements RealResource {
public static final class Component extends NamedResource<RealDynamics> implements RealResource {
private final Accumulator acc;
public final Accumulator.Rate rate;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import java.util.function.UnaryOperator;

public final class Register<Value> implements DiscreteResource<Value> {
public final class Register<Value> extends NamedResource<Value> implements DiscreteResource<Value> {
public final CellRef<Value, RegisterCell<Value>> ref;

private Register(final UnaryOperator<Value> duplicator, final Value initialValue) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* Simple resource that samples arbitrarily many existing resources/values at a specified period (default period is once
* per second).
*/
public class SampledResource<T> implements DiscreteResource<T> {
public class SampledResource<T> extends NamedResource<T> implements DiscreteResource<T> {
private final Register<T> result;
private final Supplier<T> sampler;
private final Register<Double> period;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
package gov.nasa.jpl.aerie.contrib.models;

import java.util.Optional;

public record ValidationResult(boolean success, String subject, String message) {}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package gov.nasa.jpl.aerie.contrib.models.counters;

import gov.nasa.jpl.aerie.contrib.cells.counters.CounterCell;
import gov.nasa.jpl.aerie.contrib.models.NamedResource;
import gov.nasa.jpl.aerie.merlin.framework.CellRef;
import gov.nasa.jpl.aerie.merlin.framework.resources.discrete.DiscreteResource;

import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.UnaryOperator;

public final class Counter<T> implements DiscreteResource<T> {
public final class Counter<T> extends NamedResource<T> implements DiscreteResource<T> {
private final CellRef<T, CounterCell<T>> ref;

public Counter(final T initialValue, final T zero, final BinaryOperator<T> adder, final UnaryOperator<T> duplicator) {
Expand Down
5 changes: 5 additions & 0 deletions e2e-tests/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,12 @@ dependencies {
annotationProcessor project(':procedural:processor')

implementation project(":procedural:scheduling")
implementation project(":procedural:constraints")
implementation project(":procedural:timeline")
implementation project(':merlin-sdk')
implementation project(':type-utils')
implementation project(':contrib')
implementation project(':examples:banananation')

testImplementation "com.zaxxer:HikariCP:5.1.0"
testImplementation("org.postgresql:postgresql:42.6.0")
Expand Down Expand Up @@ -118,6 +120,9 @@ tasks.create("generateProcedureJarTasks") {
manifest {
attributes 'Main-Class': getMainClassFromGeneratedFile(file)
}
dependencies {
exclude(project(":examples:banananation"))
}
minimize()
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package gov.nasa.jpl.aerie.e2e.procedural.constraints.procedures;

import gov.nasa.ammos.aerie.procedural.constraints.Constraint;
import gov.nasa.ammos.aerie.procedural.constraints.Violations;
import gov.nasa.ammos.aerie.procedural.constraints.annotations.ConstraintProcedure;
import gov.nasa.ammos.aerie.procedural.timeline.plan.Plan;
import gov.nasa.ammos.aerie.procedural.timeline.plan.SimulationResults;
import gov.nasa.ammos.aerie.procedural.timeline.util.WithModel;
import gov.nasa.jpl.aerie.banananation.Mission;
import org.jetbrains.annotations.NotNull;

import java.util.List;

/**
* A simple constraint that verifies access to the mission model through the WithModel interface
*/
@ConstraintProcedure
public record ModelIntegrationConstraint() implements Constraint, WithModel<Mission> {
@Override
public @NotNull Violations run(@NotNull Plan plan, @NotNull SimulationResults simResults) {
// Access the mission model through the WithModel interface
// This should work without ClassCastException if the class loader fix is working
final var mission = model();

// Simple constraint: fruit should never go below 2.0
final var lowFruit = simResults.resource(mission.fruit).lessThan(2.0);

return Violations.inside(lowFruit.highlightTrue());
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@WithMappers(BasicValueMappers.class)
package gov.nasa.jpl.aerie.e2e.procedural.scheduling;
package gov.nasa.jpl.aerie.e2e.procedural;

import gov.nasa.jpl.aerie.contrib.serialization.rulesets.BasicValueMappers;
import gov.nasa.ammos.aerie.procedural.scheduling.annotations.WithMappers;
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package gov.nasa.jpl.aerie.e2e.procedural.scheduling.procedures;

import gov.nasa.ammos.aerie.procedural.scheduling.Goal;
import gov.nasa.ammos.aerie.procedural.scheduling.annotations.SchedulingProcedure;
import gov.nasa.ammos.aerie.procedural.scheduling.plan.EditablePlan;
import gov.nasa.ammos.aerie.procedural.timeline.payloads.activities.DirectiveStart;
import gov.nasa.ammos.aerie.procedural.timeline.util.WithModel;
import gov.nasa.jpl.aerie.banananation.Mission;
import gov.nasa.jpl.aerie.merlin.protocol.types.SerializedValue;
import org.jetbrains.annotations.NotNull;

import java.util.Map;

/**
* Creates a bite banana every time /producer changes
*/
@SchedulingProcedure
public record ModelIntegrationGoal() implements Goal, WithModel<Mission> {
@Override
public void run(@NotNull final EditablePlan plan) {
final var changes = plan.simulate().resource(model().producer).changes().highlightTrue();
for (final var interval: changes) {
plan.create("BiteBanana", new DirectiveStart.Absolute(interval.start), Map.of("biteSize", SerializedValue.of(1)));
}
plan.commit();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package gov.nasa.jpl.aerie.e2e.procedural.scheduling;
package gov.nasa.jpl.aerie.e2e.procedural;

import com.microsoft.playwright.Playwright;
import gov.nasa.jpl.aerie.e2e.utils.GatewayRequests;
Expand All @@ -12,7 +12,7 @@
import java.io.IOException;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public abstract class ProceduralSchedulingSetup {
public abstract class ProceduralSetup {

// Requests
protected Playwright playwright;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package gov.nasa.jpl.aerie.e2e.procedural.constraints;

import gov.nasa.jpl.aerie.e2e.procedural.ProceduralSetup;
import gov.nasa.jpl.aerie.e2e.types.ConstraintInvocationId;
import gov.nasa.jpl.aerie.e2e.utils.GatewayRequests;
import gov.nasa.jpl.aerie.merlin.protocol.types.Duration;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import javax.json.Json;
import java.io.IOException;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class ModelIntegrationConstraintTests extends ProceduralSetup {
private int constraintJarId;
private ConstraintInvocationId constraintId;

@BeforeEach
void localBeforeEach() throws IOException {
try (final var gateway = new GatewayRequests(playwright)) {
constraintJarId = gateway.uploadJarFile("build/libs/ModelIntegrationConstraint.jar");
// Add Constraint Procedure
constraintId = hasura.insertPlanConstraintJar(
"Test Model Integration Constraint",
planId,
constraintJarId
);
}
}

@AfterEach
void localAfterEach() throws IOException {
hasura.deleteConstraint(constraintId.id());
}

@Test
void testModelIntegrationConstraint() throws IOException {
// Add an activity that will cause fruit to go below 2.0
hasura.insertActivityDirective(
planId,
"BiteBanana",
"1h",
Json.createObjectBuilder().add("biteSize", Json.createValue(4)).build()
);

// Simulate the plan
hasura.awaitSimulation(planId);

// Run constraints and check that our constraint can access the mission model
final var results = hasura.checkConstraints(planId);
final var run = results.constraintsRun().getFirst();

assertEquals("Test Model Integration Constraint", run.constraintName());

// The constraint should run without ClassCastException and detect violations
assertTrue(run.success());
assertEquals(1, run.result().get().violations().size());

assertEquals(Duration.hours(1), Duration.microseconds(run.result().get().violations().getFirst().windows().getFirst().start()));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package gov.nasa.jpl.aerie.e2e.procedural.scheduling;

import gov.nasa.jpl.aerie.e2e.procedural.ProceduralSetup;
import gov.nasa.jpl.aerie.e2e.types.GoalInvocationId;
import gov.nasa.jpl.aerie.e2e.utils.GatewayRequests;
import org.junit.jupiter.api.AfterEach;
Expand All @@ -10,13 +11,12 @@
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class AutoDeletionTests extends ProceduralSchedulingSetup {
public class AutoDeletionTests extends ProceduralSetup {
private GoalInvocationId edslId;
private GoalInvocationId procedureId;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package gov.nasa.jpl.aerie.e2e.procedural.scheduling;

import gov.nasa.jpl.aerie.e2e.procedural.ProceduralSetup;
import gov.nasa.jpl.aerie.e2e.types.GoalInvocationId;
import gov.nasa.jpl.aerie.e2e.utils.GatewayRequests;
import org.junit.jupiter.api.AfterEach;
Expand All @@ -13,7 +14,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class BasicTests extends ProceduralSchedulingSetup {
public class BasicTests extends ProceduralSetup {
private int procedureJarId;
private GoalInvocationId procedureId;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package gov.nasa.jpl.aerie.e2e.procedural.scheduling;

import gov.nasa.jpl.aerie.e2e.procedural.ProceduralSetup;
import gov.nasa.jpl.aerie.e2e.types.GoalInvocationId;
import gov.nasa.jpl.aerie.e2e.utils.GatewayRequests;
import org.junit.jupiter.api.AfterEach;
Expand All @@ -16,7 +17,7 @@
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class DatabaseDeletionTests extends ProceduralSchedulingSetup {
public class DatabaseDeletionTests extends ProceduralSetup {
private GoalInvocationId procedureId;

@BeforeEach
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package gov.nasa.jpl.aerie.e2e.procedural.scheduling;

import gov.nasa.jpl.aerie.e2e.procedural.ProceduralSetup;
import gov.nasa.jpl.aerie.e2e.types.GoalInvocationId;
import gov.nasa.jpl.aerie.e2e.utils.GatewayRequests;
import org.junit.jupiter.api.AfterEach;
Expand All @@ -14,7 +15,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class DeletionTests extends ProceduralSchedulingSetup {
public class DeletionTests extends ProceduralSetup {
private GoalInvocationId procedureId;

@BeforeEach
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package gov.nasa.jpl.aerie.e2e.procedural.scheduling;

import gov.nasa.jpl.aerie.e2e.procedural.ProceduralSetup;
import gov.nasa.jpl.aerie.e2e.types.GoalInvocationId;
import gov.nasa.jpl.aerie.e2e.types.Plan;
import gov.nasa.jpl.aerie.e2e.utils.GatewayRequests;
Expand All @@ -17,7 +18,7 @@

import static org.junit.jupiter.api.Assertions.assertEquals;

public class ExternalEventsSchedulingTests extends ProceduralSchedulingSetup {
public class ExternalEventsSchedulingTests extends ProceduralSetup {
private GoalInvocationId procedureId;
private final static String SOURCE_TYPE = "TestType";
private final static String EVENT_TYPE = "TestType";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gov.nasa.jpl.aerie.e2e.procedural.scheduling;

import gov.nasa.jpl.aerie.e2e.ExternalDatasetsTest;
import gov.nasa.jpl.aerie.e2e.procedural.ProceduralSetup;
import gov.nasa.jpl.aerie.e2e.types.GoalInvocationId;
import gov.nasa.jpl.aerie.e2e.utils.GatewayRequests;
import org.junit.jupiter.api.AfterEach;
Expand All @@ -14,7 +15,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class ExternalProfilesTests extends ProceduralSchedulingSetup {
public class ExternalProfilesTests extends ProceduralSetup {
private GoalInvocationId procedureId;
private int datasetId;

Expand Down
Loading
Loading