/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.cloudstack.storage.datastore.util; import static org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.IscsiTarget; import static org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.ListOfIscsiTargetsNmsResponse; import static org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.CreateIscsiTargetRequestParams; import static org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.ListOfStringsNmsResponse; import static org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.IntegerNmsResponse; import static org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.LuParams; import static org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.MappingEntry; import static org.apache.cloudstack.storage.datastore.util.NexentaStorAppliance.AddMappingEntryNmsResponse; import static org.apache.cloudstack.storage.datastore.util.NexentaNmsClient.NmsResponse; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.HashMap; import java.util.LinkedList; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner; import com.cloud.utils.exception.CloudRuntimeException; @RunWith(MockitoJUnitRunner.class) public class NexentaStorApplianceTest { private NexentaNmsClient client; private NexentaStorAppliance appliance; @Rule public ExpectedException exception = ExpectedException.none(); @Before public void init() { final String url = "nmsUrl=https://admin:nexenta@10.1.3.182:8457;volume=cloudstack;storageType=iscsi"; NexentaUtil.NexentaPluginParameters parameters = NexentaUtil.parseNexentaPluginUrl(url); //client = new NexentaNmsClient(parameters.getNmsUrl()); client = mock(NexentaNmsClient.class); appliance = new NexentaStorAppliance(client, parameters); } @Test public void testIsIscsiTargetExists() { final String targetName = NexentaStorAppliance.getTargetName("volume1"); when(client.execute(ListOfIscsiTargetsNmsResponse.class, "stmf", "list_targets")).thenReturn(null); assertFalse(appliance.isIscsiTargetExists(targetName)); when(client.execute(ListOfIscsiTargetsNmsResponse.class, "stmf", "list_targets")).thenReturn(new ListOfIscsiTargetsNmsResponse()); assertFalse(appliance.isIscsiTargetExists(targetName)); final HashMap<String, IscsiTarget> result = new HashMap<String, IscsiTarget>(); result.put("any", new IscsiTarget("Online", "iSCSI", "any", "0", "-", "iscsit")); when(client.execute(ListOfIscsiTargetsNmsResponse.class, "stmf", "list_targets")).thenReturn(new ListOfIscsiTargetsNmsResponse(result)); assertFalse(appliance.isIscsiTargetExists(targetName)); result.put(targetName, new IscsiTarget("Online", "iSCSI", targetName, "0", "-", "iscsit")); when(client.execute(ListOfIscsiTargetsNmsResponse.class, "stmf", "list_targets")).thenReturn(new ListOfIscsiTargetsNmsResponse(result)); assertTrue(appliance.isIscsiTargetExists(targetName)); } final static String ISCSI_TARGET_ALREADY_CONFIGURED_ERROR = "Unable to create iscsi target\\n iSCSI target %s already configured\\n itadm create-target failed with error " + "17\\n"; @Test public void testCreateIscsiTarget() { final String targetName = NexentaStorAppliance.getTargetName("volume1"); final CreateIscsiTargetRequestParams p = new CreateIscsiTargetRequestParams(targetName); appliance.createIscsiTarget(targetName); verify(client).execute(NmsResponse.class, "iscsitarget", "create_target", p); final String error = String.format(ISCSI_TARGET_ALREADY_CONFIGURED_ERROR, targetName); when(client.execute(NmsResponse.class, "iscsitarget", "create_target", p)).thenThrow(new CloudRuntimeException(error)); appliance.createIscsiTarget(targetName); } @Test public void testCreateIscsiTargetFails() { final String targetName = NexentaStorAppliance.getTargetName("volume1"); final CreateIscsiTargetRequestParams p = new CreateIscsiTargetRequestParams(targetName); exception.expect(CloudRuntimeException.class); exception.expectMessage("any exception"); when(client.execute(NmsResponse.class, "iscsitarget", "create_target", p)).thenThrow(new CloudRuntimeException("any exception")); appliance.createIscsiTarget(targetName); } @Test public void testIsIscsiTargetGroupExists() { final String targetGroup = NexentaStorAppliance.getTargetGroupName("volume1"); when(client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroups")).thenReturn(null); assertFalse(appliance.isIscsiTargetGroupExists(targetGroup)); when(client.execute(ListOfIscsiTargetsNmsResponse.class, "stmf", "list_targetgroups")).thenReturn(new ListOfIscsiTargetsNmsResponse()); assertFalse(appliance.isIscsiTargetGroupExists(targetGroup)); LinkedList<String> result = new LinkedList<String>(); result.add("any"); when(client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroups")).thenReturn(new ListOfStringsNmsResponse(result)); assertFalse(appliance.isIscsiTargetGroupExists(targetGroup)); result.add(targetGroup); when(client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroups")).thenReturn(new ListOfStringsNmsResponse(result)); assertTrue(appliance.isIscsiTargetGroupExists(targetGroup)); } final static String ISCSI_TARGET_GROUP_EXISTS_ERROR = "Unable to create targetgroup: stmfadm: %s: already exists\\n"; @Test public void testCreateIscsiTargetGroup() { final String targetGroupName = NexentaStorAppliance.getTargetGroupName("volume1"); appliance.createIscsiTargetGroup(targetGroupName); verify(client).execute(NmsResponse.class, "stmf", "create_targetgroup", targetGroupName); final String error = String.format(ISCSI_TARGET_GROUP_EXISTS_ERROR, targetGroupName); when(client.execute(NmsResponse.class, "stmf", "create_targetgroup", targetGroupName)).thenThrow(new CloudRuntimeException(error)); appliance.createIscsiTargetGroup(targetGroupName); } @Test public void testCreateIscsiTargetGroupFails() { final String targetGroupName = NexentaStorAppliance.getTargetGroupName("volume1"); when(client.execute(NmsResponse.class, "stmf", "create_targetgroup", targetGroupName)).thenThrow(new CloudRuntimeException("any exception")); exception.expect(CloudRuntimeException.class); exception.expectMessage("any exception"); appliance.createIscsiTargetGroup(targetGroupName); } @Test public void testIsMemberOfTargetGroup() { final String targetName = NexentaStorAppliance.getTargetName("volume1"); final String targetGroupName = NexentaStorAppliance.getTargetGroupName("volume1"); when(client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroup_members", targetGroupName)).thenReturn(null); assertFalse(appliance.isTargetMemberOfTargetGroup(targetGroupName, targetName)); when(client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroup_members", targetGroupName)).thenReturn(new ListOfStringsNmsResponse()); assertFalse(appliance.isTargetMemberOfTargetGroup(targetGroupName, targetName)); LinkedList<String> result = new LinkedList<String>(); result.add("any"); when(client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroup_members", targetGroupName)).thenReturn(new ListOfStringsNmsResponse(result)); assertFalse(appliance.isTargetMemberOfTargetGroup(targetGroupName, targetName)); result.add(targetName); when(client.execute(ListOfStringsNmsResponse.class, "stmf", "list_targetgroup_members", targetGroupName)).thenReturn(new ListOfStringsNmsResponse(result)); assertTrue(appliance.isTargetMemberOfTargetGroup(targetGroupName, targetName)); } @Test public void testAddTargetGroupMember() { final String targetName = NexentaStorAppliance.getTargetName("volume1"); final String targetGroupName = NexentaStorAppliance.getTargetGroupName("volume1"); appliance.addTargetGroupMember(targetGroupName, targetName); verify(client).execute(NmsResponse.class, "stmf", "add_targetgroup_member", targetGroupName, targetName); String error = String.format(ISCSI_TARGET_ALREADY_EXISTS_IN_TARGET_GROUP_ERROR, targetName); when(client.execute(NmsResponse.class, "stmf", "add_targetgroup_member", targetGroupName, targetName)).thenThrow(new CloudRuntimeException(error)); appliance.addTargetGroupMember(targetGroupName, targetName); } final static String ISCSI_TARGET_ALREADY_EXISTS_IN_TARGET_GROUP_ERROR = "Unable to add member to targetgroup: stmfadm: %s: already exists\\n"; @Test public void testAddTargetGroupMemberFails() { final String targetName = NexentaStorAppliance.getTargetName("volume1"); final String targetGroupName = NexentaStorAppliance.getTargetGroupName("volume1"); when(client.execute(NmsResponse.class, "stmf", "add_targetgroup_member", targetGroupName, targetName)).thenThrow(new CloudRuntimeException("any exception")); exception.expect(CloudRuntimeException.class); exception.expectMessage("any exception"); appliance.addTargetGroupMember(targetGroupName, targetName); } @Test public void testIsLuExists() { final String volumeName = appliance.getVolumeName("volume1"); when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_exists", volumeName)).thenReturn(null); assertFalse(appliance.isLuExists(volumeName)); when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_exists", volumeName)).thenReturn(new IntegerNmsResponse(0)); assertFalse(appliance.isLuExists(volumeName)); when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_exists", volumeName)).thenReturn(new IntegerNmsResponse(1)); assertTrue(appliance.isLuExists(volumeName)); when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_exists", volumeName)).thenThrow(new CloudRuntimeException("does not exist")); assertFalse(appliance.isLuExists(volumeName)); } @Test public void testIsLuExistsFails() { final String volumeName = appliance.getVolumeName("volume1"); exception.expect(CloudRuntimeException.class); exception.expectMessage("any exception"); when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_exists", volumeName)).thenThrow(new CloudRuntimeException("any exception")); assertTrue(appliance.isLuExists(volumeName)); } final static String CREATE_LU_IN_USE_ERROR = "Unable to create lu with " + "zvol '%s':\\n stmfadm: filename /dev/zvol/rdsk/%s: in use\\n"; @Test public void testCreateLu() { final String luName = appliance.getVolumeName("volume1"); final LuParams p = new LuParams(); appliance.createLu(luName); verify(client).execute(NmsResponse.class, "scsidisk", "create_lu", luName, p); String error = String.format(CREATE_LU_IN_USE_ERROR, luName, luName); when(client.execute(NmsResponse.class, "scsidisk", "create_lu", luName, p)).thenThrow(new CloudRuntimeException(error)); appliance.createLu(luName); } @Test public void testCreateLuFails() { final String luName = appliance.getVolumeName("volume1"); when(client.execute(NmsResponse.class, "scsidisk", "create_lu", luName, new LuParams())).thenThrow(new CloudRuntimeException("any exception")); exception.expect(CloudRuntimeException.class); exception.expectMessage("any exception"); appliance.createLu(luName); } final static String ZVOL_DOES_NOT_EXISTS_ERROR = "Zvol '%s' does not exist"; @Test public void testIsLuShared() { final String luName = appliance.getVolumeName("volume1"); when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_shared", luName)).thenReturn(null); assertFalse(appliance.isLuShared(luName)); when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_shared", luName)).thenReturn(new IntegerNmsResponse(0)); assertFalse(appliance.isLuShared(luName)); when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_shared", luName)).thenReturn(new IntegerNmsResponse(1)); assertTrue(appliance.isLuShared(luName)); final String error = String.format(ZVOL_DOES_NOT_EXISTS_ERROR, luName); when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_shared", luName)).thenThrow(new CloudRuntimeException(error)); assertFalse(appliance.isLuShared(luName)); } @Test public void testIsLuSharedFails() { final String luName = appliance.getVolumeName("volume1"); when(client.execute(IntegerNmsResponse.class, "scsidisk", "lu_shared", luName)).thenThrow(new CloudRuntimeException("any exception")); exception.expect(CloudRuntimeException.class); exception.expectMessage("any exception"); appliance.isLuShared(luName); } final static String ADD_LUN_MAPPING_ENTRY_ERROR = "(rc: 256) Unable to " + "add view to zvol '%s':\\n add-view: view already exists\\n"; @Test public void testAddLuMappingEntry() { final String luName = appliance.getVolumeName("volume1"); final String targetGroupName = NexentaStorAppliance.getTargetGroupName("volume1"); final MappingEntry mappingEntry = new MappingEntry(targetGroupName, "0"); appliance.addLuMappingEntry(luName, targetGroupName); verify(client).execute(AddMappingEntryNmsResponse.class, "scsidisk", "add_lun_mapping_entry", luName, mappingEntry); String error = String.format(ADD_LUN_MAPPING_ENTRY_ERROR, luName); when(client.execute(AddMappingEntryNmsResponse.class, "scsidisk", "add_lun_mapping_entry", luName, mappingEntry)).thenThrow(new CloudRuntimeException(error)); appliance.addLuMappingEntry(luName, targetGroupName); } @Test public void testAddLuMappingEntryTest() { final String luName = appliance.getVolumeName("volume1"); final String targetGroupName = NexentaStorAppliance.getTargetGroupName("volume1"); final MappingEntry mappingEntry = new MappingEntry(targetGroupName, "0"); when(client.execute(AddMappingEntryNmsResponse.class, "scsidisk", "add_lun_mapping_entry", luName, mappingEntry)).thenThrow(new CloudRuntimeException("any exception")); exception.expect(CloudRuntimeException.class); exception.expectMessage("any exception"); appliance.addLuMappingEntry(luName, targetGroupName); } @Test public void testCreateIscsiVolume() { final String volumeName = "volume1"; final Long volumeSize = Long.valueOf(1); appliance.createIscsiVolume(volumeName, volumeSize); } @Test public void testDeleteIscsiVolume() { final String volumeName = appliance.getVolumeName("volume1"); appliance.deleteIscsiVolume(volumeName); verify(client).execute(NmsResponse.class, "zvol", "destroy", volumeName, ""); when(client.execute(NmsResponse.class, "zvol", "destroy", volumeName, "")).thenThrow(new CloudRuntimeException(String.format("Zvol '%s' does not exist", volumeName))); appliance.deleteIscsiVolume(volumeName); } @Test public void testDeleteIscsiVolumeFails() { final String volumeName = appliance.getVolumeName("volume1"); exception.expect(CloudRuntimeException.class); exception.expectMessage("any exception"); when(client.execute(NmsResponse.class, "zvol", "destroy", volumeName, "")).thenThrow(new CloudRuntimeException("any exception")); appliance.deleteIscsiVolume(volumeName); } }