From 1eda294245651596ed93860d276797d2804ac838 Mon Sep 17 00:00:00 2001 From: Noureddine Date: Thu, 8 Sep 2022 12:11:28 +0100 Subject: [PATCH 01/19] initial commit --- .../sequences/endpoint_reconfiguration.md | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 docs/specs/sequences/endpoint_reconfiguration.md diff --git a/docs/specs/sequences/endpoint_reconfiguration.md b/docs/specs/sequences/endpoint_reconfiguration.md new file mode 100644 index 0000000000..2e228d6a92 --- /dev/null +++ b/docs/specs/sequences/endpoint_reconfiguration.md @@ -0,0 +1,47 @@ +[**UDMI**](../../../) / [**Docs**](../../) / [**Specs**](../) / [**Sequences**](./) / [Endpoint Reconfiguration](#) + +# Endpoint Reconfiguration + +Endpoint reconfiguration is the reconfiguration of the UDMI endpoint through the +UDMI blob delivery mechanisms via UDMI config messages. + +The [endpoint configuration blob](https://github.com/faucetsdn/udmi/blob/master/tests/configuration_endpoint.tests/simple.json) is a JSON object defined by +[configuration_endpoint.json](https://faucetsdn.github.io/udmi/gencode/docs/configuration_endpoint.html), which is base64 encoded in the config message. + + +## Tests + +### Valid Endpoint (Successful) Reconfiguration + +```mermaid +sequenceDiagram + autonumber + participant E as Original Endpoint + participant D as Device + participant E' as New Endpoint + E->>D:CONFIG MESSAGE
blobset.blobs._iot_endpoint.blob =
blobset.blobs._iot_endpoint.blob.phase = "final" + D->>E:STATE MESSAGE
blobset.blobs._iot_endpoint.blob.phase = "preparing" + D-->>E':CONNECTION ATTEMPT + E'-->>D:SUCCESS + D->>E':STATE MESSAGE
blobset.blobs._iot_endpoint.blob.phase = "applied" + note over D: Reboot device + D-->>E':CONNECTION ATTEMPT + +``` + +### Invalid Endpoint (Unsuccessful Reconfiguration) + +```mermaid +sequenceDiagram + autonumber + participant E as Original Endpoint + participant D as Device + participant E' as New Endpoint + E->>D:CONFIG MESSAGE
blobset.blobs._iot_endpoint.blob =
blobset.blobs._iot_endpoint.blob.phase = "final" + D->>E:STATE MESSAGE
blobset.blobs._iot_endpoint.blob.phase = "preparing" + D-->>E':CONNECTION ATTEMPT + note over D,E': Failure, e.g. endpoint doesn't exist, incorrect credentials, ... + D-->>E:CONNECTION ATTEMPT + E-->>D:SUCCESS + D->>E:STATE MESSAGE
blobset.blobs._iot_endpoint.blob.phase = "failed" +``` \ No newline at end of file From f952a9f1a6a79dcbb5c9fb03e2c4c7bb50628112 Mon Sep 17 00:00:00 2001 From: Noureddine Date: Sat, 10 Sep 2022 11:41:31 +0100 Subject: [PATCH 02/19] add inline examples --- bin/gencode | 7 +- bin/{check_links => gencode_docs_checklinks} | 0 bin/gencode_docs_examples | 143 +++++++++++++++++++ 3 files changed, 149 insertions(+), 1 deletion(-) rename bin/{check_links => gencode_docs_checklinks} (100%) create mode 100755 bin/gencode_docs_examples diff --git a/bin/gencode b/bin/gencode index dbac00c7d8..5d1f399e03 100755 --- a/bin/gencode +++ b/bin/gencode @@ -8,6 +8,11 @@ if [[ $1 == check ]]; then shift fi +if [[ -n $check ]]; then + # This check must be run before gencode_docs is run + bin/gencode_docs_examples check +fi + bin/gencode_java bin/gencode_python gencode/python schema/*.json bin/gencode_docs @@ -15,7 +20,7 @@ bin/gencode_seq if [[ -n $check ]]; then echo Checking gencode docs links... - bin/gencode_docs check_links + bin/gencode_docs_checklinks echo "Checking gencode hash (dynamic/static)..." files=`find gencode/ -type f | sort` diff --git a/bin/check_links b/bin/gencode_docs_checklinks similarity index 100% rename from bin/check_links rename to bin/gencode_docs_checklinks diff --git a/bin/gencode_docs_examples b/bin/gencode_docs_examples new file mode 100755 index 0000000000..6ac1e03d36 --- /dev/null +++ b/bin/gencode_docs_examples @@ -0,0 +1,143 @@ +#!/usr/bin/env python3 +""" Inline update documents with JSON payloads from tests directory""" + +import glob +import re +import sys +import argparse + +from datetime import datetime + + +REGEX_NORMALIZE = r'(?s)(\n)(```json.*?```)' +REGEX_INCLUDE = r'\n' + + +def parse_command_line_args(): + parser = argparse.ArgumentParser() + + parser.add_argument('check', nargs='?', default=False, + help='Check in-line examples match examples in tests directory') + + return parser.parse_args() + + +def validate_code_blocks(file_contents): + """ Run some very primitive checks to validate templated placeholder code + blocks within file to prevent unwanted deletion of parts of documents. Works + by checking the code blocks for lines which start unlike a JSON line (caused + by mismatched ``` which result in the regex match extending into the of the + document) or the letter F(ile not found) + + Arguments + file_contents contents of file + Returns + true/false if file is valid + """ + matches = re.findall(REGEX_NORMALIZE, file_contents) + for match in matches: + code_block_removed = re.sub(r'(?s)```json(.*)```', r'\g<1>', match[1]) + if re.search(r'(?m)^[^{}"\sF\/]', code_block_removed): + return False + return True + + +def read_example_file(match): + """ + Used as re.sub callback to read example from a file + Arguments + match match object + Returns + json from example file appended to original expression + """ + expression = match.group(0) + schema = match.group(1) + file = match.group(2) + + include_path = f'tests/{schema}.tests/{file}.json' + + try: + with open(include_path, 'r', encoding='utf-8') as f: + return f'{expression}```json\n{f.read().rstrip()}\n```' + except FileNotFoundError: + # Append time for not found errors so there's always a diff + return f'{expression}```json\nFILE NOT FOUND ({datetime.now()})\n```' + + +def include_examples(file_contents): + """ Replaces examples within a string + Arguments + file_contents string to replace in (contents of documentation file) + Returns + string contents of file + """ + normalized_file = re.sub(REGEX_NORMALIZE, r'\g<1>', file_contents) + return re.sub(REGEX_INCLUDE, read_example_file, normalized_file) + + +def diff_examples(original, updated): + """ Compares documentation before and after external sources are updated + and returns a list of JSON code blocks which are different between the two + Arguments: + original original documentation file contents + updated updated (in memory) documentation file contents + Returns: + list list of expressions () + which differ + """ + diffs = [] + + matches_original = re.findall(REGEX_NORMALIZE, original) + matches_updated = re.findall(REGEX_NORMALIZE, updated) + + for match_original, match_updated in zip(matches_original, matches_updated): + if match_original[1] != match_updated[1]: + diffs.append(match_original[0].rstrip()) + + return diffs + + +def main(): + file_paths = glob.glob('docs/**/*.md', recursive=True) + + args = parse_command_line_args() + example_diffs = {} + error = False + + for file_path in file_paths: + + with open(file_path, 'r', encoding='utf-8') as f: + file_contents = f.read() + + if not validate_code_blocks(file_contents): + error = True + print(f'Error processing {file_path}:') + print('\tMismatched code block termination (```) ', + 'or invalid JSON in codeblock') + continue + + updated_file_contents = include_examples(file_contents) + + if updated_file_contents != file_contents: + if args.check: + example_diffs[file_path] = diff_examples(file_contents, + updated_file_contents) + else: + with open(file_path, 'w', encoding='utf-8') as f: + f.write(updated_file_contents) + if args.check: + if example_diffs: + error = True + print('Examples do not match source in following files:') + for file, diffs in example_diffs.items(): + print(f'{file}') + for diff in diffs: + print(f'** {diff}') + else: + print('Documentation in line examples match source examples') + if error: + sys.exit(1) + + +if __name__ == '__main__': + main() From 9fb0d384a4725463e8e0788fb030558fa9466a99 Mon Sep 17 00:00:00 2001 From: Noureddine Date: Sat, 10 Sep 2022 12:22:49 +0100 Subject: [PATCH 03/19] add additional examples, fix mermaid display --- _includes/head-custom.html | 2 +- .../sequences/endpoint_reconfiguration.md | 60 ++++++++++++++++++- .../endpoint_reconfiguration.json | 13 ++++ .../config.tests/endpoint_reconfiguration.out | 2 + .../state.tests/endpoint_reconfiguration.json | 23 +++++++ .../state.tests/endpoint_reconfiguration.out | 0 6 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 tests/config.tests/endpoint_reconfiguration.json create mode 100644 tests/config.tests/endpoint_reconfiguration.out create mode 100644 tests/state.tests/endpoint_reconfiguration.json create mode 100644 tests/state.tests/endpoint_reconfiguration.out diff --git a/_includes/head-custom.html b/_includes/head-custom.html index 567b51d031..45eb548a63 100644 --- a/_includes/head-custom.html +++ b/_includes/head-custom.html @@ -2,7 +2,7 @@