/* * Syncany, www.syncany.org * Copyright (C) 2011-2014 Philipp C. Heckel <philipp.heckel@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.syncany.tests.util; import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; import org.simpleframework.xml.core.Persister; import org.syncany.chunk.Chunker; import org.syncany.chunk.CipherTransformer; import org.syncany.chunk.GzipTransformer; import org.syncany.chunk.ZipMultiChunker; import org.syncany.config.Config; import org.syncany.config.UserConfig; import org.syncany.config.to.ConfigTO; import org.syncany.config.to.RepoTO; import org.syncany.config.to.RepoTO.ChunkerTO; import org.syncany.config.to.RepoTO.MultiChunkerTO; import org.syncany.config.to.RepoTO.TransformerTO; import org.syncany.crypto.CipherSpecs; import org.syncany.crypto.CipherUtil; import org.syncany.crypto.SaltedSecretKey; import org.syncany.operations.init.InitOperationOptions; import org.syncany.plugins.Plugins; import org.syncany.plugins.local.LocalTransferSettings; import org.syncany.plugins.transfer.TransferPlugin; import org.syncany.plugins.transfer.TransferSettings; import org.syncany.plugins.unreliable_local.UnreliableLocalTransferPlugin; import org.syncany.plugins.unreliable_local.UnreliableLocalTransferSettings; import com.google.common.collect.Lists; public class TestConfigUtil { private static final String RUNDATE = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); private static boolean cryptoEnabled = false; private static SaltedSecretKey masterKey = null; static { try { UserConfig.init(); // Load userconfig (include system properties, e.g. org.syncany.test.tmpdir) TestConfigUtil.cryptoEnabled = Boolean.parseBoolean(System.getProperty("crypto.enable")); } catch (Exception e) { TestConfigUtil.cryptoEnabled = false; } } public static Map<String, String> createTestLocalConnectionSettings() throws Exception { Map<String, String> pluginSettings = new HashMap<String, String>(); File tempRepoDir = TestFileUtil.createTempDirectoryInSystemTemp(createUniqueName("repo", new Random().nextFloat())); pluginSettings.put("path", tempRepoDir.getAbsolutePath()); return pluginSettings; } public static Config createTestLocalConfig() throws Exception { return createTestLocalConfig("syncanyclient"); } public static Config createTestLocalConfig(String machineName) throws Exception { return createTestLocalConfig(machineName, createTestLocalConnection()); } public static MultiChunkerTO createZipMultiChunkerTO() { Map<String, String> settings = new HashMap<String, String>(); settings.put(ZipMultiChunker.PROPERTY_SIZE, "4096"); MultiChunkerTO multiChunkerTO = new MultiChunkerTO(); multiChunkerTO.setType(ZipMultiChunker.TYPE); multiChunkerTO.setSettings(settings); return multiChunkerTO; } public static ChunkerTO createFixedChunkerTO() { Map<String, String> settings = new HashMap<String, String>(); settings.put(Chunker.PROPERTY_SIZE, "32768"); ChunkerTO chunkerTO = new ChunkerTO(); chunkerTO.setType("fixed"); chunkerTO.setSettings(settings); return chunkerTO; } public static RepoTO createRepoTO() { // Create Repo TO RepoTO repoTO = new RepoTO(); repoTO.setRepoId(new byte[] { 0x01, 0x02, 0x03 }); // Create ChunkerTO and MultiChunkerTO MultiChunkerTO multiChunkerTO = createZipMultiChunkerTO(); ChunkerTO chunkerTO = createFixedChunkerTO(); repoTO.setChunkerTO(chunkerTO); // TODO [low] Chunker not configurable right now. Not used. repoTO.setMultiChunker(multiChunkerTO); // Create TransformerTO List<TransformerTO> transformerTOs = createTransformerTOs(); repoTO.setTransformers(transformerTOs); return repoTO; } public static List<TransformerTO> createTransformerTOs() { if (!cryptoEnabled) { return null; } else { TransformerTO gzipTransformerTO = new TransformerTO(); gzipTransformerTO.setType(GzipTransformer.TYPE); Map<String, String> cipherTransformerSettings = new HashMap<String, String>(); cipherTransformerSettings.put(CipherTransformer.PROPERTY_CIPHER_SPECS, "1,2"); TransformerTO cipherTransformerTO = new TransformerTO(); cipherTransformerTO.setType(CipherTransformer.TYPE); cipherTransformerTO.setSettings(cipherTransformerSettings); return Lists.newArrayList(gzipTransformerTO, cipherTransformerTO); } } private static SaltedSecretKey getMasterKey() throws Exception { if (!cryptoEnabled) { return null; } else { if (masterKey == null) { masterKey = CipherUtil.createMasterKey("some password"); } return masterKey; } } public static Config createDummyConfig() throws Exception { ConfigTO configTO = new ConfigTO(); configTO.setMachineName("dummymachine"); RepoTO repoTO = new RepoTO(); repoTO.setTransformers(null); repoTO.setChunkerTO(createFixedChunkerTO()); repoTO.setMultiChunker(createZipMultiChunkerTO()); return new Config(new File("/dummy"), configTO, repoTO); } public static Config createTestLocalConfig(String machineName, TransferSettings connection) throws Exception { File tempLocalDir = TestFileUtil.createTempDirectoryInSystemTemp(createUniqueName("client-" + machineName, connection)); tempLocalDir.mkdirs(); RepoTO repoTO = createRepoTO(); // Create config TO ConfigTO configTO = new ConfigTO(); configTO.setMachineName(machineName + CipherUtil.createRandomAlphabeticString(20)); // Get Masterkey SaltedSecretKey masterKey = getMasterKey(); configTO.setMasterKey(masterKey); LocalTransferSettings localConnection = (LocalTransferSettings) connection; // Create connection TO Map<String, String> localConnectionSettings = new HashMap<String, String>(); localConnectionSettings.put("path", localConnection.getPath().getAbsolutePath()); configTO.setTransferSettings(connection); // Create Config config = new Config(tempLocalDir, configTO, repoTO); config.setConnection(connection); config.getAppDir().mkdirs(); config.getCacheDir().mkdirs(); config.getDatabaseDir().mkdirs(); config.getLogDir().mkdirs(); config.getStateDir().mkdirs(); // Write to config folder (required for some tests) new Persister().write(configTO, new File(config.getAppDir() + "/" + Config.FILE_CONFIG)); new Persister().write(repoTO, new File(config.getAppDir() + "/" + Config.FILE_REPO)); return config; } public static InitOperationOptions createTestInitOperationOptions(String machineName) throws Exception { File tempLocalDir = TestFileUtil.createTempDirectoryInSystemTemp(createUniqueName("client-" + machineName, machineName)); File tempRepoDir = TestFileUtil.createTempDirectoryInSystemTemp(createUniqueName("repo", machineName)); tempLocalDir.mkdirs(); tempRepoDir.mkdirs(); RepoTO repoTO = createRepoTO(); // Create config TO ConfigTO configTO = new ConfigTO(); configTO.setMachineName(machineName + Math.abs(new Random().nextInt())); // Get Masterkey SaltedSecretKey masterKey = getMasterKey(); configTO.setMasterKey(masterKey); // Generic connection settings wont work anymore, because they are plugin dependent now. LocalTransferSettings transferSettings = Plugins.get("local", TransferPlugin.class).createEmptySettings(); transferSettings.setPath(tempRepoDir); configTO.setTransferSettings(transferSettings); InitOperationOptions operationOptions = new InitOperationOptions(); operationOptions.setLocalDir(tempLocalDir); operationOptions.setConfigTO(configTO); operationOptions.setRepoTO(repoTO); operationOptions.setEncryptionEnabled(cryptoEnabled); operationOptions.setCipherSpecs(CipherSpecs.getDefaultCipherSpecs()); operationOptions.setPassword(cryptoEnabled ? "some password" : null); return operationOptions; } public static InitOperationOptions createTestUnreliableInitOperationOptions(String machineName, List<String> failingOperationPatterns) throws Exception { InitOperationOptions initOperationOptions = createTestInitOperationOptions(machineName); // createTestInitOperationOptions always returns LocalTransferSettings File tempRpoDir = ((LocalTransferSettings) initOperationOptions.getConfigTO().getTransferSettings()).getPath(); UnreliableLocalTransferSettings transferSettings = Plugins.get("unreliable_local", TransferPlugin.class).createEmptySettings(); transferSettings.setPath(tempRpoDir); transferSettings.setFailingOperationPatterns(failingOperationPatterns); initOperationOptions.getConfigTO().setTransferSettings(transferSettings); return initOperationOptions; } public static TransferSettings createTestLocalConnection() throws Exception { TransferPlugin plugin = Plugins.get("local", TransferPlugin.class); LocalTransferSettings conn = plugin.createEmptySettings(); File tempRepoDir = TestFileUtil.createTempDirectoryInSystemTemp(createUniqueName("repo", conn)); conn.setPath(tempRepoDir); // TODO [medium] : possible problem plugin.createTransferManager(conn, null).init(true); return conn; } public static UnreliableLocalTransferSettings createTestUnreliableLocalConnection(List<String> failingOperationPatterns) throws Exception { UnreliableLocalTransferPlugin unreliableLocalPlugin = new UnreliableLocalTransferPlugin(); UnreliableLocalTransferSettings unreliableLocalConnection = createTestUnreliableLocalConnectionWithoutInit(unreliableLocalPlugin, failingOperationPatterns); unreliableLocalPlugin.createTransferManager(unreliableLocalConnection, null).init(true); return unreliableLocalConnection; } public static UnreliableLocalTransferSettings createTestUnreliableLocalConnectionWithoutInit(UnreliableLocalTransferPlugin unreliableLocalPlugin, List<String> failingOperationPatterns) throws Exception { UnreliableLocalTransferSettings unreliableLocalConnection = unreliableLocalPlugin.createEmptySettings(); File tempRepoDir = TestFileUtil.createTempDirectoryInSystemTemp(createUniqueName("repo", new Random().nextFloat())); unreliableLocalConnection.setPath(tempRepoDir); unreliableLocalConnection.setFailingOperationPatterns(failingOperationPatterns); return unreliableLocalConnection; } public static void deleteTestLocalConfigAndData(Config config) { TestFileUtil.deleteDirectory(config.getLocalDir()); TestFileUtil.deleteDirectory(config.getCacheDir()); TestFileUtil.deleteDirectory(config.getDatabaseDir()); if (config.getAppDir() != null) { TestFileUtil.deleteDirectory(config.getAppDir()); } // TODO [low] workaround: delete empty parent folder of getAppDir() --> ROOT/app/.. --> ROOT/ config.getLocalDir().getParentFile().delete(); // if empty! deleteTestLocalConnection(config); } private static void deleteTestLocalConnection(Config config) { LocalTransferSettings connection = (LocalTransferSettings) config.getConnection(); TestFileUtil.deleteDirectory(connection.getPath()); } public static String createUniqueName(String name, Object uniqueHashObj) { return String.format("syncany-%s-%d-%s", RUNDATE, 10000 + uniqueHashObj.hashCode() % 89999, name); } public static void setCrypto(boolean cryptoEnabled) { TestConfigUtil.cryptoEnabled = cryptoEnabled; } public static boolean getCrypto() { return cryptoEnabled; } }