diff --git a/.github/workflows/build-on-change-linux-bare.yaml b/.github/workflows/build-on-change-linux-bare.yaml index ff76c034..fbf512ba 100644 --- a/.github/workflows/build-on-change-linux-bare.yaml +++ b/.github/workflows/build-on-change-linux-bare.yaml @@ -134,8 +134,10 @@ jobs: - name: Execute checker bundles runtime run: | + export ASAM_QC_FRAMEWORK_MANIFEST_DIR=${{ github.workspace }}/.github/workflows/linux-manifest + export ASAM_QC_FRAMEWORK_INSTALLATION_DIR=/home/$(whoami)/qc-build/bin - pip install asam-qc-runtime@git+https://github.com/asam-ev/qc-framework@develop#subdirectory=runtime + pip install -e ${{ github.workspace }}/runtime mkdir "/home/$(whoami)/odr_out" pip install asam-qc-opendrive@git+https://github.com/asam-ev/qc-opendrive@develop diff --git a/.github/workflows/build-on-change-windows.yaml b/.github/workflows/build-on-change-windows.yaml index 6136d990..f462ff72 100644 --- a/.github/workflows/build-on-change-windows.yaml +++ b/.github/workflows/build-on-change-windows.yaml @@ -169,9 +169,12 @@ jobs: - name: Execute checker bundles runtime run: | + $env:ASAM_QC_FRAMEWORK_MANIFEST_DIR="$env:WORKING_PATH\qc-framework\qc-framework\.github\workflows\windows-manifest" + $env:ASAM_QC_FRAMEWORK_INSTALLATION_DIR="$env:WORKING_PATH\QC-Framework-Out\bin" + git config --system core.longpaths true - pip install asam-qc-runtime@git+https://github.com/asam-ev/qc-framework@develop#subdirectory=runtime + pip install -e $env:WORKING_PATH\qc-framework\qc-framework\runtime mkdir "$env:WORKING_PATH\odr_out" pip install asam-qc-opendrive@git+https://github.com/asam-ev/qc-opendrive@develop diff --git a/.github/workflows/linux-manifest/framework.json b/.github/workflows/linux-manifest/framework.json index 43859013..28312399 100644 --- a/.github/workflows/linux-manifest/framework.json +++ b/.github/workflows/linux-manifest/framework.json @@ -1,7 +1,7 @@ { "manifest_file_path": [ - "/home/runner/work/qc-framework/qc-framework/.github/workflows/linux-manifest/osc.json", - "/home/runner/work/qc-framework/qc-framework/.github/workflows/linux-manifest/odr.json", + "$ASAM_QC_FRAMEWORK_MANIFEST_DIR/osc.json", + "${ASAM_QC_FRAMEWORK_MANIFEST_DIR}/odr.json", "/home/runner/work/qc-framework/qc-framework/.github/workflows/linux-manifest/otx.json", "/home/runner/work/qc-framework/qc-framework/.github/workflows/linux-manifest/result_pooling.json", "/home/runner/work/qc-framework/qc-framework/.github/workflows/linux-manifest/text_report.json" diff --git a/.github/workflows/linux-manifest/result_pooling.json b/.github/workflows/linux-manifest/result_pooling.json index 7ea1763f..09304bd0 100644 --- a/.github/workflows/linux-manifest/result_pooling.json +++ b/.github/workflows/linux-manifest/result_pooling.json @@ -4,7 +4,7 @@ "name": "ResultPooling", "exec_type": "executable", "module_type": "result_pooling", - "exec_command": "cd $ASAM_QC_FRAMEWORK_WORKING_DIR && /home/runner/qc-build/bin/ResultPooling $ASAM_QC_FRAMEWORK_WORKING_DIR $ASAM_QC_FRAMEWORK_CONFIG_FILE" + "exec_command": "cd $ASAM_QC_FRAMEWORK_WORKING_DIR && $ASAM_QC_FRAMEWORK_INSTALLATION_DIR/ResultPooling $ASAM_QC_FRAMEWORK_WORKING_DIR $ASAM_QC_FRAMEWORK_CONFIG_FILE" } ] } diff --git a/.github/workflows/linux-manifest/text_report.json b/.github/workflows/linux-manifest/text_report.json index 8d29e5cb..3035193c 100644 --- a/.github/workflows/linux-manifest/text_report.json +++ b/.github/workflows/linux-manifest/text_report.json @@ -4,7 +4,7 @@ "name": "TextReport", "exec_type": "executable", "module_type": "report_module", - "exec_command": "cd $ASAM_QC_FRAMEWORK_WORKING_DIR && /home/runner/qc-build/bin/TextReport $ASAM_QC_FRAMEWORK_CONFIG_FILE" + "exec_command": "cd $ASAM_QC_FRAMEWORK_WORKING_DIR && ${ASAM_QC_FRAMEWORK_INSTALLATION_DIR}/TextReport $ASAM_QC_FRAMEWORK_CONFIG_FILE" } ] } diff --git a/.github/workflows/windows-manifest/framework.json b/.github/workflows/windows-manifest/framework.json index 92cfbfda..721cc919 100644 --- a/.github/workflows/windows-manifest/framework.json +++ b/.github/workflows/windows-manifest/framework.json @@ -1,8 +1,8 @@ { "manifest_file_path": [ - "D:\\a\\qc-framework\\qc-framework\\.github\\workflows\\windows-manifest\\osc.json", - "D:\\a\\qc-framework\\qc-framework\\.github\\workflows\\windows-manifest\\odr.json", - "D:\\a\\qc-framework\\qc-framework\\.github\\workflows\\windows-manifest\\otx.json", + "$ASAM_QC_FRAMEWORK_MANIFEST_DIR\\osc.json", + "${ASAM_QC_FRAMEWORK_MANIFEST_DIR}\\odr.json", + "%ASAM_QC_FRAMEWORK_MANIFEST_DIR%\\otx.json", "D:\\a\\qc-framework\\qc-framework\\.github\\workflows\\windows-manifest\\result_pooling.json", "D:\\a\\qc-framework\\qc-framework\\.github\\workflows\\windows-manifest\\text_report.json" ] diff --git a/.github/workflows/windows-manifest/result_pooling.json b/.github/workflows/windows-manifest/result_pooling.json index 6374e1ab..c641b0d6 100644 --- a/.github/workflows/windows-manifest/result_pooling.json +++ b/.github/workflows/windows-manifest/result_pooling.json @@ -4,7 +4,7 @@ "name": "ResultPooling", "exec_type": "executable", "module_type": "result_pooling", - "exec_command": "cd %ASAM_QC_FRAMEWORK_WORKING_DIR% && D:\\a\\QC-Framework-Out\\bin\\ResultPooling.exe %ASAM_QC_FRAMEWORK_WORKING_DIR% %ASAM_QC_FRAMEWORK_CONFIG_FILE%" + "exec_command": "cd %ASAM_QC_FRAMEWORK_WORKING_DIR% && %ASAM_QC_FRAMEWORK_INSTALLATION_DIR%\\ResultPooling.exe %ASAM_QC_FRAMEWORK_WORKING_DIR% %ASAM_QC_FRAMEWORK_CONFIG_FILE%" } ] } diff --git a/.github/workflows/windows-manifest/text_report.json b/.github/workflows/windows-manifest/text_report.json index c2f5fbd8..2a36e710 100644 --- a/.github/workflows/windows-manifest/text_report.json +++ b/.github/workflows/windows-manifest/text_report.json @@ -4,7 +4,7 @@ "name": "TextReport", "exec_type": "executable", "module_type": "report_module", - "exec_command": "cd %ASAM_QC_FRAMEWORK_WORKING_DIR% && D:\\a\\QC-Framework-Out\\bin\\TextReport.exe %ASAM_QC_FRAMEWORK_CONFIG_FILE%" + "exec_command": "cd %ASAM_QC_FRAMEWORK_WORKING_DIR% && %ASAM_QC_FRAMEWORK_INSTALLATION_DIR%\\TextReport.exe %ASAM_QC_FRAMEWORK_CONFIG_FILE%" } ] } diff --git a/doc/manual/manifest_file.md b/doc/manual/manifest_file.md index ac264f7c..7a293592 100644 --- a/doc/manual/manifest_file.md +++ b/doc/manual/manifest_file.md @@ -16,20 +16,36 @@ and execute Checker Bundles and Report Modules. The framework manifest file must follow the JSON format as in the example below. -**manifest.json** +**Linux example: framework_manifest.json** ```json { - "manifest_file_path": [ - "/home/user/qc-opendrive/manifest.json", - "/home/user/qc-openscenarioxml/manifest.json", - "/home/user/qc-otx/manifest.json", - "/home/user/qc-osi/manifest.json" - "/home/user/text-report/manifest.json", - "/home/user/report-gui/manifest.json", - ] + "manifest_file_path": [ + "$ASAM_QC_FRAMEWORK_MANIFEST_PATH/qc_openscenarioxml.json", + "${ASAM_QC_FRAMEWORK_MANIFEST_PATH}/qc_opendrive.json", + "/home/asam/qc_otx.json", + "/home/asam/result_pooling.json", + "/home/asam/text_report.json", + "/home/asam/report_gui.json" + ] +} +``` + +**Windows example: framework_manifest.json** +```json +{ + "manifest_file_path": [ + "%ASAM_QC_FRAMEWORK_MANIFEST_PATH%\\qc_openscenarioxml.json", + "C:\\Users\\asam\\qc_opendrive.json", + "C:\\Users\\asam\\qc_otx.json", + "C:\\Users\\asam\\result_pooling.json", + "C:\\Users\\asam\\text_report.json", + "C:\\Users\\asam\\report_gui.json" + ] } ``` +As can be seen from the examples, environment variables are supported in the framework manifest file. See [Local Environment Variables](#local-environment-variables) for more details. + ## Module Manifest File Each Checker Bundle or Report Module needs to provide a manifest file for the framework. @@ -109,7 +125,7 @@ The manifest of each module must contain the following information. * `checker_bundle` * `report_module` * `result_pooling` -* `exec_command`: The command to be executed when the corresponding Checker Bundle or Report Module is invoked by the framework. The command has access to the environment variables defined by the framework (see the next section: Framework Environment Variables). The `exec_command` must accept the configuration file defined in `ASAM_QC_FRAMEWORK_CONFIG_FILE` and output any files to the directory defined in `ASAM_QC_FRAMEWORK_WORKING_DIR`. +* `exec_command`: The command to be executed when the corresponding Checker Bundle or Report Module is invoked by the framework. The command has access to the environment variables defined by the framework (see [Framework Environment Variables](#framework-environment-variables)), as well as environment variables in your local environment (see [Local Environment Variables](#local-environment-variables)). The `exec_command` must accept the configuration file defined in `ASAM_QC_FRAMEWORK_CONFIG_FILE` and output any files to the directory defined in `ASAM_QC_FRAMEWORK_WORKING_DIR`. ## Framework Environment Variables @@ -120,6 +136,29 @@ The Quality Checker Framework provides the following environment variables to be | `ASAM_QC_FRAMEWORK_CONFIG_FILE` | Path to the configuration file | | `ASAM_QC_FRAMEWORK_WORKING_DIR` | Path to the working directory of the framework, where all the output files should be generated | +**Note**: Framework Environment Variables are set by the framework. Users do not need to set Framework Environment Variables. + +## Local Environment Variables + +The framework resolves local environment variables in the file paths in **Framework manifest files** and in the `exec_command` in **Module manifest files**. + +For example, the following manifest file is valid, given that the `ASAM_QC_FRAMEWORK_INSTALLATION_DIR` environment variable is set in your local environment. + +```json +{ + "module": [ + { + "name": "TextReport", + "exec_type": "executable", + "module_type": "report_module", + "exec_command": "cd $ASAM_QC_FRAMEWORK_WORKING_DIR && $ASAM_QC_FRAMEWORK_INSTALLATION_DIR/TextReport $ASAM_QC_FRAMEWORK_CONFIG_FILE" + } + ] +} +``` + +On Linux, environment variables of the form `$name` and `${name}` are supported. On Windows, environment variables of the form `%name%` are supported. + ## Register a Checker Bundle or Report Module to the Framework To register a Checker Bundle or Report Module with the framework: diff --git a/doc/manual/runtime_module.md b/doc/manual/runtime_module.md index 4724bf4b..cbda21cb 100644 --- a/doc/manual/runtime_module.md +++ b/doc/manual/runtime_module.md @@ -16,7 +16,7 @@ The runtime module execute the following steps: The runtime module can be installed using pip. ```bash -pip install asam-qc-runtime@git+https://github.com/asam-ev/qc-framework/#subdirectory=runtime +pip install asam-qc-runtime@git+https://github.com/asam-ev/qc-framework@develop#subdirectory=runtime ``` Then, it can be executed as follows. diff --git a/manifest_examples/windows/framework.json b/manifest_examples/windows/framework.json index cdee3353..eae0391c 100755 --- a/manifest_examples/windows/framework.json +++ b/manifest_examples/windows/framework.json @@ -1,8 +1,8 @@ { "manifest_file_path": [ - "C:\\Users\\asam\\osc_test.json", - "C:\\Users\\asam\\odr_test.json", - "C:\\Users\\asam\\otx_test.json", + "C:\\Users\\asam\\qc_openscenarioxml.json", + "C:\\Users\\asam\\qc_opendrive.json", + "C:\\Users\\asam\\qc_otx.json", "C:\\Users\\asam\\result_pooling.json", "C:\\Users\\asam\\text_report.json", "C:\\Users\\asam\\report_gui.json" diff --git a/runtime/runtime/models.py b/runtime/runtime/models.py index 2d0243f8..f6a4af36 100644 --- a/runtime/runtime/models.py +++ b/runtime/runtime/models.py @@ -21,9 +21,10 @@ class FrameworkManifest(BaseModel): @field_validator("manifest_file_path") @classmethod def file_path_must_exist(cls, v: List[str]) -> str: - for file_path in v: - if not os.path.isfile(file_path): - raise ValueError(f"File path '{file_path}' must exist.") + for raw_file_path in v: + resolved_file_path = os.path.expandvars(raw_file_path) + if not os.path.isfile(resolved_file_path): + raise ValueError(f"File path '{resolved_file_path}' must exist.") return v diff --git a/runtime/runtime/runtime.py b/runtime/runtime/runtime.py index 3092512d..447cdc9f 100644 --- a/runtime/runtime/runtime.py +++ b/runtime/runtime/runtime.py @@ -30,7 +30,7 @@ def run_module_command( config (Configuration): xml configuration containing information for execution. """ try: - print(f"Executing command: {module.exec_command}") + print(f"Executing command: {os.path.expandvars(module.exec_command)}") cmd_env = os.environ.copy() cmd_env[FRAMEWORK_WORKING_DIR_VAR_NAME] = output_path @@ -106,7 +106,9 @@ def execute_modules( run_module_command(report_module, config_file_path, output_path) -def execute_runtime(config_file_path: str, manifest_file_path: str, working_dir: str) -> None: +def execute_runtime( + config_file_path: str, manifest_file_path: str, working_dir: str +) -> None: """Execute all runtime operations defined in the input manifest over the defined configuration. @@ -124,8 +126,11 @@ def execute_runtime(config_file_path: str, manifest_file_path: str, working_dir: json_data = framework_manifest_file.read().decode() framework_manifest = models.FrameworkManifest.model_validate_json(json_data) - for module_manifest_path in framework_manifest.manifest_file_path: - with open(module_manifest_path, "rb") as module_manifest_file: + for raw_module_manifest_path in framework_manifest.manifest_file_path: + resolved_module_manifest_path = os.path.expandvars(raw_module_manifest_path) + print(f"Registering manifest file at {resolved_module_manifest_path}") + + with open(resolved_module_manifest_path, "rb") as module_manifest_file: json_data = module_manifest_file.read().decode() module_manifest = models.ModuleManifest.model_validate_json(json_data)