-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Temporal Subset Sim e2e-test (WIP)
- Loading branch information
1 parent
9a29a63
commit 95cc3cc
Showing
4 changed files
with
417 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.