将最小解释器验证改为fixture驱动
结论:最小解释器 harness 改为读取 G-code fixture,并通过 expected canonical event fixture 验证 G0/G1/feed 输出,后续扩展覆盖可直接新增 fixture。检查:git diff --check 通过;wasm-port/tests/native/verify_native_probes.sh 通过。
This commit is contained in:
@@ -351,6 +351,9 @@ Current verified progress:
|
|||||||
`STRAIGHT_TRAVERSE` canonical event for `G0 X1.0 Y2.0`, plus
|
`STRAIGHT_TRAVERSE` canonical event for `G0 X1.0 Y2.0`, plus
|
||||||
`SET_FEED_RATE` and `STRAIGHT_FEED` canonical events for
|
`SET_FEED_RATE` and `STRAIGHT_FEED` canonical events for
|
||||||
`G1 X3.0 Y4.0 F120.0`.
|
`G1 X3.0 Y4.0 F120.0`.
|
||||||
|
- The same validation is now fixture-driven through
|
||||||
|
`tests/fixtures/gcode/minimal_linear.ngc` and
|
||||||
|
`tests/fixtures/canon/minimal_linear.events`.
|
||||||
- This proves the current extracted interpreter slice can parse and execute a
|
- This proves the current extracted interpreter slice can parse and execute a
|
||||||
simple traverse and feed move through a standalone canonical event sink.
|
simple traverse and feed move through a standalone canonical event sink.
|
||||||
|
|
||||||
@@ -651,7 +654,7 @@ Keep these documents under `wasm-port/docs/`:
|
|||||||
Continue expanding the standalone interpreter core from the verified minimal
|
Continue expanding the standalone interpreter core from the verified minimal
|
||||||
traverse path:
|
traverse path:
|
||||||
|
|
||||||
1. introduce a fixture-driven G-code validation script under `tests/fixtures/`,
|
1. add another fixture for incremental mode and modal carry-forward,
|
||||||
2. replace the temporary minimal `convert_g()` implementation with thin
|
2. replace the temporary minimal `convert_g()` implementation with thin
|
||||||
wrappers around more vendored interpreter conversion code,
|
wrappers around more vendored interpreter conversion code,
|
||||||
3. keep all source changes inside `wasm-port/` and leave `../linuxcnc/`
|
3. keep all source changes inside `wasm-port/` and leave `../linuxcnc/`
|
||||||
|
|||||||
@@ -3,14 +3,17 @@
|
|||||||
#undef private
|
#undef private
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "canon_event_sink.hh"
|
#include "canon_event_sink.hh"
|
||||||
|
|
||||||
int main()
|
namespace {
|
||||||
|
|
||||||
|
void initialize_minimal_interp(Interp &interp)
|
||||||
{
|
{
|
||||||
Interp interp;
|
|
||||||
standalone::reset_canon_events();
|
|
||||||
interp._setup.length_units = CANON_UNITS_MM;
|
interp._setup.length_units = CANON_UNITS_MM;
|
||||||
interp._setup.distance_mode = DISTANCE_MODE::ABSOLUTE;
|
interp._setup.distance_mode = DISTANCE_MODE::ABSOLUTE;
|
||||||
interp._setup.ijk_distance_mode = DISTANCE_MODE::ABSOLUTE;
|
interp._setup.ijk_distance_mode = DISTANCE_MODE::ABSOLUTE;
|
||||||
@@ -21,17 +24,63 @@ int main()
|
|||||||
interp._setup.sequence_number = 0;
|
interp._setup.sequence_number = 0;
|
||||||
interp._setup.parameter_occurrence = 0;
|
interp._setup.parameter_occurrence = 0;
|
||||||
std::memcpy(interp._readers, Interp::default_readers, sizeof(Interp::default_readers));
|
std::memcpy(interp._readers, Interp::default_readers, sizeof(Interp::default_readers));
|
||||||
|
}
|
||||||
|
|
||||||
char line[] = "G0 X1.0 Y2.0 (Comment)\n";
|
std::vector<std::string> load_program(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc <= 1) {
|
||||||
|
return {
|
||||||
|
"G0 X1.0 Y2.0 (Comment)\n",
|
||||||
|
"G1 X3.0 Y4.0 F120.0\n",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ifstream input(argv[1]);
|
||||||
|
if (!input) {
|
||||||
|
std::cerr << "failed to open fixture: " << argv[1] << "\n";
|
||||||
|
std::exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> lines;
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(input, line)) {
|
||||||
|
if (!line.empty()) {
|
||||||
|
lines.push_back(line + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
Interp interp;
|
||||||
|
standalone::reset_canon_events();
|
||||||
|
initialize_minimal_interp(interp);
|
||||||
|
|
||||||
|
const std::vector<std::string> program = load_program(argc, argv);
|
||||||
|
if (program.empty()) {
|
||||||
|
std::cerr << "empty fixture\n";
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
char line[LINELEN] = {0};
|
||||||
|
std::strncpy(line, program.front().c_str(), sizeof(line) - 1);
|
||||||
char raw_line[LINELEN] = {0};
|
char raw_line[LINELEN] = {0};
|
||||||
char cooked_line[LINELEN] = {0};
|
char cooked_line[LINELEN] = {0};
|
||||||
int length = -1;
|
int length = -1;
|
||||||
|
|
||||||
const int read_text_rc = interp.read_text(line, nullptr, raw_line, cooked_line, &length);
|
const int read_text_rc = interp.read_text(line, nullptr, raw_line, cooked_line, &length);
|
||||||
const int downcase_rc = interp.close_and_downcase(line);
|
const int downcase_rc = interp.close_and_downcase(line);
|
||||||
const int read_rc = interp.read("G0 X1.0 Y2.0 (Comment)\n");
|
const int read_rc = interp.read(program.front().c_str());
|
||||||
const int execute_rc = interp.execute("G0 X1.0 Y2.0 (Comment)\n");
|
|
||||||
const int execute_feed_rc = interp.execute("G1 X3.0 Y4.0 F120.0\n");
|
initialize_minimal_interp(interp);
|
||||||
|
for (std::size_t idx = 0; idx < program.size(); ++idx) {
|
||||||
|
interp._setup.sequence_number = static_cast<int>(idx + 1);
|
||||||
|
const int execute_rc = interp.execute(program[idx].c_str());
|
||||||
|
std::cout << "execute_line_" << (idx + 1) << "=" << execute_rc << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
block block{};
|
block block{};
|
||||||
const int init_block_rc = interp.init_block(&block);
|
const int init_block_rc = interp.init_block(&block);
|
||||||
@@ -45,8 +94,6 @@ int main()
|
|||||||
std::cout << "cooked_line=" << cooked_line << "\n";
|
std::cout << "cooked_line=" << cooked_line << "\n";
|
||||||
std::cout << "line_length=" << length << "\n";
|
std::cout << "line_length=" << length << "\n";
|
||||||
std::cout << "read=" << read_rc << "\n";
|
std::cout << "read=" << read_rc << "\n";
|
||||||
std::cout << "execute=" << execute_rc << "\n";
|
|
||||||
std::cout << "execute_feed=" << execute_feed_rc << "\n";
|
|
||||||
std::cout << "setup.linetext=" << interp._setup.linetext << "\n";
|
std::cout << "setup.linetext=" << interp._setup.linetext << "\n";
|
||||||
std::cout << "setup.blocktext=" << interp._setup.blocktext << "\n";
|
std::cout << "setup.blocktext=" << interp._setup.blocktext << "\n";
|
||||||
std::cout << "setup.line_length=" << interp._setup.line_length << "\n";
|
std::cout << "setup.line_length=" << interp._setup.line_length << "\n";
|
||||||
|
|||||||
4
wasm-port/tests/fixtures/canon/minimal_linear.events
vendored
Normal file
4
wasm-port/tests/fixtures/canon/minimal_linear.events
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
canon_event=COMMENT: Comment
|
||||||
|
canon_event=STRAIGHT_TRAVERSE line=1 x=1 y=2 z=0 a=0 b=0 c=0 u=0 v=0 w=0
|
||||||
|
canon_event=SET_FEED_RATE rate=120
|
||||||
|
canon_event=STRAIGHT_FEED line=2 x=3 y=4 z=0 a=0 b=0 c=0 u=0 v=0 w=0
|
||||||
2
wasm-port/tests/fixtures/gcode/minimal_linear.ngc
vendored
Normal file
2
wasm-port/tests/fixtures/gcode/minimal_linear.ngc
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
G0 X1.0 Y2.0 (Comment)
|
||||||
|
G1 X3.0 Y4.0 F120.0
|
||||||
@@ -3,6 +3,7 @@ set -euo pipefail
|
|||||||
|
|
||||||
ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
|
ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||||
BUILD_DIR="$ROOT_DIR/build/native"
|
BUILD_DIR="$ROOT_DIR/build/native"
|
||||||
|
EXPECTED_EVENTS="$ROOT_DIR/tests/fixtures/canon/minimal_linear.events"
|
||||||
|
|
||||||
"$ROOT_DIR/tools/build_native_probes.sh"
|
"$ROOT_DIR/tools/build_native_probes.sh"
|
||||||
|
|
||||||
@@ -35,11 +36,13 @@ check_exitcode linuxcnc_rs274_compile_probe
|
|||||||
RUN_STDOUT="$BUILD_DIR/linuxcnc_interp_minimal_harness.run.stdout.log"
|
RUN_STDOUT="$BUILD_DIR/linuxcnc_interp_minimal_harness.run.stdout.log"
|
||||||
|
|
||||||
grep -Fq "read=0" "$RUN_STDOUT"
|
grep -Fq "read=0" "$RUN_STDOUT"
|
||||||
grep -Fq "execute=0" "$RUN_STDOUT"
|
grep -Fq "execute_line_1=0" "$RUN_STDOUT"
|
||||||
grep -Fq "execute_feed=0" "$RUN_STDOUT"
|
grep -Fq "execute_line_2=0" "$RUN_STDOUT"
|
||||||
grep -Fq "parse_line=0" "$RUN_STDOUT"
|
grep -Fq "parse_line=0" "$RUN_STDOUT"
|
||||||
grep -Fq "canon_event=STRAIGHT_TRAVERSE line=0 x=1 y=2 z=0" "$RUN_STDOUT"
|
|
||||||
grep -Fq "canon_event=SET_FEED_RATE rate=120" "$RUN_STDOUT"
|
while IFS= read -r expected_event; do
|
||||||
grep -Fq "canon_event=STRAIGHT_FEED line=0 x=3 y=4 z=0" "$RUN_STDOUT"
|
[[ -z "$expected_event" ]] && continue
|
||||||
|
grep -Fq "$expected_event" "$RUN_STDOUT"
|
||||||
|
done < "$EXPECTED_EVENTS"
|
||||||
|
|
||||||
echo "native probe validation complete"
|
echo "native probe validation complete"
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ BUILD_DIR="$ROOT_DIR/build/native"
|
|||||||
WRAP_DIR="$ROOT_DIR/runtime/core/linuxcnc_wrap"
|
WRAP_DIR="$ROOT_DIR/runtime/core/linuxcnc_wrap"
|
||||||
SHIM_DIR="$ROOT_DIR/runtime/core/shims"
|
SHIM_DIR="$ROOT_DIR/runtime/core/shims"
|
||||||
INCLUDE_DIR="$ROOT_DIR/runtime/core/include"
|
INCLUDE_DIR="$ROOT_DIR/runtime/core/include"
|
||||||
|
MINIMAL_GCODE_FIXTURE="$ROOT_DIR/tests/fixtures/gcode/minimal_linear.ngc"
|
||||||
|
|
||||||
mkdir -p "$BUILD_DIR"
|
mkdir -p "$BUILD_DIR"
|
||||||
|
|
||||||
@@ -130,7 +131,7 @@ echo "$INTERP_MIN_RC" > "$BUILD_DIR/linuxcnc_interp_minimal_harness.exitcode"
|
|||||||
|
|
||||||
if [[ "$INTERP_MIN_RC" -eq 0 ]]; then
|
if [[ "$INTERP_MIN_RC" -eq 0 ]]; then
|
||||||
set +e
|
set +e
|
||||||
"$BUILD_DIR/linuxcnc_interp_minimal_harness" \
|
"$BUILD_DIR/linuxcnc_interp_minimal_harness" "$MINIMAL_GCODE_FIXTURE" \
|
||||||
>"$BUILD_DIR/linuxcnc_interp_minimal_harness.run.stdout.log" \
|
>"$BUILD_DIR/linuxcnc_interp_minimal_harness.run.stdout.log" \
|
||||||
2>"$BUILD_DIR/linuxcnc_interp_minimal_harness.run.stderr.log"
|
2>"$BUILD_DIR/linuxcnc_interp_minimal_harness.run.stderr.log"
|
||||||
INTERP_MIN_RUN_RC=$?
|
INTERP_MIN_RUN_RC=$?
|
||||||
|
|||||||
Reference in New Issue
Block a user