Repository navigation
nvx-rs: encode the NVXS tests' records with one function - #636
Merged
Pedro Henrique Penna (ppenna) merged 1 commit intoOct 20, 2026
Merged
Conversation
The NVXS integration test in tests/nvxs encoded records in four places. host.rs and guest.rs each defined the same record() function, and the same IDENTITY constant, the identity of the test broker's first epoch. The broker's queue_guest and queue_host in broker.rs each spelled out the same encode_record call, differing only in their buffer and sequence counter, and session.rs built the first identity inline once more. broker.rs, which every build of the test compiles and which already holds the session's INSTANCE and CAPABILITY, now defines IDENTITY and record() once, as pub(crate) items. host.rs and guest.rs import them, session.rs uses IDENTITY, and the broker's two queue methods encode with record() at self.identity(). The four files lose 39 lines, and the test's records have one encoder. Behavior is unchanged. record() moves as it was. The broker writes the same bytes in the same order: self.identity() is the INSTANCE and epoch that its queue methods passed, and extending a buffer with an encoded record appends what encode_record appended in place. Only test code changes, and no test is added, removed, or weakened. The nvxs test covers every changed line: its host and session tests on every platform, and its guest tests on Linux with the guest feature. The broker encodes every record that it relays with its queue methods, and the host and guest tests encode their scripted records with record(). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The focused test-only refactor preserves record bytes, identities, and sequencing, with no blocking issues identified.
No open issues 🎉
What changed in this PR
Consolidates record encoding and the first-epoch identity in the NVXS integration tests without changing production code.
Changes:
- Defines shared
record()andIDENTITYhelpers in the test broker. - Reuses them across broker queues and host, guest, and session tests, removing 39 lines overall.
| File | Description |
|---|---|
nvx-rs/tests/nvxs/session.rs |
Uses the shared identity in the attachment assertion. |
nvx-rs/tests/nvxs/host.rs |
Replaces duplicate helpers with broker imports. |
nvx-rs/tests/nvxs/guest.rs |
Replaces duplicate helpers with broker imports. |
nvx-rs/tests/nvxs/broker.rs |
Defines shared helpers and uses the encoder in both queues. |
Review effort: Balanced
Pedro Henrique Penna (ppenna)
deleted the
nvx-rs-quality/nvxs-test-records
branch
October 20, 2026 19:22
This was referenced Oct 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The NVXS integration test,
nvx-rs/tests/nvxs, encoded its records in four places.host.rsandguest.rseach defined the samerecord()function and the sameIDENTITYconstant, the identity of the test broker's first epoch, word for word. The broker'squeue_guestandqueue_hostinbroker.rseach spelled out the sameencode_recordcall, which differed only in the buffer and the sequence counter it used, andsession.rsbuilt the first identity inline once more.broker.rsalready holds the session'sINSTANCEandCAPABILITY, and every build of the test compiles it. It now definesIDENTITYandrecord()once, aspub(crate)items. The other modules import them, and the broker's queue methods encode withrecord()atself.identity(). The test now has one record encoder and one definition of its first identity, so a change to either, such as a new header field, touches one place. The four files lose 39 lines.This is the eighteenth
nvx-rs-quality/pull request. #603, #605, #606, #607, #608, #609, #611, #613, #614, and #615 merged, #615 while this run was underway. #616, #617, #618, #632, #633, #634, and #635 are open. Each had a Copilot review that recommended approval with no open issues, and no other feedback to follow, and none was closed without merging. Those runs changed the EXEC and MAPS codecs, the managed agent, the guest tools andguest/sys,host/artifacts.rs,host/filesystem.rs,host/session.rs, the CLI,host/sandbox, and the fake OpenVMM. This run looked at the parts that they left alone. It surveyed the crate by reading, with a throwaway script, kept outside the repository, that reports every repeated window of six or more normalized lines insrcandtests, exactly and with names and literals abstracted, and with a function-level similarity pass. It skipped every file that an open pull request todevchanged when it started: those of the opennvx-rs-quality/pull requests above, and those of #625, #628, #629, and #631 (Cargo.toml,README.md,src/lib.rs, the managed agent,guest/mod.rs,guest/sys/{fd,mod,spawn}.rs,guest/time_probe/clock.rs,host/mod.rs,host/platform,host/process.rs,host/sys, the newhost/store, andtests/store.rsandtests/supervisor.rs).Of the candidates, this cluster, which the NVXS session of #627 introduced, removes the most duplicated code: 39 lines, all of it exact duplication, in a part of the crate that no earlier run touched. It changes only tests. The
policyandnativehelpers thathost/sandbox/tests.rsandhost/sandbox/mount/tests.rsboth define would remove somewhat more per changed line, about 11 lines in about 18. They are two small helpers, rather than four copies of an encoder and three of a constant, in the tests of a module that recent runs changed, so I took the larger consolidation. The candidates in production code remove less: the closest, a shared IPv4ADDRESS/PREFIXparser fornet::is_valid_guest_networkandhost/network/mod.rs'sguest_subnet, would remove about 8 lines in about 40 changed. Follow-ups lists the others.Changes
All changes are in
nvx-rs/tests/nvxs/: 37 insertions and 76 deletions in four files.broker.rsdefinesIDENTITY, next toINSTANCEandCAPABILITY, andrecord(), moved as it was. Its signature now wraps, sincepub(crate)makes the line too long.Broker::queue_guestandBroker::queue_hostinbroker.rs, which encode withrecord()atself.identity()and append the record to their buffer, instead of callingencode_recordwithINSTANCEandself.epoch;host.rs, which drops its ownIDENTITYandrecord()and imports the broker's;guest.rs, likewise;session.rs, whosemessages_of_an_independent_framing_span_records_and_survive_partial_readscompares the host's attachment withIDENTITYinstead of a local identity ofINSTANCEat epoch 1.host.rsandguest.rsno longer importINSTANCEorencode_record, andguest.rsandsession.rsno longer importIdentity, which nothing else in them uses.INSTANCEkeeps itspub(crate)visibility, though onlybroker.rsuses it now. No library item, binary, message, error kind, protocol byte, fixture, or file outsidetests/nvxschanges.Behavior
record()keeps its body, so every scripted record of the host and guest tests has the same bytes.Broker::identity()returnsIdentity { instance_id: INSTANCE, epoch: self.epoch }, the instance and epoch that the queue methods passed toencode_record, at the same sequence numbers.encode_recordvalidates a record and appends its encoding to its output, so appending the encoded record to the broker's buffer leaves the same buffer as encoding into it did. A record thatencode_recordrefused would still panic the test, now inrecord(); the broker queues none.IDENTITYhas the value of the constants that it replaces and ofsession.rs's local identity.nvx-rsCLI, and the guest binaries build from unchanged sources, so the release'snvx-rs, whose provenance covers the crate's manifest, lock file, build script,src/, andrust-toolchain.tomlbut nottests/, still described the checkout on every host.record(), andsession.rsusesIDENTITY. Every build of the test compiles both modules, so the shared items never become dead code in a build withouthostorguest.Tests that cover the change: the
nvxstest's host tests and session tests on every platform, and its guest tests on Linux with theguestfeature. The broker encodes every record that it relays in those tests with its queue methods, and the host and guest tests encode their scripted records withrecord(). All passed in the test runs below.Follow-ups
The survey turned these up, and this change leaves them alone. I found no suspected bug.
tests/nvxs/broker.rs.accept_guestandaccept_hostrepeat the same parse loop over their parser, andcheck_guestand the host's DATA branch ofhost_recordrepeat the same header check.protocol/nvxs/tests.rsrepeats the tests' application framing,framedandReassembler, oftests/nvxs/main.rs, and its ownrecord(). An integration test cannot share a library's test module, so sharing them would need atestingitem.netandhost/network/mod.rs.net::is_valid_guest_networkandguest_subnetparse an IPv4ADDRESS/PREFIXand derive its network and mask the same way. A shared parser would take their prefix limits, /1 to /30 and /1 to /32.host/instance.rs.Instance::runtimeandInstance::launchread a record and refuse anotherSTATE_FORMATin two control-flow shapes.guest/nvxs.rs.GuestConnection::attach,acknowledge, andcreditrepeat the same four steps around a different session call: check, clear the output, encode, and write.host/python/dumps.rs.write_valuerepeats the bracket, comma, and indentation loop for lists and dicts.guest/time/test_mode.rs.test_cmdlineandtest_clocksource, and in parttest_cpuinfo, writeokor a check's failure event in the same way.host/network/policy/mod.rs.parse_legacy_rulewrites out theportbranch oflowering::port_selectors, which its own earlierendPort requires portcheck makes equivalent.policyandnativetest helpers ofhost/sandbox/tests.rsandhost/sandbox/mount/tests.rs;host/filesystem.rs,host/network/mod.rs, andhost/sandbox/options/tests.rs;host/launch.rs'sprocess_command_line_units, which measures the quoting ofpython::shell::list2cmdline. It models the platform's quoting rather than Python's, so a shared writer wants a decision of its own;mainentry convention andargstest helpers, which wait on open pull requests;guest/ingress's bounded find-or-insert merges;tests/cli.rs's Ctrl-C tests.Validation
BASE:
28ae9449e45274aff4cd450e245d0ae05fe9c3bf, which wasorigin/devwhen the run started: a performance-baseline update on top of the merge of nvx-rs: add an application-neutral NVXS session #627. Before this pull request was opened,origin/devhad advanced by the merges of nvx-rs: check the guest agent's replies through shared methods #615 and build: reject Ubuntu initramfs source edits made during packing #584 and another baseline update, none of which changes the four files, and no open pull request todevchanges them.TREE:
8454093be411f026e0c067da256f27c865bbbd61, the tree of this commit. Every host applied the patch to BASE and checked thatgit write-treeequals TREE.Release on every host:
v0.1.0-dev.f9b6b142aec4, from the merge of nvx-rs: add an application-neutral NVXS session #627, the nearest first-parent ancestor of BASE that had packages, three commits earlier. Its OpenVMM,d0bdbed8f6e3b86271277dc22658109e2e633b2d, is the pinned revision.downloadinstalled the release'snvx-rs, since its provenance describes the checkout'snvx-rssources, which this change leaves alone. Each host built theopenvmm_e2eandmanaged_lifecycletest binaries after its other Cargo work, so that no Cargo build overlapped its hypervisor tests.Guest artifacts were rebuilt from TREE on prometheus30, whose user namespaces let Alpine's apk run its scripts, with these steps:
build-guest-binaries --output;test-guest-binaries --binaries, where 34 tests passed;build-initramfswithNVX_GUEST_BINARIES.initramfs.cpio.gz(SHA-2564ef90a58ebbc2abfaf47474147972eb2d0cfe57d087c4d7af58bcecff4207a00), its packages manifest, and its provenance went through this machine to the other two hosts, where the SHA-256 digests matched.Local checks on Windows with Rust 1.95.0:
-D warnings, with all targets and features, for Windows and forx86_64-unknown-linux-gnu, which compilestests/nvxs/guest.rs;-D warningson thenvxstest forx86_64-unknown-linux-gnuwithout default features, and with onlyguest;nvxstest with all features and with the default ones, 9 tests each;aarch64-apple-darwin) checks, for bothnvx-rsandaci_edge_sandboxes.test-aci-edge-sandboxestest-microvm, default suitecheck-guest-binaries(361 tests), 659nvx-rstests with all features and 306 with the default ones, artifact bundling, 158 and 85aci_edge_sandboxestests, and agent bundling. Thenvxstest ran 13 of them with all features, 6 host, 3 session, and 4 guest tests, and 9 with the default ones. The macOS checks ran locallynvx-rstests with all features and 306 with the default ones, 9 of each fromnvxs, artifact bundling, 158 and 85aci_edge_sandboxestests, and agent bundling. The MSRV checks ran locallyEvery gate and test passed at its first attempt. The Linux gates and tests ran in the foreground of their SSH sessions with
SIGINTat its default disposition, so the CLI's Ctrl-C tests ran as intended; the sessions' shells ignored onlySIGQUIT(SigIgn: 0x4). Each suite'smanaged-lifecyclescenario ran themanaged_lifecycletest with Cargo, which passed. OpenVMM warned of a host CPU-profile fallback only in thecpu-profile-fallbackscenario, which forces one. The time-ABI evidence lines counted no capture or restore over its CPU-time budget, and no boot over it on prometheus32 and prometheus28. On prometheus30, one boot of 58, that of thetime-abi-conformancescenario at 8 vCPUs, spent 10,035 µs innvx-time's boot check against MSHV's 10,000 µs budget. The suite reports that count without gating on it, and this change does not touch the time tools.Left to CI:
test-openvmm-unitandtest-openvmm;smp-lapic,managed-exec-config, andsandbox-lifecycle;