From 4dd64478c3df799fac6550bc6aee1988feb7e4ae Mon Sep 17 00:00:00 2001 From: Jeff Moody <110494049+ansjmoody@users.noreply.github.com> Date: Wed, 19 Jun 2024 17:27:48 -0500 Subject: [PATCH 1/7] Add API for update Parts List Validation properties --- doc/source/user_guide/index.rst | 2 +- src/ansys/sherlock/core/analysis.py | 147 +++++++++++++++++++ src/ansys/sherlock/core/errors.py | 12 ++ src/ansys/sherlock/core/parts.py | 24 +-- src/ansys/sherlock/core/types/parts_types.py | 23 ++- tests/test_parts.py | 19 ++- 6 files changed, 199 insertions(+), 28 deletions(-) diff --git a/doc/source/user_guide/index.rst b/doc/source/user_guide/index.rst index 7e718335e..f212364ff 100644 --- a/doc/source/user_guide/index.rst +++ b/doc/source/user_guide/index.rst @@ -82,7 +82,7 @@ This code uses the Sherlock Part Library to update the parts list: "Tutorial", "Main Board", "Sherlock Part Library", - PartsListSearchMatchingMode.BOTH, + "Both", PartsListSearchDuplicationMode.ERROR, ) diff --git a/src/ansys/sherlock/core/analysis.py b/src/ansys/sherlock/core/analysis.py index cd1106349..b3d8810cf 100644 --- a/src/ansys/sherlock/core/analysis.py +++ b/src/ansys/sherlock/core/analysis.py @@ -1829,3 +1829,150 @@ def update_part_modeling_props(self, project, part_modeling_props): except SherlockUpdatePartModelingPropsError as e: LOG.error(str(e)) raise e + + def update_part_list_validation_analysis_props( + self, + project, + analysis_properties, + ): + """Update properties for an ICT analysis. + + Parameters + ---------- + project : str + Name of the Sherlock project. + ict_analysis_properties : list + List of ICT analysis properties for a CCA consisting of these properties: + + - cca_name : str + Name of the CCA. + - ict_application_time : double + Specifies the amount of time to complete one ICT event. + - ict_application_time_units : str + Application time units. + Options are ``"ms"``, ``"sec"``, ``"min"``, ``"hr"``, ``"day"``, ``"year"``. + - ict_number_of_events: int + Specifies the number of events to apply to the application time when computing + the time to failure for a component. + - part_validation_enabled: bool + Whether to enable part validation. The default is ``None``. + - require_material_assignment_enabled: bool + Whether to require material assignment. The default is ``None``. + - ict_result_count: int + The number of ICT result layers to generate. This parameter is for use with + thermal analysis. + + 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", + ) + >>> sherlock.analysis.update_ict_analysis_props( + "Test", + [{ + 'cca_name': 'Card', + 'ict_application_time': 2, + 'ict_application_time_units': 'sec', + 'ict_number_of_events': 10, + 'part_validation_enabled': False, + 'require_material_assignment_enabled': False, + }, + ] + ) + + """ + try: + if project == "": + raise SherlockUpdateICTAnalysisPropsError(message="Project name is invalid.") + + if not isinstance(ict_analysis_properties, list): + raise SherlockUpdateICTAnalysisPropsError( + message="ICT analysis properties argument is invalid." + ) + + if len(ict_analysis_properties) == 0: + raise SherlockUpdateICTAnalysisPropsError( + message="One or more ICT analysis properties are required." + ) + + request = SherlockAnalysisService_pb2.UpdateICTAnalysisPropsRequest(project=project) + + for i, ict_analysis_props in enumerate(ict_analysis_properties): + if not isinstance(ict_analysis_props, dict): + raise SherlockUpdateICTAnalysisPropsError( + f"ICT analysis props argument is invalid for ICT analysis properties {i}." + ) + + if "cca_name" not in ict_analysis_props.keys(): + raise SherlockUpdateICTAnalysisPropsError( + message=f"CCA name is missing for ICT analysis properties {i}." + ) + + cca_name = ict_analysis_props["cca_name"] + if cca_name == "": + raise SherlockUpdateICTAnalysisPropsError( + message=f"CCA name is invalid for ICT analysis properties {i}." + ) + + props_request = request.ictAnalysisProperties.add() + props_request.ccaName = cca_name + + if "ict_analysis_count" in ict_analysis_props.keys(): + props_request.ictAnalysisCount = ict_analysis_props["ict_analysis_count"] + + if "ict_application_time" in ict_analysis_props.keys(): + props_request.applicationTime = ict_analysis_props["ict_application_time"] + + if "ict_application_time_units" in ict_analysis_props.keys(): + props_request.applicationTimeUnits = ict_analysis_props[ + "ict_application_time_units" + ] + + if "ict_number_of_events" in ict_analysis_props.keys(): + props_request.numberOfEvents = ict_analysis_props["ict_number_of_events"] + + if "part_validation_enabled" in ict_analysis_props.keys(): + props_request.partValidationEnabled = ict_analysis_props[ + "part_validation_enabled" + ] + + if "require_material_assignment_enabled" in ict_analysis_props.keys(): + props_request.requireMaterialAssignmentEnabled = ict_analysis_props[ + "require_material_assignment_enabled" + ] + + if "force_model_rebuild" in ict_analysis_props.keys(): + props_request.forceModelRebuild = ict_analysis_props["force_model_rebuild"] + + except SherlockUpdateICTAnalysisPropsError as e: + LOG.error(str(e)) + raise e + + if not self._is_connection_up(): + LOG.error("There is no connection to a gRPC service.") + return + + response = self.stub.updateICTAnalysisProps(request) + + try: + if response.value == -1: + raise SherlockUpdateICTAnalysisPropsError(response.message) + else: + LOG.info(response.message) + return response.value + except SherlockUpdateICTAnalysisPropsError as e: + LOG.error(str(e)) + raise e diff --git a/src/ansys/sherlock/core/errors.py b/src/ansys/sherlock/core/errors.py index a0ae5be06..34fb1ec13 100644 --- a/src/ansys/sherlock/core/errors.py +++ b/src/ansys/sherlock/core/errors.py @@ -846,6 +846,18 @@ def __str__(self): return f"Update mechanical shock properties error: {self.message}" +class SherlockUpdatePartListValidationAnalysisPropsError(Exception): + """Contains the error raised when part list validation analysis properties cannot be updated.""" + + def __init__(self, message): + """Initialize error message.""" + self.message = message + + def __str__(self): + """Format error message.""" + return f"Update part list validation analysis properties error: {self.message}" + + class SherlockUpdateSolderFatiguePropsError(Exception): """Contains the error raised when properties for solder fatigue analysis cannot be updated.""" diff --git a/src/ansys/sherlock/core/parts.py b/src/ansys/sherlock/core/parts.py index 94d2dfc54..0971334f3 100644 --- a/src/ansys/sherlock/core/parts.py +++ b/src/ansys/sherlock/core/parts.py @@ -3,9 +3,11 @@ """Module containing all parts management capabilities.""" try: + import SherlockCommonService_pb2 import SherlockPartsService_pb2 import SherlockPartsService_pb2_grpc except ModuleNotFoundError: + from ansys.api.sherlock.v0 import SherlockCommonService_pb2 from ansys.api.sherlock.v0 import SherlockPartsService_pb2 from ansys.api.sherlock.v0 import SherlockPartsService_pb2_grpc @@ -29,7 +31,6 @@ AVLPartNum, PartLocation, PartsListSearchDuplicationMode, - PartsListSearchMatchingMode, ) @@ -55,16 +56,16 @@ def __init__(self, channel): def _add_matching_duplication(request, matching, duplication): """Add matching and duplication properties to the request.""" if matching == "Both": - request.matching = SherlockPartsService_pb2.UpdatePartsListRequest.Both + request.matching = SherlockCommonService_pb2.MatchingMode.Both elif matching == "Part": - request.matching = SherlockPartsService_pb2.UpdatePartsListRequest.Part + request.matching = SherlockCommonService_pb2.MatchingMode.Part if duplication == "First": - request.duplication = SherlockPartsService_pb2.UpdatePartsListRequest.First + request.duplication = SherlockPartsService_pb2.DuplicationMode.First elif duplication == "Error": - request.duplication = SherlockPartsService_pb2.UpdatePartsListRequest.Error + request.duplication = SherlockPartsService_pb2.DuplicationMode.Error elif duplication == "Ignore": - request.duplication = SherlockPartsService_pb2.UpdatePartsListRequest.Ignore + request.duplication = SherlockPartsService_pb2.DuplicationMode.Ignore @staticmethod def _add_part_loc_request(request, parts): @@ -184,7 +185,7 @@ def update_parts_list( Name of the CCA. part_library : str Name of the parts library. - matching_mode : PartsListSearchMatchingMode + matching_mode : str Matching mode for updates. duplication_mode : PartsListSearchDuplicationMode How to handle duplication during the update. @@ -211,7 +212,7 @@ def update_parts_list( "Test", "Card", "Sherlock Part Library", - PartsListSearchMatchingMode.BOTH, + "Both", PartsListSearchDuplicationMode.ERROR, ) """ @@ -711,7 +712,7 @@ def update_parts_from_AVL( self, project: str, cca_name: str, - matching_mode: PartsListSearchMatchingMode, + matching_mode: str, duplication_mode: PartsListSearchDuplicationMode, avl_part_num: AVLPartNum, avl_description: AVLDescription, @@ -724,7 +725,7 @@ def update_parts_from_AVL( Name of the Sherlock project. cca_name : str Name of the CCA. - matching_mode: PartsListSearchMatchingMode + matching_mode: str Determines how parts are matched against the AVL duplication_mode: PartsListSearchDuplicationMode Determines how duplicate part matches are handled when found @@ -753,7 +754,6 @@ def update_parts_from_AVL( AVLDescription, AVLPartNum, PartsListSearchDuplicationMode, - PartsListSearchMatchingMode ) >>> sherlock = launch_sherlock() >>> sherlock.project.import_odb_archive( @@ -768,7 +768,7 @@ def update_parts_from_AVL( >>> sherlock.parts.update_parts_from_AVL( project="Test", cca_name="Card", - matching_mode=PartsListSearchMatchingMode.BOTH, + matching_mode="Both", duplication=PartsListSearchDuplicationMode.FIRST, avl_part_num=AVLPartNum.ASSIGN_INTERNAL_PART_NUM, avl_description=AVLDescription.ASSIGN_APPROVED_DESCRIPTION diff --git a/src/ansys/sherlock/core/types/parts_types.py b/src/ansys/sherlock/core/types/parts_types.py index a8e6356d3..46b8f5e24 100644 --- a/src/ansys/sherlock/core/types/parts_types.py +++ b/src/ansys/sherlock/core/types/parts_types.py @@ -2,23 +2,36 @@ """Module containing types for the Parts Service.""" +import warnings + try: + import SherlockCommonService_pb2 import SherlockPartsService_pb2 except ModuleNotFoundError: - from ansys.api.sherlock.v0 import SherlockPartsService_pb2 + from ansys.api.sherlock.v0 import SherlockCommonService_pb2, SherlockPartsService_pb2 + + +def deprecation(cls): + """Raise a DeprecationWarning when a deprecated class is used.""" + # if str(cls).find("PartsListSearchMatchingMode") != -1: + message = f"{cls} is deprecated. Use a string with the value of the constant name \ + as defined in the proto file." + warnings.warn(message, DeprecationWarning, stacklevel=2) + return cls +@deprecation class PartsListSearchMatchingMode: - """Constants for Matching Mode in the Update Parts List and Update Parts from AVL request.""" + """DEPRECATED. Constants for Matching Mode in Update Parts List & Update Parts from AVL.""" - BOTH = SherlockPartsService_pb2.MatchingMode.Both + BOTH = SherlockCommonService_pb2.MatchingMode.Both """Both""" - PART = SherlockPartsService_pb2.MatchingMode.Part + PART = SherlockCommonService_pb2.MatchingMode.Part """Part""" class PartsListSearchDuplicationMode: - """Constants for Duplication Mode in the Update Parts List and Update Parts from AVL request.""" + """Constants for Duplication Mode in Update Parts List and Update Parts from AVL request.""" FIRST = SherlockPartsService_pb2.DuplicationMode.First """First""" diff --git a/tests/test_parts.py b/tests/test_parts.py index 8abb1b283..afc900b55 100644 --- a/tests/test_parts.py +++ b/tests/test_parts.py @@ -25,7 +25,6 @@ AVLDescription, AVLPartNum, PartsListSearchDuplicationMode, - PartsListSearchMatchingMode, ) @@ -58,8 +57,8 @@ def helper_test_update_parts_list(parts): "Tutorial Project", "Main Board", "Sherlock Part Library", - PartsListSearchMatchingMode.BOTH, - PartsListSearchDuplicationMode.ERROR, + "Both", + "Error", ) assert result == 0 # wait for Sherlock to finish updating so subsequent tests don't fail @@ -72,7 +71,7 @@ def helper_test_update_parts_list(parts): "Tutorial Project", "Invalid CCA", "Sherlock Part Library", - PartsListSearchMatchingMode.BOTH, + "Both", PartsListSearchDuplicationMode.ERROR, ) pytest.fail("No exception raised when using an invalid parameter") @@ -84,7 +83,7 @@ def helper_test_update_parts_list(parts): "", "Card", "Sherlock Part Library", - PartsListSearchMatchingMode.BOTH, + "Both", PartsListSearchDuplicationMode.ERROR, ) pytest.fail("No exception raised when using an invalid parameter") @@ -96,7 +95,7 @@ def helper_test_update_parts_list(parts): "Test", "", "Sherlock Part Library", - PartsListSearchMatchingMode.BOTH, + "Both", PartsListSearchDuplicationMode.ERROR, ) pytest.fail("No exception raised when using an invalid parameter") @@ -108,7 +107,7 @@ def helper_test_update_parts_list(parts): "Test", "Card", "", - PartsListSearchMatchingMode.BOTH, + "Both", PartsListSearchDuplicationMode.ERROR, ) pytest.fail("No exception raised when using an invalid parameter") @@ -121,7 +120,7 @@ def helper_test_update_parts_from_AVL(parts): response = parts.update_parts_from_AVL( project="", cca_name="Main Board", - matching_mode=PartsListSearchMatchingMode.BOTH, + matching_mode="Both", duplication_mode=PartsListSearchDuplicationMode.FIRST, avl_part_num=AVLPartNum.ASSIGN_INTERNAL_PART_NUM, avl_description=AVLDescription.ASSIGN_APPROVED_DESCRIPTION, @@ -134,7 +133,7 @@ def helper_test_update_parts_from_AVL(parts): response = parts.update_parts_from_AVL( project="Tutorial Project", cca_name="", - matching_mode=PartsListSearchMatchingMode.BOTH, + matching_mode="Both", duplication_mode=PartsListSearchDuplicationMode.FIRST, avl_part_num=AVLPartNum.ASSIGN_INTERNAL_PART_NUM, avl_description=AVLDescription.ASSIGN_APPROVED_DESCRIPTION, @@ -148,7 +147,7 @@ def helper_test_update_parts_from_AVL(parts): response = parts.update_parts_from_AVL( project="Tutorial Project", cca_name="Main Board", - matching_mode=PartsListSearchMatchingMode.BOTH, + matching_mode="Both", duplication_mode=PartsListSearchDuplicationMode.FIRST, avl_part_num=AVLPartNum.ASSIGN_INTERNAL_PART_NUM, avl_description=AVLDescription.ASSIGN_APPROVED_DESCRIPTION, From 4bf3a28dbffaef95826879bef9ea420635425bb7 Mon Sep 17 00:00:00 2001 From: Jeff Moody <110494049+ansjmoody@users.noreply.github.com> Date: Wed, 10 Jul 2024 11:23:12 -0500 Subject: [PATCH 2/7] code cleanup --- src/ansys/sherlock/core/parts.py | 33 +++++--------------------------- tests/test_parts.py | 6 +++--- 2 files changed, 8 insertions(+), 31 deletions(-) diff --git a/src/ansys/sherlock/core/parts.py b/src/ansys/sherlock/core/parts.py index 0971334f3..35189fe12 100644 --- a/src/ansys/sherlock/core/parts.py +++ b/src/ansys/sherlock/core/parts.py @@ -3,11 +3,9 @@ """Module containing all parts management capabilities.""" try: - import SherlockCommonService_pb2 import SherlockPartsService_pb2 import SherlockPartsService_pb2_grpc except ModuleNotFoundError: - from ansys.api.sherlock.v0 import SherlockCommonService_pb2 from ansys.api.sherlock.v0 import SherlockPartsService_pb2 from ansys.api.sherlock.v0 import SherlockPartsService_pb2_grpc @@ -43,29 +41,6 @@ def __init__(self, channel): self.stub = SherlockPartsService_pb2_grpc.SherlockPartsServiceStub(channel) self.PART_LOCATION_UNITS = None self.BOARD_SIDES = None - self.MATCHING_ARGS = ["Both", "Part"] - self.DUPLICATION_ARGS = ["First", "Error", "Ignore"] - self.AVL_PART_NUM_ARGS = [ - "AssignInternalPartNum", - "AssignVendorAndPartNum", - "DoNotChangeVendorOrPartNum", - ] - self.AVL_DESCRIPTION_ARGS = ["AssignApprovedDescription", "DoNotChangeDescription"] - - @staticmethod - def _add_matching_duplication(request, matching, duplication): - """Add matching and duplication properties to the request.""" - if matching == "Both": - request.matching = SherlockCommonService_pb2.MatchingMode.Both - elif matching == "Part": - request.matching = SherlockCommonService_pb2.MatchingMode.Part - - if duplication == "First": - request.duplication = SherlockPartsService_pb2.DuplicationMode.First - elif duplication == "Error": - request.duplication = SherlockPartsService_pb2.DuplicationMode.Error - elif duplication == "Ignore": - request.duplication = SherlockPartsService_pb2.DuplicationMode.Ignore @staticmethod def _add_part_loc_request(request, parts): @@ -233,11 +208,13 @@ def update_parts_list( return request = SherlockPartsService_pb2.UpdatePartsListRequest( - project=project, ccaName=cca_name, partLibrary=part_library + project=project, + ccaName=cca_name, + partLibrary=part_library, + matching=matching_mode, + duplication=duplication_mode, ) - self._add_matching_duplication(request, matching_mode, duplication_mode) - response = self.stub.updatePartsList(request) return_code = response.returnCode diff --git a/tests/test_parts.py b/tests/test_parts.py index afc900b55..6e174517b 100644 --- a/tests/test_parts.py +++ b/tests/test_parts.py @@ -58,7 +58,7 @@ def helper_test_update_parts_list(parts): "Main Board", "Sherlock Part Library", "Both", - "Error", + PartsListSearchDuplicationMode.ERROR, ) assert result == 0 # wait for Sherlock to finish updating so subsequent tests don't fail @@ -117,7 +117,7 @@ def helper_test_update_parts_list(parts): def helper_test_update_parts_from_AVL(parts): try: - response = parts.update_parts_from_AVL( + parts.update_parts_from_AVL( project="", cca_name="Main Board", matching_mode="Both", @@ -130,7 +130,7 @@ def helper_test_update_parts_from_AVL(parts): assert e.message == "Project name is invalid." try: - response = parts.update_parts_from_AVL( + parts.update_parts_from_AVL( project="Tutorial Project", cca_name="", matching_mode="Both", From f2d5911d9917561ff1e5fb82a41c33a5254e7d2a Mon Sep 17 00:00:00 2001 From: Jeff Moody <110494049+ansjmoody@users.noreply.github.com> Date: Thu, 11 Jul 2024 14:17:48 -0500 Subject: [PATCH 3/7] test_layer: modify tests to check for exception type before happy path test and changed how to format error when happy path tests fail --- tests/test_layer.py | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/test_layer.py b/tests/test_layer.py index f0bd87f4a..ee0504277 100644 --- a/tests/test_layer.py +++ b/tests/test_layer.py @@ -572,26 +572,26 @@ def helper_test_export_all_test_points(layer): test_points_file = os.path.join(temp_dir, "test_points.csv") try: - result = layer.export_all_test_points( + layer.export_all_test_points( "Test Point Test Project", - "Main Board", + "Invalid CCA", test_points_file, ) - - assert os.path.exists(test_points_file) - assert result == 0 + pytest.fail("No exception raised when using an invalid parameter") except Exception as e: - pytest.fail(str(e.error_array) if hasattr(e, "error_array") else str(e)) + assert type(e) == SherlockExportAllTestPoints try: - layer.export_all_test_points( + result = layer.export_all_test_points( "Test Point Test Project", - "Invalid CCA", + "Main Board", test_points_file, ) - pytest.fail("No exception raised when using an invalid parameter") - except Exception as e: - assert type(e) == SherlockExportAllTestPoints + + assert os.path.exists(test_points_file) + assert result == 0 + except SherlockExportAllTestPoints as e: + pytest.fail(str(e.str_itr())) def helper_test_export_all_test_fixtures(layer): @@ -634,26 +634,26 @@ def helper_test_export_all_test_fixtures(layer): test_fixtures_file = os.path.join(temp_dir, "test_fixtures.csv") try: - result = layer.export_all_test_fixtures( + layer.export_all_test_fixtures( "Tutorial Project", - "Main Board", + "Invalid CCA", test_fixtures_file, ) - - assert os.path.exists(test_fixtures_file) - assert result == 0 + pytest.fail("No exception raised when using an invalid parameter") except Exception as e: - pytest.fail(e.message) + assert type(e) is SherlockExportAllTestFixtures try: - layer.export_all_test_fixtures( + result = layer.export_all_test_fixtures( "Tutorial Project", - "Invalid CCA", + "Main Board", test_fixtures_file, ) - pytest.fail("No exception raised when using an invalid parameter") - except Exception as e: - assert type(e) == SherlockExportAllTestFixtures + + assert os.path.exists(test_fixtures_file) + assert result == 0 + except SherlockExportAllTestFixtures as e: + pytest.fail(str(e)) def helper_test_export_all_mount_points(layer): From a0a929d272f96c8a70c8c6e01dfdadc2457800a9 Mon Sep 17 00:00:00 2001 From: Jeff Moody <110494049+ansjmoody@users.noreply.github.com> Date: Thu, 11 Jul 2024 15:32:56 -0500 Subject: [PATCH 4/7] Added unit tests --- src/ansys/sherlock/core/analysis.py | 282 ++++++++++++++-------------- tests/test_analysis.py | 147 +++++++++++++++ 2 files changed, 285 insertions(+), 144 deletions(-) diff --git a/src/ansys/sherlock/core/analysis.py b/src/ansys/sherlock/core/analysis.py index b3d8810cf..af3b9facb 100644 --- a/src/ansys/sherlock/core/analysis.py +++ b/src/ansys/sherlock/core/analysis.py @@ -17,6 +17,7 @@ SherlockUpdateICTAnalysisPropsError, SherlockUpdateMechanicalShockPropsError, SherlockUpdateNaturalFrequencyPropsError, + SherlockUpdatePartListValidationAnalysisPropsError, SherlockUpdatePartModelingPropsError, SherlockUpdatePcbModelingPropsError, SherlockUpdateRandomVibePropsError, @@ -103,13 +104,13 @@ def run_analysis( analyses : list of ``elements`` - elements: list - List of tuples (``type``, ``event``) + Tuples (``type``, ``event``) - analysis_type : RunAnalysisRequestAnalysisType Type of analysis to run. - event : list - List of tuples (``phase_name``, ``event_name``) + Tuples (``phase_name``, ``event_name``) - phase_name : str Name of the life cycle phase. @@ -195,7 +196,7 @@ def get_harmonic_vibe_input_fields(self, model_source=None): Returns ------- list - List of harmonic vibe property fields based on the user configuration. + Harmonic vibe property fields based on the user configuration. Examples -------- @@ -238,7 +239,7 @@ def update_harmonic_vibe_props( project : str Name of the Sherlock project. harmonic_vibe_properties : list - List of harmonic vibe properties for a CCA consisting of these properties: + Harmonic vibe properties for a CCA consisting of these properties: - cca_name : str Name of the CCA. @@ -301,14 +302,14 @@ def update_harmonic_vibe_props( >>> sherlock.analysis.update_harmonic_vibe_props( "Test", [{ - 'cca_name': 'Card', - 'harmonic_vibe_count': 2, - 'harmonic_vibe_damping': '0.01, 0.05', - 'part_validation_enabled': False, - 'require_material_assignment_enabled': False, - 'analysis_temp': 20, - 'analysis_temp_units': 'C', - 'filter_by_event_frequency': False, + "cca_name": "Card", + "harmonic_vibe_count": 2, + "harmonic_vibe_damping": "0.01, 0.05", + "part_validation_enabled": False, + "require_material_assignment_enabled": False, + "analysis_temp": 20, + "analysis_temp_units": "C", + "filter_by_event_frequency": False, }, ] ) @@ -498,7 +499,7 @@ def get_ict_analysis_input_fields(self): Returns ------- list - List of ICT analysis property fields based on the user configuration. + ICT analysis property fields based on the user configuration. Examples -------- @@ -530,7 +531,7 @@ def update_ict_analysis_props( project : str Name of the Sherlock project. ict_analysis_properties : list - List of ICT analysis properties for a CCA consisting of these properties: + ICT analysis properties for a CCA consisting of these properties: - cca_name : str Name of the CCA. @@ -571,12 +572,12 @@ def update_ict_analysis_props( >>> sherlock.analysis.update_ict_analysis_props( "Test", [{ - 'cca_name': 'Card', - 'ict_application_time': 2, - 'ict_application_time_units': 'sec', - 'ict_number_of_events': 10, - 'part_validation_enabled': False, - 'require_material_assignment_enabled': False, + "cca_name": "Card", + "ict_application_time": 2, + "ict_application_time_units": "sec", + "ict_number_of_events": 10, + "part_validation_enabled": False, + "require_material_assignment_enabled": False, }, ] ) @@ -678,7 +679,7 @@ def get_mechanical_shock_input_fields(self, model_source=None): Returns ------- list - List of mechanical shock property fields based on the user configuration. + Mechanical shock property fields based on the user configuration. Examples -------- @@ -721,7 +722,7 @@ def update_mechanical_shock_props( project : str Name of the Sherlock project. mechanical_shock_properties : list - List of mechanical shock properties for a CCA consisting of these properties: + Mechanical shock properties for a CCA consisting of these properties: - cca_name : str Name of the CCA. @@ -778,20 +779,20 @@ def update_mechanical_shock_props( >>> sherlock.analysis.update_mechanical_shock_props( "Test", [{ - 'cca_name': 'Card', - 'model_source': ModelSource.GENERATED, - 'shock_result_count': 2, - 'critical_shock_strain': 10, - 'critical_shock_strain_units': 'strain', - 'part_validation_enabled': True, - 'require_material_assignment_enabled': False, - 'force_model_rebuild': 'AUTO', - 'natural_freq_min': 10, - 'natural_freq_min_units': 'Hz', - 'natural_freq_max': 100, - 'natural_freq_max_units': 'KHz', - 'analysis_temp': 20, - 'analysis_temp_units': 'F', + "cca_name": "Card", + "model_source": ModelSource.GENERATED, + "shock_result_count": 2, + "critical_shock_strain": 10, + "critical_shock_strain_units": "strain", + "part_validation_enabled": True, + "require_material_assignment_enabled": False, + "force_model_rebuild": "AUTO", + "natural_freq_min": 10, + "natural_freq_min_units": "Hz", + "natural_freq_max": 100, + "natural_freq_max_units": "KHz", + "analysis_temp": 20, + "analysis_temp_units": "F", }, ] ) @@ -919,7 +920,7 @@ def get_solder_fatigue_input_fields(self): Returns ------- list - List of solder fatigue property fields based on the user configuration. + Solder fatigue property fields based on the user configuration. Examples -------- @@ -960,7 +961,7 @@ def update_solder_fatigue_props( project : str Name of the Sherlock project. solder_fatigue_properties : list - List of mechanical shock properties for a CCA consisting of these properties: + Mechanical shock properties for a CCA consisting of these properties: - cca_name : str Name of the CCA. @@ -996,12 +997,12 @@ def update_solder_fatigue_props( >>> sherlock.analysis.update_solder_fatigue_props( "Test", [{ - 'cca_name': 'Card', - 'solder_material': 'TIN-LEAD (63SN37PB)', - 'part_temp': 70, - 'part_temp_units': 'F', - 'use_part_temp_rise_min': True, - 'part_validation_enabled': True + "cca_name": "Card", + "solder_material": "TIN-LEAD (63SN37PB)", + "part_temp": 70, + "part_temp_units": "F", + "use_part_temp_rise_min": True, + "part_validation_enabled": True }, ] ) @@ -1097,7 +1098,7 @@ def get_random_vibe_input_fields(self, model_source=None): Returns ------- list - List of random vibe property fields based on the user configuration. + Random vibe property fields based on the user configuration. Examples -------- @@ -1194,7 +1195,7 @@ def update_random_vibe_props( Model source. The default is ``None``. This parameter is required for strain map analysis. strain_map_natural_freqs : list, optional - List of natural frequencies. The default is ``None``. + Natural frequencies. The default is ``None``. This parameter is required for strain map analysis. Returns @@ -1221,7 +1222,7 @@ def update_random_vibe_props( random_vibe_damping="0.01, 0.05", analysis_temp=20, analysis_temp_units="C", - model_source=ModelSource.STRAIN_MAP, + model_source=ModelSource.STRAIN_MAP ) """ @@ -1286,7 +1287,7 @@ def get_natural_frequency_input_fields(self): Returns ------- list - List of natural frequency property fields based on the user configuration. + Matural frequency property fields based on the user configuration. Examples -------- @@ -1445,12 +1446,12 @@ def run_strain_map_analysis( cca_name : str Name of the main CCA for the analysis. strain_map_analyses : list - List of analyses consisting of these properties: + Analyses consisting of these properties: - analysis_type : RunStrainMapAnalysisRequestAnalysisType Type of analysis to run. - event_strain_maps : list - List of the strain maps assigned to the desired life cycle events for + Strain maps assigned to the desired life cycle events for a given PCB side. The list consists of these properties: - phase_name : str @@ -1594,7 +1595,7 @@ def update_pcb_modeling_props(self, project, cca_names, analyses): cca_names : list Names of the CCAs to be used for the analysis. analyses : list - List of elements consisting of the following properties: + Elements consisting of the following properties: - analysis_type : UpdatePcbModelingPropsRequestAnalysisType Type of analysis applied. @@ -1647,7 +1648,7 @@ def update_pcb_modeling_props(self, project, cca_names, analyses): "mm", True, ) - ], + ] ) """ try: @@ -1708,7 +1709,7 @@ def update_part_modeling_props(self, project, part_modeling_props): project : str Name of the Sherlock project. part_modeling_props : dict - Dict of part modeling properties for a CCA consisting of these properties: + Part modeling properties for a CCA consisting of these properties: - cca_name : str Name of the CCA. @@ -1754,16 +1755,16 @@ def update_part_modeling_props(self, project, part_modeling_props): >>> sherlock.analysis.update_part_modeling_props( "Test", { - 'cca_name': 'Card', - 'part_enabled': True, - 'part_min_size': 1, - 'part_min_size_units': 'in', - 'part_elem_order': 'First Order (Linear)', - 'part_max_edge_length': 1, - 'part_max_edge_length_units': 'in', - 'part_max_vertical': 1, - 'part_max_vertical_units': 'in', - 'part_results_filtered': True + "cca_name": "Card", + "part_enabled": True, + "part_min_size": 1, + "part_min_size_units": "in", + "part_elem_order": "First Order (Linear)", + "part_max_edge_length": 1, + "part_max_edge_length_units": "in", + "part_max_vertical": 1, + "part_max_vertical_units": "in", + "part_results_filtered": True } ) @@ -1833,34 +1834,35 @@ def update_part_modeling_props(self, project, part_modeling_props): def update_part_list_validation_analysis_props( self, project, - analysis_properties, + properties_per_cca, ): - """Update properties for an ICT analysis. + """Update properties for a Part List Validation analysis. Parameters ---------- project : str Name of the Sherlock project. - ict_analysis_properties : list - List of ICT analysis properties for a CCA consisting of these properties: + properties_per_cca : list + Part List Validation analysis properties for each CCA consisting of these properties: - cca_name : str Name of the CCA. - - ict_application_time : double - Specifies the amount of time to complete one ICT event. - - ict_application_time_units : str - Application time units. - Options are ``"ms"``, ``"sec"``, ``"min"``, ``"hr"``, ``"day"``, ``"year"``. - - ict_number_of_events: int - Specifies the number of events to apply to the application time when computing - the time to failure for a component. - - part_validation_enabled: bool - Whether to enable part validation. The default is ``None``. - - require_material_assignment_enabled: bool - Whether to require material assignment. The default is ``None``. - - ict_result_count: int - The number of ICT result layers to generate. This parameter is for use with - thermal analysis. + - process_use_avl : bool + Whether to use AVL. + - process_use_wizard : bool + Whether to use the wizard. + - process_check_confirmed_properties : bool + Whether to check confirmed properties. + - process_check_part_numbers : bool + Whether to check part numbers. + - matching_mode : str + Matching type. + - avl_require_internal_part_number : bool + Whether to require an internal part number. + - avl_require_approved_description : bool + Whether to require an approved description. + - avl_require_approved_manufacturer : bool + Whether to require an approved manufacturer. Returns ------- @@ -1880,84 +1882,76 @@ def update_part_list_validation_analysis_props( project="Test", cca_name="Card", ) - >>> sherlock.analysis.update_ict_analysis_props( + >>> sherlock.analysis.update_part_list_validation_analysis_props( "Test", [{ - 'cca_name': 'Card', - 'ict_application_time': 2, - 'ict_application_time_units': 'sec', - 'ict_number_of_events': 10, - 'part_validation_enabled': False, - 'require_material_assignment_enabled': False, + "cca_name": "Card", + "process_use_avl": True, + "process_use_wizard": False, + "process_check_confirmed_properties": True, + "process_check_part_numbers": True, + "matching_mode": "Part", + "avl_require_internal_part_number": True, + "avl_require_approved_description": False, + "avl_require_approved_manufacturer": True, }, ] ) - """ try: - if project == "": - raise SherlockUpdateICTAnalysisPropsError(message="Project name is invalid.") - - if not isinstance(ict_analysis_properties, list): - raise SherlockUpdateICTAnalysisPropsError( - message="ICT analysis properties argument is invalid." + if not isinstance(properties_per_cca, list): + raise SherlockUpdatePartListValidationAnalysisPropsError( + message="Properties per CCA argument is invalid." ) - if len(ict_analysis_properties) == 0: - raise SherlockUpdateICTAnalysisPropsError( - message="One or more ICT analysis properties are required." + if len(properties_per_cca) == 0: + raise SherlockUpdatePartListValidationAnalysisPropsError( + message="One or more analysis properties are required." ) - request = SherlockAnalysisService_pb2.UpdateICTAnalysisPropsRequest(project=project) + request = SherlockAnalysisService_pb2.UpdatePartsListValidationPropsRequest( + project=project + ) - for i, ict_analysis_props in enumerate(ict_analysis_properties): - if not isinstance(ict_analysis_props, dict): - raise SherlockUpdateICTAnalysisPropsError( - f"ICT analysis props argument is invalid for ICT analysis properties {i}." + for i, analysis_properties in enumerate(properties_per_cca): + if not isinstance(analysis_properties, dict): + raise SherlockUpdatePartListValidationAnalysisPropsError( + f"Analysis properties is invalid for index {i}." ) - if "cca_name" not in ict_analysis_props.keys(): - raise SherlockUpdateICTAnalysisPropsError( - message=f"CCA name is missing for ICT analysis properties {i}." + if "cca_name" not in analysis_properties.keys(): + raise SherlockUpdatePartListValidationAnalysisPropsError( + message=f"CCA name is missing for analysis properties {i}." ) - cca_name = ict_analysis_props["cca_name"] + cca_name = analysis_properties["cca_name"] if cca_name == "": - raise SherlockUpdateICTAnalysisPropsError( - message=f"CCA name is invalid for ICT analysis properties {i}." + raise SherlockUpdatePartListValidationAnalysisPropsError( + message=f"CCA name is invalid for analysis properties {i}." ) - props_request = request.ictAnalysisProperties.add() - props_request.ccaName = cca_name - - if "ict_analysis_count" in ict_analysis_props.keys(): - props_request.ictAnalysisCount = ict_analysis_props["ict_analysis_count"] - - if "ict_application_time" in ict_analysis_props.keys(): - props_request.applicationTime = ict_analysis_props["ict_application_time"] - - if "ict_application_time_units" in ict_analysis_props.keys(): - props_request.applicationTimeUnits = ict_analysis_props[ - "ict_application_time_units" - ] - - if "ict_number_of_events" in ict_analysis_props.keys(): - props_request.numberOfEvents = ict_analysis_props["ict_number_of_events"] - - if "part_validation_enabled" in ict_analysis_props.keys(): - props_request.partValidationEnabled = ict_analysis_props[ - "part_validation_enabled" - ] - - if "require_material_assignment_enabled" in ict_analysis_props.keys(): - props_request.requireMaterialAssignmentEnabled = ict_analysis_props[ - "require_material_assignment_enabled" - ] - - if "force_model_rebuild" in ict_analysis_props.keys(): - props_request.forceModelRebuild = ict_analysis_props["force_model_rebuild"] - - except SherlockUpdateICTAnalysisPropsError as e: + request.partsListValidationProperties.add( + ccaName=cca_name, + processUseAVL=analysis_properties.get("process_use_avl", False), + processUseWizard=analysis_properties.get("process_use_wizard", False), + processCheckConfirmedProperties=analysis_properties.get( + "process_check_confirmed_properties", False + ), + processCheckPartNumbers=analysis_properties.get( + "process_check_part_numbers", False + ), + matching=analysis_properties.get("matching_mode", "Both"), + avlRequireInternalPartNumber=analysis_properties.get( + "avl_require_internal_part_number", False + ), + avlRequireApprovedDescription=analysis_properties.get( + "avl_require_approved_description", False + ), + avlRequireApprovedManufacturer=analysis_properties.get( + "avl_require_approved_manufacturer", False + ), + ) + except SherlockUpdatePartListValidationAnalysisPropsError as e: LOG.error(str(e)) raise e @@ -1965,14 +1959,14 @@ def update_part_list_validation_analysis_props( LOG.error("There is no connection to a gRPC service.") return - response = self.stub.updateICTAnalysisProps(request) + response = self.stub.updatePartsListValidationProps(request) try: if response.value == -1: - raise SherlockUpdateICTAnalysisPropsError(response.message) + raise SherlockUpdatePartListValidationAnalysisPropsError(response.message) else: LOG.info(response.message) return response.value - except SherlockUpdateICTAnalysisPropsError as e: + except SherlockUpdatePartListValidationAnalysisPropsError as e: LOG.error(str(e)) raise e diff --git a/tests/test_analysis.py b/tests/test_analysis.py index f05163ef2..faac20f46 100644 --- a/tests/test_analysis.py +++ b/tests/test_analysis.py @@ -17,6 +17,7 @@ SherlockUpdateICTAnalysisPropsError, SherlockUpdateMechanicalShockPropsError, SherlockUpdateNaturalFrequencyPropsError, + SherlockUpdatePartListValidationAnalysisPropsError, SherlockUpdatePartModelingPropsError, SherlockUpdatePcbModelingPropsError, SherlockUpdateRandomVibePropsError, @@ -56,6 +57,7 @@ def test_all(): helper_test_update_natural_frequency_props(analysis) helper_test_update_pcb_modeling_props(analysis) helper_test_update_part_modeling_props(analysis) + helper_test_update_parts_list_validation_props(analysis) def helper_test_run_analysis(analysis): @@ -1580,6 +1582,26 @@ def helper_test_update_part_modeling_props(analysis): except SherlockUpdatePartModelingPropsError as e: assert str(e) == "Update part modeling props error: CCA name is missing." + try: + analysis.update_part_modeling_props( + "Test", + { + "cca_name": "", + "part_enabled": True, + "part_min_size": 1, + "part_min_size_units": "in", + "part_elem_order": "First Order (Linear)", + "part_max_edge_length": 1, + "part_max_edge_length_units": "in", + "part_max_vertical": 1, + "part_max_vertical_units": "in", + "part_results_filtered": True, + }, + ) + pytest.fail("No exception thrown when CCA name is empty.") + except SherlockUpdatePartModelingPropsError as e: + assert str(e) == "Update part modeling props error: CCA name is invalid." + try: analysis.update_part_modeling_props( "Test", @@ -1635,5 +1657,130 @@ def helper_test_update_part_modeling_props(analysis): pytest.fail(str(e)) +def helper_test_update_parts_list_validation_props(analysis): + try: + analysis.update_part_list_validation_analysis_props("Tutorial Project", "Main Board") + pytest.fail("No exception raised when using an invalid parameter") + except SherlockUpdatePartListValidationAnalysisPropsError as e: + assert ( + str(e) == "Update part list validation analysis properties error: " + "Properties per CCA argument is invalid." + ) + + try: + analysis.update_part_list_validation_analysis_props("Tutorial Project", []) + pytest.fail("No exception raised when using an invalid parameter") + except SherlockUpdatePartListValidationAnalysisPropsError as e: + assert e.message == "One or more analysis properties are required." + + try: + analysis.update_part_list_validation_analysis_props( + "Tutorial Project", + [ + { + "cca_name": "Main Board", + "process_use_avl": True, + "process_use_wizard": False, + "process_check_confirmed_properties": True, + "process_check_part_numbers": True, + "matching_mode": "Part", + "avl_require_internal_part_number": True, + "avl_require_approved_description": True, + "avl_require_approved_manufacturer": True, + }, + { + "process_use_avl": True, + "process_use_wizard": False, + "process_check_confirmed_properties": True, + "process_check_part_numbers": True, + "matching_mode": "Part", + "avl_require_internal_part_number": True, + "avl_require_approved_description": True, + "avl_require_approved_manufacturer": True, + }, + ], + ) + pytest.fail("No exception raised when using an invalid parameter") + except SherlockUpdatePartListValidationAnalysisPropsError as e: + assert e.message == "CCA name is missing for analysis properties 1." + + try: + analysis.update_part_list_validation_analysis_props( + "Tutorial Project", + [ + { + "cca_name": "Main Board", + "process_use_avl": True, + "process_use_wizard": False, + "process_check_confirmed_properties": True, + "process_check_part_numbers": True, + "matching_mode": "Part", + "avl_require_internal_part_number": True, + "avl_require_approved_description": True, + "avl_require_approved_manufacturer": True, + }, + { + "cca_name": "", + "process_use_avl": True, + "process_use_wizard": False, + "process_check_confirmed_properties": True, + "process_check_part_numbers": True, + "matching_mode": "Part", + "avl_require_internal_part_number": True, + "avl_require_approved_description": True, + "avl_require_approved_manufacturer": True, + }, + ], + ) + pytest.fail("No exception raised when using an invalid parameter") + except SherlockUpdatePartListValidationAnalysisPropsError as e: + assert e.message == "CCA name is invalid for analysis properties 1." + + if not analysis._is_connection_up(): + return + + try: + analysis.update_part_list_validation_analysis_props( + "", + [ + { + "cca_name": "Main Board", + "process_use_avl": True, + "process_use_wizard": False, + "process_check_confirmed_properties": True, + "process_check_part_numbers": True, + "matching_mode": "Part", + "avl_require_internal_part_number": True, + "avl_require_approved_description": True, + "avl_require_approved_manufacturer": True, + }, + ], + ) + pytest.fail("No exception raised when using an invalid parameter") + except Exception as e: + assert type(e) == SherlockUpdatePartListValidationAnalysisPropsError + + try: + result = analysis.update_part_list_validation_analysis_props( + "Tutorial Project", + [ + { + "cca_name": "Main Board", + "process_use_avl": True, + "process_use_wizard": False, + "process_check_confirmed_properties": True, + "process_check_part_numbers": False, + "matching_mode": "Part", + "avl_require_internal_part_number": True, + "avl_require_approved_description": False, + "avl_require_approved_manufacturer": True, + }, + ], + ) + assert result == 0 + except SherlockUpdatePartListValidationAnalysisPropsError as e: + pytest.fail(str(e)) + + if __name__ == "__main__": test_all() From 54d0d65a67606454add20430b6514e168a28e121 Mon Sep 17 00:00:00 2001 From: Jeff Moody <110494049+ansjmoody@users.noreply.github.com> Date: Thu, 11 Jul 2024 15:48:41 -0500 Subject: [PATCH 5/7] Call pytest.fail() instead of assert False --- tests/test_analysis.py | 50 ++++++++++++++++++++--------------------- tests/test_lifecycle.py | 12 +++++----- tests/test_project.py | 14 ++++++------ 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/tests/test_analysis.py b/tests/test_analysis.py index faac20f46..38c3a3d3b 100644 --- a/tests/test_analysis.py +++ b/tests/test_analysis.py @@ -600,13 +600,13 @@ def helper_test_update_harmonic_vibe_props(analysis): }, ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateHarmonicVibePropsError as e: assert str(e) == "Update harmonic vibe properties error: Project name is invalid." try: analysis.update_harmonic_vibe_props("Test", "Card") - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateHarmonicVibePropsError as e: assert ( str(e) == "Update harmonic vibe properties error: " @@ -615,7 +615,7 @@ def helper_test_update_harmonic_vibe_props(analysis): try: analysis.update_harmonic_vibe_props("Test", []) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateHarmonicVibePropsError as e: assert ( str(e) == "Update harmonic vibe properties error: " @@ -624,7 +624,7 @@ def helper_test_update_harmonic_vibe_props(analysis): try: analysis.update_harmonic_vibe_props("Test", ["Card"]) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateHarmonicVibePropsError as e: assert ( str(e) == "Update harmonic vibe properties error: " @@ -646,7 +646,7 @@ def helper_test_update_harmonic_vibe_props(analysis): }, ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateHarmonicVibePropsError as e: assert ( str(e) == "Update harmonic vibe properties error: " @@ -669,7 +669,7 @@ def helper_test_update_harmonic_vibe_props(analysis): }, ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateHarmonicVibePropsError as e: assert ( str(e) == "Update harmonic vibe properties error: " @@ -692,7 +692,7 @@ def helper_test_update_harmonic_vibe_props(analysis): }, ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateHarmonicVibePropsError as e: assert ( str(e) == "Update harmonic vibe properties error: " @@ -756,13 +756,13 @@ def helper_test_update_ict_analysis_props(analysis): }, ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateICTAnalysisPropsError as e: assert str(e) == "Update ICT analysis properties error: Project name is invalid." try: analysis.update_ict_analysis_props("Tutorial Project", "Main Board") - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateICTAnalysisPropsError as e: assert ( str(e) == "Update ICT analysis properties error: " @@ -771,7 +771,7 @@ def helper_test_update_ict_analysis_props(analysis): try: analysis.update_ict_analysis_props("Tutorial Project", []) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateICTAnalysisPropsError as e: assert ( str(e) == "Update ICT analysis properties error: " @@ -780,7 +780,7 @@ def helper_test_update_ict_analysis_props(analysis): try: analysis.update_ict_analysis_props("Tutorial Project", ["INVALID"]) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateICTAnalysisPropsError as e: assert ( str(e) == "Update ICT analysis properties error: " @@ -801,7 +801,7 @@ def helper_test_update_ict_analysis_props(analysis): }, ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateICTAnalysisPropsError as e: assert ( str(e) == "Update ICT analysis properties error: " @@ -823,7 +823,7 @@ def helper_test_update_ict_analysis_props(analysis): }, ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateICTAnalysisPropsError as e: assert ( str(e) == "Update ICT analysis properties error: " @@ -892,13 +892,13 @@ def helper_test_update_mechanical_shock_props(analysis): }, ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateMechanicalShockPropsError as e: assert str(e) == "Update mechanical shock properties error: Project name is invalid." try: analysis.update_mechanical_shock_props("Test", "INVALID_TYPE") - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateMechanicalShockPropsError as e: assert ( str(e) == "Update mechanical shock properties error: " @@ -907,7 +907,7 @@ def helper_test_update_mechanical_shock_props(analysis): try: analysis.update_mechanical_shock_props("Test", []) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateMechanicalShockPropsError as e: assert ( str(e) == "Update mechanical shock properties error: " @@ -916,7 +916,7 @@ def helper_test_update_mechanical_shock_props(analysis): try: analysis.update_mechanical_shock_props("Test", ["INVALID"]) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateMechanicalShockPropsError as e: assert ( str(e) == "Update mechanical shock properties error: " @@ -943,7 +943,7 @@ def helper_test_update_mechanical_shock_props(analysis): }, ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateMechanicalShockPropsError as e: assert ( str(e) == "Update mechanical shock properties error: " @@ -971,7 +971,7 @@ def helper_test_update_mechanical_shock_props(analysis): }, ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateMechanicalShockPropsError as e: assert ( str(e) == "Update mechanical shock properties error: " @@ -1049,13 +1049,13 @@ def helper_test_update_solder_fatigue_props(analysis): }, ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateSolderFatiguePropsError as e: assert str(e) == "Update solder fatigue properties error: Project name is invalid." try: analysis.update_solder_fatigue_props("Test", "INVALID_TYPE") - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateSolderFatiguePropsError as e: assert ( str(e) == "Update solder fatigue properties error: " @@ -1064,7 +1064,7 @@ def helper_test_update_solder_fatigue_props(analysis): try: analysis.update_solder_fatigue_props("Test", []) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateSolderFatiguePropsError as e: assert ( str(e) == "Update solder fatigue properties error: " @@ -1073,7 +1073,7 @@ def helper_test_update_solder_fatigue_props(analysis): try: analysis.update_solder_fatigue_props("Test", ["INVALID"]) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateSolderFatiguePropsError as e: assert ( str(e) == "Update solder fatigue properties error: " @@ -1093,7 +1093,7 @@ def helper_test_update_solder_fatigue_props(analysis): }, ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateSolderFatiguePropsError as e: assert ( str(e) == "Update solder fatigue properties error: " @@ -1114,7 +1114,7 @@ def helper_test_update_solder_fatigue_props(analysis): }, ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockUpdateSolderFatiguePropsError as e: assert ( str(e) == "Update solder fatigue properties error: " diff --git a/tests/test_lifecycle.py b/tests/test_lifecycle.py index e788d7e95..290e91c10 100644 --- a/tests/test_lifecycle.py +++ b/tests/test_lifecycle.py @@ -595,7 +595,7 @@ def helper_test_add_thermal_profiles(lifecycle, phase_name, event_name): ) ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockAddThermalProfilesError as e: assert ( str(e.str_itr()) == "['Add thermal profiles error: " @@ -621,7 +621,7 @@ def helper_test_add_thermal_profiles(lifecycle, phase_name, event_name): ) ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockAddThermalProfilesError as e: assert ( str(e.str_itr()) == "['Add thermal profiles error: " @@ -647,7 +647,7 @@ def helper_test_add_thermal_profiles(lifecycle, phase_name, event_name): ) ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockAddThermalProfilesError as e: assert ( str(e.str_itr()) == "['Add thermal profiles error: " @@ -673,7 +673,7 @@ def helper_test_add_thermal_profiles(lifecycle, phase_name, event_name): ) ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockAddThermalProfilesError as e: assert ( str(e.str_itr()) == "['Add thermal profiles error: " @@ -699,7 +699,7 @@ def helper_test_add_thermal_profiles(lifecycle, phase_name, event_name): ) ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockAddThermalProfilesError as e: assert ( str(e.str_itr()) == "['Add thermal profiles error: " @@ -725,7 +725,7 @@ def helper_test_add_thermal_profiles(lifecycle, phase_name, event_name): ) ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockAddThermalProfilesError as e: assert ( str(e.str_itr()) == "['Add thermal profiles error: " diff --git a/tests/test_project.py b/tests/test_project.py index 14085fadb..8a1c7baa5 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -180,7 +180,7 @@ def helper_test_list_ccas(project): try: project.list_ccas("Tutorial Project", "CCA names that is not a list") - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockListCCAsError as e: assert str(e.str_itr()) == "['List CCAs error: cca_names is not a list.']" @@ -226,25 +226,25 @@ def helper_test_add_cca(project): }, ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockAddCCAError as e: assert str(e) == "Add CCA error: Project name is invalid." try: project.add_cca("Test", "") - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockAddCCAError as e: assert str(e) == "Add CCA error: CCA properties argument is invalid." try: project.add_cca("Test", []) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockAddCCAError as e: assert str(e) == "Add CCA error: One or more CCAs are required." try: project.add_cca("Test", [""]) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockAddCCAError as e: assert str(e) == "Add CCA error: CCA properties are invalid for CCA 0." @@ -263,7 +263,7 @@ def helper_test_add_cca(project): }, ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockAddCCAError as e: assert str(e) == "Add CCA error: CCA name is missing for CCA 0." @@ -283,7 +283,7 @@ def helper_test_add_cca(project): }, ], ) - assert False + pytest.fail("No exception raised when using an invalid parameter") except SherlockAddCCAError as e: assert str(e) == "Add CCA error: CCA name is invalid for CCA 0." From 2da385fd9707ebe9b9d98519279affac18c0edf4 Mon Sep 17 00:00:00 2001 From: Jeff Moody <110494049+ansjmoody@users.noreply.github.com> Date: Thu, 11 Jul 2024 16:37:15 -0500 Subject: [PATCH 6/7] test_model: use is instead of == for comparing type --- tests/test_model.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_model.py b/tests/test_model.py index 435c4e617..f8910d1c0 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -29,7 +29,7 @@ def test_model_export_trace_reinforcement_model(self): model.export_trace_reinforcement_model("Tutorial Project", invalid_cca, path) pytest.fail("No exception raised when using an invalid parameter") except Exception as e: - assert type(e) == SherlockModelServiceError + assert type(e) is SherlockModelServiceError try: result = model.export_trace_reinforcement_model( @@ -193,7 +193,7 @@ def test_model_generate_trace_model(self): ) pytest.fail("No exception raised when using an invalid parameter") except Exception as e: - assert type(e) == SherlockModelServiceError + assert type(e) is SherlockModelServiceError try: result = model.generate_trace_model( @@ -262,7 +262,7 @@ def test_model_export_aedb(self): ) pytest.fail("No exception raised when using an invalid parameter") except Exception as e: - assert type(e) == SherlockExportAEDBError + assert type(e) is SherlockExportAEDBError try: result = model.export_aedb( From def2e1ade6803d8c91ee32d775315c71a5b34401 Mon Sep 17 00:00:00 2001 From: Jeff Moody <110494049+ansjmoody@users.noreply.github.com> Date: Fri, 12 Jul 2024 10:53:11 -0500 Subject: [PATCH 7/7] Increase version of ansys-api-sherlock --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index af12322e0..8efd4531c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,7 +24,7 @@ classifiers = [ ] dependencies = [ - "ansys-api-sherlock==0.1.28", + "ansys-api-sherlock==0.1.29", "grpcio>=1.17", "importlib-metadata>=4.0,<5; python_version<='3.8'", "protobuf~=3.20",