package com.eucalyptus.blockstorage.async;
import static org.junit.Assert.assertTrue;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import org.jmock.Expectations;
import org.jmock.integration.junit4.JUnitRuleMockery;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import com.eucalyptus.blockstorage.BlockDeviceResource;
import com.eucalyptus.blockstorage.BlockStorageUnitTestSupport;
import com.eucalyptus.blockstorage.LogicalStorageManager;
import com.eucalyptus.blockstorage.StorageResource;
import com.eucalyptus.blockstorage.StorageResourceWithCallback;
import com.eucalyptus.blockstorage.entities.SnapshotInfo;
import com.eucalyptus.blockstorage.entities.StorageInfo;
import com.eucalyptus.blockstorage.entities.VolumeInfo;
import com.eucalyptus.blockstorage.util.StorageProperties;
import com.eucalyptus.entities.Entities;
import com.eucalyptus.entities.TransactionResource;
import com.google.common.base.Function;
import com.google.common.base.Strings;
public class SnapshotCreatorTest {
private static Logger LOG = Logger.getLogger(SnapshotCreatorTest.class);
@Rule
public JUnitRuleMockery context = new JUnitRuleMockery();
@BeforeClass
public static void setupClass() {
try {
BlockStorageUnitTestSupport.setupBlockStoragePersistenceContext();
BlockStorageUnitTestSupport.setupAuthPersistenceContext();
BlockStorageUnitTestSupport.initializeAuth(1, 1);
} catch (Exception e) {
e.printStackTrace();
}
}
@After
public void teardown() {
BlockStorageUnitTestSupport.flushStorageInfos();
BlockStorageUnitTestSupport.flushBlockStorageEntities();
}
@AfterClass
public static void teardownClass() {
BlockStorageUnitTestSupport.tearDownBlockStoragePersistenceContext();
BlockStorageUnitTestSupport.tearDownAuthPersistenceContext();
}
/**
* <li>snapshot transfer disabled</li>
* <li>snapshot deltas enabled</li>
*
* @throws Exception
*/
@Test
public void create_snapshot_test_1() throws Exception {
StorageInfo storageInfo = new StorageInfo();
storageInfo.setDefaults();
storageInfo.setShouldTransferSnapshots(Boolean.FALSE);
storageInfo.setMaxSnapshotDeltas(10);
try (TransactionResource tran = Entities.transactionFor(StorageInfo.class)) {
Entities.persist(storageInfo);
tran.commit();
}
VolumeInfo vol = new VolumeInfo("vol-0000001");
vol.setCreateTime(new Date(System.currentTimeMillis() - TimeUnit.MILLISECONDS.convert(1, TimeUnit.HOURS)));
vol.setSize(1);
vol.setStatus(StorageProperties.Status.available.toString());
try (TransactionResource tran = Entities.transactionFor(VolumeInfo.class)) {
Entities.persist(vol);
tran.commit();
}
SnapshotInfo snap = new SnapshotInfo("snap-0000001");
snap.setIsOrigin(Boolean.TRUE);
snap.setProgress("0");
snap.setSizeGb(vol.getSize());
snap.setSnapPointId("snap-point-id-1");
snap.setStartTime(new Date(System.currentTimeMillis() - TimeUnit.MILLISECONDS.convert(20, TimeUnit.MINUTES)));
snap.setStatus(StorageProperties.Status.creating.toString());
snap.setVolumeId(vol.getVolumeId());
try (TransactionResource tran = Entities.transactionFor(SnapshotInfo.class)) {
Entities.persist(snap);
tran.commit();
}
final LogicalStorageManager storageManager = context.mock(LogicalStorageManager.class);
context.checking(new Expectations() {
{
oneOf(storageManager).createSnapshot(vol.getVolumeId(), snap.getSnapshotId(), snap.getSnapPointId());
oneOf(storageManager).finishVolume(snap.getSnapshotId());
}
});
new SnapshotCreator(vol.getVolumeId(), snap.getSnapshotId(), snap.getSnapPointId(), storageManager,
BlockStorageUnitTestSupport.createMockS3SnapshotTransfer(), BlockStorageUnitTestSupport.createMockSnapshotProgressCallback()).run();
context.assertIsSatisfied();
List<SnapshotInfo> snaps;
try (TransactionResource tran = Entities.transactionFor(SnapshotInfo.class)) {
snaps = Entities.query(new SnapshotInfo());
tran.commit();
}
assertTrue("expected to have a result set querying the snapshots table in eucalyptus_storage persistence context", snaps != null);
assertTrue("expected 1 SnapshotInfo entity to exist, but found " + snaps.size(), snaps.size() == 1);
assertTrue("expected SnapshotInfo entity for " + snap.getSnapshotId() + " but found entity for " + snaps.get(0).getSnapshotId(),
snap.getSnapshotId().equals(snaps.get(0).getSnapshotId()));
assertTrue("expected SnapshotInfo entity status to be " + StorageProperties.Status.available.toString() + " but found it to be "
+ snaps.get(0).getStatus(), StorageProperties.Status.available.toString().equals(snaps.get(0).getStatus()));
assertTrue("expected SnapshotInfo entity progress to be 100% but found it to be " + snaps.get(0).getProgress(),
"100".equals(snaps.get(0).getProgress()));
assertTrue("expected SnapshotInfo entity to contain a null reference for snapshotLocation but found " + snaps.get(0).getSnapshotLocation(),
null == snaps.get(0).getSnapshotLocation());
assertTrue("expected SnapshotInfo entity to contain null reference for previousSnapshotID but found " + snaps.get(0).getPreviousSnapshotId(),
null == snaps.get(0).getPreviousSnapshotId());
}
/**
* <li>snapshot transfer enabled</li>
* <li>snapshot deltas enabled</li>
* <li>backend deltas disabled</li>
*
* @throws Exception
*/
@Test
public void create_snapshot_test_2() throws Exception {
StorageInfo storageInfo = new StorageInfo();
storageInfo.setDefaults();
storageInfo.setMaxSnapshotDeltas(10);
try (TransactionResource tran = Entities.transactionFor(StorageInfo.class)) {
Entities.persist(storageInfo);
tran.commit();
}
VolumeInfo vol = new VolumeInfo("vol-0000002");
vol.setCreateTime(new Date(System.currentTimeMillis() - TimeUnit.MILLISECONDS.convert(1, TimeUnit.HOURS)));
vol.setSize(2);
vol.setStatus(StorageProperties.Status.available.toString());
try (TransactionResource tran = Entities.transactionFor(VolumeInfo.class)) {
Entities.persist(vol);
tran.commit();
}
SnapshotInfo snap = new SnapshotInfo("snap-0000002");
snap.setIsOrigin(Boolean.TRUE);
snap.setProgress("0");
snap.setSizeGb(vol.getSize());
snap.setSnapPointId("snap-point-id-2");
snap.setStartTime(new Date());
snap.setStatus(StorageProperties.Status.creating.toString());
snap.setVolumeId(vol.getVolumeId());
try (TransactionResource tran = Entities.transactionFor(SnapshotInfo.class)) {
Entities.persist(snap);
tran.commit();
}
final LogicalStorageManager storageManager = context.mock(LogicalStorageManager.class);
context.checking(new Expectations() {
{
oneOf(storageManager).createSnapshot(vol.getVolumeId(), snap.getSnapshotId(), snap.getSnapPointId());
oneOf(storageManager).supportsIncrementalSnapshots();
will(returnValue(false));
oneOf(storageManager).prepSnapshotForUpload(vol.getVolumeId(), snap.getSnapshotId(), snap.getSnapPointId());
will(returnValue(new BlockDeviceResource(snap.getSnapshotId(), "path-to-snap")));
oneOf(storageManager).finishVolume(snap.getSnapshotId());
}
});
new SnapshotCreator(vol.getVolumeId(), snap.getSnapshotId(), snap.getSnapPointId(), storageManager,
BlockStorageUnitTestSupport.createMockS3SnapshotTransfer(), BlockStorageUnitTestSupport.createMockSnapshotProgressCallback()).run();
context.assertIsSatisfied();
List<SnapshotInfo> snaps;
try (TransactionResource tran = Entities.transactionFor(SnapshotInfo.class)) {
snaps = Entities.query(new SnapshotInfo());
tran.commit();
}
assertTrue("expected to have a result set querying the snapshots table in eucalyptus_storage persistence context", snaps != null);
assertTrue("expected 1 SnapshotInfo to exist, but found " + snaps.size(), snaps.size() == 1);
assertTrue("expected SnapshotInfo entity for " + snap.getSnapshotId() + " but found entity for " + snaps.get(0).getSnapshotId(),
snap.getSnapshotId().equals(snaps.get(0).getSnapshotId()));
assertTrue("expected SnapshotInfo entity status to be " + StorageProperties.Status.available.toString() + " but found it to be "
+ snaps.get(0).getStatus(), StorageProperties.Status.available.toString().equals(snaps.get(0).getStatus()));
assertTrue("expected SnapshotInfo entity progress to be 100% but found it to be " + snaps.get(0).getProgress(),
"100".equals(snaps.get(0).getProgress()));
assertTrue("expected SnapshotInfo entity to contain a valid reference for snapshotLocation but found " + snaps.get(0).getSnapshotLocation(),
!Strings.isNullOrEmpty(snaps.get(0).getSnapshotLocation()));
assertTrue("expected SnapshotInfo entity to contain null reference for previousSnapshotID but found " + snaps.get(0).getPreviousSnapshotId(),
null == snaps.get(0).getPreviousSnapshotId());
}
/**
* <li>snapshot transfer enabled</li>
* <li>snapshot deltas enabled</li>
* <li>backend deltas enabled</li>
* <li>first snapshot on volume</li>
*
* @throws Exception
*/
@Test
public void create_snapshot_test_3() throws Exception {
StorageInfo storageInfo = new StorageInfo();
storageInfo.setDefaults();
storageInfo.setMaxSnapshotDeltas(10);
try (TransactionResource tran = Entities.transactionFor(StorageInfo.class)) {
Entities.persist(storageInfo);
tran.commit();
}
VolumeInfo vol = new VolumeInfo("vol-0000003");
vol.setCreateTime(new Date(System.currentTimeMillis() - TimeUnit.MILLISECONDS.convert(1, TimeUnit.HOURS)));
vol.setSize(2);
vol.setStatus(StorageProperties.Status.available.toString());
try (TransactionResource tran = Entities.transactionFor(VolumeInfo.class)) {
Entities.persist(vol);
tran.commit();
}
SnapshotInfo snap = new SnapshotInfo("snap-0000003");
snap.setIsOrigin(Boolean.TRUE);
snap.setProgress("0");
snap.setSizeGb(vol.getSize());
snap.setSnapPointId("snap-point-id-3");
snap.setStartTime(new Date());
snap.setStatus(StorageProperties.Status.creating.toString());
snap.setVolumeId(vol.getVolumeId());
try (TransactionResource tran = Entities.transactionFor(SnapshotInfo.class)) {
Entities.persist(snap);
tran.commit();
}
final LogicalStorageManager storageManager = context.mock(LogicalStorageManager.class);
context.checking(new Expectations() {
{
oneOf(storageManager).createSnapshot(vol.getVolumeId(), snap.getSnapshotId(), snap.getSnapPointId());
oneOf(storageManager).supportsIncrementalSnapshots();
will(returnValue(true));
oneOf(storageManager).prepSnapshotForUpload(vol.getVolumeId(), snap.getSnapshotId(), snap.getSnapPointId());
will(returnValue(new BlockDeviceResource(snap.getSnapshotId(), "path-to-snap")));
oneOf(storageManager).finishVolume(snap.getSnapshotId());
}
});
new SnapshotCreator(vol.getVolumeId(), snap.getSnapshotId(), snap.getSnapPointId(), storageManager,
BlockStorageUnitTestSupport.createMockS3SnapshotTransfer(), BlockStorageUnitTestSupport.createMockSnapshotProgressCallback()).run();
context.assertIsSatisfied();
List<SnapshotInfo> snaps;
try (TransactionResource tran = Entities.transactionFor(SnapshotInfo.class)) {
snaps = Entities.query(new SnapshotInfo());
tran.commit();
}
assertTrue("expected to have a result set querying the snapshots table in eucalyptus_storage persistence context", snaps != null);
assertTrue("expected 1 SnapshotInfo to exist, but found " + snaps.size(), snaps.size() == 1);
assertTrue("expected SnapshotInfo entity for " + snap.getSnapshotId() + " but found entity for " + snaps.get(0).getSnapshotId(),
snap.getSnapshotId().equals(snaps.get(0).getSnapshotId()));
assertTrue("expected SnapshotInfo entity status to be " + StorageProperties.Status.available.toString() + " but found it to be "
+ snaps.get(0).getStatus(), StorageProperties.Status.available.toString().equals(snaps.get(0).getStatus()));
assertTrue("expected SnapshotInfo entity progress to be 100% but found it to be " + snaps.get(0).getProgress(),
"100".equals(snaps.get(0).getProgress()));
assertTrue("expected SnapshotInfo entity to contain a valid reference for snapshotLocation but found " + snaps.get(0).getSnapshotLocation(),
!Strings.isNullOrEmpty(snaps.get(0).getSnapshotLocation()));
assertTrue("expected SnapshotInfo entity to contain null reference for previousSnapshotID but found " + snaps.get(0).getPreviousSnapshotId(),
null == snaps.get(0).getPreviousSnapshotId());
}
/**
* <li>snapshot transfer enabled</li>
* <li>snapshot deltas enabled</li>
* <li>backend deltas enabled</li>
* <li>non-first snapshot on volume</li>
*
* @throws Exception
*/
@Test
public void create_snapshot_test_4() throws Exception {
StorageInfo storageInfo = new StorageInfo();
storageInfo.setDefaults();
storageInfo.setMaxSnapshotDeltas(10);
try (TransactionResource tran = Entities.transactionFor(StorageInfo.class)) {
Entities.persist(storageInfo);
tran.commit();
}
VolumeInfo vol = new VolumeInfo("vol-0000004");
vol.setCreateTime(new Date(System.currentTimeMillis() - TimeUnit.MILLISECONDS.convert(1, TimeUnit.HOURS)));
vol.setSize(2);
vol.setStatus(StorageProperties.Status.available.toString());
try (TransactionResource tran = Entities.transactionFor(VolumeInfo.class)) {
Entities.persist(vol);
tran.commit();
}
SnapshotInfo snapa = new SnapshotInfo("snap-000004a");
snapa.setIsOrigin(Boolean.TRUE);
snapa.setProgress("100");
snapa.setSizeGb(vol.getSize());
snapa.setSnapPointId("snap-point-id-4a");
snapa.setStartTime(new Date(System.currentTimeMillis() - TimeUnit.MILLISECONDS.convert(10, TimeUnit.MINUTES)));
snapa.setStatus(StorageProperties.Status.available.toString());
snapa.setVolumeId(vol.getVolumeId());
snapa.setSnapshotLocation("snapshots://objectstoragegateway/bucket-for-upload/snap-000004a");
SnapshotInfo snapb = new SnapshotInfo("snap-000004b");
snapb.setIsOrigin(Boolean.TRUE);
snapb.setProgress("0");
snapb.setSizeGb(vol.getSize());
snapb.setSnapPointId("snap-point-id-4b");
snapb.setStartTime(new Date());
snapb.setStatus(StorageProperties.Status.creating.toString());
snapb.setVolumeId(vol.getVolumeId());
try (TransactionResource tran = Entities.transactionFor(SnapshotInfo.class)) {
Entities.persist(snapa);
Entities.persist(snapb);
tran.commit();
}
final Function<StorageResource, String> callback = new Function<StorageResource, String>() {
@Override
public String apply(StorageResource arg0) {
return "blah";
}
};
final BlockDeviceResource bdr = new BlockDeviceResource(snapb.getSnapshotId(), "path-to-snap");
final LogicalStorageManager storageManager = context.mock(LogicalStorageManager.class);
context.checking(new Expectations() {
{
oneOf(storageManager).createSnapshot(vol.getVolumeId(), snapb.getSnapshotId(), snapb.getSnapPointId());
oneOf(storageManager).supportsIncrementalSnapshots();
will(returnValue(true));
oneOf(storageManager).prepIncrementalSnapshotForUpload(vol.getVolumeId(), snapb.getSnapshotId(), snapb.getSnapPointId(),
snapa.getSnapshotId(), snapa.getSnapPointId());
will(returnValue(new StorageResourceWithCallback(bdr, callback)));
oneOf(storageManager).executeCallback(callback, bdr);
will(returnValue("crap"));
oneOf(storageManager).finishVolume(snapb.getSnapshotId());
}
});
new SnapshotCreator(vol.getVolumeId(), snapb.getSnapshotId(), snapb.getSnapPointId(), storageManager,
BlockStorageUnitTestSupport.createMockS3SnapshotTransfer(), BlockStorageUnitTestSupport.createMockSnapshotProgressCallback()).run();
context.assertIsSatisfied();
List<SnapshotInfo> snaps;
try (TransactionResource tran = Entities.transactionFor(SnapshotInfo.class)) {
snaps = Entities.query(new SnapshotInfo());
tran.commit();
}
assertTrue("expected to have a result set querying the snapshots table in eucalyptus_storage persistence context", snaps != null);
assertTrue("expected 2 SnapshotInfo entities to exist, but found " + snaps.size(), snaps.size() == 2);
for (SnapshotInfo snap : snaps) {
assertTrue("expected SnapshotInfo entity for " + snapa.getSnapshotId() + " or " + snapb.getSnapshotId() + " but found entity for "
+ snap.getSnapshotId(), (snapa.getSnapshotId().equals(snap.getSnapshotId()) || snapb.getSnapshotId().equals(snap.getSnapshotId())));
assertTrue(
"expected SnapshotInfo entity status to be " + StorageProperties.Status.available.toString() + " but found it to be " + snap.getStatus(),
StorageProperties.Status.available.toString().equals(snap.getStatus()));
assertTrue("expected SnapshotInfo entity progress to be 100% but found it to be " + snap.getProgress(), "100".equals(snap.getProgress()));
assertTrue("expected SnapshotInfo entity to contain a valid reference for snapshotLocation but found " + snap.getSnapshotLocation(),
!Strings.isNullOrEmpty(snap.getSnapshotLocation()));
if (snapa.getSnapshotId().equals(snap.getSnapshotId())) {
assertTrue("expected SnapshotInfo entity to contain null reference for previousSnapshotID but found " + snap.getPreviousSnapshotId(),
null == snap.getPreviousSnapshotId());
} else {
assertTrue("expected previousSnapshotID of SnapshotInfo entity to be " + snapa.getSnapshotId() + " but found " + snap.getPreviousSnapshotId(),
snapa.getSnapshotId().equals(snap.getPreviousSnapshotId()));
}
}
}
}