def setUp(self): self.fqdn = "fqdn" self.servicer = ControllerServicer(self.fqdn)
class TestControllerServerUnPublishVolume(unittest.TestCase): @patch("controller.array_action.array_mediator_xiv.XIVArrayMediator._connect") def setUp(self, connect): self.fqdn = "fqdn" self.hostname = "hostname" self.mediator = XIVArrayMediator("user", "password", self.fqdn) self.mediator.client = Mock() self.mediator.get_host_by_host_identifiers = Mock() self.mediator.get_host_by_host_identifiers.return_value = self.hostname, ["iscsi"] self.mediator.unmap_volume = Mock() self.mediator.unmap_volume.return_value = None self.servicer = ControllerServicer(self.fqdn) self.request = Mock() arr_type = XIVArrayMediator.array_type self.request.volume_id = "{}:wwn1".format(arr_type) self.request.node_id = "hostname;iqn1;500143802426baf4" self.request.secrets = {"username": "******", "password": "******", "management_address": "mg"} self.request.volume_context = {} @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def test_unpublish_volume_success(self, enter): enter.return_value = self.mediator context = utils.FakeContext() self.servicer.ControllerUnpublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK) @patch("controller.controller_server.utils.validate_unpublish_volume_request") def test_unpublish_volume_validation_exception(self, publish_validation): publish_validation.side_effect = [controller_errors.ValidationException("msg")] context = utils.FakeContext() self.servicer.ControllerUnpublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INVALID_ARGUMENT) self.assertTrue("msg" in context.details) def test_unpublish_volume_wrong_volume_id(self): self.request.volume_id = "some-wrong-id-format" context = utils.FakeContext() self.servicer.ControllerUnpublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INVALID_ARGUMENT) def test_unpublish_volume_wrong_node_id(self): self.request.node_id = "some-wrong-id-format" context = utils.FakeContext() self.servicer.ControllerUnpublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.NOT_FOUND) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def test_unpublish_volume_get_host_by_host_identifiers_exception(self, enter): context = utils.FakeContext() self.mediator.get_host_by_host_identifiers = Mock() self.mediator.get_host_by_host_identifiers.side_effect = [array_errors.MultipleHostsFoundError("", "")] enter.return_value = self.mediator self.servicer.ControllerUnpublishVolume(self.request, context) self.assertTrue("Multiple hosts" in context.details) self.assertEqual(context.code, grpc.StatusCode.INTERNAL) self.mediator.get_host_by_host_identifiers.side_effect = [array_errors.HostNotFoundError("")] enter.return_value = self.mediator self.servicer.ControllerUnpublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.NOT_FOUND) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def test_unpublish_volume_unmap_volume_excpetions(self, enter): context = utils.FakeContext() self.mediator.unmap_volume.side_effect = [array_errors.PermissionDeniedError("msg")] enter.return_value = self.mediator self.servicer.ControllerUnpublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.PERMISSION_DENIED) context = utils.FakeContext() self.mediator.unmap_volume.side_effect = [array_errors.VolumeNotFoundError("vol")] enter.return_value = self.mediator self.servicer.ControllerUnpublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.NOT_FOUND) context = utils.FakeContext() self.mediator.unmap_volume.side_effect = [array_errors.HostNotFoundError("host")] enter.return_value = self.mediator self.servicer.ControllerUnpublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.NOT_FOUND) context = utils.FakeContext() self.mediator.unmap_volume.side_effect = [array_errors.UnMappingError("", "", "")] enter.return_value = self.mediator self.servicer.ControllerUnpublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INTERNAL) context = utils.FakeContext() self.mediator.unmap_volume.side_effect = [array_errors.VolumeAlreadyUnmappedError("")] enter.return_value = self.mediator self.servicer.ControllerUnpublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK)
class TestControllerServerDeleteVolume(unittest.TestCase): @patch("controller.array_action.array_mediator_xiv.XIVArrayMediator._connect") def setUp(self, connect): self.fqdn = "fqdn" self.mediator = XIVArrayMediator("user", "password", self.fqdn) self.mediator.client = Mock() self.mediator.get_volume = Mock() self.servicer = ControllerServicer(self.fqdn) self.request = Mock() self.pool = 'pool1' self.request.secrets = {"username": "******", "password": "******", "management_address": "mg"} self.request.volume_id = "xiv:vol-id" @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__exit__") def test_delete_volume_with_wrong_secrets(self, a_enter, a_exit): a_enter.return_value = self.mediator context = utils.FakeContext() self.request.secrets = {"password": "******", "management_address": "mg"} res = self.servicer.DeleteVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INVALID_ARGUMENT, "username is missing in secrets") self.assertTrue("secret" in context.details) self.request.secrets = {"username": "******", "management_address": "mg"} res = self.servicer.DeleteVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INVALID_ARGUMENT, "password is missing in secrets") self.assertTrue("secret" in context.details) self.request.secrets = {"username": "******", "password": "******"} res = self.servicer.DeleteVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INVALID_ARGUMENT, "mgmt address is missing in secrets") self.assertTrue("secret" in context.details) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__exit__") def test_delete_volume_invalid_volume_id(self, a_enter, a_exit): a_enter.return_value = self.mediator context = utils.FakeContext() self.request.volume_id = "wrong_id" res = self.servicer.DeleteVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__exit__") def test_delete_volume_with_array_connection_exception(self, a_enter, a_exit): a_enter.side_effect = [Exception("a_enter error")] context = utils.FakeContext() res = self.servicer.DeleteVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INTERNAL, "array connection internal error") self.assertTrue("a_enter error" in context.details) @patch("controller.array_action.array_mediator_xiv.XIVArrayMediator.delete_volume") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def delete_volume_returns_error(self, a_enter, delete_volume, error, return_code): a_enter.return_value = self.mediator delete_volume.side_effect = [error] context = utils.FakeContext() res = self.servicer.DeleteVolume(self.request, context) self.assertEqual(context.code, return_code) if return_code != grpc.StatusCode.OK: msg = str(error) self.assertTrue(msg in context.details, "msg : {0} is not in : {1}".format(msg, context.details)) def test_delete_volume_with_volume_not_found_error(self, ): self.delete_volume_returns_error(error=array_errors.VolumeNotFoundError("vol"), return_code=grpc.StatusCode.OK) def test_delete_volume_with_delete_volume_other_exception(self): self.delete_volume_returns_error(error=Exception("error"), return_code=grpc.StatusCode.INTERNAL) @patch("controller.array_action.array_mediator_xiv.XIVArrayMediator.delete_volume") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def test_delete_volume_succeeds(self, a_enter, delete_volume): a_enter.return_value = self.mediator context = utils.FakeContext() res = self.servicer.DeleteVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK)
class TestControllerServerPublishVolume(unittest.TestCase): @patch("controller.array_action.array_mediator_xiv.XIVArrayMediator._connect") def setUp(self, connect): self.fqdn = "fqdn" self.hostname = "hostname" self.mediator = XIVArrayMediator("user", "password", self.fqdn) self.mediator.client = Mock() self.mediator.get_host_by_host_identifiers = Mock() self.mediator.get_host_by_host_identifiers.return_value = self.hostname, ["iscsi"] self.mediator.get_volume_mappings = Mock() self.mediator.get_volume_mappings.return_value = {} self.mediator.map_volume = Mock() self.mediator.map_volume.return_value = 1 self.mediator.get_array_iqns = Mock() self.mediator.get_array_iqns.return_value = "array-iqn" self.servicer = ControllerServicer(self.fqdn) self.request = Mock() arr_type = XIVArrayMediator.array_type self.request.volume_id = "{}:wwn1".format(arr_type) self.request.node_id = "hostname;iqn.1994-05.com.redhat:686358c930fe;500143802426baf4" self.request.readonly = False self.request.readonly = False self.request.secrets = {"username": "******", "password": "******", "management_address": "mg"} self.request.volume_context = {} caps = Mock() caps.mount = Mock() caps.mount.fs_type = "ext4" access_types = csi_pb2.VolumeCapability.AccessMode caps.access_mode.mode = access_types.SINGLE_NODE_WRITER self.request.volume_capability = caps @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def test_publish_volume_success(self, enter): enter.return_value = self.mediator context = utils.FakeContext() self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK) @patch("controller.controller_server.utils.validate_publish_volume_request") def test_publish_volume_validateion_exception(self, publish_validation): publish_validation.side_effect = [controller_errors.ValidationException("msg")] context = utils.FakeContext() self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INVALID_ARGUMENT) self.assertTrue("msg" in context.details) def test_publish_volume_wrong_volume_id(self): self.request.volume_id = "some-wrong-id-format" context = utils.FakeContext() self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.NOT_FOUND) def test_publish_volume_wrong_node_id(self): self.request.node_id = "some-wrong-id-format" context = utils.FakeContext() self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.NOT_FOUND) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def test_publish_volume_get_host_by_host_identifiers_exception(self, enter): context = utils.FakeContext() self.mediator.get_host_by_host_identifiers = Mock() self.mediator.get_host_by_host_identifiers.side_effect = [array_errors.MultipleHostsFoundError("", "")] enter.return_value = self.mediator self.servicer.ControllerPublishVolume(self.request, context) self.assertTrue("Multiple hosts" in context.details) self.assertEqual(context.code, grpc.StatusCode.INTERNAL) self.mediator.get_host_by_host_identifiers.side_effect = [array_errors.HostNotFoundError("")] enter.return_value = self.mediator self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.NOT_FOUND) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def test_publish_volume_get_volume_mappings_one_map_for_existing_host(self, enter): context = utils.FakeContext() self.mediator.get_volume_mappings = Mock() self.mediator.get_volume_mappings.return_value = {self.hostname: 2} enter.return_value = self.mediator res = self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK) self.assertEqual(res.publish_context["PUBLISH_CONTEXT_LUN"], '2') self.assertEqual(res.publish_context["PUBLISH_CONTEXT_CONNECTIVITY"], "iscsi") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def test_publish_volume_with_connectivity_type_fc(self, enter): context = utils.FakeContext() self.mediator.get_host_by_host_identifiers.return_value = self.hostname, ["iscsi", "fc"] self.mediator.get_array_fc_wwns = Mock() self.mediator.get_array_fc_wwns.return_value = ["500143802426baf4"] self.mediator.get_array_iqns = Mock() self.mediator.get_array_iqns.return_value = [ "iqn.1994-05.com.redhat:686358c930fe"] enter.return_value = self.mediator res = self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK) self.assertEqual(res.publish_context["PUBLISH_CONTEXT_LUN"], '1') self.assertEqual(res.publish_context["PUBLISH_CONTEXT_CONNECTIVITY"], "fc") self.assertEqual(res.publish_context["PUBLISH_CONTEXT_ARRAY_FC_INITIATORS"], "500143802426baf4") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def test_publish_volume_with_connectivity_type_iscsi(self, enter): context = utils.FakeContext() self.mediator.get_host_by_host_identifiers.return_value = self.hostname, ["iscsi"] self.mediator.get_array_iqns = Mock() self.mediator.get_array_iqns.return_value = ["iqn.1994-05.com.redhat:686358c930fe"] self.mediator.get_array_fc_wwns = Mock() self.mediator.get_array_fc_wwns.return_value = ["500143802426baf4"] enter.return_value = self.mediator res = self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK) self.assertEqual(res.publish_context["PUBLISH_CONTEXT_LUN"], '1') self.assertEqual(res.publish_context["PUBLISH_CONTEXT_CONNECTIVITY"], "iscsi") self.assertEqual( res.publish_context["PUBLISH_CONTEXT_ARRAY_IQN"], "iqn.1994-05.com.redhat:686358c930fe") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def test_publish_volume_with_node_id_only_has_iqns(self, enter): context = utils.FakeContext() self.request.node_id = "hostname;iqn.1994-05.com.redhat:686358c930fe;" self.mediator.get_host_by_host_identifiers.return_value = self.hostname, ["iscsi"] self.mediator.get_array_iqns = Mock() self.mediator.get_array_iqns.return_value = [ "iqn.1994-05.com.redhat:686358c930fe"] enter.return_value = self.mediator res = self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK) self.assertEqual(res.publish_context["PUBLISH_CONTEXT_LUN"], '1') self.assertEqual(res.publish_context["PUBLISH_CONTEXT_CONNECTIVITY"], "iscsi") self.assertEqual( res.publish_context["PUBLISH_CONTEXT_ARRAY_IQN"], "iqn.1994-05.com.redhat:686358c930fe") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def test_publish_volume_with_node_id_only_has_wwns(self, enter): context = utils.FakeContext() self.request.node_id = "hostname;;500143802426baf4" self.mediator.get_host_by_host_identifiers.return_value = self.hostname, ["fc"] self.mediator.get_array_fc_wwns = Mock() self.mediator.get_array_fc_wwns.return_value = ["500143802426baf4"] enter.return_value = self.mediator res = self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK) self.assertEqual(res.publish_context["PUBLISH_CONTEXT_LUN"], '1') self.assertEqual(res.publish_context["PUBLISH_CONTEXT_CONNECTIVITY"], "fc") self.assertEqual( res.publish_context["PUBLISH_CONTEXT_ARRAY_FC_INITIATORS"], "500143802426baf4") self.request.node_id = "hostname;;500143802426baf4:500143806626bae2" self.mediator.get_host_by_host_identifiers.return_value = self.hostname, ["fc"] self.mediator.get_array_fc_wwns = Mock() self.mediator.get_array_fc_wwns.return_value = ["500143802426baf4", "500143806626bae2"] enter.return_value = self.mediator res = self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK) self.assertEqual(res.publish_context["PUBLISH_CONTEXT_LUN"], '1') self.assertEqual(res.publish_context["PUBLISH_CONTEXT_CONNECTIVITY"], "fc") self.assertEqual( res.publish_context["PUBLISH_CONTEXT_ARRAY_FC_INITIATORS"], "500143802426baf4,500143806626bae2") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def test_publish_volume_get_volume_mappings_one_map_for_other_host(self, enter): context = utils.FakeContext() self.mediator.get_volume_mappings = Mock() self.mediator.get_volume_mappings.return_value = {"other-hostname": 3} enter.return_value = self.mediator self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.FAILED_PRECONDITION) self.assertTrue("Volume is already mapped" in context.details) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def test_publish_volume_get_volume_mappings_more_then_one_mapping(self, enter): context = utils.FakeContext() self.mediator.get_volume_mappings = Mock() self.mediator.get_volume_mappings.return_value = {"other-hostname": 3, self.hostname: 4} enter.return_value = self.mediator self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.FAILED_PRECONDITION) self.assertTrue("Volume is already mapped" in context.details) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def test_publish_volume_map_volume_excpetions(self, enter): context = utils.FakeContext() self.mediator.map_volume.side_effect = [array_errors.PermissionDeniedError("msg")] enter.return_value = self.mediator self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.PERMISSION_DENIED) self.mediator.map_volume.side_effect = [array_errors.VolumeNotFoundError("vol")] enter.return_value = self.mediator self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.NOT_FOUND) self.mediator.map_volume.side_effect = [array_errors.HostNotFoundError("host")] enter.return_value = self.mediator self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.NOT_FOUND) self.mediator.map_volume.side_effect = [array_errors.MappingError("", "", "")] enter.return_value = self.mediator self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INTERNAL) @patch.object(XIVArrayMediator, "MAX_LUN_NUMBER", 3) @patch.object(XIVArrayMediator, "MIN_LUN_NUMBER", 1) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def test_publish_volume_map_volume_lun_already_in_use(self, enter): context = utils.FakeContext() self.mediator.map_volume.side_effect = [array_errors.LunAlreadyInUseError("", ""), 2] self.mediator.map_volume.get_array_iqns.return_value = "array-iqn" enter.return_value = self.mediator res = self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK) self.assertEqual(res.publish_context["PUBLISH_CONTEXT_LUN"], '2') self.assertEqual(res.publish_context["PUBLISH_CONTEXT_CONNECTIVITY"], "iscsi") self.mediator.map_volume.side_effect = [ array_errors.LunAlreadyInUseError("", ""), 2] self.mediator.get_host_by_host_identifiers = Mock() self.mediator.get_host_by_host_identifiers.return_value = self.hostname, ["fc"] self.mediator.get_array_fc_wwns = Mock() self.mediator.get_array_fc_wwns.return_value = ["500143802426baf4"] enter.return_value = self.mediator res = self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK) self.assertEqual(res.publish_context["PUBLISH_CONTEXT_LUN"], '2') self.assertEqual(res.publish_context["PUBLISH_CONTEXT_CONNECTIVITY"], "fc") self.mediator.map_volume.side_effect = [array_errors.LunAlreadyInUseError("", ""), array_errors.LunAlreadyInUseError("", ""), 2] enter.return_value = self.mediator self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK) self.assertEqual(res.publish_context["PUBLISH_CONTEXT_LUN"], '2') self.assertEqual(res.publish_context["PUBLISH_CONTEXT_CONNECTIVITY"], "fc") self.mediator.map_volume.side_effect = [ array_errors.LunAlreadyInUseError("", "")] * (self.mediator.max_lun_retries + 1) enter.return_value = self.mediator self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.RESOURCE_EXHAUSTED)
class TestControllerServerCreateVolume(unittest.TestCase): @patch("controller.array_action.array_mediator_xiv.XIVArrayMediator._connect") def setUp(self, connect): self.fqdn = "fqdn" self.mediator = XIVArrayMediator("user", "password", self.fqdn) self.mediator.client = Mock() self.mediator.get_volume = Mock() self.mediator.get_volume.side_effect = [array_errors.VolumeNotFoundError("vol")] self.servicer = ControllerServicer(self.fqdn) self.request = Mock() caps = Mock() caps.mount = Mock() caps.mount.fs_type = "ext4" access_types = csi_pb2.VolumeCapability.AccessMode caps.access_mode.mode = access_types.SINGLE_NODE_WRITER self.request.volume_capabilities = [caps] self.pool = 'pool1' self.request.secrets = {"username": "******", "password": "******", "management_address": "mg"} self.request.parameters = {"pool": self.pool} self.capacity_bytes = 10 self.request.capacity_range.required_bytes = self.capacity_bytes self.request.name = vol_name @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__exit__") def test_create_volume_with_empty_name(self, a_enter, a_exit): a_enter.return_value = self.mediator self.request.name = "" context = utils.FakeContext() res = self.servicer.CreateVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INVALID_ARGUMENT) self.assertTrue("name" in context.details) self.assertEqual(res, csi_pb2.CreateVolumeResponse()) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.detect_array_type") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__exit__") def test_create_volume_succeeds(self, a_exit, a_enter, array_type): a_enter.return_value = self.mediator context = utils.FakeContext() self.mediator.create_volume = Mock() self.mediator.create_volume.return_value = utils.get_mock_mediator_response_volume(10, "vol", "wwn", "xiv") array_type.return_value = "a9k" res = self.servicer.CreateVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK) self.mediator.get_volume.assert_called_once_with(vol_name) self.mediator.create_volume.assert_called_once_with(vol_name, 10, {}, 'pool1') @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.detect_array_type") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__exit__") def test_create_volume_with_wrong_secrets(self, a_enter, a_exit, array_type): a_enter.return_value = self.mediator context = utils.FakeContext() self.request.secrets = {"password": "******", "management_address": "mg"} self.servicer.CreateVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INVALID_ARGUMENT, "username is missing in secrets") self.assertTrue("secret" in context.details) self.request.secrets = {"username": "******", "management_address": "mg"} self.servicer.CreateVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INVALID_ARGUMENT, "password is missing in secrets") self.assertTrue("secret" in context.details) self.request.secrets = {"username": "******", "password": "******"} self.servicer.CreateVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INVALID_ARGUMENT, "mgmt address is missing in secrets") self.assertTrue("secret" in context.details) self.request.secrets = [] @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.detect_array_type") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__exit__") def test_create_volume_with_wrong_parameters(self, a_enter, a_exit, array_type): a_enter.return_value = self.mediator context = utils.FakeContext() self.request.parameters = {"pool": "pool1"} res = self.servicer.CreateVolume(self.request, context) self.assertNotEqual(context.code, grpc.StatusCode.INVALID_ARGUMENT) self.request.parameters = {"capabilities": ""} res = self.servicer.CreateVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INVALID_ARGUMENT, "capacity is missing in secrets") self.assertEqual(context.code, grpc.StatusCode.INVALID_ARGUMENT, "pool parameter is missing") self.assertTrue("parameter" in context.details) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__exit__") def test_create_volume_with_wrong_volume_capabilities(self, a_enter, a_exit): a_enter.return_value = self.mediator context = utils.FakeContext() caps = Mock() caps.mount = Mock() caps.mount.fs_type = "ext42" access_types = csi_pb2.VolumeCapability.AccessMode caps.access_mode.mode = access_types.SINGLE_NODE_WRITER self.request.volume_capabilities = [caps] res = self.servicer.CreateVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INVALID_ARGUMENT, "wrong fs_type") self.assertTrue("fs_type" in context.details) caps.mount.fs_type = "ext4" caps.access_mode.mode = access_types.MULTI_NODE_SINGLE_WRITER self.request.volume_capabilities = [caps] res = self.servicer.CreateVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INVALID_ARGUMENT, "wrong access_mode") self.assertTrue("access mode" in context.details) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.detect_array_type") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__exit__") def test_create_volume_with_array_connection_exception(self, a_enter, a_exit, array_type): a_enter.side_effect = [Exception("error")] context = utils.FakeContext() res = self.servicer.CreateVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INTERNAL, "connection error occured in array_connection") self.assertTrue("error" in context.details) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.detect_array_type") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__exit__") def test_create_volume_with_get_array_type_exception(self, a_enter, a_exit, array_type): a_enter.return_value = self.mediator context = utils.FakeContext() array_type.side_effect = [array_errors.FailedToFindStorageSystemType("endpoint")] res = self.servicer.CreateVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INTERNAL, "failed to find storage system") msg = array_errors.FailedToFindStorageSystemType("endpoint").message self.assertTrue(msg in context.details) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.detect_array_type") @patch("controller.array_action.array_mediator_xiv.XIVArrayMediator.get_volume") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def test_create_volume_get_volume_exception(self, a_enter, get_volume, array_type): a_enter.return_value = self.mediator self.mediator.get_volume.side_effect = [Exception("error")] context = utils.FakeContext() res = self.servicer.CreateVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INTERNAL) self.assertTrue("error" in context.details) self.mediator.get_volume.assert_called_once_with(vol_name) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.detect_array_type") @patch("controller.array_action.array_mediator_xiv.XIVArrayMediator.get_volume") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def test_create_volume_with_get_volume_illegal_object_name_exception(self, a_enter, get_volume, array_type): a_enter.return_value = self.mediator self.mediator.get_volume.side_effect = [array_errors.IllegalObjectName("vol")] context = utils.FakeContext() res = self.servicer.CreateVolume(self.request, context) msg = array_errors.IllegalObjectName("vol").message self.assertEqual(context.code, grpc.StatusCode.INVALID_ARGUMENT) self.assertTrue(msg in context.details) self.mediator.get_volume.assert_called_once_with(vol_name) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.detect_array_type") @patch("controller.array_action.array_mediator_xiv.XIVArrayMediator.create_volume") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") def create_volume_returns_error(self, a_enter, create_volume, array_type, return_code, err): a_enter.return_value = self.mediator create_volume.side_effect = [err] context = utils.FakeContext() res = self.servicer.CreateVolume(self.request, context) msg = str(err) self.assertEqual(context.code, return_code) self.assertTrue(msg in context.details) self.mediator.get_volume.assert_called_once_with(vol_name) self.mediator.create_volume.assert_called_once_with(vol_name, self.capacity_bytes, {}, self.pool) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.detect_array_type") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__exit__") def test_create_volume_cuts_name_if_its_too_long(self, a_exit, a_enter, array_type): a_enter.return_value = self.mediator context = utils.FakeContext() self.request.name = "a" * 128 self.mediator.create_volume = Mock() self.mediator.create_volume.return_value = utils.get_mock_mediator_response_volume(10, "vol", "wwn", "xiv") array_type.return_value = "a9k" res = self.servicer.CreateVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK) self.mediator.get_volume.assert_called_once_with("a" * self.mediator.max_vol_name_length) def test_create_volume_with_illegal_object_name_exception(self): self.create_volume_returns_error(return_code=grpc.StatusCode.INVALID_ARGUMENT, err=array_errors.IllegalObjectName("vol")) def test_create_volume_with_create_volume_with_volume_exsits_exception(self): self.create_volume_returns_error(return_code=grpc.StatusCode.ALREADY_EXISTS, err=array_errors.VolumeAlreadyExists("vol", "endpoint")) def test_create_volume_with_create_volume_with_pool_does_not_exist_exception(self): self.create_volume_returns_error(return_code=grpc.StatusCode.INVALID_ARGUMENT, err=array_errors.PoolDoesNotExist("pool1", "endpoint")) def test_create_volume_with_create_volume_with_pool_does_not_match_capabilities_exception(self): self.create_volume_returns_error(return_code=grpc.StatusCode.INVALID_ARGUMENT, err=array_errors.PoolDoesNotMatchCapabilities("pool1", "", "endpoint")) def test_create_volume_with_create_volume_with_capability_not_supported_exception(self): self.create_volume_returns_error(return_code=grpc.StatusCode.INVALID_ARGUMENT, err=array_errors.StorageClassCapabilityNotSupported(["cap"])) def test_create_volume_with_create_volume_with_other_exception(self): self.create_volume_returns_error(return_code=grpc.StatusCode.INTERNAL, err=Exception("error")) @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.detect_array_type") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__exit__") def test_create_volume_with_name_prefix(self, a_exit, a_enter, array_type): a_enter.return_value = self.mediator context = utils.FakeContext() self.request.name = "some_name" self.request.parameters[PARAMETERS_PREFIX] = "prefix" self.mediator.create_volume = Mock() self.mediator.create_volume.return_value = utils.get_mock_mediator_response_volume(10, "vol", "wwn", "xiv") array_type.return_value = "a9k" res = self.servicer.CreateVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK) self.mediator.create_volume.assert_called_once_with("prefix_some_name", 10, {}, "pool1") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.detect_array_type") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__enter__") @patch("controller.array_action.array_connection_manager.ArrayConnectionManager.__exit__") def test_create_volume_with_zero_size(self, a_exit, a_enter, array_type): a_enter.return_value = self.mediator context = utils.FakeContext() self.request.capacity_range.required_bytes = 0 self.mediator.create_volume = Mock() self.mediator.create_volume.return_value = utils.get_mock_mediator_response_volume(10, "vol", "wwn", "xiv") array_type.return_value = "a9k" res = self.servicer.CreateVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.OK) self.mediator.create_volume.assert_called_once_with(self.request.name, 1 * 1024 * 1024 * 1024, {}, "pool1")