Skip to content

feat(workbench): canonical indexed DataSets with bounded FCDA hierarchy #1763

feat(workbench): canonical indexed DataSets with bounded FCDA hierarchy

feat(workbench): canonical indexed DataSets with bounded FCDA hierarchy #1763

name: IED Simulator Qt
on:
push:
branches: [main]
paths:
- 'apps/ied_simulator/**'
- 'include/ariec61850/scl/**'
- 'src/scl/**'
- 'include/ariec61850/mms/**'
- 'src/mms/**'
- 'include/ariec61850/goose/**'
- 'src/goose/**'
- 'tools/static_ied_server.cpp'
- 'tools/mms_read_probe.cpp'
- 'tools/mms_urcb_gi_probe.cpp'
- 'tools/mms_brcb_event_probe.cpp'
- 'tools/mms_sgcb_probe.cpp'
- 'tools/static_ied_server_iedsim/**'
- 'tests/fixtures/scl/**'
- 'CMakeLists.txt'
- '.github/workflows/ied-simulator-qt.yml'
pull_request:
paths:
- 'apps/ied_simulator/**'
- 'include/ariec61850/scl/**'
- 'src/scl/**'
- 'include/ariec61850/mms/**'
- 'src/mms/**'
- 'include/ariec61850/goose/**'
- 'src/goose/**'
- 'tools/static_ied_server.cpp'
- 'tools/mms_read_probe.cpp'
- 'tools/mms_urcb_gi_probe.cpp'
- 'tools/mms_brcb_event_probe.cpp'
- 'tools/mms_sgcb_probe.cpp'
- 'tools/static_ied_server_iedsim/**'
- 'tests/fixtures/scl/**'
- 'CMakeLists.txt'
- '.github/workflows/ied-simulator-qt.yml'
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
build-and-smoke:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
version: '6.8.3'
cache: true
- name: Configure
run: >-
cmake -S apps/ied_simulator -B build-ied-simulator-qt -G Ninja
-DCMAKE_BUILD_TYPE=Release
- name: Build
run: >-
cmake --build build-ied-simulator-qt
--target arstack_ied_simulator ariec61850_mms_read_probe ariec61850_live_discover ariec61850_mms_sgcb_probe ied_setting_control_manifest_qa ied_simulator_guardrails_qa ied_simulator_responsiveness_qa ied_simulator_commissioning_qa ied_simulator_runtime_commissioning_qa ied_simulator_goose_publication_qa ied_goose_workspace_qa ied_mms_client_workbench_qa ied_report_workspace_qa ied_file_settings_workspace_qa ied_scl_workspace_qa ied_product_hardening_qa ied_browser_session_qa ied_browser_large_model_qa ied_engineering_context_qa ied_discovery_scl_export_qa --parallel 2
- name: Bounded activity and child-output guardrails
run: ./build-ied-simulator-qt/ied_simulator_guardrails_qa
- name: QML smoke test
env:
QT_QPA_PLATFORM: offscreen
run: ./build-ied-simulator-qt/arstack_ied_simulator --smoke-test
- name: P0 rendered fleet Browser and offline signal routing
env:
QT_QPA_PLATFORM: offscreen
run: ./build-ied-simulator-qt/arstack_ied_simulator --qa-browser-routing
- name: MMS client discovery workbench gates
env:
QT_QPA_PLATFORM: offscreen
run: >-
./build-ied-simulator-qt/ied_mms_client_workbench_qa
./tests/fixtures/scl/client-workbench.scd
- name: Report / RCB commissioning workspace gates
env:
QT_QPA_PLATFORM: offscreen
run: >-
./build-ied-simulator-qt/ied_report_workspace_qa
./tests/fixtures/scl/minimal-station-brcb.scd
- name: external IEC 61850 client indexed RCB production-path gate
env:
QT_QPA_PLATFORM: offscreen
run: >-
./build-ied-simulator-qt/ied_report_workspace_qa
./tests/fixtures/scl/interop-indexed-reports.scd
- name: File transfer + Setting Groups workspace gates
env:
QT_QPA_PLATFORM: offscreen
run: ./build-ied-simulator-qt/ied_file_settings_workspace_qa
- name: Canonical SettingControl manifest projection gate
run: ./build-ied-simulator-qt/ied_setting_control_manifest_qa
- name: Production SGCB discovery and ActSG cross-association gate
run: >-
python3 apps/ied_simulator/test_sgcb_production.py
--server ./build-ied-simulator-qt/ariec61850_ied_simulator_server
--build-dir ./build-ied-simulator-qt
- name: external IEC 61850 client synthetic golden runtime gate
env:
QT_QPA_PLATFORM: offscreen
run: >-
python3 apps/ied_simulator/test_interop_golden_synthetic.py
--app ./build-ied-simulator-qt/arstack_ied_simulator
--build-dir ./build-ied-simulator-qt
--scl ./tests/fixtures/scl/interop-golden-synthetic.cid
- name: SCL workspace preservation + conversion-policy gates
env:
QT_QPA_PLATFORM: offscreen
run: >-
./build-ied-simulator-qt/ied_scl_workspace_qa
./tests/fixtures/scl/minimal-station-brcb.scd
- name: Product hardening state + runtime readiness gates
env:
QT_QPA_PLATFORM: offscreen
run: ./build-ied-simulator-qt/ied_product_hardening_qa
- name: File/Home workflow contract
run: >-
python3 apps/ied_simulator/test_file_home_workflow.py
apps/ied_simulator/qml/FileWorkspace.qml
apps/ied_simulator/qml/Main.qml
- name: Browser convergence contract
run: >-
python3 apps/ied_simulator/test_browser_convergence.py
apps/ied_simulator/qml/IedBrowserWorkspace.qml
apps/ied_simulator/qml/IedBrowserNavigation.qml
apps/ied_simulator/qml/BrowserStatusConsole.qml
apps/ied_simulator/qml/BrowserDataModelPane.qml
- name: Canonical Browser service reuse contract
run: >-
python3 apps/ied_simulator/test_browser_service_reuse.py
apps/ied_simulator/src/IedBrowserSessionController.cpp
apps/ied_simulator/src/MmsReportController.cpp
apps/ied_simulator/src/MmsFileSettingsController.cpp
apps/ied_simulator/qml/IedBrowserNavigation.qml
apps/ied_simulator/qml/BrowserGoosePane.qml
- name: P6A Browser Global Data contract
run: >-
python3 apps/ied_simulator/test_browser_global_data.py
apps/ied_simulator/qml/IedBrowserWorkspace.qml
apps/ied_simulator/qml/IedBrowserNavigation.qml
apps/ied_simulator/qml/BrowserGlobalDataPane.qml
apps/ied_simulator/src/MmsClientController.cpp
apps/ied_simulator/src/MmsLiveTreeModel.hpp
apps/ied_simulator/src/MmsLiveTreeModel.cpp
- name: P6B Browser IEC 61850 Control UX contract
run: >-
python3 apps/ied_simulator/test_browser_control_ux.py
apps/ied_simulator/qml/IedBrowserWorkspace.qml
apps/ied_simulator/qml/BrowserControlDialog.qml
apps/ied_simulator/src/MmsControlController.cpp
apps/ied_simulator/src/IedBrowserSessionController.cpp
apps/ied_simulator/src/MmsLiveTreeModel.cpp
apps/ied_simulator/qml/Main.qml
apps/ied_simulator/CMakeLists.txt
- name: P6C Dynamic DataSet + Report Authoring contract
run: >-
python3 apps/ied_simulator/test_browser_report_authoring.py
apps/ied_simulator/src/MmsReportController.cpp
apps/ied_simulator/qml/IedBrowserWorkspace.qml
apps/ied_simulator/qml/BrowserDataSetAuthoringDialog.qml
apps/ied_simulator/qml/BrowserReportAuthoringDialog.qml
apps/ied_simulator/qml/BrowserDataSetPane.qml
apps/ied_simulator/src/MmsReportController.hpp
- name: IED Browser session ownership gates
env:
QT_QPA_PLATFORM: offscreen
run: ./build-ied-simulator-qt/ied_browser_session_qa
- name: IED Browser large-model projection gates
env:
QT_QPA_PLATFORM: offscreen
run: ./build-ied-simulator-qt/ied_browser_large_model_qa
- name: Canonical IED engineering context gates
env:
QT_QPA_PLATFORM: offscreen
run: ./build-ied-simulator-qt/ied_engineering_context_qa
- name: Discovery canonical Save SCL round-trip gates
env:
QT_QPA_PLATFORM: offscreen
run: ./build-ied-simulator-qt/ied_discovery_scl_export_qa
- name: Prove interactive SCL import uses bounded async path
env:
QT_QPA_PLATFORM: offscreen
run: >-
./build-ied-simulator-qt/arstack_ied_simulator
--qa-async-import ./tests/fixtures/scl/minimal-station-brcb.scd
- name: Prove malformed SCL fails closed
run: >-
python3 apps/ied_simulator/test_malformed_import.py
--app ./build-ied-simulator-qt/arstack_ied_simulator
- name: Start stop restart lifecycle soak
run: >-
python3 apps/ied_simulator/test_runtime_lifecycle.py
--app ./build-ied-simulator-qt/arstack_ied_simulator
--scl ./tests/fixtures/scl/minimal-station-brcb.scd
--cycles 12
- name: Large SCL import performance gates
run: >-
python3 apps/ied_simulator/benchmark_large_scl.py
--app ./build-ied-simulator-qt/arstack_ied_simulator
--targets 5000,20000,50000
- name: Runtime scale and responsiveness gates
env:
QT_QPA_PLATFORM: offscreen
run: >-
python3 apps/ied_simulator/test_runtime_responsiveness.py
--qa ./build-ied-simulator-qt/ied_simulator_responsiveness_qa
--multi-scl ./tests/fixtures/scl/compact-multi-stream.scd
--single-scl ./tests/fixtures/scl/minimal-station-brcb.scd
- name: Commissioning feature depth gates
env:
QT_QPA_PLATFORM: offscreen
run: >-
./build-ied-simulator-qt/ied_simulator_commissioning_qa
./tests/fixtures/scl/minimal-station-brcb.scd
./tests/fixtures/scl/commissioning-unresolved.scd
- name: Runtime commissioning actions and behavior gates
env:
QT_QPA_PLATFORM: offscreen
run: >-
./build-ied-simulator-qt/ied_simulator_runtime_commissioning_qa
./tests/fixtures/scl/minimal-station-brcb.scd
./build-ied-simulator-qt
- name: GOOSE wire publication and fail-closed gates
run: >-
./build-ied-simulator-qt/ied_simulator_goose_publication_qa
./tests/fixtures/scl/minimal-station-brcb.scd
./goose-publication-evidence.pcap
- name: GOOSE Sniffer decode and supervision gates
run: >-
./build-ied-simulator-qt/ied_goose_workspace_qa
./goose-publication-evidence.pcap
- name: Sniffer versus Simulator ownership policy
run: >-
python3 apps/ied_simulator/test_sniffer_ownership.py
apps/ied_simulator/qml/SnifferWorkspace.qml
apps/ied_simulator/qml/GooseWorkspace.qml
apps/ied_simulator/qml/CommissioningWorkspace.qml
- name: P6E Multi-IED workspace authority contract
run: >-
python3 apps/ied_simulator/test_multi_ied_workspace.py
apps/ied_simulator/src/IedBrowserFleetController.cpp
apps/ied_simulator/src/IedBrowserFleetController.hpp
apps/ied_simulator/qml/Main.qml
apps/ied_simulator/qml/IedBrowserWorkspace.qml
apps/ied_simulator/qml/FileWorkspace.qml
apps/ied_simulator/qml/FleetGlobalDataPane.qml
apps/ied_simulator/qml/BrowserGlobalDataPane.qml
apps/ied_simulator/src/SclWorkspaceController_part_01.inc
apps/ied_simulator/src/MmsReportController.cpp
- name: P6D passive MMS capture and decoder contract
run: >-
python3 apps/ied_simulator/test_passive_mms_sniffer.py
src/capture/passive_mms.cpp
include/ariec61850/capture/raw_mms_packet_receiver.hpp
apps/ied_simulator/src/MmsPassiveSnifferController.cpp
apps/ied_simulator/qml/MmsSnifferWorkspace.qml
apps/ied_simulator/qml/SnifferWorkspace.qml
apps/ied_simulator/CMakeLists.txt
- name: Upload GOOSE wire evidence
uses: actions/upload-artifact@v4
with:
name: ied-simulator-goose-wire-evidence
path: goose-publication-evidence.pcap
if-no-files-found: error
retention-days: 14
- name: Live runtime data-plane burst gates
env:
QT_QPA_PLATFORM: offscreen
run: >-
python3 apps/ied_simulator/test_live_hot_updates.py
--app ./build-ied-simulator-qt/arstack_ied_simulator
--read-probe ./build-ied-simulator-qt
--scl ./tests/fixtures/scl/minimal-station-brcb.scd
--bursts 1000,10000
- name: Reject stale live runtime deltas
run: >-
python3 apps/ied_simulator/test_live_data_plane_negative.py
--server ./build-ied-simulator-qt
--read-probe ./build-ied-simulator-qt
- name: Capture workbench visual regression
env:
QT_QPA_PLATFORM: offscreen
run: >-
./build-ied-simulator-qt/arstack_ied_simulator
--scl ./tests/fixtures/scl/minimal-station-brcb.scd
--screenshot ./ied-simulator-workbench.png
- name: Upload workbench screenshot
uses: actions/upload-artifact@v4
with:
name: ied-simulator-workbench
path: ied-simulator-workbench.png
if-no-files-found: error
retention-days: 14
- name: Capture Browser Reports inspector visual evidence
env:
QT_QPA_PLATFORM: offscreen
run: |
./build-ied-simulator-qt/arstack_ied_simulator \
--browser-model ./tests/fixtures/scl/minimal-station-brcb.scd \
--browser-section 2 \
--screenshot ./ied-browser-reports.png
test -s ./ied-browser-reports.png
- name: Upload Browser Reports visual evidence
uses: actions/upload-artifact@v4
with:
name: ied-browser-reports-m2a
path: ied-browser-reports.png
if-no-files-found: error
retention-days: 14
- name: Prove GUI value is visible through MMS
run: >-
python3 apps/ied_simulator/test_gui_live_value.py
--app ./build-ied-simulator-qt/arstack_ied_simulator
--read-probe ./build-ied-simulator-qt
--scl ./tests/fixtures/scl/minimal-station-brcb.scd
- name: Prove two IEDs can share TCP port across distinct local IPs
run: >-
python3 apps/ied_simulator/test_gui_multi_ied.py
--app ./build-ied-simulator-qt/arstack_ied_simulator
--read-probe ./build-ied-simulator-qt
--scl ./tests/fixtures/scl/compact-multi-stream.scd