diff --git a/datastore_server/.classpath b/datastore_server/.classpath index a8761230b090677691d7476bfe0302f72e3b5a7c..02d5a51470eca3fb2ad7ea1dd745c7bbc4a1ea20 100644 --- a/datastore_server/.classpath +++ b/datastore_server/.classpath @@ -51,5 +51,7 @@ <classpathentry kind="lib" path="/libraries/jai/jai_core.jar"/> <classpathentry kind="lib" path="/libraries/spring/spring-aop.jar" sourcepath="/libraries/spring/src.jar"/> <classpathentry kind="lib" path="/libraries/jhdf5/cisd-jhdf5-batteries_included_lin_win_mac.jar" sourcepath="/libraries/jhdf5/cisd-jhdf5-src.zip"/> + <classpathentry kind="lib" path="/libraries/spring/test/spring-test.jar" sourcepath="/libraries/spring/test/src.jar"/> + <classpathentry kind="lib" path="/libraries/spring/webmvc/spring-webmvc.jar" sourcepath="/libraries/spring/webmvc/src.jar"/> <classpathentry kind="output" path="targets/classes"/> </classpath> diff --git a/datastore_server/etc/service.properties b/datastore_server/etc/service.properties index ffe80ed617f438ffeef43720f5de93875ca86139..cc8108eb51c342cb4ecaf3b1028b1414a988435f 100644 --- a/datastore_server/etc/service.properties +++ b/datastore_server/etc/service.properties @@ -1,11 +1,13 @@ # Unique code of this Data Store Server. Not more than 40 characters. data-store-server-code = standard +root-dir = targets + # The root directory of the data store -storeroot-dir = targets/store +storeroot-dir = ${root-dir}/store # The directory for incoming files over rpc -rpc-incoming-dir = targets/incoming-rpc +rpc-incoming-dir = ${root-dir}/incoming-rpc # The directory where the command queue file is located; defaults to storeroot-dir commandqueue-dir = @@ -70,7 +72,7 @@ cifex-admin-password = download-url = http://localhost:8889 # SMTP properties (must start with 'mail' to be considered). -mail.smtp.host = file://targets/email +mail.smtp.host = file://${root-dir}/email mail.from = datastore_server@localhost mail.smtp.user = mail.smtp.password = @@ -173,14 +175,14 @@ validator.site.value-range = [0,Infinity) # Comma separated names of processing threads. Each thread should have configuration properties prefixed with its name. # E.g. 'code-extractor' property for the thread 'my-etl' should be specified as 'my-etl.code-extractor' -inputs=main-thread, tsv-thread, csv-thread, simple-thread, hdf5-thread +inputs=main-thread, tsv-thread, csv-thread, simple-thread, hdf5-thread, dss-system-test-thread # --------------------------------------------------------------------------- # Dataset uploader 'main-thread' configuration # --------------------------------------------------------------------------- # The directory to watch for incoming data. -main-thread.incoming-dir = targets/incoming +main-thread.incoming-dir = ${root-dir}/incoming # Specifies what should happen if an error occurs during dataset processing. # By default this flag is set to false and user has to modify the 'faulty paths file' @@ -225,7 +227,7 @@ main-thread.storage-processor.well_geometry = 3x3 main-thread.storage-processor.file-extractor = ch.systemsx.cisd.etlserver.imsb.HCSImageFileExtractor # The directory to watch for incoming data. -tsv-thread.incoming-dir = targets/incoming-tsv +tsv-thread.incoming-dir = ${root-dir}/incoming-tsv tsv-thread.incoming-data-completeness-condition = auto-detection tsv-thread.strip-file-extension = true tsv-thread.storage-processor = ch.systemsx.cisd.etlserver.DefaultStorageProcessor @@ -243,7 +245,7 @@ tsv-thread.type-extractor.file-format-type = TSV tsv-thread.type-extractor.locator-type = RELATIVE_LOCATION tsv-thread.type-extractor.data-set-type = TSV -csv-thread.incoming-dir = targets/incoming-csv +csv-thread.incoming-dir = ${root-dir}/incoming-csv csv-thread.incoming-data-completeness-condition = auto-detection csv-thread.storage-processor = ch.systemsx.cisd.etlserver.DefaultStorageProcessor # The extractor plugin class to use for code extraction @@ -260,7 +262,7 @@ csv-thread.type-extractor.locator-type = RELATIVE_LOCATION csv-thread.type-extractor.data-set-type = CSV # The directory to watch for incoming data. -simple-thread.incoming-dir = targets/incoming-simple +simple-thread.incoming-dir = ${root-dir}/incoming-simple simple-thread.incoming-data-completeness-condition = auto-detection simple-thread.strip-file-extension = true simple-thread.storage-processor = ch.systemsx.cisd.etlserver.DefaultStorageProcessor @@ -277,7 +279,7 @@ simple-thread.type-extractor.locator-type = RELATIVE_LOCATION simple-thread.type-extractor.data-set-type = HCS_IMAGE # The directory to watch for incoming data. -hdf5-thread.incoming-dir = targets/incoming-hdf5 +hdf5-thread.incoming-dir = ${root-dir}/incoming-hdf5 hdf5-thread.incoming-data-completeness-condition = auto-detection hdf5-thread.strip-file-extension = true hdf5-thread.storage-processor = ch.systemsx.cisd.etlserver.hdf5.Hdf5StorageProcessor @@ -293,6 +295,24 @@ hdf5-thread.type-extractor.file-format-type = HDF5 hdf5-thread.type-extractor.locator-type = RELATIVE_LOCATION hdf5-thread.type-extractor.data-set-type = HCS_IMAGE +dss-system-test-thread.incoming-dir = ${root-dir}/incoming-simple +dss-system-test-thread.incoming-data-completeness-condition = auto-detection +dss-system-test-thread.strip-file-extension = true +dss-system-test-thread.storage-processor = ch.systemsx.cisd.etlserver.DefaultStorageProcessor +# The extractor plugin class to use for code extraction +dss-system-test-thread.data-set-info-extractor = ch.systemsx.cisd.etlserver.DefaultDataSetInfoExtractor +# Separator used to extract the barcode in the data set file name +dss-system-test-thread.data-set-info-extractor.entity-separator = ${data-set-file-name-entity-separator} +dss-system-test-thread.data-set-info-extractor.strip-file-extension = true +dss-system-test-thread.data-set-info-extractor.space-code = CISD +dss-system-test-thread.data-set-info-extractor.data-set-properties-file-name = data-set.properties + +dss-system-test-thread.type-extractor = ch.systemsx.cisd.etlserver.SimpleTypeExtractor +dss-system-test-thread.type-extractor.file-format-type = TIFF +dss-system-test-thread.type-extractor.locator-type = RELATIVE_LOCATION +dss-system-test-thread.type-extractor.data-set-type = HCS_IMAGE + + # --------------------------------------------------------------------------- # (optional) archiver configuration # --------------------------------------------------------------------------- diff --git a/datastore_server/etc/web-client.properties b/datastore_server/etc/web-client.properties new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/ETLDaemon.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/ETLDaemon.java index f262dc1d3b3406e4d7d3e205828fb3d9feb352a3..85f91b8bd191ba21225dba3eeadb0a1f20bcc841 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/ETLDaemon.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/ETLDaemon.java @@ -461,6 +461,11 @@ public final class ETLDaemon public final static void main(final String[] args) { final Parameters parameters = new Parameters(args); + run(parameters); + } + + private static void run(final Parameters parameters) + { TimingParameters.setDefault(parameters.getTimingParameters()); if (QueueingPathRemoverService.isRunning() == false) { @@ -476,4 +481,21 @@ public final class ETLDaemon operationLog.info("Data Store Server ready and waiting for data."); } + /** + * Runs ETL Daemon for system testing: Replaces default {@link IExitHandler} by a one which + * throws an {@link AssertionError}. + */ + public static void runForTesting(String[] args) + { + exitHandler = new IExitHandler() + { + public void exit(int exitCode) + { + throw new AssertionError("Unexpected exit: " + exitCode); + } + }; + Parameters parameters = new Parameters(args, exitHandler); + run(parameters); + } + } 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 268bee65d4958040e4154ca76bc97c3ba35cba45..6c69e1e09e08ef2c40b19467d46d9f2cc97f1b20 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 @@ -17,7 +17,9 @@ package ch.systemsx.cisd.openbis.dss.generic.shared.utils; import java.io.File; +import java.util.Map.Entry; import java.util.Properties; +import java.util.Set; import ch.rinn.restrictions.Private; import ch.systemsx.cisd.common.filesystem.FileUtilities; @@ -31,6 +33,9 @@ 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."; + @Private static final String DSS_CODE_KEY = "data-store-server-code"; @@ -39,7 +44,8 @@ public class DssPropertyParametersUtil public static final String DOWNLOAD_URL_KEY = "download-url"; - private static final String SERVICE_PROPERTIES_FILE = "etc/service.properties"; + /** Location of service properties file. */ + public static final String SERVICE_PROPERTIES_FILE = "etc/service.properties"; /** loads server configuration */ public static ExtendedProperties loadServiceProperties() @@ -50,6 +56,14 @@ public class DssPropertyParametersUtil public static ExtendedProperties loadProperties(String filePath) { Properties properties = PropertyUtils.loadProperties(filePath); + Properties systemProperties = System.getProperties(); + ExtendedProperties dssSystemProperties = + ExtendedProperties.getSubset(systemProperties, OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX, true); + Set<Entry<Object, Object>> entrySet = dssSystemProperties.entrySet(); + for (Entry<Object, Object> entry : entrySet) + { + properties.put(entry.getKey(), entry.getValue()); + } return ExtendedProperties.createWith(properties); } diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/systemtest/DssComponentTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/systemtest/DssComponentTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c97a982d9f0c3691264f6228e0fa5a09d8d74d5c --- /dev/null +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/systemtest/DssComponentTest.java @@ -0,0 +1,188 @@ +/* + * Copyright 2010 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.systemtest; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.apache.commons.io.IOUtils; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import ch.systemsx.cisd.common.filesystem.FileUtilities; +import ch.systemsx.cisd.openbis.dss.client.api.v1.DssComponentFactory; +import ch.systemsx.cisd.openbis.dss.client.api.v1.IDataSetDss; +import ch.systemsx.cisd.openbis.dss.client.api.v1.IDssComponent; +import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService; +import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider; +import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.FileInfoDssBuilder; +import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.FileInfoDssDTO; +import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO; +import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO.DataSetOwner; +import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO.DataSetOwnerType; +import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO; + +/** + * + * + * @author Franz-Josef Elmer + */ +public class DssComponentTest extends SystemTestCase +{ + private static final Comparator<FileInfoDssDTO> FILE_INFO_COMPARATOR = + new Comparator<FileInfoDssDTO>() + { + public int compare(FileInfoDssDTO f1, FileInfoDssDTO f2) + { + return f1.getPathInDataSet().compareTo(f2.getPathInDataSet()); + } + }; + private IDssComponent dss; + + @BeforeMethod + public void beforeMethod() + { + dss = DssComponentFactory.tryCreate("test", "a", "http://localhost:8888"); + } + + @Test + public void testPutDataSet() throws Exception + { + DataSetOwner dataSetOwner = new DataSetOwner(DataSetOwnerType.SAMPLE, "CISD:/CISD/3VCP1"); + File exampleDataSet = new File(workingDirectory, "my-data"); + exampleDataSet.mkdirs(); + FileUtilities.writeToFile(new File(exampleDataSet, "data.log"), "hello world"); + FileUtilities.writeToFile(new File(exampleDataSet, "data-set.properties"), + "property\tvalue\nCOMMENT\thello"); + File subFolder = new File(exampleDataSet, "data"); + subFolder.mkdirs(); + FileUtilities.writeToFile(new File(subFolder, "1.data"), "1 2 3"); + FileUtilities.writeToFile(new File(subFolder, "2.data"), "4 5 6 7"); + String rootPath = exampleDataSet.getCanonicalPath(); + FileInfoDssBuilder builder = new FileInfoDssBuilder(rootPath, rootPath); + ArrayList<FileInfoDssDTO> list = new ArrayList<FileInfoDssDTO>(); + builder.appendFileInfosForFile(exampleDataSet, list, true); + IDataSetDss dataSet = dss.putDataSet(new NewDataSetDTO(dataSetOwner, + exampleDataSet.getName(), list), exampleDataSet); + checkDataSet(dataSet); + } + + @Test(dependsOnMethods = "testPutDataSet") + public void testGetDataSetGetFile() throws Exception + { + String code = getCodeOfLatestDataSet().getDataSetCode(); + + IDataSetDss ds = dss.getDataSet(code); + + assertEquals(code, ds.getCode()); + checkDataSet(ds); + FileInfoDssDTO[] files = ds.listFiles("/original/my-data/data", false); + Arrays.sort(files, FILE_INFO_COMPARATOR); + assertEquals("[FileInfoDssDTO[/original/my-data/data/1.data,5], " + + "FileInfoDssDTO[/original/my-data/data/2.data,7]]", Arrays.asList(files) + .toString()); + files = ds.listFiles("/", true); + Arrays.sort(files, FILE_INFO_COMPARATOR); + assertEquals("[FileInfoDssDTO[/original,-1], FileInfoDssDTO[/original/my-data,-1], " + + "FileInfoDssDTO[/original/my-data/data,-1], " + + "FileInfoDssDTO[/original/my-data/data-set.properties,28], " + + "FileInfoDssDTO[/original/my-data/data.log,11], " + + "FileInfoDssDTO[/original/my-data/data/1.data,5], " + + "FileInfoDssDTO[/original/my-data/data/2.data,7]]", Arrays.asList(files) + .toString()); + } + + @Test(dependsOnMethods = "testPutDataSet") + public void testGetDataSetGetLink() throws Exception + { + SimpleDataSetInformationDTO dataSetInfo = getCodeOfLatestDataSet(); + String code = dataSetInfo.getDataSetCode(); + File fileIntoStore = new File(new File(rootDir, "store"), dataSetInfo.getDataSetLocation()); + + IDataSetDss ds = dss.getDataSet(code); + + File link = ds.tryLinkToContents(null); + assertEquals(fileIntoStore.getAbsolutePath(), link.getAbsolutePath()); + File file = ds.getLinkOrCopyOfContents(null, workingDirectory); + assertEquals(fileIntoStore.getAbsolutePath(), file.getAbsolutePath()); + } + + @Test(dependsOnMethods = "testPutDataSet") + public void testGetDataSetGetCopy() throws Exception + { + SimpleDataSetInformationDTO dataSetInfo = getCodeOfLatestDataSet(); + String code = dataSetInfo.getDataSetCode(); + + IDataSetDss ds = dss.getDataSet(code); + + assertEquals(null, ds.tryLinkToContents("blabla")); + File file = ds.getLinkOrCopyOfContents("blabla", workingDirectory); + assertContent("hello world", file, "data.log"); + assertContent("1 2 3", file, "data/1.data"); + assertContent("4 5 6 7", file, "data/2.data"); + } + + private void assertContent(String expectedContent, File root, String path) + { + assertEquals(expectedContent, + FileUtilities.loadToString(new File(root, "original/my-data/" + path)).trim()); + } + + private SimpleDataSetInformationDTO getCodeOfLatestDataSet() + { + IEncapsulatedOpenBISService openBISService = ServiceProvider.getOpenBISService(); + List<SimpleDataSetInformationDTO> dataSets = openBISService.listDataSets(); + Collections.sort(dataSets, new Comparator<SimpleDataSetInformationDTO>() + { + public int compare(SimpleDataSetInformationDTO d1, SimpleDataSetInformationDTO d2) + { + return d2.getDataSetCode().compareTo(d1.getDataSetCode()); + } + }); + return dataSets.get(0); + } + + private void checkDataSet(IDataSetDss dataSet) throws IOException + { + assertEquals("hello world", getContent(dataSet, "data.log")); + assertEquals("1 2 3", getContent(dataSet, "data/1.data")); + assertEquals("4 5 6 7", getContent(dataSet, "data/2.data")); + } + + private String getContent(IDataSetDss dataSet, String path) throws IOException + { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + InputStream inputStream = null; + try + { + inputStream = dataSet.getFile("/original/my-data/" + path); + IOUtils.copy(inputStream, output); + } finally + { + IOUtils.closeQuietly(inputStream); + } + return output.toString(); + } + +} diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/systemtest/SystemTestCase.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/systemtest/SystemTestCase.java new file mode 100644 index 0000000000000000000000000000000000000000..854e2d0dbd5cc0fdf45fc36a2cbc1edc8d8f61c6 --- /dev/null +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/systemtest/SystemTestCase.java @@ -0,0 +1,134 @@ +/* + * Copyright 2010 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.systemtest; + +import static ch.systemsx.cisd.openbis.dss.generic.shared.utils.DssPropertyParametersUtil.OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX; +import static ch.systemsx.cisd.openbis.dss.generic.shared.utils.DssPropertyParametersUtil.SERVICE_PROPERTIES_FILE; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import org.apache.commons.io.FileUtils; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.nio.SelectChannelConnector; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.springframework.beans.factory.xml.XmlBeanFactory; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.core.io.FileSystemResource; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.GenericWebApplicationContext; +import org.springframework.web.servlet.DispatcherServlet; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeSuite; + +import ch.systemsx.cisd.common.filesystem.FileUtilities; +import ch.systemsx.cisd.etlserver.ETLDaemon; +import ch.systemsx.cisd.openbis.dss.generic.server.DataStoreServer; +import ch.systemsx.cisd.openbis.generic.server.util.TestInitializer; + +/** + * + * + * @author Franz-Josef Elmer + */ +public class SystemTestCase extends AssertJUnit +{ + private static final String UNIT_TEST_WORKING_DIRECTORY = "unit-test-wd"; + private static final String TARGETS_DIRECTORY = "targets"; + private static final File UNIT_TEST_ROOT_DIRECTORY = + new File(TARGETS_DIRECTORY + File.separator + UNIT_TEST_WORKING_DIRECTORY); + private static final String ROOT_DIR_KEY = "root-dir"; + private static final String ROOT_DIR_PREFIX = "${" + ROOT_DIR_KEY + "}/"; + + protected File workingDirectory; + protected File rootDir; + + SystemTestCase() + { + workingDirectory = new File(UNIT_TEST_ROOT_DIRECTORY, getClass().getName()); + workingDirectory.mkdirs(); + workingDirectory.deleteOnExit(); + } + + @BeforeSuite + public void beforeSuite() throws Exception + { + TestInitializer.init(); + Server server = new Server(); + Connector connector = new SelectChannelConnector(); + connector.setPort(8888); + server.addConnector(connector); + DispatcherServlet dispatcherServlet = new DispatcherServlet() + { + private static final long serialVersionUID = 1L; + + @Override + protected WebApplicationContext findWebApplicationContext() + { + XmlBeanFactory f = + new XmlBeanFactory(new FileSystemResource( + "../openbis/resource/server/spring-servlet.xml")); + GenericWebApplicationContext wac = new GenericWebApplicationContext(f); + wac.setParent(new ClassPathXmlApplicationContext( + "classpath:applicationContext.xml")); + wac.refresh(); + return wac; + } + }; + ServletContextHandler sch = + new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS); + sch.addServlet(new ServletHolder(dispatcherServlet), "/*"); + server.start(); + + rootDir = new File(workingDirectory, "dss-root"); + List<String> serviceProperties = + FileUtilities.loadToStringList(new File(SERVICE_PROPERTIES_FILE)); + for (String property : serviceProperties) + { + int index = property.indexOf(ROOT_DIR_PREFIX); + if (index >= 0) + { + File folder = + new File(rootDir, property.substring(index + ROOT_DIR_PREFIX.length())); + if (folder.exists()) + { + FileUtilities.deleteRecursively(folder); + } + assertEquals("Couldn't create folder " + folder.getAbsolutePath(), true, + folder.mkdirs()); + } + } + System.setProperty(OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX + ROOT_DIR_KEY, + rootDir.getAbsolutePath()); + System.setProperty(OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX + "dss-rpc.put-default", + "dss-system-test-thread"); + DataStoreServer.main(new String[0]); + ETLDaemon.runForTesting(new String[0]); + } + + @BeforeClass + public void beforeClass() throws IOException + { + FileUtils.deleteDirectory(workingDirectory); + workingDirectory.mkdir(); + assertTrue(workingDirectory.isDirectory() && workingDirectory.listFiles().length == 0); + } +}