/*************************************************************************
* 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.
************************************************************************/
package com.eucalyptus.blockstorage;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
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.entities.CHAPUserInfo;
import com.eucalyptus.blockstorage.entities.DirectStorageInfo;
import com.eucalyptus.blockstorage.entities.ISCSIMetaInfo;
import com.eucalyptus.blockstorage.entities.ISCSIVolumeInfo;
import com.eucalyptus.blockstorage.util.BlockStorageUtilSvc;
import com.eucalyptus.blockstorage.util.StorageProperties;
import com.eucalyptus.entities.Entities;
import com.eucalyptus.entities.TransactionResource;
/**
*
*/
public class ISCSIManagerTest {
@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 allocateTarget_BasicTest() throws Exception {
final String volId = "vol-0000";
final ISCSIVolumeInfo iscsiVolumeInfo = new ISCSIVolumeInfo();
iscsiVolumeInfo.setVolumeId(volId);
final TGTService tgtService = context.mock(TGTService.class);
final BlockStorageUtilSvc blockStorageUtilSvc = context.mock(BlockStorageUtilSvc.class);
context.checking(new Expectations() {
{
oneOf(tgtService).targetExists(volId, 1, null, DirectStorageInfo.getStorageInfo().getTimeoutInMillis());
will(returnValue(Boolean.FALSE));
}
});
ISCSIMetaInfo metaInfo = new ISCSIMetaInfo(StorageProperties.NAME);
metaInfo.setStoreNumber(new Integer(1));
metaInfo.setTid(new Integer(1));
metaInfo.setStorePrefix("foo:");
metaInfo.setStoreUser("unittestuser0");
try (TransactionResource tran = Entities.transactionFor(ISCSIMetaInfo.class)) {
metaInfo = Entities.persist(metaInfo);
tran.commit();
}
ISCSIManager iscsiManager = new ISCSIManager(tgtService, blockStorageUtilSvc);
iscsiManager.allocateTarget(iscsiVolumeInfo);
List<ISCSIMetaInfo> remaining;
try (TransactionResource tran = Entities.transactionFor(ISCSIMetaInfo.class)) {
remaining = Entities.query(new ISCSIMetaInfo());
tran.commit();
}
assertTrue("expected to have a result set querying the eucalyptus_storage persistence context", remaining != null);
ISCSIMetaInfo retrieved = remaining.get(0);
assertTrue("expected store number to be 2 but was " + retrieved.getStoreNumber(), retrieved.getStoreNumber().intValue() == 2);
assertTrue("expected tid to be 2", retrieved.getTid().intValue() == 2);
String storeName = "foo:" + StorageProperties.NAME + ":store2";
assertTrue("expected iscsiVolumeInfo store name to be " + storeName, storeName.equals(iscsiVolumeInfo.getStoreName()));
assertTrue("expected iscsiVolumeInfo store user to be unittestuser0 but was " + iscsiVolumeInfo.getStoreUser(),
"unittestuser0".equals(iscsiVolumeInfo.getStoreUser()));
assertTrue("expected iscsiVolumeInfo tid to be 1 and lun to be 1", iscsiVolumeInfo.getTid().intValue() == 1
&& iscsiVolumeInfo.getLun().intValue() == 1);
}
@Test
public void configure_BasicTest() throws Exception {
final Long timeout = DirectStorageInfo.getStorageInfo().getTimeoutInMillis();
final TGTService tgtService = context.mock(TGTService.class);
final BlockStorageUtilSvc blockStorageUtilSvc = context.mock(BlockStorageUtilSvc.class);
context.checking(new Expectations() {
{
oneOf(tgtService).userExists("eucalyptus", timeout);
will(returnValue(Boolean.FALSE));
oneOf(tgtService).addUser(with(equal("eucalyptus")), with(any(String.class)), with(equal(timeout)));
oneOf(blockStorageUtilSvc).encryptSCTargetPassword(with(any(String.class)));
will(returnValue("foo"));
}
});
ISCSIManager iscsiManager = new ISCSIManager(tgtService, blockStorageUtilSvc);
iscsiManager.configure();
List<ISCSIMetaInfo> remaining;
try (TransactionResource tran = Entities.transactionFor(ISCSIMetaInfo.class)) {
remaining = Entities.query(new ISCSIMetaInfo());
tran.commit();
}
// make sure the meta info was created
assertTrue("expected to have a result set querying the eucalyptus_storage persistence context", remaining != null);
ISCSIMetaInfo retrieved = remaining.get(0);
assertTrue("expected store prefix to be " + StorageProperties.STORE_PREFIX + " but it was " + retrieved.getStorePrefix(),
StorageProperties.STORE_PREFIX.equals(retrieved.getStorePrefix()));
assertTrue("expected store number to be 0 but it was " + retrieved.getStoreNumber().intValue(), retrieved.getStoreNumber().intValue() == 0);
assertTrue("expected store user to be eucalyptus, but it was " + retrieved.getStoreUser(), "eucalyptus".equals(retrieved.getStoreUser()));
assertTrue("expected tid to be 1, but it was " + retrieved.getTid().intValue(), 1 == retrieved.getTid().intValue());
// make sure chap user was created
CHAPUserInfo example = new CHAPUserInfo("eucalyptus");
example.setScName(StorageProperties.NAME);
try (TransactionResource tran = Entities.transactionFor(CHAPUserInfo.class)) {
example = Entities.uniqueResult(example);
tran.commit();
} catch (Exception ex) {
fail("exception caught while looking for CHAPUserInfo record - " + ex.getMessage());
ex.printStackTrace();
}
assertTrue("expected chap user info to be non-null", example != null);
assertTrue("expected eucalyptus chap user info to be created", "eucalyptus".equals(example.getUser()));
}
@Test
public void configure_NoDbUserButYesTGTUserTest() throws Exception {
final Long timeout = DirectStorageInfo.getStorageInfo().getTimeoutInMillis();
final TGTService tgtService = context.mock(TGTService.class);
final BlockStorageUtilSvc blockStorageUtilSvc = context.mock(BlockStorageUtilSvc.class);
context.checking(new Expectations() {
{
oneOf(tgtService).userExists("eucalyptus", timeout);
will(returnValue(Boolean.TRUE));
oneOf(tgtService).deleteUser("eucalyptus", timeout);
oneOf(tgtService).addUser(with(equal("eucalyptus")), with(any(String.class)), with(equal(timeout)));
oneOf(blockStorageUtilSvc).encryptSCTargetPassword(with(any(String.class)));
will(returnValue("foo"));
}
});
ISCSIManager iscsiManager = new ISCSIManager(tgtService, blockStorageUtilSvc);
iscsiManager.configure();
List<ISCSIMetaInfo> remaining;
try (TransactionResource tran = Entities.transactionFor(ISCSIMetaInfo.class)) {
remaining = Entities.query(new ISCSIMetaInfo());
tran.commit();
}
// make sure the meta info was created
assertTrue("expected to have a result set querying the eucalyptus_storage persistence context", remaining != null);
ISCSIMetaInfo retrieved = remaining.get(0);
assertTrue("expected store prefix to be " + StorageProperties.STORE_PREFIX + " but it was " + retrieved.getStorePrefix(),
StorageProperties.STORE_PREFIX.equals(retrieved.getStorePrefix()));
assertTrue("expected store number to be 0 but it was " + retrieved.getStoreNumber().intValue(), retrieved.getStoreNumber().intValue() == 0);
assertTrue("expected store user to be eucalyptus, but it was " + retrieved.getStoreUser(), "eucalyptus".equals(retrieved.getStoreUser()));
assertTrue("expected tid to be 1, but it was " + retrieved.getTid().intValue(), 1 == retrieved.getTid().intValue());
// make sure chap user was created
CHAPUserInfo example = new CHAPUserInfo("eucalyptus");
example.setScName(StorageProperties.NAME);
try (TransactionResource tran = Entities.transactionFor(CHAPUserInfo.class)) {
example = Entities.uniqueResult(example);
tran.commit();
} catch (Exception ex) {
fail("exception caught while looking for CHAPUserInfo record - " + ex.getMessage());
ex.printStackTrace();
}
assertTrue("expected chap user info to be non-null", example != null);
assertTrue("expected eucalyptus chap user info to be created", "eucalyptus".equals(example.getUser()));
}
@Test
public void configure_YesDbUserButNoTGTUserTest() throws Exception {
final Long timeout = DirectStorageInfo.getStorageInfo().getTimeoutInMillis();
final TGTService tgtService = context.mock(TGTService.class);
final BlockStorageUtilSvc blockStorageUtilSvc = context.mock(BlockStorageUtilSvc.class);
context.checking(new Expectations() {
{
oneOf(tgtService).userExists("eucalyptus", timeout);
will(returnValue(Boolean.FALSE));
oneOf(blockStorageUtilSvc).decryptSCTargetPassword("foo");
will(returnValue("foo"));
oneOf(tgtService).addUser("eucalyptus", "foo", timeout);
}
});
try (TransactionResource tran = Entities.transactionFor(CHAPUserInfo.class)) {
Entities.persist(new CHAPUserInfo("eucalyptus", "foo"));
tran.commit();
}
ISCSIManager iscsiManager = new ISCSIManager(tgtService, blockStorageUtilSvc);
iscsiManager.configure();
List<ISCSIMetaInfo> remaining;
try (TransactionResource tran = Entities.transactionFor(ISCSIMetaInfo.class)) {
remaining = Entities.query(new ISCSIMetaInfo());
tran.commit();
}
// make sure the meta info was created
assertTrue("expected to have a result set querying the eucalyptus_storage persistence context", remaining != null);
ISCSIMetaInfo retrieved = remaining.get(0);
assertTrue("expected store prefix to be " + StorageProperties.STORE_PREFIX + " but it was " + retrieved.getStorePrefix(),
StorageProperties.STORE_PREFIX.equals(retrieved.getStorePrefix()));
assertTrue("expected store number to be 0 but it was " + retrieved.getStoreNumber().intValue(), retrieved.getStoreNumber().intValue() == 0);
assertTrue("expected store user to be eucalyptus, but it was " + retrieved.getStoreUser(), "eucalyptus".equals(retrieved.getStoreUser()));
assertTrue("expected tid to be 1, but it was " + retrieved.getTid().intValue(), 1 == retrieved.getTid().intValue());
// make sure chap user was created
CHAPUserInfo example = new CHAPUserInfo("eucalyptus");
example.setScName(StorageProperties.NAME);
try (TransactionResource tran = Entities.transactionFor(CHAPUserInfo.class)) {
example = Entities.uniqueResult(example);
tran.commit();
} catch (Exception ex) {
fail("exception caught while looking for CHAPUserInfo record - " + ex.getMessage());
ex.printStackTrace();
}
assertTrue("expected chap user info to be non-null", example != null);
assertTrue("expected eucalyptus chap user info to be created", "eucalyptus".equals(example.getUser()));
}
@Test
public void configure_YesDbUserAndYesTGTUserTest() throws Exception {
final Long timeout = DirectStorageInfo.getStorageInfo().getTimeoutInMillis();
final TGTService tgtService = context.mock(TGTService.class);
final BlockStorageUtilSvc blockStorageUtilSvc = context.mock(BlockStorageUtilSvc.class);
context.checking(new Expectations() {
{
oneOf(tgtService).userExists("eucalyptus", timeout);
will(returnValue(Boolean.TRUE));
}
});
try (TransactionResource tran = Entities.transactionFor(CHAPUserInfo.class)) {
Entities.persist(new CHAPUserInfo("eucalyptus", "foo"));
tran.commit();
}
ISCSIManager iscsiManager = new ISCSIManager(tgtService, blockStorageUtilSvc);
iscsiManager.configure();
List<ISCSIMetaInfo> remaining;
try (TransactionResource tran = Entities.transactionFor(ISCSIMetaInfo.class)) {
remaining = Entities.query(new ISCSIMetaInfo());
tran.commit();
}
// make sure the meta info was created
assertTrue("expected to have a result set querying the eucalyptus_storage persistence context", remaining != null);
ISCSIMetaInfo retrieved = remaining.get(0);
assertTrue("expected store prefix to be " + StorageProperties.STORE_PREFIX + " but it was " + retrieved.getStorePrefix(),
StorageProperties.STORE_PREFIX.equals(retrieved.getStorePrefix()));
assertTrue("expected store number to be 0 but it was " + retrieved.getStoreNumber().intValue(), retrieved.getStoreNumber().intValue() == 0);
assertTrue("expected store user to be eucalyptus, but it was " + retrieved.getStoreUser(), "eucalyptus".equals(retrieved.getStoreUser()));
assertTrue("expected tid to be 1, but it was " + retrieved.getTid().intValue(), 1 == retrieved.getTid().intValue());
// make sure chap user was created
CHAPUserInfo example = new CHAPUserInfo("eucalyptus");
example.setScName(StorageProperties.NAME);
try (TransactionResource tran = Entities.transactionFor(CHAPUserInfo.class)) {
example = Entities.uniqueResult(example);
tran.commit();
} catch (Exception ex) {
fail("exception caught while looking for CHAPUserInfo record - " + ex.getMessage());
ex.printStackTrace();
}
assertTrue("expected chap user info to be non-null", example != null);
assertTrue("expected eucalyptus chap user info to be created", "eucalyptus".equals(example.getUser()));
}
@Test
public void cleanup_BasicTest() throws Exception {
final String volId = "vol-0000";
final ISCSIVolumeInfo iscsiVolumeInfo = new ISCSIVolumeInfo();
iscsiVolumeInfo.setVolumeId(volId);
iscsiVolumeInfo.setTid(new Integer(1));
iscsiVolumeInfo.setVgName("foo");
iscsiVolumeInfo.setLvName("foo");
iscsiVolumeInfo.setLun(new Integer(1));
final TGTService tgtService = context.mock(TGTService.class);
final BlockStorageUtilSvc blockStorageUtilSvc = context.mock(BlockStorageUtilSvc.class);
final Long timeout = DirectStorageInfo.getStorageInfo().getTimeoutInMillis();
context.checking(new Expectations() {
{
oneOf(tgtService).targetExists(volId, 1, iscsiVolumeInfo.getAbsoluteLVPath(), timeout);
will(returnValue(Boolean.TRUE));
oneOf(tgtService).targetExists(volId, 1, iscsiVolumeInfo.getAbsoluteLVPath(), timeout);
will(returnValue(Boolean.TRUE));
oneOf(tgtService).unbindTarget(volId, 1, timeout);
oneOf(tgtService).deleteLun(volId, 1, 1, timeout);
oneOf(tgtService).deleteTarget(volId, 1, timeout, false);
oneOf(tgtService).targetExists(volId, 1, null, timeout);
will(returnValue(Boolean.FALSE));
oneOf(tgtService).targetExists(volId, 1, iscsiVolumeInfo.getAbsoluteLVPath(), timeout);
will(returnValue(Boolean.FALSE));
}
});
try (TransactionResource tran = Entities.transactionFor(ISCSIVolumeInfo.class)) {
Entities.persist(iscsiVolumeInfo);
tran.commit();
}
ISCSIManager iscsiManager = new ISCSIManager(tgtService, blockStorageUtilSvc);
iscsiManager.cleanup(iscsiVolumeInfo);
List<ISCSIVolumeInfo> remaining;
try (TransactionResource tran = Entities.transactionFor(ISCSIVolumeInfo.class)) {
remaining = Entities.query(new ISCSIVolumeInfo());
tran.commit();
}
assertTrue("expected to have a result set querying the eucalyptus_storage persistence context", remaining != null);
ISCSIVolumeInfo retrieved = remaining.get(0);
assertTrue("expected store name to be null but was " + retrieved.getStoreName(), retrieved.getStoreName() == null);
assertTrue("expected tid to be -1", retrieved.getTid().intValue() == -1);
assertTrue("expected iscsiVolumeInfo lun to be -1 but was " + retrieved.getLun().intValue(), retrieved.getLun().intValue() == -1);
}
@Test
public void cleanup_NotExportedTest() throws Exception {
final String volId = "vol-0000";
final ISCSIVolumeInfo iscsiVolumeInfo = new ISCSIVolumeInfo();
iscsiVolumeInfo.setVolumeId(volId);
iscsiVolumeInfo.setTid(new Integer(1));
iscsiVolumeInfo.setVgName("foo");
iscsiVolumeInfo.setLvName("foo");
iscsiVolumeInfo.setLun(new Integer(1));
final TGTService tgtService = context.mock(TGTService.class);
final BlockStorageUtilSvc blockStorageUtilSvc = context.mock(BlockStorageUtilSvc.class);
final Long timeout = DirectStorageInfo.getStorageInfo().getTimeoutInMillis();
context.checking(new Expectations() {
{
oneOf(tgtService).targetExists(volId, 1, iscsiVolumeInfo.getAbsoluteLVPath(), timeout);
will(returnValue(Boolean.FALSE));
}
});
try (TransactionResource tran = Entities.transactionFor(ISCSIVolumeInfo.class)) {
Entities.persist(iscsiVolumeInfo);
tran.commit();
}
ISCSIManager iscsiManager = new ISCSIManager(tgtService, blockStorageUtilSvc);
iscsiManager.cleanup(iscsiVolumeInfo);
List<ISCSIVolumeInfo> remaining;
try (TransactionResource tran = Entities.transactionFor(ISCSIVolumeInfo.class)) {
remaining = Entities.query(new ISCSIVolumeInfo());
tran.commit();
}
assertTrue("expected to have a result set querying the eucalyptus_storage persistence context", remaining != null);
ISCSIVolumeInfo retrieved = remaining.get(0);
assertTrue("expected store name to be null but was " + retrieved.getStoreName(), retrieved.getStoreName() == null);
assertTrue("expected tid to be -1", retrieved.getTid().intValue() == -1);
assertTrue("expected iscsiVolumeInfo lun to be -1 but was " + retrieved.getLun().intValue(), retrieved.getLun().intValue() == -1);
}
@Test
public void getEncryptedPassword_BasicTest() throws Exception {
final TGTService tgtService = context.mock(TGTService.class);
final BlockStorageUtilSvc blockStorageUtilSvc = context.mock(BlockStorageUtilSvc.class);
context.checking(new Expectations() {
{
oneOf(blockStorageUtilSvc).decryptSCTargetPassword("foo");
will(returnValue("foo"));
oneOf(blockStorageUtilSvc).getPartitionForLocalService(Storage.class);
will(returnValue(null));
oneOf(blockStorageUtilSvc).encryptNodeTargetPassword("foo", null);
will(returnValue("foo"));
}
});
try (TransactionResource tran = Entities.transactionFor(CHAPUserInfo.class)) {
Entities.persist(new CHAPUserInfo("eucalyptus", "foo"));
tran.commit();
}
ISCSIManager iscsiManager = new ISCSIManager(tgtService, blockStorageUtilSvc);
String foo = iscsiManager.getEncryptedPassword();
assertTrue("expected result to be 'foo' but was - " + foo, foo != null && "foo".equals(foo));
}
}