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