diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b366c05a81ee465db17d1e881630a12628a86c44..b201796fa445ce73a4995e052691e5e8212febdd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -48,7 +48,7 @@ compile_xsd: check_count=0 fail_count=0 while IFS= read -r -d '' file; do - let "check_count=check_count+1" + let "check_count=check_count+1" if ! forgeschema -c "$file"; then echo "❌ failed schema checks for $file" let "fail_count=fail_count+1" @@ -64,7 +64,7 @@ compile_xsd: exit 1 fi echo "┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅" - echo "✅ XSD validation OK ($check_count files checked)" + echo "✅ XSD validation OK ($check_count files checked)" echo "┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅" echo "✅ XSD validation OK for $file" tags: @@ -96,7 +96,7 @@ compile_json: exit 1 fi echo "┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅" - echo "✅ JSON validation OK ($check_count files checked)" + echo "✅ JSON validation OK ($check_count files checked)" echo "┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅" - forgeschema -s 103120/schema/json/ts_103120_Core.schema.json -u 103120/schema/json -u 103120/dictionaries/ts_103120_Dictionaries.schema.json -u 103280/TS_103_280.schema.json -i 103120/examples/json tags: diff --git a/103120/examples/xml/request_takedown.xml b/103120/examples/xml/request_takedown.xml index 8bbca758dd315c336d45977c96303776a8e3fcd2..88dbd8f1b831c01239148dfa74f0f4a3099ef989 100644 --- a/103120/examples/xml/request_takedown.xml +++ b/103120/examples/xml/request_takedown.xml @@ -90,7 +90,7 @@ - 2026-02-01:12:00:00Z + 2026-02-01T12:00:00Z ETSI TDNatureOfDeadline diff --git a/103120/schema/json/ts_103120_Delivery.schema.json b/103120/schema/json/ts_103120_Delivery.schema.json index 1c34cd4139b5b99587fb5fa11fa729c873f090e9..48ddf4809e8923ddd1d357a6b2752fd967744303 100644 --- a/103120/schema/json/ts_103120_Delivery.schema.json +++ b/103120/schema/json/ts_103120_Delivery.schema.json @@ -260,6 +260,13 @@ }, "delivery:Checksums": { "$ref": "ts_103120_Common_2016_02#/$defs/ListOfChecksumAndType" + }, + "delivery:OriginalFilename": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "delivery:ContentLength": { + "type": "integer", + "minimum": 0 } }, "required": [ diff --git a/103120/schema/json/ts_103120_Encryption.schema.json b/103120/schema/json/ts_103120_Encryption.schema.json new file mode 100644 index 0000000000000000000000000000000000000000..ded5c0475e8b7452cfa78411e7953f6447239fe4 --- /dev/null +++ b/103120/schema/json/ts_103120_Encryption.schema.json @@ -0,0 +1,78 @@ +{ + "$id": "ts_103120_Encryption_2026_01", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$defs": { + "EncryptionObject": { + "type": "object", + "properties": { + "@xsi:type": { + "type": "string", + "enum": [ + "{http://uri.etsi.org/03120/common/2026/01/Encryption}EncryptionObject" + ] + }, + "ObjectIdentifier": { + "$ref": "ts_103120_Core_2019_10#/$defs/ObjectIdentifier" + }, + "CountryCode": { + "$ref": "ts_103280_2017_07#/$defs/ISOCountryCode" + }, + "OwnerIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/ShortString" + }, + "Generation": { + "type": "integer", + "minimum": 0 + }, + "ExternalIdentifier": { + "$ref": "ts_103280_2017_07#/$defs/LongString" + }, + "AssociatedObjects": { + "$ref": "ts_103120_Core_2019_10#/$defs/AssociatedObjects" + }, + "LastChanged": { + "$ref": "ts_103280_2017_07#/$defs/QualifiedDateTime" + }, + "NationalHandlingParameters": { + "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" + }, + "encryption:EncryptionScheme": { + "$ref": "ts_103120_Common_2016_02#/$defs/DictionaryEntry" + }, + "encryption:X509EncryptionDetails": { + "$ref": "#/$defs/X509EncryptionDetails" + } + }, + "required": [ + "@xsi:type", + "ObjectIdentifier", + "encryption:EncryptionScheme" + ], + "additionalProperties": false + }, + "X509EncryptionDetails": { + "type": "object", + "properties": { + "encryption:X509Certificates": { + "type": "array", + "items": { + "$ref": "#/$defs/X509Certificate" + } + } + }, + "required": [], + "additionalProperties": false + }, + "X509Certificate": { + "type": "object", + "properties": { + "encryption:X509CertificateDER": { + "type": "string", + "pattern": "^[A-Za-z0-9+\\/]*={0,3}$" + } + }, + "required": [], + "additionalProperties": false + } + } +} diff --git a/103120/schema/json/ts_103120_Task.schema.json b/103120/schema/json/ts_103120_Task.schema.json index c0163759a197784009477532ceadcb97694d5576..7ea9a56944c25dd5d9f656b35810436bdbd931ef 100644 --- a/103120/schema/json/ts_103120_Task.schema.json +++ b/103120/schema/json/ts_103120_Task.schema.json @@ -867,9 +867,6 @@ "NationalHandlingParameters": { "$ref": "ts_103120_Core_2019_10#/$defs/NationalHandlingParameters" }, - "task:Reference": { - "$ref": "ts_103280_2017_07#/$defs/LongString" - }, "task:RequesterReference": { "$ref": "ts_103280_2017_07#/$defs/LongString" }, @@ -972,7 +969,9 @@ "properties": { "task:TakedownDeadline": { "type": "array", - "items": {} + "items": { + "$ref": "#/$defs/TakedownDeadline" + } } }, "required": [], diff --git a/103120/schema/xsd/ts_103120_Core.xsd b/103120/schema/xsd/ts_103120_Core.xsd index d30f6949d68778ca02ab6c4ea8e34d240b21221f..527b2e0ec4e10b33d3376f5f3bd9a4f848b905d8 100644 --- a/103120/schema/xsd/ts_103120_Core.xsd +++ b/103120/schema/xsd/ts_103120_Core.xsd @@ -10,6 +10,7 @@ + diff --git a/103120/schema/xsd/ts_103120_Delivery.xsd b/103120/schema/xsd/ts_103120_Delivery.xsd index f1c67d70227514ffcd5b283b86c3be56b39930ae..47212c0bb30ebdc775d287af04bd9a73cce2a72e 100644 --- a/103120/schema/xsd/ts_103120_Delivery.xsd +++ b/103120/schema/xsd/ts_103120_Delivery.xsd @@ -47,6 +47,7 @@ + diff --git a/103120/schema/xsd/ts_103120_Encryption.xsd b/103120/schema/xsd/ts_103120_Encryption.xsd index fc8b7c86dd2046e8c5c6b34f5ce09b76cee5a1b1..4661388c85cd31df5625b8e33d42fc76c45d2a9e 100644 --- a/103120/schema/xsd/ts_103120_Encryption.xsd +++ b/103120/schema/xsd/ts_103120_Encryption.xsd @@ -8,7 +8,7 @@ - + diff --git a/103120/schema/xsd/ts_103120_Task.xsd b/103120/schema/xsd/ts_103120_Task.xsd index 2374709d4f049b993fd526d1e82350f144c8c82e..d32d4a79a39c4ea3002c8d24028cf0f94f1cd4bb 100644 --- a/103120/schema/xsd/ts_103120_Task.xsd +++ b/103120/schema/xsd/ts_103120_Task.xsd @@ -269,7 +269,6 @@ - @@ -310,7 +309,7 @@ - + diff --git a/testing/dockerfiles/Dockerfile.asn1test b/testing/dockerfiles/Dockerfile.asn1test new file mode 100644 index 0000000000000000000000000000000000000000..b7c3f01c4a46f309fdb74260dbcf1d33c2b22a70 --- /dev/null +++ b/testing/dockerfiles/Dockerfile.asn1test @@ -0,0 +1,10 @@ +# docker login forge.etsi.org:5050 +# docker build -t forge.etsi.org:5050/li/schemas-definitions/asn1test -f Dockerfile.asn1test . +# docker push forge.etsi.org:5050/li/schemas-definitions/asn1test + +FROM python:3.9-slim-bullseye + +RUN apt-get update -y && \ + apt-get install -y asn1c && \ + rm -rf /var/lib/apt/lists/* && \ + pip install --no-cache-dir asn1tools pycrate diff --git a/testing/dockerfiles/forgeschema b/testing/dockerfiles/Dockerfile.forgeschema similarity index 66% rename from testing/dockerfiles/forgeschema rename to testing/dockerfiles/Dockerfile.forgeschema index d3f9249d2036ee5ba12133410439df7b50ccc3e0..f321cb570fd46670c5cf9c9ac74219db43894073 100644 --- a/testing/dockerfiles/forgeschema +++ b/testing/dockerfiles/Dockerfile.forgeschema @@ -1,19 +1,20 @@ # docker login forge.etsi.org:5050 -# docker build -t forge.etsi.org:5050/li/schemas-definitions/forgeschema -f forgeschema . +# docker build -t forge.etsi.org:5050/li/schemas-definitions/forgeschema -f Dockerfile.forgeschema . # docker push forge.etsi.org:5050/li/schemas-definitions/forgeschema -FROM python:3.12-alpine +FROM python:3.14-alpine RUN apk add --no-cache \ + build-base \ + editorconfig \ + gcc \ jq \ - libxml2-utils \ libffi-dev \ - openssl-dev \ - gcc \ + libxml2-utils \ musl-dev \ - python3-dev \ - build-base \ - editorconfig + openssl-dev \ + python3-dev +COPY requirements.txt /requirements.txt RUN pip install --upgrade pip && \ - pip install forgeschema \ No newline at end of file + pip install -r /requirements.txt diff --git a/testing/dockerfiles/dockerfile_asn b/testing/dockerfiles/dockerfile_asn deleted file mode 100644 index 2a4198b43ab2d126a9db22fc372a3b1dbee8e4e5..0000000000000000000000000000000000000000 --- a/testing/dockerfiles/dockerfile_asn +++ /dev/null @@ -1,11 +0,0 @@ -# docker build -t mcanterb/asn1test -# docker push mcanterb/asn1test - -FROM python:3.9-slim-bullseye -RUN apt-get update -y && \ - apt-get install -y asn1c && \ - rm -rf /var/lib/apt/lists/* && \ - pip install --no-cache-dir asn1tools pycrate - - - diff --git a/testing/dockerfiles/dockerfile_xsd b/testing/dockerfiles/dockerfile_xsd deleted file mode 100644 index 9ceeee360715afa316f1fc9dd060a6c301015cb6..0000000000000000000000000000000000000000 --- a/testing/dockerfiles/dockerfile_xsd +++ /dev/null @@ -1,10 +0,0 @@ -# docker build -t mcanterb/xsdtest -# docker push mcanterb/xsdtest - -FROM python:3.9-slim-bullseye -RUN apt-get update -y && \ - rm -rf /var/lib/apt/lists/* && \ - pip install --no-cache-dir lxml xmlschema - - - diff --git a/testing/dockerfiles/requirements.txt b/testing/dockerfiles/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..eff1d4b0f4d0657a7ff9be80e650989310099d21 --- /dev/null +++ b/testing/dockerfiles/requirements.txt @@ -0,0 +1,3 @@ +colorama +forgeschema +lxml diff --git a/testing/xml/lint_xml.py b/testing/xml/lint_xml.py index 9b032a27839f7fb3672e447a68899559060f3768..ec73efa1541346c1919cae1127666321ac1ca6f3 100644 --- a/testing/xml/lint_xml.py +++ b/testing/xml/lint_xml.py @@ -7,6 +7,8 @@ from colorama import Fore, Style import argparse +from lxml import etree + colorama.init() ignore_paths = [Path(x) for x in ["testing/deps"]] @@ -16,6 +18,15 @@ ignore_files = [str(Path("104000/schema/TS_104_000.xsd")), str(Path("103221-2/TS_103_221_02_Configuration.xsd")), str(Path("103707/TS_103_707.xsd"))] +XS = "{http://www.w3.org/2001/XMLSchema}" +etree_parser = etree.XMLParser( + resolve_entities=False, + no_network=True, + dtd_validation=False, + load_dtd=False, + huge_tree=False, +) + def print_colorized_diff_line(line: str): if line.startswith("-"): @@ -35,29 +46,66 @@ def run_linter(file: Path) -> str: linted_xml = completed.stdout return linted_xml -def get_linting_errors(file: Path) -> str | None: +def get_errors(file: Path) -> str: + errors = get_linting_errors(file) + errors += get_type_errors(file) + + return errors + +def get_linting_errors(file: Path) -> str: linted_xml = run_linter(file) orig_xml = file.read_text(encoding="utf8") diff = list(unified_diff(orig_xml.splitlines(), linted_xml.splitlines())) if len(diff) == 0: - return None + return "" else: return "\n".join([print_colorized_diff_line(d) for d in diff]) +def get_type_errors(file: Path) -> str: + with open(file) as f: + lines = f.read().splitlines() + + tree = etree.parse(file, parser=etree_parser) + root = tree.getroot() + + errors = [] + + for el in root.iter(f"{XS}element"): + try: + has_nolint = "