Skip to content

Commit

Permalink
Add Temporal Subset Sim e2e-test (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mythicaeda committed Mar 20, 2023
1 parent 9a29a63 commit 95cc3cc
Show file tree
Hide file tree
Showing 4 changed files with 417 additions and 0 deletions.
311 changes: 311 additions & 0 deletions e2e-tests/src/tests/temporal-subset-simulation.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,311 @@
import { expect, test } from '@playwright/test';
import req from '../utilities/requests.js';
import time from "../utilities/time.js";


/*
Tests various simulation and simulation template start and end time configurations.
On all tests, unless otherwise specified, these are the following values:
- Simulation's simulation_start_time: Plan Start (January 1, 2023, at 00:00:00 Z)
- Simulation's simulation_end_time: Halfway through plan (January 1, 2023, at 12:00:00 Z)
- Simulation Template's simulation_start_time: Halfway through plan (January 1, 2023, at 12:00:00 Z)
- Simulation Template's simulation_end_time: Plan End (January 2, 2023, at 00:00:00 Z)
*/

test.describe('Temporal Subset Simulation Config and Template Inputs: Exception Cases', () => {
const plan_start_timestamp = "2023-01-01T00:00:00+00:00";
const midway_plan_timestamp = "2023-01-01T12:00:00+00:00";
const plan_end_timestamp = "2023-01-02T00:00:00+00:00";

let mission_model_id: number;
let plan_id: number;
let simulation_id: number;
let simulation_template_id: number;

test.beforeEach(async ({ request }) => {
let rd = Math.random()*100000;
let jar_id = await req.uploadJarFile(request);
const model: MissionModelInsertInput = {
jar_id,
mission: 'aerie_e2e_tests',
name: 'Banananation (e2e tests)',
version: rd + "",
};
mission_model_id = await req.createMissionModel(request, model);
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)
};
plan_id = await req.createPlan(request, plan_input);
simulation_id = await req.getSimulationId(request, plan_id);
const simulation_template : InsertSimulationTemplateInput = {
model_id: mission_model_id,
arguments: {},
description: 'Template for Plan ' +plan_id
};
simulation_template_id = await req.insertAndAssociateSimulationTemplate(request, simulation_template, simulation_id );
const firstHalfActivity : ActivityInsertInput =
{
arguments : {
"duration": 1
},
plan_id: plan_id,
type : "ControllableDurationActivity",
start_offset : "1h"
};
const midpointActivity : ActivityInsertInput =
{
arguments : {
"duration": 2
},
plan_id: plan_id,
type : "ControllableDurationActivity",
start_offset : "12h"
};
const secondHalfActivity : ActivityInsertInput =
{
arguments : {
"duration": 3
},
plan_id: plan_id,
type : "ControllableDurationActivity",
start_offset : "14h"
};
await req.insertActivity(request, firstHalfActivity);
await req.insertActivity(request, midpointActivity);
await req.insertActivity(request, secondHalfActivity);
});
test.afterEach(async ({ request }) => {
// Delete Plan and Model cascades the rest of the cleanup
await req.deleteMissionModel(request, mission_model_id);
await req.deletePlan(request, plan_id);
});

// ~~~~~~~~ Exception Cases ~~~~~~~~ //
test('Simulation start time, end time are null; Template start time, end time are null', async ({ request }) => {
// Expect a 500 error bc of a RuntimeException
try{
await req.simulate(request, plan_id);
test.fail();
} catch(error) {
const err = error as Error;
expect(err.message).toEqual("internal error");
}
});
test('Simulation start time is defined, end time is null; Template start time, end time are null', async({request}) => {
// Expect a 500 error bc of a RuntimeException
const simulationBounds : UpdateSimulationBoundsInput = {
plan_id : plan_id,
simulation_start_time: plan_start_timestamp,
simulation_end_time: null
};
await req.updateSimulationBounds(request, simulationBounds);
try{
await req.simulate(request, plan_id);
test.fail();
} catch(error) {
const err = error as Error;
expect(err.message).toEqual("internal error");
}
});
test('Simulation start time is null, end time is defined; Template start time, end time are null', async({request}) => {
// Expect a 500 error bc of a RuntimeException
const simulationBounds : UpdateSimulationBoundsInput = {
plan_id : plan_id,
simulation_start_time: null,
simulation_end_time: midway_plan_timestamp
};
await req.updateSimulationBounds(request, simulationBounds);
try{
await req.simulate(request, plan_id);
test.fail();
} catch(error) {
const err = error as Error;
expect(err.message).toEqual("internal error");
}
});
test('Simulation start time, end time is null; Template start time is defined, end time is null', async({request}) => {
// Expect a 500 error bc of a RuntimeException
const templateBounds : UpdateSimulationTemplateBoundsInput = {
simulation_template_id : simulation_template_id,
simulation_start_time: plan_start_timestamp,
simulation_end_time: null
};
await req.updateSimulationTemplateBounds(request, templateBounds);
try{
await req.simulate(request, plan_id);
test.fail();
} catch(error) {
const err = error as Error;
expect(err.message).toEqual("internal error");
}
});
test('Simulation start time, end time is null; Template start time is null, end time is defined', async({request}) => {
// Expect a 500 error bc of a RuntimeException

});
test('Simulation start time is defined, end time is null; Template start time is defined, end time is null', async({request}) => {
// Expect a 500 error bc of a RuntimeException

});
test('Simulation start time is null, end time is defined; Template start time is null, end time is defined', async({request}) => {
// Expect a 500 error bc of a RuntimeException

});
});

test.describe('Temporal Subset Simulation Config and Template Inputs: Valid Cases', () => {
const plan_start_timestamp = "2023-01-01T00:00:00+00:00";
const midway_plan_timestamp = "2023-01-01T12:00:00+00:00";
const plan_end_timestamp = "2023-01-02T00:00:00+00:00";

let mission_model_id: number;
let plan_id: number;
let simulation_id: number;
let simulation_template_id: number;
let first_half_activity_id: number;
let midpoint_activity_id: number;
let second_half_activity_id: number;

test.beforeEach(async ({ request }, testInfo) => {
let rd = Math.random()*100000;
let jar_id = await req.uploadJarFile(request);
const model: MissionModelInsertInput = {
jar_id,
mission: 'aerie_e2e_tests',
name: 'Banananation (e2e tests)',
version: rd + "",
};
mission_model_id = await req.createMissionModel(request, model);
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)
};
plan_id = await req.createPlan(request, plan_input);
simulation_id = await req.getSimulationId(request, plan_id);
const simulation_template : InsertSimulationTemplateInput = {
model_id: mission_model_id,
arguments: {},
description: 'Template for Plan ' +plan_id
};
simulation_template_id = await req.insertAndAssociateSimulationTemplate(request, simulation_template, simulation_id);
const firstHalfActivity : ActivityInsertInput =
{
arguments : {
"duration": 1
},
plan_id: plan_id,
type : "ControllableDurationActivity",
start_offset : "1h"
};
const midpointActivity : ActivityInsertInput =
{
arguments : {
"duration": 2
},
plan_id: plan_id,
type : "ControllableDurationActivity",
start_offset : "12h"
};
const secondHalfActivity : ActivityInsertInput =
{
arguments : {
"duration": 3
},
plan_id: plan_id,
type : "ControllableDurationActivity",
start_offset : "14h"
};
first_half_activity_id = await req.insertActivity(request, firstHalfActivity);
midpoint_activity_id = await req.insertActivity(request, midpointActivity);
second_half_activity_id = await req.insertActivity(request, secondHalfActivity);
});
test.afterEach(async ({ request }, testInfo) => {
// Deleting Plan and Model cascades the rest of the cleanup
await req.deleteMissionModel(request, mission_model_id);
await req.deletePlan(request, plan_id);
});

test('Simulation start time, end time are defined; Template start time, end time are null', async ({ request }) => {
// Expect the first half of the plan to be simulated
const simulationBounds : UpdateSimulationBoundsInput = {
plan_id : plan_id,
simulation_start_time: plan_start_timestamp,
simulation_end_time: midway_plan_timestamp
};
await req.updateSimulationBounds(request, simulationBounds);

let simulationDatasetId = await awaitSimulation(request, plan_id);
await delay(1000); // Time for results to be written


let {canceled, simulation_start_time, simulation_end_time, simulated_activities} = await req.getSimulationDataset(request, simulationDatasetId);
expect(canceled).toEqual(false);
expect(simulation_start_time).toEqual(plan_start_timestamp);
expect(simulation_end_time).toEqual(midway_plan_timestamp);
expect(simulated_activities.length).toEqual(2);

let unfinishedActivity = simulated_activities.pop();
expect(unfinishedActivity.id).toEqual(midpoint_activity_id);
expect(unfinishedActivity.duration).toEqual(null);
expect(unfinishedActivity.startOffset).toEqual("12:00:00");
expect(unfinishedActivity.startTime).toEqual(midway_plan_timestamp);

let firstActivity = simulated_activities.pop();
expect(firstActivity.id).toEqual(first_half_activity_id);
expect(firstActivity.duration).toEqual("01:00:00");
expect(firstActivity.startOffset).toEqual("01:00:00");
expect(firstActivity.startTime).toEqual("2023-01-01T01:00:00+00:00");
});
test('Simulation start time, end time are null; Template start time, end time are defined', async ({ request }) => {
// Expect the second half of the plan to be simulated
});
test('Simulation start time is defined, end time is null; Template start time is null, end time are defined', async ({ request }) => {
// Expect the entire plan to be simulated
});
test('Simulation start time is null, end time is defined; Template start time is defined, end time is null', async({request}) => {
// Expect the simulation to have no duration
});
test('Simulation start time, end time is defined; Template start time, end time is defined', async({request}) => {
/*
In this test:
- Simulation's simulation_start_time: (March 17, 2023, at 02:00:00 Z)
- Simulation's simulation_end_time: (March 17, 2023, at 13:00:00 Z)
*/
// Expect the simulation to be 11 Hours long (02:00:00 Z to 13:00:00 Z)

});
});

test.describe('Temporal Subset Simulation Config: No Template', () => {
test('Simulation start time, end time are null', async ({ request }) => {
// Expect a 500 error bc of a RuntimeException
});
test('Simulation start time, end time are defined', async ({ request }) => {
// Expect the first half of the plan to be simulated
});
});

function delay(ms: number) {
return new Promise( resolve => setTimeout(resolve, ms) );
}

async function awaitSimulation(request, plan_id, ) {
let it = 0;
while (it++ < 10) {
const { reason, status, simulationDatasetId } = await req.simulate(request, plan_id);
if (!(status == "pending" || status == "incomplete")) {
if (!(status === "complete")) {
console.error(JSON.stringify({reason}, undefined, 4));
expect(status).toEqual("complete");
}
return simulationDatasetId;
}
await delay(1000);
}
throw Error("Simulation timed out after " + 10 + " iterations");
}
26 changes: 26 additions & 0 deletions e2e-tests/src/types/simulation.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ type SimulationTemplate = {
simulation_end_time: string | null;
};

type InsertSimulationTemplateInput = {
arguments: ArgumentsMap;
description: string;
model_id: number;
}

type UpdateSimulationTemplateBoundsInput = {
simulation_template_id: number,
simulation_start_time: string,
simulation_end_time: string
}

type Resource = {
name: string;
schema: ValueSchema;
Expand Down Expand Up @@ -54,3 +66,17 @@ type SimulationResponse = {
status: SimulationResponseStatus;
simulationDatasetId: number;
};

type SimulationDataset = {
canceled: boolean;
simulation_start_time: string;
simulation_end_time: string;
simulated_activities: SimulatedActivity[];
};

type SimulatedActivity = {
id: number;
duration: string | null;
startTime: string;
startOffset: string;
}
Loading

0 comments on commit 95cc3cc

Please sign in to comment.