Merge pull request #1753 from SiboVG/issue-1621
Write unit tests for flight events
This commit is contained in:
commit
b1777bb36b
@ -308,7 +308,7 @@ public class Simulation implements ChangeSource, Cloneable {
|
||||
*/
|
||||
public Status getStatus() {
|
||||
mutex.verify();
|
||||
if (status == Status.UPTODATE || status == Status.LOADED) {
|
||||
if (isStatusUpToDate(status)) {
|
||||
if (rocket.getFunctionalModID() != simulatedRocketID || !options.equals(simulatedConditions)) {
|
||||
status = Status.OUTDATED;
|
||||
}
|
||||
@ -331,6 +331,14 @@ public class Simulation implements ChangeSource, Cloneable {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true is the status indicates that the simulation data is up-to-date.
|
||||
* @param status status of the simulation to check for if its data is up-to-date
|
||||
*/
|
||||
public static boolean isStatusUpToDate(Status status) {
|
||||
return status == Status.UPTODATE || status == Status.LOADED || status == Status.EXTERNAL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -6,8 +6,6 @@ import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.simulation.exception.MotorIgnitionException;
|
||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||
import net.sf.openrocket.simulation.listeners.AbstractSimulationListener;
|
||||
import net.sf.openrocket.simulation.listeners.SimulationListener;
|
||||
import net.sf.openrocket.util.BaseTestCase.BaseTestCase;
|
||||
import net.sf.openrocket.util.TestRockets;
|
||||
import org.junit.Assert;
|
||||
@ -35,11 +33,9 @@ public class DisableStageTest extends BaseTestCase {
|
||||
simDisabled.getOptions().setISAAtmosphere(true);
|
||||
simDisabled.getOptions().setTimeStep(0.05);
|
||||
|
||||
SimulationListener simulationListener = new AbstractSimulationListener();
|
||||
|
||||
// Since there are no stages, the simulation should throw an exception.
|
||||
try {
|
||||
simDisabled.simulate(simulationListener);
|
||||
simDisabled.simulate();
|
||||
} catch (SimulationException e) {
|
||||
if (!(e instanceof MotorIgnitionException)) {
|
||||
Assert.fail("Simulation should have thrown a MotorIgnitionException");
|
||||
@ -56,7 +52,7 @@ public class DisableStageTest extends BaseTestCase {
|
||||
|
||||
simDisabled.getActiveConfiguration().setAllStages(); // Re-enable all stages.
|
||||
|
||||
compareSims(simOriginal, simDisabled, simulationListener, delta);
|
||||
compareSims(simOriginal, simDisabled, delta);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,9 +79,7 @@ public class DisableStageTest extends BaseTestCase {
|
||||
simDisabled.getOptions().setISAAtmosphere(true);
|
||||
simDisabled.getOptions().setTimeStep(0.05);
|
||||
|
||||
SimulationListener simulationListener = new AbstractSimulationListener();
|
||||
|
||||
compareSims(simRemoved, simDisabled, simulationListener, delta);
|
||||
compareSims(simRemoved, simDisabled, delta);
|
||||
|
||||
//// Test re-enableing the stage.
|
||||
Rocket rocketOriginal = TestRockets.makeBeta();
|
||||
@ -96,7 +90,7 @@ public class DisableStageTest extends BaseTestCase {
|
||||
|
||||
simDisabled.getActiveConfiguration().setAllStages();
|
||||
|
||||
compareSims(simOriginal, simDisabled, simulationListener, delta);
|
||||
compareSims(simOriginal, simDisabled, delta);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,9 +167,7 @@ public class DisableStageTest extends BaseTestCase {
|
||||
simDisabled.getOptions().setISAAtmosphere(true);
|
||||
simDisabled.getOptions().setTimeStep(0.05);
|
||||
|
||||
SimulationListener simulationListener = new AbstractSimulationListener();
|
||||
|
||||
compareSims(simRemoved, simDisabled, simulationListener, delta);
|
||||
compareSims(simRemoved, simDisabled, delta);
|
||||
|
||||
//// Test re-enableing the stage.
|
||||
Rocket rocketOriginal = TestRockets.makeFalcon9Heavy();
|
||||
@ -186,7 +178,7 @@ public class DisableStageTest extends BaseTestCase {
|
||||
|
||||
simDisabled.getActiveConfiguration().setAllStages();
|
||||
|
||||
compareSims(simOriginal, simDisabled, simulationListener, delta);
|
||||
compareSims(simOriginal, simDisabled, delta);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -214,11 +206,9 @@ public class DisableStageTest extends BaseTestCase {
|
||||
simDisabled.getOptions().setISAAtmosphere(true);
|
||||
simDisabled.getOptions().setTimeStep(0.05);
|
||||
|
||||
SimulationListener simulationListener = new AbstractSimulationListener();
|
||||
|
||||
// There should be no motors left at this point, so a no motors exception should be thrown
|
||||
try {
|
||||
simRemoved.simulate(simulationListener);
|
||||
simRemoved.simulate();
|
||||
} catch (SimulationException e) {
|
||||
if (!(e instanceof MotorIgnitionException)) {
|
||||
Assert.fail("Simulation failed: " + e);
|
||||
@ -226,7 +216,7 @@ public class DisableStageTest extends BaseTestCase {
|
||||
}
|
||||
|
||||
try {
|
||||
simDisabled.simulate(simulationListener);
|
||||
simDisabled.simulate();
|
||||
} catch (SimulationException e) {
|
||||
if (!(e instanceof MotorIgnitionException)) {
|
||||
Assert.fail("Simulation failed: " + e);
|
||||
@ -242,7 +232,7 @@ public class DisableStageTest extends BaseTestCase {
|
||||
|
||||
simDisabled.getActiveConfiguration().setAllStages();
|
||||
|
||||
compareSims(simOriginal, simDisabled, simulationListener, delta);
|
||||
compareSims(simOriginal, simDisabled, delta);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -259,13 +249,11 @@ public class DisableStageTest extends BaseTestCase {
|
||||
* - groundHitVelocity
|
||||
* @param simExpected the expected simulation results
|
||||
* @param simActual the actual simulation results
|
||||
* @param simulationListener the simulation listener to use for the comparison
|
||||
* @param delta the error margin for the comparison (e.g. 0.05 = 5 % error margin)
|
||||
*/
|
||||
private void compareSims(Simulation simExpected, Simulation simActual,
|
||||
SimulationListener simulationListener, double delta) {
|
||||
private void compareSims(Simulation simExpected, Simulation simActual, double delta) {
|
||||
try {
|
||||
simExpected.simulate(simulationListener);
|
||||
simExpected.simulate();
|
||||
double maxAltitudeOriginal = simExpected.getSimulatedData().getMaxAltitude();
|
||||
double maxVelocityOriginal = simExpected.getSimulatedData().getMaxVelocity();
|
||||
double maxMachNumberOriginal = simExpected.getSimulatedData().getMaxMachNumber();
|
||||
@ -274,7 +262,7 @@ public class DisableStageTest extends BaseTestCase {
|
||||
double launchRodVelocityOriginal = simExpected.getSimulatedData().getLaunchRodVelocity();
|
||||
double deploymentVelocityOriginal = simExpected.getSimulatedData().getDeploymentVelocity();
|
||||
|
||||
simActual.simulate(simulationListener);
|
||||
simActual.simulate();
|
||||
double maxAltitudeDisabled = simActual.getSimulatedData().getMaxAltitude();
|
||||
double maxVelocityDisabled = simActual.getSimulatedData().getMaxVelocity();
|
||||
double maxMachNumberDisabled = simActual.getSimulatedData().getMaxMachNumber();
|
||||
|
107
core/test/net/sf/openrocket/simulation/FlightEventsTest.java
Normal file
107
core/test/net/sf/openrocket/simulation/FlightEventsTest.java
Normal file
@ -0,0 +1,107 @@
|
||||
package net.sf.openrocket.simulation;
|
||||
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||
import net.sf.openrocket.util.BaseTestCase.BaseTestCase;
|
||||
import net.sf.openrocket.util.TestRockets;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
/**
|
||||
* Tests to verify that simulations contain all the expected flight events.
|
||||
*/
|
||||
public class FlightEventsTest extends BaseTestCase {
|
||||
/**
|
||||
* Tests for a single stage design.
|
||||
*/
|
||||
@Test
|
||||
public void testSingleStage() throws SimulationException {
|
||||
Rocket rocket = TestRockets.makeEstesAlphaIII();
|
||||
Simulation sim = new Simulation(rocket);
|
||||
sim.getOptions().setISAAtmosphere(true);
|
||||
sim.getOptions().setTimeStep(0.05);
|
||||
sim.setFlightConfigurationId(TestRockets.TEST_FCID_0);
|
||||
|
||||
sim.simulate();
|
||||
|
||||
// Test branch count
|
||||
int branchCount = sim.getSimulatedData().getBranchCount();
|
||||
assertEquals(" Single stage simulation invalid branch count", 1, branchCount);
|
||||
|
||||
FlightEvent.Type[] expectedEventTypes = {FlightEvent.Type.LAUNCH, FlightEvent.Type.IGNITION, FlightEvent.Type.LIFTOFF,
|
||||
FlightEvent.Type.LAUNCHROD, FlightEvent.Type.BURNOUT, FlightEvent.Type.EJECTION_CHARGE, FlightEvent.Type.RECOVERY_DEVICE_DEPLOYMENT,
|
||||
FlightEvent.Type.APOGEE, FlightEvent.Type.GROUND_HIT, FlightEvent.Type.SIMULATION_END};
|
||||
|
||||
// Test event count
|
||||
FlightDataBranch branch = sim.getSimulatedData().getBranch(0);
|
||||
List<FlightEvent> eventList = branch.getEvents();
|
||||
List<FlightEvent.Type> eventTypes = eventList.stream().map(FlightEvent::getType).collect(Collectors.toList());
|
||||
assertEquals(" Single stage simulation invalid number of events", expectedEventTypes.length, eventTypes.size());
|
||||
|
||||
// Test that all expected events are present, and in the right order
|
||||
for (int i = 0; i < expectedEventTypes.length; i++) {
|
||||
assertSame(" Flight type " + expectedEventTypes[i] + " not found in single stage simulation",
|
||||
eventTypes.get(i), expectedEventTypes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for a multi-stage design.
|
||||
*/
|
||||
@Test
|
||||
public void testMultiStage() throws SimulationException {
|
||||
Rocket rocket = TestRockets.makeFalcon9Heavy();
|
||||
Simulation sim = new Simulation(rocket);
|
||||
sim.getOptions().setISAAtmosphere(true);
|
||||
sim.getOptions().setTimeStep(0.05);
|
||||
rocket.getSelectedConfiguration().setAllStages();
|
||||
FlightConfigurationId fcid = rocket.getSelectedConfiguration().getFlightConfigurationID();
|
||||
sim.setFlightConfigurationId(fcid);
|
||||
|
||||
sim.simulate();
|
||||
|
||||
// Test branch count
|
||||
int branchCount = sim.getSimulatedData().getBranchCount();
|
||||
assertEquals(" Multi-stage simulation invalid branch count", 3, branchCount);
|
||||
|
||||
for (int b = 0; b < 3; b++) {
|
||||
FlightEvent.Type[] expectedEventTypes;
|
||||
switch (b) {
|
||||
case 0:
|
||||
expectedEventTypes = new FlightEvent.Type[]{FlightEvent.Type.LAUNCH, FlightEvent.Type.IGNITION, FlightEvent.Type.IGNITION,
|
||||
FlightEvent.Type.LIFTOFF, FlightEvent.Type.LAUNCHROD, FlightEvent.Type.APOGEE, FlightEvent.Type.BURNOUT,
|
||||
FlightEvent.Type.BURNOUT, FlightEvent.Type.EJECTION_CHARGE, FlightEvent.Type.EJECTION_CHARGE,
|
||||
FlightEvent.Type.STAGE_SEPARATION, FlightEvent.Type.STAGE_SEPARATION, FlightEvent.Type.TUMBLE, FlightEvent.Type.GROUND_HIT,
|
||||
FlightEvent.Type.SIMULATION_END};
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
expectedEventTypes = new FlightEvent.Type[]{FlightEvent.Type.TUMBLE, FlightEvent.Type.GROUND_HIT,
|
||||
FlightEvent.Type.SIMULATION_END};
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Invalid branch number " + b);
|
||||
}
|
||||
|
||||
// Test event count
|
||||
FlightDataBranch branch = sim.getSimulatedData().getBranch(b);
|
||||
List<FlightEvent> eventList = branch.getEvents();
|
||||
List<FlightEvent.Type> eventTypes = eventList.stream().map(FlightEvent::getType).collect(Collectors.toList());
|
||||
assertEquals(" Multi-stage simulation, branch " + b + " invalid number of events", expectedEventTypes.length, eventTypes.size());
|
||||
|
||||
// Test that all expected events are present, and in the right order
|
||||
for (int i = 0; i < expectedEventTypes.length; i++) {
|
||||
assertSame(" Flight type " + expectedEventTypes[i] + ", branch " + b + " not found in multi-stage simulation",
|
||||
eventTypes.get(i), expectedEventTypes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -504,8 +504,7 @@ public class SimulationPanel extends JPanel {
|
||||
|
||||
private void openDialog(final Simulation sim) {
|
||||
boolean plotMode = false;
|
||||
if (sim.hasSimulationData() && (sim.getStatus() == Status.UPTODATE || sim.getStatus() == Status.LOADED
|
||||
|| sim.getStatus() == Status.EXTERNAL)) {
|
||||
if (sim.hasSimulationData() && Simulation.isStatusUpToDate(sim.getStatus())) {
|
||||
plotMode = true;
|
||||
}
|
||||
openDialog(plotMode, sim);
|
||||
|
@ -60,7 +60,7 @@ import org.jfree.ui.RectangleInsets;
|
||||
import org.jfree.ui.TextAnchor;
|
||||
|
||||
/*
|
||||
* It should be possible to simplify this code quite a bit by using a single Renderer instance for
|
||||
* TODO: It should be possible to simplify this code quite a bit by using a single Renderer instance for
|
||||
* both datasets and the legend. But for now, the renderers are queried for the line color information
|
||||
* and this is held in the Legend.
|
||||
*/
|
||||
|
@ -857,8 +857,8 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
// Re-run the present simulation(s)
|
||||
List<Simulation> sims = new LinkedList<>();
|
||||
for (Simulation sim : document.getSimulations()) {
|
||||
if (sim.getStatus() == Simulation.Status.UPTODATE || sim.getStatus() == Simulation.Status.LOADED
|
||||
|| !document.getRocket().getFlightConfiguration(sim.getFlightConfigurationId()).hasMotors())
|
||||
if (Simulation.isStatusUpToDate(sim.getStatus()) ||
|
||||
!document.getRocket().getFlightConfiguration(sim.getFlightConfigurationId()).hasMotors())
|
||||
continue;
|
||||
|
||||
// Find a Simulation based on the current flight configuration
|
||||
|
@ -292,8 +292,7 @@ public class SimulationEditDialog extends JDialog {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// If the simulation is out of date, run the simulation.
|
||||
if (simulationList[0].getStatus() != Simulation.Status.UPTODATE &&
|
||||
simulationList[0].getStatus() != Simulation.Status.LOADED) {
|
||||
if (!Simulation.isStatusUpToDate(simulationList[0].getStatus())) {
|
||||
new SimulationRunDialog(SimulationEditDialog.this.parentWindow, document, simulationList[0]).setVisible(true);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user