diff --git a/packages/service/ni_measurement_plugin_sdk_service/measurement/service.py b/packages/service/ni_measurement_plugin_sdk_service/measurement/service.py index ab8718563..625faf454 100644 --- a/packages/service/ni_measurement_plugin_sdk_service/measurement/service.py +++ b/packages/service/ni_measurement_plugin_sdk_service/measurement/service.py @@ -210,7 +210,10 @@ def __init__( raise RuntimeError(f"File does not exist. {service_config_path}") with open(service_config_path) as service_config_file: - service_config = json.load(service_config_file) + try: + service_config = json.loads(service_config_file.read()) + except json.decoder.JSONDecodeError: + raise NameError(f"Invalid character(s) in {service_config_path}") if service_class is None: service = next(iter(service_config["services"]), None) diff --git a/packages/service/tests/assets/check_char/example.Control.V1.serviceconfig b/packages/service/tests/assets/check_char/example.Control.V1.serviceconfig new file mode 100644 index 000000000..305fd8840 --- /dev/null +++ b/packages/service/tests/assets/check_char/example.Control.V1.serviceconfig @@ -0,0 +1,19 @@ +{ + "services": [ + { + "displayName": "SampleMeasurement", + "serviceClass": "SampleMeasurement_Python", + "descriptionUrl": "https://www.example.com/SampleMeasurement.html", + "providedInterfaces": [ + "ni.measurementlink.measurement.v1.MeasurementService", + "ni.measurementlink.measurement.v2.MeasurementService" + ], + "path": "start.bat", + "annotations": { + "ni/service.description": "Measure inrush current with a shorted load and validate results against configured limits.", + "ni/service.collection": "CurrentTests.Inrush", + "ni/service.tags": [ "powerup", "current" ] + } + } + ] +} \ No newline at end of file diff --git a/packages/service/tests/assets/check_char/example.Control.V2.serviceconfig b/packages/service/tests/assets/check_char/example.Control.V2.serviceconfig new file mode 100644 index 000000000..305fd8840 --- /dev/null +++ b/packages/service/tests/assets/check_char/example.Control.V2.serviceconfig @@ -0,0 +1,19 @@ +{ + "services": [ + { + "displayName": "SampleMeasurement", + "serviceClass": "SampleMeasurement_Python", + "descriptionUrl": "https://www.example.com/SampleMeasurement.html", + "providedInterfaces": [ + "ni.measurementlink.measurement.v1.MeasurementService", + "ni.measurementlink.measurement.v2.MeasurementService" + ], + "path": "start.bat", + "annotations": { + "ni/service.description": "Measure inrush current with a shorted load and validate results against configured limits.", + "ni/service.collection": "CurrentTests.Inrush", + "ni/service.tags": [ "powerup", "current" ] + } + } + ] +} \ No newline at end of file diff --git a/packages/service/tests/assets/check_char/example.Control.serviceconfig b/packages/service/tests/assets/check_char/example.Control.serviceconfig new file mode 100644 index 000000000..305fd8840 --- /dev/null +++ b/packages/service/tests/assets/check_char/example.Control.serviceconfig @@ -0,0 +1,19 @@ +{ + "services": [ + { + "displayName": "SampleMeasurement", + "serviceClass": "SampleMeasurement_Python", + "descriptionUrl": "https://www.example.com/SampleMeasurement.html", + "providedInterfaces": [ + "ni.measurementlink.measurement.v1.MeasurementService", + "ni.measurementlink.measurement.v2.MeasurementService" + ], + "path": "start.bat", + "annotations": { + "ni/service.description": "Measure inrush current with a shorted load and validate results against configured limits.", + "ni/service.collection": "CurrentTests.Inrush", + "ni/service.tags": [ "powerup", "current" ] + } + } + ] +} \ No newline at end of file diff --git a/packages/service/tests/assets/check_char/example.ErrorAnnotations.serviceconfig b/packages/service/tests/assets/check_char/example.ErrorAnnotations.serviceconfig new file mode 100644 index 000000000..5a070d54f --- /dev/null +++ b/packages/service/tests/assets/check_char/example.ErrorAnnotations.serviceconfig @@ -0,0 +1,19 @@ +{ + "services": [ + { + "displayName": "SampleMeasurement", + "serviceClass": "SampleMeasurement_Python", + "descriptionUrl": "https://www.example.com/SampleMeasurement.html", + "providedInterfaces": [ + "ni.measurementlink.measurement.v1.MeasurementService", + "ni.measurementlink.measurement.v2.MeasurementService" + ], + "path": "start.bat", + "annotations": { + "ni/service.description": """, + "ni/service.collection": "CurrentTests.Inrush", + "ni/service.tags": [ "powerup", "current" ] + } + } + ] +} \ No newline at end of file diff --git a/packages/service/tests/assets/check_char/example.ErrorCollections.serviceconfig b/packages/service/tests/assets/check_char/example.ErrorCollections.serviceconfig new file mode 100644 index 000000000..1dc3c2f05 --- /dev/null +++ b/packages/service/tests/assets/check_char/example.ErrorCollections.serviceconfig @@ -0,0 +1,19 @@ +{ + "services": [ + { + "displayName": "SampleMeasurement\", + "serviceClass": "SampleMeasurement_Python", + "descriptionUrl": "https://www.example.com/SampleMeasurement.html", + "providedInterfaces": [ + "ni.measurementlink.measurement.v1.MeasurementService", + "ni.measurementlink.measurement.v2.MeasurementService" + ], + "path": "start.bat", + "annotations": { + "ni/service.description": "Measure inrush current with a shorted load and validate results against configured limits.", + "ni/service.collection": "\", + "ni/service.tags": [ "powerup", "current" ] + } + } + ] +} \ No newline at end of file diff --git a/packages/service/tests/assets/check_char/example.ErrorDisplayName.serviceconfig b/packages/service/tests/assets/check_char/example.ErrorDisplayName.serviceconfig new file mode 100644 index 000000000..7df8043f4 --- /dev/null +++ b/packages/service/tests/assets/check_char/example.ErrorDisplayName.serviceconfig @@ -0,0 +1,19 @@ +{ + "services": [ + { + "displayName": "\\SampleMeasurement\", + "serviceClass": "SampleMeasurement_Python", + "descriptionUrl": "https://www.example.com/SampleMeasurement.html", + "providedInterfaces": [ + "ni.measurementlink.measurement.v1.MeasurementService", + "ni.measurementlink.measurement.v2.MeasurementService" + ], + "path": "start.bat", + "annotations": { + "ni/service.description": "Measure inrush current with a shorted load and validate results against configured limits.", + "ni/service.collection": "CurrentTests.Inrush", + "ni/service.tags": [ "powerup", "current" ] + } + } + ] +} \ No newline at end of file diff --git a/packages/service/tests/assets/check_char/example.ErrorTags.serviceconfig b/packages/service/tests/assets/check_char/example.ErrorTags.serviceconfig new file mode 100644 index 000000000..053b7430a --- /dev/null +++ b/packages/service/tests/assets/check_char/example.ErrorTags.serviceconfig @@ -0,0 +1,19 @@ +{ + "services": [ + { + "displayName": "SampleMeasurement\", + "serviceClass": "SampleMeasurement_Python", + "descriptionUrl": "https://www.example.com/SampleMeasurement.html", + "providedInterfaces": [ + "ni.measurementlink.measurement.v1.MeasurementService", + "ni.measurementlink.measurement.v2.MeasurementService" + ], + "path": "start.bat", + "annotations": { + "ni/service.description": "Measure inrush current with a shorted load and validate results against configured limits.", + "ni/service.collection": "CurrentTests.Inrush", + "ni/service.tags": [ "powerup", "\"" ] + } + } + ] +} \ No newline at end of file diff --git a/packages/service/tests/unit/test_service.py b/packages/service/tests/unit/test_service.py index b62235f2f..edea0121c 100644 --- a/packages/service/tests/unit/test_service.py +++ b/packages/service/tests/unit/test_service.py @@ -10,8 +10,13 @@ from ni_measurement_plugin_sdk_service import _datatypeinfo from ni_measurement_plugin_sdk_service._annotations import TYPE_SPECIALIZATION_KEY -from ni_measurement_plugin_sdk_service._internal.stubs.ni.protobuf.types import xydata_pb2 -from ni_measurement_plugin_sdk_service.measurement.info import DataType, TypeSpecialization +from ni_measurement_plugin_sdk_service._internal.stubs.ni.protobuf.types import ( + xydata_pb2, +) +from ni_measurement_plugin_sdk_service.measurement.info import ( + DataType, + TypeSpecialization, +) from ni_measurement_plugin_sdk_service.measurement.service import MeasurementService @@ -421,6 +426,58 @@ def test___service_config___create_measurement_service___service_info_matches_se assert measurement_service.service_info.annotations == provided_annotations +@pytest.mark.parametrize( + "service_config,have_special_char", + [ + ( + "Control.serviceconfig", + False, + ), + ( + "Control.V1.serviceconfig", + False, + ), + ( + "Control.V2.serviceconfig", + False, + ), + ( + "ErrorDisplayName.serviceconfig", + True, + ), + ( + "ErrorAnnotations.serviceconfig", + True, + ), + ( + "ErrorTags.serviceconfig", + True, + ), + ( + "ErrorCollections.serviceconfig", + True, + ), + ], +) +def test___service_config___check_service_config___validiate_no_special_characters( + test_assets_directory: pathlib.Path, + service_config: str, + have_special_char: bool, +): + char_service_config = "check_char\\example." + service_config + try: + MeasurementService( + service_config_path=test_assets_directory / char_service_config, + version="1.0.0.0", + ui_file_paths=[], + ) + error_occurred = False + except NameError: + error_occurred = True + + assert error_occurred == have_special_char + + @pytest.mark.parametrize( "display_name,type,default_value,enum_type", [