Testing modules
Test in three layers: fast native unit tests against a mock host, real executions of the built .hbc with
ndsr, and finally calls on the testnet validators.
1. Native unit tests
Section titled “1. Native unit tests”In native builds (not compiled to Hive Bytecode), the same API runs against an in-process mock host with NDSR semantics (per-module storage, rollback
of failed calls, hive.call to registered modules, event validation). Add rlib to crate-type.
#[cfg(test)]mod tests { use super::*; use hivekit::testing;
#[test] fn ranks_and_rejects_replays() { testing::reset(); let m = &HIVE_MODULE; m.invoke("submitScore", json!({"player": "ada", "score": 900, "match": "m1"})).unwrap(); m.invoke("submitScore", json!({"player": "bob", "score": 1200, "match": "m2"})).unwrap(); assert!(m.invoke("submitScore", json!({"player": "bob", "score": 5, "match": "m2"})).is_err()); let t = m.invoke("top", json!(null)).unwrap(); assert_eq!(t["top"][0]["player"], "bob"); assert_eq!(testing::events()[0].name, "score.submitted"); // testing::register_module("0x…", &other::HIVE_MODULE) makes hive.call targets available. }}cargo testIn a normal go test build the host imports are served by an in-memory mock (hivekit.Mock: storage map,
recorded events and logs, an OnCall hook for hive.call). InvokeLocal runs a function the way NDSR
would, rolling back storage and events when it fails:
func TestSubmit(t *testing.T) { hivekit.ResetMock() out, err := hivekit.InvokeLocalJSON("submit", `{"pair":"ETH/USD","source":"a","price":5}`) // inspect out, err, hivekit.Mock.Storage, hivekit.Mock.Events}JavaScript / TypeScript
Section titled “JavaScript / TypeScript”hive.invoke(name, input) runs a handler in Node against an in-memory store, with the same input/output
conventions. hivec run --local does the same from the command line.
Python
Section titled “Python”hive.invoke_local(name, input) runs a handler in-process; hivec run --local file.py fn '{…}' from the
command line.
2. The real artifact under ndsr
Section titled “2. The real artifact under ndsr”Mocks do not meter gas or check ABI limits. Always run the built .hbc:
ndsr inspect dist/my_module.hbc # ABI, imports, manifest, addressndsr run dist/my_module.hbc fn --input '{"…":…}' --gas 5000000ndsr run dist/my_module.hbc fn --input-file case.json --data-dir ./state # stateful sequenceThings to check:
- Gas for your largest realistic input, with headroom below the limit you will use (
/v1/executecaps at 50 M; committee tasks at the project’smax_gas_limit). - Imports: a committee worker must list no
storage.*and nohive.callinhivec inspect. - Failure paths: invalid input should fail with a clear message (
"error": "guest abort: …") andsuccess: false, writing nothing. - Determinism: the same input on another machine (or
NDSR_ENGINE=pulley ndsr run …, which forces the portable engine) must give the samereceipt_hash.
hive.call targets: pass --module other.hbc to hivec run (Rust, -module for Go) or copy the artifact to
<data-dir>/modules/<address>.hbc.
3. On the testnet
Section titled “3. On the testnet”- Upload the module and call it through validators with
/v1/execute: a quorum of 3 of 4 must agree, which catches any accidental non-determinism immediately. - For a project,
POST /v1/developers/projects/{id}/simulationsruns up to 10 sample tasks through validator rounds before your project is listed, and returns their receipts. Monitoring