Skip to content

Commit

Permalink
Tests
Browse files Browse the repository at this point in the history
  • Loading branch information
adrienmaillard committed Sep 21, 2023
1 parent 4b411cd commit 8edd004
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 1 deletion.
58 changes: 57 additions & 1 deletion e2e-tests/src/tests/bindings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,62 @@ test.describe.serial('Scheduler Bindings', () => {
status: 'failure',
reason: 'No mission model exists with id `MissionModelId[id=-1]`'
});
// Returns a 200 with a failure status if a invalid plan id is passed
// reason is "No plan exists with id `PlanId[id=-1]`"
response = await request.post(`${urls.SCHEDULER_URL}/schedulingDslTypescript`, {
data: {
action: {name: "schedulingDslTypescript"},
input: {missionModelId: mission_model_id, planId:-1},
request_query: "",
session_variables: admin.session}});
expect(response.status()).toEqual(200);
expect(await response.json()).toEqual({
status: 'failure',
reason: 'No plan exists with id `PlanId[id=-1]`'
});

//verify that when inserting an external dataset, the resource is generated in the constraints edsl
await request.post(`${urls.MERLIN_URL}/addExternalDataset`, {
data: {
action: {name: "addExternalDataset"},
input: {
planId: plan_id,
datasetStart:'2021-001T06:00:00.000',
profileSet: {'/my_other_boolean':{schema:{type:'boolean'},segments:[{duration:3600000000,dynamics:true}],type:'discrete'}},
simulationDatasetId: null
},
request_query: "",
session_variables: admin.session}});

let resourceTypesWithExternalResource = `export type Resource = {
"/peel": number,
"/fruit": {initial: number, rate: number, },
"/data/line_count": number,
"/my_other_boolean": boolean,
"/flag/conflicted": boolean,
"/plant": number,
"/flag": ( | "A" | "B"),
"/producer": string,
};
`;
// Returns a 200 with a success status and the resource types containing the external type
response = await request.post(`${urls.SCHEDULER_URL}/schedulingDslTypescript`, {
data: {
action: {name: "schedulingDslTypescript"},
input: {missionModelId: mission_model_id, planId:plan_id},
request_query: "",
session_variables: admin.session}});
let respBody = await response.json();
let found = false;
for(let file of respBody.typescriptFiles){
if(file.filePath == "file:///mission-model-generated-code.ts"){
expect(file.content.includes(resourceTypesWithExternalResource)).toEqual(true);
found = true;
}
}
expect(found).toEqual(true);
expect(response.status()).toEqual(200);
expect(respBody.status).toEqual('success');

// Returns a 200 with a success status if the ID is valid
response = await request.post(`${urls.SCHEDULER_URL}/schedulingDslTypescript`, {
Expand All @@ -649,7 +705,7 @@ test.describe.serial('Scheduler Bindings', () => {
input: {missionModelId: mission_model_id},
request_query: "",
session_variables: admin.session}});
let respBody = await response.json();
respBody = await response.json();
expect(response.status()).toEqual(200);
expect(respBody.status).toEqual('success');
expect(respBody.typescriptFiles).not.toBeNull();
Expand Down
109 changes: 109 additions & 0 deletions e2e-tests/src/tests/scheduler-external-datasets.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@

import {expect, test} from "@playwright/test";
import req, {awaitScheduling, awaitSimulation} from "../utilities/requests.js";
import time from "../utilities/time.js";

/*
This test uploads an external dataset and checks that it is possible to use an external resource in a scheduling goal
*/
test.describe.serial('Scheduling with external dataset', () => {
const rd = Math.random() * 100;
const plan_start_timestamp = "2021-001T00:00:00.000";
const plan_end_timestamp = "2021-001T12:00:00.000";

test('Main', async ({request}) => {
//upload bananation jar
const jar_id = await req.uploadJarFile(request);

const model: MissionModelInsertInput = {
jar_id,
mission: 'aerie_e2e_tests' + rd,
name: 'Banananation (e2e tests)' + rd,
version: '0.0.0' + rd,
};
const mission_model_id = await req.createMissionModel(request, model);
//delay for generation
await delay(2000);
const plan_input: CreatePlanInput = {
model_id: mission_model_id,
name: 'test_plan' + rd,
start_time: plan_start_timestamp,
duration: time.getIntervalFromDoyRange(plan_start_timestamp, plan_end_timestamp)
};
const plan_id = await req.createPlan(request, plan_input);

const profile_set = {
'/my_boolean': {
type: 'discrete',
schema: {
type: 'boolean',
},
segments: [
{ duration: 3600000000, dynamics: false },
{ duration: 3600000000, dynamics: true },
{ duration: 3600000000, dynamics: false },
],
},
};

const externalDatasetInput: ExternalDatasetInsertInput = {
plan_id,
dataset_start: plan_start_timestamp,
profile_set,
};

await req.insertExternalDataset(request, externalDatasetInput);

await awaitSimulation(request, plan_id);

const schedulingGoal1: SchedulingGoalInsertInput =
{
description: "Test goal",
model_id: mission_model_id,
name: "ForEachGrowPeel" + rd,
definition: `export default function myGoal() {
return Goal.CoexistenceGoal({
forEach: Discrete.Resource("/my_boolean").equal(true).assignGaps(false),
activityTemplate: ActivityTemplates.BiteBanana({
biteSize: 1,
}),
startsAt:TimingConstraint.singleton(WindowProperty.END)
})
}`
};

const first_goal_id = await req.insertSchedulingGoal(request, schedulingGoal1);

let plan_revision = await req.getPlanRevision(request, plan_id);

const schedulingSpecification: SchedulingSpecInsertInput = {
// @ts-ignore
horizon_end: plan_end_timestamp,
horizon_start: plan_start_timestamp,
plan_id: plan_id,
plan_revision: plan_revision,
simulation_arguments: {},
analysis_only: false
}
const scheduling_specification_id = await req.insertSchedulingSpecification(request, schedulingSpecification);

const priority = 0;
const specGoal: SchedulingSpecGoalInsertInput = {
goal_id: first_goal_id,
priority: priority,
specification_id: scheduling_specification_id,
};
await req.createSchedulingSpecGoal(request, specGoal);

await awaitScheduling(request, scheduling_specification_id);
const plan = await req.getPlan(request, plan_id)
expect(plan.activity_directives.length).toEqual(1);
expect(plan.activity_directives[0].startTime == "2021-001T02:00:00.000")
await req.deletePlan(request, plan_id);
await req.deleteMissionModel(request, mission_model_id)
});
});

function delay(ms: number) {
return new Promise( resolve => setTimeout(resolve, ms) );
}
Original file line number Diff line number Diff line change
Expand Up @@ -1716,6 +1716,42 @@ export default (): Goal => {
assertEquals("Fyffes", changeProducer.serializedActivity().getArguments().get("producer").asString().get());
}

@Test
void testExternalResource() {

final var myBooleanResource = new DiscreteProfile(
List.of(
new Segment<>(Interval.between(HOUR.times(2), HOUR.times(4)), SerializedValue.of(true))
)
).assignGaps(new DiscreteProfile(List.of(new Segment(Interval.FOREVER, SerializedValue.of(false)))));

final var results = runScheduler(
BANANANATION,
List.of(),
List.of(new SchedulingGoal(new GoalId(0L), """
export default (): Goal => {
return Goal.CoexistenceGoal({
activityTemplate: ActivityTemplates.PeelBanana({peelDirection: "fromStem"}),
forEach: Discrete.Resource(Resources["/my_boolean"]).equal(true),
startsAt: TimingConstraint.singleton(WindowProperty.START)
})
}""", true)),
List.of(),
PLANNING_HORIZON,
Optional.of(
new ExternalProfiles(
Map.of(),
Map.of("/my_boolean", myBooleanResource),
List.of(new ResourceType("/my_boolean", new ValueSchema.BooleanSchema()))))
);

assertEquals(1, results.scheduleResults.goalResults().size());
assertEquals(1, results.updatedPlan().size());
final var planByActivityType = partitionByActivityType(results.updatedPlan());
final var peelBanana = planByActivityType.get("PeelBanana").iterator().next();
assertEquals(HOUR.times(2), peelBanana.startOffset());
}

@Test
void testApplyWhen() {
final var growBananaDuration = Duration.of(1, Duration.SECONDS);
Expand Down

0 comments on commit 8edd004

Please sign in to comment.