Add unit-tests for RASAero import

Could probably be elaborated more for the separate handlers... I'm just sick of RASAero importing at this point
This commit is contained in:
SiboVG 2023-02-23 21:50:57 +01:00
parent f26aced544
commit dfac4c6e56
3 changed files with 557 additions and 0 deletions

View File

@ -0,0 +1,178 @@
package net.sf.openrocket.file.rasaero.importt;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.document.OpenRocketDocumentFactory;
import net.sf.openrocket.file.DatabaseMotorFinder;
import net.sf.openrocket.file.DocumentLoadingContext;
import net.sf.openrocket.file.RocketLoadException;
import net.sf.openrocket.rocketcomponent.AxialStage;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.ExternalComponent;
import net.sf.openrocket.rocketcomponent.FinSet;
import net.sf.openrocket.rocketcomponent.NoseCone;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.Transition;
import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
import net.sf.openrocket.util.BaseTestCase.BaseTestCase;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
public class RASAeroLoaderTest extends BaseTestCase {
private static final double EPSILON = 0.0001;
/**
* Test loading a three stage RASAero rocket and verifying the parameters.
*/
@Test
public void testThreeStageRocket() {
RASAeroLoader loader = new RASAeroLoader();
InputStream stream = this.getClass().getResourceAsStream("Three-stage rocket.CDX1");
assertNotNull("Could not open Three-stage rocket.CDX1", stream);
try {
OpenRocketDocument doc = OpenRocketDocumentFactory.createEmptyRocket();
DocumentLoadingContext context = new DocumentLoadingContext();
context.setOpenRocketDocument(doc);
context.setMotorFinder(new DatabaseMotorFinder());
loader.loadFromStream(context, new BufferedInputStream(stream), null);
Rocket rocket = doc.getRocket();
assertNotNull(rocket);
// Test number and type of components
assertEquals("Incorrect amount of stages", 3, rocket.getChildCount());
AxialStage sustainer = rocket.getStage(0);
AxialStage booster1 = rocket.getStage(1);
AxialStage booster2 = rocket.getStage(2);
assertEquals("Incorrect amount of sustainer children", 2, sustainer.getChildCount());
assertEquals("Incorrect amount of booster 1 children", 1, booster1.getChildCount());
assertEquals("Incorrect amount of booster 2 children", 1, booster2.getChildCount());
RocketComponent noseCone = sustainer.getChild(0);
assertTrue("First component should be nose cone", noseCone instanceof NoseCone);
assertEquals(0, noseCone.getChildCount());
RocketComponent bodyTube = sustainer.getChild(1);
assertTrue("Second component should be body tube", bodyTube instanceof BodyTube);
assertEquals(1, bodyTube.getChildCount());
RocketComponent finSet = bodyTube.getChild(0);
assertTrue("Body tube child should be trapezoid fin set", finSet instanceof TrapezoidFinSet);
RocketComponent booster1Tube = booster1.getChild(0);
assertTrue("Booster child should be nose cone", booster1Tube instanceof BodyTube);
assertEquals(1, booster1Tube.getChildCount());
RocketComponent booster1FinSet = booster1Tube.getChild(0);
assertTrue("Booster 1 tube child should be trapezoid fin set", booster1FinSet instanceof TrapezoidFinSet);
RocketComponent booster2Tube = booster2.getChild(0);
assertTrue("Booster child should be nose cone", booster2Tube instanceof BodyTube);
assertEquals(1, booster2Tube.getChildCount());
RocketComponent booster2FinSet = booster2Tube.getChild(0);
assertTrue("Booster 1 tube child should be trapezoid fin set", booster2FinSet instanceof TrapezoidFinSet);
// Test component parameters
assertEquals("Three-stage rocket", rocket.getName());
//// Sustainer
NoseCone nose = (NoseCone) noseCone;
assertEquals(Transition.Shape.OGIVE, nose.getShapeType());
assertEquals(0.0125, nose.getBaseRadius(), EPSILON);
assertEquals(0.1, nose.getLength(), EPSILON);
assertEquals(0.002, nose.getThickness(), EPSILON);
assertEquals(ExternalComponent.Finish.MIRROR , nose.getFinish());
BodyTube tube = (BodyTube) bodyTube;
assertEquals(0.0125, tube.getOuterRadius(), EPSILON);
assertTrue(tube.isOuterRadiusAutomatic());
assertEquals(0.3, tube.getLength(), EPSILON);
assertEquals(0.002, tube.getThickness(), EPSILON);
assertEquals(ExternalComponent.Finish.MIRROR , tube.getFinish());
TrapezoidFinSet fins = (TrapezoidFinSet) finSet;
assertEquals(4, fins.getFinCount());
assertEquals(0, fins.getCantAngle(), EPSILON);
assertEquals(0.05, fins.getRootChord(), EPSILON);
assertEquals(0.05, fins.getTipChord(), EPSILON);
assertEquals(0.03, fins.getHeight(), EPSILON);
assertEquals(0.6947, fins.getSweepAngle() , EPSILON);
assertEquals(FinSet.CrossSection.SQUARE, fins.getCrossSection());
assertEquals(0.00201, fins.getThickness() , EPSILON);
assertEquals(ExternalComponent.Finish.MIRROR , fins.getFinish());
//// Booster 1
BodyTube tube1 = (BodyTube) booster1Tube;
assertEquals(0.0125, tube1.getOuterRadius(), EPSILON);
assertFalse(tube1.isOuterRadiusAutomatic());
assertEquals(0.08, tube1.getLength(), EPSILON);
assertEquals(0.002, tube1.getThickness(), EPSILON);
assertEquals(ExternalComponent.Finish.MIRROR , tube1.getFinish());
TrapezoidFinSet fins1 = (TrapezoidFinSet) booster1FinSet;
assertEquals(4, fins1.getFinCount());
assertEquals(0, fins1.getCantAngle(), EPSILON);
assertEquals(0.08, fins1.getRootChord(), EPSILON);
assertEquals(0.073, fins1.getTipChord(), EPSILON);
assertEquals(0.03, fins1.getHeight(), EPSILON);
assertEquals(0.6947, fins1.getSweepAngle() , EPSILON);
assertEquals(FinSet.CrossSection.SQUARE, fins1.getCrossSection());
assertEquals(0.00201, fins1.getThickness() , EPSILON);
assertEquals(ExternalComponent.Finish.MIRROR , fins1.getFinish());
//// Booster 2
BodyTube tube2 = (BodyTube) booster2Tube;
assertEquals(0.0125, tube2.getOuterRadius(), EPSILON);
assertFalse(tube2.isOuterRadiusAutomatic());
assertEquals(0.08, tube2.getLength(), EPSILON);
assertEquals(0.002, tube2.getThickness(), EPSILON);
assertEquals(ExternalComponent.Finish.MIRROR , tube2.getFinish());
TrapezoidFinSet fins2 = (TrapezoidFinSet) booster2FinSet;
assertEquals(4, fins2.getFinCount());
assertEquals(0, fins2.getCantAngle(), EPSILON);
assertEquals(0.08, fins2.getRootChord(), EPSILON);
assertEquals(0.03, fins2.getTipChord(), EPSILON);
assertEquals(0.04, fins2.getHeight(), EPSILON);
assertEquals(0.5584, fins2.getSweepAngle() , EPSILON);
assertEquals(FinSet.CrossSection.SQUARE, fins2.getCrossSection());
assertEquals(0.00201, fins2.getThickness() , EPSILON);
assertEquals(ExternalComponent.Finish.MIRROR , fins2.getFinish());
} catch (IllegalStateException ise) {
fail(ise.getMessage());
} catch (RocketLoadException | IOException e) {
throw new RuntimeException(e);
}
assertTrue(loader.getWarnings().isEmpty());
}
/**
* Test whether we can load a very complex rocket with practically all RASAero features.
*/
@Test
public void testShowRocket() {
RASAeroLoader loader = new RASAeroLoader();
InputStream stream = this.getClass().getResourceAsStream("Show-off.CDX1");
assertNotNull("Could not open Show-off.CDX1", stream);
try {
OpenRocketDocument doc = OpenRocketDocumentFactory.createEmptyRocket();
DocumentLoadingContext context = new DocumentLoadingContext();
context.setOpenRocketDocument(doc);
context.setMotorFinder(new DatabaseMotorFinder());
loader.loadFromStream(context, new BufferedInputStream(stream), null);
Rocket rocket = doc.getRocket();
assertNotNull(rocket);
} catch (IllegalStateException ise) {
fail(ise.getMessage());
} catch (RocketLoadException | IOException e) {
throw new RuntimeException(e);
}
assertEquals(5, loader.getWarnings().size());
}
}

View File

@ -0,0 +1,242 @@
<RASAeroDocument>
<FileVersion>2</FileVersion>
<RocketDesign>
<NoseCone>
<PartType>NoseCone</PartType>
<Length>1</Length>
<Diameter>1.5</Diameter>
<Shape>Tangent Ogive</Shape>
<BluntRadius>0</BluntRadius>
<Location>0</Location>
<Color>Black</Color>
</NoseCone>
<BodyTube>
<PartType>BodyTube</PartType>
<Length>7</Length>
<Diameter>1.5</Diameter>
<LaunchLugDiameter>0.2</LaunchLugDiameter>
<LaunchLugLength>0.4</LaunchLugLength>
<RailGuideDiameter>0</RailGuideDiameter>
<RailGuideHeight>0</RailGuideHeight>
<LaunchShoeArea>0</LaunchShoeArea>
<Location>1</Location>
<Color>Black</Color>
<BoattailLength>0</BoattailLength>
<BoattailRearDiameter>0</BoattailRearDiameter>
<BoattailOffset>0</BoattailOffset>
<Overhang>0</Overhang>
</BodyTube>
<FinCan>
<PartType>FinCan</PartType>
<Length>2.34</Length>
<Diameter>2.73</Diameter>
<InsideDiameter>1.5</InsideDiameter>
<LaunchLugDiameter>0</LaunchLugDiameter>
<LaunchLugLength>0</LaunchLugLength>
<RailGuideDiameter>0</RailGuideDiameter>
<RailGuideHeight>0</RailGuideHeight>
<LaunchShoeArea>0</LaunchShoeArea>
<Location>8</Location>
<ShoulderLength>0.23</ShoulderLength>
<Offset>-2.34</Offset>
<Color>Black</Color>
<Fin>
<Count>3</Count>
<Chord>1</Chord>
<Span>1</Span>
<SweepDistance>0</SweepDistance>
<TipChord>1</TipChord>
<Thickness>0.5</Thickness>
<LERadius>0</LERadius>
<Location>1</Location>
<AirfoilSection>Single Wedge</AirfoilSection>
<FX1>0</FX1>
<FX3>0</FX3>
</Fin>
</FinCan>
<BodyTube>
<PartType>BodyTube</PartType>
<Length>4</Length>
<Diameter>2.73</Diameter>
<LaunchLugDiameter>0</LaunchLugDiameter>
<LaunchLugLength>0</LaunchLugLength>
<RailGuideDiameter>0.25</RailGuideDiameter>
<RailGuideHeight>0.26</RailGuideHeight>
<LaunchShoeArea>0</LaunchShoeArea>
<Location>8</Location>
<Color>Black</Color>
<BoattailLength>0</BoattailLength>
<BoattailRearDiameter>0</BoattailRearDiameter>
<BoattailOffset>0</BoattailOffset>
<Overhang>0</Overhang>
</BodyTube>
<BodyTube>
<PartType>BodyTube</PartType>
<Length>5</Length>
<Diameter>2.73</Diameter>
<LaunchLugDiameter>0</LaunchLugDiameter>
<LaunchLugLength>0</LaunchLugLength>
<RailGuideDiameter>0</RailGuideDiameter>
<RailGuideHeight>0</RailGuideHeight>
<LaunchShoeArea>0</LaunchShoeArea>
<Location>12</Location>
<Color>Black</Color>
<BoattailLength>0</BoattailLength>
<BoattailRearDiameter>0</BoattailRearDiameter>
<BoattailOffset>0</BoattailOffset>
<Overhang>0</Overhang>
</BodyTube>
<BodyTube>
<PartType>BodyTube</PartType>
<Length>2</Length>
<Diameter>2.73</Diameter>
<LaunchLugDiameter>0</LaunchLugDiameter>
<LaunchLugLength>0</LaunchLugLength>
<RailGuideDiameter>0</RailGuideDiameter>
<RailGuideHeight>0</RailGuideHeight>
<LaunchShoeArea>0</LaunchShoeArea>
<Location>17</Location>
<Color>Black</Color>
<BoattailLength>1</BoattailLength>
<BoattailRearDiameter>0.25</BoattailRearDiameter>
<BoattailOffset>0</BoattailOffset>
<Overhang>0</Overhang>
</BodyTube>
<BoatTail>
<PartType>BoatTail</PartType>
<Length>1</Length>
<Diameter>2.73</Diameter>
<RearDiameter>0.25</RearDiameter>
<Location>19</Location>
<Color>Black</Color>
<Fin>
<Count>4</Count>
<Chord>0.5</Chord>
<Span>0.5</Span>
<SweepDistance>0</SweepDistance>
<TipChord>0.5</TipChord>
<Thickness>0.25</Thickness>
<LERadius>0</LERadius>
<Location>0.5</Location>
<AirfoilSection>Square</AirfoilSection>
<FX1>0</FX1>
<FX3>0</FX3>
</Fin>
</BoatTail>
<Booster>
<PartType>Booster</PartType>
<Length>2</Length>
<Diameter>2.73</Diameter>
<InsideDiameter>2.73</InsideDiameter>
<LaunchLugDiameter>0</LaunchLugDiameter>
<LaunchLugLength>0</LaunchLugLength>
<RailGuideDiameter>0</RailGuideDiameter>
<RailGuideHeight>0</RailGuideHeight>
<LaunchShoeArea>0</LaunchShoeArea>
<Location>19</Location>
<ShoulderLength>0</ShoulderLength>
<Color>Black</Color>
<NozzleExitDiameter>0</NozzleExitDiameter>
<BoattailLength>1</BoattailLength>
<BoattailRearDiameter>1</BoattailRearDiameter>
<Fin>
<Count>5</Count>
<Chord>1</Chord>
<Span>2</Span>
<SweepDistance>0</SweepDistance>
<TipChord>2</TipChord>
<Thickness>0.25</Thickness>
<LERadius>0</LERadius>
<Location>1</Location>
<AirfoilSection>Rounded</AirfoilSection>
<FX1>0</FX1>
<FX3>0</FX3>
</Fin>
</Booster>
<Surface>Smooth (Zero Roughness)</Surface>
<CP>0</CP>
<ModifiedBarrowman>False</ModifiedBarrowman>
<Turbulence>False</Turbulence>
<SustainerNozzle>0</SustainerNozzle>
<Booster1Nozzle>0</Booster1Nozzle>
<Booster2Nozzle>0</Booster2Nozzle>
<UseBooster1>False</UseBooster1>
<UseBooster2>False</UseBooster2>
<Comments>Comments are for suckers.</Comments>
</RocketDesign>
<LaunchSite>
<Altitude>410</Altitude>
<Pressure>2</Pressure>
<RodAngle>20</RodAngle>
<RodLength>4</RodLength>
<Temperature>74</Temperature>
<WindSpeed>1.34</WindSpeed>
</LaunchSite>
<Recovery>
<Altitude1>1000</Altitude1>
<Altitude2>1000</Altitude2>
<DeviceType1>Parachute</DeviceType1>
<DeviceType2>Parachute</DeviceType2>
<Event1>True</Event1>
<Event2>True</Event2>
<Size1>6</Size1>
<Size2>1</Size2>
<EventType1>Apogee</EventType1>
<EventType2>Altitude</EventType2>
<CD1>1</CD1>
<CD2>1.33</CD2>
</Recovery>
<MachAlt />
<SimulationList>
<Simulation>
<SustainerEngine>1/4A2 (AP)</SustainerEngine>
<SustainerLaunchWt>1</SustainerLaunchWt>
<SustainerNozzleDiameter>0</SustainerNozzleDiameter>
<SustainerCG>1</SustainerCG>
<SustainerIgnitionDelay>0</SustainerIgnitionDelay>
<Booster1Engine>A8 (ES)</Booster1Engine>
<Booster1LaunchWt>0</Booster1LaunchWt>
<Booster1SeparationDelay>0</Booster1SeparationDelay>
<Booster1IgnitionDelay>0</Booster1IgnitionDelay>
<Booster1CG>0</Booster1CG>
<Booster1NozzleDiameter>0</Booster1NozzleDiameter>
<IncludeBooster1>True</IncludeBooster1>
<Booster2Engine>A6Q (QU)</Booster2Engine>
<Booster2LaunchWt>0</Booster2LaunchWt>
<Booster2Delay>0</Booster2Delay>
<Booster2CG>0</Booster2CG>
<Booster2NozzleDiameter>0</Booster2NozzleDiameter>
<IncludeBooster2>False</IncludeBooster2>
<FlightTime>0</FlightTime>
<TimetoApogee>50.42754</TimetoApogee>
<MaxAltitude>3.758801</MaxAltitude>
<MaxVelocity>2.357251</MaxVelocity>
<OptimumWt>0</OptimumWt>
<OptimumMaxAlt>0</OptimumMaxAlt>
</Simulation>
<Simulation>
<SustainerEngine>C4 (AP)</SustainerEngine>
<SustainerLaunchWt>1</SustainerLaunchWt>
<SustainerNozzleDiameter>0</SustainerNozzleDiameter>
<SustainerCG>2</SustainerCG>
<SustainerIgnitionDelay>0</SustainerIgnitionDelay>
<Booster1LaunchWt>0</Booster1LaunchWt>
<Booster1SeparationDelay>0</Booster1SeparationDelay>
<Booster1IgnitionDelay>0</Booster1IgnitionDelay>
<Booster1CG>0</Booster1CG>
<Booster1NozzleDiameter>0</Booster1NozzleDiameter>
<IncludeBooster1>False</IncludeBooster1>
<Booster2LaunchWt>0</Booster2LaunchWt>
<Booster2Delay>0</Booster2Delay>
<Booster2CG>0</Booster2CG>
<Booster2NozzleDiameter>0</Booster2NozzleDiameter>
<IncludeBooster2>False</IncludeBooster2>
<FlightTime>0</FlightTime>
<TimetoApogee>1.479999</TimetoApogee>
<MaxAltitude>10.15928</MaxAltitude>
<MaxVelocity>29.81428</MaxVelocity>
<OptimumWt>0</OptimumWt>
<OptimumMaxAlt>0</OptimumMaxAlt>
</Simulation>
</SimulationList>
</RASAeroDocument>

View File

@ -0,0 +1,137 @@
<RASAeroDocument>
<FileVersion>2</FileVersion>
<RocketDesign>
<NoseCone>
<PartType>NoseCone</PartType>
<Length>3.937</Length>
<Diameter>0.984</Diameter>
<Shape>Tangent Ogive</Shape>
<BluntRadius>0</BluntRadius>
<Location>0</Location>
<Color>Black</Color>
</NoseCone>
<BodyTube>
<PartType>BodyTube</PartType>
<Length>11.811</Length>
<Diameter>0.984</Diameter>
<LaunchLugDiameter>0</LaunchLugDiameter>
<LaunchLugLength>0</LaunchLugLength>
<RailGuideDiameter>0</RailGuideDiameter>
<RailGuideHeight>0</RailGuideHeight>
<LaunchShoeArea>0</LaunchShoeArea>
<Location>3.937</Location>
<Color>Black</Color>
<BoattailLength>0</BoattailLength>
<BoattailRearDiameter>0</BoattailRearDiameter>
<BoattailOffset>0</BoattailOffset>
<Overhang>0</Overhang>
<Fin>
<Count>4</Count>
<Chord>1.969</Chord>
<Span>1.181</Span>
<SweepDistance>0.984</SweepDistance>
<TipChord>1.969</TipChord>
<Thickness>0.079</Thickness>
<LERadius>0</LERadius>
<Location>1.969</Location>
<AirfoilSection>Square</AirfoilSection>
<FX1>0</FX1>
<FX3>0</FX3>
</Fin>
</BodyTube>
<Booster>
<PartType>Booster</PartType>
<Length>3.15</Length>
<Diameter>0.984</Diameter>
<InsideDiameter>0.984</InsideDiameter>
<LaunchLugDiameter>0</LaunchLugDiameter>
<LaunchLugLength>0</LaunchLugLength>
<RailGuideDiameter>0</RailGuideDiameter>
<RailGuideHeight>0</RailGuideHeight>
<LaunchShoeArea>0</LaunchShoeArea>
<Location>15.748</Location>
<ShoulderLength>0</ShoulderLength>
<Color>Black</Color>
<NozzleExitDiameter>0</NozzleExitDiameter>
<BoattailLength>0</BoattailLength>
<BoattailRearDiameter>0</BoattailRearDiameter>
<Fin>
<Count>4</Count>
<Chord>3.15</Chord>
<Span>1.181</Span>
<SweepDistance>0.984</SweepDistance>
<TipChord>2.875</TipChord>
<Thickness>0.079</Thickness>
<LERadius>0</LERadius>
<Location>3.15</Location>
<AirfoilSection>Square</AirfoilSection>
<FX1>0</FX1>
<FX3>0</FX3>
</Fin>
</Booster>
<Booster>
<PartType>Booster</PartType>
<Length>3.15</Length>
<Diameter>0.984</Diameter>
<InsideDiameter>0.984</InsideDiameter>
<LaunchLugDiameter>0</LaunchLugDiameter>
<LaunchLugLength>0</LaunchLugLength>
<RailGuideDiameter>0</RailGuideDiameter>
<RailGuideHeight>0</RailGuideHeight>
<LaunchShoeArea>0</LaunchShoeArea>
<Location>18.898</Location>
<ShoulderLength>0</ShoulderLength>
<Color>Black</Color>
<NozzleExitDiameter>0</NozzleExitDiameter>
<BoattailLength>0</BoattailLength>
<BoattailRearDiameter>0</BoattailRearDiameter>
<Fin>
<Count>4</Count>
<Chord>3.15</Chord>
<Span>1.575</Span>
<SweepDistance>0.984</SweepDistance>
<TipChord>1.181</TipChord>
<Thickness>0.079</Thickness>
<LERadius>0</LERadius>
<Location>3.15</Location>
<AirfoilSection>Square</AirfoilSection>
<FX1>0</FX1>
<FX3>0</FX3>
</Fin>
</Booster>
<Surface>Smooth (Zero Roughness)</Surface>
<CP>0</CP>
<ModifiedBarrowman>False</ModifiedBarrowman>
<Turbulence>False</Turbulence>
<SustainerNozzle>0</SustainerNozzle>
<Booster1Nozzle>0</Booster1Nozzle>
<Booster2Nozzle>0</Booster2Nozzle>
<UseBooster1>False</UseBooster1>
<UseBooster2>False</UseBooster2>
<Comments />
</RocketDesign>
<LaunchSite>
<Altitude>3750</Altitude>
<Pressure>0</Pressure>
<RodAngle>7.64</RodAngle>
<RodLength>12</RodLength>
<Temperature>80</Temperature>
<WindSpeed>0</WindSpeed>
</LaunchSite>
<Recovery>
<Altitude1>1000</Altitude1>
<Altitude2>1000</Altitude2>
<DeviceType1>None</DeviceType1>
<DeviceType2>None</DeviceType2>
<Event1>False</Event1>
<Event2>False</Event2>
<Size1>1</Size1>
<Size2>1</Size2>
<EventType1>None</EventType1>
<EventType2>None</EventType2>
<CD1>1.33</CD1>
<CD2>1.33</CD2>
</Recovery>
<MachAlt />
<SimulationList />
</RASAeroDocument>