From 03c5dede19bf3e8d6e470336fbbd22fbae08f853 Mon Sep 17 00:00:00 2001
From: kaloyane <kaloyane>
Date: Thu, 5 May 2011 14:55:29 +0000
Subject: [PATCH] [LMS-2231]: simple unit testing added

SVN: 21147
---
 .../cisd/common/test/TrackingMockery.java     |  51 ++++
 .../generic/server/ftp/FtpServerConfig.java   |  14 +-
 .../TemplateBasedDataSetResourceResolver.java |   5 +-
 .../server/ftp/FtpServerConfigBuilder.java    |  66 +++++
 ...plateBasedDataSetResourceResolverTest.java | 259 ++++++++++++++++++
 5 files changed, 387 insertions(+), 8 deletions(-)
 create mode 100644 common/source/java/ch/systemsx/cisd/common/test/TrackingMockery.java
 create mode 100644 datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServerConfigBuilder.java
 create mode 100644 datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolverTest.java

diff --git a/common/source/java/ch/systemsx/cisd/common/test/TrackingMockery.java b/common/source/java/ch/systemsx/cisd/common/test/TrackingMockery.java
new file mode 100644
index 00000000000..8a39b3262ff
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/test/TrackingMockery.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2011 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.common.test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jmock.Mockery;
+
+/**
+ * A {@link Mockery} that tracks all created mocks and offers a method to retrieve them by name.
+ * 
+ * @author Kaloyan Enimanev
+ */
+public class TrackingMockery extends Mockery
+{
+
+    private Map<String, Object> createdMocks = new HashMap<String, Object>();
+
+    @Override
+    public <T> T mock(Class<T> typeToMock, String name)
+    {
+        T mock = super.mock(typeToMock, name);
+        createdMocks.put(name, mock);
+        return mock;
+    }
+
+    /**
+     * retrieves a previously created mock object.
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T getMock(String name, Class<T> type)
+    {
+        return (T) createdMocks.get(name);
+    }
+
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServerConfig.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServerConfig.java
index 191b61bc1b4..d94591cff99 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServerConfig.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServerConfig.java
@@ -41,19 +41,19 @@ public class FtpServerConfig
 
     private final static String PREFIX = "ftp.server.";
 
-    private final static String ENABLE_KEY = PREFIX + "enable";
+    final static String ENABLE_KEY = PREFIX + "enable";
 
-    private final static String PORT_KEY = PREFIX + "port";
+    final static String PORT_KEY = PREFIX + "port";
 
-    private final static String USE_SSL_KEY = PREFIX + "use-ssl";
+    final static String USE_SSL_KEY = PREFIX + "use-ssl";
 
-    private final static String MAX_THREADS_KEY = PREFIX + "maxThreads";
+    final static String MAX_THREADS_KEY = PREFIX + "maxThreads";
 
-    private final static String DATASET_DISPLAY_TEMPLATE_KEY = PREFIX + "dataset.display.template";
+    final static String DATASET_DISPLAY_TEMPLATE_KEY = PREFIX + "dataset.display.template";
 
-    private final static String DATASET_FILELIST_SUBPATH_KEY = PREFIX + "dataset.filelist.subpath.";
+    final static String DATASET_FILELIST_SUBPATH_KEY = PREFIX + "dataset.filelist.subpath.";
 
-    private final static String DATASET_FILELIST_FILTER_KEY = PREFIX + "dataset.filelist.filter.";
+    final static String DATASET_FILELIST_FILTER_KEY = PREFIX + "dataset.filelist.filter.";
 
     private static final int DEFAULT_PORT = 2121;
 
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolver.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolver.java
index d7c756d7e0d..8e2e3c448cf 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolver.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolver.java
@@ -404,7 +404,10 @@ public class TemplateBasedDataSetResourceResolver implements IFtpPathResolver,
         properties.put(DATA_SET_TYPE_VARNAME, dataSet.getDataSetType().getCode());
         String dataSetDate = extractDateValue(dataSet.getRegistrationDate());
         properties.put(DATA_SET_DATE_VARNAME, dataSetDate);
-        properties.put(FILE_NAME_VARNAME, fileName);
+        if (fileName != null)
+        {
+            properties.put(FILE_NAME_VARNAME, fileName);
+        }
         properties.put(DISAMBIGUATION_VARNAME, disambiguation);
 
         properties.put(TEMPLATE, template);
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServerConfigBuilder.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServerConfigBuilder.java
new file mode 100644
index 00000000000..c9157046a84
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServerConfigBuilder.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2011 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.server.ftp;
+
+import java.util.Properties;
+
+/**
+ * A builder for {@link FtpServerConfig} objects.
+ * 
+ * @author Kaloyan Enimanev
+ */
+public class FtpServerConfigBuilder
+{
+    private Properties props = new Properties();
+
+    public FtpServerConfig getConfig()
+    {
+        return new FtpServerConfig(props);
+    }
+
+    public FtpServerConfigBuilder()
+    {
+        this(true, false);
+    }
+
+    public FtpServerConfigBuilder(boolean enable, boolean useSSL)
+    {
+        props.put(FtpServerConfig.ENABLE_KEY, String.valueOf(enable));
+        props.put(FtpServerConfig.USE_SSL_KEY, String.valueOf(useSSL));
+    }
+
+    public FtpServerConfigBuilder withTemplate(String template)
+    {
+        props.setProperty(FtpServerConfig.DATASET_DISPLAY_TEMPLATE_KEY, template);
+        return this;
+
+    }
+
+    public FtpServerConfigBuilder withFileListFilter(String dataSetType, String filterPattern)
+    {
+        String key = FtpServerConfig.DATASET_FILELIST_FILTER_KEY + dataSetType;
+        props.setProperty(key, filterPattern);
+        return this;
+    }
+
+    public FtpServerConfigBuilder withFileListSubPath(String dataSetType, String subPathPattern)
+    {
+        String key = FtpServerConfig.DATASET_FILELIST_SUBPATH_KEY + dataSetType;
+        props.setProperty(key, subPathPattern);
+        return this;
+    }
+}
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolverTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolverTest.java
new file mode 100644
index 00000000000..69b7e82345d
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/resolver/TemplateBasedDataSetResourceResolverTest.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2011 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.server.ftp.resolver;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.ftpserver.ftplet.FtpFile;
+import org.jmock.Expectations;
+import org.springframework.beans.factory.BeanFactory;
+import org.testng.AssertJUnit;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.io.IHierarchicalContent;
+import ch.systemsx.cisd.common.io.IHierarchicalContentNode;
+import ch.systemsx.cisd.common.test.TrackingMockery;
+import ch.systemsx.cisd.openbis.dss.generic.server.ftp.FtpConstants;
+import ch.systemsx.cisd.openbis.dss.generic.server.ftp.FtpPathResolverContext;
+import ch.systemsx.cisd.openbis.dss.generic.server.ftp.FtpServerConfig;
+import ch.systemsx.cisd.openbis.dss.generic.server.ftp.FtpServerConfigBuilder;
+import ch.systemsx.cisd.openbis.dss.generic.shared.IHierarchicalContentProvider;
+import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProviderTestWrapper;
+import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory;
+
+/**
+ * @author Kaloyan Enimanev
+ */
+public class TemplateBasedDataSetResourceResolverTest extends AssertJUnit
+{
+
+    private static final String SESSION_TOKEN = "token";
+
+    private static final String EXP_ID = "/space/project/experiment";
+
+    private static final long EXP_TECH_ID = 1L;
+
+    private static final String SIMPLE_TEMPLATE = "${dataSetCode}";
+
+    private static final String DS_TYPE1 = "DS_TYPE1";
+
+    // private static final String TEMPLATE_WITH_FILENAMES =
+    // "DS-${dataSetType}-${fileName}-${disambiguation}";
+
+
+    private TrackingMockery context;
+    private IETLLIMSService service;
+
+    private IHierarchicalContentProvider hierarchicalContentProvider;
+
+    private FtpPathResolverContext resolverContext;
+    private TemplateBasedDataSetResourceResolver resolver;
+
+    private Experiment experiment;
+
+    @BeforeMethod
+    public void setUp()
+    {
+        experiment = new Experiment();
+        experiment.setIdentifier(EXP_ID);
+        experiment.setId(EXP_TECH_ID);
+
+        context = new TrackingMockery();
+        service = context.mock(IETLLIMSService.class);
+        hierarchicalContentProvider = context.mock(IHierarchicalContentProvider.class);
+
+        resolverContext = new FtpPathResolverContext(SESSION_TOKEN, service, null);
+
+        final BeanFactory beanFactory = context.mock(BeanFactory.class);
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(beanFactory).getBean("hierarchical-content-provider");
+                    will(returnValue(hierarchicalContentProvider));
+
+                    ExperimentIdentifier experimentIdentifier =
+                            new ExperimentIdentifierFactory(EXP_ID).createIdentifier();
+                    allowing(service).tryToGetExperiment(SESSION_TOKEN, experimentIdentifier);
+                    will(returnValue(experiment));
+                }
+            });
+        ServiceProviderTestWrapper.setApplicationContext(beanFactory);
+    }
+
+    @AfterMethod(alwaysRun = true)
+    public void tearDown()
+    {
+        ServiceProviderTestWrapper.restoreApplicationContext();
+    }
+
+    @Test
+    public void testResolveSimpleTemplate()
+    {
+        FtpServerConfig config =
+                new FtpServerConfigBuilder().withTemplate(SIMPLE_TEMPLATE).getConfig();
+        resolver = new TemplateBasedDataSetResourceResolver(config);
+
+        final String dataSetCode = "dataSetCode";
+
+        String path = EXP_ID + FtpConstants.FILE_SEPARATOR + dataSetCode;
+
+        List<ExternalData> dataSets =
+                Arrays.asList(createDataSet("randomCode", "randomType"),
+                        createDataSet(dataSetCode, DS_TYPE1),
+                        createDataSet("randomCode2", "randomType2"));
+
+        prepareExperimentListExpectations(dataSets);
+
+        context.checking(new Expectations()
+            {
+                {
+                    IHierarchicalContent content = getHierarchicalContentMock(dataSetCode);
+                    IHierarchicalContentNode rootNode = getHierarchicalRootNodeMock(dataSetCode);
+
+                    allowing(content).getNode(StringUtils.EMPTY);
+                    will(returnValue(rootNode));
+                }
+            });
+
+        FtpFile ftpFile = resolver.resolve(path, resolverContext);
+
+        assertNotNull(ftpFile);
+        assertEquals(dataSetCode, ftpFile.getName());
+
+    }
+
+    @Test
+    public void testResolveSimpleTemplateRecursive()
+    {
+        FtpServerConfig config =
+                new FtpServerConfigBuilder().withTemplate(SIMPLE_TEMPLATE).getConfig();
+        resolver = new TemplateBasedDataSetResourceResolver(config);
+
+        final String dataSetCode = "dataSetCode";
+        final String subPath = "/level1/level2/fileName.txt";
+
+        String path = EXP_ID + FtpConstants.FILE_SEPARATOR + dataSetCode + subPath;
+
+        List<ExternalData> dataSets = Arrays.asList(createDataSet(dataSetCode, DS_TYPE1));
+
+        prepareExperimentListExpectations(dataSets);
+
+        context.checking(new Expectations()
+            {
+                {
+                    IHierarchicalContent content = getHierarchicalContentMock(dataSetCode);
+                    IHierarchicalContentNode mockNode =
+                            context.mock(IHierarchicalContentNode.class);
+
+                    allowing(content).getNode(subPath);
+                    will(returnValue(mockNode));
+
+                    one(mockNode).isDirectory();
+                    will(returnValue(false));
+                }
+            });
+
+        FtpFile ftpFile = resolver.resolve(path, resolverContext);
+
+        assertNotNull(ftpFile);
+        assertEquals("fileName.txt", ftpFile.getName());
+        assertTrue(ftpFile.isFile());
+
+    }
+
+    private void prepareExperimentListExpectations(final List<ExternalData> dataSets)
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(service).listDataSetsByExperimentID(SESSION_TOKEN,
+                            new TechId(experiment));
+                    will(returnValue(dataSets));
+
+                    for (ExternalData dataSet : dataSets)
+                    {
+                        String mockName = getHierarchicalContentMockName(dataSet.getCode());
+                        IHierarchicalContent content =
+                                context.mock(IHierarchicalContent.class, mockName);
+                        allowing(hierarchicalContentProvider).asContent(dataSet.getCode());
+                        will(returnValue(content));
+
+                        String rootMockName = getRootNodeMockName(dataSet.getCode());
+                        IHierarchicalContentNode rootNode =
+                                context.mock(IHierarchicalContentNode.class, rootMockName);
+                        allowing(content).getRootNode();
+                        will(returnValue(rootNode));
+
+                        allowing(rootNode).getRelativePath();
+                        will(returnValue(StringUtils.EMPTY));
+
+                        allowing(rootNode).getName();
+                        will(returnValue(null));
+                    }
+                }
+            });
+    }
+
+    private String getHierarchicalContentMockName(String dataSetCode)
+    {
+        return dataSetCode;
+    }
+
+    private String getRootNodeMockName(String dataSetCode)
+    {
+        return dataSetCode + "-rootNode";
+    }
+
+    private IHierarchicalContentNode getHierarchicalRootNodeMock(String dataSetCode)
+    {
+        String mockName = getRootNodeMockName(dataSetCode);
+        return context.getMock(mockName, IHierarchicalContentNode.class);
+    }
+
+    protected IHierarchicalContent getHierarchicalContentMock(String dataSetCode)
+    {
+        String mockName = getHierarchicalContentMockName(dataSetCode);
+        return context.getMock(mockName, IHierarchicalContent.class);
+    }
+
+    private ExternalData createDataSet(String dataSetCode, String dataSetType)
+    {
+        return createDataSet(dataSetCode, dataSetType, new Date());
+    }
+
+    private ExternalData createDataSet(String dataSetCode, String dataSetType, Date registrationDate)
+    {
+        ExternalData result = new ExternalData();
+        result.setCode(dataSetCode);
+        DataSetType type = new DataSetType(dataSetType);
+        result.setDataSetType(type);
+        result.setRegistrationDate(registrationDate);
+        return result;
+    }
+
+}
-- 
GitLab