diff options
author | Jiri Vanek <[email protected]> | 2013-12-02 16:04:32 +0100 |
---|---|---|
committer | Jiri Vanek <[email protected]> | 2013-12-02 16:04:32 +0100 |
commit | 77f5431e3b77c3d16693de34c21189d3f960ec41 (patch) | |
tree | ecced48bc4b7d1de33ad38cb066a6c6db9b88504 | |
parent | 57a108d5385a5810cf627d9d70792379d4c27000 (diff) |
Better validation of crytical dirs with proper message on startup
8 files changed, 697 insertions, 17 deletions
@@ -1,5 +1,20 @@ 2013-11-29 Jiri Vanek <[email protected]> + Better validation of crytical dirs with proper message on startup + * netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java: small + refactoring to match the new directory validator pattern. + * netx/net/sourceforge/jnlp/config/DirectoryValidator.java: new class to verify + if directory have necessary permissions (like creating subdirectories, + read and write files created in). + * netx/net/sourceforge/jnlp/resources/Messages.properties: patterns for + validation results + * netx/net/sourceforge/jnlp/runtime/Boot.java: headless determination moved + as up as possible in (main) + * tests/netx/unit/net/sourceforge/jnlp/config/DeploymentConfigurationTest.java: + Few test testing what DirtectoryValidator should validate. + +2013-11-29 Jiri Vanek <[email protected]> + Pipes moved into XDG_RUNTIME_DIR * plugin/icedteanp/IcedTeaNPPlugin.cc: (initialize_data_directory) logic responsible for tmp dir path moved into (getTmpPath) and (data_directory) diff --git a/netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java b/netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java index 02a4933..a132864 100644 --- a/netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java +++ b/netx/net/sourceforge/jnlp/config/DeploymentConfiguration.java @@ -36,6 +36,7 @@ import java.util.Properties; import java.util.Set; import javax.naming.ConfigurationException; +import javax.swing.JOptionPane; import net.sourceforge.jnlp.cache.CacheLRUWrapper; import net.sourceforge.jnlp.runtime.JNLPRuntime; @@ -213,9 +214,9 @@ public final class DeploymentConfiguration { /** is it mandatory to load the system properties? */ private boolean systemPropertiesMandatory = false; - /** The system's deployment.config file */ + /** The system's subdirResult deployment.config file */ private File systemPropertiesFile = null; - /** The user's deployment.config file */ + /** The user's subdirResult deployment.config file */ private File userPropertiesFile = null; /*default user file*/ @@ -280,7 +281,7 @@ public final class DeploymentConfiguration { Map<String, Setting<String>> systemProperties = null; /* - * First, try to read the system's deployment.config file to find if + * First, try to read the system's subdirResult deployment.config file to find if * there is a system-level deployment.poperties file */ @@ -304,7 +305,7 @@ public final class DeploymentConfiguration { } /* - * Third, read the user's deployment.properties file + * Third, read the user's subdirResult deployment.properties file */ userPropertiesFile = userFile; Map<String, Setting<String>> userProperties = loadProperties(ConfigType.User, userPropertiesFile, false); @@ -713,6 +714,8 @@ public final class DeploymentConfiguration { int errors = 0; String PRE_15_DEPLOYMENT_DIR = ".icedtea"; String LEGACY_USER_HOME = System.getProperty("user.home") + File.separator + PRE_15_DEPLOYMENT_DIR; + File configDir = new File(Defaults.USER_CONFIG_HOME); + File cacheDir = new File(Defaults.USER_CACHE_HOME); File legacyUserDir = new File(LEGACY_USER_HOME); if (legacyUserDir.exists()) { OutputController.getLogger().log(OutputController.Level.MESSAGE_ALL, "Legacy configuration and cache found. Those will be now transported to new locations"); @@ -723,11 +726,9 @@ public final class DeploymentConfiguration { OutputController.getLogger().log(OutputController.Level.MESSAGE_ALL, "Preparing new directories:"); OutputController.getLogger().log(OutputController.Level.MESSAGE_ALL, " " + Defaults.USER_CONFIG_HOME); - File f1 = new File(Defaults.USER_CONFIG_HOME); - errors += resultToStd(f1.mkdirs()); + errors += resultToStd(configDir.mkdirs()); OutputController.getLogger().log(OutputController.Level.MESSAGE_ALL, " " + Defaults.USER_CACHE_HOME); - File f2 = new File(Defaults.USER_CACHE_HOME); - errors += resultToStd(f2.mkdirs()); + errors += resultToStd(cacheDir.mkdirs()); String legacySecurity = LEGACY_USER_HOME + File.separator + "security"; String currentSecurity = Defaults.USER_SECURITY; @@ -786,16 +787,23 @@ public final class DeploymentConfiguration { } else { OutputController.getLogger().log("System is already following XDG .cache and .config specifications"); try { - OutputController.getLogger().log("config: " + Defaults.USER_CONFIG_HOME + " file exists: " + new File(Defaults.USER_CONFIG_HOME).exists()); + OutputController.getLogger().log("config: " + Defaults.USER_CONFIG_HOME + " file exists: " + configDir.exists()); } catch (Exception ex) { OutputController.getLogger().log(ex); } try { - OutputController.getLogger().log("cache: " + Defaults.USER_CACHE_HOME + " file exists:" + new File(Defaults.USER_CACHE_HOME)); + OutputController.getLogger().log("cache: " + Defaults.USER_CACHE_HOME + " file exists:" + cacheDir.exists()); } catch (Exception ex) { OutputController.getLogger().log(ex); } } + //this call should endure even if (ever) will migration code be removed + DirectoryValidator.DirectoryCheckResults r = new DirectoryValidator().ensureDirs(); + if (!JNLPRuntime.isHeadless()) { + if (r.getFailures() > 0) { + JOptionPane.showMessageDialog(null, r.getMessage()); + } + } } diff --git a/netx/net/sourceforge/jnlp/config/DirectoryValidator.java b/netx/net/sourceforge/jnlp/config/DirectoryValidator.java new file mode 100644 index 0000000..3d526fd --- /dev/null +++ b/netx/net/sourceforge/jnlp/config/DirectoryValidator.java @@ -0,0 +1,379 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package net.sourceforge.jnlp.config; + +import static net.sourceforge.jnlp.runtime.Translator.R; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import net.sourceforge.jnlp.runtime.JNLPRuntime; +import net.sourceforge.jnlp.util.FileUtils; +import net.sourceforge.jnlp.util.logging.OutputController; + +/** + * + * @author jvanek + */ +public class DirectoryValidator { + + /** + * This class is holding results of directory validation. + * Various errors like can not read, write create dir can apeear + * For sumaries of results are here getPasses, getFailures methods + * + * Individual results can be read from results field, or converted to string + */ + public static class DirectoryCheckResults { + public final List<DirectoryCheckResult> results; + + /** + * Wraps results so we can make some statistics or convert to message + * @param results + */ + public DirectoryCheckResults(List<DirectoryCheckResult> results) { + this.results = results; + } + + /** + * + * @return sum of passed checks, 0-3 per result + */ + public int getPasses() { + int passes = 0; + for (DirectoryCheckResult directoryCheckResult : results) { + passes += directoryCheckResult.getPasses(); + } + return passes; + } + + /** + * + * @return sum of failed checks, 0-3 per results + */ + public int getFailures() { + int failures = 0; + for (DirectoryCheckResult directoryCheckResult : results) { + failures += directoryCheckResult.getFailures(); + } + return failures; + } + + /** + * The result have one reuslt per line, separated by \n + * as is inherited from result.getMessage() method. + * + * @return all results connected. + */ + public String getMessage(){ + return resultsToString(results); + } + + /** + * using getMessage + * @return + */ + @Override + public String toString() { + return getMessage(); + } + + + + public static String resultsToString(List<DirectoryCheckResult> results) { + StringBuilder sb = new StringBuilder(); + for (DirectoryCheckResult r : results) { + if (r.getFailures() >0 ){ + sb.append(r.getMessage()); + } + } + return sb.toString(); + } + + } + + /** + * Is storing result of directory validation. + * + * validated are existence of directory + * whether it is directory + * if it have read/write permissions + */ + public static class DirectoryCheckResult { + + //do exist? + public boolean exists = true; + //is dir? + public boolean isDir = true; + //can be read, written to? + public boolean correctPermissions = true; + //have correct subdir? - this implies soe rules, when subdirecotry of some + //particular directory have weeker permissions + public DirectoryCheckResult subDir = null; + //actual tested directory + private final File testedDir; + + public DirectoryCheckResult(File testedDir) { + this.testedDir = testedDir; + } + + public static String notExistsMessage(File f) { + return R("DCmaindircheckNotexists", f.getAbsolutePath()); + } + + public static String notDirMessage(File f) { + return R("DCmaindircheckNotdir", f.getAbsolutePath()); + } + + public static String wrongPermissionsMessage(File f) { + return R("DCmaindircheckRwproblem", f.getAbsolutePath()); + } + + private static int booleanToInt(boolean b) { + if (b) { + return 1; + } else { + return 0; + } + } + + + /** + * count passes of this result (0-3, both inclusive). + */ + public int getPasses() { + int subdirs = 0; + if (subDir != null) { + subdirs = subDir.getPasses(); + } + return booleanToInt(exists) + + booleanToInt(isDir) + + booleanToInt(correctPermissions) + + subdirs; + } + + /* + * count failures of this result (0-3, both inclusive). + */ + public int getFailures() { + int max = 3; + if (subDir != null) { + max = 2 * max; + } + return max - getPasses(); + } + + /** + * Convert results to string. + * Each failure by line. PAsses are not mentioned + * The subdirectory (and it subdirectories are included to ) + * + * @return string with \n, or/and ended by \n + */ + public String getMessage() { + StringBuilder sb = new StringBuilder(); + if (!exists) { + sb.append(notExistsMessage(testedDir)).append("\n"); + } + if (!isDir) { + sb.append(notDirMessage(testedDir)).append("\n"); + } + if (!correctPermissions) { + sb.append(wrongPermissionsMessage(testedDir)).append("\n"); + } + + if (subDir != null) { + String s = subDir.getMessage(); + if (!s.isEmpty()) { + sb.append(s); + } + } + return sb.toString(); + } + + @Override + public String toString() { + return getMessage(); + } + } + + + private final List<File> dirsToCheck; + + + /** + * Creates DirectoryValidator to ensure given directories + * + * @param dirsToCheck + */ + public DirectoryValidator(List<File> dirsToCheck) { + this.dirsToCheck = dirsToCheck; + } + + + /** + * Creates DirectoryValidator to ensure directories read from + * user (if any - default otherwise ) settings via keys: + * <li>KEY_USER_CACHE_DIR</li> + * <li>KEY_USER_PERSISTENCE_CACHE_DIR</li> + * <li>KEY_SYSTEM_CACHE_DIR</li> + * <li>KEY_USER_LOG_DIR</li> + * <li>KEY_USER_TMP_DIR</li> + * <li>KEY_USER_LOCKS_DIR</li> + */ + public DirectoryValidator() { + dirsToCheck = new ArrayList<File>(6); + DeploymentConfiguration dc = JNLPRuntime.getConfiguration(); + String[] keys = new String[]{ + DeploymentConfiguration.KEY_USER_CACHE_DIR, + DeploymentConfiguration.KEY_USER_PERSISTENCE_CACHE_DIR, + DeploymentConfiguration.KEY_SYSTEM_CACHE_DIR, + DeploymentConfiguration.KEY_USER_LOG_DIR, + DeploymentConfiguration.KEY_USER_TMP_DIR, + DeploymentConfiguration.KEY_USER_LOCKS_DIR}; + for (String key : keys) { + String value = dc.getProperty(key); + if (value == null) { + OutputController.getLogger().log(OutputController.Level.MESSAGE_DEBUG, "WARNING: key " + key + " has no value, setting to default value"); + value = Defaults.getDefaults().get(key).getValue(); + } + if (value == null) { + if (JNLPRuntime.isDebug()) { + OutputController.getLogger().log(OutputController.Level.MESSAGE_DEBUG, "WARNING: key " + key + " has no value, skipping"); + } + continue; + } + File f = new File(value); + dirsToCheck.add(f); + } + } + + /** + * This method is ensuring, that specified directories will exists after + * call and will have enough permissions. + * + * This methods is trying to create the directories if they are not present + * and is testing if can be written inside. All checks are done in bulk. If + * one or more defect is found, user is warned via dialogue in gui mode + * (again in bulk). In headless mode stdout/stderr is enough, as application + * (both gui and headless) should not stop to work, but continue to run with + * hope that corrupted dirs will not be necessary + */ + public DirectoryCheckResults ensureDirs() { + return ensureDirs(dirsToCheck); + } + + static DirectoryCheckResults ensureDirs(List<File> dirs) { + List<DirectoryCheckResult> result = new ArrayList<DirectoryCheckResult>(dirs.size()); + for (File f : dirs) { + if (f.exists()) { + DirectoryCheckResult r = testDir(f, true, true); + result.add(r); + continue; + } + if (!f.mkdirs()) { + OutputController.getLogger().log(OutputController.Level.ERROR_DEBUG, "ERROR: Directory " + f.getAbsolutePath() + " does not exist and has not been created"); + } else { + OutputController.getLogger().log(OutputController.Level.MESSAGE_DEBUG,"OK: Directory " + f.getAbsolutePath() + " did not exist but has been created"); + } + DirectoryCheckResult r = testDir(f, true, true); + result.add(r); + } + return new DirectoryCheckResults(result); + } + + /** + * This method is package private for testing purposes only. + * + * This method verify that directory exists, is directory, file and + * directory can be created, file can be written into, and subdirectory can + * be written into. + * + * Some steps may looks like redundant, but some permission settings really + * alow to create file but not directory and vice versa. Also some settings + * can allow to create file or directory which can not be written into. (eg + * ACL or network disks) + */ + static DirectoryCheckResult testDir(File f, boolean verbose, boolean testSubdir) { + DirectoryCheckResult result = new DirectoryCheckResult(f); + if (!f.exists()) { + if (verbose) { + OutputController.getLogger().log(OutputController.Level.ERROR_ALL, DirectoryCheckResult.notExistsMessage(f)); + } + result.exists = false; + } + if (!f.isDirectory()) { + if (verbose) { + OutputController.getLogger().log(OutputController.Level.ERROR_ALL, DirectoryCheckResult.notDirMessage(f)); + } + result.isDir = false; + } + File testFile = null; + boolean correctPermissions = true; + try { + testFile = File.createTempFile("maindir", "check", f); + if (!testFile.exists()) { + correctPermissions = false; + } + try { + FileUtils.saveFile("ww", testFile); + String s = FileUtils.loadFileAsString(testFile); + if (!s.trim().equals("ww")) { + correctPermissions = false; + } + } catch (Exception ex) { + if (JNLPRuntime.isDebug()) { + ex.printStackTrace(); + } + correctPermissions = false; + } + File[] canList = f.listFiles(); + if (canList == null || canList.length == 0) { + correctPermissions = false; + } + testFile.delete(); + if (testFile.exists()) { + correctPermissions = false; + } else { + boolean created = testFile.mkdir(); + if (!created) { + correctPermissions = false; + } + if (testFile.exists()) { + if (testSubdir) { + DirectoryCheckResult subdirResult = testDir(testFile, verbose, false); + if (subdirResult.getFailures() != 0) { + result.subDir = subdirResult; + correctPermissions = false; + } + testFile.delete(); + if (testFile.exists()) { + correctPermissions = false; + } + } + } else { + correctPermissions = false; + } + } + } catch (Exception ex) { + if (JNLPRuntime.isDebug()) { + ex.printStackTrace(); + } + correctPermissions = false; + } finally { + if (testFile != null && testFile.exists()) { + testFile.delete(); + } + } + if (!correctPermissions) { + if (verbose) { + OutputController.getLogger().log(OutputController.Level.ERROR_ALL, DirectoryCheckResult.wrongPermissionsMessage(f)); + } + result.correctPermissions = false; + } + return result; + + } +} diff --git a/netx/net/sourceforge/jnlp/resources/Messages.properties b/netx/net/sourceforge/jnlp/resources/Messages.properties index 2e5fb82..15844e3 100644 --- a/netx/net/sourceforge/jnlp/resources/Messages.properties +++ b/netx/net/sourceforge/jnlp/resources/Messages.properties @@ -304,6 +304,9 @@ DCIncorrectValue=Property "{0}" has incorrect value "{1}". Possible values {2}. DCInternal=Internal error: {0} DCSourceInternal=<internal> DCUnknownSettingWithName=Property "{0}" is unknown. +DCmaindircheckNotexists=After all attempts, your configuration directory {0} do not exists. +DCmaindircheckNotdir=Your configuration directory {0} is not directory. +DCmaindircheckRwproblem=Your configuration directory {0} can not be read/written properly. # Value Validator messages. Messages should follow "Possible values ..." VVPossibleValues=Possible values {0} diff --git a/netx/net/sourceforge/jnlp/runtime/Boot.java b/netx/net/sourceforge/jnlp/runtime/Boot.java index 3f774cf..1ef0b6b 100644 --- a/netx/net/sourceforge/jnlp/runtime/Boot.java +++ b/netx/net/sourceforge/jnlp/runtime/Boot.java @@ -124,11 +124,15 @@ public final class Boot implements PrivilegedAction<Void> { * Launch the JNLP file specified by the command-line arguments. */ public static void main(String[] argsIn) { + args = argsIn; + if (AppContext.getAppContext() == null) { SunToolkit.createNewAppContext(); } + if (null != getOption("-headless")) + JNLPRuntime.setHeadless(true); + DeploymentConfiguration.move14AndOlderFilesTo15StructureCatched(); - args = argsIn; if (null != getOption("-viewer")) { @@ -170,9 +174,6 @@ public final class Boot implements PrivilegedAction<Void> { JNLPRuntime.setDefaultUpdatePolicy(new UpdatePolicy(value * 1000l)); } - if (null != getOption("-headless")) - JNLPRuntime.setHeadless(true); - if (null != getOption("-noupdate")) JNLPRuntime.setDefaultUpdatePolicy(UpdatePolicy.NEVER); diff --git a/tests/netx/unit/net/sourceforge/jnlp/config/DeploymentConfigurationTest.java b/tests/netx/unit/net/sourceforge/jnlp/config/DeploymentConfigurationTest.java index 1d047ea..3c1a4ed 100644 --- a/tests/netx/unit/net/sourceforge/jnlp/config/DeploymentConfigurationTest.java +++ b/tests/netx/unit/net/sourceforge/jnlp/config/DeploymentConfigurationTest.java @@ -69,4 +69,4 @@ public class DeploymentConfigurationTest { assertTrue(target.size() != 0); } -} + } diff --git a/tests/netx/unit/net/sourceforge/jnlp/config/DirectoryValidatorTest.java b/tests/netx/unit/net/sourceforge/jnlp/config/DirectoryValidatorTest.java new file mode 100644 index 0000000..19e049e --- /dev/null +++ b/tests/netx/unit/net/sourceforge/jnlp/config/DirectoryValidatorTest.java @@ -0,0 +1,272 @@ +/* + Copyright (C) 2012 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea 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, version 2. + + IcedTea 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 IcedTea; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. + */ +package net.sourceforge.jnlp.config; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import net.sourceforge.jnlp.util.logging.NoStdOutErrTest; +import org.junit.Test; + +public class DirectoryValidatorTest extends NoStdOutErrTest{ + + @Test + public void testMainDirTestNotExists() { + DirectoryValidator.DirectoryCheckResult result = DirectoryValidator.testDir(new File("/definitely/not/existing/file/efgrhisaes"), false, false); + String s = result.getMessage(); + assertTrue(s.endsWith("\n")); + assertTrue(s.split("\n").length == 3); + } + + @Test + public void testMainDirTestExistsAsFile() throws IOException { + File f = File.createTempFile("test", "testMainDirs"); + f.deleteOnExit(); + DirectoryValidator.DirectoryCheckResult result = DirectoryValidator.testDir(f, false, false); + String s = result.getMessage(); + assertTrue(s.endsWith("\n")); + assertTrue(s.split("\n").length == 2); + } + + @Test + public void testMainDirTestExistsAsDir() throws IOException { + File f = File.createTempFile("test", "testMainDirs"); + assertTrue(f.delete()); + assertTrue(f.mkdir()); + f.deleteOnExit(); + DirectoryValidator.DirectoryCheckResult result = DirectoryValidator.testDir(f, false, false); + String s = result.getMessage(); + assertTrue(s.isEmpty()); + } + + @Test + public void testMainDirTestExistsAsDirButNotWritable() throws IOException { + File f = File.createTempFile("test", "testMainDirs"); + assertTrue(f.delete()); + assertTrue(f.mkdir()); + assertTrue(f.setWritable(false)); + f.deleteOnExit(); + DirectoryValidator.DirectoryCheckResult result = DirectoryValidator.testDir(f, false, false); + String s = result.getMessage(); + assertTrue(s.endsWith("\n")); + assertTrue(s.split("\n").length == 1); + assertTrue(f.setWritable(true)); + } + + @Test + public void testMainDirTestExistsAsDirButNotReadable() throws IOException { + File f = File.createTempFile("test", "testMainDirs"); + assertTrue(f.delete()); + assertTrue(f.mkdir()); + f.deleteOnExit(); + assertTrue(f.setReadable(false)); + DirectoryValidator.DirectoryCheckResult result = DirectoryValidator.testDir(f, false, false); + String s = result.getMessage(); + assertTrue(s.endsWith("\n")); + assertTrue(s.split("\n").length == 1); + assertTrue(f.setReadable(true)); + } + + @Test + public void testMainDirTestNotExistsWithSubdir() { + DirectoryValidator.DirectoryCheckResult result = DirectoryValidator.testDir(new File("/definitely/not/existing/file/efgrhisaes"), false, true); + String s = result.getMessage(); + assertTrue(s.endsWith("\n")); + assertTrue(s.split("\n").length == 3); + } + + @Test + public void testMainDirTestExistsAsFileWithSubdir() throws IOException { + File f = File.createTempFile("test", "testMainDirs"); + f.deleteOnExit(); + DirectoryValidator.DirectoryCheckResult result = DirectoryValidator.testDir(f, false, true); + String s = result.getMessage(); + assertTrue(s.endsWith("\n")); + assertTrue(s.split("\n").length == 2); + } + + @Test + public void testMainDirTestExistsAsDirWithSubdir() throws IOException { + File f = File.createTempFile("test", "testMainDirs"); + assertTrue(f.delete()); + assertTrue(f.mkdir()); + f.deleteOnExit(); + DirectoryValidator.DirectoryCheckResult result = DirectoryValidator.testDir(f, false, true); + String s = result.getMessage(); + assertTrue(s.isEmpty()); + } + + @Test + public void testMainDirTestExistsAsDirButNotWritableWithSubdir() throws IOException { + File f = File.createTempFile("test", "testMainDirs"); + assertTrue(f.delete()); + assertTrue(f.mkdir()); + assertTrue(f.setWritable(false)); + f.deleteOnExit(); + DirectoryValidator.DirectoryCheckResult result = DirectoryValidator.testDir(f, false, true); + String s = result.getMessage(); + assertTrue(s.endsWith("\n")); + assertTrue(s.split("\n").length == 1); + assertTrue(f.setWritable(true)); + } + + @Test + public void testMainDirTestExistsAsDirButNotReadableWithSubdir() throws IOException { + File f = File.createTempFile("test", "testMainDirs"); + assertTrue(f.delete()); + assertTrue(f.mkdir()); + f.deleteOnExit(); + f.setReadable(false); + DirectoryValidator.DirectoryCheckResult result = DirectoryValidator.testDir(f, false, true); + String s = result.getMessage(); + assertTrue(s.endsWith("\n")); + assertTrue(s.split("\n").length == 1); + } + + @Test + public void testDirectoryCheckResult() { + DirectoryValidator.DirectoryCheckResult r1 = new DirectoryValidator.DirectoryCheckResult(new File("a")); + DirectoryValidator.DirectoryCheckResult r2 = new DirectoryValidator.DirectoryCheckResult(new File("b")); + r1.subDir = r2; + assertTrue(r1.getMessage().isEmpty()); + assertTrue(r2.getMessage().isEmpty()); + assertTrue(r1.getFailures() == 0); + assertTrue(r2.getFailures() == 0); + assertTrue(r1.getPasses() == 6); + assertTrue(r2.getPasses() == 3); + r1.correctPermissions = false; + r2.isDir = false; + assertTrue(r1.getMessage().split("\n").length == 2); + assertTrue(r2.getMessage().split("\n").length == 1); + assertTrue(r1.getFailures() == 2); + assertTrue(r2.getFailures() == 1); + assertTrue(r1.getPasses() == 4); + assertTrue(r2.getPasses() == 2); + r1.exists = false; + r2.exists = false; + assertTrue(r1.getMessage().split("\n").length == 4); + assertTrue(r2.getMessage().split("\n").length == 2); + assertTrue(r1.getFailures() == 4); + assertTrue(r2.getFailures() == 2); + assertTrue(r1.getPasses() == 2); + assertTrue(r2.getPasses() == 1); + r1.isDir = false; + r2.correctPermissions = false; + assertTrue(r1.getMessage().split("\n").length == 6); + assertTrue(r2.getMessage().split("\n").length == 3); + assertTrue(r1.getFailures() == 6); + assertTrue(r2.getFailures() == 3); + assertTrue(r1.getPasses() == 0); + assertTrue(r2.getPasses() == 0); + } + + @Test + public void testDirectoryValidator() throws IOException { + File f1 = File.createTempFile("test", "testMainDirs"); + File f2 = File.createTempFile("test", "testMainDirs"); + DirectoryValidator dv = new DirectoryValidator(Arrays.asList(f1, f2)); + + assertTrue(f1.delete()); + assertTrue(f1.mkdir()); + assertTrue(f1.setWritable(false)); + f1.deleteOnExit(); + + assertTrue(f2.delete()); + assertTrue(f2.mkdir()); + assertTrue(f2.setWritable(false)); + f2.deleteOnExit(); + + + DirectoryValidator.DirectoryCheckResults results1 = dv.ensureDirs(); + assertTrue(results1.results.size() == 2); + assertTrue(results1.getFailures() == 2); + assertTrue(results1.getPasses() == 4); + String s1 = results1.getMessage(); + assertTrue(s1.endsWith("\n")); + assertTrue(s1.split("\n").length == 2); + + assertTrue(f1.setWritable(true)); + + DirectoryValidator.DirectoryCheckResults results2 = dv.ensureDirs(); + assertTrue(results2.results.size() == 2); + assertTrue(results2.getFailures() == 1); + assertTrue(results2.getPasses() == 5); + String s2 = results2.getMessage(); + assertTrue(s2.endsWith("\n")); + assertTrue(s2.split("\n").length == 1); + + assertTrue(f2.setWritable(true)); + + DirectoryValidator.DirectoryCheckResults results3 = dv.ensureDirs(); + assertTrue(results3.results.size() == 2); + assertTrue(results3.getFailures() == 0); + assertTrue(results3.getPasses() == 6); + String s3 = results3.getMessage(); + assertTrue(s3.isEmpty()); + + assertTrue(f2.delete()); //will be created in dv.ensureDirs(); + + DirectoryValidator.DirectoryCheckResults results4 = dv.ensureDirs(); + assertTrue(results4.results.size() == 2); + assertTrue(results4.getFailures() == 0); + assertTrue(results4.getPasses() == 6); + String s4 = results4.getMessage(); + assertTrue(s4.isEmpty()); + + File f3 = File.createTempFile("test", "testMainDirs", f2); + File f4 = File.createTempFile("test", "testMainDirs", f2); + assertTrue(f4.delete()); + assertTrue(f3.delete()); + assertTrue(f4.mkdir()); + assertTrue(f2.setWritable(false)); //now f2 will not be recreated + + dv= new DirectoryValidator(Arrays.asList(f3, f4)); + + DirectoryValidator.DirectoryCheckResults results5 = dv.ensureDirs(); + assertTrue(results5.results.size() == 2); + assertTrue(results5.getFailures() == 3); + assertTrue(results5.getPasses() == 3); + String s5 = results5.getMessage(); + assertTrue(s5.endsWith("\n")); + assertTrue(s5.split("\n").length == 3); + assertTrue(f2.setWritable(true)); + assertTrue(f4.delete()); + + } +} diff --git a/tests/reproducers/simple/simpletest1/testcases/XDGspecificationTests.java b/tests/reproducers/simple/simpletest1/testcases/XDGspecificationTests.java index 0904404..05d559a 100644 --- a/tests/reproducers/simple/simpletest1/testcases/XDGspecificationTests.java +++ b/tests/reproducers/simple/simpletest1/testcases/XDGspecificationTests.java @@ -1014,10 +1014,11 @@ public class XDGspecificationTests extends BrowserTest { pw.addStdOutListener(new RulesFolowingClosingListener(applet1Run)); pw.setVars(setXdgVAlues(f)); ProcessResult pr = pw.execute(); - Assert.assertTrue(applet1Run.toPassingString(), applet1Run.evaluate(pr.stdout)); Assert.assertTrue(notMoving.toPassingString(), notMoving.evaluate(pr.stdout)); assertMainFiles(listToString(getContentOfDirectory(f)), false, false, true); assertOldNotMainFilesInHome(true, true, true); + /*do alst, we need to check the migration, not applet lunching itself*/ + Assert.assertTrue(applet1Run.toPassingString(), applet1Run.evaluate(pr.stdout)); } finally { deleteRecursively(f); } @@ -1090,10 +1091,11 @@ public class XDGspecificationTests extends BrowserTest { pw.addStdOutListener(new RulesFolowingClosingListener(applet1Run)); pw.setVars(setXdgVAlues(f)); ProcessResult pr = pw.execute(); - Assert.assertTrue(applet1Run.toPassingString(), applet1Run.evaluate(pr.stdout)); Assert.assertTrue(notMoving.toPassingString(), notMoving.evaluate(pr.stdout)); assertMainFiles(listToString(getContentOfDirectory(f)), false, false, true); assertOldNotMainFilesInHome(true, true, true); + /*do last, we need to check the migration, not applet lunching itself*/ + Assert.assertTrue(applet1Run.toPassingString(), applet1Run.evaluate(pr.stdout)); } finally { deleteRecursively(f); } |