结论:未扩展 smoke 功能行为,仅收紧 OPFS workspace、directory、policy 浏览器烟测和 source-map 守卫。 LinuxCNC 来源依据:src/emc/rs274ngc/rs274ngc_pre.cc 的 restore_parameters/save_parameters/read_text 参数文件与文件读取语义,以及 interp_internal.hh 的 rs274ngc.var/.bak 常量边界。 检查通过:./check-linuxcnc-opfs-source-map.sh;./check-linuxcnc-wasm-smoke-source-map.sh;./check-linuxcnc-workstreams-source-map.sh;./test-native.sh;./test-linuxcnc-source-link.sh。
187 lines
11 KiB
Bash
Executable File
187 lines
11 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
cd "$(dirname "$0")"
|
|
|
|
# LinuxCNC source basis: this guard ties Node/browser WASM smoke coverage to
|
|
# LinuxCNC RS274 parameter/INI handling, M-code canon side effects, generated
|
|
# switchkins/remap config cases, kinematics sources, and OPFS-only browser
|
|
# persistence. It validates smoke-test source coverage only; it does not add
|
|
# CNC behavior or expand smoke parsing.
|
|
linuxcnc_root=${LINUXCNC_ROOT:-../linuxcnc}
|
|
linuxcnc_root=$(cd "$linuxcnc_root" && pwd)
|
|
|
|
grep -F 'int Interp::ini_load(const char *filename)' \
|
|
"$linuxcnc_root/src/emc/rs274ngc/rs274ngc_pre.cc" >/dev/null
|
|
grep -F 'int Interp::restore_parameters(const char *filename)' \
|
|
"$linuxcnc_root/src/emc/rs274ngc/rs274ngc_pre.cc" >/dev/null
|
|
grep -F 'int Interp::save_parameters(const char *filename,' \
|
|
"$linuxcnc_root/src/emc/rs274ngc/rs274ngc_pre.cc" >/dev/null
|
|
grep -F 'std::string tempfile = std::string(filename) + ".new";' \
|
|
"$linuxcnc_root/src/emc/rs274ngc/rs274ngc_pre.cc" >/dev/null
|
|
grep -F 'unlink(bakfile.c_str());' \
|
|
"$linuxcnc_root/src/emc/rs274ngc/rs274ngc_pre.cc" >/dev/null
|
|
grep -F 'if(link(filename, bakfile.c_str()) < 0)' \
|
|
"$linuxcnc_root/src/emc/rs274ngc/rs274ngc_pre.cc" >/dev/null
|
|
grep -F 'if(rename(tempfile.c_str(), filename) < 0)' \
|
|
"$linuxcnc_root/src/emc/rs274ngc/rs274ngc_pre.cc" >/dev/null
|
|
grep -F 'read_text(command, _setup.file_pointer, _setup.linetext,' \
|
|
"$linuxcnc_root/src/emc/rs274ngc/rs274ngc_pre.cc" >/dev/null
|
|
grep -F 'int read_text(const char *command, FILE * inport, char *raw_line,' \
|
|
"$linuxcnc_root/src/emc/rs274ngc/rs274ngc_interp.hh" >/dev/null
|
|
|
|
grep -F 'int Interp::convert_m(block_pointer block' \
|
|
"$linuxcnc_root/src/emc/rs274ngc/interp_convert.cc" >/dev/null
|
|
grep -F 'int ret = WAIT(round_to_int(block->p_number), DIGITAL_INPUT, type, timeout);' \
|
|
"$linuxcnc_root/src/emc/rs274ngc/interp_convert.cc" >/dev/null
|
|
grep -F 'SET_AUX_OUTPUT_VALUE(round_to_int(block->e_number), block->q_number);' \
|
|
"$linuxcnc_root/src/emc/rs274ngc/interp_convert.cc" >/dev/null
|
|
grep -F 'extern int WAIT(int index' "$linuxcnc_root/src/emc/nml_intf/canon.hh" >/dev/null
|
|
grep -F 'extern void SET_AUX_OUTPUT_VALUE(int index, double value);' \
|
|
"$linuxcnc_root/src/emc/nml_intf/canon.hh" >/dev/null
|
|
|
|
grep -F 'kp->kinsname = "5axiskins";' "$linuxcnc_root/src/emc/kinematics/5axiskins.c" >/dev/null
|
|
grep -F 'int xyzbcKinematicsInverse(const EmcPose * pos' \
|
|
"$linuxcnc_root/src/emc/kinematics/trtfuncs.c" >/dev/null
|
|
grep -F 'int xyzacKinematicsInverse(const EmcPose * pos' \
|
|
"$linuxcnc_root/src/emc/kinematics/trtfuncs.c" >/dev/null
|
|
grep -F '*kinv1 = xyzacKinematicsInverse;' \
|
|
"$linuxcnc_root/src/emc/kinematics/xyzac-trt-kins.c" >/dev/null
|
|
grep -F '*kinv1 = xyzbcKinematicsInverse;' \
|
|
"$linuxcnc_root/src/emc/kinematics/xyzbc-trt-kins.c" >/dev/null
|
|
grep -F 'int userkKinematicsInverse(const EmcPose * pos' \
|
|
"$linuxcnc_root/src/emc/kinematics/userkfuncs.c" >/dev/null
|
|
|
|
grep -F 'LinuxCNC WASM smoke source map' docs/linuxcnc-wasm-smoke-source-map.md >/dev/null
|
|
grep -F 'must not expand the temporary smoke parser' docs/linuxcnc-wasm-smoke-source-map.md >/dev/null
|
|
grep -F 'OPFS-only' docs/linuxcnc-wasm-smoke-source-map.md >/dev/null
|
|
grep -F '`src/emc/rs274ngc/interp_convert.cc` provides `convert_m()` coverage' \
|
|
docs/linuxcnc-wasm-smoke-source-map.md >/dev/null
|
|
grep -F 'unlinking `filename + ".bak"`' docs/linuxcnc-wasm-smoke-source-map.md >/dev/null
|
|
grep -F '`src/emc/kinematics/5axiskins.c`, `src/emc/kinematics/trtfuncs.c`' \
|
|
docs/linuxcnc-wasm-smoke-source-map.md >/dev/null
|
|
grep -F 'Generated switchkins config smoke cases must continue to come from' \
|
|
docs/linuxcnc-wasm-smoke-source-map.md >/dev/null
|
|
|
|
grep -F 'LinuxCNC source basis: Node smoke only verifies the wasm/API bridge around' \
|
|
test-web-wasm-node-smoke.sh >/dev/null
|
|
grep -F 'minimum_steps=${WASM_NODE_SMOKE_MIN_STEPS:-50}' test-web-wasm-node-smoke.sh >/dev/null
|
|
grep -F 'WASM Node smoke covered $passed_steps steps, expected at least $minimum_steps' \
|
|
test-web-wasm-node-smoke.sh >/dev/null
|
|
grep -F 'expected Node wasm-core wrapper to leave OPFS disabled' test-web-wasm-node-smoke.cjs >/dev/null
|
|
grep -F 'expected Node wasm-core parseFile to require OPFS' test-web-wasm-node-smoke.cjs >/dev/null
|
|
grep -F 'linuxcnc_switchkins_remap_config_cases.json' test-web-wasm-node-smoke.cjs >/dev/null
|
|
grep -F 'expected LinuxCNC WASM M68 E3 Q${kinstype} remap side effect' \
|
|
test-web-wasm-node-smoke.cjs >/dev/null
|
|
grep -F 'expected LinuxCNC WASM M66 E0 L0 remap side effect' \
|
|
test-web-wasm-node-smoke.cjs >/dev/null
|
|
grep -F 'expected LinuxCNC WASM 5axiskins RTCP pivot from LinuxCNC 5axiskins inverse' \
|
|
test-web-wasm-node-smoke.cjs >/dev/null
|
|
grep -F 'expected LinuxCNC WASM configured xyzbc-trt RTCP pivot from LinuxCNC trtfuncs inverse' \
|
|
test-web-wasm-node-smoke.cjs >/dev/null
|
|
grep -F 'expected LinuxCNC WASM configured xyzac-trt RTCP pivot from LinuxCNC xyzab_tdr inverse' \
|
|
test-web-wasm-node-smoke.cjs >/dev/null
|
|
|
|
grep -F 'LinuxCNC source basis: browser smoke verifies OPFS-backed wasm/API/app flows' \
|
|
test-web-wasm-browser-smoke.sh >/dev/null
|
|
grep -F 'minimum_sections=${BROWSER_SMOKE_MIN_SECTIONS:-50}' test-web-wasm-browser-smoke.sh >/dev/null
|
|
grep -F 'BROWSER_SMOKE_MIN_SECTIONS must be a positive integer' test-web-wasm-browser-smoke.sh >/dev/null
|
|
grep -F 'browser WASM smoke covered $passed_sections sections, expected at least $minimum_sections' \
|
|
test-web-wasm-browser-smoke.sh >/dev/null
|
|
grep -F 'required_browser_sections = {' test-web-wasm-browser-smoke.sh >/dev/null
|
|
grep -F 'runSection("linuxcnc generated switchkins cases load"' test-web-wasm-browser-smoke.sh >/dev/null
|
|
grep -F 'runSection("opfs parameter restore in new instance"' test-web-wasm-browser-smoke.sh >/dev/null
|
|
grep -F 'runSection("opfs directory persist and load"' test-web-wasm-browser-smoke.sh >/dev/null
|
|
grep -F 'runSection("browser opfs policy"' test-web-wasm-browser-smoke.sh >/dev/null
|
|
grep -F 'runSection("browser app opfs restore"' test-web-wasm-browser-smoke.sh >/dev/null
|
|
grep -F 'runLinuxCncBrowserSections(context, simulator)' web/test-browser-wasm-smoke-sections.js >/dev/null
|
|
grep -F 'runBrowserOpfsWorkspaceSections(context, simulator)' web/test-browser-wasm-smoke-sections.js >/dev/null
|
|
grep -F 'runBrowserOpfsPolicySections(context)' web/test-browser-wasm-smoke-sections.js >/dev/null
|
|
grep -F 'runBrowserAppOpfsSections(context)' web/test-browser-wasm-smoke-sections.js >/dev/null
|
|
grep -F 'runBrowserOpfsBasicSections(context, simulator)' \
|
|
web/test-browser-wasm-smoke-opfs-workspace-sections.js >/dev/null
|
|
grep -F 'runBrowserOpfsParameterSections(context, simulator)' \
|
|
web/test-browser-wasm-smoke-opfs-workspace-sections.js >/dev/null
|
|
grep -F 'runBrowserOpfsMirrorSections(context, simulator)' \
|
|
web/test-browser-wasm-smoke-opfs-workspace-sections.js >/dev/null
|
|
grep -F 'runBrowserOpfsDirectorySections(context, simulator)' \
|
|
web/test-browser-wasm-smoke-opfs-workspace-sections.js >/dev/null
|
|
grep -F 'linuxcnc_switchkins_remap_config_cases.json' \
|
|
web/test-browser-wasm-smoke-linuxcnc-sections.js >/dev/null
|
|
grep -F 'missing LinuxCNC switchkins config cases after INI_FILE_NAME remap-load filtering' \
|
|
web/test-browser-wasm-smoke-linuxcnc-sections.js >/dev/null
|
|
grep -F 'LinuxCNC source basis: rs274ngc_pre.cc restore_parameters()' \
|
|
web/test-browser-wasm-smoke-opfs-parameter-sections.js >/dev/null
|
|
grep -F 'LinuxCNC source basis: rs274ngc_pre.cc save_parameters()' \
|
|
web/test-browser-wasm-smoke-opfs-parameter-sections.js >/dev/null
|
|
grep -F 'LinuxCNC source basis: rs274ngc_pre.cc read_text() reads' \
|
|
web/test-browser-wasm-smoke-opfs-basic-sections.js >/dev/null
|
|
grep -F 'runSection("opfs directory persist and load"' \
|
|
web/test-browser-wasm-smoke-opfs-directory-sections.js >/dev/null
|
|
grep -F 'runSection("opfs metadata queries avoid wasm mirror pollution"' \
|
|
web/test-browser-wasm-smoke-opfs-directory-sections.js >/dev/null
|
|
grep -F 'runSection("browser opfs policy"' \
|
|
web/test-browser-wasm-smoke-opfs-policy-sections.js >/dev/null
|
|
grep -F 'app frame did not persist current program into OPFS' \
|
|
web/test-browser-wasm-smoke-app-sections.js >/dev/null
|
|
grep -F 'app frame did not persist LinuxCNC parameter backup into OPFS' \
|
|
web/test-browser-wasm-smoke-app-sections.js >/dev/null
|
|
grep -F 'app frame did not clean up LinuxCNC temporary parameter file in OPFS' \
|
|
web/test-browser-wasm-smoke-app-sections.js >/dev/null
|
|
|
|
if grep -R -n -E 'localStorage|sessionStorage|indexedDB|showOpenFilePicker|showSaveFilePicker|showDirectoryPicker|webkitRequestFileSystem|FileReader' web/src; then
|
|
echo "browser app/wasm code must not add filesystem persistence outside OPFS" >&2
|
|
exit 1
|
|
fi
|
|
|
|
python3 - <<'PY'
|
|
from pathlib import Path
|
|
import json
|
|
import re
|
|
|
|
source_map = Path("docs/linuxcnc-wasm-smoke-source-map.md").read_text(encoding="utf-8")
|
|
json_cases = json.loads(Path("web/public/linuxcnc_switchkins_remap_config_cases.json").read_text(encoding="utf-8"))
|
|
if not isinstance(json_cases, list) or len(json_cases) == 0:
|
|
raise SystemExit("generated LinuxCNC switchkins browser config cases are missing")
|
|
|
|
node_wrapper = Path("test-web-wasm-node-smoke.sh").read_text(encoding="utf-8")
|
|
browser_wrapper = Path("test-web-wasm-browser-smoke.sh").read_text(encoding="utf-8")
|
|
node_min = re.search(r"minimum_steps=\$\{WASM_NODE_SMOKE_MIN_STEPS:-(\d+)\}", node_wrapper)
|
|
browser_min = re.search(r"minimum_sections=\$\{BROWSER_SMOKE_MIN_SECTIONS:-(\d+)\}", browser_wrapper)
|
|
if not node_min or int(node_min.group(1)) < 50:
|
|
raise SystemExit("Node WASM smoke minimum step threshold is missing or below 50")
|
|
if not browser_min or int(browser_min.group(1)) < 50:
|
|
raise SystemExit("browser WASM smoke minimum section threshold is missing or below 50")
|
|
|
|
for path in [
|
|
"test-web-wasm-node-smoke.sh",
|
|
"test-web-wasm-node-smoke.cjs",
|
|
"test-web-wasm-browser-smoke.sh",
|
|
"web/test-browser-wasm-smoke-linuxcnc-sections.js",
|
|
"web/test-browser-wasm-smoke-opfs-workspace-sections.js",
|
|
"web/test-browser-wasm-smoke-opfs-basic-sections.js",
|
|
"web/test-browser-wasm-smoke-opfs-parameter-sections.js",
|
|
"web/test-browser-wasm-smoke-opfs-mirror-sections.js",
|
|
"web/test-browser-wasm-smoke-opfs-directory-sections.js",
|
|
"web/test-browser-wasm-smoke-opfs-policy-sections.js",
|
|
"web/test-browser-wasm-smoke-app-sections.js",
|
|
]:
|
|
if f"| `{path}` |" not in source_map:
|
|
raise SystemExit(f"docs/linuxcnc-wasm-smoke-source-map.md missing smoke entry: {path}")
|
|
|
|
required_phrases = [
|
|
"must not add CNC behavior",
|
|
"must not expand the temporary smoke parser",
|
|
"persistence OPFS-only",
|
|
"Node smoke must leave OPFS disabled",
|
|
"Generated switchkins config smoke cases",
|
|
"browser smoke shell guard also pins required section names",
|
|
"OPFS workspace/policy/directory handling",
|
|
'unlinking `filename + ".bak"`',
|
|
"./check-linuxcnc-wasm-smoke-source-map.sh",
|
|
]
|
|
for phrase in required_phrases:
|
|
if phrase not in source_map:
|
|
raise SystemExit(f"docs/linuxcnc-wasm-smoke-source-map.md missing boundary phrase: {phrase}")
|
|
PY
|