From 9ad1788d4248bb28f317eb6c759e518151b3e1b3 Mon Sep 17 00:00:00 2001 From: Alexandra Date: Wed, 19 Sep 2018 17:11:46 -0400 Subject: [PATCH] support for absolute paths for the log and database directories #627 --- .../org/aion/zero/impl/config/CfgAion.java | 176 ++++++++++-------- .../test/org/aion/zero/impl/cli/CliTest.java | 104 ++++------- 2 files changed, 135 insertions(+), 145 deletions(-) diff --git a/modAionImpl/src/org/aion/zero/impl/config/CfgAion.java b/modAionImpl/src/org/aion/zero/impl/config/CfgAion.java index 0280e6d33e..b08bee85a3 100644 --- a/modAionImpl/src/org/aion/zero/impl/config/CfgAion.java +++ b/modAionImpl/src/org/aion/zero/impl/config/CfgAion.java @@ -25,20 +25,33 @@ package org.aion.zero.impl.config; -import java.io.*; +import com.google.common.base.Objects; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.UUID; -import javax.xml.stream.*; -import com.google.common.base.Objects; -import org.aion.mcf.config.*; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; +import org.aion.mcf.config.Cfg; +import org.aion.mcf.config.CfgApi; +import org.aion.mcf.config.CfgDb; +import org.aion.mcf.config.CfgGui; +import org.aion.mcf.config.CfgLog; +import org.aion.mcf.config.CfgNet; +import org.aion.mcf.config.CfgReports; +import org.aion.mcf.config.CfgSync; +import org.aion.mcf.config.CfgTx; import org.aion.zero.exceptions.HeaderStructureException; import org.aion.zero.impl.AionGenesis; import org.aion.zero.impl.GenesisBlockLoader; -/** - * @author chris - */ +/** @author chris */ public final class CfgAion extends Cfg { private static String NETWORK = "mainnet"; @@ -52,7 +65,6 @@ public final class CfgAion extends Cfg { private static final String NODE_ID_PLACEHOLDER = "[NODE-ID-PLACEHOLDER]"; - public CfgAion() { this.mode = "aion"; this.id = UUID.randomUUID().toString(); @@ -105,8 +117,7 @@ public CfgConsensusPow getConsensus() { } public synchronized AionGenesis getGenesis() { - if (this.genesis == null) - setGenesis(); + if (this.genesis == null) setGenesis(); return this.genesis; } @@ -118,7 +129,7 @@ public static int getK() { return K; } - private void closeFileInputStream(final FileInputStream fis){ + private void closeFileInputStream(final FileInputStream fis) { if (fis != null) { try { fis.close(); @@ -136,25 +147,24 @@ public void dbFromXML() { try { fis = new FileInputStream(cfgFile); XMLStreamReader sr = input.createXMLStreamReader(fis); - loop: while (sr.hasNext()) { + loop: + while (sr.hasNext()) { int eventType = sr.next(); switch (eventType) { - case XMLStreamReader.START_ELEMENT: - String elementName = sr.getLocalName().toLowerCase(); - switch (elementName) { - case "db": - this.db.fromXML(sr); - break; - default: - skipElement(sr); - break; - } - break; - case XMLStreamReader.END_ELEMENT: - if (sr.getLocalName().toLowerCase().equals("aion")) - break loop; - else + case XMLStreamReader.START_ELEMENT: + String elementName = sr.getLocalName().toLowerCase(); + switch (elementName) { + case "db": + this.db.fromXML(sr); + break; + default: + skipElement(sr); + break; + } break; + case XMLStreamReader.END_ELEMENT: + if (sr.getLocalName().toLowerCase().equals("aion")) break loop; + else break; } } } catch (Exception e) { @@ -167,61 +177,60 @@ public void dbFromXML() { public boolean fromXML(final XMLStreamReader sr) throws XMLStreamException { boolean shouldWriteBackToFile = false; - loop: while (sr.hasNext()) { + loop: + while (sr.hasNext()) { int eventType = sr.next(); switch (eventType) { case XMLStreamReader.START_ELEMENT: String elementName = sr.getLocalName().toLowerCase(); switch (elementName) { - case "id": - String nodeId = readValue(sr); - if(NODE_ID_PLACEHOLDER.equals(nodeId)) { - this.id = UUID.randomUUID().toString(); - shouldWriteBackToFile = true; - } else { - this.id = nodeId; - } - break; - case "mode": - this.mode = readValue(sr); - break; - case "api": - this.api.fromXML(sr); - break; - case "net": - this.net.fromXML(sr); - break; - case "sync": - this.sync.fromXML(sr); - break; - case "consensus": - this.consensus.fromXML(sr); - break; - case "db": - this.db.fromXML(sr); - break; - case "log": - this.log.fromXML(sr); - break; - case "tx": - this.tx.fromXML(sr); - break; - case "reports": - this.reports.fromXML(sr); - break; - case "gui": - this.gui.fromXML(sr); - break; - default: - skipElement(sr); - break; + case "id": + String nodeId = readValue(sr); + if (NODE_ID_PLACEHOLDER.equals(nodeId)) { + this.id = UUID.randomUUID().toString(); + shouldWriteBackToFile = true; + } else { + this.id = nodeId; + } + break; + case "mode": + this.mode = readValue(sr); + break; + case "api": + this.api.fromXML(sr); + break; + case "net": + this.net.fromXML(sr); + break; + case "sync": + this.sync.fromXML(sr); + break; + case "consensus": + this.consensus.fromXML(sr); + break; + case "db": + this.db.fromXML(sr); + break; + case "log": + this.log.fromXML(sr); + break; + case "tx": + this.tx.fromXML(sr); + break; + case "reports": + this.reports.fromXML(sr); + break; + case "gui": + this.gui.fromXML(sr); + break; + default: + skipElement(sr); + break; } break; case XMLStreamReader.END_ELEMENT: - if (sr.getLocalName().toLowerCase().equals("aion")) - break loop; - else - break; + if (sr.getLocalName().toLowerCase().equals("aion")) break loop; + else break; } } return shouldWriteBackToFile; @@ -249,6 +258,19 @@ public boolean fromXML(File cfgFile) { System.out.println(""); System.exit(1); } + + // checks for absolute path for database + File db = new File(this.getDb().getPath()); + if (db.isAbsolute()) { + this.setDatabaseDirectory(db); + } + + // checks for absolute path for log + File log = new File(this.getLog().getLogPath()); + if (log.isAbsolute()) { + this.setLogDirectory(log); + } + return shouldWriteBackToFile; } @@ -279,8 +301,7 @@ public void toXML(final String[] args, File file) { if (subArgsArr.length > 0) { List _nodes = new ArrayList<>(); for (String subArg : subArgsArr) { - if (!subArg.equals("")) - _nodes.add(subArg); + if (!subArg.equals("")) _nodes.add(subArg); } this.getNet().setNodes(_nodes.toArray(new String[0])); } @@ -306,8 +327,7 @@ public void toXML(final String[] args, File file) { } } } - if (override) - System.out.println("Config Override"); + if (override) System.out.println("Config Override"); } XMLOutputFactory output = XMLOutputFactory.newInstance(); diff --git a/modAionImpl/test/org/aion/zero/impl/cli/CliTest.java b/modAionImpl/test/org/aion/zero/impl/cli/CliTest.java index 4e9a037d76..52a1177e96 100644 --- a/modAionImpl/test/org/aion/zero/impl/cli/CliTest.java +++ b/modAionImpl/test/org/aion/zero/impl/cli/CliTest.java @@ -66,7 +66,9 @@ public class CliTest { private static final String initialConfigFile = "test_resources/config.xml"; private static final String initialGenesisFile = "test_resources/genesis.json"; private static final String dataDirectory = "datadir"; + private static final String alternativeDirectory = "random"; private static final File path = new File(BASE_PATH, dataDirectory); + private static final File alternativePath = new File(BASE_PATH, alternativeDirectory); private static File config = BASE_PATH.contains(module) @@ -118,6 +120,7 @@ public void setup() { @After public void shutdown() { deleteRecursively(path); + deleteRecursively(alternativePath); // to avoid deleting config for all tests if (BASE_PATH.contains(module)) { @@ -303,6 +306,40 @@ private void printPaths(Cfg cfg) { + "\n----------------------------------------------------------------------------\n\n"); } + /** + * Ensures that the { -d, --datadir, -n, --network } arguments work + * with absolute paths for the database and log. The absolute path overwrites the datadir option + * location. + */ + @Test + @Parameters(method = "parametersWithDirectoryAndNetwork") + public void testDirectoryAndNetwork_wAbsoluteDbAndLogPath( + String[] input, ReturnType expectedReturn, String expectedPath) { + + String db = new File(alternativePath, "database").getAbsolutePath(); + cfg.getDb().setPath(db); + String log = new File(alternativePath, "log").getAbsolutePath(); + cfg.getLog().setLogPath(log); + + // save and reload for changes to take effect + cfg.toXML(null); + cfg.fromXML(); + + assertThat(cli.call(input, cfg)).isEqualTo(expectedReturn); + assertThat(cfg.getBasePath()).isEqualTo(expectedPath); + + assertThat(cfg.getDatabasePath()) + .isNotEqualTo(new File(expectedPath, "database").getAbsolutePath()); + assertThat(cfg.getDatabasePath()).isEqualTo(db); + + assertThat(cfg.getLogPath()).isNotEqualTo(new File(expectedPath, "log").getAbsolutePath()); + assertThat(cfg.getLogPath()).isEqualTo(log); + + if (verbose) { + printPaths(cfg); + } + } + /** Parameters for testing {@link #testConfig(String[], String)}. */ @SuppressWarnings("unused") private Object parametersWithConfig() { @@ -602,73 +639,6 @@ public void testInfo_execLocation(String option) { assertThat(cli.call(new String[] {option, "-d", dataDirectory}, cfg)).isEqualTo(EXIT); } - // /** - // * Sets up a spy Cli class that returns the String "password" when the cli.readPassword() - // is - // * called using any two params. - // */ - // @Before - // public void setup() throws IOException { - // doReturn("password").when(cli).readPassword(any(), any()); - // - // // Copies config folder recursively - // File src = new File(BASE_PATH + "/../modBoot/resource"); - // File dst = new File(BASE_PATH + "/config"); - // copyRecursively(src, dst); - // - // CfgAion.setConfFilePath(BASE_PATH + "/config/mainnet/config.xml"); - // CfgAion.setGenesisFilePath(BASE_PATH + "/config/mainnet/genesis.json"); - // Keystore.setKeystorePath(BASE_PATH + "/keystore"); - // } - // - // @After - // public void shutdown() { - // // Deletes created folders recursively - // File path1 = new File(BASE_PATH + "/aaaaaaaa"); - // File path2 = new File(BASE_PATH + "/abbbbbbb"); - // File path3 = new File(BASE_PATH + "/abcccccc"); - // File path4 = new File(BASE_PATH + "/keystore"); - // File path5 = new File(BASE_PATH + "/config"); - // if (path1.exists() - // || path2.exists() - // || path3.exists() - // || path4.exists() - // || path5.exists()) { - // deleteRecursively(path1); - // deleteRecursively(path2); - // deleteRecursively(path3); - // deleteRecursively(path4); - // deleteRecursively(path5); - // } - // - // CfgAion.setConfFilePath(BASE_PATH + "/config/mainnet/config.xml"); - // CfgAion.setGenesisFilePath(BASE_PATH + "/config/mainnet/genesis.json"); - // Keystore.setKeystorePath(BASE_PATH + "/keystore"); - // } - - // /** Ensures correct behavior for the -c and --config arguments. */ - // @Test - // public void testConfig() { - // // compatibility with old kernels - // assertEquals(EXIT, cli.call(new String[] {"-c"}, CfgAion.inst())); - // assertEquals(EXIT, cli.call(new String[] {"--config"}, CfgAion.inst())); - // - // // available networks - // for (Cli.Network net : Cli.Network.values()) { - // assertEquals(EXIT, cli.call(new String[] {"-c", net.toString()}, CfgAion.inst())); - // assertEquals(EXIT, cli.call(new String[] {"--config", net.toString()}, - // CfgAion.inst())); - // } - // - // // accepted alias - // assertEquals(EXIT, cli.call(new String[] {"-c", "testnet"}, CfgAion.inst())); - // assertEquals(EXIT, cli.call(new String[] {"--config", "testnet"}, CfgAion.inst())); - // - // // incorrect value - // assertEquals(ERROR, cli.call(new String[] {"-c", "random"}, CfgAion.inst())); - // assertEquals(ERROR, cli.call(new String[] {"--config", "random"}, CfgAion.inst())); - // } - /** Tests the -a create arguments work. */ @Test @Ignore