Skip to content
Snippets Groups Projects
Commit e5d9ddb2 authored by felmer's avatar felmer
Browse files

LMS-1995 IDataSetMover introduced. Tests written for SegmentedStoreBalancerTask and SimpleBalancer.

SVN: 19922
parent 2d0c8c72
No related branches found
No related tags found
No related merge requests found
Showing with 444 additions and 36 deletions
/*
* 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.etlserver.plugins;
import java.io.File;
/**
* Strategy of moving a data set to another share.
*
* @author Franz-Josef Elmer
*/
public interface IDataSetMover
{
/**
* Moves the specified data set to the specified share. The data set is folder in the store
* its name is the data set code. The destination folder is <code>share</code>. Its name is
* the share id. Share id and size will be updated on openBIS.
*/
public void moveDataSetToAnotherShare(File dataSetDirInStore, File share);
}
...@@ -23,12 +23,18 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService; ...@@ -23,12 +23,18 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
import ch.systemsx.cisd.openbis.dss.generic.shared.utils.Share; import ch.systemsx.cisd.openbis.dss.generic.shared.utils.Share;
/** /**
* * Strategy of balancing data sets between shares in segmented store.
* *
* @author Franz-Josef Elmer * @author Franz-Josef Elmer
*/ */
public interface ISegmentedStoreBalancer public interface ISegmentedStoreBalancer
{ {
/**
* Balances sizes of specified shares by moving data sets between them using specified data set mover.
*
* @param service
*
*/
public void balanceStore(List<Share> shares, IEncapsulatedOpenBISService service, public void balanceStore(List<Share> shares, IEncapsulatedOpenBISService service,
ISimpleLogger logger); IDataSetMover dataSetMover, ISimpleLogger logger);
} }
...@@ -39,21 +39,26 @@ public class NonBalancer implements ISegmentedStoreBalancer ...@@ -39,21 +39,26 @@ public class NonBalancer implements ISegmentedStoreBalancer
private static final int N = 3; private static final int N = 3;
public void balanceStore(List<Share> shares, IEncapsulatedOpenBISService service, public void balanceStore(List<Share> shares, IEncapsulatedOpenBISService service,
ISimpleLogger logger) IDataSetMover dataSetMover, ISimpleLogger logger)
{ {
logger.log(INFO, "Data Store Shares:"); logger.log(INFO, "Data Store Shares:");
for (Share share : shares) for (Share share : shares)
{ {
List<SimpleDataSetInformationDTO> dataSets = share.getDataSetsOrderedBySize(); List<SimpleDataSetInformationDTO> dataSets = share.getDataSetsOrderedBySize();
logger.log(INFO, " Share " + share.getShareId() + " (free space: " logger.log(
+ FileUtils.byteCountToDisplaySize(share.calculateFreeSpace()) + ") has " INFO,
+ dataSets.size() + " data sets occupying " " Share " + share.getShareId() + " (free space: "
+ FileUtilities.byteCountToDisplaySize(share.getTotalSizeOfDataSets()) + "."); + FileUtils.byteCountToDisplaySize(share.calculateFreeSpace())
+ ") has " + dataSets.size() + " data sets occupying "
+ FileUtilities.byteCountToDisplaySize(share.getTotalSizeOfDataSets())
+ ".");
for (int i = 0, n = Math.min(N, dataSets.size()); i < n; i++) for (int i = 0, n = Math.min(N, dataSets.size()); i < n; i++)
{ {
SimpleDataSetInformationDTO dataSet = dataSets.get(i); SimpleDataSetInformationDTO dataSet = dataSets.get(i);
logger.log(INFO, " " + dataSet.getDataSetCode() + " " logger.log(
+ FileUtilities.byteCountToDisplaySize(dataSet.getDataSetSize())); INFO,
" " + dataSet.getDataSetCode() + " "
+ FileUtilities.byteCountToDisplaySize(dataSet.getDataSetSize()));
} }
if (dataSets.size() > N) if (dataSets.size() > N)
{ {
......
...@@ -22,6 +22,7 @@ import java.util.Properties; ...@@ -22,6 +22,7 @@ import java.util.Properties;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import ch.rinn.restrictions.Private;
import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel;
import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException;
import ch.systemsx.cisd.common.filesystem.IFreeSpaceProvider; import ch.systemsx.cisd.common.filesystem.IFreeSpaceProvider;
...@@ -42,38 +43,48 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.utils.SegmentedStoreUtils; ...@@ -42,38 +43,48 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.utils.SegmentedStoreUtils;
import ch.systemsx.cisd.openbis.dss.generic.shared.utils.Share; import ch.systemsx.cisd.openbis.dss.generic.shared.utils.Share;
/** /**
* * Maintenance task which tries to balance a segmented store.
* *
* @author Franz-Josef Elmer * @author Franz-Josef Elmer
*/ */
public class SegmentedStoreBalancingTask implements IMaintenanceTask public class SegmentedStoreBalancingTask implements IMaintenanceTask
{ {
private static final String BALANCER_SECTION_NAME = "balancer"; @Private static final String BALANCER_SECTION_NAME = "balancer";
private static final String CLASS_PROPERTY_NAME = "class"; @Private static final String CLASS_PROPERTY_NAME = "class";
private static final Logger operationLog = private static final Logger operationLog =
LogFactory.getLogger(LogCategory.OPERATION, SegmentedStoreBalancingTask.class); LogFactory.getLogger(LogCategory.OPERATION, SegmentedStoreBalancingTask.class);
private final IEncapsulatedOpenBISService service; private final IEncapsulatedOpenBISService service;
private final IDataSetMover dataSetMover;
private final IFreeSpaceProvider freeSpaceProvider; private final IFreeSpaceProvider freeSpaceProvider;
private final ISimpleLogger operationLogger; private final ISimpleLogger operationLogger;
private File storeRoot; private File storeRoot;
private String dataStoreCode; private String dataStoreCode;
private ISegmentedStoreBalancer balancer; @Private ISegmentedStoreBalancer balancer;
public SegmentedStoreBalancingTask() public SegmentedStoreBalancingTask()
{ {
this(ServiceProvider.getOpenBISService(), new SimpleFreeSpaceProvider(), this(ServiceProvider.getOpenBISService(), new SimpleFreeSpaceProvider(),
new Log4jSimpleLogger(operationLog)); new IDataSetMover()
{
public void moveDataSetToAnotherShare(File dataSetDirInStore, File share)
{
SegmentedStoreUtils.moveDataSetToAnotherShare(dataSetDirInStore, share,
ServiceProvider.getOpenBISService());
}
}, new Log4jSimpleLogger(operationLog));
} }
SegmentedStoreBalancingTask(IEncapsulatedOpenBISService service, SegmentedStoreBalancingTask(final IEncapsulatedOpenBISService service,
IFreeSpaceProvider freeSpaceProvider, ISimpleLogger logger) IFreeSpaceProvider freeSpaceProvider, IDataSetMover dataSetMover, ISimpleLogger logger)
{ {
LogInitializer.init(); LogInitializer.init();
this.freeSpaceProvider = freeSpaceProvider; this.freeSpaceProvider = freeSpaceProvider;
this.service = service; this.service = service;
this.dataSetMover = dataSetMover;
operationLogger = logger; operationLogger = logger;
} }
...@@ -126,7 +137,7 @@ public class SegmentedStoreBalancingTask implements IMaintenanceTask ...@@ -126,7 +137,7 @@ public class SegmentedStoreBalancingTask implements IMaintenanceTask
List<Share> shares = List<Share> shares =
SegmentedStoreUtils.getDataSetsPerShare(storeRoot, dataStoreCode, SegmentedStoreUtils.getDataSetsPerShare(storeRoot, dataStoreCode,
freeSpaceProvider, service, operationLogger); freeSpaceProvider, service, operationLogger);
balancer.balanceStore(shares, service, operationLogger); balancer.balanceStore(shares, service, dataSetMover, operationLogger);
operationLog.info("Segmented store balancing finished."); operationLog.info("Segmented store balancing finished.");
} }
......
...@@ -26,22 +26,26 @@ import java.util.List; ...@@ -26,22 +26,26 @@ import java.util.List;
import java.util.Properties; import java.util.Properties;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.time.StopWatch;
import ch.rinn.restrictions.Private;
import ch.systemsx.cisd.common.logging.ISimpleLogger; import ch.systemsx.cisd.common.logging.ISimpleLogger;
import ch.systemsx.cisd.common.utilities.ITimeProvider;
import ch.systemsx.cisd.common.utilities.PropertyUtils; import ch.systemsx.cisd.common.utilities.PropertyUtils;
import ch.systemsx.cisd.common.utilities.SystemTimeProvider;
import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService; import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
import ch.systemsx.cisd.openbis.dss.generic.shared.utils.SegmentedStoreUtils;
import ch.systemsx.cisd.openbis.dss.generic.shared.utils.Share; import ch.systemsx.cisd.openbis.dss.generic.shared.utils.Share;
import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO; import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO;
/** /**
* Simple balancer which moves data sets from full shares to the share with initial most free space
* until it is full.
* *
*
* @author Franz-Josef Elmer * @author Franz-Josef Elmer
*/ */
public class SimpleBalancer implements ISegmentedStoreBalancer public class SimpleBalancer implements ISegmentedStoreBalancer
{ {
@Private static final String MINIMUM_FREE_SPACE_KEY = "minimum-free-space-in-MB";
private static final class ShareState private static final class ShareState
{ {
private final Share share; private final Share share;
...@@ -88,16 +92,24 @@ public class SimpleBalancer implements ISegmentedStoreBalancer ...@@ -88,16 +92,24 @@ public class SimpleBalancer implements ISegmentedStoreBalancer
} }
private final long minimumFreeSpace; private final long minimumFreeSpace;
private final ITimeProvider timeProvider;
public SimpleBalancer(Properties properties) public SimpleBalancer(Properties properties)
{ {
this(properties, SystemTimeProvider.SYSTEM_TIME_PROVIDER);
}
SimpleBalancer(Properties properties, ITimeProvider timeProvider)
{
this.timeProvider = timeProvider;
minimumFreeSpace = minimumFreeSpace =
FileUtils.ONE_MB FileUtils.ONE_MB
* PropertyUtils.getLong(properties, "minimum-free-space-in-MB", 1024); * PropertyUtils.getLong(properties, MINIMUM_FREE_SPACE_KEY, 1024);
} }
public void balanceStore(List<Share> shares, IEncapsulatedOpenBISService service, public void balanceStore(List<Share> shares, IEncapsulatedOpenBISService service,
ISimpleLogger logger) IDataSetMover dataSetMover, ISimpleLogger logger)
{ {
List<ShareState> shareStates = getSortedShares(shares); List<ShareState> shareStates = getSortedShares(shares);
ShareState shareWithMostFree = shareStates.get(shareStates.size() - 1); ShareState shareWithMostFree = shareStates.get(shareStates.size() - 1);
...@@ -119,7 +131,7 @@ public class SimpleBalancer implements ISegmentedStoreBalancer ...@@ -119,7 +131,7 @@ public class SimpleBalancer implements ISegmentedStoreBalancer
long dataSetSize = dataSets.get(i).getDataSetSize(); long dataSetSize = dataSets.get(i).getDataSetSize();
if (shareWithMostFree.getFreeSpace() - dataSetSize > minimumFreeSpace) if (shareWithMostFree.getFreeSpace() - dataSetSize > minimumFreeSpace)
{ {
copy(fullShare, 0, shareWithMostFree, service, logger); copy(fullShare, 0, shareWithMostFree, dataSetMover, logger);
} }
} }
} }
...@@ -137,11 +149,11 @@ public class SimpleBalancer implements ISegmentedStoreBalancer ...@@ -137,11 +149,11 @@ public class SimpleBalancer implements ISegmentedStoreBalancer
} }
freeSpaceAboveMinimum += dataSets.get(i).getDataSetSize(); freeSpaceAboveMinimum += dataSets.get(i).getDataSetSize();
} }
return -1; return freeSpaceAboveMinimum > 0 ? dataSets.size() : -1;
} }
private void copy(ShareState from, int dataSetIndex, ShareState to, private void copy(ShareState from, int dataSetIndex, ShareState to,
IEncapsulatedOpenBISService service, ISimpleLogger logger) IDataSetMover mover, ISimpleLogger logger)
{ {
Share fromShare = from.getShare(); Share fromShare = from.getShare();
Share toShare = to.getShare(); Share toShare = to.getShare();
...@@ -149,17 +161,15 @@ public class SimpleBalancer implements ISegmentedStoreBalancer ...@@ -149,17 +161,15 @@ public class SimpleBalancer implements ISegmentedStoreBalancer
fromShare.getDataSetsOrderedBySize().get(dataSetIndex); fromShare.getDataSetsOrderedBySize().get(dataSetIndex);
File dataSetDirInStore = new File(fromShare.getShare(), dataSet.getDataSetLocation()); File dataSetDirInStore = new File(fromShare.getShare(), dataSet.getDataSetLocation());
String commonMessage = String commonMessage =
"data set " + dataSet.getDataSetCode() + " from share " + fromShare.getShareId() "Moving data set " + dataSet.getDataSetCode() + " from share " + fromShare.getShareId()
+ " to share " + toShare.getShareId(); + " to share " + toShare.getShareId();
logger.log(INFO, "Move " + commonMessage + " ..."); logger.log(INFO, commonMessage + " ...");
StopWatch stopWatch = new StopWatch(); long t0 = timeProvider.getTimeInMilliseconds();
stopWatch.start(); mover.moveDataSetToAnotherShare(dataSetDirInStore, toShare.getShare());
SegmentedStoreUtils.moveDataSetToAnotherShare(dataSetDirInStore, toShare.getShare(),
service);
from.removeDataSet(dataSetIndex); from.removeDataSet(dataSetIndex);
to.addDataSet(dataSet); to.addDataSet(dataSet);
stopWatch.stop(); logger.log(INFO, commonMessage + " took "
logger.log(INFO, "Moving " + commonMessage + " took " + stopWatch.toString()); + ((timeProvider.getTimeInMilliseconds() - t0 + 500) / 1000) + " seconds.");
} }
private List<ShareState> getFullShares(List<ShareState> shareStates) private List<ShareState> getFullShares(List<ShareState> shareStates)
......
...@@ -59,7 +59,7 @@ public final class Share ...@@ -59,7 +59,7 @@ public final class Share
private long size; private long size;
Share(File share, IFreeSpaceProvider freeSpaceProvider) public Share(File share, IFreeSpaceProvider freeSpaceProvider)
{ {
this.share = share; this.share = share;
this.freeSpaceProvider = freeSpaceProvider; this.freeSpaceProvider = freeSpaceProvider;
...@@ -96,7 +96,7 @@ public final class Share ...@@ -96,7 +96,7 @@ public final class Share
} }
} }
void addDataSet(SimpleDataSetInformationDTO dataSet) public void addDataSet(SimpleDataSetInformationDTO dataSet)
{ {
dataSets.add(dataSet); dataSets.add(dataSet);
size += dataSet.getDataSetSize(); size += dataSet.getDataSetSize();
......
/*
* 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.etlserver.plugins;
import static ch.systemsx.cisd.etlserver.plugins.SegmentedStoreBalancingTask.BALANCER_SECTION_NAME;
import static ch.systemsx.cisd.etlserver.plugins.SegmentedStoreBalancingTask.CLASS_PROPERTY_NAME;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import ch.rinn.restrictions.Friend;
import ch.systemsx.cisd.base.tests.AbstractFileSystemTestCase;
import ch.systemsx.cisd.common.filesystem.IFreeSpaceProvider;
import ch.systemsx.cisd.common.logging.ISimpleLogger;
import ch.systemsx.cisd.common.logging.LogLevel;
import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
import ch.systemsx.cisd.openbis.dss.generic.shared.utils.DssPropertyParametersUtil;
import ch.systemsx.cisd.openbis.dss.generic.shared.utils.Share;
import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO;
/**
*
*
* @author Franz-Josef Elmer
*/
@Friend(toClasses=SegmentedStoreBalancingTask.class)
public class SegmentedStoreBalancingTaskTest extends AbstractFileSystemTestCase
{
public static final class Balancer implements ISegmentedStoreBalancer
{
private final Properties properties;
private List<Share> shares;
private IEncapsulatedOpenBISService service;
private IDataSetMover dataSetMover;
private ISimpleLogger logger;
public Balancer(Properties properties)
{
this.properties = properties;
}
public void balanceStore(List<Share> list, IEncapsulatedOpenBISService openBisService,
IDataSetMover mover, ISimpleLogger simpleLogger)
{
shares = list;
service = openBisService;
dataSetMover = mover;
logger = simpleLogger;
}
}
private Mockery context;
private IEncapsulatedOpenBISService service;
private IFreeSpaceProvider spaceProvider;
private IDataSetMover dataSetMover;
private ISimpleLogger logger;
private SegmentedStoreBalancingTask balancerTask;
private File storeRoot;
@BeforeMethod
public void beforeMethod()
{
context = new Mockery();
service = context.mock(IEncapsulatedOpenBISService.class);
spaceProvider = context.mock(IFreeSpaceProvider.class);
dataSetMover = context.mock(IDataSetMover.class);
logger = context.mock(ISimpleLogger.class);
balancerTask = new SegmentedStoreBalancingTask(service, spaceProvider, dataSetMover, logger);
storeRoot = new File(workingDirectory, "store");
storeRoot.mkdirs();
}
@AfterMethod
public void afterMethod()
{
// The 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 testExecute()
{
Properties properties = new Properties();
properties.setProperty(DssPropertyParametersUtil.DSS_CODE_KEY, "data-store-1");
properties.setProperty(DssPropertyParametersUtil.STOREROOT_DIR_KEY, storeRoot.getPath());
properties.setProperty(BALANCER_SECTION_NAME + "." + CLASS_PROPERTY_NAME,
SegmentedStoreBalancingTaskTest.Balancer.class.getName());
balancerTask.setUp("mock-balancer", properties);
context.checking(new Expectations()
{
{
one(service).listDataSets();
SimpleDataSetInformationDTO ds = new SimpleDataSetInformationDTO();
ds.setDataStoreCode("other data store");
will(returnValue(Arrays.asList(ds)));
}
});
balancerTask.execute();
Balancer balancer = (SegmentedStoreBalancingTaskTest.Balancer) balancerTask.balancer;
assertEquals("{class=" + balancer.getClass().getName() + "}",
balancer.properties.toString());
assertEquals("[]", balancer.shares.toString());
assertSame(service, balancer.service);
assertSame(dataSetMover, balancer.dataSetMover);
assertSame(logger, balancer.logger);
context.assertIsSatisfied();
}
@Test
public void testDefaultBalancer()
{
Properties properties = new Properties();
properties.setProperty(DssPropertyParametersUtil.DSS_CODE_KEY, "data-store-1");
properties.setProperty(DssPropertyParametersUtil.STOREROOT_DIR_KEY, storeRoot.getPath());
balancerTask.setUp("mock-balancer", properties);
context.checking(new Expectations()
{
{
one(service).listDataSets();
will(returnValue(Arrays.asList()));
one(logger).log(LogLevel.INFO, "Data Store Shares:");
}
});
balancerTask.execute();
context.assertIsSatisfied();
}
}
/*
* 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.etlserver.plugins;
import static org.apache.commons.io.FileUtils.ONE_MB;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import ch.rinn.restrictions.Friend;
import ch.systemsx.cisd.base.tests.AbstractFileSystemTestCase;
import ch.systemsx.cisd.common.filesystem.HostAwareFile;
import ch.systemsx.cisd.common.filesystem.IFreeSpaceProvider;
import ch.systemsx.cisd.common.logging.ISimpleLogger;
import ch.systemsx.cisd.common.logging.LogLevel;
import ch.systemsx.cisd.common.utilities.ITimeProvider;
import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
import ch.systemsx.cisd.openbis.dss.generic.shared.utils.Share;
import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO;
/**
*
*
* @author Franz-Josef Elmer
*/
@Friend(toClasses=SimpleBalancer.class)
public class SimpleBalancerTest extends AbstractFileSystemTestCase
{
private static final String STORE_PATH = "01/02/03/";
private static final class MockSpaceProvider implements IFreeSpaceProvider
{
private final Map<File, List<Long>> freeSpace = new HashMap<File, List<Long>>();
void addFreeSpaceExpectationFor(Share share, long valueInKb)
{
List<Long> list = freeSpace.get(share.getShare());
if (list == null)
{
list = new ArrayList<Long>();
freeSpace.put(share.getShare(), list);
}
list.add(valueInKb);
}
@SuppressWarnings("null")
public long freeSpaceKb(HostAwareFile path) throws IOException
{
File file = path.getFile();
List<Long> list = freeSpace.get(file);
assertTrue("Unknown file " + file, list != null);
assertFalse("Unexpected invocation for file " + file, list.isEmpty());
return list.remove(0);
}
void assertIsSatiesfied()
{
Set<Entry<File, List<Long>>> entrySet = freeSpace.entrySet();
for (Entry<File, List<Long>> entry : entrySet)
{
assertEquals("Unfullfilled free space assertions for " + entry.getKey().getPath(),
0, entry.getValue().size());
}
}
}
private MockSpaceProvider spaceProvider;
private Mockery context;
private IEncapsulatedOpenBISService service;
private IDataSetMover dataSetMover;
private ISimpleLogger logger;
private SimpleBalancer balancer;
private File store;
@BeforeMethod
public void beforeMethod()
{
spaceProvider = new MockSpaceProvider();
context = new Mockery();
service = context.mock(IEncapsulatedOpenBISService.class);
dataSetMover = context.mock(IDataSetMover.class);
logger = context.mock(ISimpleLogger.class);
final ITimeProvider timeProvider = context.mock(ITimeProvider.class);
context.checking(new Expectations()
{
{
allowing(timeProvider).getTimeInMilliseconds();
will(returnValue(0L));
}
});
Properties properties = new Properties();
properties.setProperty(SimpleBalancer.MINIMUM_FREE_SPACE_KEY, "2");
balancer = new SimpleBalancer(properties, timeProvider);
store = new File(workingDirectory, "store");
}
@AfterMethod
public void afterMethod()
{
// The 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 test()
{
final Share share1 = new Share(new File(store, "1"), spaceProvider);
share1.addDataSet(dataSet("ds1", 2000));
share1.addDataSet(dataSet("ds2", ONE_MB));
share1.addDataSet(dataSet("ds3", ONE_MB + 100));
spaceProvider.addFreeSpaceExpectationFor(share1, 100l);
spaceProvider.addFreeSpaceExpectationFor(share1, 1100l);
spaceProvider.addFreeSpaceExpectationFor(share1, 2100l);
final Share share2 = new Share(new File(store, "2"), spaceProvider);
share2.addDataSet(dataSet("ds4", 2 * ONE_MB));
spaceProvider.addFreeSpaceExpectationFor(share2, 500l);
final Share share3 = new Share(new File(store, "3"), spaceProvider);
spaceProvider.addFreeSpaceExpectationFor(share3, 4 * 1024l);
spaceProvider.addFreeSpaceExpectationFor(share3, 3 * 1024l);
spaceProvider.addFreeSpaceExpectationFor(share3, 1024l);
final Share share4 = new Share(new File(store, "4"), spaceProvider);
spaceProvider.addFreeSpaceExpectationFor(share4, 3 * 1024l);
context.checking(new Expectations()
{
{
one(logger).log(LogLevel.INFO, "Moving data set ds3 from share 1 to share 3 ...");
one(dataSetMover).moveDataSetToAnotherShare(new File(share1.getShare(), STORE_PATH + "ds3"), share3.getShare());
one(logger).log(LogLevel.INFO, "Moving data set ds3 from share 1 to share 3 took 0 seconds.");
one(logger).log(LogLevel.INFO, "Moving data set ds2 from share 1 to share 3 ...");
one(dataSetMover).moveDataSetToAnotherShare(new File(share1.getShare(), STORE_PATH + "ds2"), share3.getShare());
one(logger).log(LogLevel.INFO, "Moving data set ds2 from share 1 to share 3 took 0 seconds.");
}
});
balancer.balanceStore(Arrays.asList(share1, share2, share3, share4), service, dataSetMover, logger);
assertEquals(1, share1.getDataSetsOrderedBySize().size());
assertEquals(1, share2.getDataSetsOrderedBySize().size());
assertEquals("ds3", share3.getDataSetsOrderedBySize().get(0).getDataSetCode());
assertEquals("ds2", share3.getDataSetsOrderedBySize().get(1).getDataSetCode());
assertEquals(2, share3.getDataSetsOrderedBySize().size());
assertEquals(0, share4.getDataSetsOrderedBySize().size());
spaceProvider.assertIsSatiesfied();
context.assertIsSatisfied();
}
private SimpleDataSetInformationDTO dataSet(String code, long size)
{
SimpleDataSetInformationDTO dataSet = new SimpleDataSetInformationDTO();
dataSet.setDataSetCode(code);
dataSet.setDataSetLocation(STORE_PATH + code);
dataSet.setDataSetSize(size);
return dataSet;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment