diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml new file mode 100644 index 0000000..bb496d8 --- /dev/null +++ b/.github/workflows/pylint.yml @@ -0,0 +1,31 @@ +name: Run Lint Check via Pylint + +on: [push] + +jobs: + lint: + name: lint + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ['3.9', '3.10', '3.11', '3.12'] + + steps: + - name: Checkout the source code + uses: actions/checkout@v3 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: python -m pip install --upgrade pip && pip install pylint + + - name: Install requirements + run: | + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + + - name: Analyzing the code with pylint + run: pylint $(git ls-files '*.py') diff --git a/PyPowerFlex/__init__.py b/PyPowerFlex/__init__.py index bb4f88d..943951d 100644 --- a/PyPowerFlex/__init__.py +++ b/PyPowerFlex/__init__.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""This module is used for the initialization of PowerFlex Client.""" + +# pylint: disable=invalid-name,too-many-arguments,too-many-positional-arguments + from packaging import version from PyPowerFlex import configuration @@ -28,6 +32,12 @@ class PowerFlexClient: + """ + Client class for interacting with PowerFlex API. + + This class initializes the client with the provided configuration and provides + access to the various storage entities available in the PowerFlex system. + """ __slots__ = ( '__is_initialized', 'configuration', @@ -76,12 +86,18 @@ def __init__(self, def __getattr__(self, item): if not self.__is_initialized and item in self.__slots__: raise exceptions.ClientNotInitialized - return super(PowerFlexClient, self).__getattribute__(item) + return super().__getattribute__(item) def __add_storage_entity(self, attr_name, entity_class): setattr(self, attr_name, entity_class(self.token, self.configuration)) def initialize(self): + """ + Initializes the client. + + Raises: + PowerFlexClientException: If the PowerFlex API version is lower than 3.0. + """ self.configuration.validate() self.__add_storage_entity('device', objects.Device) self.__add_storage_entity('fault_set', objects.FaultSet) @@ -97,12 +113,16 @@ def initialize(self): self.__add_storage_entity('system', objects.System) self.__add_storage_entity('volume', objects.Volume) self.__add_storage_entity('utility', objects.PowerFlexUtility) - self.__add_storage_entity('replication_consistency_group', objects.ReplicationConsistencyGroup) + self.__add_storage_entity( + 'replication_consistency_group', + objects.ReplicationConsistencyGroup) self.__add_storage_entity('replication_pair', objects.ReplicationPair) self.__add_storage_entity('service_template', objects.ServiceTemplate) self.__add_storage_entity('managed_device', objects.ManagedDevice) self.__add_storage_entity('deployment', objects.Deployment) - self.__add_storage_entity('firmware_repository', objects.FirmwareRepository) + self.__add_storage_entity( + 'firmware_repository', + objects.FirmwareRepository) self.__add_storage_entity('host', objects.Host) utils.init_logger(self.configuration.log_level) if version.parse(self.system.api_version()) < version.Version('3.0'): diff --git a/PyPowerFlex/base_client.py b/PyPowerFlex/base_client.py index f289959..79ccb9d 100644 --- a/PyPowerFlex/base_client.py +++ b/PyPowerFlex/base_client.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""This module is the base client of the PowerFlex APIs.""" + +# pylint: disable=no-member,import-error,broad-exception-raised + import logging import requests @@ -26,6 +30,9 @@ class Request: + """ + This class contains the methods for making requests to the PowerFlex API. + """ GET = "get" POST = "post" PUT = "put" @@ -38,24 +45,46 @@ def __init__(self, token, configuration): @property def base_url(self): - return 'https://{address}:{port}/api'.format( - address=self.configuration.gateway_address, - port=self.configuration.gateway_port - ) + """ + Get the base URL for the PowerFlex API. + + Returns: + str: The base URL. + """ + return f'https://{self.configuration.gateway_address}:{self.configuration.gateway_port}/api' @property def auth_url(self): - return 'https://{address}:{port}/rest/auth'.format( - address=self.configuration.gateway_address, - port=self.configuration.gateway_port + """ + Get the authentication URL for the PowerFlex API. + + Returns: + str: The authentication URL. + """ + gateway_address = self.configuration.gateway_address + port = self.configuration.gateway_port + return ( + f"https://{gateway_address}:{port}/rest/auth" ) @property def headers(self): + """ + Get the headers for the PowerFlex API. + + Returns: + dict: The headers. + """ return {'content-type': 'application/json'} @property def verify_certificate(self): + """ + Get the verification status of the certificate for the PowerFlex API. + + Returns: + bool: The verification status. + """ verify_certificate = self.configuration.verify_certificate if ( self.configuration.verify_certificate @@ -65,12 +94,35 @@ def verify_certificate(self): return verify_certificate def get_auth_headers(self, request_type=None): + """ + Get the authentication headers for the PowerFlex API. + + Args: + request_type (str): The type of the request. + + Returns: + dict: The authentication headers. + """ if request_type == self.GET: - return {'Authorization': 'Bearer {0}'.format(self.token.get())} - return {'Authorization': 'Bearer {0}'.format(self.token.get()), - 'content-type': 'application/json'} + return {'Authorization': f'Bearer {self.token.get()}'} + return { + 'Authorization': f'Bearer {self.token.get()}', + 'content-type': 'application/json' + } def send_request(self, method, url, params=None, **url_params): + """ + Send a request to the PowerFlex API. + + Args: + method (str): The HTTP method. + url (str): The URL. + params (dict): The parameters. + url_params (dict): The URL parameters. + + Returns: + Response: The response object. + """ params = params or {} request_url = f"{self.base_url}{url.format(**url_params)}" version = self.login() @@ -80,7 +132,8 @@ def send_request(self, method, url, params=None, **url_params): 'timeout': self.configuration.timeout } if utils.is_version_3(version): - request_params['auth'] = (self.configuration.username, self.token.get()) + request_params['auth'] = ( + self.configuration.username, self.token.get()) del request_params['headers']['Authorization'] if method in [self.PUT, self.POST]: @@ -90,23 +143,76 @@ def send_request(self, method, url, params=None, **url_params): return response def send_get_request(self, url, params=None, **url_params): + """ + Send a GET request to the PowerFlex API. + + Args: + url (str): The URL. + params (dict): The parameters. + url_params (dict): The URL parameters. + + Returns: + tuple: The response object and the response content. + """ response = self.send_request(self.GET, url, params, **url_params) return response, response.json() def send_post_request(self, url, params=None, **url_params): + """ + Send a POST request to the PowerFlex API. + + Args: + url (str): The URL. + params (dict): The parameters. + url_params (dict): The URL parameters. + + Returns: + tuple: The response object and the response content. + """ response = self.send_request(self.POST, url, params, **url_params) return response, response.json() def send_put_request(self, url, params=None, **url_params): + """ + Send a PUT request to the PowerFlex API. + + Args: + url (str): The URL. + params (dict): The parameters. + url_params (dict): The URL parameters. + + Returns: + tuple: The response object and the response content. + """ response = self.send_request(self.PUT, url, params, **url_params) return response, response.json() def send_delete_request(self, url, params=None, **url_params): + """ + Send a DELETE request. + + Args: + url (str): The URL for the request. + params (dict, optional): The parameters for the request. Defaults to None. + + Returns: + The response from the request. + """ return self.send_request(self.DELETE, url, params, **url_params) def send_mdm_cluster_post_request(self, url, params=None, **url_params): + """ + Send a POST request for the MDM cluster. + + Args: + url (str): The URL for the request. + params (dict, optional): The parameters for the request. Defaults to None. + + Returns: + tuple: A tuple containing the response and the JSON content of the response. + """ if params is None: - params = dict() + params = {} response = None version = self.login() request_url = self.base_url + url.format(**url_params) @@ -125,8 +231,13 @@ def send_mdm_cluster_post_request(self, url, params=None, **url_params): self.logout(version) return r, response - # To perform login based on the API version def login(self): + """ + Perform login based on the API version. + + Returns: + str: The API version. + """ version = self.get_api_version() if utils.is_version_3(version=version): self._login() @@ -134,15 +245,22 @@ def login(self): self._appliance_login() return version - # To perform logout based on the API version def logout(self, version): + """ + Perform logout based on the API version. + """ if utils.is_version_3(version=version): self._logout() else: self._appliance_logout() - # Get the Current API version def get_api_version(self): + """ + Get the current API version. + + Returns: + dict: The JSON response containing the API version. + """ request_url = self.base_url + '/version' self._login() r = requests.get(request_url, @@ -154,12 +272,15 @@ def get_api_version(self): response = r.json() return response - # API Login method for 4.0 and above. def _appliance_login(self): + """ + Perform login for API version 4.0 and above. + """ request_url = self.auth_url + '/login' - payload = {"username": "%s" % self.configuration.username, - "password": "%s" % self.configuration.password - } + payload = { + "username": f"{self.configuration.username}", + "password": f"{self.configuration.password}" + } r = requests.post(request_url, headers=self.headers, json=payload, verify=self.verify_certificate, timeout=self.configuration.timeout @@ -173,14 +294,18 @@ def _appliance_login(self): self.token.set(token) self.__refresh_token = response['refresh_token'] - # API logout method for 4.0 and above. def _appliance_logout(self): + """ + Perform logout for API version 4.0 and above. + """ request_url = self.auth_url + '/logout' - data = {'refresh_token': '{0}'.format(self.__refresh_token)} - r = requests.post(request_url, headers=self.get_auth_headers(), json=data, - verify=self.verify_certificate, - timeout=self.configuration.timeout - ) + data = {'refresh_token': f'{self.__refresh_token}'} + r = requests.post( + request_url, + headers=self.get_auth_headers(), + json=data, + verify=self.verify_certificate, + timeout=self.configuration.timeout) if r.status_code != requests.codes.no_content: exc = exceptions.PowerFlexFailQuerying('token') @@ -190,24 +315,34 @@ def _appliance_logout(self): self.__refresh_token = None def _login(self): + """ + Perform login for API version below 4.0. + """ request_url = self.base_url + '/login' try: r = requests.get(request_url, - auth=( - self.configuration.username, - self.configuration.password - ), - verify=self.verify_certificate, - timeout=self.configuration.timeout) + auth=( + self.configuration.username, + self.configuration.password + ), + verify=self.verify_certificate, + timeout=self.configuration.timeout) r.raise_for_status() token = r.json() self.token.set(token) except requests.exceptions.RequestException as e: - error_msg = f'Login failed with error:{e.response.content}' if e.response else f'Login failed with error:{str(e)}' + error_msg = ( + f'Login failed with error: {e.response.content}' + if e.response + else f'Login failed with error: {str(e)}' + ) LOG.error(error_msg) - raise Exception(error_msg) + raise Exception(error_msg) from e def _logout(self): + """ + Perform logout for API version below 4.0. + """ token = self.token.get() if token: @@ -227,6 +362,9 @@ def _logout(self): class EntityRequest(Request): + """ + Base class for entity requests. + """ base_action_url = '/instances/{entity}::{entity_id}/action/{action}' base_entity_url = '/instances/{entity}::{entity_id}' base_entity_list_or_create_url = '/types/{entity}/instances' @@ -243,9 +381,24 @@ class EntityRequest(Request): @property def entity(self): + """ + Returns the entity name. + """ return self.entity_name or self.__class__.__name__ def _create_entity(self, params=None): + """ + Creates an entity. + + Args: + params (dict, optional): Parameters for the entity. + + Returns: + dict: The created entity. + + Raises: + PowerFlexFailCreating: If the entity fails to be created. + """ r, response = self.send_post_request( self.base_entity_list_or_create_url, entity=self.entity, @@ -260,6 +413,16 @@ def _create_entity(self, params=None): return self.get(entity_id=entity_id) def _delete_entity(self, entity_id, params=None): + """ + Deletes an entity. + + Args: + entity_id (str): The ID of the entity. + params (dict, optional): Parameters for the entity. + + Raises: + PowerFlexFailDeleting: If the entity fails to be deleted. + """ action = 'remove' + self.entity r, response = self.send_post_request(self.base_action_url, @@ -274,6 +437,20 @@ def _delete_entity(self, entity_id, params=None): raise exc def _rename_entity(self, action, entity_id, params=None): + """ + Renames an entity. + + Args: + action (str): The action to perform. + entity_id (str): The ID of the entity. + params (dict, optional): Parameters for the entity. + + Returns: + dict: The renamed entity. + + Raises: + PowerFlexFailRenaming: If the entity fails to be renamed. + """ r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, @@ -288,8 +465,22 @@ def _rename_entity(self, action, entity_id, params=None): return self.get(entity_id=entity_id) def get(self, entity_id=None, filter_fields=None, fields=None): + """ + Gets an entity. + + Args: + entity_id (str, optional): The ID of the entity. + filter_fields (dict, optional): Fields to filter. + fields (dict, optional): Fields to query. + + Returns: + dict: The entity. + + Raises: + PowerFlexFailQuerying: If the entity fails to be queried. + """ url = self.base_entity_list_or_create_url - url_params = dict(entity=self.entity) + url_params = {'entity': self.entity} if entity_id: url = self.base_entity_url @@ -312,22 +503,33 @@ def get(self, entity_id=None, filter_fields=None, fields=None): def get_related(self, entity_id, related, filter_fields=None, fields=None): - url_params = dict( - entity=self.entity, - entity_id=entity_id, - related=related - ) + """ + Gets related entities. + + Args: + entity_id (str): The ID of the entity. + related (str): The related entity. + filter_fields (dict, optional): Fields to filter. + fields (dict, optional): Fields to query. + + Returns: + dict: The related entities. + + Raises: + PowerFlexClientException: If the related entities fail to be queried. + """ + url_params = { + "entity": self.entity, + "entity_id": entity_id, + "related": related + } r, response = self.send_get_request(self.base_relationship_url, **url_params) if r.status_code != requests.codes.ok: msg = ( - 'Failed to query related {related} entities for PowerFlex ' - '{entity} with id {_id}.' - ' Error: {response}'.format(related=related, - entity=self.entity, - _id=entity_id, - response=response) + f"Failed to query related {related} entities for PowerFlex " + f"{self.entity} with id {entity_id}. Error: {response}" ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -337,8 +539,29 @@ def get_related(self, entity_id, related, filter_fields=None, response = utils.query_response_fields(response, fields) return response - def _perform_entity_operation_based_on_action(self, entity_id, action, - params=None, add_entity=True, **url_params): + def _perform_entity_operation_based_on_action( + self, + entity_id, + action, + params=None, + add_entity=True, + **url_params): + """ + Perform a specific action on an entity. + + Args: + entity_id (str): The ID of the entity. + action (str): The action to perform. + params (dict, optional): Additional parameters. + add_entity (bool, optional): Whether to add the entity to the action. + **url_params: Additional URL parameters. + + Raises: + exceptions.PowerFlexFailEntityOperation: If the entity operation fails. + + Returns: + dict: The response from the API. + """ if add_entity: action = action + self.entity @@ -349,12 +572,25 @@ def _perform_entity_operation_based_on_action(self, entity_id, action, params=params, **url_params) if r.status_code != requests.codes.ok: - exc = exceptions.PowerFlexFailEntityOperation(self.entity, entity_id, - action, response) + exc = exceptions.PowerFlexFailEntityOperation( + self.entity, entity_id, action, response) LOG.error(exc.message) raise exc def _query_selected_statistics(self, action, params=None): + """ + Query the selected statistics. + + Args: + action (str): The action to perform. + params (dict, optional): Additional parameters. + + Raises: + exceptions.PowerFlexFailQuerying: If the query fails. + + Returns: + dict: The response from the API. + """ r, response = self.send_post_request(self.base_type_special_action_url, action=action, entity=self.entity, diff --git a/PyPowerFlex/configuration.py b/PyPowerFlex/configuration.py index 2e9057e..5517ead 100644 --- a/PyPowerFlex/configuration.py +++ b/PyPowerFlex/configuration.py @@ -13,10 +13,16 @@ # License for the specific language governing permissions and limitations # under the License. -from PyPowerFlex import exceptions +"""This module is used for the configuration of the client.""" + +# pylint: disable=too-many-instance-attributes,too-many-arguments,too-many-positional-arguments,too-few-public-methods +from PyPowerFlex import exceptions class Configuration: + """ + Configuration class for the PyPowerFlex library. + """ def __init__(self, gateway_address=None, gateway_port=443, @@ -26,6 +32,9 @@ def __init__(self, certificate_path=None, timeout=120, log_level=None): + """ + Initializes the Configuration class. + """ self.gateway_address = gateway_address self.gateway_port = gateway_port self.username = username @@ -36,6 +45,11 @@ def __init__(self, self.log_level = log_level def validate(self): + """ + Validates the configuration. + + :raises exceptions.InvalidConfiguration: If any of the required parameters are not set. + """ if not all( [ self.gateway_address, diff --git a/PyPowerFlex/constants.py b/PyPowerFlex/constants.py index 98535bf..ee56ff7 100644 --- a/PyPowerFlex/constants.py +++ b/PyPowerFlex/constants.py @@ -13,96 +13,355 @@ # License for the specific language governing permissions and limitations # under the License. +"""This module contains the definitions of constants used in the code.""" + +# pylint: disable=too-few-public-methods class StoragePoolConstants: + """ + This class holds constants related to StoragePool. + """ DEFAULT_STATISTICS_PROPERTIES = [ - "backgroundScanFixedReadErrorCount","pendingMovingOutBckRebuildJobs", - "degradedHealthyCapacityInKb","activeMovingOutFwdRebuildJobs", - "bckRebuildWriteBwc","netFglUncompressedDataSizeInKb","primaryReadFromDevBwc","BackgroundScannedInMB","volumeIds", - "maxUserDataCapacityInKb","persistentChecksumBuilderProgress","rfcacheReadsSkippedAlignedSizeTooLarge", - "pendingMovingInRebalanceJobs","rfcacheWritesSkippedHeavyLoad","unusedCapacityInKb","userDataSdcReadLatency", - "totalReadBwc","numOfDeviceAtFaultRebuilds","totalWriteBwc","persistentChecksumCapacityInKb","rmPendingAllocatedInKb", - "numOfVolumes","rfcacheIosOutstanding","capacityAvailableForVolumeAllocationInKb","numOfMappedToAllVolumes", - "netThinUserDataCapacityInKb","backgroundScanFixedCompareErrorCount","volMigrationWriteBwc","thinAndSnapshotRatio", - "fglUserDataCapacityInKb","pendingMovingInEnterProtectedMaintenanceModeJobs","activeMovingInNormRebuildJobs", - "aggregateCompressionLevel","targetOtherLatency","netUserDataCapacityInKb","pendingMovingOutExitProtectedMaintenanceModeJobs", - "overallUsageRatio","volMigrationReadBwc","netCapacityInUseNoOverheadInKb","pendingMovingInBckRebuildJobs", - "rfcacheReadsSkippedInternalError","activeBckRebuildCapacityInKb","rebalanceCapacityInKb","pendingMovingInExitProtectedMaintenanceModeJobs", - "rfcacheReadsSkippedLowResources","rplJournalCapAllowed","thinCapacityInUseInKb","userDataSdcTrimLatency", - "activeMovingInEnterProtectedMaintenanceModeJobs","rfcacheWritesSkippedInternalError","netUserDataCapacityNoTrimInKb", - "rfcacheWritesSkippedCacheMiss","degradedFailedCapacityInKb","activeNormRebuildCapacityInKb","fglSparesInKb", - "snapCapacityInUseInKb","numOfMigratingVolumes","compressionRatio","rfcacheWriteMiss","primaryReadFromRmcacheBwc", - "migratingVtreeIds","numOfVtrees","userDataCapacityNoTrimInKb","rfacheReadHit","compressedDataCompressionRatio", - "rplUsedJournalCap","pendingMovingCapacityInKb","numOfSnapshots","pendingFwdRebuildCapacityInKb","tempCapacityInKb", - "totalFglMigrationSizeInKb","normRebuildCapacityInKb","logWrittenBlocksInKb","primaryWriteBwc","numOfThickBaseVolumes", - "enterProtectedMaintenanceModeReadBwc","activeRebalanceCapacityInKb","numOfReplicationJournalVolumes","rfcacheReadsSkippedLockIos", - "unreachableUnusedCapacityInKb","netProvisionedAddressesInKb","trimmedUserDataCapacityInKb","provisionedAddressesInKb", - "numOfVolumesInDeletion","pendingMovingOutFwdRebuildJobs","maxCapacityInKb","rmPendingThickInKb","protectedCapacityInKb", - "secondaryWriteBwc","normRebuildReadBwc","thinCapacityAllocatedInKb","netFglUserDataCapacityInKb","metadataOverheadInKb", - "rebalanceWriteBwc","primaryVacInKb","deviceIds","netSnapshotCapacityInKb","secondaryVacInKb", - "numOfDevices","rplTotalJournalCap","failedCapacityInKb","netMetadataOverheadInKb","activeMovingOutBckRebuildJobs", - "rfcacheReadsFromCache","activeMovingOutEnterProtectedMaintenanceModeJobs","enterProtectedMaintenanceModeCapacityInKb", - "pendingMovingInNormRebuildJobs","failedVacInKb","primaryReadBwc","fglUncompressedDataSizeInKb", - "fglCompressedDataSizeInKb","pendingRebalanceCapacityInKb","rfcacheAvgReadTime","semiProtectedCapacityInKb", - "pendingMovingOutEnterProtectedMaintenanceModeJobs","mgUserDdataCcapacityInKb","snapshotCapacityInKb", - "netMgUserDataCapacityInKb","fwdRebuildReadBwc","rfcacheWritesReceived","netUnusedCapacityInKb", - "protectedVacInKb","activeMovingRebalanceJobs","bckRebuildCapacityInKb","activeMovingInFwdRebuildJobs","netTrimmedUserDataCapacityInKb", - "pendingMovingRebalanceJobs","numOfMarkedVolumesForReplication","degradedHealthyVacInKb","semiProtectedVacInKb", - "userDataReadBwc","pendingBckRebuildCapacityInKb","capacityLimitInKb","vtreeIds","activeMovingCapacityInKb", - "targetWriteLatency","pendingExitProtectedMaintenanceModeCapacityInKb","rfcacheIosSkipped","userDataWriteBwc", - "inMaintenanceVacInKb","exitProtectedMaintenanceModeReadBwc","netFglSparesInKb","rfcacheReadsSkipped", - "activeExitProtectedMaintenanceModeCapacityInKb","activeMovingOutExitProtectedMaintenanceModeJobs","numOfUnmappedVolumes", - "tempCapacityVacInKb","volumeAddressSpaceInKb","currentFglMigrationSizeInKb","rfcacheWritesSkippedMaxIoSize", - "netMaxUserDataCapacityInKb","numOfMigratingVtrees","atRestCapacityInKb","rfacheWriteHit","bckRebuildReadBwc", - "rfcacheSourceDeviceWrites","spareCapacityInKb","enterProtectedMaintenanceModeWriteBwc","rfcacheIoErrors","inaccessibleCapacityInKb", - "normRebuildWriteBwc","capacityInUseInKb","rebalanceReadBwc","rfcacheReadsSkippedMaxIoSize","activeMovingInExitProtectedMaintenanceModeJobs", - "secondaryReadFromDevBwc","secondaryReadBwc","rfcacheWritesSkippedStuckIo","secondaryReadFromRmcacheBwc", - "inMaintenanceCapacityInKb","exposedCapacityInKb","netFglCompressedDataSizeInKb","userDataSdcWriteLatency","inUseVacInKb", - "fwdRebuildCapacityInKb","thickCapacityInUseInKb","backgroundScanReadErrorCount","activeMovingInRebalanceJobs", - "migratingVolumeIds","rfcacheWritesSkippedLowResources","capacityInUseNoOverheadInKb","exitProtectedMaintenanceModeWriteBwc", - "rfcacheSkippedUnlinedWrite","netCapacityInUseInKb","numOfOutgoingMigrations","rfcacheAvgWriteTime", - "pendingNormRebuildCapacityInKb","pendingMovingOutNormrebuildJobs","rfcacheSourceDeviceReads","rfcacheReadsPending", - "volumeAllocationLimitInKb","rfcacheReadsSkippedHeavyLoad","fwdRebuildWriteBwc","rfcacheReadMiss","targetReadLatency", - "userDataCapacityInKb","activeMovingInBckRebuildJobs","movingCapacityInKb","activeEnterProtectedMaintenanceModeCapacityInKb", - "backgroundScanCompareErrorCount","pendingMovingInFwdRebuildJobs","rfcacheReadsReceived","spSdsIds", - "pendingEnterProtectedMaintenanceModeCapacityInKb","vtreeAddresSpaceInKb","snapCapacityInUseOccupiedInKb", - "activeFwdRebuildCapacityInKb","rfcacheReadsSkippedStuckIo","activeMovingOutNormRebuildJobs","rfcacheWritePending", - "numOfThinBaseVolumes","degradedFailedVacInKb","userDataTrimBwc","numOfIncomingVtreeMigrations" - ] - - DEFAULT_STATISTICS_PROPERTIES_ABOVE_3_5 = ["thinCapacityAllocatedInKm","thinUserDataCapacityInKb"] + "backgroundScanFixedReadErrorCount", + "pendingMovingOutBckRebuildJobs", + "degradedHealthyCapacityInKb", + "activeMovingOutFwdRebuildJobs", + "bckRebuildWriteBwc", + "netFglUncompressedDataSizeInKb", + "primaryReadFromDevBwc", + "BackgroundScannedInMB", + "volumeIds", + "maxUserDataCapacityInKb", + "persistentChecksumBuilderProgress", + "rfcacheReadsSkippedAlignedSizeTooLarge", + "pendingMovingInRebalanceJobs", + "rfcacheWritesSkippedHeavyLoad", + "unusedCapacityInKb", + "userDataSdcReadLatency", + "totalReadBwc", + "numOfDeviceAtFaultRebuilds", + "totalWriteBwc", + "persistentChecksumCapacityInKb", + "rmPendingAllocatedInKb", + "numOfVolumes", + "rfcacheIosOutstanding", + "capacityAvailableForVolumeAllocationInKb", + "numOfMappedToAllVolumes", + "netThinUserDataCapacityInKb", + "backgroundScanFixedCompareErrorCount", + "volMigrationWriteBwc", + "thinAndSnapshotRatio", + "fglUserDataCapacityInKb", + "pendingMovingInEnterProtectedMaintenanceModeJobs", + "activeMovingInNormRebuildJobs", + "aggregateCompressionLevel", + "targetOtherLatency", + "netUserDataCapacityInKb", + "pendingMovingOutExitProtectedMaintenanceModeJobs", + "overallUsageRatio", + "volMigrationReadBwc", + "netCapacityInUseNoOverheadInKb", + "pendingMovingInBckRebuildJobs", + "rfcacheReadsSkippedInternalError", + "activeBckRebuildCapacityInKb", + "rebalanceCapacityInKb", + "pendingMovingInExitProtectedMaintenanceModeJobs", + "rfcacheReadsSkippedLowResources", + "rplJournalCapAllowed", + "thinCapacityInUseInKb", + "userDataSdcTrimLatency", + "activeMovingInEnterProtectedMaintenanceModeJobs", + "rfcacheWritesSkippedInternalError", + "netUserDataCapacityNoTrimInKb", + "rfcacheWritesSkippedCacheMiss", + "degradedFailedCapacityInKb", + "activeNormRebuildCapacityInKb", + "fglSparesInKb", + "snapCapacityInUseInKb", + "numOfMigratingVolumes", + "compressionRatio", + "rfcacheWriteMiss", + "primaryReadFromRmcacheBwc", + "migratingVtreeIds", + "numOfVtrees", + "userDataCapacityNoTrimInKb", + "rfacheReadHit", + "compressedDataCompressionRatio", + "rplUsedJournalCap", + "pendingMovingCapacityInKb", + "numOfSnapshots", + "pendingFwdRebuildCapacityInKb", + "tempCapacityInKb", + "totalFglMigrationSizeInKb", + "normRebuildCapacityInKb", + "logWrittenBlocksInKb", + "primaryWriteBwc", + "numOfThickBaseVolumes", + "enterProtectedMaintenanceModeReadBwc", + "activeRebalanceCapacityInKb", + "numOfReplicationJournalVolumes", + "rfcacheReadsSkippedLockIos", + "unreachableUnusedCapacityInKb", + "netProvisionedAddressesInKb", + "trimmedUserDataCapacityInKb", + "provisionedAddressesInKb", + "numOfVolumesInDeletion", + "pendingMovingOutFwdRebuildJobs", + "maxCapacityInKb", + "rmPendingThickInKb", + "protectedCapacityInKb", + "secondaryWriteBwc", + "normRebuildReadBwc", + "thinCapacityAllocatedInKb", + "netFglUserDataCapacityInKb", + "metadataOverheadInKb", + "rebalanceWriteBwc", + "primaryVacInKb", + "deviceIds", + "netSnapshotCapacityInKb", + "secondaryVacInKb", + "numOfDevices", + "rplTotalJournalCap", + "failedCapacityInKb", + "netMetadataOverheadInKb", + "activeMovingOutBckRebuildJobs", + "rfcacheReadsFromCache", + "activeMovingOutEnterProtectedMaintenanceModeJobs", + "enterProtectedMaintenanceModeCapacityInKb", + "pendingMovingInNormRebuildJobs", + "failedVacInKb", + "primaryReadBwc", + "fglUncompressedDataSizeInKb", + "fglCompressedDataSizeInKb", + "pendingRebalanceCapacityInKb", + "rfcacheAvgReadTime", + "semiProtectedCapacityInKb", + "pendingMovingOutEnterProtectedMaintenanceModeJobs", + "mgUserDdataCcapacityInKb", + "snapshotCapacityInKb", + "netMgUserDataCapacityInKb", + "fwdRebuildReadBwc", + "rfcacheWritesReceived", + "netUnusedCapacityInKb", + "protectedVacInKb", + "activeMovingRebalanceJobs", + "bckRebuildCapacityInKb", + "activeMovingInFwdRebuildJobs", + "netTrimmedUserDataCapacityInKb", + "pendingMovingRebalanceJobs", + "numOfMarkedVolumesForReplication", + "degradedHealthyVacInKb", + "semiProtectedVacInKb", + "userDataReadBwc", + "pendingBckRebuildCapacityInKb", + "capacityLimitInKb", + "vtreeIds", + "activeMovingCapacityInKb", + "targetWriteLatency", + "pendingExitProtectedMaintenanceModeCapacityInKb", + "rfcacheIosSkipped", + "userDataWriteBwc", + "inMaintenanceVacInKb", + "exitProtectedMaintenanceModeReadBwc", + "netFglSparesInKb", + "rfcacheReadsSkipped", + "activeExitProtectedMaintenanceModeCapacityInKb", + "activeMovingOutExitProtectedMaintenanceModeJobs", + "numOfUnmappedVolumes", + "tempCapacityVacInKb", + "volumeAddressSpaceInKb", + "currentFglMigrationSizeInKb", + "rfcacheWritesSkippedMaxIoSize", + "netMaxUserDataCapacityInKb", + "numOfMigratingVtrees", + "atRestCapacityInKb", + "rfacheWriteHit", + "bckRebuildReadBwc", + "rfcacheSourceDeviceWrites", + "spareCapacityInKb", + "enterProtectedMaintenanceModeWriteBwc", + "rfcacheIoErrors", + "inaccessibleCapacityInKb", + "normRebuildWriteBwc", + "capacityInUseInKb", + "rebalanceReadBwc", + "rfcacheReadsSkippedMaxIoSize", + "activeMovingInExitProtectedMaintenanceModeJobs", + "secondaryReadFromDevBwc", + "secondaryReadBwc", + "rfcacheWritesSkippedStuckIo", + "secondaryReadFromRmcacheBwc", + "inMaintenanceCapacityInKb", + "exposedCapacityInKb", + "netFglCompressedDataSizeInKb", + "userDataSdcWriteLatency", + "inUseVacInKb", + "fwdRebuildCapacityInKb", + "thickCapacityInUseInKb", + "backgroundScanReadErrorCount", + "activeMovingInRebalanceJobs", + "migratingVolumeIds", + "rfcacheWritesSkippedLowResources", + "capacityInUseNoOverheadInKb", + "exitProtectedMaintenanceModeWriteBwc", + "rfcacheSkippedUnlinedWrite", + "netCapacityInUseInKb", + "numOfOutgoingMigrations", + "rfcacheAvgWriteTime", + "pendingNormRebuildCapacityInKb", + "pendingMovingOutNormrebuildJobs", + "rfcacheSourceDeviceReads", + "rfcacheReadsPending", + "volumeAllocationLimitInKb", + "rfcacheReadsSkippedHeavyLoad", + "fwdRebuildWriteBwc", + "rfcacheReadMiss", + "targetReadLatency", + "userDataCapacityInKb", + "activeMovingInBckRebuildJobs", + "movingCapacityInKb", + "activeEnterProtectedMaintenanceModeCapacityInKb", + "backgroundScanCompareErrorCount", + "pendingMovingInFwdRebuildJobs", + "rfcacheReadsReceived", + "spSdsIds", + "pendingEnterProtectedMaintenanceModeCapacityInKb", + "vtreeAddresSpaceInKb", + "snapCapacityInUseOccupiedInKb", + "activeFwdRebuildCapacityInKb", + "rfcacheReadsSkippedStuckIo", + "activeMovingOutNormRebuildJobs", + "rfcacheWritePending", + "numOfThinBaseVolumes", + "degradedFailedVacInKb", + "userDataTrimBwc", + "numOfIncomingVtreeMigrations"] + + DEFAULT_STATISTICS_PROPERTIES_ABOVE_3_5 = [ + "thinCapacityAllocatedInKm", "thinUserDataCapacityInKb"] + class VolumeConstants: + """ + This class holds constants related to Volume. + """ DEFAULT_STATISTICS_PROPERTIES = [ - "rplUsedJournalCap","replicationState","numOfChildVolumes","userDataWriteBwc","rplTotalJournalCap","initiatorSdcId", - "userDataSdcReadLatency","userDataSdcTrimLatency","mappedSdcIds","registrationKey","registrationKeys", - "descendantVolumeIds","numOfMappedSdcs","reservationType","userDataReadBwc","numOfDescendantVolumes", - "replicationJournalVolume","userDataTrimBwc","childVolumeIds","userDataSdcWriteLatency" - ] + "rplUsedJournalCap", + "replicationState", + "numOfChildVolumes", + "userDataWriteBwc", + "rplTotalJournalCap", + "initiatorSdcId", + "userDataSdcReadLatency", + "userDataSdcTrimLatency", + "mappedSdcIds", + "registrationKey", + "registrationKeys", + "descendantVolumeIds", + "numOfMappedSdcs", + "reservationType", + "userDataReadBwc", + "numOfDescendantVolumes", + "replicationJournalVolume", + "userDataTrimBwc", + "childVolumeIds", + "userDataSdcWriteLatency"] + class RCGConstants: + """ + This class holds constants related to RCG. + """ DEFAULT_STATISTICS_PROPERTIES = [ - "rcgLocalReadBwc","initialCopyNumPairs","lagPersistentInMillis","rplRemoteUserBwc","rplApplyLatency", - "lagReceivedInMillis","nextPlannedCycle","lagPersistentSkew","lastSadBarrierId","readyForTransmit","initialCopyTransmit", - "rplLocalUserBwc","rplPairIds","numOfRplPairs","rplReceiveLatency","rplLocalApplyBwc","lagAppliedInMillis", - "lastCsadBarrierId","lastCompletedPeriodicBarrier","lastAppliedBarrierId","rplRemoteApplyBwc","readyForApply", - "initialCopyApply","lagReceivedSkew","initialCopyProgress","rcgLocalWriteBwc","notReadyForTransmit","rplCgRpoCompliance", - "notReadyForApply","rplTransmitBwc","lastCradBarrierId","lagAppliedSkew","lastRadBarrierId","rplReceiveBwc","rcgRemoteWriteBwc", - "rcgRemoteReadBwc","rplTransmitLatency" - ] + "rcgLocalReadBwc", + "initialCopyNumPairs", + "lagPersistentInMillis", + "rplRemoteUserBwc", + "rplApplyLatency", + "lagReceivedInMillis", + "nextPlannedCycle", + "lagPersistentSkew", + "lastSadBarrierId", + "readyForTransmit", + "initialCopyTransmit", + "rplLocalUserBwc", + "rplPairIds", + "numOfRplPairs", + "rplReceiveLatency", + "rplLocalApplyBwc", + "lagAppliedInMillis", + "lastCsadBarrierId", + "lastCompletedPeriodicBarrier", + "lastAppliedBarrierId", + "rplRemoteApplyBwc", + "readyForApply", + "initialCopyApply", + "lagReceivedSkew", + "initialCopyProgress", + "rcgLocalWriteBwc", + "notReadyForTransmit", + "rplCgRpoCompliance", + "notReadyForApply", + "rplTransmitBwc", + "lastCradBarrierId", + "lagAppliedSkew", + "lastRadBarrierId", + "rplReceiveBwc", + "rcgRemoteWriteBwc", + "rcgRemoteReadBwc", + "rplTransmitLatency"] DEFAULT_STATISTICS_PROPERTIES_ABOVE_3_5 = [ - "rcgLocalWriteBwc","nextPlannedCycle","rplTransmitLatency","lagReceivedInMillis","rcgRemoteReadBwc","lastCradBarrierId", - "lagAppliedSkew","readyForApply","rplUsedJournalCapacityDst","rplReceiveBwc","lastSadBarrierId","isInSlimMode", - "lastRadBarrierId","lastAppliedBarrierId","initialCopyTransmit","initialCopyNumPairs","lagAppliedInMillis", - "lastCompletedPeriodicBarrier","rplLocalApplyBwc","rcgLocalReadBwc","notReadyForTransmit","rplCgRpoCompliance", - "freezeTransmit","lagPersistentInMillis","lagReceivedSkew","notReadyForApply","initialCopyApply","rplPairIds", - "rplLocalUserBwc","numOfRplPairs","rplReceiveLatency","lastCsadBarrierId","rplRemoteApplyBwc","rcgRemoteWriteBwc", - "initialCopyProgress","lagPersistentSkew","rplSasBarriersBacklogSize","rplTransmitBwc","rplApplyLatency","readyForTransmit", - "rplRemoteUserBwc" - ] + "rcgLocalWriteBwc", + "nextPlannedCycle", + "rplTransmitLatency", + "lagReceivedInMillis", + "rcgRemoteReadBwc", + "lastCradBarrierId", + "lagAppliedSkew", + "readyForApply", + "rplUsedJournalCapacityDst", + "rplReceiveBwc", + "lastSadBarrierId", + "isInSlimMode", + "lastRadBarrierId", + "lastAppliedBarrierId", + "initialCopyTransmit", + "initialCopyNumPairs", + "lagAppliedInMillis", + "lastCompletedPeriodicBarrier", + "rplLocalApplyBwc", + "rcgLocalReadBwc", + "notReadyForTransmit", + "rplCgRpoCompliance", + "freezeTransmit", + "lagPersistentInMillis", + "lagReceivedSkew", + "notReadyForApply", + "initialCopyApply", + "rplPairIds", + "rplLocalUserBwc", + "numOfRplPairs", + "rplReceiveLatency", + "lastCsadBarrierId", + "rplRemoteApplyBwc", + "rcgRemoteWriteBwc", + "initialCopyProgress", + "lagPersistentSkew", + "rplSasBarriersBacklogSize", + "rplTransmitBwc", + "rplApplyLatency", + "readyForTransmit", + "rplRemoteUserBwc"] + class SnapshotPolicyConstants: + """ + This class holds constants related to SnapshotPolicy. + """ DEFAULT_STATISTICS_PROPERTIES = [ - "autoSnapshotVolIds","expiredButLockedSnapshotsIds","numOfAutoSnapshots", - "numOfExpiredButLockedSnapshots","numOfSrcVols","srcVolIds" - ] + "autoSnapshotVolIds", + "expiredButLockedSnapshotsIds", + "numOfAutoSnapshots", + "numOfExpiredButLockedSnapshots", + "numOfSrcVols", + "srcVolIds"] diff --git a/PyPowerFlex/exceptions.py b/PyPowerFlex/exceptions.py index 34f998c..2526e09 100644 --- a/PyPowerFlex/exceptions.py +++ b/PyPowerFlex/exceptions.py @@ -13,8 +13,14 @@ # License for the specific language governing permissions and limitations # under the License. +"""This module contains the definitions of the exceptions used in the code.""" + +# pylint: disable=super-init-not-called class PowerFlexClientException(Exception): + """ + Base class for all exceptions raised by the PowerFlexClient. + """ def __init__(self, message, response=None): self.message = message self.response = response @@ -24,6 +30,9 @@ def __str__(self): class ClientNotInitialized(PowerFlexClientException): + """ + Exception raised when the PowerFlexClient is not initialized. + """ def __init__(self): self.message = ( 'PowerFlex Client is not initialized. ' @@ -32,76 +41,87 @@ def __init__(self): class InvalidConfiguration(PowerFlexClientException): - pass + """ + Exception raised when the configuration is invalid. + """ class FieldsNotFound(PowerFlexClientException): - pass + """ + Exception raised when the required fields are not found. + """ class InvalidInput(PowerFlexClientException): - pass + """ + Exception raised when the input is invalid. + """ class PowerFlexFailCreating(PowerFlexClientException): + """ + Exception raised when creating a PowerFlex entity fails. + """ base = 'Failed to create PowerFlex {entity}.' def __init__(self, entity, response=None): self.message = self.base.format(entity=entity) self.response = response if response: - self.message = '{msg} Error: ' \ - '{response}'.format(msg=self.message, - response=response) + self.message = ( + f"{self.message} Error: " + f"{response}" + ) class PowerFlexFailDeleting(PowerFlexClientException): + """ + Exception raised when deleting a PowerFlex entity fails. + """ base = 'Failed to delete PowerFlex {entity} with id {_id}.' def __init__(self, entity, entity_id, response=None): self.message = self.base.format(entity=entity, _id=entity_id) self.response = response if response: - self.message = '{msg} Error: ' \ - '{response}'.format(msg=self.message, - response=response) + self.message = f"{self.message} Error: {response}" class PowerFlexFailQuerying(PowerFlexClientException): + """ + Exception raised when querying a PowerFlex entity fails. + """ base = 'Failed to query PowerFlex {entity}' def __init__(self, entity, entity_id=None, response=None): base = self.base.format(entity=entity) self.response = response if entity_id and response is None: - self.message = '{base} with id {_id}.'.format(base=base, - _id=entity_id) + self.message = f"{base} with id {entity_id}." elif entity is None and response: - self.message = '{base} Error: ' \ - '{response}'.format(base=base, - response=response) + self.message = f"{base} Error: {response}." elif entity and response: - self.message = '{base} with id {_id}.' \ - ' Error: {response}'.format(base=base, - _id=entity_id, - response=response) + self.message = f"{base} with id {entity_id}. Error: {response}." else: - self.message = '{base}.'.format(base=base) + self.message = f"{base}." class PowerFlexFailRenaming(PowerFlexClientException): + """ + Exception raised when renaming a PowerFlex entity fails. + """ base = 'Failed to rename PowerFlex {entity} with id {_id}.' def __init__(self, entity, entity_id, response=None): self.message = self.base.format(entity=entity, _id=entity_id) self.response = response if response: - self.message = '{msg} Error: ' \ - '{response}'.format(msg=self.message, - response=response) - + self.message = f"{self.message} Error: {response}" class PowerFlexFailEntityOperation(PowerFlexClientException): + """ + Exception raised when performing an operation on a PowerFlex entity fails. + """ base = 'Failed to perform {action} on PowerFlex {entity} with id {_id}.' def __init__(self, entity, entity_id, action, response=None): @@ -109,6 +129,4 @@ def __init__(self, entity, entity_id, action, response=None): self.base.format(action=action, entity=entity, _id=entity_id) self.response = response if response: - self.message = '{msg} Error: ' \ - '{response}'.format(msg=self.message, - response=response) + self.message = f"{self.message} Error: {response}" diff --git a/PyPowerFlex/objects/__init__.py b/PyPowerFlex/objects/__init__.py index bd601da..716fb43 100644 --- a/PyPowerFlex/objects/__init__.py +++ b/PyPowerFlex/objects/__init__.py @@ -13,6 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. +"""This module contains the objects for interacting with the PowerFlex APIs.""" + from PyPowerFlex.objects.device import Device from PyPowerFlex.objects.fault_set import FaultSet from PyPowerFlex.objects.protection_domain import ProtectionDomain diff --git a/PyPowerFlex/objects/acceleration_pool.py b/PyPowerFlex/objects/acceleration_pool.py index 6f03050..81667e8 100644 --- a/PyPowerFlex/objects/acceleration_pool.py +++ b/PyPowerFlex/objects/acceleration_pool.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for interacting with accelaration pool APIs.""" + +# pylint: disable=too-few-public-methods,duplicate-code + import logging from PyPowerFlex import base_client from PyPowerFlex import exceptions @@ -29,30 +33,35 @@ class MediaType: class AccelerationPool(base_client.EntityRequest): + """ + A class representing a PowerFlex acceleration pool. + + This class provides methods to create, delete, and query acceleration pools. + """ def create(self, media_type, protection_domain_id, name=None, - isRfcache=None): + is_rfcache=None): """Create PowerFlex acceleration pool. :param media_type: one of predefined attributes of MediaType :type media_type: str :type protection_domain_id: str :type name: str - :type isRfcache: bool + :type is_rfcache: bool :rtype: dict """ - if media_type == MediaType.ssd and not isRfcache: - msg = 'isRfcache must be set for media_type SSD.' + if media_type == MediaType.ssd and not is_rfcache: + msg = 'is_rfcache must be set for media_type SSD.' raise exceptions.InvalidInput(msg) - params = dict( - mediaType=media_type, - protectionDomainId=protection_domain_id, - name=name, - isRfcache=isRfcache - ) + params = { + 'mediaType': media_type, + 'protectionDomainId': protection_domain_id, + 'name': name, + 'isRfcache': is_rfcache + } return self._create_entity(params) @@ -76,7 +85,7 @@ def query_selected_statistics(self, properties, ids=None): action = "querySelectedStatistics" - params = dict(properties=properties) + params = {'properties': properties} if ids: params["ids"] = ids diff --git a/PyPowerFlex/objects/deployment.py b/PyPowerFlex/objects/deployment.py index a737f8c..7798e92 100644 --- a/PyPowerFlex/objects/deployment.py +++ b/PyPowerFlex/objects/deployment.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for doing the deployment.""" + +# pylint: disable=arguments-renamed,too-many-arguments,too-many-positional-arguments,no-member + import logging import requests from PyPowerFlex import base_client @@ -22,8 +26,18 @@ class Deployment(base_client.EntityRequest): - def get(self, filters=None, full=None, include_devices=None, include_template=None, - limit=None, offset=None, sort=None): + """ + A class representing Deployment client. + """ + def get( + self, + filters=None, + full=None, + include_devices=None, + include_template=None, + limit=None, + offset=None, + sort=None): """ Retrieve all Deployments with filter, sort, pagination :param filters: (Optional) The filters to apply to the results. @@ -35,18 +49,20 @@ def get(self, filters=None, full=None, include_devices=None, include_template=No :param sort: (Optional) The field to sort the results by. :return: A list of dictionary containing the retrieved Deployments. """ - params = dict( - filter=filters, - full=full, - sort=sort, - offset=offset, - limit=limit, - includeDevices=include_devices, - includeTemplate=include_template - ) - r, response = self.send_get_request(utils.build_uri_with_params(self.deployment_url, **params)) + params = { + 'filter': filters, + 'full': full, + 'sort': sort, + 'offset': offset, + 'limit': limit, + 'includeDevices': include_devices, + 'includeTemplate': include_template + } + r, response = self.send_get_request( + utils.build_uri_with_params( + self.deployment_url, **params)) if r.status_code != requests.codes.ok: - msg = (f'Failed to retrieve deployments. Error: {response}') + msg = f'Failed to retrieve deployments. Error: {response}' LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return response @@ -57,9 +73,11 @@ def get_by_id(self, deployment_id): :param deployment_id: Deployment ID. :return: A dictionary containing the retrieved Deployment. """ - r, response = self.send_get_request(f'{self.deployment_url}/{deployment_id}') + r, response = self.send_get_request( + f'{self.deployment_url}/{deployment_id}') if r.status_code != requests.codes.ok: - msg = (f'Failed to retrieve deployment by id {deployment_id}. Error: {response}') + msg = ( + f'Failed to retrieve deployment by id {deployment_id}. Error: {response}') LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return response @@ -74,9 +92,10 @@ def validate(self, rg_data): Raises: PowerFlexClientException: If the deployment fails. """ - r, response = self.send_post_request(f'{self.deployment_url}/validate', rg_data) + r, response = self.send_post_request( + f'{self.deployment_url}/validate', rg_data) if r.status_code != requests.codes.ok: - msg = (f'Failed to validate the deployment. Error: {response}') + msg = f'Failed to validate the deployment. Error: {response}' LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -94,7 +113,7 @@ def create(self, rg_data): """ r, response = self.send_post_request(self.deployment_url, rg_data) if r.status_code != requests.codes.ok: - msg = (f'Failed to create a new deployment. Error: {response}') + msg = f'Failed to create a new deployment. Error: {response}' LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -113,9 +132,9 @@ def edit(self, deployment_id, rg_data): """ request_url = f'{self.deployment_url}/{deployment_id}' r, response = self.send_put_request(request_url, rg_data) - + if r.status_code != requests.codes.ok: - msg = (f'Failed to edit the deployment. Error: {response}') + msg = f'Failed to edit the deployment. Error: {response}' LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -135,7 +154,7 @@ def delete(self, deployment_id): response = self.send_delete_request(request_url) if response.status_code != requests.codes.no_content: - msg = (f'Failed to delete deployment. Error: {response}') + msg = f'Failed to delete deployment. Error: {response}' LOG.error(msg) raise exceptions.PowerFlexClientException(msg) diff --git a/PyPowerFlex/objects/device.py b/PyPowerFlex/objects/device.py index 7b03e12..9d2a29d 100644 --- a/PyPowerFlex/objects/device.py +++ b/PyPowerFlex/objects/device.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for interacting with device APIs.""" + +# pylint: disable=too-few-public-methods,too-many-arguments,too-many-positional-arguments,no-member,duplicate-code + import logging import requests @@ -43,6 +47,9 @@ class ExternalAccelerationType: class Device(base_client.EntityRequest): + """ + A class representing Device client. + """ def create(self, current_pathname, sds_id, @@ -76,16 +83,16 @@ def create(self, 'set.' raise exceptions.InvalidInput(msg) - params = dict( - deviceCurrentPathname=current_pathname, - sdsId=sds_id, - accelerationPoolId=acceleration_pool_id, - externalAccelerationType=external_acceleration_type, - forceDeviceTakeover=force, - mediaType=media_type, - name=name, - storagePoolId=storage_pool_id - ) + params = { + "deviceCurrentPathname": current_pathname, + "sdsId": sds_id, + "accelerationPoolId": acceleration_pool_id, + "externalAccelerationType": external_acceleration_type, + "forceDeviceTakeover": force, + "mediaType": media_type, + "name": name, + "storagePoolId": storage_pool_id + } return self._create_entity(params) @@ -97,9 +104,9 @@ def delete(self, device_id, force=None): :rtype: None """ - params = dict( - forceRemove=force - ) + params = { + "forceRemove": force + } return self._delete_entity(device_id, params) @@ -113,9 +120,9 @@ def rename(self, device_id, name): action = 'setDeviceName' - params = dict( - newName=name - ) + params = { + "newName": name + } return self._rename_entity(action, device_id, params) @@ -132,9 +139,7 @@ def set_media_type(self, action = 'setMediaType' - params = dict( - mediaType=media_type - ) + params = {"mediaType": media_type} r, response = self.send_post_request(self.base_action_url, action=action, @@ -142,10 +147,10 @@ def set_media_type(self, entity_id=device_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to set media type for PowerFlex {entity} ' - 'with id {_id}. Error: {response}' - .format(entity=self.entity, _id=device_id, - response=response)) + msg = ( + f"Failed to set media type for PowerFlex {self.entity} " + f"with id {device_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -161,7 +166,7 @@ def query_selected_statistics(self, properties, ids=None): action = "querySelectedStatistics" - params = dict(properties=properties) + params = {'properties': properties} if ids: params["ids"] = ids diff --git a/PyPowerFlex/objects/fault_set.py b/PyPowerFlex/objects/fault_set.py index c6666f9..a47b1fa 100644 --- a/PyPowerFlex/objects/fault_set.py +++ b/PyPowerFlex/objects/fault_set.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for interacting with fault set APIs.""" + +# pylint: disable=no-member,duplicate-code + import logging import requests @@ -25,6 +29,9 @@ class FaultSet(base_client.EntityRequest): + """ + A class representing Fault Set client. + """ def clear(self, fault_set_id): """Clear PowerFlex fault set. @@ -39,10 +46,10 @@ def clear(self, fault_set_id): entity=self.entity, entity_id=fault_set_id) if r.status_code != requests.codes.ok: - msg = ('Failed to clear PowerFlex {entity} ' - 'with id {_id}. Error: {response}' - .format(entity=self.entity, _id=fault_set_id, - response=response)) + msg = ( + f"Failed to clear PowerFlex {self.entity} " + f"with id {fault_set_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -56,10 +63,10 @@ def create(self, protection_domain_id, name=None): :rtype: dict """ - params = dict( - protectionDomainId=protection_domain_id, - name=name - ) + params = { + "protectionDomainId": protection_domain_id, + "name": name + } return self._create_entity(params) @@ -96,9 +103,9 @@ def rename(self, fault_set_id, name): action = 'setFaultSetName' - params = dict( - newName=name - ) + params = { + "newName": name + } return self._rename_entity(action, fault_set_id, params) @@ -112,7 +119,7 @@ def query_selected_statistics(self, properties, ids=None): action = "querySelectedStatistics" - params = dict(properties=properties) + params = {'properties': properties} if ids: params["ids"] = ids diff --git a/PyPowerFlex/objects/firmware_repository.py b/PyPowerFlex/objects/firmware_repository.py index d8428cc..161cd9b 100644 --- a/PyPowerFlex/objects/firmware_repository.py +++ b/PyPowerFlex/objects/firmware_repository.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for interacting with firmware repository APIs.""" + +# pylint: disable=arguments-renamed,no-member,too-many-arguments,too-many-positional-arguments + import logging import requests from PyPowerFlex import base_client @@ -22,7 +26,11 @@ class FirmwareRepository(base_client.EntityRequest): - def get(self, filters=None, limit=None, offset=None, sort=None, related=False, bundles=False, components=False): + """ + A class representing Firmware Repository client. + """ + def get(self, filters=None, limit=None, offset=None, sort=None, + related=False, bundles=False, components=False): """ Retrieve all firmware repository with filter, sort, pagination :param filters: (Optional) The filters to apply to the results. @@ -34,18 +42,21 @@ def get(self, filters=None, limit=None, offset=None, sort=None, related=False, b :param components: Whether to include components in the response. :return: A list of dictionary containing the retrieved firmware repository. """ - params = dict( - filter=filters, - sort=sort, - offset=offset, - limit=limit, - related=related, - bundles=bundles, - components=components - ) - r, response = self.send_get_request(utils.build_uri_with_params(self.firmware_repository_url, **params)) + params = { + 'filter': filters, + 'sort': sort, + 'offset': offset, + 'limit': limit, + 'related': related, + 'bundles': bundles, + 'components': components + } + r, response = self.send_get_request( + utils.build_uri_with_params( + self.firmware_repository_url, **params)) if r.status_code != requests.codes.ok: - msg = (f'Failed to retrieve firmware repository. Error: {response}') + msg = ( + f'Failed to retrieve firmware repository. Error: {response}') LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return response diff --git a/PyPowerFlex/objects/host.py b/PyPowerFlex/objects/host.py index 1d9fd8d..79ef13c 100644 --- a/PyPowerFlex/objects/host.py +++ b/PyPowerFlex/objects/host.py @@ -13,6 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for interacting with host APIs.""" + import logging from PyPowerFlex import base_client @@ -20,6 +22,9 @@ LOG = logging.getLogger(__name__) class Host(base_client.EntityRequest): + """ + A class representing Host client. + """ def create(self, nqn, name=None, @@ -39,18 +44,18 @@ def create(self, :rtype: dict """ - params = dict( - nqn=nqn, - name=name, - maxNumPaths=max_num_paths, - maxNumSysPorts=max_num_sys_ports - ) + params = { + "nqn": nqn, + "name": name, + "maxNumPaths": max_num_paths, + "maxNumSysPorts": max_num_sys_ports + } return self._create_entity(params) def modify_max_num_paths(self, host_id, max_num_paths): """Modify Maximum Number of Paths Per Volume. - + :param host_id: ID of the SDC :type host_id: str :param max_num_paths: Maximum Number of Paths Per Volume. @@ -61,16 +66,14 @@ def modify_max_num_paths(self, host_id, max_num_paths): action = 'modifyMaxNumPaths' - params = dict( - newMaxNumPaths=max_num_paths - ) + params = {"newMaxNumPaths": max_num_paths} - return self._perform_entity_operation_based_on_action(action=action, - entity_id=host_id, params=params, add_entity=False) + return self._perform_entity_operation_based_on_action( + action=action, entity_id=host_id, params=params, add_entity=False) def modify_max_num_sys_ports(self, host_id, max_num_sys_ports): """Modify Maximum Number of Ports Per Protection Domain. - + :param host_id: ID of the SDC :type host_id: str :param max_num_sys_ports: Maximum Number of Ports Per Protection Domain. @@ -81,9 +84,7 @@ def modify_max_num_sys_ports(self, host_id, max_num_sys_ports): action = 'modifyMaxNumSysPorts' - params = dict( - newMaxNumSysPorts=max_num_sys_ports - ) + params = {"newMaxNumSysPorts": max_num_sys_ports} - return self._perform_entity_operation_based_on_action(action=action, - entity_id=host_id, params=params, add_entity=False) + return self._perform_entity_operation_based_on_action( + action=action, entity_id=host_id, params=params, add_entity=False) diff --git a/PyPowerFlex/objects/managed_device.py b/PyPowerFlex/objects/managed_device.py index 1e41c23..f7641ae 100644 --- a/PyPowerFlex/objects/managed_device.py +++ b/PyPowerFlex/objects/managed_device.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for interacting with managed device APIs.""" + +# pylint: disable=arguments-renamed,no-member + import logging import requests from PyPowerFlex import base_client @@ -20,7 +24,11 @@ from PyPowerFlex import utils LOG = logging.getLogger(__name__) + class ManagedDevice(base_client.EntityRequest): + """ + A class representing Managed Device client. + """ def get(self, filters=None, limit=None, offset=None, sort=None): """ Retrieve all devices from inventory with filter, sort, pagination @@ -30,15 +38,17 @@ def get(self, filters=None, limit=None, offset=None, sort=None): :param sort: (Optional) The field to sort the results by. :return: A list of dictionary containing the retrieved devices from inventory. """ - params = dict( - filter=filters, - limit=limit, - offset=offset, - sort=sort - ) - r, response = self.send_get_request(utils.build_uri_with_params(self.managed_device_url, **params)) + params = { + "filter": filters, + "limit": limit, + "offset": offset, + "sort": sort + } + r, response = self.send_get_request( + utils.build_uri_with_params( + self.managed_device_url, **params)) if r.status_code != requests.codes.ok: - msg = (f'Failed to retrieve managed devices. Error: {response}') + msg = f'Failed to retrieve managed devices. Error: {response}' LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return response diff --git a/PyPowerFlex/objects/protection_domain.py b/PyPowerFlex/objects/protection_domain.py index 9f8cb44..438996c 100644 --- a/PyPowerFlex/objects/protection_domain.py +++ b/PyPowerFlex/objects/protection_domain.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for interacting with protection domain APIs.""" + +# pylint: disable=too-few-public-methods,no-member,too-many-arguments,too-many-positional-arguments,duplicate-code + import logging import requests @@ -35,6 +39,9 @@ class RFCacheOperationMode: class ProtectionDomain(base_client.EntityRequest): + """ + A class representing Protection Domain client. + """ def activate(self, protection_domain_id, force=False): """Activate PowerFlex protection domain. @@ -45,9 +52,9 @@ def activate(self, protection_domain_id, force=False): action = 'activateProtectionDomain' - params = dict( - forceActivate=force - ) + params = { + "forceActivate": force + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -55,10 +62,10 @@ def activate(self, protection_domain_id, force=False): entity_id=protection_domain_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to activate PowerFlex {entity} ' - 'with id {_id}. Error: {response}' - .format(entity=self.entity, _id=protection_domain_id, - response=response)) + msg = ( + f"Failed to activate PowerFlex {self.entity} " + f"with id {protection_domain_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -71,9 +78,7 @@ def create(self, name): :rtype: dict """ - params = dict( - name=name - ) + params = {"name": name} return self._create_entity(params) @@ -127,9 +132,9 @@ def inactivate(self, protection_domain_id, force=False): action = 'inactivateProtectionDomain' - params = dict( - forceShutdown=force - ) + params = { + "forceShutdown": force + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -137,10 +142,10 @@ def inactivate(self, protection_domain_id, force=False): entity_id=protection_domain_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to inactivate PowerFlex {entity} ' - 'with id {_id}. Error: {response}' - .format(entity=self.entity, _id=protection_domain_id, - response=response)) + msg = ( + f"Failed to inactivate PowerFlex {self.entity} " + f"with id {protection_domain_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -156,9 +161,7 @@ def rename(self, protection_domain_id, name): action = 'setProtectionDomainName' - params = dict( - name=name - ) + params = {"name": name} return self._rename_entity(action, protection_domain_id, params) @@ -178,12 +181,12 @@ def network_limits(self, protection_domain_id, rebuild_limit=None, action = "setSdsNetworkLimits" - params = dict( - rebuildLimitInKbps=rebuild_limit, - rebalanceLimitInKbps=rebalance_limit, - vtreeMigrationLimitInKbps=vtree_migration_limit, - overallLimitInKbps=overall_limit - ) + params = { + "rebuildLimitInKbps": rebuild_limit, + "rebalanceLimitInKbps": rebalance_limit, + "vtreeMigrationLimitInKbps": vtree_migration_limit, + "overallLimitInKbps": overall_limit + } r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, @@ -191,10 +194,10 @@ def network_limits(self, protection_domain_id, rebuild_limit=None, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to update the network limits of PowerFlex {entity}' - ' with id {_id}. Error: {response}' - .format(entity=self.entity, _id=protection_domain_id, - response=response)) + msg = ( + f"Failed to update the network limits of PowerFlex {self.entity} " + f"with id {protection_domain_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -218,10 +221,10 @@ def set_rfcache_enabled(self, protection_domain_id, enable_rfcache=None): entity=self.entity, entity_id=protection_domain_id) if r.status_code != requests.codes.ok: - msg = ('Failed to enable/disable RFcache in PowerFlex {entity} ' - ' with id {_id}. Error: {response}' - .format(entity=self.entity, _id=protection_domain_id, - response=response)) + msg = ( + f"Failed to enable/disable RFcache in PowerFlex {self.entity} " + f"with id {protection_domain_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -241,11 +244,11 @@ def rfcache_parameters(self, protection_domain_id, page_size=None, action = "setRfcacheParameters" - params = dict( - pageSizeKb=page_size, - maxIOSizeKb=max_io_limit, - rfcacheOperationMode=pass_through_mode - ) + params = { + "pageSizeKb": page_size, + "maxIOSizeKb": max_io_limit, + "rfcacheOperationMode": pass_through_mode + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -254,10 +257,10 @@ def rfcache_parameters(self, protection_domain_id, page_size=None, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to set RFcache parameters in PowerFlex {entity} ' - ' with id {_id}. Error: {response}' - .format(entity=self.entity, _id=protection_domain_id, - response=response)) + msg = ( + f"Failed to set RFcache parameters in PowerFlex {self.entity} " + f"with id {protection_domain_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -274,7 +277,7 @@ def query_selected_statistics(self, properties, ids=None): action = "querySelectedStatistics" - params = dict(properties=properties) + params = {'properties': properties} if ids: params["ids"] = ids diff --git a/PyPowerFlex/objects/replication_consistency_group.py b/PyPowerFlex/objects/replication_consistency_group.py index 2510557..23e5256 100644 --- a/PyPowerFlex/objects/replication_consistency_group.py +++ b/PyPowerFlex/objects/replication_consistency_group.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for interacting with replication consistency group APIs.""" + +# pylint: disable=too-many-public-methods,no-member,too-many-arguments,too-many-positional-arguments,duplicate-code + import logging import requests @@ -26,8 +30,11 @@ class ReplicationConsistencyGroup(base_client.EntityRequest): + """ + A class representing Replication Consistency Group client. + """ def create_snapshot(self, - rcg_id): + rcg_id): """Create a snapshot of PowerFlex replication consistency group. :param rcg_id: str @@ -41,10 +48,10 @@ def create_snapshot(self, entity=self.entity, entity_id=rcg_id) if r.status_code != requests.codes.ok: - msg = ('Failed to create a snapshot of PowerFlex {entity} ' - 'with id {_id} . Error: {response}'.format(entity=self.entity, - _id=rcg_id, - response=response)) + msg = ( + f"Failed to create a snapshot of PowerFlex {self.entity} " + f"with id {rcg_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -82,16 +89,16 @@ def create(self, :return: dict """ - params = dict( - rpoInSeconds=rpo, - protectionDomainId=protection_domain_id, - remoteProtectionDomainId=remote_protection_domain_id, - peerMdmId=peer_mdm_id, - destinationSystemId=destination_system_id, - name=name, - forceIgnoreConsistency=force_ignore_consistency, - activityMode=activity_mode - ) + params = { + "rpoInSeconds": rpo, + "protectionDomainId": protection_domain_id, + "remoteProtectionDomainId": remote_protection_domain_id, + "peerMdmId": peer_mdm_id, + "destinationSystemId": destination_system_id, + "name": name, + "forceIgnoreConsistency": force_ignore_consistency, + "activityMode": activity_mode + } return self._create_entity(params) @@ -105,9 +112,7 @@ def delete(self, :return: None """ - params = dict( - forceIgnoreConsistency=force_ignore_consistency - ) + params = {"forceIgnoreConsistency": force_ignore_consistency} return self._delete_entity(rcg_id, params) @@ -117,9 +122,9 @@ def activate(self, rcg_id): :param rcg_id: str :return: dict """ - action = "activate%s" % self.entity - return self._perform_entity_operation_based_on_action\ - (rcg_id, action, add_entity=False) + action = f"activate{self.entity}" + return self._perform_entity_operation_based_on_action( + rcg_id, action, add_entity=False) def inactivate(self, rcg_id): """Inactivate PowerFlex RCG. @@ -127,9 +132,9 @@ def inactivate(self, rcg_id): :param rcg_id: str :return: dict """ - action = "terminate%s" % self.entity - return self._perform_entity_operation_based_on_action\ - (rcg_id, action, add_entity=False) + action = f"terminate{self.entity}" + return self._perform_entity_operation_based_on_action( + rcg_id, action, add_entity=False) def freeze(self, rcg_id): """Freeze PowerFlex RCG. @@ -138,7 +143,8 @@ def freeze(self, rcg_id): :return: dict """ - return self._perform_entity_operation_based_on_action(rcg_id, "freezeApply") + return self._perform_entity_operation_based_on_action( + rcg_id, "freezeApply") def unfreeze(self, rcg_id): """Freeze PowerFlex RCG. @@ -147,7 +153,8 @@ def unfreeze(self, rcg_id): :return: dict """ - return self._perform_entity_operation_based_on_action(rcg_id, "unfreezeApply") + return self._perform_entity_operation_based_on_action( + rcg_id, "unfreezeApply") def pause(self, rcg_id, pause_mode): """Pause PowerFlex RCG. @@ -157,10 +164,9 @@ def pause(self, rcg_id, pause_mode): :return: dict """ - params = dict( - pauseMode=pause_mode - ) - return self._perform_entity_operation_based_on_action(rcg_id, "pause", params) + params = {"pauseMode": pause_mode} + return self._perform_entity_operation_based_on_action( + rcg_id, "pause", params) def resume(self, rcg_id): """Resume PowerFlex RCG. @@ -178,7 +184,8 @@ def failover(self, rcg_id): :return: dict """ - return self._perform_entity_operation_based_on_action(rcg_id, "failover") + return self._perform_entity_operation_based_on_action( + rcg_id, "failover") def sync(self, rcg_id): """Synchronize PowerFlex RCG. @@ -187,7 +194,8 @@ def sync(self, rcg_id): :return: dict """ - return self._perform_entity_operation_based_on_action(rcg_id, "syncNow") + return self._perform_entity_operation_based_on_action( + rcg_id, "syncNow") def restore(self, rcg_id): """Restore PowerFlex RCG. @@ -196,7 +204,8 @@ def restore(self, rcg_id): :return: dict """ - return self._perform_entity_operation_based_on_action(rcg_id, "restore") + return self._perform_entity_operation_based_on_action( + rcg_id, "restore") def reverse(self, rcg_id): """Reverse PowerFlex RCG. @@ -205,7 +214,8 @@ def reverse(self, rcg_id): :return: dict """ - return self._perform_entity_operation_based_on_action(rcg_id, "reverse") + return self._perform_entity_operation_based_on_action( + rcg_id, "reverse") def switchover(self, rcg_id, force=False): """Switch over PowerFlex RCG. @@ -215,9 +225,10 @@ def switchover(self, rcg_id, force=False): :return: dict """ url_params = { - 'force':force + 'force': force } - return self._perform_entity_operation_based_on_action(rcg_id, "switchover", **url_params) + return self._perform_entity_operation_based_on_action( + rcg_id, "switchover", **url_params) def set_as_consistent(self, rcg_id): """Set PowerFlex RCG as consistent. @@ -225,9 +236,9 @@ def set_as_consistent(self, rcg_id): :param rcg_id: str :return: dict """ - action = "set%sConsistent" % self.entity - return self._perform_entity_operation_based_on_action\ - (rcg_id, action, add_entity=False) + action = f"set{self.entity}Consistent" + return self._perform_entity_operation_based_on_action( + rcg_id, action, add_entity=False) def set_as_inconsistent(self, rcg_id): """Set PowerFlex RCG as in-consistent. @@ -235,9 +246,9 @@ def set_as_inconsistent(self, rcg_id): :param rcg_id: str :return: dict """ - action = "set%sInconsistent" % self.entity - return self._perform_entity_operation_based_on_action\ - (rcg_id, action, add_entity=False) + action = f"set{self.entity}Inconsistent" + return self._perform_entity_operation_based_on_action( + rcg_id, action, add_entity=False) def modify_rpo(self, rcg_id, rpo_in_seconds): """Modify rpo of PowerFlex RCG. @@ -247,14 +258,15 @@ def modify_rpo(self, rcg_id, rpo_in_seconds): :return: dict """ - params = dict( - rpoInSeconds=rpo_in_seconds - ) - action = "Modify%sRpo" % self.entity - return self._perform_entity_operation_based_on_action\ - (rcg_id, action, params=params, add_entity=False) + params = { + 'rpoInSeconds': rpo_in_seconds + } + action = f"Modify{self.entity}Rpo" + return self._perform_entity_operation_based_on_action( + rcg_id, action, params=params, add_entity=False) - def modify_target_volume_access_mode(self, rcg_id, target_volume_access_mode): + def modify_target_volume_access_mode( + self, rcg_id, target_volume_access_mode): """Modify TargetVolumeAccessMode of PowerFlex RCG. :param rcg_id: str @@ -262,12 +274,10 @@ def modify_target_volume_access_mode(self, rcg_id, target_volume_access_mode): :return: dict """ - params = dict( - targetVolumeAccessMode=target_volume_access_mode - ) - action = "modify%sTargetVolumeAccessMode" % self.entity - return self._perform_entity_operation_based_on_action\ - (rcg_id, action, params=params, add_entity=False) + params = {"targetVolumeAccessMode": target_volume_access_mode} + action = f"modify{self.entity}TargetVolumeAccessMode" + return self._perform_entity_operation_based_on_action( + rcg_id, action, params=params, add_entity=False) def rename_rcg(self, rcg_id, new_name): """Rename PowerFlex RCG. @@ -277,11 +287,9 @@ def rename_rcg(self, rcg_id, new_name): :return: dict """ - params = dict( - newName=new_name - ) - return self._perform_entity_operation_based_on_action\ - (rcg_id, "rename", params=params) + params = {"newName": new_name} + return self._perform_entity_operation_based_on_action( + rcg_id, "rename", params=params) def get_replication_pairs(self, rcg_id): """Get replication pairs of PowerFlex RCG. @@ -300,7 +308,8 @@ def get_all_statistics(self, api_version_less_than_3_6): """ params = {'properties': RCGConstants.DEFAULT_STATISTICS_PROPERTIES} if not api_version_less_than_3_6: - params = {'properties': RCGConstants.DEFAULT_STATISTICS_PROPERTIES_ABOVE_3_5} + params = { + 'properties': RCGConstants.DEFAULT_STATISTICS_PROPERTIES_ABOVE_3_5} params['allIds'] = "" r, response = self.send_post_request(self.list_statistics_url, @@ -308,8 +317,10 @@ def get_all_statistics(self, api_version_less_than_3_6): action="querySelectedStatistics", params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to list replication consistencty group statistics for PowerFlex. ' - 'Error: {response}'.format(response=response)) + msg = ( + f'Failed to list replication consistency group statistics for PowerFlex. ' + f'Error: {response}' + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -326,7 +337,7 @@ def query_selected_statistics(self, properties, ids=None): action = "querySelectedStatistics" - params = dict(properties=properties) + params = {'properties': properties} if ids: params["ids"] = ids diff --git a/PyPowerFlex/objects/replication_pair.py b/PyPowerFlex/objects/replication_pair.py index c1755f3..60b8915 100644 --- a/PyPowerFlex/objects/replication_pair.py +++ b/PyPowerFlex/objects/replication_pair.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for interacting with replication pair APIs.""" + +# pylint: disable=redefined-builtin,no-member,too-many-arguments,too-many-positional-arguments,duplicate-code + import logging import requests @@ -25,6 +29,9 @@ class ReplicationPair(base_client.EntityRequest): + """ + A class representing Replication Pair client. + """ def get_statistics(self, id): """Retrieve statistics for the specified ReplicationPair object. @@ -51,13 +58,13 @@ def add(self, :return: dict """ - params = dict( - sourceVolumeId=source_vol_id, - destinationVolumeId=dest_vol_id, - replicationConsistencyGroupId=rcg_id, - copyType=copy_type, - name=name - ) + params = { + "sourceVolumeId": source_vol_id, + "destinationVolumeId": dest_vol_id, + "replicationConsistencyGroupId": rcg_id, + "copyType": copy_type, + "name": name + } return self._create_entity(params) @@ -75,8 +82,8 @@ def pause(self, id): :param id: str :return: dict """ - return self._perform_entity_operation_based_on_action\ - (id, "pausePairInitialCopy", add_entity=False) + return self._perform_entity_operation_based_on_action( + id, "pausePairInitialCopy", add_entity=False) def resume(self, id): """Resume initial copy of the ReplicationPair. @@ -84,8 +91,8 @@ def resume(self, id): :param id: str :return: dict """ - return self._perform_entity_operation_based_on_action\ - (id, "resumePairInitialCopy", add_entity=False) + return self._perform_entity_operation_based_on_action( + id, "resumePairInitialCopy", add_entity=False) def get_all_statistics(self): """Retrieve statistics for all ReplicationPair objects. @@ -95,8 +102,10 @@ def get_all_statistics(self): entity=self.entity, action="querySelectedStatistics") if r.status_code != requests.codes.ok: - msg = ('Failed to list statistics for all ReplicationPair objects. ' - 'Error: {response}'.format(response=response)) + msg = ( + 'Failed to list statistics for all ReplicationPair objects. ' + f'Error: {response}' + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -113,7 +122,7 @@ def query_selected_statistics(self, properties, ids=None): action = "querySelectedStatistics" - params = dict(properties=properties) + params = {'properties': properties} if ids: params["ids"] = ids diff --git a/PyPowerFlex/objects/sdc.py b/PyPowerFlex/objects/sdc.py index 518ce0c..614c123 100644 --- a/PyPowerFlex/objects/sdc.py +++ b/PyPowerFlex/objects/sdc.py @@ -13,16 +13,19 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for interacting with SDC APIs.""" + import logging -import requests from PyPowerFlex import base_client -from PyPowerFlex import exceptions LOG = logging.getLogger(__name__) class Sdc(base_client.EntityRequest): + """ + A class representing SDC client. + """ def delete(self, sdc_id): """Remove PowerFlex SDC. @@ -53,9 +56,7 @@ def rename(self, sdc_id, name): action = 'setSdcName' - params = dict( - sdcName=name - ) + params = {"sdcName": name} return self._rename_entity(action, sdc_id, params) @@ -69,11 +70,9 @@ def set_performance_profile(self, sdc_id, perf_profile): action = 'setSdcPerformanceParameters' - params = dict( - perfProfile=perf_profile - ) - return self._perform_entity_operation_based_on_action\ - (sdc_id, action, params=params, add_entity=False) + params = {"perfProfile": perf_profile} + return self._perform_entity_operation_based_on_action( + sdc_id, action, params=params, add_entity=False) def query_selected_statistics(self, properties, ids=None): """Query PowerFlex SDC statistics. @@ -85,7 +84,7 @@ def query_selected_statistics(self, properties, ids=None): action = "querySelectedStatistics" - params = dict(properties=properties) + params = {'properties': properties} if ids: params["ids"] = ids diff --git a/PyPowerFlex/objects/sds.py b/PyPowerFlex/objects/sds.py index aa80acf..54c4787 100644 --- a/PyPowerFlex/objects/sds.py +++ b/PyPowerFlex/objects/sds.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for interacting with SDS APIs.""" + +# pylint: disable=too-few-public-methods,no-member,too-many-arguments,too-many-positional-arguments,too-many-locals,duplicate-code + import logging import requests @@ -74,7 +78,7 @@ def __init__(self, }, dump=False ) - super(AccelerationDeviceInfo, self).__init__(**params) + super().__init__(**params) class DeviceInfo: @@ -98,7 +102,7 @@ def __init__(self, }, dump=False ) - super(DeviceInfo, self).__init__(**params) + super().__init__(**params) class RfcacheDevice(dict): @@ -116,7 +120,7 @@ def __init__(self, path, name): }, dump=False ) - super(RfcacheDevice, self).__init__(**params) + super().__init__(**params) class SdsIp(dict): @@ -134,10 +138,13 @@ def __init__(self, ip, role): }, dump=False ) - super(SdsIp, self).__init__(**params) + super().__init__(**params) class Sds(base_client.EntityRequest): + """ + A class representing SDS client. + """ def add_ip(self, sds_id, sds_ip): """Add PowerFlex SDS IP-address. @@ -154,9 +161,10 @@ def add_ip(self, sds_id, sds_ip): entity_id=sds_id, params=sds_ip) if r.status_code != requests.codes.ok: - msg = ('Failed to add IP for PowerFlex {entity} ' - 'with id {_id}. Error: {response}' - .format(entity=self.entity, _id=sds_id, response=response)) + msg = ( + f"Failed to add IP for PowerFlex {self.entity} " + f"with id {sds_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -203,24 +211,24 @@ def create(self, :rtype: dict """ - params = dict( - protectionDomainId=protection_domain_id, - sdsIpList=sds_ips, - accelerationDeviceInfoList=acceleration_devices_info, - deviceInfoList=devices_info, - deviceTestMode=device_test_mode, - deviceTestTimeSecs=device_test_time_sec, - drlMode=drl_mode, - faultSetId=fault_set_id, - forceClean=force_clean, - forceDeviceTakeover=force_device_takeover, - name=name, - numOfIoBuffers=num_of_io_buffers, - sdsRfcacheDeviceInfoList=rfcache_devices_info, - rmcacheEnabled=rmcache_enabled, - rmcacheSizeInKb=rmcache_size_in_kb, - sdsPort=sds_port - ) + params = { + "protectionDomainId": protection_domain_id, + "sdsIpList": sds_ips, + "accelerationDeviceInfoList": acceleration_devices_info, + "deviceInfoList": devices_info, + "deviceTestMode": device_test_mode, + "deviceTestTimeSecs": device_test_time_sec, + "drlMode": drl_mode, + "faultSetId": fault_set_id, + "forceClean": force_clean, + "forceDeviceTakeover": force_device_takeover, + "name": name, + "numOfIoBuffers": num_of_io_buffers, + "sdsRfcacheDeviceInfoList": rfcache_devices_info, + "rmcacheEnabled": rmcache_enabled, + "rmcacheSizeInKb": rmcache_size_in_kb, + "sdsPort": sds_port + } return self._create_entity(params) @@ -232,9 +240,7 @@ def delete(self, sds_id, force=None): :rtype: None """ - params = dict( - force=force - ) + params = {"force": force} return self._delete_entity(sds_id, params) @@ -259,9 +265,7 @@ def rename(self, sds_id, name): action = 'setSdsName' - params = dict( - name=name - ) + params = {"name": name} return self._rename_entity(action, sds_id, params) @@ -275,9 +279,7 @@ def remove_ip(self, sds_id, ip): action = 'removeSdsIp' - params = dict( - ip=ip - ) + params = {"ip": ip} r, response = self.send_post_request(self.base_action_url, action=action, @@ -285,9 +287,8 @@ def remove_ip(self, sds_id, ip): entity_id=sds_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to remove IP from PowerFlex {entity} ' - 'with id {_id}. Error: {response}' - .format(entity=self.entity, _id=sds_id, response=response)) + msg = f"Failed to remove IP from PowerFlex {self.entity} " \ + f"with id {sds_id}. Error: {response}" LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -306,12 +307,11 @@ def set_ip_role(self, sds_id, ip, role, force=None): action = 'setSdsIpRole' - params = dict( - sdsIpToSet=ip, - newRole=role, - forceRoleModification=force - - ) + params = { + 'sdsIpToSet': ip, + 'newRole': role, + 'forceRoleModification': force + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -319,9 +319,10 @@ def set_ip_role(self, sds_id, ip, role, force=None): entity_id=sds_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to set ip role for PowerFlex {entity} ' - 'with id {_id}. Error: {response}' - .format(entity=self.entity, _id=sds_id, response=response)) + msg = ( + f"Failed to set ip role for PowerFlex {self.entity} " + f"with id {sds_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -337,9 +338,9 @@ def set_port(self, sds_id, sds_port): action = 'setSdsPort' - params = dict( - sdsPort=sds_port - ) + params = { + 'sdsPort': sds_port + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -347,9 +348,8 @@ def set_port(self, sds_id, sds_port): entity_id=sds_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to set port for PowerFlex {entity} ' - 'with id {_id}. Error: {response}' - .format(entity=self.entity, _id=sds_id, response=response)) + msg = f"Failed to set port for PowerFlex {self.entity} " \ + f"with id {sds_id}. Error: {response}" LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -372,9 +372,10 @@ def set_rfcache_enabled(self, sds_id, rfcache_enabled): entity=self.entity, entity_id=sds_id) if r.status_code != requests.codes.ok: - msg = ('Failed to enable/disable Rfcache for PowerFlex {entity} ' - 'with id {_id}. Error: {response}' - .format(entity=self.entity, _id=sds_id, response=response)) + msg = ( + f"Failed to enable/disable Rfcache for PowerFlex {self.entity} " + f"with id {sds_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -390,9 +391,9 @@ def set_rmcache_enabled(self, sds_id, rmcache_enabled): action = 'setSdsRmcacheEnabled' - params = dict( - rmcacheEnabled=rmcache_enabled - ) + params = { + 'rmcacheEnabled': rmcache_enabled + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -400,9 +401,10 @@ def set_rmcache_enabled(self, sds_id, rmcache_enabled): entity_id=sds_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to enable/disable Rmcache for PowerFlex {entity} ' - 'with id {_id}. Error: {response}' - .format(entity=self.entity, _id=sds_id, response=response)) + msg = ( + f"Failed to enable/disable Rmcache for PowerFlex {self.entity} " + f"with id {sds_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -418,9 +420,7 @@ def set_rmcache_size(self, sds_id, rmcache_size): action = 'setSdsRmcacheSize' - params = dict( - rmcacheSizeInMB=rmcache_size - ) + params = {"rmcacheSizeInMB": rmcache_size} r, response = self.send_post_request(self.base_action_url, action=action, @@ -428,9 +428,10 @@ def set_rmcache_size(self, sds_id, rmcache_size): entity_id=sds_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to set Rmcache size for PowerFlex {entity} ' - 'with id {_id}. Error: {response}' - .format(entity=self.entity, _id=sds_id, response=response)) + msg = ( + f"Failed to set Rmcache size for PowerFlex {self.entity} " + f"with id {sds_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -446,9 +447,7 @@ def set_performance_parameters(self, sds_id, performance_profile): action = 'setSdsPerformanceParameters' - params = dict( - perfProfile=performance_profile - ) + params = {"perfProfile": performance_profile} r, response = self.send_post_request(self.base_action_url, action=action, @@ -456,9 +455,10 @@ def set_performance_parameters(self, sds_id, performance_profile): entity_id=sds_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to set performance parameters for PowerFlex ' - '{entity} with id {_id}. Error: {response}' - .format(entity=self.entity, _id=sds_id, response=response)) + msg = ( + f"Failed to set performance parameters for PowerFlex " + f"{self.entity} with id {sds_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -474,7 +474,7 @@ def query_selected_statistics(self, properties, ids=None): action = "querySelectedStatistics" - params = dict(properties=properties) + params = {'properties': properties} if ids: params["ids"] = ids diff --git a/PyPowerFlex/objects/sdt.py b/PyPowerFlex/objects/sdt.py index 689244a..40d7878 100644 --- a/PyPowerFlex/objects/sdt.py +++ b/PyPowerFlex/objects/sdt.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for interacting with SDT APIs.""" + +# pylint: disable=too-few-public-methods,no-member,too-many-arguments,too-many-positional-arguments + import logging import requests from PyPowerFlex import base_client @@ -37,7 +41,7 @@ def __init__(self, ip, role): }, dump=False, ) - super(SdtIp, self).__init__(**params) + super().__init__(**params) class SdtIpRoles: @@ -49,7 +53,9 @@ class SdtIpRoles: class Sdt(base_client.EntityRequest): - + """ + A class representing SDT client. + """ def create( self, sdt_ips, @@ -70,14 +76,14 @@ def create( :rtype: dict """ - params = dict( - ips=sdt_ips, - storagePort=storage_port, - nvmePort=nvme_port, - discoveryPort=discovery_port, - name=sdt_name, - protectionDomainId=protection_domain_id, - ) + params = { + "ips": sdt_ips, + "storagePort": storage_port, + "nvmePort": nvme_port, + "discoveryPort": discovery_port, + "name": sdt_name, + "protectionDomainId": protection_domain_id, + } return self._create_entity(params) @@ -91,7 +97,7 @@ def rename(self, sdt_id, name): action = "renameSdt" - params = dict(newName=name) + params = {'newName': name} return self._rename_entity(action, sdt_id, params) @@ -106,10 +112,10 @@ def add_ip(self, sdt_id, ip, role): action = "addIp" - params = dict( - ip=ip, - role=role, - ) + params = { + "ip": ip, + "role": role, + } r, response = self.send_post_request( self.base_action_url, @@ -120,10 +126,8 @@ def add_ip(self, sdt_id, ip, role): ) if r.status_code != requests.codes.ok: msg = ( - "Failed to add IP for PowerFlex {entity} " - "with id {_id}. Error: {response}".format( - entity=self.entity, _id=sdt_id, response=response - ) + f"Failed to add IP for PowerFlex {self.entity} " + f"with id {sdt_id}. Error: {response}" ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -140,7 +144,7 @@ def remove_ip(self, sdt_id, ip): action = "removeIp" - params = dict(ip=ip) + params = {"ip": ip} r, response = self.send_post_request( self.base_action_url, @@ -150,12 +154,8 @@ def remove_ip(self, sdt_id, ip): params=params, ) if r.status_code != requests.codes.ok: - msg = ( - "Failed to remove IP from PowerFlex {entity} " - "with id {_id}. Error: {response}".format( - entity=self.entity, _id=sdt_id, response=response - ) - ) + msg = f"Failed to remove IP from PowerFlex {self.entity} " \ + f"with id {sdt_id}. Error: {response}" LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -173,10 +173,10 @@ def set_ip_role(self, sdt_id, ip, role): action = "modifyIpRole" - params = dict( - ip=ip, - newRole=role, - ) + params = { + "ip": ip, + "newRole": role + } r, response = self.send_post_request( self.base_action_url, @@ -186,12 +186,8 @@ def set_ip_role(self, sdt_id, ip, role): params=params, ) if r.status_code != requests.codes.ok: - msg = ( - "Failed to set ip role for PowerFlex {entity} " - "with id {_id}. Error: {response}".format( - entity=self.entity, _id=sdt_id, response=response - ) - ) + msg = f"Failed to set ip role for PowerFlex {self.entity} " \ + f"with id {sdt_id}. Error: {response}" LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -207,7 +203,7 @@ def set_storage_port(self, sdt_id, storage_port): action = "modifyStoragePort" - params = dict(newStoragePort=storage_port) + params = {"newStoragePort": storage_port} r, response = self.send_post_request( self.base_action_url, @@ -218,10 +214,8 @@ def set_storage_port(self, sdt_id, storage_port): ) if r.status_code != requests.codes.ok: msg = ( - "Failed to set storage port for PowerFlex {entity} " - "with id {_id}. Error: {response}".format( - entity=self.entity, _id=sdt_id, response=response - ) + f"Failed to set storage port for PowerFlex {self.entity} " + f"with id {sdt_id}. Error: {response}" ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -238,7 +232,7 @@ def set_nvme_port(self, sdt_id, nvme_port): action = "modifyNvmePort" - params = dict(newNvmePort=nvme_port) + params = {"newNvmePort": nvme_port} r, response = self.send_post_request( self.base_action_url, @@ -249,10 +243,8 @@ def set_nvme_port(self, sdt_id, nvme_port): ) if r.status_code != requests.codes.ok: msg = ( - "Failed to set nvme port for PowerFlex {entity} " - "with id {_id}. Error: {response}".format( - entity=self.entity, _id=sdt_id, response=response - ) + f"Failed to set nvme port for PowerFlex {self.entity} " + f"with id {sdt_id}. Error: {response}" ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -269,7 +261,7 @@ def set_discovery_port(self, sdt_id, discovery_port): action = "modifyDiscoveryPort" - params = dict(newDiscoveryPort=discovery_port) + params = {"newDiscoveryPort": discovery_port} r, response = self.send_post_request( self.base_action_url, @@ -280,10 +272,8 @@ def set_discovery_port(self, sdt_id, discovery_port): ) if r.status_code != requests.codes.ok: msg = ( - "Failed to set discovery port for PowerFlex {entity} " - "with id {_id}. Error: {response}".format( - entity=self.entity, _id=sdt_id, response=response - ) + f"Failed to set discovery port for PowerFlex {self.entity} " + f"with id {sdt_id}. Error: {response}" ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -308,10 +298,8 @@ def enter_maintenance_mode(self, sdt_id): ) if r.status_code != requests.codes.ok: msg = ( - "Failed to enter maintenance mode for PowerFlex {entity} " - "with id {_id}. Error: {response}".format( - entity=self.entity, _id=sdt_id, response=response - ) + f"Failed to enter maintenance mode for PowerFlex {self.entity} " + f"with id {sdt_id}. Error: {response}" ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -336,10 +324,8 @@ def exit_maintenance_mode(self, sdt_id): ) if r.status_code != requests.codes.ok: msg = ( - "Failed to exit maintenance mode for PowerFlex {entity} " - "with id {_id}. Error: {response}".format( - entity=self.entity, _id=sdt_id, response=response - ) + f"Failed to exit maintenance mode for PowerFlex {self.entity} " + f"with id {sdt_id}. Error: {response}" ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -354,6 +340,6 @@ def delete(self, sdt_id, force=None): :rtype: None """ - params = dict(force=force) + params = {"force": force} return self._delete_entity(sdt_id, params) diff --git a/PyPowerFlex/objects/service_template.py b/PyPowerFlex/objects/service_template.py index 66d138c..4997426 100644 --- a/PyPowerFlex/objects/service_template.py +++ b/PyPowerFlex/objects/service_template.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for interacting with service template APIs.""" + +# pylint: disable=arguments-renamed,no-member,too-many-arguments,too-many-positional-arguments + import logging import requests from PyPowerFlex import base_client @@ -20,8 +24,19 @@ from PyPowerFlex import utils LOG = logging.getLogger(__name__) + class ServiceTemplate(base_client.EntityRequest): - def get(self, filters=None, full=None, limit=None, offset=None, sort=None, include_attachments=None): + """ + A class representing Service Template client. + """ + def get( + self, + filters=None, + full=None, + limit=None, + offset=None, + sort=None, + include_attachments=None): """ Retrieve all Service Templates with filter, sort, pagination :param filters: (Optional) The filters to apply to the results. @@ -32,17 +47,19 @@ def get(self, filters=None, full=None, limit=None, offset=None, sort=None, inclu :param include_attachments: (Optional) Whether to include attachments. :return: A list of dictionary containing the retrieved Service Templates. """ - params = dict( - filter=filters, - full=full, - limit=limit, - offset=offset, - sort=sort, - includeAttachments=include_attachments - ) - r, response = self.send_get_request(utils.build_uri_with_params(self.service_template_url, **params)) + params = { + "filter": filters, + "full": full, + "limit": limit, + "offset": offset, + "sort": sort, + "includeAttachments": include_attachments + } + r, response = self.send_get_request( + utils.build_uri_with_params( + self.service_template_url, **params)) if r.status_code != requests.codes.ok: - msg = (f'Failed to retrieve service templates. Error: {response}') + msg = f'Failed to retrieve service templates. Error: {response}' LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return response @@ -59,7 +76,10 @@ def get_by_id(self, service_template_id, for_deployment=False): url += '?forDeployment=true' r, response = self.send_get_request(url) if r.status_code != requests.codes.ok: - msg = (f'Failed to retrieve service template by id {service_template_id}. Error: {response}') + msg = ( + f'Failed to retrieve service template by id {service_template_id}. ' + f'Error: {response}' + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return response diff --git a/PyPowerFlex/objects/snapshot_policy.py b/PyPowerFlex/objects/snapshot_policy.py index ab7fe95..58c4efd 100644 --- a/PyPowerFlex/objects/snapshot_policy.py +++ b/PyPowerFlex/objects/snapshot_policy.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for interacting with snapshot policy APIs.""" + +# pylint: disable=too-few-public-methods,no-member,too-many-arguments,too-many-positional-arguments,duplicate-code + import logging import requests @@ -32,6 +36,9 @@ class AutoSnapshotRemovalAction: class SnapshotPolicy(base_client.EntityRequest): + """ + A class representing Snapshot Policy client. + """ def add_source_volume(self, snapshot_policy_id, volume_id): """Add source volume to PowerFlex snapshot policy. @@ -42,9 +49,7 @@ def add_source_volume(self, snapshot_policy_id, volume_id): action = 'addSourceVolumeToSnapshotPolicy' - params = dict( - sourceVolumeId=volume_id - ) + params = {"sourceVolumeId": volume_id} r, response = self.send_post_request(self.base_action_url, action=action, @@ -52,11 +57,11 @@ def add_source_volume(self, snapshot_policy_id, volume_id): entity_id=snapshot_policy_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to add source volume to PowerFlex {entity} ' - 'with id {_id}. ' - 'Error: {response}'.format(entity=self.entity, - _id=snapshot_policy_id, - response=response)) + msg = ( + f"Failed to add source volume to PowerFlex {self.entity} " + f"with id {snapshot_policy_id}. " + f"Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -67,8 +72,8 @@ def create(self, retained_snaps_per_level, name=None, paused=None, - snapshotAccessMode=None, - secureSnapshots=None): + snapshot_access_mode=None, + secure_snapshots=None): """Create PowerFlex snapshot policy. :type auto_snap_creation_cadence_in_min: int @@ -78,12 +83,14 @@ def create(self, :rtype: dict """ - params = dict( - autoSnapshotCreationCadenceInMin=auto_snap_creation_cadence_in_min, - numOfRetainedSnapshotsPerLevel=retained_snaps_per_level, - name=name, paused=paused, snapshotAccessMode=snapshotAccessMode, - secureSnapshots=secureSnapshots - ) + params = { + "autoSnapshotCreationCadenceInMin": auto_snap_creation_cadence_in_min, + "numOfRetainedSnapshotsPerLevel": retained_snaps_per_level, + "name": name, + "paused": paused, + "snapshotAccessMode": snapshot_access_mode, + "secureSnapshots": secure_snapshots + } return self._create_entity(params) @@ -110,10 +117,10 @@ def modify(self, action = 'modifySnapshotPolicy' - params = dict( - autoSnapshotCreationCadenceInMin=auto_snap_creation_cadence_in_min, - numOfRetainedSnapshotsPerLevel=retained_snaps_per_level - ) + params = { + "autoSnapshotCreationCadenceInMin": auto_snap_creation_cadence_in_min, + "numOfRetainedSnapshotsPerLevel": retained_snaps_per_level + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -121,11 +128,10 @@ def modify(self, entity_id=snapshot_policy_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to modify PowerFlex {entity} ' - 'with id {_id}. ' - 'Error: {response}'.format(entity=self.entity, - _id=snapshot_policy_id, - response=response)) + msg = ( + f"Failed to modify PowerFlex {self.entity} with id {snapshot_policy_id}. " + f"Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -145,10 +151,10 @@ def pause(self, snapshot_policy_id): entity=self.entity, entity_id=snapshot_policy_id) if r.status_code != requests.codes.ok: - msg = ('Failed to pause PowerFlex {entity} with id {_id}.' - ' Error: {response}'.format(entity=self.entity, - _id=snapshot_policy_id, - response=response)) + msg = ( + f"Failed to pause PowerFlex {self.entity} with id {snapshot_policy_id}. " + f"Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -172,11 +178,11 @@ def remove_source_volume(self, action = 'removeSourceVolumeFromSnapshotPolicy' - params = dict( - sourceVolumeId=volume_id, - autoSnapshotRemovalAction=auto_snap_removal_action, - detachLockedAutoSnapshots=detach_locked_auto_snaps - ) + params = { + "sourceVolumeId": volume_id, + "autoSnapshotRemovalAction": auto_snap_removal_action, + "detachLockedAutoSnapshots": detach_locked_auto_snaps + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -184,11 +190,11 @@ def remove_source_volume(self, entity_id=snapshot_policy_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to remove source volume from PowerFlex {entity} ' - 'with id {_id}. ' - 'Error: {response}'.format(entity=self.entity, - _id=snapshot_policy_id, - response=response)) + msg = ( + f"Failed to remove source volume from PowerFlex {self.entity} " + f"with id {snapshot_policy_id}. " + f"Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -204,9 +210,9 @@ def rename(self, snapshot_policy_id, name): action = 'renameSnapshotPolicy' - params = dict( - newName=name - ) + params = { + "newName": name + } return self._rename_entity(action, snapshot_policy_id, params) @@ -224,10 +230,10 @@ def resume(self, snapshot_policy_id): entity=self.entity, entity_id=snapshot_policy_id) if r.status_code != requests.codes.ok: - msg = ('Failed to resume PowerFlex {entity} with id {_id}. ' - 'Error: {response}'.format(entity=self.entity, - _id=snapshot_policy_id, - response=response)) + msg = ( + f"Failed to resume PowerFlex {self.entity} with id {snapshot_policy_id}. " + f"Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -256,7 +262,7 @@ def query_selected_statistics(self, properties, ids=None): action = "querySelectedStatistics" - params = dict(properties=properties) + params = {'properties': properties} if ids: params["ids"] = ids diff --git a/PyPowerFlex/objects/storage_pool.py b/PyPowerFlex/objects/storage_pool.py index 2992030..149b19c 100644 --- a/PyPowerFlex/objects/storage_pool.py +++ b/PyPowerFlex/objects/storage_pool.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for interacting with storage pool APIs.""" + +# pylint: disable=too-few-public-methods,too-many-public-methods,no-member,too-many-arguments,too-many-positional-arguments,too-many-locals,cyclic-import,duplicate-code + import logging import requests @@ -66,6 +70,9 @@ class RmcacheWriteHandlingMode: class StoragePool(base_client.EntityRequest): + """ + A class representing Storage Pool client. + """ def create(self, media_type, protection_domain_id, @@ -108,21 +115,21 @@ def create(self, if data_layout == DataLayout.fine and not fgl_accp_id: msg = 'fgl_accp_id must be set for Fine Granular Storage Pool.' raise exceptions.InvalidInput(msg) - params = dict( - mediaType=media_type, - protectionDomainId=protection_domain_id, - checksumEnabled=checksum_enabled, - compressionMethod=compression_method, - dataLayout=data_layout, - externalAccelerationType=external_acceleration_type, - fglAccpId=fgl_accp_id, - name=name, - rmcacheWriteHandlingMode=rmcache_write_handling_mode, - sparePercentage=spare_percentage, - useRfcache=use_rfcache, - useRmcache=use_rmcache, - zeroPaddingEnabled=zero_padding_enabled - ) + params = { + "mediaType": media_type, + "protectionDomainId": protection_domain_id, + "checksumEnabled": checksum_enabled, + "compressionMethod": compression_method, + "dataLayout": data_layout, + "externalAccelerationType": external_acceleration_type, + "fglAccpId": fgl_accp_id, + "name": name, + "rmcacheWriteHandlingMode": rmcache_write_handling_mode, + "sparePercentage": spare_percentage, + "useRfcache": use_rfcache, + "useRmcache": use_rmcache, + "zeroPaddingEnabled": zero_padding_enabled + } return self._create_entity(params) @@ -207,10 +214,7 @@ def rename(self, storage_pool_id, name): action = 'setStoragePoolName' - params = dict( - name=name - ) - + params = {"name": name} return self._rename_entity(action, storage_pool_id, params) def set_checksum_enabled(self, storage_pool_id, checksum_enabled): @@ -223,9 +227,7 @@ def set_checksum_enabled(self, storage_pool_id, checksum_enabled): action = 'setChecksumEnabled' - params = dict( - checksumEnabled=checksum_enabled - ) + params = {"checksumEnabled": checksum_enabled} r, response = self.send_post_request(self.base_action_url, action=action, @@ -233,8 +235,9 @@ def set_checksum_enabled(self, storage_pool_id, checksum_enabled): entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: - msg = (f'Failed to enable/disable checksum for PowerFlex {self.entity} ' - f'with id {storage_pool_id}. Error: {response}') + msg = ( + f'Failed to enable/disable checksum for PowerFlex {self.entity} ' + f'with id {storage_pool_id}. Error: {response}') LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -250,9 +253,9 @@ def set_compression_method(self, storage_pool_id, compression_method): action = 'modifyCompressionMethod' - params = dict( - compressionMethod=compression_method - ) + params = { + "compressionMethod": compression_method + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -260,8 +263,9 @@ def set_compression_method(self, storage_pool_id, compression_method): entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: - msg = (f'Failed to set compression method for PowerFlex {self.entity} ' - f'with id {storage_pool_id}. Error: {response}') + msg = ( + f'Failed to set compression method for PowerFlex {self.entity} ' + f'with id {storage_pool_id}. Error: {response}') LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -291,11 +295,11 @@ def set_external_acceleration_type( msg = ('Either override_device_configuration or ' 'keep_device_specific_external_acceleration can be set.') raise exceptions.InvalidInput(msg) - params = dict( - externalAccelerationType=external_acceleration_type, - overrideDeviceConfiguration=override_device_configuration, - keepDeviceSpecificExternalAcceleration=keep_device_ext_acceleration - ) + params = { + "externalAccelerationType": external_acceleration_type, + "overrideDeviceConfiguration": override_device_configuration, + "keepDeviceSpecificExternalAcceleration": keep_device_ext_acceleration + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -325,10 +329,10 @@ def set_media_type(self, action = 'setMediaType' - params = dict( - mediaType=media_type, - overrideDeviceConfiguration=override_device_configuration - ) + params = { + "mediaType": media_type, + "overrideDeviceConfiguration": override_device_configuration + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -353,19 +357,19 @@ def set_rebalance_enabled(self, storage_pool_id, rebalance_enabled): action = 'setRebalanceEnabled' - params = dict( - rebalanceEnabled=rebalance_enabled - ) + params = { + "rebalanceEnabled": rebalance_enabled + } - r, response = self.send_post_request(self.base_action_url, + r, _ = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: - msg = (f'Failed to enable/disable rebalance for PowerFlex {self.entity}' - ' with id {storage_pool_id}. Error: {response}' - ) + msg = ( + f'Failed to enable/disable rebalance for PowerFlex {self.entity}' + ' with id {storage_pool_id}. Error: {response}') LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -381,9 +385,9 @@ def set_rebuild_enabled(self, storage_pool_id, rebuild_enabled): action = 'setRebuildEnabled' - params = dict( - rebuildEnabled=rebuild_enabled - ) + params = { + "rebuildEnabled": rebuild_enabled + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -391,8 +395,9 @@ def set_rebuild_enabled(self, storage_pool_id, rebuild_enabled): entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: - msg = (f'Failed to enable/disable rebuild for PowerFlex {self.entity} ' - f'with id {storage_pool_id}. Error: {response}') + msg = ( + f'Failed to enable/disable rebuild for PowerFlex {self.entity} ' + f'with id {storage_pool_id}. Error: {response}') LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -408,9 +413,9 @@ def set_spare_percentage(self, storage_pool_id, spare_percentage): action = 'setSparePercentage' - params = dict( - sparePercentage=spare_percentage - ) + params = { + "sparePercentage": spare_percentage + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -418,8 +423,9 @@ def set_spare_percentage(self, storage_pool_id, spare_percentage): entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: - msg = (f'Failed to set spare percentage for PowerFlex {self.entity} ' - f'with id {storage_pool_id}. Error: {response}') + msg = ( + f'Failed to set spare percentage for PowerFlex {self.entity} ' + f'with id {storage_pool_id}. Error: {response}') LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -459,9 +465,9 @@ def set_use_rmcache(self, storage_pool_id, use_rmcache): action = 'setUseRmcache' - params = dict( - useRmcache=use_rmcache - ) + params = { + "useRmcache": use_rmcache + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -487,9 +493,7 @@ def set_zero_padding_policy(self, storage_pool_id, zero_padding_enabled): action = 'setZeroPaddingPolicy' - params = dict( - zeroPadEnabled=zero_padding_enabled - ) + params = {"zeroPadEnabled": zero_padding_enabled} r, response = self.send_post_request(self.base_action_url, action=action, @@ -497,8 +501,9 @@ def set_zero_padding_policy(self, storage_pool_id, zero_padding_enabled): entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: - msg = (f'Failed to set Zero Padding policy for PowerFlex {self.entity} ' - f'with id {storage_pool_id}. Error: {response}') + msg = ( + f'Failed to set Zero Padding policy for PowerFlex {self.entity} ' + f'with id {storage_pool_id}. Error: {response}') LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -514,9 +519,9 @@ def set_rep_cap_max_ratio(self, storage_pool_id, rep_cap_max_ratio): action = 'setReplicationJournalCapacity' - params = dict( - replicationJournalCapacityMaxRatio=rep_cap_max_ratio - ) + params = { + "replicationJournalCapacityMaxRatio": rep_cap_max_ratio + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -524,15 +529,19 @@ def set_rep_cap_max_ratio(self, storage_pool_id, rep_cap_max_ratio): entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: - msg = (f'Failed to set the replication journal capacity ratio for PowerFlex {self.entity} ' - f'with id {storage_pool_id}. Error: {response}') + msg = ( + f'Failed to set the replication journal capacity ratio for PowerFlex {self.entity}' + f'with id {storage_pool_id}. Error: {response}') LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=storage_pool_id) - - def set_cap_alert_thresholds(self, storage_pool_id, cap_alert_high_threshold, cap_alert_critical_threshold): + def set_cap_alert_thresholds( + self, + storage_pool_id, + cap_alert_high_threshold, + cap_alert_critical_threshold): """Set the capacity alert thresholds on the specified Storage Pool. :type storage_pool_id: str @@ -543,10 +552,10 @@ def set_cap_alert_thresholds(self, storage_pool_id, cap_alert_high_threshold, ca action = 'setCapacityAlertThresholds' - params = dict( - capacityAlertHighThresholdPercent=cap_alert_high_threshold, - capacityAlertCriticalThresholdPercent=cap_alert_critical_threshold - ) + params = { + "capacityAlertHighThresholdPercent": cap_alert_high_threshold, + "capacityAlertCriticalThresholdPercent": cap_alert_critical_threshold + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -554,14 +563,16 @@ def set_cap_alert_thresholds(self, storage_pool_id, cap_alert_high_threshold, ca entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: - msg = (f'Failed to set the capacity alert thresholds for PowerFlex {self.entity} ' - f'with id {storage_pool_id}. Error: {response}') + msg = ( + f'Failed to set the capacity alert thresholds for PowerFlex {self.entity}' + f'with id {storage_pool_id}. Error: {response}') LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=storage_pool_id) - def set_protected_maintenance_mode_io_priority_policy(self, storage_pool_id, policy, concurrent_ios_per_device, bw_limit_per_device): + def set_protected_maintenance_mode_io_priority_policy( + self, storage_pool_id, policy, concurrent_ios_per_device, bw_limit_per_device): """Set protected maintenance mode I/O priority policy. :type storage_pool_id: str @@ -573,11 +584,11 @@ def set_protected_maintenance_mode_io_priority_policy(self, storage_pool_id, pol action = 'setProtectedMaintenanceModeIoPriorityPolicy' - params = dict( - policy=policy, - numOfConcurrentIosPerDevice=concurrent_ios_per_device, - bwLimitPerDeviceInKbps=bw_limit_per_device - ) + params = { + 'policy': policy, + 'numOfConcurrentIosPerDevice': concurrent_ios_per_device, + 'bwLimitPerDeviceInKbps': bw_limit_per_device + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -585,15 +596,21 @@ def set_protected_maintenance_mode_io_priority_policy(self, storage_pool_id, pol entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: - msg = (f'Failed to set the protected maintenance mode IO priority policy for PowerFlex {self.entity} ' - f'with id {storage_pool_id}. Error: {response}') + msg = ( + f'Failed to set the protected maintenance mode IO priority policy for ' + f'PowerFlex {self.entity} with id {storage_pool_id}. Error: {response}' + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=storage_pool_id) - - def set_vtree_migration_io_priority_policy(self, storage_pool_id, policy, concurrent_ios_per_device, bw_limit_per_device): + def set_vtree_migration_io_priority_policy( + self, + storage_pool_id, + policy, + concurrent_ios_per_device, + bw_limit_per_device): """Set the vtree migration I/O priority policy on the specified Storage Pool. :type storage_pool_id: str @@ -605,11 +622,11 @@ def set_vtree_migration_io_priority_policy(self, storage_pool_id, policy, concur action = 'setVTreeMigrationIoPriorityPolicy' - params = dict( - policy=policy, - numOfConcurrentIosPerDevice=concurrent_ios_per_device, - bwLimitPerDeviceInKbps=bw_limit_per_device - ) + params = { + "policy": policy, + "numOfConcurrentIosPerDevice": concurrent_ios_per_device, + "bwLimitPerDeviceInKbps": bw_limit_per_device + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -617,14 +634,20 @@ def set_vtree_migration_io_priority_policy(self, storage_pool_id, policy, concur entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: - msg = (f'Failed to set VTree migration I/O priority policy for PowerFlex {self.entity} ' - f'with id {storage_pool_id}. Error: {response}') + msg = ( + f'Failed to set VTree migration I/O priority policy for PowerFlex {self.entity} ' + f'with id {storage_pool_id}. Error: {response}') LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=storage_pool_id) - def rebalance_io_priority_policy(self, storage_pool_id, policy, concurrent_ios_per_device, bw_limit_per_device): + def rebalance_io_priority_policy( + self, + storage_pool_id, + policy, + concurrent_ios_per_device, + bw_limit_per_device): """Set the rebalance I/O priority policy on the specified Storage Pool. :type storage_pool_id: str @@ -636,11 +659,11 @@ def rebalance_io_priority_policy(self, storage_pool_id, policy, concurrent_ios_p action = 'setRebalanceIoPriorityPolicy' - params = dict( - policy=policy, - numOfConcurrentIosPerDevice=concurrent_ios_per_device, - bwLimitPerDeviceInKbps=bw_limit_per_device - ) + params = { + 'policy': policy, + 'numOfConcurrentIosPerDevice': concurrent_ios_per_device, + 'bwLimitPerDeviceInKbps': bw_limit_per_device + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -648,14 +671,16 @@ def rebalance_io_priority_policy(self, storage_pool_id, policy, concurrent_ios_p entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: - msg = (f'Failed to set the rebalance I/O priority policy for PowerFlex {self.entity} ' - f'with id {storage_pool_id}. Error: {response}') + msg = ( + f'Failed to set the rebalance I/O priority policy for PowerFlex {self.entity} ' + f'with id {storage_pool_id}. Error: {response}') LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=storage_pool_id) - def set_rmcache_write_handling_mode(self, storage_pool_id, rmcache_write_handling_mode): + def set_rmcache_write_handling_mode( + self, storage_pool_id, rmcache_write_handling_mode): """Set the RM cache write handling mode on the specified Storage Pool. :type storage_pool_id: str @@ -665,9 +690,9 @@ def set_rmcache_write_handling_mode(self, storage_pool_id, rmcache_write_handlin action = 'setRmcacheWriteHandlingMode' - params = dict( - rmcacheWriteHandlingMode=rmcache_write_handling_mode - ) + params = { + 'rmcacheWriteHandlingMode': rmcache_write_handling_mode + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -675,14 +700,16 @@ def set_rmcache_write_handling_mode(self, storage_pool_id, rmcache_write_handlin entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: - msg = (f'Failed to set the RM cache write handling mode for PowerFlex {self.entity} ' - f'with id {storage_pool_id}. Error: {response}') + msg = ( + f'Failed to set the RM cache write handling mode for PowerFlex {self.entity} ' + f'with id {storage_pool_id}. Error: {response}') LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=storage_pool_id) - def set_rebuild_rebalance_parallelism_limit(self, storage_pool_id, no_of_parallel_rebuild_rebalance_jobs_per_device): + def set_rebuild_rebalance_parallelism_limit( + self, storage_pool_id, no_of_parallel_rebuild_rebalance_jobs_per_device): """Set the rebuild rebalance parallelism limit on the specified Storage Pool. :type storage_pool_id: str @@ -692,9 +719,9 @@ def set_rebuild_rebalance_parallelism_limit(self, storage_pool_id, no_of_paralle action = 'setRebuildRebalanceParallelism' - params = dict( - limit=no_of_parallel_rebuild_rebalance_jobs_per_device - ) + params = { + "limit": no_of_parallel_rebuild_rebalance_jobs_per_device + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -702,14 +729,20 @@ def set_rebuild_rebalance_parallelism_limit(self, storage_pool_id, no_of_paralle entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: - msg = (f'Failed to set rebuild rebalance parallelism limit for PowerFlex {self.entity} ' - f'with id {storage_pool_id}. Error: {response}') + msg = ( + f'Failed to set rebuild rebalance parallelism limit for PowerFlex {self.entity} ' + f'with id {storage_pool_id}. Error: {response}') LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=storage_pool_id) - def set_persistent_checksum(self, storage_pool_id, enable, validate, builder_limit): + def set_persistent_checksum( + self, + storage_pool_id, + enable, + validate, + builder_limit): """Set the persistent_checksum on the specified Storage Pool. :type storage_pool_id: str @@ -722,11 +755,8 @@ def set_persistent_checksum(self, storage_pool_id, enable, validate, builder_lim action = 'disablePersistentChecksum' params = None if enable is True: - action='enablePersistentChecksum' - params = dict( - validateOnRead=validate, - builderLimitInKb=builder_limit - ) + action = 'enablePersistentChecksum' + params = {"validateOnRead": validate, "builderLimitInKb": builder_limit} r, response = self.send_post_request(self.base_action_url, action=action, @@ -734,15 +764,19 @@ def set_persistent_checksum(self, storage_pool_id, enable, validate, builder_lim entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: - msg = (f'Failed to set the persistent checksum for PowerFlex {self.entity} ' - f'with id {storage_pool_id}. Error: {response}') + msg = ( + f'Failed to set the persistent checksum for PowerFlex {self.entity} ' + f'with id {storage_pool_id}. Error: {response}') LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return self.get(entity_id=storage_pool_id) - - def modify_persistent_checksum(self, storage_pool_id, validate, builder_limit): + def modify_persistent_checksum( + self, + storage_pool_id, + validate, + builder_limit): """Modify the persistent_checksum on the specified Storage Pool. :type storage_pool_id: str @@ -752,10 +786,10 @@ def modify_persistent_checksum(self, storage_pool_id, validate, builder_limit): """ action = 'modifyPersistentChecksum' - params = dict( - validateOnRead=validate, - builderLimitInKb=builder_limit - ) + params = { + "validateOnRead": validate, + "builderLimitInKb": builder_limit + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -763,8 +797,9 @@ def modify_persistent_checksum(self, storage_pool_id, validate, builder_limit): entity_id=storage_pool_id, params=params) if r.status_code != requests.codes.ok: - msg = (f'Failed to modify the persistent checksum for PowerFlex {self.entity} ' - f'with id {storage_pool_id}. Error: {response}') + msg = ( + f'Failed to modify the persistent checksum for PowerFlex {self.entity} ' + f'with id {storage_pool_id}. Error: {response}') LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -782,14 +817,14 @@ def set_fragmentation_enabled(self, storage_pool_id, enable_fragmentation): if enable_fragmentation: action = 'enableFragmentation' - r, response = self.send_post_request(self.base_action_url, action=action, entity=self.entity, entity_id=storage_pool_id) if r.status_code != requests.codes.ok: - msg = (f'Failed to enable/disable fragmentation for PowerFlex {self.entity} ' - f'with id {storage_pool_id}. Error: {response}') + msg = ( + f'Failed to enable/disable fragmentation for PowerFlex {self.entity} ' + f'with id {storage_pool_id}. Error: {response}') LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -805,7 +840,7 @@ def query_selected_statistics(self, properties, ids=None): action = "querySelectedStatistics" - params = dict(properties=properties) + params = {'properties': properties} if ids: params["ids"] = ids diff --git a/PyPowerFlex/objects/system.py b/PyPowerFlex/objects/system.py index 1e18d64..40b7957 100644 --- a/PyPowerFlex/objects/system.py +++ b/PyPowerFlex/objects/system.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for doing system-related operations.""" + +# pylint: disable=no-member,too-many-arguments,too-many-positional-arguments + import logging import re @@ -47,13 +51,14 @@ def __init__(self, volume_id, name=None): }, dump=False ) - super(SnapshotDef, self).__init__(**params) + super().__init__(**params) class System(base_client.EntityRequest): + """Client for system operations""" def __init__(self, token, configuration): self.__api_version = None - super(System, self).__init__(token, configuration) + super().__init__(token, configuration) def api_version(self, cached=True): """Get PowerFlex API version. @@ -74,8 +79,8 @@ def api_version(self, cached=True): pattern = re.compile(r'^\d+(\.\d+)*$') if not pattern.match(response): msg = ( - 'Failed to query PowerFlex API version. Invalid version ' - 'format: {response}.'.format(response=r.text) + f"Failed to query PowerFlex API version. Invalid version " + f"format: {response}." ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -93,10 +98,10 @@ def remove_cg_snapshots(self, system_id, cg_id, allow_ext_managed=None): action = 'removeConsistencyGroupSnapshots' - params = dict( - snapGroupId=cg_id, - allowOnExtManagedVol=allow_ext_managed - ) + params = { + "snapGroupId": cg_id, + "allowOnExtManagedVol": allow_ext_managed + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -104,11 +109,11 @@ def remove_cg_snapshots(self, system_id, cg_id, allow_ext_managed=None): entity_id=system_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to remove consistency group snapshots from ' - 'PowerFlex {entity} with id {_id}. ' - 'Error: {response}'.format(entity=self.entity, - _id=system_id, - response=response)) + msg = ( + f"Failed to remove consistency group snapshots from " + f"PowerFlex {self.entity} with id {system_id}. " + f"Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -132,12 +137,12 @@ def snapshot_volumes(self, action = 'snapshotVolumes' - params = dict( - snapshotDefs=snapshot_defs, - allowOnExtManagedVol=allow_ext_managed, - accessModeLimit=access_mode, - retentionPeriodInMin=retention_period - ) + params = { + 'snapshotDefs': snapshot_defs, + 'allowOnExtManagedVol': allow_ext_managed, + 'accessModeLimit': access_mode, + 'retentionPeriodInMin': retention_period + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -145,11 +150,10 @@ def snapshot_volumes(self, entity_id=system_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to snapshot volumes on PowerFlex {entity} ' - 'with id {_id}.' - ' Error: {response}'.format(entity=self.entity, - _id=system_id, - response=response)) + msg = ( + f"Failed to snapshot volumes on PowerFlex {self.entity} " + f"with id {system_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -184,25 +188,24 @@ def add_standby_mdm(self, mdm_ips, role, management_ips=None, port=None, :rtype: dict """ action = 'addStandbyMdm' - params = dict( - ips=mdm_ips, - role=role, - managementIps=management_ips, - name=mdm_name, - port=port, - allowAsymmetricIps=allow_multiple_ips, - forceClean=clean, - virtIpIntfs=virtual_interface - ) + params = { + "ips": mdm_ips, + "role": role, + "managementIps": management_ips, + "name": mdm_name, + "port": port, + "allowAsymmetricIps": allow_multiple_ips, + "forceClean": clean, + "virtIpIntfs": virtual_interface + } r, response = self.send_post_request(self.base_object_url, action=action, entity=self.entity, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to add standBy MDM on PowerFlex {entity}. ' - 'Error: {response}'.format(entity=self.entity, - response=response)) + msg = f"Failed to add standBy MDM on PowerFlex {self.entity}. " \ + f"Error: {response}" LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -216,18 +219,19 @@ def remove_standby_mdm(self, mdm_id): :return: None """ action = 'removeStandbyMdm' - params = dict( - id=mdm_id - ) + params = { + "id": mdm_id + } r, response = self.send_mdm_cluster_post_request(self.base_object_url, action=action, entity=self.entity, params=params) if r.status_code != requests.codes.ok and response is not None: - msg = ('Failed to remove standBy MDM from PowerFlex {entity}. ' - 'Error: {response}.'.format(entity=self.entity, - response=response)) + msg = ( + f"Failed to remove standBy MDM from PowerFlex {self.entity}. " + f"Error: {response}." + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -243,9 +247,10 @@ def get_mdm_cluster_details(self): r, response = self.send_post_request(self.query_mdm_cluster_url, entity=self.entity) if r.status_code != requests.codes.ok: - msg = ('Failed to get MDM cluster details on PowerFlex {entity}. ' - 'Error: {response}'.format(entity=self.entity, - response=response)) + msg = ( + f"Failed to get MDM cluster details on PowerFlex {self.entity}. " + f"Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -260,9 +265,10 @@ def get_gateway_configuration_details(self): r, response = self.send_get_request('/Configuration') if r.status_code != requests.codes.ok: - msg = ('Failed to get gateway configuration details on PowerFlex {entity}. ' - 'Error: {response}'.format(entity=self.entity, - response=response)) + msg = ( + f"Failed to get gateway configuration details on PowerFlex {self.entity}. " + f"Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -278,18 +284,19 @@ def change_mdm_ownership(self, mdm_id): :rtype: dict """ action = 'changeMdmOwnership' - params = dict( - id=mdm_id - ) + params = { + "id": mdm_id + } r, response = self.send_post_request(self.base_object_url, action=action, entity=self.entity, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to change ownership on PowerFlex {entity}. ' - 'Error: {response}'.format(entity=self.entity, - response=response)) + msg = ( + f"Failed to change ownership on PowerFlex {self.entity}. " + f"Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -303,18 +310,17 @@ def set_cluster_mdm_performance_profile(self, performance_profile): :rtype: dict """ action = 'setMdmPerformanceParameters' - params = dict( - perfProfile=performance_profile - ) + params = {"perfProfile": performance_profile} r, response = self.send_post_request(self.base_object_url, action=action, entity=self.entity, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to set performance profile of MDMs on PowerFlex ' - '{entity}. Error: {response}'.format(entity=self.entity, - response=response)) + msg = ( + f"Failed to set performance profile of MDMs on PowerFlex " + f"{self.entity}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -332,18 +338,20 @@ def rename_mdm(self, mdm_id, mdm_new_name): :rtype: dict """ action = 'renameMdm' - params = dict( - id=mdm_id, - newName=mdm_new_name - ) + params = { + "id": mdm_id, + "newName": mdm_new_name + } r, response = self.send_post_request(self.base_object_url, action=action, entity=self.entity, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to rename the MDM on PowerFlex {entity}. Error: ' - '{response}'.format(entity=self.entity, response=response)) + msg = ( + f"Failed to rename the MDM on PowerFlex {self.entity}. " + f"Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -366,31 +374,37 @@ def modify_virtual_ip_interface(self, mdm_id, virtual_ip_interfaces=None, """ action = 'modifyVirtualIpInterfaces' if virtual_ip_interfaces is not None: - params = dict( - id=mdm_id, - virtIpIntfs=virtual_ip_interfaces - ) + params = { + "id": mdm_id, + "virtIpIntfs": virtual_ip_interfaces + } else: - params = dict( - id=mdm_id, - clear=clear_interfaces - ) + params = { + "id": mdm_id, + "clear": clear_interfaces + } r, response = self.send_post_request(self.base_object_url, action=action, entity=self.entity, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to modify virtual IP interface on PowerFlex ' - '{entity}. Error: {response}'.format(entity=self.entity, - response=response)) + msg = ( + f"Failed to modify virtual IP interface on PowerFlex " + f"{self.entity}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return response - def switch_cluster_mode(self, cluster_mode, add_secondary=None, - remove_secondary=None, add_tb=None, remove_tb=None): + def switch_cluster_mode( + self, + cluster_mode, + add_secondary=None, + remove_secondary=None, + add_tb=None, + remove_tb=None): """ Switch cluster mode. @@ -411,22 +425,21 @@ def switch_cluster_mode(self, cluster_mode, add_secondary=None, :return: None """ action = 'switchClusterMode' - params = dict( - mode=cluster_mode, - addSlaveMdmIdList=add_secondary, - addTBIdList=add_tb, - removeSlaveMdmIdList=remove_secondary, - removeTBIdList=remove_tb - ) + params = { + "mode": cluster_mode, + "addSlaveMdmIdList": add_secondary, + "addTBIdList": add_tb, + "removeSlaveMdmIdList": remove_secondary, + "removeTBIdList": remove_tb + } r, response = self.send_mdm_cluster_post_request(self.base_object_url, action=action, entity=self.entity, params=params) if r.status_code != requests.codes.ok and response is not None: - msg = ('Failed to switch MDM cluster mode PowerFlex {entity}. ' - 'Error: {response}.'.format(entity=self.entity, - response=response)) + msg = f"Failed to switch MDM cluster mode PowerFlex {self.entity}. " \ + f"Error: {response}." LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -441,6 +454,6 @@ def query_selected_statistics(self, properties): action = "querySelectedStatistics" - params = dict(properties=properties) + params = {'properties': properties} return self._query_selected_statistics(action, params) diff --git a/PyPowerFlex/objects/utility.py b/PyPowerFlex/objects/utility.py index dfe04bd..db60eea 100644 --- a/PyPowerFlex/objects/utility.py +++ b/PyPowerFlex/objects/utility.py @@ -13,13 +13,15 @@ # License for the specific language governing permissions and limitations # under the License. +"""Utility module for PowerFlex.""" + +# pylint: disable=no-member,useless-parent-delegation import logging import requests from PyPowerFlex import base_client from PyPowerFlex import exceptions -from PyPowerFlex import utils from PyPowerFlex.constants import StoragePoolConstants, VolumeConstants, SnapshotPolicyConstants @@ -27,8 +29,9 @@ class PowerFlexUtility(base_client.EntityRequest): + "Utility class for PowerFlex" def __init__(self, token, configuration): - super(PowerFlexUtility, self).__init__(token, configuration) + super().__init__(token, configuration) def get_statistics_for_all_storagepools(self, ids=None, properties=None): """list storagepool statistics for PowerFlex. @@ -42,21 +45,24 @@ def get_statistics_for_all_storagepools(self, ids=None, properties=None): version = self.get_api_version() default_properties = StoragePoolConstants.DEFAULT_STATISTICS_PROPERTIES if version != '3.5': - default_properties = default_properties + StoragePoolConstants.DEFAULT_STATISTICS_PROPERTIES_ABOVE_3_5 - params = {'properties': default_properties if properties is None else properties} + default_properties = default_properties + \ + StoragePoolConstants.DEFAULT_STATISTICS_PROPERTIES_ABOVE_3_5 + params = { + 'properties': default_properties if properties is None else properties} if ids is None: params['allIds'] = "" else: params['ids'] = ids - r, response = self.send_post_request(self.list_statistics_url, entity='StoragePool', action=action, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to list storage pool statistics for PowerFlex. ' - 'Error: {response}'.format(response=response)) + msg = ( + f"Failed to list storage pool statistics for PowerFlex. " + f"Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -72,26 +78,34 @@ def get_statistics_for_all_volumes(self, ids=None, properties=None): action = 'querySelectedStatistics' - params = {'properties': VolumeConstants.DEFAULT_STATISTICS_PROPERTIES if properties is None else properties} + params = { + 'properties': ( + VolumeConstants.DEFAULT_STATISTICS_PROPERTIES + if properties is None + else properties + ) + } if ids is None: params['allIds'] = "" else: params['ids'] = ids - r, response = self.send_post_request(self.list_statistics_url, entity='Volume', action=action, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to list volume statistics for PowerFlex. ' - 'Error: {response}'.format(response=response)) + msg = ( + 'Failed to list volume statistics for PowerFlex. ' + f'Error: {response}' + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) return response - def get_statistics_for_all_snapshot_policies(self, ids=None, properties=None): + def get_statistics_for_all_snapshot_policies( + self, ids=None, properties=None): """list snapshot policy statistics for PowerFlex. :param ids: list @@ -101,20 +115,25 @@ def get_statistics_for_all_snapshot_policies(self, ids=None, properties=None): action = 'querySelectedStatistics' - params = {'properties': SnapshotPolicyConstants.DEFAULT_STATISTICS_PROPERTIES if properties is None else properties} + params = {} + if properties is None: + params['properties'] = SnapshotPolicyConstants.DEFAULT_STATISTICS_PROPERTIES + else: + params['properties'] = properties if ids is None: params['allIds'] = "" else: params['ids'] = ids - r, response = self.send_post_request(self.list_statistics_url, entity='SnapshotPolicy', action=action, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to list snapshot policy statistics for PowerFlex. ' - 'Error: {response}'.format(response=response)) + msg = ( + f"Failed to list snapshot policy statistics for PowerFlex. " + f"Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) diff --git a/PyPowerFlex/objects/volume.py b/PyPowerFlex/objects/volume.py index d7e45b1..bdaa5f7 100644 --- a/PyPowerFlex/objects/volume.py +++ b/PyPowerFlex/objects/volume.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for interacting with volume APIs.""" + +# pylint: disable=too-few-public-methods,no-member,too-many-arguments,too-many-positional-arguments,duplicate-code + import logging import requests @@ -52,6 +56,9 @@ class VolumeType: class Volume(base_client.EntityRequest): + """ + A class representing Volume client. + """ def add_mapped_sdc(self, volume_id, sdc_id=None, @@ -75,13 +82,13 @@ def add_mapped_sdc(self, if all([sdc_id, sdc_guid]) or not any([sdc_id, sdc_guid]): msg = 'Either sdc_id or sdc_guid must be set.' raise exceptions.InvalidInput(msg) - params = dict( - sdcId=sdc_id, - guid=sdc_guid, - allowMultipleMappings=allow_multiple_mappings, - allowOnExtManagedVol=allow_ext_managed, - accessMode=access_mode - ) + params = { + "sdcId": sdc_id, + "guid": sdc_guid, + "allowMultipleMappings": allow_multiple_mappings, + "allowOnExtManagedVol": allow_ext_managed, + "accessMode": access_mode + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -89,10 +96,10 @@ def add_mapped_sdc(self, entity_id=volume_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to map PowerFlex {entity} with id {_id} ' - 'to SDC. Error: {response}'.format(entity=self.entity, - _id=volume_id, - response=response)) + msg = ( + f"Failed to map PowerFlex {self.entity} with id {volume_id} " + f"to SDC. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -119,14 +126,14 @@ def create(self, :return: dict """ - params = dict( - storagePoolId=storage_pool_id, - volumeSizeInGb=size_in_gb, - name=name, - volumeType=volume_type, - useRmcache=use_rmcache, - compressionMethod=compression_method - ) + params = { + 'storagePoolId': storage_pool_id, + 'volumeSizeInGb': size_in_gb, + 'name': name, + 'volumeType': volume_type, + 'useRmcache': use_rmcache, + 'compressionMethod': compression_method + } return self._create_entity(params) @@ -139,10 +146,10 @@ def delete(self, volume_id, remove_mode, allow_ext_managed=None): :return: None """ - params = dict( - removeMode=remove_mode, - allowOnExtManagedVol=allow_ext_managed - ) + params = { + "removeMode": remove_mode, + "allowOnExtManagedVol": allow_ext_managed + } return self._delete_entity(volume_id, params) @@ -157,10 +164,7 @@ def extend(self, volume_id, size_in_gb, allow_ext_managed=None): action = 'setVolumeSize' - params = dict( - sizeInGB=size_in_gb, - allowOnExtManagedVol=allow_ext_managed - ) + params = {"sizeInGB": size_in_gb, "allowOnExtManagedVol": allow_ext_managed} r, response = self.send_post_request(self.base_action_url, action=action, @@ -168,10 +172,10 @@ def extend(self, volume_id, size_in_gb, allow_ext_managed=None): entity_id=volume_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to extend PowerFlex {entity} with id {_id}. ' - 'Error: {response}'.format(entity=self.entity, - _id=volume_id, - response=response)) + msg = ( + f"Failed to extend PowerFlex {self.entity} with id {volume_id}. " + f"Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -203,11 +207,11 @@ def lock_auto_snapshot(self, volume_id): entity=self.entity, entity_id=volume_id) if r.status_code != requests.codes.ok: - msg = ('Failed to lock AutoSnapshot for PowerFlex {entity} ' - 'with id {_id}. ' - 'Error: {response}'.format(entity=self.entity, - _id=volume_id, - response=response)) + msg = ( + f"Failed to lock AutoSnapshot for PowerFlex {self.entity} " + f"with id {volume_id}. " + f"Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -240,13 +244,13 @@ def remove_mapped_sdc(self, msg = 'Either sdc_id or sdc_guid or all_sdcs must be set.' raise exceptions.InvalidInput(msg) - params = dict( - sdcId=sdc_id, - guid=sdc_guid, - allSdcs=all_sdcs, - skipApplianceValidation=skip_appliance_validation, - allowOnExtManagedVol=allow_ext_managed - ) + params = { + "sdcId": sdc_id, + "guid": sdc_guid, + "allSdcs": all_sdcs, + "skipApplianceValidation": skip_appliance_validation, + "allowOnExtManagedVol": allow_ext_managed + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -254,10 +258,10 @@ def remove_mapped_sdc(self, entity_id=volume_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to unmap PowerFlex {entity} with id {_id} from ' - 'SDC. Error: {response}'.format(entity=self.entity, - _id=volume_id, - response=response)) + msg = ( + f"Failed to unmap PowerFlex {self.entity} with id {volume_id} from " + f"SDC. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -274,10 +278,10 @@ def rename(self, volume_id, name, allow_ext_managed=None): action = 'setVolumeName' - params = dict( - newName=name, - allowOnExtManagedVol=allow_ext_managed - ) + params = { + "newName": name, + "allowOnExtManagedVol": allow_ext_managed + } return self._rename_entity(action, volume_id, params) @@ -291,9 +295,9 @@ def unlock_auto_snapshot(self, volume_id, remove_auto_snapshot=None): action = 'unlockAutoSnapshot' - params = dict( - autoSnapshotWillBeRemoved=remove_auto_snapshot - ) + params = { + "autoSnapshotWillBeRemoved": remove_auto_snapshot + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -301,10 +305,10 @@ def unlock_auto_snapshot(self, volume_id, remove_auto_snapshot=None): entity_id=volume_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to unlock AutoSnapshot for PowerFlex {entity} ' - 'with id {_id}. Error: ' - '{response}'.format(entity=self.entity, _id=volume_id, - response=response)) + msg = ( + f"Failed to unlock AutoSnapshot for PowerFlex {self.entity} " + f"with id {volume_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -327,11 +331,11 @@ def set_mapped_sdc_limits(self, volume_id, sdc_id, bandwidth_limit=None, action = 'setMappedSdcLimits' - params = dict( - sdcId=sdc_id, - bandwidthLimitInKbps=bandwidth_limit, - iopsLimit=iops_limit - ) + params = { + "sdcId": sdc_id, + "bandwidthLimitInKbps": bandwidth_limit, + "iopsLimit": iops_limit + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -339,11 +343,11 @@ def set_mapped_sdc_limits(self, volume_id, sdc_id, bandwidth_limit=None, entity_id=volume_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to update the SDC limits of PowerFlex' - ' {entity} with id {_id}. ' - 'Error: {response}'.format(entity=self.entity, - _id=volume_id, - response=response)) + msg = ( + f"Failed to update the SDC limits of PowerFlex " + f"{self.entity} with id {volume_id}. " + f"Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -364,9 +368,9 @@ def set_compression_method(self, volume_id, compression_method): action = 'modifyCompressionMethod' - params = dict( - compressionMethod=compression_method, - ) + params = { + 'compressionMethod': compression_method, + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -374,11 +378,10 @@ def set_compression_method(self, volume_id, compression_method): entity_id=volume_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to update the compression method of PowerFlex' - ' {entity} with id' - ' {_id}. Error: {response}'.format(entity=self.entity, - _id=volume_id, - response=response)) + msg = ( + f"Failed to update the compression method of PowerFlex " + f"{self.entity} with id {volume_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -400,9 +403,9 @@ def set_use_rmcache(self, volume_id, use_rmcache): action = 'setVolumeUseRmcache' - params = dict( - useRmcache=use_rmcache - ) + params = { + "useRmcache": use_rmcache + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -410,11 +413,11 @@ def set_use_rmcache(self, volume_id, use_rmcache): entity_id=volume_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to update the use_rmcache of PowerFlex' - ' {entity} with id {_id}. ' - 'Error: {response}'.format(entity=self.entity, - _id=volume_id, - response=response)) + msg = ( + f"Failed to update the use_rmcache of PowerFlex " + f"{self.entity} with id {volume_id}. " + f"Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -436,10 +439,10 @@ def set_access_mode_for_sdc(self, volume_id, sdc_id, access_mode): action = 'setVolumeMappingAccessMode' - params = dict( - accessMode=access_mode, - sdcId=sdc_id - ) + params = { + "accessMode": access_mode, + "sdcId": sdc_id + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -447,10 +450,11 @@ def set_access_mode_for_sdc(self, volume_id, sdc_id, access_mode): entity_id=volume_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to set the access mode for the SDC {sdc_id}' - ' mapped to PowerFlex {entity} with id {_id}. Error:' - ' {response}'.format(entity=self.entity, _id=volume_id, - sdc_id=sdc_id, response=response)) + msg = ( + f"Failed to set the access mode for the SDC {sdc_id} " + f"mapped to PowerFlex {self.entity} with id {volume_id}. Error: " + f"{response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -470,9 +474,9 @@ def set_retention_period(self, snap_id, retention_period): action = 'setSnapshotSecurity' - params = dict( - retentionPeriodInMin=retention_period, - ) + params = { + "retentionPeriodInMin": retention_period, + } r, response = self.send_post_request(self.base_action_url, action=action, @@ -480,11 +484,10 @@ def set_retention_period(self, snap_id, retention_period): entity_id=snap_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to set the retention period for PowerFlex' - ' {entity} with id {_id}.' - ' Error: {response}'.format(entity=self.entity, - _id=snap_id, - response=response)) + msg = ( + f"Failed to set the retention period for PowerFlex {self.entity} " + f"with id {snap_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -504,9 +507,7 @@ def set_volume_access_mode_limit(self, volume_id, access_mode_limit): action = 'setVolumeAccessModeLimit' - params = dict( - accessModeLimit=access_mode_limit - ) + params = {"accessModeLimit": access_mode_limit} r, response = self.send_post_request(self.base_action_url, action=action, @@ -514,10 +515,10 @@ def set_volume_access_mode_limit(self, volume_id, access_mode_limit): entity_id=volume_id, params=params) if r.status_code != requests.codes.ok: - msg = ('Failed to update the Volume Access Mode Limit of ' - 'PowerFlex {entity} with id {_id}. Error: {response}' - .format(entity=self.entity, _id=volume_id, - response=response)) + msg = ( + f"Failed to update the Volume Access Mode Limit of PowerFlex " + f"{self.entity} with id {volume_id}. Error: {response}" + ) LOG.error(msg) raise exceptions.PowerFlexClientException(msg) @@ -533,7 +534,7 @@ def query_selected_statistics(self, properties, ids=None): action = "querySelectedStatistics" - params = dict(properties=properties) + params = {'properties': properties} if ids: params["ids"] = ids diff --git a/PyPowerFlex/token.py b/PyPowerFlex/token.py index e8370e2..0538423 100644 --- a/PyPowerFlex/token.py +++ b/PyPowerFlex/token.py @@ -13,13 +13,37 @@ # License for the specific language governing permissions and limitations # under the License. +"""This module is used for the management of token.""" class Token: + """ + A class to manage a token. + """ def __init__(self): + """ + Initialize the Token object. + + The initial value of the token is None. + """ self.__token = None def get(self): + """ + Get the current token. + + Returns: + The current token. + """ return self.__token def set(self, token): + """ + Set the token. + + Args: + token (Any): The new token. + + Returns: + None + """ self.__token = token diff --git a/PyPowerFlex/utils.py b/PyPowerFlex/utils.py index e77ff1d..177229e 100644 --- a/PyPowerFlex/utils.py +++ b/PyPowerFlex/utils.py @@ -13,6 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. +"""This module contains the utils used in the code.""" + import json import logging import numbers @@ -77,8 +79,8 @@ def query_response_fields(response, fields): """ def query_entity_fields(entity): - entity_fields = dict() - fields_not_found = list() + entity_fields = {} + fields_not_found = [] for field in fields: try: entity_fields[field] = entity[field] @@ -87,28 +89,32 @@ def query_entity_fields(entity): if fields_not_found: msg = ( 'The following fields are not found in response: ' - '{fields_not_found}.'.format( - fields_not_found=', '.join(fields_not_found) - ) + f'{", ".join(fields_not_found)}.' ) raise exceptions.FieldsNotFound(msg) return entity_fields if isinstance(response, list): return list(map(query_entity_fields, response)) - elif isinstance(response, dict): + if isinstance(response, dict): return query_entity_fields(response) + return None def convert(param): + """ + Convert parameters to appropriate types. + + :param param: request parameters + :return: converted parameters + """ if isinstance(param, list): return [convert(item) for item in param] - elif isinstance(param, (numbers.Number, bool)): + if isinstance(param, (numbers.Number, bool)): # Convert numbers and boolean to string. return str(param) - else: - # Other types are not converted. - return param + # Other types are not converted. + return param def prepare_params(params, dump=True): @@ -123,7 +129,7 @@ def prepare_params(params, dump=True): if not isinstance(params, dict): return params - prepared = dict() + prepared = {} for name, value in params.items(): if value is not None: prepared[name] = convert(value) @@ -144,8 +150,23 @@ def is_version_3(version): return True return False + def build_uri_with_params(uri, **url_params): - query_params = [f"{key}={item}" if isinstance(value, list) else f"{key}={value}" for key, value in url_params.items() for item in (value if isinstance(value, list) else [value]) if item is not None] + """ + Build the URI with query parameters. + + :param uri: base URI + :param url_params: query parameters + :return: URI with query parameters + """ + query_params = [ + f"{key}={item}" if isinstance( + value, + list) else f"{key}={value}" for key, + value in url_params.items() for item in ( + value if isinstance( + value, + list) else [value]) if item is not None] if query_params: uri += '?' + '&'.join(query_params) return uri diff --git a/README.md b/README.md index 71ca540..c38be70 100644 --- a/README.md +++ b/README.md @@ -177,7 +177,7 @@ from PyPowerFlex.objects.acceleration_pool import MediaType client.acceleration_pool.create(media_type=MediaType.ssd, protection_domain_id='1caf743100000000', name='ACP_SSD', - isRfcache=True) + is_rfcache=True) client.acceleration_pool.get(filter_fields={'id': '9c8c5c7800000001'}, fields=['name', 'id']) [{'name': 'ACP_SSD', 'id': '9c8c5c7800000001'}] diff --git a/setup.py b/setup.py index b9d3303..999daad 100644 --- a/setup.py +++ b/setup.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for general setup.""" + +# pylint: disable=import-error + from setuptools import setup setup( diff --git a/tests/__init__.py b/tests/__init__.py index c6e1df7..74cebf5 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""This module is used for the initialization of the test framework.""" + +# pylint: disable=too-many-instance-attributes,keyword-arg-before-vararg,broad-exception-raised,unused-argument + import collections import contextlib import json @@ -27,28 +31,55 @@ class MockResponse(requests.Response): - """Mock HTTP Response. + """ + Mock HTTP Response. Defines http replies from mocked calls to do_request(). """ - def __init__(self, content, status_code=200): - super(MockResponse, self).__init__() + """ + Initialize a MockResponse. + + Args: + content (str or dict): The content of the response. + status_code (int): The status code of the response. + """ + super().__init__() self._content = content self.request = mock.MagicMock() self.status_code = status_code def json(self, **kwargs): + """ + Return the content of the response as JSON. + + Args: + **kwargs: Additional keyword arguments. + + Returns: + dict: The content of the response. + """ return self._content @property def text(self): + """ + Return the content of the response as text. + + Returns: + str: The content of the response. + """ if not isinstance(self._content, bytes): return json.dumps(self._content) - return super(MockResponse, self).text + return super().text class PyPowerFlexTestCase(TestCase): + """ + Base test case for PyPowerFlex. + + Provides a mocked HTTP response for testing. + """ RESPONSE_MODE = ( collections.namedtuple('RESPONSE_MODE', 'Valid Invalid BadStatus') (Valid='Valid', Invalid='Invalid', BadStatus='BadStatus') @@ -59,7 +90,7 @@ class PyPowerFlexTestCase(TestCase): 'message': 'Test default bad status', }, 500 ) - MOCK_RESPONSES = dict() + MOCK_RESPONSES = {} DEFAULT_MOCK_RESPONSES = { RESPONSE_MODE.Valid: { '/login': 'token', @@ -93,6 +124,11 @@ class PyPowerFlexTestCase(TestCase): __http_response_mode = RESPONSE_MODE.Valid def setUp(self): + """ + Set up the test case. + + Creates a PyPowerFlex client and sets up mocked HTTP responses. + """ self.gateway_address = '1.2.3.4' self.gateway_port = 443 self.username = 'admin' @@ -124,6 +160,15 @@ def mock_object(self, obj, attr_name, *args, **kwargs): @contextlib.contextmanager def http_response_mode(self, mode): + """ + Context manager for setting the HTTP response mode. + + Args: + mode: The HTTP response mode. + + Yields: + None. + """ previous_response_mode, self.__http_response_mode = ( self.__http_response_mode, mode ) @@ -131,6 +176,19 @@ def http_response_mode(self, mode): self.__http_response_mode = previous_response_mode def get_mock_response(self, url, request_url=None, mode=None, *args, **kwargs): + """ + Get a mock HTTP response. + + Args: + url (str): The URL of the request. + request_url (str): The URL of the request. + mode (str): The HTTP response mode. + *args: Additional arguments. + **kwargs: Additional keyword arguments. + + Returns: + requests.Response: The mocked HTTP response. + """ if mode is None: mode = self.__http_response_mode @@ -142,7 +200,7 @@ def get_mock_response(self, url, request_url=None, mode=None, *args, **kwargs): response = self.RESPONSE_MODE.Valid[2] else: response = self.MOCK_RESPONSES[mode][api_path] - except KeyError: + except KeyError as e: try: response = self.DEFAULT_MOCK_RESPONSES[mode][api_path] except KeyError: @@ -150,10 +208,9 @@ def get_mock_response(self, url, request_url=None, mode=None, *args, **kwargs): response = self.BAD_STATUS_RESPONSE else: raise Exception( - 'Mock API Endpoint is not implemented: [{}]{}'.format( - mode, api_path - ) - ) + f"Mock API Endpoint is not implemented: [{mode}]" + f"{api_path}" + ) from e if not isinstance(response, MockResponse): response = self._get_mock_response(response) @@ -162,7 +219,15 @@ def get_mock_response(self, url, request_url=None, mode=None, *args, **kwargs): return response def _get_mock_response(self, response): + """ + Returns a MockResponse object based on the given response. + + Args: + response (str): The response to be wrapped. + + Returns: + MockResponse: The mock response object. + """ if "204" in str(response): return MockResponse(response, 204) - else: - return MockResponse(response, 200) + return MockResponse(response, 200) diff --git a/tests/test_acceleration_pool.py b/tests/test_acceleration_pool.py index 74fa9bb..195bfb9 100644 --- a/tests/test_acceleration_pool.py +++ b/tests/test_acceleration_pool.py @@ -13,14 +13,24 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing accelaration pool client.""" + +# pylint: disable=invalid-name + from PyPowerFlex import exceptions from PyPowerFlex.objects import acceleration_pool import tests class TestAccelerationPoolClient(tests.PyPowerFlexTestCase): + """ + Test class for the AccelerationPoolClient. + """ def setUp(self): - super(TestAccelerationPoolClient, self).setUp() + """ + Set up the test environment. + """ + super().setUp() self.client.initialize() self.fake_pd_id = '1' self.fake_ap_id = '1' @@ -30,10 +40,9 @@ def setUp(self): self.RESPONSE_MODE.Valid: { '/types/AccelerationPool/instances': {'id': self.fake_ap_id}, - '/instances/AccelerationPool::{}'.format(self.fake_ap_id): + f'/instances/AccelerationPool::{self.fake_ap_id}': {'id': self.fake_ap_id}, - '/instances/AccelerationPool::{}' - '/action/removeAccelerationPool'.format(self.fake_ap_id): + f'/instances/AccelerationPool::{self.fake_ap_id}/action/removeAccelerationPool': {}, '/types/AccelerationPool' '/instances/action/querySelectedStatistics': { @@ -47,37 +56,55 @@ def setUp(self): } def test_acceleration_pool_create(self): + """ + Test the create method of the AccelerationPoolClient. + """ self.client.acceleration_pool.create( media_type=acceleration_pool.MediaType.ssd, protection_domain_id=self.fake_pd_id, - isRfcache=True) + is_rfcache=True) def test_acceleration_pool_create_bad_status(self): + """ + Test the create method of the AccelerationPoolClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailCreating, self.client.acceleration_pool.create, media_type=acceleration_pool.MediaType.ssd, protection_domain_id=self.fake_pd_id, - isRfcache=True) + is_rfcache=True) def test_acceleration_pool_create_no_id_in_response(self): + """ + Test the create method of the AccelerationPoolClient with no id in the response. + """ with self.http_response_mode(self.RESPONSE_MODE.Invalid): self.assertRaises(KeyError, self.client.acceleration_pool.create, media_type=acceleration_pool.MediaType.ssd, protection_domain_id=self.fake_pd_id, - isRfcache=True) + is_rfcache=True) def test_acceleration_pool_delete(self): + """ + Test the delete method of the AccelerationPoolClient. + """ self.client.acceleration_pool.delete(self.fake_ap_id) def test_acceleration_pool_delete_bad_status(self): + """ + Test the delete method of the AccelerationPoolClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailDeleting, self.client.acceleration_pool.delete, self.fake_ap_id) def test_acceleration_pool_query_selected_statistics(self): + """ + Test the query_selected_statistics method of the AccelerationPoolClient. + """ ret = self.client.acceleration_pool.query_selected_statistics( properties=["accelerationDeviceIds"] ) @@ -86,6 +113,9 @@ def test_acceleration_pool_query_selected_statistics(self): ] def test_acceleration_pool_query_selected_statistics_bad_status(self): + """ + Test the query_selected_statistics method of the AccelerationPoolClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexFailQuerying, diff --git a/tests/test_base.py b/tests/test_base.py index 615a2ff..1068f8b 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -13,6 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing base client.""" + import json from PyPowerFlex import exceptions @@ -21,8 +23,14 @@ class TestBaseClient(tests.PyPowerFlexTestCase): + """ + Test class for the BaseClient. + """ def setUp(self): - super(TestBaseClient, self).setUp() + """ + Set up the test environment. + """ + super().setUp() self.fake_response = [ { 'first': 1, @@ -37,74 +45,117 @@ def setUp(self): ] def test_client_not_initialized(self): + """ + Test that the client is not initialized. + """ with self.assertRaises(exceptions.ClientNotInitialized): self.client.volume.get() def test_client_initialize(self): + """ + Test that the client is initialized. + """ self.client.initialize() def test_client_initialize_required_params_not_set(self): + """ + Test that the client initialization fails when required parameters are not set. + """ self.client.configuration.gateway_address = None with self.assertRaises(exceptions.InvalidConfiguration): self.client.initialize() def test_client_initialize_api_version_not_supported(self): + """ + Test that the client initialization fails when the API version is not supported. + """ with self.http_response_mode(self.RESPONSE_MODE.Invalid): with self.assertRaises(exceptions.PowerFlexClientException): self.client.initialize() def test_utils_filter_response(self): + """ + Test that the response is filtered correctly. + """ filter_fields = {'second': 2048} result = utils.filter_response(self.fake_response, filter_fields) self.assertTrue(len(result) == 1) self.assertTrue(result[0]['second'] == 2048) def test_utils_filter_response_iterable_in_response(self): + """ + Test that the response is filtered correctly when the filter field is an iterable. + """ filter_fields = {'third': 'one'} result = utils.filter_response(self.fake_response, filter_fields) self.assertTrue(len(result) == 1) def test_utils_filter_response_iterable_filter_field(self): + """ + Test that the response is filtered correctly when the filter field is an iterable. + """ filter_fields = {'third': ['one', 'two']} result = utils.filter_response(self.fake_response, filter_fields) self.assertTrue(len(result) == 2) def test_utils_filter_response_iterable_filter_field_no_match(self): + """ + Test that the response is filtered correctly when the filter field is an iterable + and has no match. + """ filter_fields = {'third': ['four', 'five']} result = utils.filter_response(self.fake_response, filter_fields) self.assertFalse(len(result)) def test_utils_filter_response_invalid_field(self): + """ + Test that the response is filtered correctly when the filter field is not found. + """ filter_fields = {'not_found_in_response': True} result = utils.filter_response(self.fake_response, filter_fields) self.assertTrue(len(result) == 0) def test_utils_query_response_fields_list(self): + """ + Test that the response fields are queried correctly. + """ fields = ('first',) result = utils.query_response_fields(self.fake_response, fields) self.assertTrue(all(map(lambda entity: len(entity) == 1, result))) self.assertTrue(all(map(lambda entity: entity['first'], result))) def test_utils_query_response_fields_dict(self): + """ + Test that the response fields are queried correctly. + """ fields = ('first',) result = utils.query_response_fields(self.fake_response[0], fields) self.assertTrue(len(result) == 1) self.assertTrue(result['first']) def test_utils_query_response_fields_invalid_field(self): + """ + Test that the response fields are queried correctly with invalid field. + """ fields = ('not_found_in_response', 'first', 'second') with self.assertRaises(exceptions.FieldsNotFound): utils.query_response_fields(self.fake_response, fields) def test_utils_prepare_params(self): - params = dict(first=1, second=True, third=None) + """ + Test that the parameters are prepared correctly. + """ + params = {"first": 1, "second": True, "third": None} prepared = json.loads(utils.prepare_params(params)) self.assertNotIn('third', prepared) self.assertEqual('1', prepared['first']) self.assertEqual('True', prepared['second']) def test_utils_prepare_params_with_lists(self): - params = dict(first=['second', 3, [4, True, {'fifth': 5}]]) + """ + Test that the parameters are prepared correctly when the values are lists. + """ + params = {"first": ["second", 3, [4, True, {"fifth": 5}]]} prepared = json.loads(utils.prepare_params(params)) self.assertEqual( {'first': ['second', '3', ['4', 'True', {'fifth': 5}]]}, prepared diff --git a/tests/test_deployment.py b/tests/test_deployment.py index b6cb93a..57d26e6 100644 --- a/tests/test_deployment.py +++ b/tests/test_deployment.py @@ -13,14 +13,23 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing deployment client.""" + +# pylint: disable=invalid-name + from PyPowerFlex import exceptions import tests class TestDeploymentClient(tests.PyPowerFlexTestCase): - + """ + Test class for the DeploymentClient. + """ def setUp(self): - super(TestDeploymentClient, self).setUp() + """ + Set up the test environment. + """ + super().setUp() self.client.initialize() self.RESPONSE_204 = "" self.deployment_id = '8aaa03a88de961fa018de9c882d20301' @@ -35,38 +44,65 @@ def setUp(self): } def test_deployment_get(self): + """ + Test the get method of the DeploymentClient. + """ self.client.deployment.get() def test_deployment_get_with_query_params(self): + """ + Test the get method of the DeploymentClient with query parameters. + """ self.client.deployment.get(filters=['co,name,Partial'], include_devices=False) def test_deployment_get_by_id(self): + """ + Test the get_by_id method of the DeploymentClient. + """ self.client.deployment.get_by_id(self.deployment_id) def test_deployment_get_bad_status(self): + """ + Test the get method of the DeploymentClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.deployment.get) def test_deployment_get_by_id_bad_status(self): + """ + Test the get_by_id method of the DeploymentClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.deployment.get_by_id, self.deployment_id) def test_deployment_create(self): + """ + Test the create method of the DeploymentClient. + """ self.client.deployment.create(self.rg_data) def test_deployment_create_bad_status(self): + """ + Test the create method of the DeploymentClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.deployment.create, self.rg_data) def test_deployment_edit(self): + """ + Test the edit method of the DeploymentClient. + """ self.client.deployment.edit(self.deployment_id, self.rg_data) def test_deployment_edit_bad_status(self): + """ + Test the edit method of the DeploymentClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.deployment.edit, @@ -74,20 +110,32 @@ def test_deployment_edit_bad_status(self): self.rg_data) def test_deployment_delete(self): + """ + Test the delete method of the DeploymentClient. + """ url = f'/V1/Deployment/{self.deployment_id}' self.MOCK_RESPONSES[self.RESPONSE_MODE.Valid][url] = self.RESPONSE_204 self.client.deployment.delete(self.deployment_id) def test_deployment_delete_bad_status(self): + """ + Test the delete method of the DeploymentClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.deployment.delete, self.deployment_id) def test_deployment_validate(self): + """ + Test the validate method of the DeploymentClient. + """ self.client.deployment.validate(self.rg_data) def test_deployment_validate_bad_status(self): + """ + Test the validate method of the DeploymentClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.deployment.validate, diff --git a/tests/test_device.py b/tests/test_device.py index 7b8da49..9c604ac 100644 --- a/tests/test_device.py +++ b/tests/test_device.py @@ -13,14 +13,24 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing device client.""" + +# pylint: disable=invalid-name + from PyPowerFlex import exceptions from PyPowerFlex.objects.device import MediaType import tests class TestDeviceClient(tests.PyPowerFlexTestCase): + """ + Test class for DeviceClient. + """ def setUp(self): - super(TestDeviceClient, self).setUp() + """ + Set up the test environment. + """ + super().setUp() self.client.initialize() self.fake_device_id = '1' self.fake_sds_id = '1' @@ -31,16 +41,16 @@ def setUp(self): self.RESPONSE_MODE.Valid: { '/types/Device/instances': {'id': self.fake_device_id}, - '/instances/Device::{}'.format(self.fake_device_id): + f'/instances/Device::{self.fake_device_id}': {'id': self.fake_device_id}, - '/instances/Device::{}' - '/action/removeDevice'.format(self.fake_device_id): + f'/instances/Device::{self.fake_device_id}' + '/action/removeDevice': {}, - '/instances/Device::{}' - '/action/setDeviceName'.format(self.fake_device_id): + f'/instances/Device::{self.fake_device_id}' + '/action/setDeviceName': {}, - '/instances/Device::{}' - '/action/setMediaType'.format(self.fake_device_id): + f'/instances/Device::{self.fake_device_id}' + '/action/setMediaType': {}, '/types/Device' '/instances/action/querySelectedStatistics': { @@ -54,12 +64,18 @@ def setUp(self): } def test_device_create(self): + """ + Test device creation. + """ self.client.device.create('/dev/sda', self.fake_sds_id, media_type=MediaType.ssd, storage_pool_id=self.fake_sp_id) def test_device_create_bad_status(self): + """ + Test device creation with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailCreating, self.client.device.create, @@ -69,6 +85,9 @@ def test_device_create_bad_status(self): storage_pool_id=self.fake_sp_id) def test_device_create_no_id_in_response(self): + """ + Test device creation with no id in response. + """ with self.http_response_mode(self.RESPONSE_MODE.Invalid): self.assertRaises(KeyError, self.client.device.create, @@ -78,6 +97,9 @@ def test_device_create_no_id_in_response(self): storage_pool_id=self.fake_sp_id) def test_device_create_storage_pool_id_and_acc_pool_id_are_set(self): + """ + Test device creation with both storage pool id and acceleration pool id set. + """ self.assertRaises(exceptions.InvalidInput, self.client.device.create, '/dev/sda', @@ -87,18 +109,30 @@ def test_device_create_storage_pool_id_and_acc_pool_id_are_set(self): storage_pool_id=self.fake_sp_id) def test_device_delete(self): + """ + Test device deletion. + """ self.client.device.delete(self.fake_device_id) def test_device_delete_bad_status(self): + """ + Test device deletion with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailDeleting, self.client.device.delete, self.fake_device_id) def test_device_rename(self): + """ + Test device renaming. + """ self.client.device.rename(self.fake_device_id, name='new_name') def test_device_rename_bad_status(self): + """ + Test device renaming with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailRenaming, self.client.device.rename, @@ -106,12 +140,18 @@ def test_device_rename_bad_status(self): name='new_name') def test_device_set_media_type(self): + """ + Test device media type setting. + """ self.client.device.set_media_type( self.fake_device_id, media_type=MediaType.hdd ) def test_device_set_media_type_bad_status(self): + """ + Test device media type setting with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -121,12 +161,18 @@ def test_device_set_media_type_bad_status(self): ) def test_device_query_selected_statistics(self): + """ + Test device query selected statistics. + """ ret = self.client.device.query_selected_statistics( properties=["avgReadLatencyInMicrosec"] ) assert ret.get(self.fake_device_id).get("avgReadLatencyInMicrosec") == 0 def test_device_query_selected_statistics_bad_status(self): + """ + Test device query selected statistics with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexFailQuerying, diff --git a/tests/test_fault_set.py b/tests/test_fault_set.py index b80e126..770f064 100644 --- a/tests/test_fault_set.py +++ b/tests/test_fault_set.py @@ -13,13 +13,24 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing fault set client.""" + +# pylint: disable=invalid-name + from PyPowerFlex import exceptions import tests class TestFaultSetClient(tests.PyPowerFlexTestCase): + """ + Test class for the PowerFlex FaultSetClient. + """ + def setUp(self): - super(TestFaultSetClient, self).setUp() + """ + Set up the test environment. + """ + super().setUp() self.client.initialize() self.fake_fault_set_id = '1' self.fake_pd_id = '1' @@ -28,19 +39,15 @@ def setUp(self): self.RESPONSE_MODE.Valid: { '/types/FaultSet/instances': {'id': self.fake_fault_set_id}, - '/instances/FaultSet::{}'.format(self.fake_fault_set_id): + f'/instances/FaultSet::{self.fake_fault_set_id}': {'id': self.fake_fault_set_id}, - '/instances/FaultSet::{}' - '/action/clearFaultSet'.format(self.fake_fault_set_id): + f'/instances/FaultSet::{self.fake_fault_set_id}/action/clearFaultSet': {}, - '/instances/FaultSet::{}' - '/relationships/Sds'.format(self.fake_fault_set_id): + f'/instances/FaultSet::{self.fake_fault_set_id}/relationships/Sds': [], - '/instances/FaultSet::{}' - '/action/removeFaultSet'.format(self.fake_fault_set_id): + f'/instances/FaultSet::{self.fake_fault_set_id}/action/removeFaultSet': {}, - '/instances/FaultSet::{}' - '/action/setFaultSetName'.format(self.fake_fault_set_id): + f'/instances/FaultSet::{self.fake_fault_set_id}/action/setFaultSetName': {}, '/types/FaultSet' '/instances/action/querySelectedStatistics': { @@ -54,18 +61,30 @@ def setUp(self): } def test_fault_set_clear(self): + """ + Test clearing a fault set. + """ self.client.fault_set.clear(self.fake_fault_set_id) def test_fault_set_clear_bad_status(self): + """ + Test clearing a fault set with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.fault_set.clear, self.fake_fault_set_id) def test_fault_set_create(self): + """ + Test creating a fault set. + """ self.client.fault_set.create(self.fake_pd_id, name='fake_name') def test_fault_set_create_bad_status(self): + """ + Test creating a fault set with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailCreating, self.client.fault_set.create, @@ -73,6 +92,9 @@ def test_fault_set_create_bad_status(self): name='fake_name') def test_fault_set_create_no_id_in_response(self): + """ + Test creating a fault set with no ID in the response. + """ with self.http_response_mode(self.RESPONSE_MODE.Invalid): self.assertRaises(KeyError, self.client.fault_set.create, @@ -80,27 +102,45 @@ def test_fault_set_create_no_id_in_response(self): name='fake_name') def test_fault_set_get_sdss(self): + """ + Test getting the SDS for a fault set. + """ self.client.fault_set.get_sdss(self.fake_fault_set_id) def test_fault_set_get_sdss_bad_status(self): + """ + Test getting the SDS for a fault set with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.fault_set.get_sdss, self.fake_fault_set_id) def test_fault_set_delete(self): + """ + Test deleting a fault set. + """ self.client.fault_set.delete(self.fake_fault_set_id) def test_fault_set_delete_bad_status(self): + """ + Test deleting a fault set with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailDeleting, self.client.fault_set.delete, self.fake_fault_set_id) def test_fault_set_rename(self): + """ + Test renaming a fault set. + """ self.client.fault_set.rename(self.fake_fault_set_id, name='new_name') def test_fault_set_rename_bad_status(self): + """ + Test renaming a fault set with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailRenaming, self.client.fault_set.rename, @@ -108,12 +148,18 @@ def test_fault_set_rename_bad_status(self): name='new_name') def test_fault_set_query_selected_statistics(self): + """ + Test querying selected statistics for a fault set. + """ ret = self.client.fault_set.query_selected_statistics( properties=["rfcacheFdReadTimeGreater5Sec"] ) assert ret.get(self.fake_fault_set_id).get("rfcacheFdReadTimeGreater5Sec") == 0 def test_fault_set_query_selected_statistics_bad_status(self): + """ + Test querying selected statistics for a fault set with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexFailQuerying, diff --git a/tests/test_firmware_repository.py b/tests/test_firmware_repository.py index 83d36cf..7ce7112 100644 --- a/tests/test_firmware_repository.py +++ b/tests/test_firmware_repository.py @@ -13,13 +13,23 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing firmware repository client.""" + +# pylint: disable=invalid-name + from PyPowerFlex import exceptions import tests class TestFirmwareRepositoryClient(tests.PyPowerFlexTestCase): + """ + Test class for FirmwareRepositoryClient. + """ def setUp(self): - super(TestFirmwareRepositoryClient, self).setUp() + """ + Set up the test environment. + """ + super().setUp() self.client.initialize() self.MOCK_RESPONSES = { @@ -30,12 +40,21 @@ def setUp(self): } def test_firmware_repository_get(self): + """ + Test the get method of the FirmwareRepositoryClient. + """ self.client.firmware_repository.get() def test_firmware_repository_get_with_query_params(self): + """ + Test the get method of the FirmwareRepositoryClient with query parameters. + """ self.client.firmware_repository.get(related=False, bundles=False, components=False) def test_firmware_repository_get_bad_status(self): + """ + Test the get method of the FirmwareRepositoryClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.firmware_repository.get) diff --git a/tests/test_host.py b/tests/test_host.py index 655e7cd..4012d2d 100644 --- a/tests/test_host.py +++ b/tests/test_host.py @@ -13,13 +13,23 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing host client.""" + +# pylint: disable=invalid-name + from PyPowerFlex import exceptions import tests class TestHostClient(tests.PyPowerFlexTestCase): + """ + Tests for the HostClient class. + """ def setUp(self): - super(TestHostClient, self).setUp() + """ + Set up the test environment. + """ + super().setUp() self.client.initialize() self.fake_host_id="1" self.fake_nqn = "nqn::" @@ -28,37 +38,53 @@ def setUp(self): self.RESPONSE_MODE.Valid: { # create '/types/Host/instances': {'id': self.fake_host_id}, - '/instances/Host::{}'.format(self.fake_host_id): + f'/instances/Host::{self.fake_host_id}': {'id': self.fake_host_id}, - '/instances/Host::{}' - '/action/modifyMaxNumPaths'.format(self.fake_host_id): {}, - '/instances/Host::{}' - '/action/modifyMaxNumSysPorts'.format(self.fake_host_id): {}, + f'/instances/Host::{self.fake_host_id}/action/modifyMaxNumPaths': {}, + f'/instances/Host::{self.fake_host_id}/action/modifyMaxNumSysPorts': {}, } } - + def test_sdc_host_create(self): + """ + Test the creation of a new host. + """ self.client.host.create(self.fake_nqn, max_num_paths='8', max_num_sys_ports='8') def test_sdc_host_create_bad_status(self): + """ + Test the creation of a new host with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailCreating, self.client.host.create, self.fake_nqn) def test_sdc_modify_max_num_paths(self): + """ + Test the modification of the maximum number of paths. + """ self.client.host.modify_max_num_paths(self.fake_host_id, max_num_paths='8') - + def test_sdc_modify_max_num_paths_bad_status(self): - with self.http_response_mode(self.RESPONSE_MODE.BadStatus): + """ + Test the modification of the maximum number of paths with a bad status. + """ + with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailEntityOperation, self.client.host.modify_max_num_paths, self.fake_host_id, max_num_paths='8') def test_sdc_modify_max_num_sys_ports(self): + """ + Test the modification of the maximum number of system ports. + """ self.client.host.modify_max_num_sys_ports(self.fake_host_id, max_num_sys_ports='8') def test_sdc_modify_max_num_sys_ports_bad_status(self): - with self.http_response_mode(self.RESPONSE_MODE.BadStatus): + """ + Test the modification of the maximum number of system ports with a bad status. + """ + with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailEntityOperation, self.client.host.modify_max_num_sys_ports, self.fake_host_id, diff --git a/tests/test_managed_device.py b/tests/test_managed_device.py index 51f6fd2..9e5039c 100644 --- a/tests/test_managed_device.py +++ b/tests/test_managed_device.py @@ -13,13 +13,23 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing managed device client.""" + +# pylint: disable=invalid-name + from PyPowerFlex import exceptions import tests class TestManagedDeviceClient(tests.PyPowerFlexTestCase): + """ + Test class for the ManagedDeviceClient. + """ def setUp(self): - super(TestManagedDeviceClient, self).setUp() + """ + Set up the test environment. + """ + super().setUp() self.client.initialize() self.MOCK_RESPONSES = { @@ -30,12 +40,21 @@ def setUp(self): } def test_managed_device_get(self): + """ + Test the managed_device.get() method. + """ self.client.managed_device.get() def test_managed_device_get_with_query_params(self): + """ + Test the managed_device.get() method with query parameters. + """ self.client.managed_device.get(filters=['eq,deviceType,scaleio'], sort="state") def test_managed_device_get_bad_status(self): + """ + Test the managed_device.get() method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.managed_device.get) diff --git a/tests/test_protection_domain.py b/tests/test_protection_domain.py index 61d0dee..8d3146a 100644 --- a/tests/test_protection_domain.py +++ b/tests/test_protection_domain.py @@ -13,14 +13,24 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing protection domain client.""" + +# pylint: disable=invalid-name,too-many-public-methods,duplicate-code + from PyPowerFlex import exceptions from PyPowerFlex.objects import protection_domain import tests class TestProtectionDomainClient(tests.PyPowerFlexTestCase): + """ + Test class for the ProtectionDomainClient. + """ def setUp(self): - super(TestProtectionDomainClient, self).setUp() + """ + Set up the test environment. + """ + super().setUp() self.client.initialize() self.fake_pd_id = '1' @@ -28,41 +38,37 @@ def setUp(self): self.RESPONSE_MODE.Valid: { '/types/ProtectionDomain/instances': {'id': self.fake_pd_id}, - '/instances/ProtectionDomain::{}'.format(self.fake_pd_id): + f'/instances/ProtectionDomain::{self.fake_pd_id}': {'id': self.fake_pd_id}, - '/instances/ProtectionDomain::{}' - '/action/activateProtectionDomain'.format(self.fake_pd_id): + f'/instances/ProtectionDomain::{self.fake_pd_id}/action/activateProtectionDomain': {'id': self.fake_pd_id}, - '/instances/ProtectionDomain::{}' - '/relationships/Sds'.format(self.fake_pd_id): + f'/instances/ProtectionDomain::{self.fake_pd_id}/relationships/Sds': [], - '/instances/ProtectionDomain::{}' - '/relationships/StoragePool'.format(self.fake_pd_id): + f'/instances/ProtectionDomain::{self.fake_pd_id}/relationships/StoragePool': [], - '/instances/ProtectionDomain::{}' - '/action/removeProtectionDomain'.format(self.fake_pd_id): + f'/instances/ProtectionDomain::{self.fake_pd_id}/action/removeProtectionDomain': {}, - '/instances/ProtectionDomain::{}' - '/action/inactivateProtectionDomain'.format(self.fake_pd_id): + f'/instances/ProtectionDomain::{self.fake_pd_id}/action/inactivateProtectionDomain': {'id': self.fake_pd_id}, - '/instances/ProtectionDomain::{}' - '/action/setProtectionDomainName'.format(self.fake_pd_id): + f'/instances/ProtectionDomain::{self.fake_pd_id}/action/setProtectionDomainName': {}, - '/instances/ProtectionDomain::{}' - '/action/setSdsNetworkLimits'.format(self.fake_pd_id): + f'/instances/ProtectionDomain::{self.fake_pd_id}/action/setSdsNetworkLimits': {}, - '/instances/ProtectionDomain::{}' - '/action/enableSdsRfcache'.format(self.fake_pd_id): + f'/instances/ProtectionDomain::{self.fake_pd_id}/action/enableSdsRfcache': {}, - '/instances/ProtectionDomain::{}' - '/action/disableSdsRfcache'.format(self.fake_pd_id): + f'/instances/ProtectionDomain::{self.fake_pd_id}/action/disableSdsRfcache': {}, - '/instances/ProtectionDomain::{}' - '/action/setRfcacheParameters'.format(self.fake_pd_id): + f'/instances/ProtectionDomain::{self.fake_pd_id}/action/setRfcacheParameters': {}, '/types/ProtectionDomain' '/instances/action/querySelectedStatistics': { - self.fake_pd_id: {'rplTransmitBwc': {'numSeconds': 0, 'totalWeightInKb': 0, 'numOccured': 0}} + self.fake_pd_id: { + 'rplTransmitBwc': { + 'numSeconds': 0, + 'totalWeightInKb': 0, + 'numOccured': 0 + } + } }, }, self.RESPONSE_MODE.Invalid: { @@ -72,69 +78,114 @@ def setUp(self): } def test_protection_domain_activate(self): + """ + Test the activation of a protection domain. + """ self.client.protection_domain.activate(self.fake_pd_id) def test_protection_domain_activate_bad_status(self): + """ + Test the activation of a protection domain with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.protection_domain.activate, self.fake_pd_id) def test_protection_domain_create(self): + """ + Test the creation of a protection domain. + """ self.client.protection_domain.create(name='fake_name') def test_protection_domain_create_bad_status(self): + """ + Test the creation of a protection domain with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailCreating, self.client.protection_domain.create, name='fake_name') def test_protection_domain_create_no_id_in_response(self): + """ + Test the creation of a protection domain with no ID in the response. + """ with self.http_response_mode(self.RESPONSE_MODE.Invalid): self.assertRaises(KeyError, self.client.protection_domain.create, name='fake_name') def test_protection_domain_get_sdss(self): + """ + Test the retrieval of SDS for a protection domain. + """ self.client.protection_domain.get_sdss(self.fake_pd_id) def test_protection_domain_get_sdss_bad_status(self): + """ + Test the retrieval of SDS for a protection domain with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.protection_domain.get_sdss, self.fake_pd_id) def test_protection_domain_get_storage_pools(self): + """ + Test the retrieval of storage pools for a protection domain. + """ self.client.protection_domain.get_storage_pools(self.fake_pd_id) def test_protection_domain_get_storage_pools_bad_status(self): + """ + Test the retrieval of storage pools for a protection domain with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.protection_domain.get_storage_pools, self.fake_pd_id) def test_protection_domain_delete(self): + """ + Test the deletion of a protection domain. + """ self.client.protection_domain.delete(self.fake_pd_id) def test_protection_domain_delete_bad_status(self): + """ + Test the deletion of a protection domain with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailDeleting, self.client.protection_domain.delete, self.fake_pd_id) def test_protection_domain_inactivate(self): + """ + Test the inactivation of a protection domain. + """ self.client.protection_domain.inactivate(self.fake_pd_id) def test_protection_domain_inactivate_bad_status(self): + """ + Test the inactivation of a protection domain with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.protection_domain.inactivate, self.fake_pd_id) def test_protection_domain_rename(self): + """ + Test the rename method of the ProtectionDomainClient. + """ self.client.protection_domain.rename(self.fake_pd_id, name='new_name') def test_protection_domain_rename_bad_status(self): + """ + Test the rename method of the ProtectionDomainClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailRenaming, self.client.protection_domain.rename, @@ -142,6 +193,9 @@ def test_protection_domain_rename_bad_status(self): name='new_name') def test_protection_domain_network_limits(self): + """ + Test the network_limits method of the ProtectionDomainClient. + """ self.client.protection_domain.network_limits(self.fake_pd_id, rebuild_limit=10240, rebalance_limit=10240, @@ -150,22 +204,34 @@ def test_protection_domain_network_limits(self): overall_limit=10240) def test_protection_domain_network_limits_bad_status(self): + """ + Test the network_limits method of the ProtectionDomainClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.protection_domain.network_limits, self.fake_pd_id) def test_protection_domain_set_rfcache_enabled(self): + """ + Test the set_rfcache_enabled method of the ProtectionDomainClient. + """ self.client.protection_domain.set_rfcache_enabled(self.fake_pd_id, enable_rfcache=True) def test_protection_domain_set_rfcache_enabled_bad_status(self): + """ + Test the set_rfcache_enabled method of the ProtectionDomainClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.protection_domain.set_rfcache_enabled, self.fake_pd_id) def test_protection_domain_rfcache_parameters(self): + """ + Test the rfcache_parameters method of the ProtectionDomainClient. + """ self.client.protection_domain.rfcache_parameters(self.fake_pd_id, page_size=16, max_io_limit=128, @@ -175,12 +241,18 @@ def test_protection_domain_rfcache_parameters(self): write) def test_protection_domain_rfcache_parameters_bad_status(self): + """ + Test the rfcache_parameters method of the ProtectionDomainClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.protection_domain. rfcache_parameters, self.fake_pd_id) def test_protection_domain_query_selected_statistics(self): + """ + Test the query_selected_statistics method of the ProtectionDomainClient. + """ ret = self.client.protection_domain.query_selected_statistics( properties=["rplTransmitBwc"] ) @@ -191,6 +263,9 @@ def test_protection_domain_query_selected_statistics(self): } def test_protection_domain_query_selected_statistics_bad_status(self): + """ + Test the query_selected_statistics method of the ProtectionDomainClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexFailQuerying, diff --git a/tests/test_replication_consistency_group.py b/tests/test_replication_consistency_group.py index 467897f..fb3befe 100644 --- a/tests/test_replication_consistency_group.py +++ b/tests/test_replication_consistency_group.py @@ -13,14 +13,23 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing replication consistency group client.""" + +# pylint: disable=invalid-name,too-many-public-methods + from PyPowerFlex import exceptions -from PyPowerFlex.objects import replication_consistency_group as rcg import tests class TestReplicationConsistencyGroupClient(tests.PyPowerFlexTestCase): + """ + Tests for the ReplicationConsistencyGroupClient. + """ def setUp(self): - super(TestReplicationConsistencyGroupClient, self).setUp() + """ + Set up the test environment. + """ + super().setUp() self.client.initialize() self.fake_rcg_id = '1' @@ -28,69 +37,69 @@ def setUp(self): self.RESPONSE_MODE.Valid: { '/types/ReplicationConsistencyGroup/instances': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/createReplicationConsistencyGroupSnapshots'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/createReplicationConsistencyGroupSnapshots': {}, - '/instances/ReplicationConsistencyGroup::{}'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/activateReplicationConsistencyGroup'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/activateReplicationConsistencyGroup': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/terminateReplicationConsistencyGroup'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/terminateReplicationConsistencyGroup': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/terminateReplicationConsistencyGroup'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/terminateReplicationConsistencyGroup': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/freezeApplyReplicationConsistencyGroup'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/freezeApplyReplicationConsistencyGroup': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/unfreezeApplyReplicationConsistencyGroup'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/unfreezeApplyReplicationConsistencyGroup': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/pauseReplicationConsistencyGroup'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/pauseReplicationConsistencyGroup': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/resumeReplicationConsistencyGroup'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/resumeReplicationConsistencyGroup': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/ModifyReplicationConsistencyGroupRpo'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/ModifyReplicationConsistencyGroupRpo': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/modifyReplicationConsistencyGroupTargetVolumeAccessMode'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/modifyReplicationConsistencyGroupTargetVolumeAccessMode': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/setReplicationConsistencyGroupConsistent'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/setReplicationConsistencyGroupConsistent': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/setReplicationConsistencyGroupInconsistent'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/setReplicationConsistencyGroupInconsistent': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/renameReplicationConsistencyGroup'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/renameReplicationConsistencyGroup': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/removeReplicationConsistencyGroup'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/removeReplicationConsistencyGroup': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/failoverReplicationConsistencyGroup'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/failoverReplicationConsistencyGroup': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/reverseReplicationConsistencyGroup'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/reverseReplicationConsistencyGroup': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/restoreReplicationConsistencyGroup'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/restoreReplicationConsistencyGroup': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/switchoverReplicationConsistencyGroup'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/switchoverReplicationConsistencyGroup': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/action/syncNowReplicationConsistencyGroup'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/action/syncNowReplicationConsistencyGroup': {'id': self.fake_rcg_id}, - '/instances/ReplicationConsistencyGroup::{}' - '/relationships/ReplicationPair'.format(self.fake_rcg_id): + f'/instances/ReplicationConsistencyGroup::{self.fake_rcg_id}' + '/relationships/ReplicationPair': {'id': self.fake_rcg_id}, '/types/ReplicationConsistencyGroup' '/instances/action/querySelectedStatistics': { @@ -105,9 +114,15 @@ def setUp(self): def test_rcg_create_snapshots(self): + """ + Test the create_snapshot method. + """ self.client.replication_consistency_group.create_snapshot(self.fake_rcg_id) def test_add_rcg(self): + """ + Test the create method. + """ self.client.replication_consistency_group.create\ (rpo=20, protection_domain_id='1', remote_protection_domain_id='1', @@ -116,64 +131,125 @@ def test_add_rcg(self): activity_mode=None) def test_remove_rcg(self): + """ + Test the delete method. + """ self.client.replication_consistency_group.delete(self.fake_rcg_id) def test_freeze_rcg(self): + """ + Test the freeze method. + """ self.client.replication_consistency_group.freeze(self.fake_rcg_id) def test_unfreeze_rcg(self): + """ + Test the unfreeze method. + """ self.client.replication_consistency_group.unfreeze(self.fake_rcg_id) def test_activate(self): + """ + Test the activate method. + """ self.client.replication_consistency_group.activate(self.fake_rcg_id) def test_inactivate(self): + """ + Test the inactivate method. + """ self.client.replication_consistency_group.inactivate(self.fake_rcg_id) def test_pause(self): - self.client.replication_consistency_group.pause(self.fake_rcg_id, pause_mode="StopDataTransfer") + """ + Test the pause method. + """ + self.client.replication_consistency_group.pause( + self.fake_rcg_id, pause_mode="StopDataTransfer") def test_resume(self): + """ + Test the resume method. + """ self.client.replication_consistency_group.resume(self.fake_rcg_id) def test_failover(self): + """ + Test the failover method. + """ self.client.replication_consistency_group.failover(self.fake_rcg_id) def test_reverse(self): + """ + Test the reverse method. + """ self.client.replication_consistency_group.reverse(self.fake_rcg_id) def test_restore(self): + """ + Test the restore method. + """ self.client.replication_consistency_group.restore(self.fake_rcg_id) def test_sync(self): + """ + Test the sync method. + """ self.client.replication_consistency_group.sync(self.fake_rcg_id) def test_switchover(self): + """ + Test the switchover method. + """ self.client.replication_consistency_group.switchover(self.fake_rcg_id) def test_set_as_consistent(self): + """ + Test the set_as_consistent method. + """ self.client.replication_consistency_group.set_as_consistent(self.fake_rcg_id) def test_set_as_inconsistent(self): + """ + Test the set_as_inconsistent method. + """ self.client.replication_consistency_group.set_as_inconsistent(self.fake_rcg_id) def test_modify_rpo(self): + """ + Test the modify_rpo method. + """ self.client.replication_consistency_group.modify_rpo(self.fake_rcg_id, rpo_in_seconds=30) def test_modify_target_volume_access_mode(self): + """ + Test the modify_target_volume_access_mode method. + """ self.client.replication_consistency_group.modify_target_volume_access_mode\ (self.fake_rcg_id, target_volume_access_mode=None) def test_rename_rcg(self): + """ + Test the rename_rcg method. + """ self.client.replication_consistency_group.rename_rcg(self.fake_rcg_id, new_name="rename") def test_get_replication_pairs(self): + """ + Test the get_replication_pairs method. + """ self.client.replication_consistency_group.get_replication_pairs(self.fake_rcg_id) def test_get_all_statistics(self): + """ + Test the get_all_statistics method. + """ self.client.replication_consistency_group.get_all_statistics(True) def test_rename_rcg_bad_status(self): + """ + Test the rename_rcg method with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailEntityOperation, self.client.replication_consistency_group.rename_rcg, @@ -181,6 +257,9 @@ def test_rename_rcg_bad_status(self): new_name='rename') def test_create_rcg_bad_status(self): + """ + Test the create method with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailCreating, self.client.replication_consistency_group.create, @@ -191,24 +270,37 @@ def test_create_rcg_bad_status(self): activity_mode=None) def test_delete_rcg_bad_status(self): + """ + Test the delete method with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailDeleting, self.client.replication_consistency_group.delete, self.fake_rcg_id) def test_get_all_statistics_bad_status(self): + """ + Test the get_all_statistics method with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.replication_consistency_group.get_all_statistics, False) def test_replication_consistency_group_query_selected_statistics(self): + """ + Test the query_selected_statistics method of the ReplicationConsistencyGroupClient. + """ ret = self.client.replication_consistency_group.query_selected_statistics( properties=["thinCapacityInUseInKb"] ) assert ret.get(self.fake_rcg_id).get("thinCapacityInUseInKb") == 0 def test_replication_consistency_group_query_selected_statistics_bad_status(self): + """ + Test the query_selected_statistics method of the ReplicationConsistencyGroupClient + with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexFailQuerying, diff --git a/tests/test_replication_pair.py b/tests/test_replication_pair.py index 58a6261..d81a95e 100644 --- a/tests/test_replication_pair.py +++ b/tests/test_replication_pair.py @@ -13,14 +13,23 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing replication pair client.""" + +# pylint: disable=invalid-name + from PyPowerFlex import exceptions -from PyPowerFlex.objects import replication_pair import tests class TestReplicationPairClient(tests.PyPowerFlexTestCase): + """ + Test class for the ReplicationPairClient. + """ def setUp(self): - super(TestReplicationPairClient, self).setUp() + """ + Set up the test environment. + """ + super().setUp() self.client.initialize() self.fake_replication_pair_id = '1' @@ -28,16 +37,16 @@ def setUp(self): self.RESPONSE_MODE.Valid: { '/types/ReplicationPair/instances': {'id': self.fake_replication_pair_id}, - '/instances/ReplicationPair::{}'.format(self.fake_replication_pair_id): + f'/instances/ReplicationPair::{self.fake_replication_pair_id}': {'id': self.fake_replication_pair_id}, - '/instances/ReplicationPair::{}' - '/action/removeReplicationPair'.format(self.fake_replication_pair_id): + f'/instances/ReplicationPair::{self.fake_replication_pair_id}' + '/action/removeReplicationPair': {}, - '/instances/ReplicationPair::{}' - '/action/pausePairInitialCopy'.format(self.fake_replication_pair_id): + f'/instances/ReplicationPair::{self.fake_replication_pair_id}' + '/action/pausePairInitialCopy': {'id': self.fake_replication_pair_id}, - '/instances/ReplicationPair::{}' - '/action/resumePairInitialCopy'.format(self.fake_replication_pair_id): + f'/instances/ReplicationPair::{self.fake_replication_pair_id}' + '/action/resumePairInitialCopy': {'id': self.fake_replication_pair_id}, '/types/ReplicationPair' '/instances/action/querySelectedStatistics': { @@ -51,23 +60,41 @@ def setUp(self): } def test_add_replication_pair(self): + """ + Test the add method of the ReplicationPairClient. + """ self.client.replication_pair.add\ (source_vol_id='1', dest_vol_id='1', rcg_id='1', copy_type='OnlineCopy', name='test') def test_remove_replication_pair(self): + """ + Test the remove method of the ReplicationPairClient. + """ self.client.replication_pair.remove(self.fake_replication_pair_id) def test_pause_online_copy(self): + """ + Test the pause method of the ReplicationPairClient. + """ self.client.replication_pair.pause(self.fake_replication_pair_id) def test_resume_online_copy(self): + """ + Test the resume method of the ReplicationPairClient. + """ self.client.replication_pair.resume(self.fake_replication_pair_id) def test_get_all_statistics(self): + """ + Test the get_all_statistics method of the ReplicationPairClient. + """ self.client.replication_pair.get_all_statistics() def test_add_replication_pair_bad_status(self): + """ + Test the add method of the ReplicationPairClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailCreating, self.client.replication_pair.add, @@ -75,23 +102,35 @@ def test_add_replication_pair_bad_status(self): rcg_id='1', copy_type='OnlineCopy', name='test') def test_remove_replication_pair_bad_status(self): + """ + Test the remove method of the ReplicationPairClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailDeleting, self.client.replication_pair.remove, self.fake_replication_pair_id) def test_get_all_statistics_bad_status(self): + """ + Test the get_all_statistics method of the ReplicationPairClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.replication_pair.get_all_statistics) def test_replication_pair_query_selected_statistics(self): + """ + Test the query_selected_statistics method of the ReplicationPairClient. + """ ret = self.client.replication_pair.query_selected_statistics( properties=["initialCopyProgress"] ) assert ret.get(self.fake_replication_pair_id).get("initialCopyProgress") == 0 def test_replication_pair_query_selected_statistics_bad_status(self): + """ + Test the query_selected_statistics method of the ReplicationPairClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexFailQuerying, diff --git a/tests/test_sdc.py b/tests/test_sdc.py index c970372..39f1f08 100644 --- a/tests/test_sdc.py +++ b/tests/test_sdc.py @@ -13,13 +13,23 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing SDC client.""" + +# pylint: disable=invalid-name + from PyPowerFlex import exceptions import tests class TestSdcClient(tests.PyPowerFlexTestCase): + """ + Tests for the SdcClient class. + """ def setUp(self): - super(TestSdcClient, self).setUp() + """ + Set up the test case. + """ + super().setUp() self.client.initialize() self.fake_sdc_id = '1' @@ -27,19 +37,15 @@ def setUp(self): self.RESPONSE_MODE.Valid: { '/types/Sdc/instances': {'id': self.fake_sdc_id}, - '/instances/Sdc::{}'.format(self.fake_sdc_id): + f'/instances/Sdc::{self.fake_sdc_id}': {'id': self.fake_sdc_id}, - '/instances/Sdc::{}' - '/action/removeSdc'.format(self.fake_sdc_id): + f'/instances/Sdc::{self.fake_sdc_id}/action/removeSdc': {}, - '/instances/Sdc::{}' - '/relationships/Volume'.format(self.fake_sdc_id): + f'/instances/Sdc::{self.fake_sdc_id}/relationships/Volume': [], - '/instances/Sdc::{}' - '/action/setSdcName'.format(self.fake_sdc_id): + f'/instances/Sdc::{self.fake_sdc_id}/action/setSdcName': {}, - '/instances/Sdc::{}' - '/action/setSdcPerformanceParameters'.format(self.fake_sdc_id): + f'/instances/Sdc::{self.fake_sdc_id}/action/setSdcPerformanceParameters': {}, '/types/Sdc' '/instances/action/querySelectedStatistics': { @@ -49,27 +55,45 @@ def setUp(self): } def test_sdc_delete(self): + """ + Test the delete method of the SdcClient. + """ self.client.sdc.delete(self.fake_sdc_id) def test_sdc_delete_bad_status(self): + """ + Test the delete method of the SdcClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailDeleting, self.client.sdc.delete, self.fake_sdc_id) def test_sdc_get_mapped_volumes(self): + """ + Test the get_mapped_volumes method of the SdcClient. + """ self.client.sdc.get_mapped_volumes(self.fake_sdc_id) def test_sdc_get_mapped_volumes_bad_status(self): + """ + Test the get_mapped_volumes method of the SdcClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.sdc.get_mapped_volumes, self.fake_sdc_id) def test_sdc_rename(self): + """ + Test the rename method of the SdcClient. + """ self.client.sdc.rename(self.fake_sdc_id, name='new_name') def test_sdc_rename_bad_status(self): + """ + Test the rename method of the SdcClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailRenaming, self.client.sdc.rename, @@ -77,9 +101,15 @@ def test_sdc_rename_bad_status(self): name='new_name') def test_set_performance_profile(self): + """ + Test the set_performance_profile method of the SdcClient. + """ self.client.sdc.set_performance_profile(self.fake_sdc_id, 'Compact') def test_set_performance_profile_bad_status(self): + """ + Test the set_performance_profile method of the SdcClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailEntityOperation, self.client.sdc.set_performance_profile, @@ -87,12 +117,18 @@ def test_set_performance_profile_bad_status(self): 'Compact') def test_sdc_query_selected_statistics(self): + """ + Test the query_selected_statistics method of the SdcClient. + """ ret = self.client.sdc.query_selected_statistics( properties=["numOfMappedVolumes"] ) assert ret.get(self.fake_sdc_id).get("numOfMappedVolumes") == 1 def test_sdc_query_selected_statistics_bad_status(self): + """ + Test the query_selected_statistics method of the SdcClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexFailQuerying, diff --git a/tests/test_sds.py b/tests/test_sds.py index 223ca2f..8b9ac4b 100644 --- a/tests/test_sds.py +++ b/tests/test_sds.py @@ -13,14 +13,24 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing SDS client.""" + +# pylint: disable=invalid-name,too-many-public-methods + from PyPowerFlex import exceptions from PyPowerFlex.objects import sds import tests class TestSdsClient(tests.PyPowerFlexTestCase): + """ + Tests for the SdsClient class. + """ def setUp(self): - super(TestSdsClient, self).setUp() + """ + Set up the test environment. + """ + super().setUp() self.client.initialize() self.fake_sds_id = '1' self.fake_sp_id = '1' @@ -31,49 +41,36 @@ def setUp(self): self.RESPONSE_MODE.Valid: { '/types/Sds/instances': {'id': self.fake_sds_id}, - '/instances/Sds::{}'.format(self.fake_sds_id): + f'/instances/Sds::{self.fake_sds_id}': {'id': self.fake_sds_id}, - '/instances/Sds::{}' - '/action/addSdsIp'.format(self.fake_sds_id): + f'/instances/Sds::{self.fake_sds_id}/action/addSdsIp': {}, - '/instances/Sds::{}' - '/action/removeSds'.format(self.fake_sds_id): + f'/instances/Sds::{self.fake_sds_id}/action/removeSds': {}, - '/instances/Sds::{}' - '/relationships/Device'.format(self.fake_sds_id): + f'/instances/Sds::{self.fake_sds_id}/relationships/Device': [], - '/instances/Sds::{}' - '/action/setSdsName'.format(self.fake_sds_id): + f'/instances/Sds::{self.fake_sds_id}/action/setSdsName': {}, - '/instances/Sds::{}' - '/action/removeSdsIp'.format(self.fake_sds_id): + f'/instances/Sds::{self.fake_sds_id}/action/removeSdsIp': {}, - '/instances/Sds::{}' - '/action/setSdsIpRole'.format(self.fake_sds_id): + f'/instances/Sds::{self.fake_sds_id}/action/setSdsIpRole': {}, - '/instances/Sds::{}' - '/action/setSdsPort'.format(self.fake_sds_id): + f'/instances/Sds::{self.fake_sds_id}/action/setSdsPort': {}, - '/instances/Sds::{}' - '/action/enableRfcache'.format(self.fake_sds_id): + f'/instances/Sds::{self.fake_sds_id}/action/enableRfcache': {}, - '/instances/Sds::{}' - '/action/disableRfcache'.format(self.fake_sds_id): + f'/instances/Sds::{self.fake_sds_id}/action/disableRfcache': {}, - '/instances/Sds::{}' - '/action/setSdsRmcacheEnabled'.format(self.fake_sds_id): + f'/instances/Sds::{self.fake_sds_id}/action/setSdsRmcacheEnabled': {}, - '/instances/Sds::{}' - '/action/setSdsRmcacheSize'.format(self.fake_sds_id): + f'/instances/Sds::{self.fake_sds_id}/action/setSdsRmcacheSize': {}, - '/instances/Sds::{}' - '/action/setSdsPerformanceParameters' - .format(self.fake_sds_id): + f'/instances/Sds::{self.fake_sds_id}/action/setSdsPerformanceParameters': {}, '/types/Sds' '/instances/action/querySelectedStatistics': { self.fake_sds_id: {'rfcacheFdReadTimeGreater5Sec': 0} - }, + }, }, self.RESPONSE_MODE.Invalid: { '/types/Sds/instances': @@ -82,9 +79,15 @@ def setUp(self): } def test_sds_add_ip(self): + """ + Test the add_ip method of the SdsClient. + """ self.client.sds.add_ip(self.fake_sds_id, self.fake_sds_ips[0]) def test_sds_add_ip_bad_status(self): + """ + Test the add_ip method of the SdsClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.sds.add_ip, @@ -92,10 +95,16 @@ def test_sds_add_ip_bad_status(self): self.fake_sds_ips[0]) def test_sds_create(self): + """ + Test the create method of the SdsClient. + """ self.client.sds.create(protection_domain_id=self.fake_pd_id, sds_ips=self.fake_sds_ips) def test_sds_create_bad_status(self): + """ + Test the create method of the SdsClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailCreating, self.client.sds.create, @@ -103,6 +112,9 @@ def test_sds_create_bad_status(self): sds_ips=self.fake_sds_ips) def test_sds_create_no_id_in_response(self): + """ + Test the create method of the SdsClient with no ID in the response. + """ with self.http_response_mode(self.RESPONSE_MODE.Invalid): self.assertRaises(KeyError, self.client.sds.create, @@ -110,27 +122,45 @@ def test_sds_create_no_id_in_response(self): sds_ips=self.fake_sds_ips) def test_sds_delete(self): + """ + Test the delete method of the SdsClient. + """ self.client.sds.delete(self.fake_sds_id) def test_sds_delete_bad_status(self): + """ + Test the delete method of the SdsClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailDeleting, self.client.sds.delete, self.fake_sds_id) def test_sds_get_devices(self): + """ + Test the get_devices method of the SdsClient. + """ self.client.sds.get_devices(self.fake_sds_id) def test_sds_get_devices_bad_status(self): + """ + Test the get_devices method of the SdsClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.sds.get_devices, self.fake_sds_id) def test_sds_rename(self): + """ + Test the rename method of the SdsClient. + """ self.client.sds.rename(self.fake_sds_id, name='new_name') def test_sds_rename_bad_status(self): + """ + Test the rename method of the SdsClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailRenaming, self.client.sds.rename, @@ -138,9 +168,15 @@ def test_sds_rename_bad_status(self): name='new_name') def test_sds_remove_ip(self): + """ + Test the remove_ip method of the SdsClient. + """ self.client.sds.remove_ip(self.fake_sds_id, ip='1.2.3.4') def test_sds_remove_ip_bad_status(self): + """ + Test the remove_ip method of the SdsClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.sds.remove_ip, @@ -148,12 +184,18 @@ def test_sds_remove_ip_bad_status(self): ip='1.2.3.4') def test_sds_set_ip_role(self): + """ + Test the set_ip_role method. + """ self.client.sds.set_ip_role(self.fake_sds_id, ip='1.2.3.4', role=sds.SdsIpRoles.sdc_only, force=True) def test_sds_set_ip_role_bad_status(self): + """ + Test the set_ip_role method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.sds.set_ip_role, @@ -163,9 +205,15 @@ def test_sds_set_ip_role_bad_status(self): force=True) def test_sds_set_port(self): + """ + Test the set_port method. + """ self.client.sds.set_port(self.fake_sds_id, sds_port=4443) def test_sds_set_port_bad_status(self): + """ + Test the set_port method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.sds.set_port, @@ -173,10 +221,16 @@ def test_sds_set_port_bad_status(self): sds_port=4443) def test_sds_set_rfcache_enabled(self): + """ + Test the set_rfcache_enabled method. + """ self.client.sds.set_rfcache_enabled(self.fake_sds_id, rfcache_enabled=True) def test_sds_set_rfcache_enabled_bad_status(self): + """ + Test the set_rfcache_enabled method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.sds.set_rfcache_enabled, @@ -184,10 +238,16 @@ def test_sds_set_rfcache_enabled_bad_status(self): rfcache_enabled=True) def test_sds_set_rmcache_enabled(self): + """ + Test the set_rmcache_enabled method. + """ self.client.sds.set_rmcache_enabled(self.fake_sds_id, rmcache_enabled=True) def test_sds_set_rmcache_enabled_bad_status(self): + """ + Test the set_rmcache_enabled method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.sds.set_rmcache_enabled, @@ -195,10 +255,16 @@ def test_sds_set_rmcache_enabled_bad_status(self): rmcache_enabled=True) def test_sds_set_rmcache_size(self): + """ + Test the set_rmcache_size method. + """ self.client.sds.set_rmcache_size(self.fake_sds_id, rmcache_size=128) def test_sds_set_rmcache_size_bad_status(self): + """ + Test the set_rmcache_size method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.sds.set_rmcache_size, @@ -206,11 +272,17 @@ def test_sds_set_rmcache_size_bad_status(self): rmcache_size=128) def test_sds_set_performance_parameters(self): + """ + Test the set_performance_parameters method. + """ self.client.sds.set_performance_parameters( self.fake_sds_id, performance_profile=sds.PerformanceProfile.highperformance) def test_sds_set_performance_parameters_bad_status(self): + """ + Test the set_performance_parameters method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -219,12 +291,19 @@ def test_sds_set_performance_parameters_bad_status(self): performance_profile=sds.PerformanceProfile.highperformance) def test_sds_query_selected_statistics(self): + """ + Test the query_selected_statistics method. + """ ret = self.client.sds.query_selected_statistics( properties=["rfcacheFdReadTimeGreater5Sec"] ) - assert ret.get(self.fake_sds_id).get("rfcacheFdReadTimeGreater5Sec") == 0 + assert ret.get(self.fake_sds_id).get( + "rfcacheFdReadTimeGreater5Sec") == 0 def test_sds_query_selected_statistics_bad_status(self): + """ + Test the query_selected_statistics method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexFailQuerying, diff --git a/tests/test_sdt.py b/tests/test_sdt.py index f975675..927d007 100644 --- a/tests/test_sdt.py +++ b/tests/test_sdt.py @@ -13,14 +13,24 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing SDT client.""" + +# pylint: disable=invalid-name,too-many-public-methods + from PyPowerFlex import exceptions from PyPowerFlex.objects import sdt import tests class TestSdtClient(tests.PyPowerFlexTestCase): + """ + Tests for the SdtClient class. + """ def setUp(self): - super(TestSdtClient, self).setUp() + """ + Set up the test environment. + """ + super().setUp() self.client.initialize() self.fake_sdt_id = "1" self.fake_sdt_name = "1" @@ -30,23 +40,17 @@ def setUp(self): self.MOCK_RESPONSES = { self.RESPONSE_MODE.Valid: { "/types/Sdt/instances": {"id": self.fake_sdt_id}, - "/instances/Sdt::{}".format(self.fake_sdt_id): {"id": self.fake_sdt_id}, - "/instances/Sdt::{}" "/action/addIp".format(self.fake_sdt_id): {}, - "/instances/Sdt::{}" "/action/removeIp".format(self.fake_sdt_id): {}, - "/instances/Sdt::{}" "/action/renameSdt".format(self.fake_sdt_id): {}, - "/instances/Sdt::{}" - "/action/modifyIpRole".format(self.fake_sdt_id): {}, - "/instances/Sdt::{}" - "/action/modifyStoragePort".format(self.fake_sdt_id): {}, - "/instances/Sdt::{}" - "/action/modifyNvmePort".format(self.fake_sdt_id): {}, - "/instances/Sdt::{}" - "/action/modifyDiscoveryPort".format(self.fake_sdt_id): {}, - "/instances/Sdt::{}" - "/action/enterMaintenanceMode".format(self.fake_sdt_id): {}, - "/instances/Sdt::{}" - "/action/exitMaintenanceMode".format(self.fake_sdt_id): {}, - "/instances/Sdt::{}" "/action/removeSdt".format(self.fake_sdt_id): {}, + f"/instances/Sdt::{self.fake_sdt_id}": {"id": self.fake_sdt_id}, + f"/instances/Sdt::{self.fake_sdt_id}/action/addIp": {}, + f"/instances/Sdt::{self.fake_sdt_id}/action/removeIp": {}, + f"/instances/Sdt::{self.fake_sdt_id}/action/renameSdt": {}, + f"/instances/Sdt::{self.fake_sdt_id}/action/modifyIpRole": {}, + f"/instances/Sdt::{self.fake_sdt_id}/action/modifyStoragePort": {}, + f"/instances/Sdt::{self.fake_sdt_id}/action/modifyNvmePort": {}, + f"/instances/Sdt::{self.fake_sdt_id}/action/modifyDiscoveryPort": {}, + f"/instances/Sdt::{self.fake_sdt_id}/action/enterMaintenanceMode": {}, + f"/instances/Sdt::{self.fake_sdt_id}/action/exitMaintenanceMode": {}, + f"/instances/Sdt::{self.fake_sdt_id}/action/removeSdt": {}, }, self.RESPONSE_MODE.Invalid: { "/types/Sdt/instances": {}, @@ -54,6 +58,9 @@ def setUp(self): } def test_sdt_create(self): + """ + Test the create method of the SdtClient. + """ self.client.sdt.create( protection_domain_id=self.fake_pd_id, sdt_ips=self.fake_sdt_ips, @@ -61,6 +68,9 @@ def test_sdt_create(self): ) def test_sdt_create_bad_status(self): + """ + Test the create method of the SdtClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexFailCreating, @@ -71,6 +81,9 @@ def test_sdt_create_bad_status(self): ) def test_sdt_create_no_id_in_response(self): + """ + Test the create method of the SdtClient with no id in the response. + """ with self.http_response_mode(self.RESPONSE_MODE.Invalid): self.assertRaises( KeyError, @@ -81,9 +94,15 @@ def test_sdt_create_no_id_in_response(self): ) def test_sdt_rename(self): + """ + Test the rename method of the SdtClient. + """ self.client.sdt.rename(self.fake_sdt_id, name="new_name") def test_sdt_rename_bad_status(self): + """ + Test the rename method of the SdtClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexFailRenaming, @@ -93,11 +112,17 @@ def test_sdt_rename_bad_status(self): ) def test_sdt_add_ip(self): + """ + Test the add_ip method of the SdtClient. + """ self.client.sdt.add_ip( self.fake_sdt_id, ip="1.2.3.4", role=sdt.SdtIpRoles.storage_and_host ) def test_sdt_add_ip_bad_status(self): + """ + Test the add_ip method of the SdtClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -108,9 +133,15 @@ def test_sdt_add_ip_bad_status(self): ) def test_sdt_remove_ip(self): + """ + Test the remove_ip method of the SdtClient. + """ self.client.sdt.remove_ip(self.fake_sdt_id, ip="1.2.3.4") def test_sdt_remove_ip_bad_status(self): + """ + Test the remove_ip method of the SdtClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -120,11 +151,17 @@ def test_sdt_remove_ip_bad_status(self): ) def test_sdt_set_ip_role(self): + """ + Test the set_ip_role method of the SdtClient. + """ self.client.sdt.set_ip_role( self.fake_sdt_id, ip="1.2.3.4", role=sdt.SdtIpRoles.storage_and_host ) def test_sdt_set_ip_role_bad_status(self): + """ + Test the set_ip_role method of the SdtClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -135,9 +172,15 @@ def test_sdt_set_ip_role_bad_status(self): ) def test_sdt_set_storage_port(self): + """ + Test the set_storage_port method of the SdtClient. + """ self.client.sdt.set_storage_port(self.fake_sdt_id, storage_port=12200) def test_sdt_set_storage_port_bad_status(self): + """ + Test the set_storage_port method of the SdtClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -147,9 +190,15 @@ def test_sdt_set_storage_port_bad_status(self): ) def test_sdt_set_nvme_port(self): + """ + Test case for setting NVMe port of a Storage Device Target. + """ self.client.sdt.set_nvme_port(self.fake_sdt_id, nvme_port=4420) def test_sdt_set_nvme_port_bad_status(self): + """ + Test case for setting NVMe port of a Storage Device Target with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -159,9 +208,15 @@ def test_sdt_set_nvme_port_bad_status(self): ) def test_sdt_set_discovery_port(self): + """ + Test case for setting discovery port of a Storage Device Target. + """ self.client.sdt.set_discovery_port(self.fake_sdt_id, discovery_port=8009) def test_sdt_set_discovery_port_bad_status(self): + """ + Test case for setting discovery port of a Storage Device Target with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -171,9 +226,15 @@ def test_sdt_set_discovery_port_bad_status(self): ) def test_sdt_enter_maintenance_mode(self): + """ + Test case for entering maintenance mode of a Storage Device Target. + """ self.client.sdt.enter_maintenance_mode(self.fake_sdt_id) def test_sdt_enter_maintenance_mode_bad_status(self): + """ + Test case for entering maintenance mode of a Storage Device Target with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -182,9 +243,15 @@ def test_sdt_enter_maintenance_mode_bad_status(self): ) def test_sdt_exit_maintenance_mode(self): + """ + Test case for exiting maintenance mode of a Storage Device Target. + """ self.client.sdt.exit_maintenance_mode(self.fake_sdt_id) def test_sdt_exit_maintenance_mode_bad_status(self): + """ + Test case for exiting maintenance mode of a Storage Device Target with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -193,9 +260,15 @@ def test_sdt_exit_maintenance_mode_bad_status(self): ) def test_sdt_delete(self): + """ + Test case for deleting a Storage Device Target. + """ self.client.sdt.delete(self.fake_sdt_id) def test_sdt_delete_bad_status(self): + """ + Test case for deleting a Storage Device Target with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexFailDeleting, diff --git a/tests/test_service_template.py b/tests/test_service_template.py index ee1ccfe..b0afa22 100644 --- a/tests/test_service_template.py +++ b/tests/test_service_template.py @@ -13,13 +13,23 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing service template client.""" + +# pylint: disable=invalid-name + from PyPowerFlex import exceptions import tests class TestServiceTemplateClient(tests.PyPowerFlexTestCase): + """ + Test class for the ServiceTemplateClient. + """ def setUp(self): - super(TestServiceTemplateClient, self).setUp() + """ + Set up the test environment. + """ + super().setUp() self.client.initialize() self.template_id = 1234 self.MOCK_RESPONSES = { @@ -31,20 +41,36 @@ def setUp(self): } def test_service_template_get(self): + """ + Test the get method of the ServiceTemplateClient. + """ self.client.service_template.get() def test_service_template_get_with_filters(self): - self.client.service_template.get(filters=['eq,draft,False'], limit=10, include_attachments=False) + """ + Test the get method of the ServiceTemplateClient with filters. + """ + self.client.service_template.get( + filters=['eq,draft,False'], limit=10, include_attachments=False) def test_service_template_get_bad_status(self): + """ + Test the get method of the ServiceTemplateClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.service_template.get) def test_service_template_get_by_id(self): + """ + Test the get_by_id method of the ServiceTemplateClient. + """ self.client.service_template.get_by_id(self.template_id, for_deployment=True) def test_service_template_get_by_id_bad_status(self): + """ + Test the get_by_id method of the ServiceTemplateClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.service_template.get_by_id, diff --git a/tests/test_snapshot_policy.py b/tests/test_snapshot_policy.py index 107355b..917650e 100644 --- a/tests/test_snapshot_policy.py +++ b/tests/test_snapshot_policy.py @@ -13,14 +13,24 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing snapshot policy client.""" + +# pylint: disable=invalid-name + from PyPowerFlex import exceptions from PyPowerFlex.objects import snapshot_policy as sp import tests class TestSnapshotPolicyClient(tests.PyPowerFlexTestCase): + """ + Test class for snapshot policy client. + """ def setUp(self): - super(TestSnapshotPolicyClient, self).setUp() + """ + Set up the test case. + """ + super().setUp() self.client.initialize() self.fake_policy_id = '1' self.fake_volume_id = '1' @@ -29,30 +39,23 @@ def setUp(self): self.RESPONSE_MODE.Valid: { '/types/SnapshotPolicy/instances': {'id': self.fake_policy_id}, - '/instances/SnapshotPolicy::{}'.format(self.fake_policy_id): + f'/instances/SnapshotPolicy::{self.fake_policy_id}': {'id': self.fake_policy_id}, - '/instances/SnapshotPolicy::{}' - '/action/removeSnapshotPolicy'.format(self.fake_policy_id): + f'/instances/SnapshotPolicy::{self.fake_policy_id}/action/removeSnapshotPolicy': {}, - '/instances/SnapshotPolicy::{}' - '/action' - '/addSourceVolumeToSnapshotPolicy'.format(self.fake_policy_id): + f'/instances/SnapshotPolicy::{self.fake_policy_id}' + '/action/addSourceVolumeToSnapshotPolicy': {}, - '/instances/SnapshotPolicy::{}' - '/action/modifySnapshotPolicy'.format(self.fake_policy_id): + f'/instances/SnapshotPolicy::{self.fake_policy_id}/action/modifySnapshotPolicy': {}, - '/instances/SnapshotPolicy::{}' - '/action/pauseSnapshotPolicy'.format(self.fake_policy_id): + f'/instances/SnapshotPolicy::{self.fake_policy_id}/action/pauseSnapshotPolicy': {}, - '/instances/SnapshotPolicy::{}' - '/action/removeSourceVolume' - 'FromSnapshotPolicy'.format(self.fake_policy_id): + f'/instances/SnapshotPolicy::{self.fake_policy_id}' + '/action/removeSourceVolumeFromSnapshotPolicy': {}, - '/instances/SnapshotPolicy::{}' - '/action/renameSnapshotPolicy'.format(self.fake_policy_id): + f'/instances/SnapshotPolicy::{self.fake_policy_id}/action/renameSnapshotPolicy': {}, - '/instances/SnapshotPolicy::{}' - '/action/resumeSnapshotPolicy'.format(self.fake_policy_id): + f'/instances/SnapshotPolicy::{self.fake_policy_id}/action/resumeSnapshotPolicy': {}, '/types/SnapshotPolicy' '/instances/action/querySelectedStatistics': { @@ -66,10 +69,16 @@ def setUp(self): } def test_snapshot_policy_add_source_volume(self): + """ + Test adding a source volume to a snapshot policy. + """ self.client.snapshot_policy.add_source_volume(self.fake_policy_id, self.fake_volume_id) def test_snapshot_policy_add_source_volume_bad_status(self): + """ + Test adding a source volume to a snapshot policy with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.snapshot_policy.add_source_volume, @@ -77,6 +86,9 @@ def test_snapshot_policy_add_source_volume_bad_status(self): self.fake_volume_id) def test_snapshot_policy_create(self): + """ + Test creating a snapshot policy. + """ self.client.snapshot_policy.create( auto_snap_creation_cadence_in_min=15, retained_snaps_per_level=[1, 2, 3], @@ -85,6 +97,9 @@ def test_snapshot_policy_create(self): ) def test_snapshot_policy_create_bad_status(self): + """ + Test creating a snapshot policy with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailCreating, self.client.snapshot_policy.create, @@ -94,6 +109,9 @@ def test_snapshot_policy_create_bad_status(self): paused=False) def test_snapshot_policy_create_no_id_in_response(self): + """ + Test creating a snapshot policy with no id in the response. + """ with self.http_response_mode(self.RESPONSE_MODE.Invalid): self.assertRaises(KeyError, self.client.snapshot_policy.create, @@ -103,15 +121,24 @@ def test_snapshot_policy_create_no_id_in_response(self): paused=False) def test_snapshot_policy_delete(self): + """ + Test deleting a snapshot policy. + """ self.client.snapshot_policy.delete(self.fake_policy_id) def test_snapshot_policy_delete_bad_status(self): + """ + Test deleting a snapshot policy with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailDeleting, self.client.snapshot_policy.delete, self.fake_policy_id) def test_snapshot_policy_modify(self): + """ + Test modifying a snapshot policy. + """ self.client.snapshot_policy.modify( self.fake_policy_id, auto_snap_creation_cadence_in_min=25, @@ -119,6 +146,9 @@ def test_snapshot_policy_modify(self): ) def test_snapshot_policy_modify_bad_status(self): + """ + Test modifying a snapshot policy with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.snapshot_policy.modify, @@ -127,15 +157,24 @@ def test_snapshot_policy_modify_bad_status(self): retained_snaps_per_level=[1, 2, 4]) def test_snapshot_policy_pause(self): + """ + Test pausing a snapshot policy. + """ self.client.snapshot_policy.pause(self.fake_policy_id) def test_snapshot_policy_pause_bad_status(self): + """ + Test pausing a snapshot policy with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.snapshot_policy.pause, self.fake_policy_id) def test_snapshot_policy_remove_source_volume(self): + """ + Test removing a source volume from a snapshot policy. + """ self.client.snapshot_policy.remove_source_volume( self.fake_policy_id, self.fake_volume_id, @@ -144,6 +183,9 @@ def test_snapshot_policy_remove_source_volume(self): ) def test_snapshot_policy_remove_source_volume_bad_status(self): + """ + Test removing a source volume from a snapshot policy with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.snapshot_policy.remove_source_volume, @@ -153,10 +195,16 @@ def test_snapshot_policy_remove_source_volume_bad_status(self): False) def test_snapshot_policy_rename(self): + """ + Test renaming a snapshot policy. + """ self.client.snapshot_policy.rename(self.fake_policy_id, name='new_name') def test_snapshot_policy_rename_bad_status(self): + """ + Tests the behavior of the rename method when the HTTP response has a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailRenaming, self.client.snapshot_policy.rename, @@ -164,21 +212,34 @@ def test_snapshot_policy_rename_bad_status(self): name='new_name') def test_snapshot_policy_resume(self): + """ + Tests the behavior of the resume method. + """ self.client.snapshot_policy.resume(self.fake_policy_id) def test_snapshot_policy_resume_bad_status(self): + """ + Tests the behavior of the resume method when the HTTP response has a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.snapshot_policy.resume, self.fake_policy_id) def test_snapshot_policy_query_selected_statistics(self): + """ + Tests the behavior of the query_selected_statistics method. + """ ret = self.client.snapshot_policy.query_selected_statistics( properties=["numOfSrcVols"] ) assert ret.get(self.fake_policy_id).get("numOfSrcVols") == 1 def test_snapshot_policy_query_selected_statistics_bad_status(self): + """ + Tests the behavior of the query_selected_statistics method + when the HTTP response has a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexFailQuerying, diff --git a/tests/test_storage_pool.py b/tests/test_storage_pool.py index 0c4e1d9..0b0ba2c 100644 --- a/tests/test_storage_pool.py +++ b/tests/test_storage_pool.py @@ -13,6 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing storage pool client.""" + +# pylint: disable=invalid-name,too-many-public-methods + from PyPowerFlex import exceptions from PyPowerFlex.objects.storage_pool import CompressionMethod from PyPowerFlex.objects.storage_pool import ExternalAccelerationType @@ -21,8 +25,14 @@ class TestStoragePoolClient(tests.PyPowerFlexTestCase): + """ + Test class for the StoragePoolClient. + """ def setUp(self): - super(TestStoragePoolClient, self).setUp() + """ + Set up the test environment. + """ + super().setUp() self.client.initialize() self.fake_pd_id = '1' self.fake_sp_id = '1' @@ -33,93 +43,65 @@ def setUp(self): [], '/types/StoragePool/instances': {'id': self.fake_sp_id}, - '/instances/StoragePool::{}'.format(self.fake_sp_id): + f"/instances/StoragePool::{self.fake_sp_id}": {'id': self.fake_sp_id}, - '/instances/StoragePool::{}' - '/action/removeStoragePool'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/removeStoragePool': {}, - '/instances/StoragePool::{}' - '/relationships/Device'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/relationships/Device': [], - '/instances/StoragePool::{}' - '/relationships/SpSds'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/relationships/SpSds': [], - '/instances/StoragePool::{}' - '/relationships/Volume'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/relationships/Volume': [], - '/instances/StoragePool::{}' - '/relationships/Statistics'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/relationships/Statistics': {}, - '/instances/StoragePool::{}' - '/action/setStoragePoolName'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/setStoragePoolName': {}, - '/instances/StoragePool::{}' - '/action/setChecksumEnabled'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/setChecksumEnabled': {}, - '/instances/StoragePool::{}' - '/action/modifyCompressionMethod'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/modifyCompressionMethod': {}, - '/instances/StoragePool::{}' - '/action/setExternalAccelerationType'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/setExternalAccelerationType': {}, - '/instances/StoragePool::{}' - '/action/setMediaType'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/setMediaType': {}, - '/instances/StoragePool::{}' - '/action/setRebalanceEnabled'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/setRebalanceEnabled': {}, - '/instances/StoragePool::{}' - '/action/setRebuildEnabled'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/setRebuildEnabled': {}, - '/instances/StoragePool::{}' - '/action/setSparePercentage'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/setSparePercentage': {}, - '/instances/StoragePool::{}' - '/action/enableRfcache'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/enableRfcache': {}, - '/instances/StoragePool::{}' - '/action/disableRfcache'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/disableRfcache': {}, - '/instances/StoragePool::{}' - '/action/setUseRmcache'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/setUseRmcache': {}, - '/instances/StoragePool::{}' - '/action/setZeroPaddingPolicy'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/setZeroPaddingPolicy': {}, - - - '/instances/StoragePool::{}' - '/action/setReplicationJournalCapacity'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/setReplicationJournalCapacity': {}, - '/instances/StoragePool::{}' - '/action/setCapacityAlertThresholds'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/setCapacityAlertThresholds': {}, - '/instances/StoragePool::{}' - '/action/setProtectedMaintenanceModeIoPriorityPolicy'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}' + '/action/setProtectedMaintenanceModeIoPriorityPolicy': {}, - '/instances/StoragePool::{}' - '/action/setVTreeMigrationIoPriorityPolicy'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}' + '/action/setVTreeMigrationIoPriorityPolicy': {}, - '/instances/StoragePool::{}' - '/action/setRebalanceIoPriorityPolicy'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/setRebalanceIoPriorityPolicy': {}, - '/instances/StoragePool::{}' - '/action/setRmcacheWriteHandlingMode'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/setRmcacheWriteHandlingMode': {}, - '/instances/StoragePool::{}' - '/action/setRebuildRebalanceParallelism'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/setRebuildRebalanceParallelism': {}, - '/instances/StoragePool::{}' - '/action/disablePersistentChecksum'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/disablePersistentChecksum': {}, - '/instances/StoragePool::{}' - '/action/enablePersistentChecksum'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/enablePersistentChecksum': {}, - '/instances/StoragePool::{}' - '/action/disableFragmentation'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/disableFragmentation': {}, - '/instances/StoragePool::{}' - '/action/enableFragmentation'.format(self.fake_sp_id): + f'/instances/StoragePool::{self.fake_sp_id}/action/enableFragmentation': {}, '/types/StoragePool' '/instances/action/querySelectedStatistics': { @@ -133,10 +115,16 @@ def setUp(self): } def test_storage_pool_create(self): + """ + Test the create method of the StoragePoolClient. + """ self.client.storage_pool.create(media_type=MediaType.hdd, protection_domain_id=self.fake_pd_id) def test_storage_pool_create_bad_status(self): + """ + Test the create method of the StoragePoolClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailCreating, self.client.storage_pool.create, @@ -144,6 +132,9 @@ def test_storage_pool_create_bad_status(self): protection_domain_id=self.fake_pd_id) def test_storage_pool_create_no_id_in_response(self): + """ + Test the create method of the StoragePoolClient with no id in the response. + """ with self.http_response_mode(self.RESPONSE_MODE.Invalid): self.assertRaises(KeyError, self.client.storage_pool.create, @@ -151,54 +142,90 @@ def test_storage_pool_create_no_id_in_response(self): protection_domain_id=self.fake_pd_id) def test_storage_pool_delete(self): + """ + Test the delete method of the StoragePoolClient. + """ self.client.storage_pool.delete(self.fake_sp_id) def test_storage_pool_delete_bad_status(self): + """ + Test the delete method of the StoragePoolClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailDeleting, self.client.storage_pool.delete, self.fake_sp_id) def test_storage_pool_get_devices(self): + """ + Test the get_devices method of the StoragePoolClient. + """ self.client.storage_pool.get_devices(self.fake_sp_id) def test_storage_pool_get_devices_bad_status(self): + """ + Test the get_devices method of the StoragePoolClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.storage_pool.get_devices, self.fake_sp_id) def test_storage_pool_get_sdss(self): + """ + Test the get_sdss method of the StoragePoolClient. + """ self.client.storage_pool.get_sdss(self.fake_sp_id) def test_storage_pool_get_sdss_bad_status(self): + """ + Test the get_sdss method of the StoragePoolClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.storage_pool.get_sdss, self.fake_sp_id) def test_storage_pool_get_volumes(self): + """ + Test the get_volumes method of the StoragePoolClient. + """ self.client.storage_pool.get_volumes(self.fake_sp_id) def test_storage_pool_get_volumes_bad_status(self): + """ + Test the get_volumes method of the StoragePoolClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.storage_pool.get_volumes, self.fake_sp_id) def test_storage_pool_get_statistics(self): + """ + Test the get_statistics method of the StoragePoolClient. + """ self.client.storage_pool.get_statistics(self.fake_sp_id) def test_storage_pool_get_statistics_bad_status(self): + """ + Test the get_statistics method of the StoragePoolClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.storage_pool.get_statistics, self.fake_sp_id) def test_storage_pool_rename(self): + """ + Test the rename method of the StoragePoolClient. + """ self.client.storage_pool.rename(self.fake_sp_id, name='new_name') def test_storage_pool_rename_bad_status(self): + """ + Test the rename method of the StoragePoolClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailRenaming, self.client.storage_pool.rename, @@ -206,10 +233,16 @@ def test_storage_pool_rename_bad_status(self): name='new_name') def test_storage_pool_set_checksum_enabled(self): + """ + Test the set_checksum_enabled method of the StoragePoolClient. + """ self.client.storage_pool.set_checksum_enabled(self.fake_sp_id, checksum_enabled=True) def test_storage_pool_set_checksum_enabled_bad_status(self): + """ + Test the set_checksum_enabled method of the StoragePoolClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.storage_pool.set_checksum_enabled, @@ -217,12 +250,18 @@ def test_storage_pool_set_checksum_enabled_bad_status(self): checksum_enabled=True) def test_storage_pool_set_compression_method(self): + """ + Test the set_compression_method method of the StoragePoolClient. + """ self.client.storage_pool.set_compression_method( self.fake_sp_id, compression_method=CompressionMethod.normal ) def test_storage_pool_set_compression_method_bad_status(self): + """ + Test the set_compression_method method of the StoragePoolClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -232,12 +271,18 @@ def test_storage_pool_set_compression_method_bad_status(self): ) def test_storage_pool_set_external_acceleration_type(self): + """ + Test case for setting external acceleration type for PowerFlex storage pool. + """ self.client.storage_pool.set_external_acceleration_type( self.fake_sp_id, external_acceleration_type=ExternalAccelerationType.read ) def test_storage_pool_set_external_acceleration_type_bad_status(self): + """ + Test case for setting external acceleration type for PowerFlex storage pool with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -247,6 +292,10 @@ def test_storage_pool_set_external_acceleration_type_bad_status(self): ) def test_storage_pool_set_external_acceleration_type_invalid_input(self): + """ + Test case for setting external acceleration type for PowerFlex + storage pool with invalid input. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.InvalidInput, @@ -258,12 +307,18 @@ def test_storage_pool_set_external_acceleration_type_invalid_input(self): ) def test_storage_pool_set_media_type(self): + """ + Test case for setting media type for PowerFlex storage pool. + """ self.client.storage_pool.set_media_type( self.fake_sp_id, media_type=MediaType.hdd ) def test_storage_pool_set_media_type_bad_status(self): + """ + Test case for setting media type for PowerFlex storage pool with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -273,12 +328,18 @@ def test_storage_pool_set_media_type_bad_status(self): ) def test_storage_pool_set_rebalance_enabled(self): + """ + Test case for setting rebalance enabled for PowerFlex storage pool. + """ self.client.storage_pool.set_rebalance_enabled( self.fake_sp_id, rebalance_enabled=True ) def test_storage_pool_set_rebalance_enabled_bad_status(self): + """ + Test case for setting rebalance enabled for PowerFlex storage pool with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -288,12 +349,18 @@ def test_storage_pool_set_rebalance_enabled_bad_status(self): ) def test_storage_pool_set_rebuild_enabled(self): + """ + Test case for setting rebuild enabled for PowerFlex storage pool. + """ self.client.storage_pool.set_rebuild_enabled( self.fake_sp_id, rebuild_enabled=True ) def test_storage_pool_set_rebuild_enabled_bad_status(self): + """ + Test case for setting rebuild enabled for PowerFlex storage pool with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -303,12 +370,18 @@ def test_storage_pool_set_rebuild_enabled_bad_status(self): ) def test_storage_pool_set_spare_percentage(self): + """ + Test case for setting spare percentage for PowerFlex storage pool. + """ self.client.storage_pool.set_spare_percentage( self.fake_sp_id, spare_percentage=25 ) def test_storage_pool_set_spare_percentage_bad_status(self): + """ + Test case for setting spare percentage for PowerFlex storage pool with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -318,18 +391,27 @@ def test_storage_pool_set_spare_percentage_bad_status(self): ) def test_storage_pool_set_use_rfcache_enabled(self): + """ + Test case for setting use_rfcache enabled for PowerFlex storage pool. + """ self.client.storage_pool.set_use_rfcache( self.fake_sp_id, use_rfcache=True ) def test_storage_pool_set_use_rfcache_disabled(self): + """ + Test case for setting use_rfcache disabled for PowerFlex storage pool. + """ self.client.storage_pool.set_use_rfcache( self.fake_sp_id, use_rfcache=False ) def test_storage_pool_set_use_rfcache_bad_status(self): + """ + Test case for setting use_rfcache for PowerFlex storage pool with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -339,12 +421,18 @@ def test_storage_pool_set_use_rfcache_bad_status(self): ) def test_storage_pool_set_use_rmcache(self): + """ + Test case for setting use_rmcache for PowerFlex storage pool. + """ self.client.storage_pool.set_use_rmcache( self.fake_sp_id, use_rmcache=True ) def test_storage_pool_set_use_rmcache_bad_status(self): + """ + Test case for setting use_rmcache for PowerFlex storage pool with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -354,12 +442,18 @@ def test_storage_pool_set_use_rmcache_bad_status(self): ) def test_storage_pool_set_zero_padding_policy(self): + """ + Test case for setting zero padding policy for PowerFlex storage pool. + """ self.client.storage_pool.set_zero_padding_policy( self.fake_sp_id, zero_padding_enabled=True ) def test_storage_pool_set_zero_padding_policy_bad_status(self): + """ + Test case for setting zero padding policy for PowerFlex storage pool with bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -369,12 +463,18 @@ def test_storage_pool_set_zero_padding_policy_bad_status(self): ) def test_storage_pool_set_rep_cap_max_ratio(self): + """ + Test method for setting rep_cap_max_ratio + """ self.client.storage_pool.set_rep_cap_max_ratio( self.fake_sp_id, rep_cap_max_ratio=60 ) def test_storage_pool_set_rep_cap_max_ratio_bad_status(self): + """ + Test method for setting rep_cap_max_ratio with bad status + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -384,6 +484,9 @@ def test_storage_pool_set_rep_cap_max_ratio_bad_status(self): ) def test_storage_pool_set_cap_alert_thresholds(self): + """ + Test method for setting cap_alert_thresholds + """ self.client.storage_pool.set_cap_alert_thresholds( self.fake_sp_id, cap_alert_high_threshold=20, @@ -391,6 +494,9 @@ def test_storage_pool_set_cap_alert_thresholds(self): ) def test_storage_pool_set_cap_alert_thresholds_bad_status(self): + """ + Test method for setting cap_alert_thresholds with bad status + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -401,6 +507,9 @@ def test_storage_pool_set_cap_alert_thresholds_bad_status(self): ) def test_storage_pool_set_protected_maintenance_mode_io_priority_policy(self): + """ + Test method for setting protected_maintenance_mode_io_priority_policy + """ self.client.storage_pool.set_protected_maintenance_mode_io_priority_policy( self.fake_sp_id, policy='unlimited', @@ -408,7 +517,10 @@ def test_storage_pool_set_protected_maintenance_mode_io_priority_policy(self): bw_limit_per_device="2048" ) - def test_storage_pool_set_protected_maintenance_mode_io_priority_policy(self): + def test_storage_pool_set_protected_maintenance_mode_io_priority_policy_bad_status(self): + """ + Test method for setting protected_maintenance_mode_io_priority_policy with bad status + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -420,6 +532,9 @@ def test_storage_pool_set_protected_maintenance_mode_io_priority_policy(self): ) def test_storage_pool_set_vtree_migration_io_priority_policy(self): + """ + Test method for setting vtree_migration_io_priority_policy + """ self.client.storage_pool.set_vtree_migration_io_priority_policy( self.fake_sp_id, policy='unlimited', @@ -428,6 +543,9 @@ def test_storage_pool_set_vtree_migration_io_priority_policy(self): ) def test_storage_pool_set_vtree_migration_io_priority_policy_bad_status(self): + """ + Test method for setting vtree_migration_io_priority_policy with bad status + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -439,12 +557,18 @@ def test_storage_pool_set_vtree_migration_io_priority_policy_bad_status(self): ) def test_storage_pool_set_rmcache_write_handling_mode(self): + """ + Test method for setting rmcache_write_handling_mode + """ self.client.storage_pool.set_rmcache_write_handling_mode( self.fake_sp_id, rmcache_write_handling_mode="Passthrough" ) def test_storage_pool_set_rmcache_write_handling_mode_bad_status(self): + """ + Test method for setting rmcache_write_handling_mode with bad status + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -454,12 +578,18 @@ def test_storage_pool_set_rmcache_write_handling_mode_bad_status(self): ) def test_storage_pool_set_rebuild_rebalance_parallelism_limit(self): + """ + Test method for setting rebuild_rebalance_parallelism_limit + """ self.client.storage_pool.set_rebuild_rebalance_parallelism_limit( self.fake_sp_id, no_of_parallel_rebuild_rebalance_jobs_per_device="3" ) def test_storage_pool_set_rebuild_rebalance_parallelism_limit_bad_status(self): + """ + Test method for setting rebuild_rebalance_parallelism_limit with bad status + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -469,6 +599,9 @@ def test_storage_pool_set_rebuild_rebalance_parallelism_limit_bad_status(self): ) def test_storage_pool_set_persistent_checksum(self): + """ + Test method for setting persistent_checksum + """ self.client.storage_pool.set_persistent_checksum( self.fake_sp_id, enable=True, @@ -477,6 +610,9 @@ def test_storage_pool_set_persistent_checksum(self): ) def test_storage_pool_set_persistent_checksum_bad_status(self): + """ + Test method for setting persistent_checksum with bad status + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -488,12 +624,18 @@ def test_storage_pool_set_persistent_checksum_bad_status(self): ) def test_storage_pool_set_fragmentation_enabled(self): + """ + Test method for setting enable_fragmentation + """ self.client.storage_pool.set_fragmentation_enabled( self.fake_sp_id, enable_fragmentation=True ) def test_storage_pool_set_fragmentation_enabled_bad_status(self): + """ + Tests that an exception is raised when the API returns a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexClientException, @@ -503,12 +645,18 @@ def test_storage_pool_set_fragmentation_enabled_bad_status(self): ) def test_storage_pool_query_selected_statistics(self): + """ + Tests that the query_selected_statistics method returns the expected value. + """ ret = self.client.storage_pool.query_selected_statistics( properties=["rfcacheWritesSkippedCacheMiss"] ) assert ret.get(self.fake_sp_id).get("rfcacheWritesSkippedCacheMiss") == 0 def test_storage_pool_query_selected_statistics_bad_status(self): + """ + Tests that an exception is raised when the API returns a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexFailQuerying, diff --git a/tests/test_system.py b/tests/test_system.py index 2c99c40..b5f6e92 100644 --- a/tests/test_system.py +++ b/tests/test_system.py @@ -13,14 +13,24 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing system client.""" + +# pylint: disable=invalid-name,too-many-public-methods,duplicate-code + from PyPowerFlex import exceptions from PyPowerFlex.objects import system import tests class TestSystemClient(tests.PyPowerFlexTestCase): + """ + Test class for the SystemClient. + """ def setUp(self): - super(TestSystemClient, self).setUp() + """ + Set up the test environment. + """ + super().setUp() self.client.initialize() self.fake_system_id = '1' self.fake_cg_id = '1' @@ -29,12 +39,11 @@ def setUp(self): self.MOCK_RESPONSES = { self.RESPONSE_MODE.Valid: { - '/instances/System::{}' - '/action' - '/removeConsistencyGroupSnapshots'.format(self.fake_system_id): + f'/instances/System::{self.fake_system_id}' + '/action/removeConsistencyGroupSnapshots': {}, - '/instances/System::{}' - '/action/snapshotVolumes'.format(self.fake_system_id): + f'/instances/System::{self.fake_system_id}' + '/action/snapshotVolumes': {}, '/instances/System' '/action' @@ -80,32 +89,50 @@ def setUp(self): } def test_system_api_version(self): + """ + Test the API version. + """ self.client.system.api_version() self.assertEqual(4, self.get_mock.call_count) def test_system_api_version_bad_status(self): + """ + Test the API version with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailQuerying, self.client.system.api_version, cached=False) def test_system_api_version_invalid_format(self): + """ + Test the API version with an invalid format. + """ with self.http_response_mode(self.RESPONSE_MODE.Invalid): self.assertRaises(exceptions.PowerFlexClientException, self.client.system.api_version, cached=False) def test_system_api_version_cached(self): + """ + Test the API version with caching. + """ self.client.system.api_version() self.client.system.api_version() self.client.system.api_version() self.assertEqual(4, self.get_mock.call_count) def test_system_remove_cg_snapshots(self): + """ + Test removing consistency group snapshots. + """ self.client.system.remove_cg_snapshots(self.fake_system_id, self.fake_cg_id) def test_system_remove_cg_snapshots_bad_status(self): + """ + Test removing consistency group snapshots with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.system.remove_cg_snapshots, @@ -113,10 +140,16 @@ def test_system_remove_cg_snapshots_bad_status(self): self.fake_cg_id) def test_system_snapshot_volumes(self): + """ + Test snapshotting volumes. + """ self.client.system.snapshot_volumes(self.fake_system_id, self.fake_snapshot_defs) def test_system_snapshot_volumes_bad_status(self): + """ + Test snapshotting volumes with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.system.snapshot_volumes, @@ -124,46 +157,76 @@ def test_system_snapshot_volumes_bad_status(self): self.fake_snapshot_defs) def test_add_standby_mdm(self): + """ + Test the add_standby_mdm method. + """ self.client.system.add_standby_mdm(mdm_ips=["10.x.x.x"], role="Manager") def test_add_standby_mdm_bad_status(self): + """ + Test the add_standby_mdm method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.system.add_standby_mdm, mdm_ips=["10.x.x.x"], role="Manager") def test_remove_standby_mdm(self): + """ + Test the remove_standby_mdm method. + """ self.client.system.remove_standby_mdm(self.fake_mdm_id) def test_remove_standby_mdm_bad_status(self): + """ + Test the remove_standby_mdm method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.system.remove_standby_mdm, self.fake_mdm_id) def test_get_mdm_cluster(self): + """ + Test the get_mdm_cluster_details method. + """ self.client.system.get_mdm_cluster_details() def test_get_mdm_cluster_bad_status(self): + """ + Test the get_mdm_cluster_details method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.system.get_mdm_cluster_details) def test_change_mdm_ownership(self): + """ + Test the change_mdm_ownership method. + """ self.client.system.change_mdm_ownership(self.fake_mdm_id) def test_change_mdm_ownership_bad_status(self): + """ + Test the change_mdm_ownership method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.system.change_mdm_ownership, self.fake_mdm_id) def test_change_performance_profile(self): + """ + Test the set_cluster_mdm_performance_profile method. + """ self.client.system.\ set_cluster_mdm_performance_profile(performance_profile="Compact") def test_change_performance_profile_bad_status(self): + """ + Test the set_cluster_mdm_performance_profile method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.system. @@ -171,20 +234,32 @@ def test_change_performance_profile_bad_status(self): performance_profile="Compact") def test_rename_mdm(self): + """ + Test the rename_mdm method. + """ self.client.system.rename_mdm(self.fake_mdm_id, mdm_new_name="fake") def test_rename_mdm_bad_status(self): + """ + Test the rename_mdm method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.system.rename_mdm, self.fake_mdm_id, mdm_new_name="fake") def test_modify_virtual_ip_interface(self): + """ + Test the modify_virtual_ip_interface method. + """ self.client.system.\ modify_virtual_ip_interface(self.fake_mdm_id, virtual_ip_interfaces=["interface"]) def test_modify_virtual_ip_interface_bad_status(self): + """ + Test the modify_virtual_ip_interface method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.system.modify_virtual_ip_interface, @@ -192,32 +267,53 @@ def test_modify_virtual_ip_interface_bad_status(self): virtual_ip_interfaces=["interface"]) def test_clear_virtual_ip_interface(self): + """ + Test the modify_virtual_ip_interface method with no arguments. + """ self.client.system.modify_virtual_ip_interface(self.fake_mdm_id) def test_clear_virtual_ip_interface_bad_status(self): + """ + Test the modify_virtual_ip_interface method with no arguments and a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.system.modify_virtual_ip_interface, self.fake_mdm_id) def test_switch_cluster_mode(self): + """ + Test the switch_cluster_mode method. + """ self.client.system.switch_cluster_mode(self.fake_mdm_id) def test_switch_cluster_mode_bad_status(self): + """ + Test the switch_cluster_mode method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.system.switch_cluster_mode, self.fake_mdm_id) def test_get_gateway_configuration_details(self): + """ + Test the get_gateway_configuration_details method. + """ self.client.system.get_gateway_configuration_details() def test_get_gateway_configuration_details_bad_status(self): + """ + Test the get_gateway_configuration_details method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.system.get_gateway_configuration_details) def test_system_query_selected_statistics(self): + """ + Test the query_selected_statistics method. + """ ret = self.client.system.query_selected_statistics( properties=["rplTransmitBwc"] ) @@ -228,6 +324,9 @@ def test_system_query_selected_statistics(self): } def test_system_query_selected_statistics_bad_status(self): + """ + Test the query_selected_statistics method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexFailQuerying, diff --git a/tests/test_utility.py b/tests/test_utility.py index 951756d..a434a3f 100644 --- a/tests/test_utility.py +++ b/tests/test_utility.py @@ -13,14 +13,24 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing PowerFlex utility.""" + +# pylint: disable=invalid-name + from PyPowerFlex import exceptions -from PyPowerFlex.objects import utility import tests class TestPowerFlexUtility(tests.PyPowerFlexTestCase): + """ + Test class for the PowerFlex utility. + """ + def setUp(self): - super(TestPowerFlexUtility, self).setUp() + """ + Set up the test case. + """ + super().setUp() self.client.initialize() self.MOCK_RESPONSES = { @@ -33,17 +43,29 @@ def setUp(self): } def test_get_statistics_for_all_storagepools(self): + """ + Test the get_statistics_for_all_storagepools method. + """ self.client.utility.get_statistics_for_all_storagepools() def test_get_statistics_for_all_storagepools_bad_status(self): + """ + Test the get_statistics_for_all_storagepools method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.utility.get_statistics_for_all_storagepools) def test_get_statistics_for_all_volumes(self): + """ + Test the get_statistics_for_all_volumes method. + """ self.client.utility.get_statistics_for_all_volumes() def test_get_statistics_for_all_volumes_bad_status(self): + """ + Test the get_statistics_for_all_volumes method with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.utility.get_statistics_for_all_volumes) diff --git a/tests/test_volume.py b/tests/test_volume.py index 882ad74..0944a3d 100644 --- a/tests/test_volume.py +++ b/tests/test_volume.py @@ -13,14 +13,25 @@ # License for the specific language governing permissions and limitations # under the License. +"""Module for testing volume client.""" + +# pylint: disable=invalid-name,too-many-public-methods + from PyPowerFlex import exceptions from PyPowerFlex.objects import volume import tests class TestVolumeClient(tests.PyPowerFlexTestCase): + """ + Test class for the volume client. + """ + def setUp(self): - super(TestVolumeClient, self).setUp() + """ + Set up the test case. + """ + super().setUp() self.client.initialize() self.fake_sp_id = '1' self.fake_volume_id = '1' @@ -29,35 +40,33 @@ def setUp(self): self.RESPONSE_MODE.Valid: { '/types/Volume/instances': {'id': self.fake_volume_id}, - '/instances/Volume::{}'.format(self.fake_volume_id): + f'/instances/Volume::{self.fake_volume_id}': {'id': self.fake_volume_id}, - '/instances/Volume::{}' - '/action/addMappedSdc'.format(self.fake_volume_id): + f'/instances/Volume::{self.fake_volume_id}/action/addMappedSdc': {'id': self.fake_volume_id}, - '/instances/Volume::{}' - '/action/removeVolume'.format(self.fake_volume_id): + f'/instances/Volume::{self.fake_volume_id}/action/removeVolume': {}, - '/instances/Volume::{}' - '/action/setVolumeSize'.format(self.fake_volume_id): + f'/instances/Volume::{self.fake_volume_id}/action/setVolumeSize': {}, - '/instances/Volume::{}' - '/relationships/Statistics'.format(self.fake_sp_id): + f'/instances/Volume::{self.fake_volume_id}/relationships/Statistics': {}, - '/instances/Volume::{}' - '/action/lockAutoSnapshot'.format(self.fake_volume_id): + f'/instances/Volume::{self.fake_volume_id}/action/lockAutoSnapshot': {}, - '/instances/Volume::{}' - '/action/removeMappedSdc'.format(self.fake_volume_id): + f'/instances/Volume::{self.fake_volume_id}/action/removeMappedSdc': {}, - '/instances/Volume::{}' - '/action/setVolumeName'.format(self.fake_volume_id): + f'/instances/Volume::{self.fake_volume_id}/action/setVolumeName': {}, - '/instances/Volume::{}' - '/action/unlockAutoSnapshot'.format(self.fake_volume_id): + f'/instances/Volume::{self.fake_volume_id}/action/unlockAutoSnapshot': {}, '/types/Volume' '/instances/action/querySelectedStatistics': { - self.fake_volume_id: {'userDataSdcReadLatency': {'numSeconds': 0, 'totalWeightInKb': 0, 'numOccured': 0}} + self.fake_volume_id: { + 'userDataSdcReadLatency': { + 'numSeconds': 0, + 'totalWeightInKb': 0, + 'numOccured': 0 + } + } }, }, self.RESPONSE_MODE.Invalid: { @@ -67,6 +76,10 @@ def setUp(self): } def test_volume_add_mapped_sdc_id_and_guid_are_set(self): + """ + Test if volume add mapped sdc raises an exception + when both sdc_id and sdc_guid are set. + """ with self.assertRaises(exceptions.InvalidInput) as error: self.client.volume.add_mapped_sdc(self.fake_volume_id, sdc_id='1', @@ -75,10 +88,16 @@ def test_volume_add_mapped_sdc_id_and_guid_are_set(self): error.exception.message) def test_volume_add_mapped_sdc(self): + """ + Test if volume add mapped sdc is successful. + """ self.client.volume.add_mapped_sdc(self.fake_volume_id, sdc_id='1') def test_volume_add_mapped_sdc_bad_status(self): + """ + Test if volume add mapped sdc raises an exception when the HTTP status is bad. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.volume.add_mapped_sdc, @@ -86,11 +105,17 @@ def test_volume_add_mapped_sdc_bad_status(self): sdc_id='1') def test_volume_create(self): + """ + Test if volume create is successful. + """ self.client.volume.create(size_in_gb=8, storage_pool_id=self.fake_sp_id, volume_type=volume.VolumeType.thin) def test_volume_create_bad_status(self): + """ + Test if volume create raises an exception when the HTTP status is bad. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailCreating, self.client.volume.create, @@ -99,6 +124,9 @@ def test_volume_create_bad_status(self): volume_type=volume.VolumeType.thin) def test_volume_create_no_id_in_response(self): + """ + Test if volume create raises an exception when the response does not contain an id. + """ with self.http_response_mode(self.RESPONSE_MODE.Invalid): self.assertRaises(KeyError, self.client.volume.create, @@ -107,19 +135,31 @@ def test_volume_create_no_id_in_response(self): volume_type=volume.VolumeType.thin) def test_volume_get_statistics(self): + """ + Test if volume get statistics is successful. + """ self.client.volume.get_statistics(self.fake_volume_id) def test_volume_get_statistics_bad_status(self): + """ + Test if volume get statistics raises an exception when the HTTP status is bad. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.volume.get_statistics, self.fake_volume_id) def test_volume_delete(self): + """ + Test if volume delete is successful. + """ self.client.volume.delete(self.fake_volume_id, remove_mode=volume.RemoveMode.only_me) def test_volume_delete_bad_status(self): + """ + Test if volume delete raises an exception when the HTTP status is bad. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailDeleting, self.client.volume.delete, @@ -127,10 +167,16 @@ def test_volume_delete_bad_status(self): remove_mode=volume.RemoveMode.only_me) def test_volume_extend(self): + """ + Test if volume extend is successful. + """ self.client.volume.extend(self.fake_volume_id, size_in_gb=16) def test_volume_extend_bad_status(self): + """ + Test if volume extend raises an exception when the HTTP status is bad. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.volume.extend, @@ -138,15 +184,25 @@ def test_volume_extend_bad_status(self): size_in_gb=16) def test_volume_lock_auto_snapshot(self): + """ + Test the lock_auto_snapshot method of the VolumeClient. + """ self.client.volume.lock_auto_snapshot(self.fake_volume_id) def test_volume_lock_auto_snapshot_bad_status(self): + """ + Test the lock_auto_snapshot method of the VolumeClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.volume.lock_auto_snapshot, self.fake_volume_id) def test_volume_remove_mapped_sdc_id_guid_and_all_sdcs_are_set(self): + """ + Test the remove_mapped_sdc method of the VolumeClient + when sdc_id, sdc_guid, and all_sdcs are all set. + """ with self.assertRaises(exceptions.InvalidInput) as error: self.client.volume.remove_mapped_sdc(self.fake_volume_id, sdc_id='1', @@ -156,10 +212,16 @@ def test_volume_remove_mapped_sdc_id_guid_and_all_sdcs_are_set(self): error.exception.message) def test_volume_remove_mapped_sdc(self): + """ + Test the remove_mapped_sdc method of the VolumeClient. + """ self.client.volume.remove_mapped_sdc(self.fake_volume_id, sdc_id='1') def test_volume_remove_mapped_sdc_bad_status(self): + """ + Test the remove_mapped_sdc method of the VolumeClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.volume.remove_mapped_sdc, @@ -167,10 +229,16 @@ def test_volume_remove_mapped_sdc_bad_status(self): sdc_id='1') def test_volume_rename(self): + """ + Test the rename method of the VolumeClient. + """ self.client.volume.rename(self.fake_volume_id, name='new_name') def test_volume_rename_bad_status(self): + """ + Test the rename method of the VolumeClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexFailRenaming, self.client.volume.rename, @@ -178,15 +246,24 @@ def test_volume_rename_bad_status(self): name='new_name') def test_volume_unlock_auto_snapshot(self): + """ + Test the unlock_auto_snapshot method of the VolumeClient. + """ self.client.volume.unlock_auto_snapshot(self.fake_volume_id) def test_volume_unlock_auto_snapshot_bad_status(self): + """ + Test the unlock_auto_snapshot method of the VolumeClient with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises(exceptions.PowerFlexClientException, self.client.volume.unlock_auto_snapshot, self.fake_volume_id) def test_volume_query_selected_statistics(self): + """ + Test case for querying selected statistics of a volume. + """ ret = self.client.volume.query_selected_statistics( properties=["userDataSdcReadLatency"] ) @@ -197,6 +274,9 @@ def test_volume_query_selected_statistics(self): } def test_volume_query_selected_statistics_bad_status(self): + """ + Test case for querying selected statistics of a volume with a bad status. + """ with self.http_response_mode(self.RESPONSE_MODE.BadStatus): self.assertRaises( exceptions.PowerFlexFailQuerying,