package net.sf.openrocket.file.openrocket; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import java.io.File; import java.io.FileFilter; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import net.sf.openrocket.ServicesForTesting; import net.sf.openrocket.database.ComponentPresetDao; import net.sf.openrocket.database.ComponentPresetDatabase; import net.sf.openrocket.database.motor.MotorDatabase; import net.sf.openrocket.database.motor.ThrustCurveMotorSetDatabase; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.StorageOptions; import net.sf.openrocket.file.GeneralRocketLoader; import net.sf.openrocket.file.RocketLoadException; import net.sf.openrocket.file.motor.GeneralMotorLoader; import net.sf.openrocket.l10n.DebugTranslator; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.motor.Motor; import net.sf.openrocket.motor.ThrustCurveMotor; import net.sf.openrocket.plugin.PluginModule; import net.sf.openrocket.simulation.extension.impl.ScriptingExtension; import net.sf.openrocket.simulation.extension.impl.ScriptingUtil; import net.sf.openrocket.startup.Application; import net.sf.openrocket.util.TestRockets; import org.junit.After; import org.junit.BeforeClass; import org.junit.Test; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Module; import com.google.inject.Provider; import com.google.inject.util.Modules; public class OpenRocketSaverTest { private OpenRocketSaver saver = new OpenRocketSaver(); private static final String TMP_DIR = "./tmp/"; public static final String SIMULATION_EXTENSION_SCRIPT = "// Test < &\n// >\n// <![CDATA["; private static Injector injector; @BeforeClass public static void setup() { Module applicationModule = new ServicesForTesting(); Module pluginModule = new PluginModule(); Module dbOverrides = new AbstractModule() { @Override protected void configure() { bind(ComponentPresetDao.class).toProvider(new EmptyComponentDbProvider()); bind(MotorDatabase.class).toProvider(new MotorDbProvider()); bind(Translator.class).toInstance(new DebugTranslator(null)); } }; injector = Guice.createInjector(Modules.override(applicationModule).with(dbOverrides), pluginModule); Application.setInjector(injector); File tmpDir = new File("./tmp"); if (!tmpDir.exists()) { boolean success = tmpDir.mkdirs(); if (!success) { fail("Unable to create core/tmp dir needed for tests."); } } } @After public void deleteRocketFilesFromTemp() { final String fileNameMatchStr = String.format("%s_.*\\.ork", this.getClass().getName()); File directory = new File(TMP_DIR); File[] toBeDeleted = directory.listFiles(new FileFilter() { @Override public boolean accept(File theFile) { if (theFile.isFile()) { if (theFile.getName().matches(fileNameMatchStr)) { return true; } } return false; } }); for (File deletableFile : toBeDeleted) { deletableFile.delete(); } } /** * Test for creating, saving, and loading various rockets with different file versions * * TODO: add a deep equality check to ensure no changes after save/read */ @Test public void testCreateLoadSave() { // Create rockets ArrayList<OpenRocketDocument> rocketDocs = new ArrayList<OpenRocketDocument>(); rocketDocs.add(TestRockets.makeTestRocket_v100()); rocketDocs.add(TestRockets.makeTestRocket_v101_withFinTabs()); rocketDocs.add(TestRockets.makeTestRocket_v101_withTubeCouplerChild()); // no version 1.2 file type exists // no version 1.3 file type exists rocketDocs.add(TestRockets.makeTestRocket_v104_withSimulationData()); rocketDocs.add(TestRockets.makeTestRocket_v104_withMotor()); rocketDocs.add(TestRockets.makeTestRocket_v105_withComponentPreset()); rocketDocs.add(TestRockets.makeTestRocket_v105_withCustomExpression()); rocketDocs.add(TestRockets.makeTestRocket_v105_withLowerStageRecoveryDevice()); rocketDocs.add(TestRockets.makeTestRocket_v106_withAppearance()); rocketDocs.add(TestRockets.makeTestRocket_v106_withMotorMountIgnitionConfig()); rocketDocs.add(TestRockets.makeTestRocket_v106_withRecoveryDeviceDeploymentConfig()); rocketDocs.add(TestRockets.makeTestRocket_v106_withStageSeparationConfig()); rocketDocs.add(TestRockets.makeTestRocket_v107_withSimulationExtension(SIMULATION_EXTENSION_SCRIPT)); rocketDocs.add(TestRockets.makeTestRocket_for_estimateFileSize()); StorageOptions options = new StorageOptions(); options.setSimulationTimeSkip(0.05); // Save rockets, load, validate for (OpenRocketDocument rocketDoc : rocketDocs) { File file = saveRocket(rocketDoc, options); OpenRocketDocument rocketDocLoaded = loadRocket(file.getPath()); assertNotNull(rocketDocLoaded); } } @Test public void testUntrustedScriptDisabledOnLoad() { OpenRocketDocument rocketDoc = TestRockets.makeTestRocket_v107_withSimulationExtension(SIMULATION_EXTENSION_SCRIPT); StorageOptions options = new StorageOptions(); File file = saveRocket(rocketDoc, options); OpenRocketDocument rocketDocLoaded = loadRocket(file.getPath()); assertEquals(1, rocketDocLoaded.getSimulations().size()); assertEquals(1, rocketDocLoaded.getSimulations().get(0).getSimulationExtensions().size()); ScriptingExtension ext = (ScriptingExtension) rocketDocLoaded.getSimulations().get(0).getSimulationExtensions().get(0); assertEquals(false, ext.isEnabled()); assertEquals(SIMULATION_EXTENSION_SCRIPT, ext.getScript()); } @Test public void testTrustedScriptEnabledOnLoad() { OpenRocketDocument rocketDoc = TestRockets.makeTestRocket_v107_withSimulationExtension("TESTING"); injector.getInstance(ScriptingUtil.class).setTrustedScript("JavaScript", "TESTING", true); StorageOptions options = new StorageOptions(); File file = saveRocket(rocketDoc, options); OpenRocketDocument rocketDocLoaded = loadRocket(file.getPath()); assertEquals(1, rocketDocLoaded.getSimulations().size()); assertEquals(1, rocketDocLoaded.getSimulations().get(0).getSimulationExtensions().size()); ScriptingExtension ext = (ScriptingExtension) rocketDocLoaded.getSimulations().get(0).getSimulationExtensions().get(0); assertEquals(true, ext.isEnabled()); assertEquals("TESTING", ext.getScript()); } /* * Test how accurate estimatedFileSize is. * * Actual file is 5822 Bytes * Estimated file is 440 Bytes (yeah....) */ @Test public void testEstimateFileSize() { OpenRocketDocument rocketDoc = TestRockets.makeTestRocket_v104_withSimulationData(); StorageOptions options = new StorageOptions(); options.setSimulationTimeSkip(0.05); long estimatedSize = saver.estimateFileSize(rocketDoc, options); // TODO: fix estimateFileSize so that it's a lot more accurate } //////////////////////////////// // Tests for File Version 1.0 // //////////////////////////////// @Test public void testFileVersion100() { OpenRocketDocument rocketDoc = TestRockets.makeTestRocket_v100(); assertEquals(100, getCalculatedFileVersion(rocketDoc)); } //////////////////////////////// // Tests for File Version 1.1 // //////////////////////////////// @Test public void testFileVersion101_withFinTabs() { OpenRocketDocument rocketDoc = TestRockets.makeTestRocket_v101_withFinTabs(); assertEquals(101, getCalculatedFileVersion(rocketDoc)); } @Test public void testFileVersion101_withTubeCouplerChild() { OpenRocketDocument rocketDoc = TestRockets.makeTestRocket_v101_withTubeCouplerChild(); assertEquals(101, getCalculatedFileVersion(rocketDoc)); } //////////////////////////////// // Tests for File Version 1.2 // //////////////////////////////// // no version 1.2 file type exists //////////////////////////////// // Tests for File Version 1.3 // //////////////////////////////// // no version 1.3 file type exists //////////////////////////////// // Tests for File Version 1.4 // //////////////////////////////// @Test public void testFileVersion104_withSimulationData() { OpenRocketDocument rocketDoc = TestRockets.makeTestRocket_v104_withSimulationData(); assertEquals(104, getCalculatedFileVersion(rocketDoc)); } @Test public void testFileVersion104_withMotor() { OpenRocketDocument rocketDoc = TestRockets.makeTestRocket_v104_withMotor(); assertEquals(104, getCalculatedFileVersion(rocketDoc)); } //////////////////////////////// // Tests for File Version 1.5 // //////////////////////////////// @Test public void testFileVersion105_withComponentPresets() { OpenRocketDocument rocketDoc = TestRockets.makeTestRocket_v105_withComponentPreset(); assertEquals(105, getCalculatedFileVersion(rocketDoc)); } @Test public void testFileVersion105_withCustomExpressions() { OpenRocketDocument rocketDoc = TestRockets.makeTestRocket_v105_withCustomExpression(); assertEquals(105, getCalculatedFileVersion(rocketDoc)); } @Test public void testFileVersion105_withLowerStageRecoveryDevice() { OpenRocketDocument rocketDoc = TestRockets.makeTestRocket_v105_withLowerStageRecoveryDevice(); assertEquals(105, getCalculatedFileVersion(rocketDoc)); } //////////////////////////////// // Tests for File Version 1.6 // //////////////////////////////// @Test public void testFileVersion106_withAppearance() { OpenRocketDocument rocketDoc = TestRockets.makeTestRocket_v106_withAppearance(); assertEquals(106, getCalculatedFileVersion(rocketDoc)); } @Test public void testFileVersion106_withMotorMountIgnitionConfig() { OpenRocketDocument rocketDoc = TestRockets.makeTestRocket_v106_withMotorMountIgnitionConfig(); assertEquals(106, getCalculatedFileVersion(rocketDoc)); } @Test public void testFileVersion106_withRecoveryDeviceDeploymentConfig() { OpenRocketDocument rocketDoc = TestRockets.makeTestRocket_v106_withRecoveryDeviceDeploymentConfig(); assertEquals(106, getCalculatedFileVersion(rocketDoc)); } @Test public void testFileVersion106_withStageDeploymentConfig() { OpenRocketDocument rocketDoc = TestRockets.makeTestRocket_v106_withStageSeparationConfig(); assertEquals(106, getCalculatedFileVersion(rocketDoc)); } //////////////////////////////// // Tests for File Version 1.7 // //////////////////////////////// @Test public void testFileVersion107_withSimulationExtension() { OpenRocketDocument rocketDoc = TestRockets.makeTestRocket_v107_withSimulationExtension(SIMULATION_EXTENSION_SCRIPT); assertEquals(107, getCalculatedFileVersion(rocketDoc)); } /* * Utility Functions */ private int getCalculatedFileVersion(OpenRocketDocument rocketDoc) { int fileVersion = this.saver.testAccessor_calculateNecessaryFileVersion(rocketDoc, null); return fileVersion; } private OpenRocketDocument loadRocket(String fileName) { GeneralRocketLoader loader = new GeneralRocketLoader(new File(fileName)); OpenRocketDocument rocketDoc = null; try { rocketDoc = loader.load(); } catch (RocketLoadException e) { e.printStackTrace(); fail("RocketLoadException while loading file " + fileName + " : " + e.getMessage()); } return rocketDoc; } private File saveRocket(OpenRocketDocument rocketDoc, StorageOptions options) { String fileName = String.format(TMP_DIR + "%s_%s.ork", this.getClass().getName(), rocketDoc.getRocket().getName()); File file = new File(fileName); OutputStream out = null; try { out = new FileOutputStream(file); this.saver.save(out, rocketDoc, options); } catch (FileNotFoundException e) { fail("FileNotFound saving file " + fileName + ": " + e.getMessage()); } catch (IOException e) { fail("IOException saving file " + fileName + ": " + e.getMessage()); } try { if (out != null) { out.close(); } } catch (IOException e) { fail("Unable to close output stream for file " + fileName + ": " + e.getMessage()); } return file; } private static ThrustCurveMotor readMotor() { GeneralMotorLoader loader = new GeneralMotorLoader(); InputStream is = OpenRocketSaverTest.class.getResourceAsStream("/net/sf/openrocket/Estes_A8.rse"); assertNotNull("Problem in unit test, cannot find Estes_A8.rse", is); try { for (Motor m : loader.load(is, "Estes_A8.rse")) { return (ThrustCurveMotor) m; } is.close(); } catch (IOException e) { e.printStackTrace(); fail("IOException: " + e); } throw new RuntimeException("Could not load motor"); } private static class EmptyComponentDbProvider implements Provider<ComponentPresetDao> { final ComponentPresetDao db = new ComponentPresetDatabase(); @Override public ComponentPresetDao get() { return db; } } private static class MotorDbProvider implements Provider<ThrustCurveMotorSetDatabase> { final ThrustCurveMotorSetDatabase db = new ThrustCurveMotorSetDatabase(); public MotorDbProvider() { db.addMotor(readMotor()); assertEquals(1, db.getMotorSets().size()); } @Override public ThrustCurveMotorSetDatabase get() { return db; } } }