| /* |
| * 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); |
| } |
| } |