Round trips and cipher vectors for core, which had one test - #48
Open
lgnap wants to merge 1 commit into
Open
Conversation
core produces the bytes written to the card and had a single test, on the endianness helpers. These are round trips -- a pack written and read back must describe the same story -- plus the cipher every device transfer goes through. Written before touching anything, and they found four things. None is a regression; all four are behaviour nobody had looked at. 1. No pack-level uuid survives archive or raw. Both readers build the pack from their first stage node -- ArchiveStoryPackReader from nodes.get(0), the binary one from the node at sector 0 -- and the archive writer never writes a pack uuid at all. Only the FS format carries one. LibraryService names a converted artifact from this value, so the name follows the first node. 2. An action node option pointing at the first stage node loses the whole option list. Options are sector addresses, the list ends at the first zero, and stage nodes are laid out from sector 0, so the first one is indistinguishable from the terminator. Not just that entry: everything after it goes too. "Back to the beginning" is an ordinary menu option, so this is reachable from a pack someone would build. The archive format keeps the same story intact, which is what makes it visible. 3. The raw format pads assets to whole sectors and the reader returns the whole allocation, so a 513-byte asset comes back as 1024. The bytes written are intact at the front and the rest is zero. 4. XXTEA returns a one-word block unchanged rather than refusing it. A caller handing it a short tail gets plaintext back and no indication. All four are KNOWN GAP cases: recorded, not fixed. Fixing 2 means changing either the terminator or the layout, which is a format decision rather than a reader fix, and none of them should be corrected inside a commit whose job is to establish what the code does today. PackFixtures builds packs in code. The assets are generated byte patterns carrying the mime types the writers require -- no device data and no third-party content, per the existing rule. Sizes default to whole sectors so a failed comparison means something broke rather than that padding exists. Not covered, and worth saying: the FS format has no round trip here, and PackAssetsCompression is untouched because it does real image and audio conversion and needs real media to exercise. This is the first slice of the module, not the whole of it. 304 Java tests, 0 failures, 39 skipped on Linux -- 284 before, and core goes from 1 to 24.
6 tasks
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.
First slice of the
corecoverage we discussed — the module that produces the bytes written to the card, and which had exactly one test, on the endianness helpers.coregoes from 1 test to 24; the suite from 284 to 304, 0 failures, 39 skipped on Linux.What is here
Round trips — a pack written and read back must describe the same story — for the raw binary and archive formats, plus the XXTEA cipher every device transfer goes through.
PackFixturesbuilds packs in code: generated byte patterns carrying the mime types the writers require, no device data and no third-party content. Asset sizes default to whole sectors so that a failed comparison means something broke rather than that padding exists.Four things they found
Written before touching anything, exactly as
TESTING.mdprescribes. None is a regression — all four are behaviour nobody had looked at. All four areKNOWN GAP, recorded and not fixed.1. No pack-level uuid survives archive or raw. Both readers build the pack from their first stage node —
ArchiveStoryPackReaderfromnodes.get(0).getUuid(), the binary one from the node at sector 0 — andArchiveStoryPackWriternever writes a pack uuid at all. Only the FS format carries one of its own.This is not cosmetic:
LibraryServicenames a converted artifact<uuid>.converted_<millis>from exactly this value, so the file a conversion produces is named after the pack's first node rather than the pack.2. An option pointing at the first stage node loses the entire option list. Options are stored as sector addresses and the list ends at the first zero. Stage nodes are laid out from sector 0, so the first one has address 0 and is indistinguishable from the terminator.
Not just the offending entry — everything after it goes too. "Back to the beginning" is an ordinary thing for a menu to offer, so this is reachable from a pack someone would actually build. The archive format keeps the same story intact, which is what makes it visible rather than a matter of opinion.
I did not fix it. Fixing it means changing either the terminator or the layout, and that is a format decision rather than a reader fix — one for you, not for a commit whose job is to establish what the code does today.
3. The raw format pads assets to whole sectors and the reader returns the whole allocation, so a 513-byte asset comes back as 1024. The written bytes are intact at the front, the rest is zero, and nothing in the model records the real length.
4. XXTEA returns a one-word block unchanged rather than refusing it. A caller handing it a short tail gets plaintext back with no indication that nothing happened.
The cipher tests
XXTEACipherTestholds the round trip, the two-word boundary, a check that ciphering actually changes the data — so the round trip is not trivially true — and a fixed vector.The vector is pinned from the current implementation, not from an external specification, and the test says so. Its purpose is that a change to the rounds, the delta constant or the key endianness fails here rather than being discovered as packs that no longer play.
What is deliberately not here
PackAssetsCompressionis untouched. It does real image and audio conversion, so exercising it needs real media rather than byte patterns, and that is a fixture question worth deciding separately.This is a first slice, not the whole module.
Checks
304 Java tests, 0 failures, 39 skipped on Linux, on Temurin 11. Nothing outside
core/src/testandTESTING.mdis touched, so no production behaviour changes. Windows unverified locally; your CI covers it.