/*************************************************************************
* Copyright 2009-2014 Eucalyptus Systems, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*
* Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta
* CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need
* additional information or have any questions.
*
* This file may incorporate work covered under the following copyright
* and permission notice:
*
* Software License Agreement (BSD License)
*
* Copyright (c) 2008, Regents of the University of California
* All rights reserved.
*
* Redistribution and use of this software in source and binary forms,
* with or without modification, are permitted provided that the
* following conditions are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. USERS OF THIS SOFTWARE ACKNOWLEDGE
* THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE LICENSED MATERIAL,
* COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS SOFTWARE,
* AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
* IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA,
* SANTA BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY,
* WHICH IN THE REGENTS' DISCRETION MAY INCLUDE, WITHOUT LIMITATION,
* REPLACEMENT OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO
* IDENTIFIED, OR WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT
* NEEDED TO COMPLY WITH ANY SUCH LICENSES OR RIGHTS.
************************************************************************/
package com.eucalyptus.blockstorage.san.common;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
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.BlockStorageUnitTestSupport;
import com.eucalyptus.blockstorage.StorageResource;
import com.eucalyptus.blockstorage.san.common.entities.SANInfo;
import com.eucalyptus.blockstorage.san.common.entities.SANVolumeInfo;
import com.eucalyptus.blockstorage.util.StorageProperties;
import com.eucalyptus.entities.Entities;
import com.eucalyptus.entities.TransactionResource;
import com.eucalyptus.util.EucalyptusCloudException;
/**
* Created by wesw on 8/7/14.
*/
public class SANManagerTest {
@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.flushBlockStorageEntities();
}
@AfterClass
public static void teardownClass() {
BlockStorageUnitTestSupport.tearDownBlockStoragePersistenceContext();
BlockStorageUnitTestSupport.tearDownAuthPersistenceContext();
}
@Test
public void cleanSnapshot_BasicTest() throws Exception {
final String snapId = "foo";
final String sanVolId = "bar";
final String iqn = "foo-iqn";
final String snapshotPointId = "snap-point-foo";
SANVolumeInfo volInfo = new SANVolumeInfo(snapId);
volInfo.setSanVolumeId(sanVolId);
volInfo.setIqn(iqn);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
Entities.persist(volInfo);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).deleteSnapshot(sanVolId, iqn, snapshotPointId);
will(returnValue(Boolean.TRUE));
}
});
SANManager test = new SANManager(sanProvider);
test.cleanSnapshot(snapId, snapshotPointId);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
List<SANVolumeInfo> results = Entities.query(new SANVolumeInfo());
assertTrue("expected no SANVolumeInfos to exist", results == null || results.size() == 0);
}
}
@Test
public void cleanSnapshot_NoVolTest() throws Exception {
final String snapId = "foo";
final String snapshotPointId = "snap-point-foo";
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations());
SANManager test = new SANManager(sanProvider);
test.cleanSnapshot(snapId, snapshotPointId);
assertTrue("expected to reach this statement without an exception", true);
}
@Test
public void cleanVolume_BasicTest() throws Exception {
final String volId = "foo";
final String sanVolId = "bar";
final String iqn = "iqn";
SANVolumeInfo volInfo = new SANVolumeInfo(volId);
volInfo.setSanVolumeId(sanVolId);
volInfo.setIqn(iqn);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
Entities.persist(volInfo);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).deleteVolume(sanVolId, iqn);
will(returnValue(Boolean.TRUE));
}
});
SANManager test = new SANManager(sanProvider);
test.cleanVolume(volId);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
List<SANVolumeInfo> results = Entities.query(new SANVolumeInfo());
assertTrue("expected no SANVolumeInfos to exist", results == null || results.size() == 0);
}
}
@Test
public void cleanVolume_NoVolTest() throws Exception {
final String snapId = "foo";
final String snapshotPointId = "snap-point-foo";
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations());
SANManager test = new SANManager(sanProvider);
test.cleanSnapshot(snapId, snapshotPointId);
assertTrue("expected to reach this statement without an exception", true);
}
@Test
public void createVolume_BasicTest() throws Exception {
SANInfo sanInfo = new SANInfo(StorageProperties.NAME, "foohost", "foouser", "foopassword");
sanInfo.setResourcePrefix("fooprefix");
sanInfo.setResourceSuffix("foosuffix");
try (TransactionResource tran = Entities.transactionFor(SANInfo.class)) {
Entities.persist(sanInfo);
tran.commit();
}
final String volId = "foo";
final int volSz = 5;
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
// oneOf(sanProvider).volumeExists(volId); will(returnValue(Boolean.FALSE));
oneOf(sanProvider).createVolume("fooprefix" + volId + "foosuffix", volSz);
will(returnValue("foo-iqn"));
}
});
SANManager test = new SANManager(sanProvider);
test.createVolume(volId, volSz);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
List<SANVolumeInfo> results = Entities.query(new SANVolumeInfo());
assertTrue("expected one SANVolumeInfo to exist", results != null && results.size() == 1);
SANVolumeInfo created = results.get(0);
assertTrue("expected volume id to be " + volId + ", but was " + created.getVolumeId(), volId.equals(created.getVolumeId()));
assertTrue(
"expected SAN volume id to " + sanInfo.getResourcePrefix() + volId + sanInfo.getResourceSuffix() + ", but was " + created.getSanVolumeId(),
created.getSanVolumeId().equals(sanInfo.getResourcePrefix() + volId + sanInfo.getResourceSuffix()));
assertTrue("expected iqn to be foo-iqn, but was " + created.getIqn(), "foo-iqn".equals(created.getIqn()));
}
}
@Test
public void createVolume_DbRecExistsTest() throws Exception {
SANInfo sanInfo = new SANInfo(StorageProperties.NAME, "foohost", "foouser", "foopassword");
sanInfo.setResourcePrefix("fooprefix");
sanInfo.setResourceSuffix("foosuffix");
final String volId = "foo";
final String iqn = "iqn";
final SANVolumeInfo existing = new SANVolumeInfo(volId).withSanVolumeId("fooprefix" + volId + "foosuffix");
existing.setIqn(iqn);
try (TransactionResource tran = Entities.transactionFor(SANInfo.class)) {
Entities.persist(sanInfo);
Entities.persist(existing);
tran.commit();
}
final int volSz = 5;
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).volumeExists(existing.getSanVolumeId(), iqn);
will(returnValue(Boolean.FALSE));
oneOf(sanProvider).createVolume("fooprefix" + volId + "foosuffix", volSz);
will(returnValue("foo-iqn"));
}
});
SANManager test = new SANManager(sanProvider);
test.createVolume(volId, volSz);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
List<SANVolumeInfo> results = Entities.query(new SANVolumeInfo());
assertTrue("expected one SANVolumeInfo to exist", results != null && results.size() == 1);
SANVolumeInfo created = results.get(0);
assertTrue("expected volume id to be " + volId + ", but was " + created.getVolumeId(), volId.equals(created.getVolumeId()));
assertTrue(
"expected SAN volume id to " + sanInfo.getResourcePrefix() + volId + sanInfo.getResourceSuffix() + ", but was " + created.getSanVolumeId(),
created.getSanVolumeId().equals(sanInfo.getResourcePrefix() + volId + sanInfo.getResourceSuffix()));
assertTrue("expected iqn to be foo-iqn, but was " + created.getIqn(), "foo-iqn".equals(created.getIqn()));
}
}
@Test
public void deleteSnapshot_BasicTest() throws Exception {
final String volId = "foo";
final String iqn = "foo-iqn";
final String snapshotPointId = "snap-point-foo";
final SANVolumeInfo existing = new SANVolumeInfo(volId).withSanVolumeId("fooprefix" + volId + "foosuffix");
existing.setIqn(iqn);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
Entities.persist(existing);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).deleteSnapshot(existing.getSanVolumeId(), iqn, snapshotPointId);
will(returnValue(Boolean.TRUE));
}
});
SANManager test = new SANManager(sanProvider);
test.deleteSnapshot(volId, snapshotPointId);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
List<SANVolumeInfo> results = Entities.query(new SANVolumeInfo());
assertTrue("expected no SANVolumeInfos to exist", results == null || results.size() == 0);
}
}
@Test
public void deleteSnapshot_NoSANSnapshot() throws Exception {
final String volId = "foo";
final String iqn = "foo-iqn";
final String snapshotPointId = "snap-point-foo";
final SANVolumeInfo existing = new SANVolumeInfo(volId).withSanVolumeId("fooprefix" + volId + "foosuffix");
existing.setIqn(iqn);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
Entities.persist(existing);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).deleteSnapshot(existing.getSanVolumeId(), iqn, snapshotPointId);
will(returnValue(Boolean.FALSE));
oneOf(sanProvider).snapshotExists(existing.getSanVolumeId(), iqn);
will(returnValue(Boolean.FALSE));
}
});
SANManager test = new SANManager(sanProvider);
test.deleteSnapshot(volId, snapshotPointId);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
List<SANVolumeInfo> results = Entities.query(new SANVolumeInfo());
assertTrue("expected no SANVolumeInfos to exist", results == null || results.size() == 0);
}
}
@Test
public void getSnapshotSize_BasicTest() throws Exception {
final String snapId = "foo";
final String sanVolId = "bar";
Integer size = new Integer(5);
SANVolumeInfo volInfo = new SANVolumeInfo(snapId).withSanVolumeId(sanVolId).withSize(size);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
Entities.persist(volInfo);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
SANManager test = new SANManager(sanProvider);
int sizeReturned = test.getSnapshotSize(snapId);
assertTrue("expected the size returned, " + sizeReturned + ", to match the size specified, " + size.intValue(), size.intValue() == sizeReturned);
}
@Test(expected = EucalyptusCloudException.class)
public void getSnapshotSize_NoSnapshotTest() throws Exception {
final SANProvider sanProvider = context.mock(SANProvider.class);
SANManager test = new SANManager(sanProvider);
test.getSnapshotSize("foo");
}
@Test
public void deleteVolume_BasicTest() throws Exception {
final String volId = "foo";
final SANVolumeInfo existing = new SANVolumeInfo(volId).withSanVolumeId("fooprefix" + volId + "foosuffix");
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
Entities.persist(existing);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).deleteVolume(existing.getSanVolumeId(), null);
will(returnValue(Boolean.TRUE));
}
});
SANManager test = new SANManager(sanProvider);
test.deleteVolume(volId);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
List<SANVolumeInfo> results = Entities.query(new SANVolumeInfo());
assertTrue("expected no SANVolumeInfos to exist", results == null || results.size() == 0);
}
}
@Test
public void finishVolume_BasicTest() throws Exception {
final String volId = "foo";
final String sanVolId = "fooprefix" + volId + "foosuffix";
final String volIqn = "foo-iqn";
final String lun = "1";
final SANVolumeInfo existing = new SANVolumeInfo(volId);
existing.setSanVolumeId(sanVolId);
existing.setIqn(volIqn + ',' + lun);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
Entities.persist(existing);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).disconnectTarget(sanVolId, volIqn, lun);
oneOf(sanProvider).unexportResource(sanVolId, "sc-foo-iqn");
oneOf(sanProvider).waitAndComplete(sanVolId, existing.getIqn());
}
});
SANManager test = new SANManager(sanProvider);
test.finishVolume(volId);
}
@Test
public void finishVolume_NoVolumeTest() throws Exception {
final SANProvider sanProvider = context.mock(SANProvider.class);
SANManager test = new SANManager(sanProvider);
test.finishVolume("foo");
}
@Test
public void getVolumePath_BasicTest() throws Exception {
final String volId = "foo";
final String sanVolId = "fooprefix" + volId + "foosuffix";
final String volIqn = "foo-iqn";
final SANVolumeInfo existing = new SANVolumeInfo(volId);
existing.setSanVolumeId(sanVolId);
existing.setIqn(volIqn);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
Entities.persist(existing);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).connectTarget(volIqn, null);
will(returnValue(new StorageResource(volId, "foopath", StorageResource.Type.FILE) {
@Override
public Long getSize() throws Exception {
return null;
}
@Override
public InputStream getInputStream() throws Exception {
return null;
}
@Override
public OutputStream getOutputStream() throws Exception {
return null;
}
@Override
public Boolean isDownloadSynchronous() {
return Boolean.TRUE;
}
}));
}
});
SANManager test = new SANManager(sanProvider);
String path = test.getVolumePath(volId);
assertTrue("expected the returned value to be 'foopath', but it was '" + path + "'", "foopath".equals(path));
}
@Test(expected = EucalyptusCloudException.class)
public void getVolumePath_NoVolumeTest() throws Exception {
final SANProvider sanProvider = context.mock(SANProvider.class);
SANManager test = new SANManager(sanProvider);
test.getVolumePath("foo");
}
// @Test
public void importVolume_BasicTest() throws Exception {
final String volPath = File.createTempFile("blockstoragetest-", ".tmp").getCanonicalPath();
final String devName = File.createTempFile("blockstoragetest-", ".tmp").getCanonicalPath();
final String volId = "foo";
final String sanVolId = "fooprefix" + volId + "foosuffix";
final String volIqn = "foo-iqn";
final Integer volSz = new Integer(5);
SANInfo sanInfo = new SANInfo(StorageProperties.NAME, "foohost", "foouser", "foopassword");
sanInfo.setResourcePrefix("fooprefix");
sanInfo.setResourceSuffix("foosuffix");
try (TransactionResource tran = Entities.transactionFor(SANInfo.class)) {
Entities.persist(sanInfo);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).createVolume(sanVolId, volSz);
will(returnValue(volIqn));
oneOf(sanProvider).connectTarget(volIqn, null);
will(returnValue(new StorageResource(volId, devName, StorageResource.Type.FILE) {
@Override
public Long getSize() throws Exception {
return null;
}
@Override
public InputStream getInputStream() throws Exception {
return null;
}
@Override
public OutputStream getOutputStream() throws Exception {
return null;
}
@Override
public Boolean isDownloadSynchronous() {
return Boolean.TRUE;
}
}));
oneOf(sanProvider).disconnectTarget(sanVolId, volIqn, null);
}
});
SANManager test = new SANManager(sanProvider);
test.importVolume(volId, volPath, volSz);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
List<SANVolumeInfo> results = Entities.query(new SANVolumeInfo());
assertTrue("expected one SANVolumeInfo to exist", results != null && results.size() == 1);
SANVolumeInfo created = results.get(0);
assertTrue("expected volume id to be " + volId + ", but was " + created.getVolumeId(), volId.equals(created.getVolumeId()));
assertTrue(
"expected SAN volume id to " + sanInfo.getResourcePrefix() + volId + sanInfo.getResourceSuffix() + ", but was " + created.getSanVolumeId(),
created.getSanVolumeId().equals(sanInfo.getResourcePrefix() + volId + sanInfo.getResourceSuffix()));
assertTrue("expected iqn to be foo-iqn, but was " + created.getIqn(), "foo-iqn".equals(created.getIqn()));
}
new File(volPath).delete();
new File(devName).delete();
}
// @Test(expected = EucalyptusCloudException.class)
public void importVolume_VolumeExistsTest() throws Exception {
final String volId = "foo";
final String sanVolId = "fooprefix" + volId + "foosuffix";
final String volIqn = "foo-iqn";
final SANVolumeInfo existing = new SANVolumeInfo(volId);
existing.setSanVolumeId(sanVolId);
existing.setIqn(volIqn);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
Entities.persist(existing);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
SANManager test = new SANManager(sanProvider);
test.importVolume(volId, "foo", new Integer(5));
}
// @Test
public void importSnapshot_BasicTest() throws Exception {
final String snapPath = File.createTempFile("blockstoragetest-", ".tmp").getCanonicalPath();
final String devName = File.createTempFile("blockstoragetest-", ".tmp").getCanonicalPath();
final String snapId = "foo";
final String sanVolId = "fooprefix" + snapId + "foosuffix";
final String fromVolId = "fromfoo";
final String volIqn = "foo-iqn";
final Integer volSz = new Integer(5);
SANInfo sanInfo = new SANInfo(StorageProperties.NAME, "foohost", "foouser", "foopassword");
sanInfo.setResourcePrefix("fooprefix");
sanInfo.setResourceSuffix("foosuffix");
try (TransactionResource tran = Entities.transactionFor(SANInfo.class)) {
Entities.persist(sanInfo);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).createVolume(sanVolId, volSz);
will(returnValue(volIqn));
oneOf(sanProvider).connectTarget(volIqn, null);
will(returnValue(new StorageResource(snapId, devName, StorageResource.Type.FILE) {
@Override
public Long getSize() throws Exception {
return null;
}
@Override
public InputStream getInputStream() throws Exception {
return null;
}
@Override
public OutputStream getOutputStream() throws Exception {
return null;
}
@Override
public Boolean isDownloadSynchronous() {
return Boolean.TRUE;
}
}));
oneOf(sanProvider).disconnectTarget(sanVolId, volIqn, null);
}
});
SANManager test = new SANManager(sanProvider);
test.importSnapshot(snapId, fromVolId, snapPath, volSz);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
List<SANVolumeInfo> results = Entities.query(new SANVolumeInfo());
assertTrue("expected one SANVolumeInfo to exist", results != null && results.size() == 1);
SANVolumeInfo created = results.get(0);
assertTrue("expected volume id to be " + snapId + ", but was " + created.getVolumeId(), snapId.equals(created.getVolumeId()));
assertTrue(
"expected SAN volume id to " + sanInfo.getResourcePrefix() + snapId + sanInfo.getResourceSuffix() + ", but was " + created.getSanVolumeId(),
created.getSanVolumeId().equals(sanInfo.getResourcePrefix() + snapId + sanInfo.getResourceSuffix()));
assertTrue("expected iqn to be foo-iqn, but was " + created.getIqn(), "foo-iqn".equals(created.getIqn()));
}
new File(snapPath).delete();
new File(devName).delete();
}
// @Test(expected = EucalyptusCloudException.class)
public void importSnapshot_VolumeExistsTest() throws Exception {
final String snapId = "foo";
final String sanVolId = "fooprefix" + snapId + "foosuffix";
final String volIqn = "foo-iqn";
final String fromVolId = "fromfoo";
final SANVolumeInfo existing = new SANVolumeInfo(snapId);
existing.setSanVolumeId(sanVolId);
existing.setIqn(volIqn);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
Entities.persist(existing);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
SANManager test = new SANManager(sanProvider);
test.importSnapshot(snapId, fromVolId, "foo", new Integer(5));
}
@Test
public void exportVolume_BasicTest() throws Exception {
final String volId = "foo";
final String sanVolId = "fooprefix" + volId + "foosuffix";
final String nodeIqn = "node-iqn";
final String volIqn = "foo-iqn";
final SANVolumeInfo existing = new SANVolumeInfo(volId);
existing.setSanVolumeId(sanVolId);
existing.setIqn(volIqn);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
Entities.persist(existing);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).getProtocol();
will(returnValue("fooprotocol"));
oneOf(sanProvider).getProviderName();
will(returnValue("fooprovider"));
oneOf(sanProvider).exportResource(sanVolId, nodeIqn, volIqn);
will(returnValue(new String("1")));
oneOf(sanProvider).getVolumeConnectionString(volId);
will(returnValue("fooconnectionstring"));
oneOf(sanProvider).getAuthType();
will(returnValue("fooauthtype"));
oneOf(sanProvider).getOptionalChapUser();
will(returnValue("foooptchapuser"));
}
});
String expected = "fooprotocol,fooprovider,foooptchapuser,fooauthtype,1,fooconnectionstring";
SANManager test = new SANManager(sanProvider);
String result = test.exportVolume(volId, nodeIqn);
assertTrue("expected result to be '" + expected + "' but was '" + result + "'", expected.equals(result));
}
@Test(expected = EucalyptusCloudException.class)
public void exportVolume_VolumeDoesNotExistTest() throws Exception {
final SANProvider sanProvider = context.mock(SANProvider.class);
SANManager test = new SANManager(sanProvider);
test.exportVolume("foo", "foo-iqn");
}
@Test
public void unexportVolumeFromAll_BasicTest() throws Exception {
final String volId = "foo";
final String sanVolId = "fooprefix" + volId + "foosuffix";
final String volIqn = "foo-iqn";
final SANVolumeInfo existing = new SANVolumeInfo(volId);
existing.setSanVolumeId(sanVolId);
existing.setIqn(volIqn);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
Entities.persist(existing);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).unexportResourceFromAll(sanVolId);
}
});
SANManager test = new SANManager(sanProvider);
test.unexportVolumeFromAll(volId);
}
@Test(expected = EucalyptusCloudException.class)
public void unexportVolumeFromAll_VolumeDoesNotExistTest() throws Exception {
final SANProvider sanProvider = context.mock(SANProvider.class);
SANManager test = new SANManager(sanProvider);
test.unexportVolumeFromAll("foo");
}
@Test
public void unexportVolume_BasicTest() throws Exception {
final String volId = "foo";
final String sanVolId = "fooprefix" + volId + "foosuffix";
final String volIqn = "foo-iqn";
final SANVolumeInfo existing = new SANVolumeInfo(volId);
existing.setSanVolumeId(sanVolId);
existing.setIqn(volIqn);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
Entities.persist(existing);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).unexportResource(sanVolId, volIqn);
}
});
SANManager test = new SANManager(sanProvider);
test.unexportVolume(volId, volIqn);
}
@Test(expected = EucalyptusCloudException.class)
public void unexportVolume_VolumeDoesNotExistTest() throws Exception {
final SANProvider sanProvider = context.mock(SANProvider.class);
SANManager test = new SANManager(sanProvider);
test.unexportVolume("foo", "foo-iqn");
}
@Test
public void getFromBackend_BasicTest() throws Exception {
final String volId = "foo";
final SANVolumeInfo existing = new SANVolumeInfo(volId).withSanVolumeId("fooprefix" + volId + "foosuffix");
try (TransactionResource tran = Entities.transactionFor(SANInfo.class)) {
Entities.persist(existing);
tran.commit();
}
final int volSz = 5;
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).snapshotExists(existing.getSanVolumeId(), null);
will(returnValue(Boolean.TRUE));
}
});
SANManager test = new SANManager(sanProvider);
boolean result = test.getFromBackend(volId, volSz);
assertTrue("expected result to be true", result);
}
@Test
public void getFromBackend_SnapExistsOnOtherPartitionTest() throws Exception {
final String volId = "foo";
final SANVolumeInfo existing = new SANVolumeInfo(volId).withSanVolumeId("fooprefix" + volId + "foosuffix");
existing.setScName("other");
existing.setIqn("foo-iqn");
existing.setSize(new Integer(5));
existing.setSnapshotOf("foo-vol");
try (TransactionResource tran = Entities.transactionFor(SANInfo.class)) {
Entities.persist(existing);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).snapshotExists(existing.getSanVolumeId(), existing.getIqn());
will(returnValue(Boolean.TRUE));
}
});
SANManager test = new SANManager(sanProvider);
boolean result = test.getFromBackend(volId, new Integer(5));
assertTrue("expected result to be true", result);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
List<SANVolumeInfo> results = Entities.query(new SANVolumeInfo());
assertTrue("expected one SANVolumeInfo to exist", results != null && results.size() == 1);
}
}
@Test
public void getFromBackend_NoSnapTest() throws Exception {
final String volId = "foo";
final int volSz = 5;
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
}
});
SANManager test = new SANManager(sanProvider);
boolean result = test.getFromBackend(volId, volSz);
assertTrue("expected result to be false", !result);
}
@Test
public void createSnapshotPoint_BasicTest() throws Exception {
final String volId = "testparentvol";
final String rezPrefix = "fooprefix";
final String rezSuffix = "foosuffix";
final String iqn = "foo-iqn";
final SANVolumeInfo existing = new SANVolumeInfo(volId).withSanVolumeId(rezPrefix + volId + rezSuffix);
existing.setIqn(iqn);
existing.setSize(new Integer(5));
existing.setSnapshotOf("foo-vol");
SANInfo sanInfo = new SANInfo(StorageProperties.NAME, "foohost", "foouser", "foopassword");
sanInfo.setResourcePrefix(rezPrefix);
sanInfo.setResourceSuffix(rezSuffix);
try (TransactionResource tran = Entities.transactionFor(SANInfo.class)) {
Entities.persist(existing);
Entities.persist(sanInfo);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).createSnapshotPoint(existing.getSanVolumeId(), rezPrefix + "foo" + rezSuffix, iqn);
will(returnValue("result"));
}
});
SANManager test = new SANManager(sanProvider);
String result = test.createSnapshotPoint(volId, "foo");
assertTrue("expected result to be 'result', but was '" + result + "'", "result".equals(result));
}
@Test(expected = EucalyptusCloudException.class)
public void createSnapshotPoint_VolumeDoesNotExistTest() throws Exception {
final String rezPrefix = "fooprefix";
final String rezSuffix = "foosuffix";
SANInfo sanInfo = new SANInfo(StorageProperties.NAME, "foohost", "foouser", "foopassword");
sanInfo.setResourcePrefix(rezPrefix);
sanInfo.setResourceSuffix(rezSuffix);
try (TransactionResource tran = Entities.transactionFor(SANInfo.class)) {
Entities.persist(sanInfo);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
SANManager test = new SANManager(sanProvider);
test.createSnapshotPoint("fooparent", "foo");
}
@Test
public void cloneVolume_BasicTest() throws Exception {
final String volId = "testparentvol";
final String rezPrefix = "fooprefix";
final String rezSuffix = "foosuffix";
final SANVolumeInfo existing = new SANVolumeInfo(volId).withSanVolumeId(rezPrefix + volId + rezSuffix);
existing.setIqn("foo-parent-iqn");
existing.setSize(new Integer(5));
existing.setSnapshotOf("foo-vol");
SANInfo sanInfo = new SANInfo(StorageProperties.NAME, "foohost", "foouser", "foopassword");
sanInfo.setResourcePrefix(rezPrefix);
sanInfo.setResourceSuffix(rezSuffix);
try (TransactionResource tran = Entities.transactionFor(SANInfo.class)) {
Entities.persist(existing);
Entities.persist(sanInfo);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
// oneOf(sanProvider).snapshotExists(existing.getSanVolumeId()); will(returnValue(Boolean.FALSE));
oneOf(sanProvider).cloneVolume(rezPrefix + "foo" + rezSuffix, existing.getSanVolumeId(), existing.getIqn());
will(returnValue("foo-iqn"));
}
});
SANManager test = new SANManager(sanProvider);
test.cloneVolume("foo", existing.getVolumeId());
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
List<SANVolumeInfo> results = Entities.query(new SANVolumeInfo());
assertTrue("expected two SANVolumeInfo to exist", results != null && results.size() == 2);
}
}
@Test
public void cloneVolume_CloneDbRecExistsTest() throws Exception {
final String volId = "testparentvol";
final String rezPrefix = "fooprefix";
final String rezSuffix = "foosuffix";
final SANVolumeInfo existing = new SANVolumeInfo(volId).withSanVolumeId(rezPrefix + volId + rezSuffix);
existing.setIqn("foo-parent-iqn");
existing.setSize(new Integer(5));
existing.setSnapshotOf("foo-vol");
final SANVolumeInfo existingClone = new SANVolumeInfo("testvol").withSanVolumeId(rezPrefix + "testvol" + rezSuffix);
existingClone.setIqn("foo-iqn");
existingClone.setSize(new Integer(5));
SANInfo sanInfo = new SANInfo(StorageProperties.NAME, "foohost", "foouser", "foopassword");
sanInfo.setResourcePrefix(rezPrefix);
sanInfo.setResourceSuffix(rezSuffix);
try (TransactionResource tran = Entities.transactionFor(SANInfo.class)) {
Entities.persist(existing);
Entities.persist(existingClone);
Entities.persist(sanInfo);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).snapshotExists(existingClone.getSanVolumeId(), existingClone.getIqn());
will(returnValue(Boolean.FALSE));
oneOf(sanProvider).cloneVolume(rezPrefix + "testvol" + rezSuffix, existing.getSanVolumeId(), existing.getIqn());
will(returnValue("foo-iqn"));
}
});
SANManager test = new SANManager(sanProvider);
test.cloneVolume("testvol", existing.getVolumeId());
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
List<SANVolumeInfo> results = Entities.query(new SANVolumeInfo());
assertTrue("expected two SANVolumeInfo to exist", results != null && results.size() == 2);
}
}
@Test
public void createSnapshot_BasicTest() throws Exception {
final String volId = "testparentvol";
final String rezPrefix = "fooprefix";
final String rezSuffix = "foosuffix";
final String parentIqn = "foo-parent-iqn";
final SANVolumeInfo existing = new SANVolumeInfo(volId).withSanVolumeId(rezPrefix + volId + rezSuffix);
existing.setIqn(parentIqn);
existing.setSize(new Integer(5));
existing.setSnapshotOf("foo-vol");
SANInfo sanInfo = new SANInfo(StorageProperties.NAME, "foohost", "foouser", "foopassword");
sanInfo.setResourcePrefix(rezPrefix);
sanInfo.setResourceSuffix(rezSuffix);
try (TransactionResource tran = Entities.transactionFor(SANInfo.class)) {
Entities.persist(existing);
Entities.persist(sanInfo);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
// oneOf(sanProvider).snapshotExists(existing.getSanVolumeId()); will(returnValue(Boolean.FALSE));
oneOf(sanProvider).createSnapshot(existing.getSanVolumeId(), rezPrefix + "foo" + rezSuffix, "bar");
will(returnValue("foo-iqn"));
}
});
SANManager test = new SANManager(sanProvider);
StorageResource result = test.createSnapshot(volId, "foo", "bar", false);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
List<SANVolumeInfo> results = Entities.query(new SANVolumeInfo());
assertTrue("expected two SANVolumeInfo to exist", results != null && results.size() == 2);
}
}
@Test
public void createSnapshot_CloneDbRecExistsTest() throws Exception {
final String volId = "testparentvol";
final String rezPrefix = "fooprefix";
final String rezSuffix = "foosuffix";
final SANVolumeInfo existing = new SANVolumeInfo(volId).withSanVolumeId(rezPrefix + volId + rezSuffix);
existing.setIqn("foo-parent-iqn");
existing.setSize(new Integer(5));
existing.setSnapshotOf("foo-vol");
final SANVolumeInfo existingClone = new SANVolumeInfo("testvol").withSanVolumeId(rezPrefix + "testvol" + rezSuffix);
existingClone.setIqn("foo-iqn");
existingClone.setSize(new Integer(5));
SANInfo sanInfo = new SANInfo(StorageProperties.NAME, "foohost", "foouser", "foopassword");
sanInfo.setResourcePrefix(rezPrefix);
sanInfo.setResourceSuffix(rezSuffix);
try (TransactionResource tran = Entities.transactionFor(SANInfo.class)) {
Entities.persist(existing);
Entities.persist(existingClone);
Entities.persist(sanInfo);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).snapshotExists(existingClone.getSanVolumeId(), existingClone.getIqn());
will(returnValue(Boolean.FALSE));
oneOf(sanProvider).createSnapshot(existing.getSanVolumeId(), rezPrefix + "testvol" + rezSuffix, "bar");
will(returnValue("foo-iqn"));
}
});
SANManager test = new SANManager(sanProvider);
StorageResource result = test.createSnapshot(volId, "testvol", "bar", false);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
List<SANVolumeInfo> results = Entities.query(new SANVolumeInfo());
assertTrue("expected two SANVolumeInfo to exist", results != null && results.size() == 2);
}
}
@Test
public void createVolume_FromSnap_BasicTest() throws Exception {
final String volId = "testparentvol";
final String rezPrefix = "fooprefix";
final String rezSuffix = "foosuffix";
final Integer snapSz = new Integer(5);
final SANVolumeInfo existing = new SANVolumeInfo(volId).withSanVolumeId(rezPrefix + volId + rezSuffix);
existing.setIqn("foo-parent-iqn");
existing.setSize(snapSz);
existing.setSnapshotOf("foo-vol");
SANInfo sanInfo = new SANInfo(StorageProperties.NAME, "foohost", "foouser", "foopassword");
sanInfo.setResourcePrefix(rezPrefix);
sanInfo.setResourceSuffix(rezSuffix);
try (TransactionResource tran = Entities.transactionFor(SANInfo.class)) {
Entities.persist(existing);
Entities.persist(sanInfo);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
// oneOf(sanProvider).snapshotExists(existing.getSanVolumeId()); will(returnValue(Boolean.FALSE));
oneOf(sanProvider).createVolume(rezPrefix + "foo" + rezSuffix, existing.getSanVolumeId(), snapSz.intValue(), snapSz.intValue(),
existing.getIqn());
will(returnValue("foo-iqn"));
}
});
SANManager test = new SANManager(sanProvider);
test.createVolume("foo", volId, snapSz.intValue());
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
List<SANVolumeInfo> results = Entities.query(new SANVolumeInfo());
assertTrue("expected two SANVolumeInfo to exist", results != null && results.size() == 2);
}
}
@Test
public void createVolume_FromSnap_CloneDbRecExistsTest() throws Exception {
final String volId = "testparentvol";
final String rezPrefix = "fooprefix";
final String rezSuffix = "foosuffix";
final Integer snapSz = new Integer(5);
final SANVolumeInfo existing = new SANVolumeInfo(volId).withSanVolumeId(rezPrefix + volId + rezSuffix);
existing.setIqn("foo-parent-iqn");
existing.setSize(new Integer(5));
existing.setSnapshotOf("foo-vol");
final SANVolumeInfo existingClone = new SANVolumeInfo("testvol").withSanVolumeId(rezPrefix + "testvol" + rezSuffix);
existingClone.setIqn("foo-iqn");
existingClone.setSize(new Integer(5));
SANInfo sanInfo = new SANInfo(StorageProperties.NAME, "foohost", "foouser", "foopassword");
sanInfo.setResourcePrefix(rezPrefix);
sanInfo.setResourceSuffix(rezSuffix);
try (TransactionResource tran = Entities.transactionFor(SANInfo.class)) {
Entities.persist(existing);
Entities.persist(existingClone);
Entities.persist(sanInfo);
tran.commit();
}
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).volumeExists(existingClone.getSanVolumeId(), existingClone.getIqn());
will(returnValue(Boolean.FALSE));
oneOf(sanProvider).createVolume(rezPrefix + "testvol" + rezSuffix, existingClone.getSanVolumeId(), snapSz.intValue(), snapSz.intValue(),
existingClone.getIqn());
will(returnValue("foo-iqn"));
}
});
SANManager test = new SANManager(sanProvider);
test.createVolume("testvol", existingClone.getVolumeId(), snapSz.intValue());
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
List<SANVolumeInfo> results = Entities.query(new SANVolumeInfo());
assertTrue("expected two SANVolumeInfo to exist", results != null && results.size() == 2);
}
}
@Test
public void prepareSnapshot_BasicTest() throws Exception {
final String volId = "testsnap";
final String rezPrefix = "fooprefix";
final String rezSuffix = "foosuffix";
final Integer snapSz = new Integer(5);
// final SANVolumeInfo existing = new SANVolumeInfo(volId).withSanVolumeId(rezPrefix + volId + rezSuffix);
// existing.setIqn("foo-parent-iqn");
// existing.setSize(snapSz);
// existing.setSnapshotOf("foo-vol");
SANInfo sanInfo = new SANInfo(StorageProperties.NAME, "foohost", "foouser", "foopassword");
sanInfo.setResourcePrefix(rezPrefix);
sanInfo.setResourceSuffix(rezSuffix);
try (TransactionResource tran = Entities.transactionFor(SANInfo.class)) {
// Entities.persist(existing);
Entities.persist(sanInfo);
tran.commit();
}
StorageProperties.SC_INITIATOR_IQN = "sc-foo-iqn";
final SANProvider sanProvider = context.mock(SANProvider.class);
context.checking(new Expectations() {
{
oneOf(sanProvider).createSnapshotHolder(rezPrefix + volId + rezSuffix, snapSz * 1024l);
will(returnValue("foo-iqn"));
oneOf(sanProvider).exportResource(rezPrefix + volId + rezSuffix, "sc-foo-iqn", "foo-iqn");
will(returnValue(new String("1")));
oneOf(sanProvider).connectTarget("foo-iqn", "1");
will(returnValue(new StorageResource(volId, "foopath", StorageResource.Type.FILE) {
@Override
public Long getSize() throws Exception {
return null;
}
@Override
public InputStream getInputStream() throws Exception {
return null;
}
@Override
public OutputStream getOutputStream() throws Exception {
return null;
}
@Override
public Boolean isDownloadSynchronous() {
return Boolean.TRUE;
}
}));
}
});
SANManager test = new SANManager(sanProvider);
test.prepSnapshotForDownload(volId, snapSz.intValue(), snapSz.intValue() * 1024l);
try (TransactionResource tran = Entities.transactionFor(SANVolumeInfo.class)) {
List<SANVolumeInfo> results = Entities.query(new SANVolumeInfo());
assertTrue("expected one SANVolumeInfo to exist", results != null && results.size() == 1);
}
}
}