diff --git a/src/ansys/sherlock/core/errors.py b/src/ansys/sherlock/core/errors.py index e12dd759a..d53a6a626 100644 --- a/src/ansys/sherlock/core/errors.py +++ b/src/ansys/sherlock/core/errors.py @@ -1246,3 +1246,15 @@ def __init__(self, message): def __str__(self): """Format error message.""" return f"Get parts list validation analysis properties error: {self.message}" + + +class SherlockDeleteModelingRegionError(Exception): + """Contains the error raised when the modeling regions cannot be deleted.""" + + def __init__(self, message): + """Initialize error message.""" + self.message = message + + def __str__(self): + """Format error message.""" + return f"Delete modeling region error: {self.message}" diff --git a/src/ansys/sherlock/core/layer.py b/src/ansys/sherlock/core/layer.py index 0ac4ceb4b..f6195a904 100644 --- a/src/ansys/sherlock/core/layer.py +++ b/src/ansys/sherlock/core/layer.py @@ -28,6 +28,7 @@ SherlockDeleteAllICTFixturesError, SherlockDeleteAllMountPointsError, SherlockDeleteAllTestPointsError, + SherlockDeleteModelingRegionError, SherlockExportAllMountPoints, SherlockExportAllTestFixtures, SherlockExportAllTestPoints, @@ -1490,6 +1491,10 @@ def copy_modeling_region( if not copy_regions: raise SherlockCopyModelingRegionError(message="Copy regions list is empty.") + if not self._is_connection_up(): + LOG.error("There is no connection to a gRPC service.") + return + copy_regions_request = [] for region in copy_regions: if "cca_name" not in region or region["cca_name"] == "": @@ -1529,3 +1534,80 @@ def copy_modeling_region( except SherlockCopyModelingRegionError as e: LOG.error(str(e)) raise e + + def delete_modeling_region(self, project: str, delete_regions: List[Dict[str, str]]): + """Delete one or more modeling regions for a specific project. + + Parameters + ---------- + project : str + Name of the Sherlock project. + delete_regions : list of dict + List of modeling regions to delete. Each dictionary should contain: + - "cca_name" : str, Name of the CCA. + - "region_id" : str, Unique region ID of the modeling region to delete. + + Returns + ------- + int + Status code of the response. 0 for success. + + Examples + -------- + >>> from ansys.sherlock.core.launcher import launch_sherlock + >>> sherlock = launch_sherlock() + >>> sherlock.project.import_odb_archive( + "ODB++ Tutorial.tgz", + True, + True, + True, + True, + project="Test", + cca_name="Card", + ) + >>> delete_regions = [{"cca_name": "Card", "region_id": "12345"}] + >>> sherlock.layer.delete_modeling_region("Test", delete_regions) + """ + try: + if project == "": + raise SherlockDeleteModelingRegionError(message="Project name is invalid.") + if not isinstance(delete_regions, list): + raise SherlockDeleteModelingRegionError(message="Delete regions should be a list.") + if not delete_regions: + raise SherlockDeleteModelingRegionError(message="Delete regions list is empty.") + + for region in delete_regions: + if not isinstance(region, dict): + raise SherlockDeleteModelingRegionError( + message="Each region should be a dictionary." + ) + if "cca_name" not in region or region["cca_name"] == "": + raise SherlockDeleteModelingRegionError(message="CCA name is invalid.") + if "region_id" not in region or region["region_id"] == "": + raise SherlockDeleteModelingRegionError(message="Region ID is invalid.") + + if not self._is_connection_up(): + LOG.error("There is no connection to a gRPC service.") + return + + delete_regions_info = [ + SherlockLayerService_pb2.DeleteModelingRegionRequest.DeleteModelingRegionInfo( + ccaName=region["cca_name"], regionId=region["region_id"] + ) + for region in delete_regions + ] + + request = SherlockLayerService_pb2.DeleteModelingRegionRequest( + project=project, deleteRegions=delete_regions_info + ) + + response = self.stub.deleteModelingRegion(request) + + if response.value == -1: + raise SherlockDeleteModelingRegionError(message=response.message) + + except SherlockDeleteModelingRegionError as e: + LOG.error(str(e)) + raise e + + return response.value diff --git a/tests/test_layer.py b/tests/test_layer.py index 15679e471..f4b10625f 100644 --- a/tests/test_layer.py +++ b/tests/test_layer.py @@ -14,6 +14,7 @@ SherlockDeleteAllICTFixturesError, SherlockDeleteAllMountPointsError, SherlockDeleteAllTestPointsError, + SherlockDeleteModelingRegionError, SherlockExportAllMountPoints, SherlockExportAllTestFixtures, SherlockExportAllTestPoints, @@ -51,6 +52,7 @@ def test_all(): region_id = helper_test_add_modeling_region(layer) region_id = helper_test_update_modeling_region(layer, region_id) helper_test_copy_modeling_region(layer, region_id) + helper_test_delete_modeling_region(layer, region_id) def helper_test_add_potting_region(layer): @@ -1163,5 +1165,71 @@ def helper_test_copy_modeling_region(layer, region_id): pytest.fail(e.str_itr()) +def helper_test_delete_modeling_region(layer, region_id): + + # Invalid project name + try: + layer.delete_modeling_region("", [{"cca_name": "Main Board", "region_id": "12345"}]) + pytest.fail("No exception thrown when using an invalid parameter") + except SherlockDeleteModelingRegionError as e: + assert str(e) == "Delete modeling region error: Project name is invalid." + + # Non-list delete regions + try: + layer.delete_modeling_region("Tutorial Project", "not_a_list") + pytest.fail("No exception thrown when using a non-list delete regions") + except SherlockDeleteModelingRegionError as e: + assert str(e) == "Delete modeling region error: Delete regions should be a list." + + # Invalid modeling regions list + try: + layer.delete_modeling_region("Tutorial Project", []) + pytest.fail("No exception thrown when using an invalid parameter") + except SherlockDeleteModelingRegionError as e: + assert str(e) == "Delete modeling region error: Delete regions list is empty." + + # Non-dictionary delete region + try: + layer.delete_modeling_region("Tutorial Project", ["not_a_dict"]) + pytest.fail("No exception thrown when using a non-dictionary delete region") + except SherlockDeleteModelingRegionError as e: + assert str(e) == "Delete modeling region error: Each region should be a dictionary." + + # Invalid CCA name + try: + layer.delete_modeling_region("Tutorial Project", [{"cca_name": "", "region_id": "12345"}]) + pytest.fail("No exception thrown when using an invalid parameter") + except SherlockDeleteModelingRegionError as e: + assert str(e) == "Delete modeling region error: CCA name is invalid." + + # Invalid region ID + try: + layer.delete_modeling_region( + "Tutorial Project", [{"cca_name": "Main Board", "region_id": ""}] + ) + pytest.fail("No exception thrown when using an invalid parameter") + except SherlockDeleteModelingRegionError as e: + assert str(e) == "Delete modeling region error: Region ID is invalid." + + if layer._is_connection_up(): + # Unhappy project name + try: + layer.delete_modeling_region( + "Tutorial Project", [{"cca_name": "Main Board", "region_id": "InvalidID"}] + ) + pytest.fail("No exception thrown when using an invalid parameter") + except Exception as e: + assert type(e) == SherlockDeleteModelingRegionError + + # Valid request + try: + result = layer.delete_modeling_region( + "Tutorial Project", [{"cca_name": "Main Board", "region_id": region_id}] + ) + assert result == 0 + except Exception as e: + pytest.fail(e.message) + + if __name__ == "__main__": test_all()