From 5a70a09fbd8ca19448090fb80d3930951da531f8 Mon Sep 17 00:00:00 2001 From: Tom Kralidis Date: Mon, 26 Aug 2024 09:17:39 -0400 Subject: [PATCH] add link channel check for valid WIS2 topic (#121) --- pywcmp/wcmp2/ets.py | 7 + tests/data/wcmp2-failing-created-none.json | 2 +- .../data/wcmp2-failing-invalid-centre-id.json | 2 +- ...iling-invalid-link-channel-wis2-topic.json | 161 ++++++++++++++++++ tests/data/wcmp2-failing.json | 2 +- tests/data/wcmp2-passing-test-centre-id.json | 2 +- tests/data/wcmp2-passing.json | 2 +- tests/run_tests.py | 17 ++ 8 files changed, 190 insertions(+), 5 deletions(-) create mode 100644 tests/data/wcmp2-failing-invalid-link-channel-wis2-topic.json diff --git a/pywcmp/wcmp2/ets.py b/pywcmp/wcmp2/ets.py index 608355f..236eaa7 100644 --- a/pywcmp/wcmp2/ets.py +++ b/pywcmp/wcmp2/ets.py @@ -446,6 +446,13 @@ def test_requirement_links(self): status['message'] = 'missing channel for Pub/Sub link' return status + if link['channel'].startswith(('origin/a/wis2', 'cache/a/wis2')): # noqa + LOGGER.debug('Validating topic in link channel') + if not self.th.validate(link['channel']): + status['code'] = 'FAILED' + status['message'] = 'Invalid WIS2 topic for Pub/Sub link channel' # noqa + return status + LOGGER.debug('Checking that links with security have descriptions') if 'security' in link: for key, value in link['security'].items(): diff --git a/tests/data/wcmp2-failing-created-none.json b/tests/data/wcmp2-failing-created-none.json index 15c3eb5..e77a0eb 100644 --- a/tests/data/wcmp2-failing-created-none.json +++ b/tests/data/wcmp2-failing-created-none.json @@ -153,7 +153,7 @@ { "rel": "items", "href": "mqtt://example.org:8883", - "channel": "origin/a/wis2/can/eccc-msc/data/core/weather/observations/surface-land/landFixed", + "channel": "origin/a/wis2/ca-eccc-msc/data/core/weather/surface-based-observations/synop", "type": "application/json", "title": "Data notifications" } diff --git a/tests/data/wcmp2-failing-invalid-centre-id.json b/tests/data/wcmp2-failing-invalid-centre-id.json index c193c69..b8357b5 100644 --- a/tests/data/wcmp2-failing-invalid-centre-id.json +++ b/tests/data/wcmp2-failing-invalid-centre-id.json @@ -153,7 +153,7 @@ { "rel": "items", "href": "mqtt://example.org:8883", - "channel": "origin/a/wis2/can/eccc-msc/data/core/weather/observations/surface-land/landFixed", + "channel": "origin/a/wis2/ca-eccc-msc/data/core/weather/surface-based-observations/synop", "type": "application/json", "title": "Data notifications" } diff --git a/tests/data/wcmp2-failing-invalid-link-channel-wis2-topic.json b/tests/data/wcmp2-failing-invalid-link-channel-wis2-topic.json new file mode 100644 index 0000000..9c7ee13 --- /dev/null +++ b/tests/data/wcmp2-failing-invalid-link-channel-wis2-topic.json @@ -0,0 +1,161 @@ +{ + "id": "urn:wmo:md:ca-eccc-msc:weather.observations.swob-realtime", + "conformsTo": [ + "http://wis.wmo.int/spec/wcmp/2/conf/core" + ], + "time": { + "interval": [ + "2010-11-11T11:11:11Z", + ".." + ], + "resolution": "P1H" + }, + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -142, + 28 + ], + [ + -142, + 82 + ], + [ + -52, + 82 + ], + [ + -52, + 28 + ], + [ + -142, + 28 + ] + ] + ] + }, + "properties": { + "title": "Surface weather observations", + "description": "Surface Observations measured at the automatic and manual stations of the Environment and Climate Change Canada and partners networks, either for a single station, or for the stations of specific provinces and territories (last 30 days)", + "themes": [ + { + "concepts": [ + { + "id": "Weather" + }, + { + "id": "Archives" + }, + { + "id": "Precipitation" + }, + { + "id": "Air temperature" + }, + { + "id": "Humidity" + }, + { + "id": "Snow" + }, + { + "id": "Wind" + }, + { + "id": "Meteorological data" + } + ], + "scheme": "https://library-archives.canada.ca/eng/services/government-canada/controlled-vocabularies-government-canada/pages/controlled-vocabularies-government-canada.aspx" + }, + { + "concepts": [ + { + "id": "weather" + } + ], + "scheme": "https://codes.wmo.int/wis/topic-hierarchy/earth-system-discipline" + } + ], + "contacts": [ + { + "organization": "Government of Canada; Environment and Climate Change Canada; Meteorological Service of Canada", + "position": "National Inquiry Response Team", + "phones": [ + { + "value": "+18199972800" + } + ], + "emails": [ + { + "value": "enviroinfo@ec.gc.ca" + } + ], + "addresses": [ + { + "deliveryPoint": [ + "77 Westmorland Street, suite 260" + ], + "city": "Fredericton", + "administrativeArea": "NB", + "postalCode": "E3B 6Z4", + "country": "Canada" + } + ], + "links": [ + { + "rel": "canonical", + "type": "text/html", + "href": "https://example.org" + } + ], + "contactInstructions": "via email", + "roles": [ + "host", + "producer" + ] + } + ], + "type": "dataset", + "created": "2018-01-01T11:11:11Z", + "updated": "2022-06-22T12:42:46Z", + "wmo:dataPolicy": "core" + }, + "links": [ + { + "rel": "stations", + "href": "https://dd.weather.gc.ca/observations/doc/swob-xml_station_list.csv", + "type": "text/csv", + "title": "Stations associated with this dataset" + }, + { + "rel": "data", + "href": "https://dd.weather.gc.ca/observations/swob-ml", + "type": "text/html", + "hreflang": "en", + "title": "Raw data download (CSV files)" + }, + { + "rel": "items", + "href": "https://api.weather.gc.ca/collections/swob-realtime/items", + "type": "application/json", + "title": "Data access API interface" + }, + { + "rel": "related", + "href": "https://eccc-msc.github.io/open-data/msc-data/obs_station/readme_obs_insitu_swobdatamart_en", + "type": "text/html", + "title": "Documentation" + }, + { + "rel": "items", + "href": "mqtt://example.org:8883", + "channel": "origin/a/wis2/ca-eccc-msc/data/core/weather/surface-based-observations/landFixed", + "type": "application/json", + "title": "Data notifications" + } + ] +} diff --git a/tests/data/wcmp2-failing.json b/tests/data/wcmp2-failing.json index 37b1f47..3ad3dfe 100644 --- a/tests/data/wcmp2-failing.json +++ b/tests/data/wcmp2-failing.json @@ -148,7 +148,7 @@ { "rel": "items", "href": "mqtt://example.org:8883", - "channel": "origin/a/wis2/can/eccc-msc/data/core/weather/observations/surface-land/landFixed", + "channel": "origin/a/wis2/ca-eccc-msc/data/core/weather/surface-based-observations/synop", "type": "application/json", "title": "Data notifications" } diff --git a/tests/data/wcmp2-passing-test-centre-id.json b/tests/data/wcmp2-passing-test-centre-id.json index fb85a7a..7f9e4df 100644 --- a/tests/data/wcmp2-passing-test-centre-id.json +++ b/tests/data/wcmp2-passing-test-centre-id.json @@ -153,7 +153,7 @@ { "rel": "items", "href": "mqtt://example.org:8883", - "channel": "origin/a/wis2/can/eccc-msc/data/core/weather/observations/surface-land/landFixed", + "channel": "origin/a/wis2/ca-eccc-msc/data/core/weather/surface-based-observations/synop", "type": "application/json", "title": "Data notifications" } diff --git a/tests/data/wcmp2-passing.json b/tests/data/wcmp2-passing.json index 6fdb783..4b5fcc6 100644 --- a/tests/data/wcmp2-passing.json +++ b/tests/data/wcmp2-passing.json @@ -153,7 +153,7 @@ { "rel": "items", "href": "mqtt://example.org:8883", - "channel": "origin/a/wis2/can/eccc-msc/data/core/weather/observations/surface-land/landFixed", + "channel": "origin/a/wis2/ca-eccc-msc/data/core/weather/surface-based-observations/synop", "type": "application/json", "title": "Data notifications" } diff --git a/tests/run_tests.py b/tests/run_tests.py index 6958b6d..69aa4ea 100644 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -123,6 +123,23 @@ def test_fail_created_none(self): self.assertEqual(codes.count('PASSED'), 11) self.assertEqual(codes.count('SKIPPED'), 0) + def test_fail_invalid_link_channel_wis2_topic(self): + """ + Simple tests for a failing record with an invalid + link channel WIS2 topic + """ + + with open(get_test_file_path('data/wcmp2-failing-invalid-link-channel-wis2-topic.json')) as fh: # noqa + record = json.load(fh) + ts = WMOCoreMetadataProfileTestSuite2(record) + results = ts.run_tests() + + codes = [r['code'] for r in results['ets-report']['tests']] + + self.assertEqual(codes.count('FAILED'), 1) + self.assertEqual(codes.count('PASSED'), 11) + self.assertEqual(codes.count('SKIPPED'), 0) + class WCMP2KPITest(unittest.TestCase): """WCMP KPI tests of tests"""