diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/admin/AbstractCommand.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/admin/AbstractCommand.java index 500910abac5f454b0d8a285ee8712e3f28206698..5a402c707955e84eb1062b73b426bef7612b26aa 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/admin/AbstractCommand.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/admin/AbstractCommand.java @@ -29,6 +29,7 @@ import org.apache.commons.lang.StringUtils; import ch.systemsx.cisd.args4j.CmdLineParser; import ch.systemsx.cisd.args4j.ExampleMode; +import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.properties.ExtendedProperties; import ch.systemsx.cisd.common.ssl.SslCertificateHelper; import ch.systemsx.cisd.openbis.common.api.client.ServiceFinder; @@ -44,7 +45,7 @@ import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService */ abstract class AbstractCommand { - private static final String BASH_COMMAND = "share-manager.sh"; + static final String BASH_COMMAND = "share-manager.sh"; private final String name; protected String sessionToken; @@ -80,7 +81,7 @@ abstract class AbstractCommand parser.printUsage(writer, null); out.println("Example: " + cmdString + parser.printExample(ExampleMode.ALL) + " " + getRequiredArgumentsString()); - throw new IllegalArgumentException(writer.toString()); + throw new UserFailureException(writer.toString()); } } @@ -89,26 +90,36 @@ abstract class AbstractCommand String username = getArguments().getUsername(); if (StringUtils.isBlank(username)) { - throw new IllegalArgumentException("Unspecified user name."); + throw new UserFailureException("Unspecified user name."); } String password = getArguments().getPassword(); if (StringUtils.isBlank(password)) { - throw new IllegalArgumentException("Unspecified password."); + throw new UserFailureException("Unspecified password."); } Properties properties = loadServiceProperties(); String openBisServerUrl = DssPropertyParametersUtil.getOpenBisServerUrl(properties); - SslCertificateHelper.trustAnyCertificate(openBisServerUrl); - ServiceFinder serviceFinder = new ServiceFinder("openbis", IGeneralInformationService.SERVICE_URL); - IGeneralInformationService infoService = serviceFinder.createService(IGeneralInformationService.class, - openBisServerUrl); + IGeneralInformationService infoService = createGeneralInfoService(openBisServerUrl); sessionToken = infoService.tryToAuthenticateForAllServices(username, password); if (sessionToken == null) { - throw new IllegalArgumentException("Invalid username/password combination"); + throw new UserFailureException("Invalid username/password combination."); } String downloadUrl = DssPropertyParametersUtil.getDownloadUrl(properties); - service = new DssServiceRpcGenericFactory().getService(downloadUrl); + service = createDssService(downloadUrl); + } + + IDssServiceRpcGeneric createDssService(String downloadUrl) + { + return new DssServiceRpcGenericFactory().getService(downloadUrl); + } + + IGeneralInformationService createGeneralInfoService(String openBisServerUrl) + { + SslCertificateHelper.trustAnyCertificate(openBisServerUrl); + ServiceFinder serviceFinder = + new ServiceFinder("openbis", IGeneralInformationService.SERVICE_URL); + return serviceFinder.createService(IGeneralInformationService.class, openBisServerUrl); } private Properties loadServiceProperties() @@ -124,13 +135,13 @@ abstract class AbstractCommand return ExtendedProperties.createWith(properties); } catch (FileNotFoundException ex) { - throw new IllegalArgumentException("DSS service.properties file not found: " + throw new UserFailureException("DSS service.properties file not found: " + servicPropertiesFile.getAbsolutePath() + (arguments.isServicePropertiesPathSpecified() ? "" : "\nUse option -sp to specify it.")); } catch (IOException ex) { - throw new IllegalArgumentException("Error while loading '" + throw new UserFailureException("Error while loading '" + servicPropertiesFile.getAbsolutePath() + "': " + ex, ex); } finally { diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/admin/ListSharesCommand.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/admin/ListSharesCommand.java index 86d9b16932a01d5381df6bd65f45f532c549a2c3..9234a17b74b5b1bd16639127e58ba9b7e1dfca75 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/admin/ListSharesCommand.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/admin/ListSharesCommand.java @@ -63,7 +63,9 @@ public class ListSharesCommand extends AbstractCommand System.out.println(shares.size() + " shares:"); for (ShareInfo shareInfo : shares) { - System.out.println(shareInfo.getShareId() + ": " + DirectoryRendererUtil.renderFileSize(shareInfo.getFreeSpace()) + " bytes free."); + System.out.println(shareInfo.getShareId() + ": " + + DirectoryRendererUtil.renderFileSize(shareInfo.getFreeSpace()) + + " bytes free."); } } } diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/admin/ShareManagerApplication.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/admin/ShareManagerApplication.java index d40180fa3d3a640ed2f22c441d5d5e9608e74959..67897e919ec413db755ed3829558e261e4f69412 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/admin/ShareManagerApplication.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/admin/ShareManagerApplication.java @@ -19,6 +19,10 @@ package ch.systemsx.cisd.openbis.dss.client.admin; import java.util.HashMap; import java.util.Map; +import org.apache.log4j.helpers.LogLog; + +import ch.systemsx.cisd.common.exceptions.UserFailureException; + /** * * @@ -37,11 +41,11 @@ public class ShareManagerApplication } } - void parseAndRun(String[] args) + void parseAndRun(String... args) { if (args.length == 0) { - throw new IllegalArgumentException("No command specified. Allowed commands are " + throw new UserFailureException("No command specified. Allowed commands are " + commandMap.keySet() + "."); } String commandName = args[0]; @@ -49,7 +53,7 @@ public class ShareManagerApplication commandMap.get(commandName); if (command == null) { - throw new IllegalArgumentException("Unknown command '" + commandName + throw new UserFailureException("Unknown command '" + commandName + "'. Allowed commands are " + commandMap.keySet() + "."); } String[] reducedArgs = new String[args.length - 1]; @@ -61,12 +65,13 @@ public class ShareManagerApplication public static void main(String[] args) { + LogLog.setQuietMode(true); ShareManagerApplication application = new ShareManagerApplication(new ListSharesCommand(), new MoveDataSetCommand()); try { application.parseAndRun(args); - } catch (IllegalArgumentException ex) + } catch (UserFailureException ex) { System.err.println(ex.getMessage()); System.exit(1); diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGeneric.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGeneric.java index 686994bf0a4f40a4418736bc42c4b5fa5a8cd7ca..323ce039f1e89cdafd5bad3c7bd8c4fb507fb088 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGeneric.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGeneric.java @@ -34,6 +34,7 @@ import org.apache.log4j.Logger; import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; import ch.systemsx.cisd.base.exceptions.IOExceptionUnchecked; +import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.filesystem.FileUtilities; import ch.systemsx.cisd.common.filesystem.IFreeSpaceProvider; import ch.systemsx.cisd.common.filesystem.SimpleFreeSpaceProvider; @@ -453,29 +454,29 @@ public class DssServiceRpcGeneric extends AbstractDssServiceRpc<IDssServiceRpcGe ExternalData dataSet = getOpenBISService().tryGetDataSet(dataSetCode); if (dataSet == null) { - throw new IllegalArgumentException("Unknown data set: " + dataSetCode); + throw new UserFailureException("Unknown data set: " + dataSetCode); } if (dataSet.isContainer()) { - throw new IllegalArgumentException("Container data set: " + dataSetCode); + throw new UserFailureException("Container data set: " + dataSetCode); } DataSet realDataSet = dataSet.tryGetAsDataSet(); String dataSetLocation = realDataSet.getDataSetLocation(); if (realDataSet.getShareId().equals(shareId)) { - throw new IllegalArgumentException("Data set " + dataSetCode + " is already in share " + throw new UserFailureException("Data set " + dataSetCode + " is already in share " + shareId + "."); } File share = new File(getStoreDirectory(), getShareIdManager().getShareId(dataSetCode)); File newShare = new File(getStoreDirectory(), shareId); if (newShare.exists() == false) { - throw new IllegalArgumentException("Share does not exists: " + throw new UserFailureException("Share does not exists: " + newShare.getAbsolutePath()); } if (newShare.isDirectory() == false) { - throw new IllegalArgumentException("Share is not a directory: " + throw new UserFailureException("Share is not a directory: " + newShare.getAbsolutePath()); } getDataSetMover().moveDataSetToAnotherShare(new File(share, dataSetLocation), newShare, diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/postregistration/EagerShufflingTaskTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/postregistration/EagerShufflingTaskTest.java index b678a980837ada7f40d4fa1c5e2e21bc4c4f716c..9a0805fe93ed335c28973e18a22d09ab61bd4010 100644 --- a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/postregistration/EagerShufflingTaskTest.java +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/postregistration/EagerShufflingTaskTest.java @@ -17,11 +17,8 @@ package ch.systemsx.cisd.etlserver.postregistration; import java.io.File; -import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashSet; -import java.util.List; import java.util.Properties; import org.apache.commons.io.FileUtils; @@ -37,8 +34,6 @@ import ch.rinn.restrictions.Friend; import ch.systemsx.cisd.base.tests.AbstractFileSystemTestCase; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; import ch.systemsx.cisd.common.filesystem.FileUtilities; -import ch.systemsx.cisd.common.filesystem.HostAwareFile; -import ch.systemsx.cisd.common.filesystem.IFreeSpaceProvider; import ch.systemsx.cisd.common.logging.BufferedAppender; import ch.systemsx.cisd.common.logging.ISimpleLogger; import ch.systemsx.cisd.common.logging.LogLevel; @@ -48,6 +43,7 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.IChecksumProvider; import ch.systemsx.cisd.openbis.dss.generic.shared.IConfigProvider; import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService; import ch.systemsx.cisd.openbis.dss.generic.shared.IShareIdManager; +import ch.systemsx.cisd.openbis.dss.generic.shared.utils.MockFreeSpaceProvider; import ch.systemsx.cisd.openbis.generic.shared.Constants; import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO; @@ -57,27 +53,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO; @Friend(toClasses = EagerShufflingTask.class) public class EagerShufflingTaskTest extends AbstractFileSystemTestCase { - private static final class MockFreeSpaceProvider implements IFreeSpaceProvider - { - private final List<String> shares = new ArrayList<String>(); - - private Integer[] freeSpaceValues; - - private int index; - - void setFreeSpaceValues(Integer... freeSpaceValues) - { - this.freeSpaceValues = freeSpaceValues; - } - - @Override - public long freeSpaceKb(HostAwareFile path) throws IOException - { - shares.add(path.getLocalFile().getName()); - return freeSpaceValues[index++ % freeSpaceValues.length]; - } - } - private static final String SHARDING = "sharding/"; private static final String DATA_STORE_SERVER_CODE = "DSS"; @@ -178,7 +153,7 @@ public class EagerShufflingTaskTest extends AbstractFileSystemTestCase assertEquals("Data set ds-1 successfully moved from share 1 to 4.", infoMessageMatcher.recordedObject()); - assertEquals("[1, 2, 3, 4, 4, 4]", freeSpaceProvider.shares.toString()); + assertEquals("[1, 2, 3, 4, 4, 4]", freeSpaceProvider.getShares().toString()); context.assertIsSatisfied(); } @@ -205,7 +180,7 @@ public class EagerShufflingTaskTest extends AbstractFileSystemTestCase assertEquals("Data set ds-1 successfully moved from share 1 to 2.", infoMessageMatcher.recordedObject()); - assertEquals("[1, 2, 3, 4, 2, 2]", freeSpaceProvider.shares.toString()); + assertEquals("[1, 2, 3, 4, 2, 2]", freeSpaceProvider.getShares().toString()); context.assertIsSatisfied(); } @@ -225,7 +200,7 @@ public class EagerShufflingTaskTest extends AbstractFileSystemTestCase assertEquals("No share found for shuffling data set ds-1.", logMessageMatcher.recordedObject()); - assertEquals("[1, 2, 3, 4, 1, 2, 3, 4]", freeSpaceProvider.shares.toString()); + assertEquals("[1, 2, 3, 4, 1, 2, 3, 4]", freeSpaceProvider.getShares().toString()); context.assertIsSatisfied(); } @@ -260,7 +235,7 @@ public class EagerShufflingTaskTest extends AbstractFileSystemTestCase "After moving data set ds-1 to share 2 that share has only 900.00 KB free space. " + "It might be necessary to add a new share.", notificationRecorder.recordedObject()); - assertEquals("[1, 2, 3, 4, 2, 2]", freeSpaceProvider.shares.toString()); + assertEquals("[1, 2, 3, 4, 2, 2]", freeSpaceProvider.getShares().toString()); context.assertIsSatisfied(); } @@ -293,7 +268,7 @@ public class EagerShufflingTaskTest extends AbstractFileSystemTestCase assertEquals("No share found for shuffling data set ds-1.", notificationRecorder.recordedObject()); - assertEquals("[1, 2, 3, 4, 1, 2, 3, 4]", freeSpaceProvider.shares.toString()); + assertEquals("[1, 2, 3, 4, 1, 2, 3, 4]", freeSpaceProvider.getShares().toString()); context.assertIsSatisfied(); } diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/admin/ShareManagerApplicationTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/admin/ShareManagerApplicationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a46f7e9f98ba95428fab80e2e6200fd89c229598 --- /dev/null +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/admin/ShareManagerApplicationTest.java @@ -0,0 +1,203 @@ +/* + * Copyright 2013 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.client.admin; + +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.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.IDssServiceRpcGeneric; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService; + +/** + * + * + * @author Franz-Josef Elmer + */ +public class ShareManagerApplicationTest extends AssertJUnit +{ + private static final String SEESION_TOKEN = "seesiontoken"; + + private static final class MockCommand extends AbstractCommand + { + private final CommonArguments arguments = new CommonArguments() + { + @Override + protected boolean allAdditionalMandatoryArgumentsPresent() + { + return arguments.size() == 1; + } + }; + + private final IGeneralInformationService service; + + private final IDssServiceRpcGeneric dssService; + + private String recordedDownloadUrl; + + private String recordedOpenBisServerUrl; + + private boolean executed; + + MockCommand(IGeneralInformationService service, IDssServiceRpcGeneric dssService) + { + super("mock"); + this.service = service; + this.dssService = dssService; + } + + @Override + protected CommonArguments getArguments() + { + return arguments; + } + + @Override + protected String getRequiredArgumentsString() + { + return "<arg>"; + } + + @Override + IDssServiceRpcGeneric createDssService(String downloadUrl) + { + this.recordedDownloadUrl = downloadUrl; + return dssService; + } + + @Override + IGeneralInformationService createGeneralInfoService(String openBisServerUrl) + { + recordedOpenBisServerUrl = openBisServerUrl; + return service; + } + + @Override + void execute() + { + executed = true; + } + + } + + private Mockery context; + private IDssServiceRpcGeneric dssService; + private IGeneralInformationService service; + private ShareManagerApplication shareManagerApplication; + private MockCommand mockCommand; + + @BeforeMethod + public void setUp() + { + context = new Mockery(); + dssService = context.mock(IDssServiceRpcGeneric.class); + service = context.mock(IGeneralInformationService.class); + mockCommand = new MockCommand(service, dssService); + shareManagerApplication = new ShareManagerApplication(mockCommand); + } + + @AfterMethod + public void tearDown() + { + context.assertIsSatisfied(); + } + @Test(expectedExceptionsMessageRegExp = "No command specified. Allowed commands are \\[mock\\]\\.", expectedExceptions = UserFailureException.class) + public void testParseAndRunMissingCommand() + { + shareManagerApplication.parseAndRun(); + + context.assertIsSatisfied(); + } + + @Test(expectedExceptionsMessageRegExp = "Unknown command 'hello'. Allowed commands are \\[mock\\]\\.", expectedExceptions = UserFailureException.class) + public void testParseAndRunUnknowngCommand() + { + shareManagerApplication.parseAndRun("hello"); + + context.assertIsSatisfied(); + } + + @Test + public void testMissingMandatoryArgument() + { + try + { + shareManagerApplication.parseAndRun("mock", "-u", "user", "-p", "pswd"); + fail("UserFailureException expected"); + } catch (UserFailureException ex) + { + assertEquals( + "Usage: " + + AbstractCommand.BASH_COMMAND + + " mock [options] <arg>\n" + + " [-p,--password] VAL : User login password\n" + + " [-sp,--service-properties] VAL : Path to DSS service.properties (default:\n" + + " etc/service.properties)\n" + + " [-u,--username] VAL : User login name\n" + "Example: " + + AbstractCommand.BASH_COMMAND + " mock -p VAL -sp VAL -u VAL <arg>\n", + ex.getMessage()); + } + context.assertIsSatisfied(); + } + + @Test + public void testParseAndRunLoginFailed() + { + context.checking(new Expectations() + { + { + one(service).tryToAuthenticateForAllServices("user", "pswd"); + will(returnValue(null)); + } + }); + + try + { + shareManagerApplication.parseAndRun("mock", "-u", "user", "-p", "pswd", "a"); + fail("UserFailureException expected"); + } catch (UserFailureException ex) + { + assertEquals("Invalid username/password combination.", ex.getMessage()); + } + + context.assertIsSatisfied(); + } + + @Test + public void testParseAndRun() + { + context.checking(new Expectations() + { + { + one(service).tryToAuthenticateForAllServices("user", "pswd"); + will(returnValue(SEESION_TOKEN)); + } + }); + + shareManagerApplication.parseAndRun("mock", "-u", "user", "-p", "pswd", "a"); + + assertEquals(true, mockCommand.executed); + assertEquals("http://localhost:8888", mockCommand.recordedOpenBisServerUrl); + assertEquals("http://localhost:8889", mockCommand.recordedDownloadUrl); + context.assertIsSatisfied(); + } + +} diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericTest.java index e30b6122e4b9f588f287edb32751df39b3bd7e9e..74a2d50e13f5d5fb65bb39a2831193e07bc82f7a 100644 --- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericTest.java +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericTest.java @@ -19,17 +19,20 @@ package ch.systemsx.cisd.openbis.dss.generic.server.api.v1; import java.io.File; import java.util.Arrays; import java.util.Collections; +import java.util.List; +import org.apache.commons.io.FileUtils; import org.jmock.Expectations; import org.jmock.Mockery; import org.springframework.aop.framework.ProxyFactoryBean; import org.springframework.beans.factory.support.StaticListableBeanFactory; -import org.testng.AssertJUnit; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import ch.systemsx.cisd.common.filesystem.IFreeSpaceProvider; +import ch.systemsx.cisd.base.tests.AbstractFileSystemTestCase; +import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.common.filesystem.FileUtilities; import ch.systemsx.cisd.common.io.IOUtilities; import ch.systemsx.cisd.common.server.ISessionTokenProvider; import ch.systemsx.cisd.common.test.RecordingMatcher; @@ -45,14 +48,17 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProviderTestWrapper; import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.authorization.DssSessionAuthorizationHolder; import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.FileInfoDssDTO; import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.IDssServiceRpcGeneric; +import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.ShareInfo; +import ch.systemsx.cisd.openbis.dss.generic.shared.utils.MockFreeSpaceProvider; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ContainerDataSet; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSet; import ch.systemsx.cisd.openbis.plugin.query.shared.api.v1.IQueryApiServer; /** * @author Franz-Josef Elmer */ -public class DssServiceRpcGenericTest extends AssertJUnit +public class DssServiceRpcGenericTest extends AbstractFileSystemTestCase { - private static final String SESSION_TOKEN = "SESSION"; private IEncapsulatedOpenBISService service; @@ -63,8 +69,8 @@ public class DssServiceRpcGenericTest extends AssertJUnit private IShareIdManager shareIdManager; - private IFreeSpaceProvider freeSpaceProvider; - + private MockFreeSpaceProvider freeSpaceProvider; + private IPluginTaskInfoProvider infoProvider; private IQueryApiServer apiService; @@ -73,6 +79,12 @@ public class DssServiceRpcGenericTest extends AssertJUnit private IHierarchicalContent content; + private File share1; + + private File share2; + + private File storeDir; + @BeforeMethod public void beforeMethod() { @@ -82,7 +94,7 @@ public class DssServiceRpcGenericTest extends AssertJUnit context = new Mockery(); service = context.mock(IEncapsulatedOpenBISService.class); apiService = context.mock(IQueryApiServer.class); - freeSpaceProvider = context.mock(IFreeSpaceProvider.class); + freeSpaceProvider = new MockFreeSpaceProvider(); shareIdManager = context.mock(IShareIdManager.class); infoProvider = context.mock(IPluginTaskInfoProvider.class); context.checking(new Expectations() @@ -101,6 +113,12 @@ public class DssServiceRpcGenericTest extends AssertJUnit DssServiceRpcGeneric nakedDssService = new DssServiceRpcGeneric(service, apiService, infoProvider, freeSpaceProvider, shareIdManager, contentProvider); + storeDir = new File(workingDirectory, "store"); + share1 = new File(storeDir, "1"); + share1.mkdirs(); + share2 = new File(storeDir, "2"); + share2.mkdirs(); + nakedDssService.setStoreDirectory(storeDir); proxyFactoryBean.setTarget(nakedDssService); proxyFactoryBean.addAdvisor(new DssServiceRpcAuthorizationAdvisor(shareIdManager)); dssService = (IDssServiceRpcGeneric) proxyFactoryBean.getObject(); @@ -175,7 +193,7 @@ public class DssServiceRpcGenericTest extends AssertJUnit IHierarchicalContentNode mainNode = createNodeMock("mainNode"); one(content).getNode(path); will(returnValue(mainNode)); - + IHierarchicalContentNode childNode1 = createNodeMock("childNode1"); IHierarchicalContentNode childNode1Child1 = createNodeMock("childNode1Child1"); IHierarchicalContentNode childNode1Child2 = createNodeMock("childNode1Child2"); @@ -244,6 +262,165 @@ public class DssServiceRpcGenericTest extends AssertJUnit context.assertIsSatisfied(); } + @Test + public void testListAllShares() + { + prepareCheckInstanceAdminAuthorization(); + freeSpaceProvider.setFreeSpaceValues(4711, 42); + + List<ShareInfo> shares = dssService.listAllShares(SESSION_TOKEN); + + assertEquals("1", shares.get(0).getShareId()); + assertEquals(4711 * FileUtils.ONE_KB, shares.get(0).getFreeSpace()); + assertEquals("2", shares.get(1).getShareId()); + assertEquals(42 * FileUtils.ONE_KB, shares.get(1).getFreeSpace()); + assertEquals(2, shares.size()); + context.assertIsSatisfied(); + } + + @Test + public void testShuffleDataSet() + { + File dataSetDir = new File(share1, "uuid/a/b/c/ds1"); + dataSetDir.mkdirs(); + FileUtilities.writeToFile(new File(dataSetDir, "hello.txt"), "hello world"); + prepareCheckInstanceAdminAuthorization(); + prepareLockDataSet("ds1"); + context.checking(new Expectations() + { + { + atLeast(1).of(service).tryGetDataSet("ds1"); + DataSet dataSet = new DataSet(); + dataSet.setCode("ds1"); + dataSet.setShareId("1"); + dataSet.setLocation("uuid/a/b/c/ds1"); + will(returnValue(dataSet)); + + one(shareIdManager).getShareId("ds1"); + will(returnValue("1")); + + one(shareIdManager).lock("ds1"); + one(shareIdManager).releaseLock("ds1"); + + one(service).updateShareIdAndSize("ds1", "2", 11); + one(shareIdManager).setShareId("ds1", "2"); + one(shareIdManager).await("ds1"); + } + }); + freeSpaceProvider.setFreeSpaceValues(4711, 42); + + dssService.shuffleDataSet(SESSION_TOKEN, "ds1", "2"); + + assertEquals("hello world", + FileUtilities.loadToString(new File(share2, "uuid/a/b/c/ds1/hello.txt")).trim()); + context.assertIsSatisfied(); + } + + @Test + public void testShuffleUnknownDataSet() + { + prepareCheckInstanceAdminAuthorization(); + prepareLockDataSet("ds1"); + context.checking(new Expectations() + { + { + atLeast(1).of(service).tryGetDataSet("ds1"); + } + }); + + try + { + dssService.shuffleDataSet(SESSION_TOKEN, "ds1", "2"); + fail("UserFailureException expected"); + } catch (UserFailureException ex) + { + assertEquals("Unknown data set: ds1", ex.getMessage()); + } + context.assertIsSatisfied(); + } + + @Test + public void testShuffleContainerDataSet() + { + prepareCheckInstanceAdminAuthorization(); + prepareLockDataSet("ds1"); + context.checking(new Expectations() + { + { + atLeast(1).of(service).tryGetDataSet("ds1"); + will(returnValue(new ContainerDataSet())); + } + }); + + try + { + dssService.shuffleDataSet(SESSION_TOKEN, "ds1", "2"); + fail("UserFailureException expected"); + } catch (UserFailureException ex) + { + assertEquals("Container data set: ds1", ex.getMessage()); + } + context.assertIsSatisfied(); + } + + @Test + public void testShuffleDataSetToSameShare() + { + prepareCheckInstanceAdminAuthorization(); + prepareLockDataSet("ds1"); + context.checking(new Expectations() + { + { + atLeast(1).of(service).tryGetDataSet("ds1"); + DataSet dataSet = new DataSet(); + dataSet.setCode("ds1"); + dataSet.setShareId("1"); + will(returnValue(dataSet)); + } + }); + + try + { + dssService.shuffleDataSet(SESSION_TOKEN, "ds1", "1"); + fail("UserFailureException expected"); + } catch (UserFailureException ex) + { + assertEquals("Data set ds1 is already in share 1.", ex.getMessage()); + } + context.assertIsSatisfied(); + } + + @Test + public void testShuffleDataSetToUnknownShare() + { + prepareCheckInstanceAdminAuthorization(); + prepareLockDataSet("ds1"); + context.checking(new Expectations() + { + { + atLeast(1).of(service).tryGetDataSet("ds1"); + DataSet dataSet = new DataSet(); + dataSet.setCode("ds1"); + dataSet.setShareId("1"); + will(returnValue(dataSet)); + + one(shareIdManager).getShareId("ds1"); + will(returnValue("1")); + } + }); + + try + { + dssService.shuffleDataSet(SESSION_TOKEN, "ds1", "3"); + fail("UserFailureException expected"); + } catch (UserFailureException ex) + { + assertEquals("Share does not exists: " + storeDir.getAbsolutePath() + "/3", + ex.getMessage()); + } + context.assertIsSatisfied(); + } + private static String fileInfoString(String startPath, String pathInListing, long length, Integer checksum) { @@ -265,7 +442,19 @@ public class DssServiceRpcGenericTest extends AssertJUnit { { one(shareIdManager).lock(Arrays.asList(dataSetCode)); - one(shareIdManager).releaseLocks(); + allowing(shareIdManager).releaseLocks(); + } + }); + } + + private void prepareCheckInstanceAdminAuthorization() + { + context.checking(new Expectations() + { + { + one(service).checkInstanceAdminAuthorization(SESSION_TOKEN); + one(service).checkSession(SESSION_TOKEN); + allowing(shareIdManager).releaseLocks(); } }); } diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/MockFreeSpaceProvider.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/MockFreeSpaceProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..1bd5ecc107f2da29932ed3a40365bbee7e0cf26e --- /dev/null +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/MockFreeSpaceProvider.java @@ -0,0 +1,50 @@ +/* + * Copyright 2013 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 java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import ch.systemsx.cisd.common.filesystem.HostAwareFile; +import ch.systemsx.cisd.common.filesystem.IFreeSpaceProvider; + +public class MockFreeSpaceProvider implements IFreeSpaceProvider +{ + final List<String> shares = new ArrayList<String>(); + + private Integer[] freeSpaceValues; + + private int index; + + public void setFreeSpaceValues(Integer... freeSpaceValues) + { + this.freeSpaceValues = freeSpaceValues; + } + + public List<String> getShares() + { + return shares; + } + + @Override + public long freeSpaceKb(HostAwareFile path) throws IOException + { + shares.add(path.getLocalFile().getName()); + return freeSpaceValues[index++ % freeSpaceValues.length]; + } +} \ No newline at end of file