From 98148d2ed98d2aac80954a968aaaba70b5dbb540 Mon Sep 17 00:00:00 2001
From: felmer <felmer>
Date: Wed, 18 Jan 2012 09:05:35 +0000
Subject: [PATCH] LMS-2737 getDssInternalTempDir() and
 getDssRegistrationLogDir() refactored. Tests written. Check added that these
 directories are on local file system.

SVN: 24217
---
 .../utils/DssPropertyParametersUtil.java      | 110 ++++--
 .../utils/DssPropertyParametersUtilTest.java  | 320 ++++++++++++++++++
 2 files changed, 404 insertions(+), 26 deletions(-)
 create mode 100644 datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtilTest.java

diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtil.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtil.java
index 61d8266422a..6fe9a4707e1 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtil.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtil.java
@@ -21,10 +21,14 @@ import java.util.Map.Entry;
 import java.util.Properties;
 import java.util.Set;
 
+import ch.rinn.restrictions.Private;
 import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException;
+import ch.systemsx.cisd.common.filesystem.FileOperations;
 import ch.systemsx.cisd.common.filesystem.FileUtilities;
+import ch.systemsx.cisd.common.filesystem.IFileOperations;
 import ch.systemsx.cisd.common.utilities.ExtendedProperties;
 import ch.systemsx.cisd.common.utilities.PropertyUtils;
+import ch.systemsx.cisd.common.utilities.Template;
 
 /**
  * Utility class to load properties.
@@ -33,6 +37,7 @@ import ch.systemsx.cisd.common.utilities.PropertyUtils;
  */
 public class DssPropertyParametersUtil
 {
+
     /** Prefix of system properties which may override service.properties. */
     public static final String OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX = "openbis.dss.";
 
@@ -49,6 +54,8 @@ public class DssPropertyParametersUtil
      */
     static final String DSS_TEMP_DIR_PATH = "dss-temp-dir";
 
+    @Private static final File EMPTY_TEST_FILE = new File("an-empty-test-file");
+    
     /**
      * Directory for registration log files.
      */
@@ -57,6 +64,17 @@ public class DssPropertyParametersUtil
     /** Location of service properties file. */
     public static final String SERVICE_PROPERTIES_FILE = "etc/service.properties";
 
+    private static final String EXPLANATION =
+            "Please make sure this directory exists on the local file system and is writable "
+                    + "by the data store server or provide such a directory "
+                    + "by the configuration parameter '${path-key}'.";
+
+    private static final Template NON_EXISTING_DIR_TEMPLATE = new Template(
+            "Could not create ${dir-description} at path: ${path}. " + EXPLANATION);
+
+    private static final Template NON_LOCAL_DIR_TEMPLATE = new Template(
+            "Directory at path '${path}' is not on the local file system. " + EXPLANATION);
+
     /** loads server configuration */
     public static ExtendedProperties loadServiceProperties()
     {
@@ -98,43 +116,83 @@ public class DssPropertyParametersUtil
     {
         return PropertyUtils.getMandatoryProperty(serviceProperties, DOWNLOAD_URL_KEY);
     }
-
+    
     public static File getDssInternalTempDir(final Properties properties)
     {
-        String defaultTempDirPath =
-                new File(System.getProperty("user.dir"), "dss-tmp").getAbsolutePath();
-        String tempDirPath =
-                PropertyUtils.getProperty(properties, DSS_TEMP_DIR_PATH, defaultTempDirPath);
-        File tempDir = new File(tempDirPath);
-        tempDir.mkdirs();
-        if (false == tempDir.exists())
-        {
-            throw new ConfigurationFailureException(
-                    "Could not create an internal temp directory for the data store server at path: "
-                            + tempDir.getPath()
-                            + ". Please make sure this directory exists and is writable by the data store server or provide an alternate using directory for the "
-                            + DSS_TEMP_DIR_PATH + " configuration setting");
-        }
-        return tempDir;
+        return getDssInternalTempDir(FileOperations.getInstance(), properties);
+    }
+
+    @Private
+    static File getDssInternalTempDir(IFileOperations fileOperations, final Properties properties)
+    {
+        return getDir(fileOperations, properties, "dss-tmp",
+                "an internal temp directory for the data store server", DSS_TEMP_DIR_PATH);
     }
 
     public static File getDssRegistrationLogDir(final Properties properties)
+    {
+        return getDssRegistrationLogDir(FileOperations.getInstance(), properties);
+    }
+
+    @Private
+    static File getDssRegistrationLogDir(IFileOperations fileOperations, final Properties properties)
+    {
+        return getDir(fileOperations, properties, "log-registrations",
+                "a directory for storing registration logs", DSS_REGISTRATION_LOG_DIR_PATH);
+    }
+
+    private static File getDir(IFileOperations fileOperations, final Properties properties,
+            String defaultDirName, String dirDescription, String pathKey)
     {
         String defaultRegistrationLogDirPath =
-                new File(System.getProperty("user.dir"), "log-registrations").getAbsolutePath();
+                new File(System.getProperty("user.dir"), defaultDirName).getAbsolutePath();
         String registrationLogDirPath =
-                PropertyUtils.getProperty(properties, DSS_REGISTRATION_LOG_DIR_PATH,
+                PropertyUtils.getProperty(properties, pathKey,
                         defaultRegistrationLogDirPath);
         File registrationLogDir = new File(registrationLogDirPath);
-        registrationLogDir.mkdirs();
-        if (false == registrationLogDir.exists())
+        fileOperations.mkdirs(registrationLogDir);
+        assertDirExistsAndIsLocal(fileOperations, registrationLogDir,
+                dirDescription, pathKey);
+        return registrationLogDir;
+    }
+
+    private static void assertDirExistsAndIsLocal(IFileOperations fileOperations, File dir,
+            String dirDescription, String pathKey)
+    {
+        assertDirExists(fileOperations, dir, dirDescription, pathKey);
+        File emptyTestFileInDir = new File(dir, EMPTY_TEST_FILE.getName());
+        try
+        {
+            fileOperations.createNewFile(EMPTY_TEST_FILE);
+            if (fileOperations.rename(EMPTY_TEST_FILE, emptyTestFileInDir) == false)
+            {
+                throw createException(NON_LOCAL_DIR_TEMPLATE.createFreshCopy(), dir, dirDescription,
+                        pathKey);
+            }
+        } finally
         {
-            throw new ConfigurationFailureException(
-                    "Could not create a directory for storing for registration logs at path: "
-                            + registrationLogDir.getPath()
-                            + ". Please make sure this directory exists and is writable by the data store server or provide an alternate using directory for the "
-                            + DSS_REGISTRATION_LOG_DIR_PATH + " configuration setting");
+            fileOperations.delete(EMPTY_TEST_FILE);
+            fileOperations.delete(emptyTestFileInDir);
         }
-        return registrationLogDir;
+    }
+
+    private static void assertDirExists(IFileOperations fileOperations, File dir, String dirDescription,
+            String pathKey)
+    {
+        if (fileOperations.exists(dir) == false)
+        {
+            throw createException(NON_EXISTING_DIR_TEMPLATE.createFreshCopy(), dir, dirDescription,
+                    pathKey);
+        }
+    }
+
+    private static ConfigurationFailureException createException(Template template, File dir,
+            String dirName, String pathKey)
+    {
+        template.attemptToBind("dir-description", dirName);
+        template.bind("path", dir.getPath());
+        template.bind("path-key", pathKey);
+        ConfigurationFailureException e = new ConfigurationFailureException(template.createText());
+        return e;
     }
 }
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtilTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtilTest.java
new file mode 100644
index 00000000000..f861d825a8c
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtilTest.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.dss.generic.shared.utils;
+
+import static ch.systemsx.cisd.openbis.dss.generic.shared.utils.DssPropertyParametersUtil.EMPTY_TEST_FILE;
+
+import java.io.File;
+import java.util.Properties;
+
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.testng.AssertJUnit;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import ch.rinn.restrictions.Friend;
+import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException;
+import ch.systemsx.cisd.common.filesystem.IFileOperations;
+
+/**
+ * @author Franz-Josef Elmer
+ */
+@Friend(toClasses = DssPropertyParametersUtil.class)
+public class DssPropertyParametersUtilTest extends AssertJUnit
+{
+
+    private Mockery context;
+
+    private IFileOperations fileOperations;
+
+    @BeforeMethod
+    public void setUp()
+    {
+        context = new Mockery();
+        fileOperations = context.mock(IFileOperations.class);
+    }
+
+    @AfterMethod
+    public void tearDown()
+    {
+        // To following line of code should also be called at the end of each test method.
+        // Otherwise one do not known which test failed.
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testGetDssInternalTempDirWithDefaultValue()
+    {
+        File expectedDir = new File(System.getProperty("user.dir"), "dss-tmp");
+        prepareForMkdirs(expectedDir);
+        prepareForExists(expectedDir);
+        prepareForCreateNewFile(EMPTY_TEST_FILE);
+        File movedEmptyTestFile = new File(expectedDir, EMPTY_TEST_FILE.getName());
+        prepareForRenameFile(EMPTY_TEST_FILE, movedEmptyTestFile, true);
+        prepareForDeleteFile(EMPTY_TEST_FILE);
+        prepareForDeleteFile(movedEmptyTestFile);
+
+        File tempDir =
+                DssPropertyParametersUtil.getDssInternalTempDir(fileOperations, new Properties());
+
+        assertEquals(expectedDir, tempDir);
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testGetDssInternalTempDirWithValidValue()
+    {
+        File expectedDir = new File("my-dss-tmp");
+        Properties properties = new Properties();
+        properties.setProperty(DssPropertyParametersUtil.DSS_TEMP_DIR_PATH, expectedDir.getPath());
+        prepareForMkdirs(expectedDir);
+        prepareForExists(expectedDir);
+        prepareForCreateNewFile(EMPTY_TEST_FILE);
+        File movedEmptyTestFile = new File(expectedDir, EMPTY_TEST_FILE.getName());
+        prepareForRenameFile(EMPTY_TEST_FILE, movedEmptyTestFile, true);
+        prepareForDeleteFile(EMPTY_TEST_FILE);
+        prepareForDeleteFile(movedEmptyTestFile);
+
+        File tempDir = DssPropertyParametersUtil.getDssInternalTempDir(fileOperations, properties);
+
+        assertEquals(expectedDir, tempDir);
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testGetDssInternalTempDirWhichDoesNotExists()
+    {
+        File expectedDir = new File("my-dss-tmp");
+        Properties properties = new Properties();
+        properties.setProperty(DssPropertyParametersUtil.DSS_TEMP_DIR_PATH, expectedDir.getPath());
+        prepareForMkdirs(expectedDir);
+        prepareForNonExists(expectedDir);
+
+        try
+        {
+            DssPropertyParametersUtil.getDssInternalTempDir(fileOperations, properties);
+            fail("ConfigurationFailureException expected");
+        } catch (ConfigurationFailureException ex)
+        {
+            assertEquals("Could not create an internal temp directory for "
+                    + "the data store server at path: my-dss-tmp. "
+                    + "Please make sure this directory exists on the local file system and "
+                    + "is writable by the data store server or provide such a directory "
+                    + "by the configuration parameter 'dss-temp-dir'.", ex.getMessage());
+        }
+
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testGetDssInternalTempDirWhichIsNotLocal()
+    {
+        File expectedDir = new File("my-dss-tmp");
+        Properties properties = new Properties();
+        properties.setProperty(DssPropertyParametersUtil.DSS_TEMP_DIR_PATH, expectedDir.getPath());
+        prepareForMkdirs(expectedDir);
+        prepareForExists(expectedDir);
+        prepareForCreateNewFile(EMPTY_TEST_FILE);
+        File movedEmptyTestFile = new File(expectedDir, EMPTY_TEST_FILE.getName());
+        prepareForRenameFile(EMPTY_TEST_FILE, movedEmptyTestFile, false);
+        prepareForDeleteFile(EMPTY_TEST_FILE);
+        prepareForDeleteFile(movedEmptyTestFile);
+
+        try
+        {
+            DssPropertyParametersUtil.getDssInternalTempDir(fileOperations, properties);
+            fail("ConfigurationFailureException expected");
+        } catch (ConfigurationFailureException ex)
+        {
+            assertEquals("Directory at path 'my-dss-tmp' is not on the local file system. "
+                    + "Please make sure this directory exists on the local file system and "
+                    + "is writable by the data store server or provide such a directory "
+                    + "by the configuration parameter 'dss-temp-dir'.", ex.getMessage());
+        }
+
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testGetDssRegistrationLogDirWithDefaultValue()
+    {
+        File expectedDir = new File(System.getProperty("user.dir"), "log-registrations");
+        prepareForMkdirs(expectedDir);
+        prepareForExists(expectedDir);
+        prepareForCreateNewFile(EMPTY_TEST_FILE);
+        File movedEmptyTestFile = new File(expectedDir, EMPTY_TEST_FILE.getName());
+        prepareForRenameFile(EMPTY_TEST_FILE, movedEmptyTestFile, true);
+        prepareForDeleteFile(EMPTY_TEST_FILE);
+        prepareForDeleteFile(movedEmptyTestFile);
+
+        File tempDir =
+                DssPropertyParametersUtil
+                        .getDssRegistrationLogDir(fileOperations, new Properties());
+
+        assertEquals(expectedDir, tempDir);
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testGetDssRegistrationLogDirWithValidValue()
+    {
+        File expectedDir = new File("my-dss-log");
+        Properties properties = new Properties();
+        properties.setProperty(DssPropertyParametersUtil.DSS_REGISTRATION_LOG_DIR_PATH,
+                expectedDir.getPath());
+        prepareForMkdirs(expectedDir);
+        prepareForExists(expectedDir);
+        prepareForCreateNewFile(EMPTY_TEST_FILE);
+        File movedEmptyTestFile = new File(expectedDir, EMPTY_TEST_FILE.getName());
+        prepareForRenameFile(EMPTY_TEST_FILE, movedEmptyTestFile, true);
+        prepareForDeleteFile(EMPTY_TEST_FILE);
+        prepareForDeleteFile(movedEmptyTestFile);
+
+        File tempDir =
+                DssPropertyParametersUtil.getDssRegistrationLogDir(fileOperations, properties);
+
+        assertEquals(expectedDir, tempDir);
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testGetDssRegistrationLogDirWhichDoesNotExists()
+    {
+        File expectedDir = new File("my-dss-log");
+        Properties properties = new Properties();
+        properties.setProperty(DssPropertyParametersUtil.DSS_REGISTRATION_LOG_DIR_PATH,
+                expectedDir.getPath());
+        prepareForMkdirs(expectedDir);
+        prepareForNonExists(expectedDir);
+
+        try
+        {
+            DssPropertyParametersUtil.getDssRegistrationLogDir(fileOperations, properties);
+            fail("ConfigurationFailureException expected");
+        } catch (ConfigurationFailureException ex)
+        {
+            assertEquals("Could not create a directory for storing "
+                    + "registration logs at path: my-dss-log. "
+                    + "Please make sure this directory exists on the local file system and "
+                    + "is writable by the data store server or provide such a directory "
+                    + "by the configuration parameter 'dss-registration-log-dir'.", ex.getMessage());
+        }
+
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testGetDssRegistrationLogDirWhichIsNotLocal()
+    {
+        File expectedDir = new File("my-dss-log");
+        Properties properties = new Properties();
+        properties.setProperty(DssPropertyParametersUtil.DSS_REGISTRATION_LOG_DIR_PATH,
+                expectedDir.getPath());
+        prepareForMkdirs(expectedDir);
+        prepareForExists(expectedDir);
+        prepareForCreateNewFile(EMPTY_TEST_FILE);
+        File movedEmptyTestFile = new File(expectedDir, EMPTY_TEST_FILE.getName());
+        prepareForRenameFile(EMPTY_TEST_FILE, movedEmptyTestFile, false);
+        prepareForDeleteFile(EMPTY_TEST_FILE);
+        prepareForDeleteFile(movedEmptyTestFile);
+
+        try
+        {
+            DssPropertyParametersUtil.getDssRegistrationLogDir(fileOperations, properties);
+            fail("ConfigurationFailureException expected");
+        } catch (ConfigurationFailureException ex)
+        {
+            assertEquals("Directory at path 'my-dss-log' is not on the local file system. "
+                    + "Please make sure this directory exists on the local file system and "
+                    + "is writable by the data store server or provide such a directory "
+                    + "by the configuration parameter 'dss-registration-log-dir'.", ex.getMessage());
+        }
+
+        context.assertIsSatisfied();
+    }
+
+    private void prepareForMkdirs(final File dir)
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    one(fileOperations).mkdirs(dir);
+                    will(returnValue(true));
+                }
+            });
+
+    }
+
+    private void prepareForExists(final File dir)
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    one(fileOperations).exists(dir);
+                    will(returnValue(true));
+                }
+            });
+    }
+
+    private void prepareForNonExists(final File dir)
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    one(fileOperations).exists(dir);
+                    will(returnValue(false));
+                }
+            });
+    }
+
+    private void prepareForCreateNewFile(final File file)
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    one(fileOperations).createNewFile(file);
+                    will(returnValue(true));
+                }
+            });
+    }
+
+    private void prepareForRenameFile(final File source, final File destination,
+            final boolean success)
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    one(fileOperations).rename(source, destination);
+                    will(returnValue(success));
+                }
+            });
+    }
+
+    private void prepareForDeleteFile(final File file)
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    one(fileOperations).delete(file);
+                    will(returnValue(true));
+                }
+            });
+    }
+
+}
-- 
GitLab