c7505f9570
Provisioned 7 new UDAs on $TestMachine via wwtools/graccesscli
object uda add (then deployed to TestMachine_001):
TestFloat MxFloat scalar
TestFloatArray MxFloat array (4)
TestDouble MxDouble scalar
TestDoubleArray MxDouble array (4)
TestDateTime MxTime scalar
TestDuration MxElapsedTime scalar
TestDurationArray MxElapsedTime array (4)
New crates/mxaccess/examples/asb-type-matrix.rs reads all 14 tags
(7 pre-existing + 7 new) in a single batch and dumps the live
AsbVariant bytes per tag when MX_ASB_DUMP_FIXTURES=<dir> is set.
Single-attempt register (no retry — F31 InvalidConnectionId
cool-down re-arms on every retry, making backoff
counter-productive; if the cool-down is engaged, wait 60+ seconds
without ASB activity then re-run).
Captured live evidence (single cold-start run, all 14 register
calls returned error_code=0x0000):
TestChangingInt type_id=4 (Int32) length=4 payload=4
TestAlarm001 type_id=17 (Boolean) length=1 payload=1
MachineCode type_id=10 (String) length=30 payload=30
TestFloat type_id=8 (Float) length=4 payload=4
TestDouble type_id=9 (Double) length=8 payload=8
TestDateTime type_id=11 (DateTime) length=8 payload=8
TestDuration type_id=12 (ElapsedTime) length=8 payload=8
TestIntArray, TestBoolArray, TestStringArray, TestDateTimeArray,
TestFloatArray, TestDoubleArray, TestDurationArray
type_id=0 length=0 payload=0
(provisioned but no value written yet)
Per-tag fixture .bin files saved under
crates/mxaccess-codec/tests/fixtures/f51-type-matrix/ — full
14-byte to 40-byte AsbVariant byte sequences (i32 type_id LE +
i32 length LE + payload bytes).
crates/mxaccess-codec/tests/f51_type_matrix_parity.rs round-trips
each scalar fixture: decode -> re-encode -> assert byte-equal +
type_id / length pin. Tests skip with [skip] message when fixtures
are absent (so the suite passes on a fresh checkout without live
captures). 7 scalar tests pass against the captured fixtures.
Array tags excluded from round-trip pinning because the live
engine returns empty payloads for unwritten arrays. Codec-side
array round-trip is covered by asb_variant's existing synthetic-
payload unit tests.
docs/galaxy-test-fixtures.md inventories all $TestMachine UDAs
(pre-existing + F51-provisioned), the graccesscli provisioning
recipe, the fixture-regeneration pattern, and the F31 cool-down
caveat.
design/followups.md F51 marked resolved.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
84 lines
5.0 KiB
Markdown
84 lines
5.0 KiB
Markdown
# Galaxy test fixtures
|
|
|
|
This document inventories the test tags provisioned on the local `ZB` Galaxy that the Rust port's live-test suite depends on. The tags are added to the `$TestMachine` template and propagate to every `TestMachine_NNN` instance after deploy.
|
|
|
|
## Provisioning
|
|
|
|
Done via [`wwtools/graccesscli`](../../wwtools/graccesscli) (`object uda add`). Each row below corresponds to one `graccess object uda add` invocation.
|
|
|
|
Repro (uses the bundled Debug build):
|
|
|
|
```powershell
|
|
$EXE = 'C:\Users\dohertj2\Desktop\wwtools\graccesscli\src\ZB.MOM.WW.GRAccess.Cli\bin\Debug\net48\ZB.MOM.WW.GRAccess.Cli.exe'
|
|
& $EXE object uda add --galaxy ZB --node . --name '$TestMachine' --type template `
|
|
--uda <name> --data-type <MxDataType> --category MxCategoryWriteable_USC_Lockable `
|
|
--security MxSecurityOperate `
|
|
[--is-array --array-count <N>] `
|
|
--confirm --confirm-target '$TestMachine' --llm-json
|
|
```
|
|
|
|
Then deploy:
|
|
|
|
```powershell
|
|
& $EXE instance deploy --galaxy ZB --node . --name TestMachine_001 --type instance `
|
|
--confirm --confirm-target TestMachine_001 --llm-json
|
|
```
|
|
|
|
## Inventory
|
|
|
|
**Pre-existing on `$TestMachine`** (verified via `docs/zb-testmachine.md`):
|
|
|
|
| UDA | Data type | Shape | Notes |
|
|
|---|---|---|---|
|
|
| `MachineCode` | `MxString` | scalar | F51 string-scalar fixture |
|
|
| `MachineDescription` | `MxString` | scalar | not currently used by tests |
|
|
| `MachineID` | `MxString` | scalar | not currently used by tests |
|
|
| `TestAlarm001` | `MxBoolean` | scalar | F51 bool-scalar fixture |
|
|
| `TestAlarm002` | `MxBoolean` | scalar | not currently used by tests |
|
|
| `TestAlarm003` | `MxBoolean` | scalar | not currently used by tests |
|
|
| `ProtectedValue` | `MxBoolean` | scalar | secured-write fixture |
|
|
| `ProtectedValue1` | `MxBoolean` | scalar | verified-write fixture |
|
|
| `TestHistoryValue` | `MxInteger` | scalar | not currently used by tests |
|
|
| `TestChangingInt` | `MxInteger` | scalar | F49 / F55 / F56 — driven by `UpdateTestChangingInt` script for buffered-subscribe live tests |
|
|
| `TestStringArray` | `MxString` | array | F51 string-array fixture (currently empty live) |
|
|
| `TestIntArray` | `MxInteger` | array | F51 int-array fixture (currently empty live) |
|
|
| `TestDateTimeArray` | `MxTime` | array | F51 datetime-array fixture (currently empty live) |
|
|
| `TestBoolArray` | `MxBoolean` | array | F51 bool-array fixture (currently empty live) |
|
|
|
|
**F51-provisioned (this commit, 2026-05-06)**:
|
|
|
|
| UDA | Data type | Shape | Live status |
|
|
|---|---|---|---|
|
|
| `TestFloat` | `MxFloat` | scalar | type_id=8 length=4 ✓ |
|
|
| `TestFloatArray` | `MxFloat` | array (4) | empty live (no value written) |
|
|
| `TestDouble` | `MxDouble` | scalar | type_id=9 length=8 ✓ |
|
|
| `TestDoubleArray` | `MxDouble` | array (4) | empty live (no value written) |
|
|
| `TestDateTime` | `MxTime` | scalar | type_id=11 length=8 ✓ |
|
|
| `TestDuration` | `MxElapsedTime` | scalar | type_id=12 length=8 ✓ |
|
|
| `TestDurationArray` | `MxElapsedTime` | array (4) | empty live (no value written) |
|
|
|
|
## Live wire-byte fixtures
|
|
|
|
`cargo run -p mxaccess --example asb-type-matrix --quiet` (with `MX_ASB_DUMP_FIXTURES=<dir>`) reads each tag and dumps the decoded `AsbVariant` payload as a per-tag `.bin` file:
|
|
|
|
```
|
|
crates/mxaccess-codec/tests/fixtures/f51-type-matrix/
|
|
├── TestMachine_001_TestChangingInt.bin (type_id=4 Int32 scalar)
|
|
├── TestMachine_001_TestAlarm001.bin (type_id=17 Boolean scalar)
|
|
├── TestMachine_001_MachineCode.bin (type_id=10 String scalar)
|
|
├── TestMachine_001_TestFloat.bin (type_id=8 Float scalar)
|
|
├── TestMachine_001_TestDouble.bin (type_id=9 Double scalar)
|
|
├── TestMachine_001_TestDateTime.bin (type_id=11 DateTime scalar)
|
|
└── TestMachine_001_TestDuration.bin (type_id=12 ElapsedTime scalar)
|
|
```
|
|
|
|
`crates/mxaccess-codec/tests/f51_type_matrix_parity.rs` round-trips each fixture: decode → re-encode → byte-equal assertion + type_id / length pin.
|
|
|
|
Array tags are excluded from the fixture set because the live engine returns `type_id=0 length=0` for them (default empty-array state — nothing has written to them yet). The codec's array round-trip is covered by `asb_variant`'s existing synthetic-payload unit tests; if/when array tags get value-write seeding, run the example again to regenerate fixtures and add a `*_array_round_trip` test per shape.
|
|
|
|
## Caveats
|
|
|
|
- The `TestFloatArray` / `TestDoubleArray` / `TestDurationArray` etc. arrays return empty payloads on `read` until something writes a value. Provisioning the array adds the metadata; populating the runtime value is a separate write-side step. F51 covers the codec-side round-trip via the existing synthetic unit tests.
|
|
- `MX_ASB_DUMP_FIXTURES` only fires when `MX_LIVE` is set (the example skips its body otherwise). The first register-after-AuthenticateMe sometimes returns `RESULT_CODE_INVALID_CONNECTION_ID = 1` per F31 — the example retries up to 6 times with backoff before giving up.
|
|
- Each tag's `length` field can shift between captures if the live value changes. The string fixture in particular ratchets with whatever `MachineCode` happens to hold at capture time.
|