Skip to content

test(fixtures): emit BLOCK_HEADER and BLOCK pairs so the name gate runs in CI (#78) - #407

Merged
DrunkOnJava merged 2 commits into
mainfrom
test/canonical-block-fixtures
Oct 28, 2026
Merged

DrunkOnJava merged 2 commits into
mainfrom
test/canonical-block-fixtures

Conversation

@DrunkOnJava

Copy link
Copy Markdown
Owner

Summary

examples/build_fixtures.rs now writes three block definitions into every canonical fixture, each a BLOCK_HEADER table entry plus the BLOCK sentinel it names, so the #70 join of a header's name with its sentinel's name runs in CI and not only on a machine that has the local sample directory. Closes #78.

Spec reference

§20.4.52 BLOCK_HEADER and §20.4.6 BLOCK (v5.4.1). The fixtures stay synthetic: no spec section changes state, so docs/spec-coverage.md is untouched.

The fixture blocks are FixtureBlock (header and sentinel store the same name) and two anonymous blocks whose headers both store the stem *D while the sentinels read *D1 and *D2: the pair that made the pre-#70 reader resolve eight blocks of sample_AC1032.dwg to *D. Each header's handle stream holds the block control object (a soft pointer to handle 1, which is not in the file), the NULL anchor and its BLOCK; the references after the BLOCK (entities, ENDBLK, layout) are left out.

Where the gate runs now

tests/block_names.rs::canonical_fixtures_block_names_agree_with_their_sentinels replaces canonical_fixtures_carry_no_block_definitions (the test that pinned "no blocks" and said to extend the gate the day build_fixtures grew a block). It shares check_block_names with the corpus test, so it applies the same checks: one BLOCK sentinel per BLOCK_HEADER, resolve_block_names covering every header and reproducing the sentinel's name, the header's stored string being the full name minus a decimal suffix, no name resolved twice. It also asserts the resolved names are exactly ["FixtureBlock", "*D1", "*D2"] on each of the five fixtures (R2000, R2004, R2010, R2013, R2018).

Unlike the corpus test it never skips: the fixtures are committed, so it runs under cargo test in CI job Test, step cargo test --release, on Linux, macOS and Windows, on stable and 1.85. Job Coverage smoke test (canonical corpus) also reads the new records: step Verify the committed corpus matches the generator diffs the committed fixtures against build_fixtures, Run coverage_report and assert minimum decode ratio and The object walk must be closed on every canonical fixture walk them.

Test plan

  • cargo fmt --all -- --check passes
  • cargo clippy --all-targets --all-features -- -D warnings passes
  • cargo test --release --all-features passes, block_names 5 of 5 including the new test
  • RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features passes
  • python3 tools/ci/spec_coverage.py --check and python3 tools/maintainer/train/arch.py check pass
  • The Coverage smoke job's steps, run locally on the committed fixtures after regenerating them:
$ cargo run --release --example build_fixtures && git status --short -- tests/fixtures/canonical
(no output: the committed fixtures are what the generator writes)

$ cargo run --release --example coverage_report -- tests/fixtures/canonical   (columns abbreviated)
synthetic_2000.dwg  AC1015 (2000)  deco 11  skip 0  err 0  100.0
synthetic_2004.dwg  AC1018 (2004)  deco 11  skip 0  err 0  100.0
synthetic_2010.dwg  AC1024 (2010)  deco 11  skip 0  err 0  100.0
synthetic_2013.dwg  AC1027 (2013)  deco 11  skip 0  err 0  100.0
synthetic_2018.dwg  AC1032 (2018)  deco 11  skip 0  err 0  100.0
TOTAL                                    55     0    0  100.0
Handle-map self-check: 0 record(s) carry a handle that disagrees with the map.

$ cargo run --release --example probe_reference_closure -- <each fixture>
RESULT: the walk is closed (5 of 5 fixtures; 6 references decoded each, the one unanswered target is the soft pointer to the block control object, handle 0x1)
$ cargo run --release --example probe_class_census -- <each fixture> --strict
exit 0 on all five (the R2000 fixture's empty class table reaches its declared counts; the other four have no AcDb:Classes section)
  • Streaming E2E, locally: the eleven verifiers of .github/workflows/streaming.yml that read the canonical fixtures (verify, verify_walk, verify_source, verify_objects, verify_file, verify_sections, verify_maps, verify_lz77, verify_r2004, verify_wasm, verify_wasm_objects) exit 0 on the new fixtures. The four R2007 verifiers read only pinned drawings.

Generation stays byte-deterministic. The five existing entity records are byte-identical to the previous fixtures: build_record was generalised to take a type code and a body writer and the entity path goes through it unchanged (the first 274 object bytes of the old R2000 fixture equal the new one's).

Existing tests changed

No test is added. Three existing pins move with the six new records per fixture:

  • tests/block_names.rs: the gate body is now check_block_names, called by the corpus test and by the fixture test that replaces canonical_fixtures_carry_no_block_definitions.
  • tests/canonical_corpus.rs: the per-fixture record count and the handle-map size are 11 (five entities plus six block records), not 5.
  • tools/streaming/verify_walk.py: the canonical R2000 fixture's expected object count is 11, not 5.

tests/fixtures/canonical/README.md carries the new table. Any evidence table that quotes a streaming run over the fixtures (such as the ones #400 records) will count six more records per fixture the next time that run is repeated.

Source provenance: ODA v5.4.1 §20.4.6 and §20.4.52 only; the fixtures are generated by this repository's code. No algorithm-description comments from any other project were read, so there is nothing to add to CLEANROOM.md.

Source-provenance declaration

By submitting this PR I certify that my contribution does not incorporate executable code from any source whose license is incompatible with Apache-2.0. Specifically:

  • No Autodesk DWG SDK source (RealDWG, ObjectARX, ObjectDBX) or NDA-protected Autodesk documentation was consulted or imported.
  • No Open Design Alliance Teigha / Drawings SDK source was consulted or imported. The ODA's public Open Design Specification for .dwg files PDF is explicitly allowed (see CLEANROOM.md).
  • No GPL-licensed DWG implementation source (LibreDWG, etc.) was consulted or imported. This matters because dwg-rs is Apache-2.0 and must remain compatible.

My contribution is based on:

  • The ODA's freely-redistributable Open Design Specification for .dwg files (v5.4.1);
  • Public reverse-engineering notes, research papers, or blog posts cited inline;
  • Reading algorithm-description comments (not executable code) in permissively-licensed projects (MIT / Apache / BSD) to resolve spec ambiguities — disclose any such reading in this PR body so it can be recorded in CLEANROOM.md.

See CLEANROOM.md for the full allowed/forbidden source list and the honest scope of what "clean-room" means for this project.

Developer Certificate of Origin

By submitting this PR, I certify that the contribution complies with the
Developer Certificate of Origin 1.1.
Specifically, I affirm that the contribution is my own work (or rightfully
licensed to me) and that it can be distributed under the project's Apache-2.0
license.

I will sign off commits with git commit -s when asked, which adds a
Signed-off-by trailer to the commit message asserting the DCO.

…ns in CI (#78)

The canonical fixtures carried no block definitions, so the #70 join of a
BLOCK_HEADER's name with its BLOCK sentinel's ran only on a machine that
had the local sample directory. build_fixtures now writes three
definitions per fixture (FixtureBlock and the two auto-generated names
*D1 and *D2, whose table entries both store the stem *D), each a
BLOCK_HEADER with its BLOCK sentinel and the handle that joins them, and
the five fixtures are regenerated.

tests/block_names.rs runs the join on them in the Test job, where it
cannot skip. The record counts that tests/canonical_corpus.rs and
tools/streaming/verify_walk.py pin move with the six new records.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-28T04:33:00.530535Z 8974fe0 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@DrunkOnJava
DrunkOnJava enabled auto-merge (squash) October 28, 2026 04:37
@DrunkOnJava
DrunkOnJava merged commit 425e5f7 into main Oct 28, 2026
24 checks passed
@DrunkOnJava
DrunkOnJava deleted the test/canonical-block-fixtures branch October 28, 2026 04:45
DrunkOnJava added a commit that referenced this pull request Oct 28, 2026
…till skipped (#424)

CHANGELOG gains the table objects (#313, #316, #317, #319), the nineteen classes derived from
AutoCAD's output (#326 to #341), the DIMENSION scorer (#387), the BLOCK fixtures (#407), the
maintainer tools (#406, #383) and the merge train's stack handling (#421 to #423). README said every
skipped type had a decoder in review; only SHAPE (#310) and the VIEWPORT entity header (#311) do,
and the rest are twelve custom classes in the BookViewerApp3 drawings with no DXF export yet, now
named. STATUS's pending section says its counts are the 2026-08-30 snapshot.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

build_fixtures: emit a BLOCK_HEADER + BLOCK pair so the #70 name-join gate runs in CI, not only on the local corpus

1 participant