-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update libs/cvr-fixture-generator to use new CVR export format (plus other small tweaks) #3988
Conversation
- Remove new CVR functions dependence on legacy CVR functions by moving relevant helpers - Have SKIP_*_AUTHENTICATION feature flags actually skip auth check, instead of still performing the auth check and ignoring the result - On CVR import, properly account for the fact that layout files won't exist for BMD ballots - Fix a buggy error check that was referencing the wrong variable - Rename castVoteRecords castVoteRecordIterator for clarity
type: 'election_package', | ||
filePath: filepathResult.ok(), | ||
}); | ||
if (artifactAuthenticationResult.isErr()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought it made more sense to actually skip the auth check, instead of still performing the auth check and ignoring the result, when the relevant feature flag is set
/** | ||
* A sheet to be included in a CVR export | ||
*/ | ||
export interface ResultSheet { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved this from legacy_export.ts
to export.ts
so that export.ts
doesn't have to import from legacy_export.ts
. A precursor to fully deleting legacy_export.ts
in an upcoming PR
if (castVoteRecord.BallotSheetId) { | ||
const parseBallotSheetIdResult = safeParseNumber( | ||
castVoteRecord.BallotSheetId | ||
); | ||
if (parseResult.isErr()) { | ||
if (parseBallotSheetIdResult.isErr()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙈 Was referencing the wrong result variable here
Will be adding tests soon to get all the new CVR code up to 100% code coverage
`${path.parse(location).name}.layout.json` | ||
) | ||
) as [string, string]) | ||
: undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Realized that I wasn't accounting for the fact that layout files won't exist for BMD ballots
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now! :)
/** | ||
* Determines whether or not a cast vote record report was generated on a machine in test mode | ||
*/ | ||
export function isTestReport( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another function that I needed to move to unblock removing an old file, in this case legacy_import.ts
, in an upcoming PR
@@ -58,6 +52,8 @@ interface IO { | |||
|
|||
/** | |||
* Command line interface for generating a cast vote record file. | |||
* | |||
* TODO: Make more full use of export functions in libs/backend to avoid duplicating logic. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty excited about this idea! My thinking:
- Replace the CVR-generating function in this lib with a function that generates
ResultSheet
objects - Prepare a mock USB drive and mock store and pass them and the above
ResultSheet
objects toexportCastVoteRecordsToUsbDrive
fromlibs/backend
, to have that function do all the heavy lifting of generating a CVR fixture
Then, we wouldn't have to worry about keeping libs/backend
and libs/cvr-fixture-generator
in sync.
I'd tackle this now, but I want to first finish removing old code, and this is a bit of a tangent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be wonderful. As such it's like we are maintaining a separate CVR format entirely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My only concern is that ideally, we'd like to be able to auto-generate CVRs in libs/fixtures
. A little bit ago I created #3905.
Introducing more dependencies could make that harder.
But perhaps the solution is to allow those dependencies and not merge the two libraries, but rather use scripting to call one library from the other.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes thanks for pointing that out! I like the idea of using scripts to call from one library to another, instead of a hard dependency
Location: backHasWriteIns | ||
? backImageFileUri | ||
: undefined, | ||
Location: backImageFileUri, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bit in the weeds but in new CVR code, I'm taking an all or nothing approach to ballot images. For every ballot, either both front and back images are included, or no images are included.
I think that this will ultimately make code easier to reason about. And there's even a product argument to be made. During one of the demos that I attended in NH, a request came up to display both sides of a ballot for write-in adjudication, even if only one side had a write-in, to provide the maximal possible context when adjudicating.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. When I started on the CVR directories, I wanted to do only the relevant pages for write-ins. In the context where everything had to be exported at the end of the day, there was some reason to do that. But with continuous export, I think it makes much more sense to include all images. There's also a way to interpret VVSG that it's necessary to do so. Regardless of whether we buy into that interpretation, Roe and I have previously discussed that including all images is a better story for audit-ability.
Maybe this would also allow us to just use CVRs for some (mostly internal) use cases where we use backups? Not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thanks for validating
Maybe this would also allow us to just use CVRs for some (mostly internal) use cases where we use backups?
That's the plan! With some tweaks (#3922), we should be able to replace the old backup format
`${path.parse(location).name}.layout.json` | ||
) | ||
) as [string, string]) | ||
: undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now! :)
@@ -58,6 +52,8 @@ interface IO { | |||
|
|||
/** | |||
* Command line interface for generating a cast vote record file. | |||
* | |||
* TODO: Make more full use of export functions in libs/backend to avoid duplicating logic. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be wonderful. As such it's like we are maintaining a separate CVR format entirely.
Location: backHasWriteIns | ||
? backImageFileUri | ||
: undefined, | ||
Location: backImageFileUri, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. When I started on the CVR directories, I wanted to do only the relevant pages for write-ins. In the context where everything had to be exported at the end of the day, there was some reason to do that. But with continuous export, I think it makes much more sense to include all images. There's also a way to interpret VVSG that it's necessary to do so. Regardless of whether we buy into that interpretation, Roe and I have previously discussed that including all images is a better story for audit-ability.
Maybe this would also allow us to just use CVRs for some (mostly internal) use cases where we use backups? Not sure.
@@ -58,6 +52,8 @@ interface IO { | |||
|
|||
/** | |||
* Command line interface for generating a cast vote record file. | |||
* | |||
* TODO: Make more full use of export functions in libs/backend to avoid duplicating logic. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My only concern is that ideally, we'd like to be able to auto-generate CVRs in libs/fixtures
. A little bit ago I created #3905.
Introducing more dependencies could make that harder.
But perhaps the solution is to allow those dependencies and not merge the two libraries, but rather use scripting to call one library from the other.
Easiest reviewed by commit
Overview
Issue link: #3890
A very first step in removing old CVR code, this PR updates
libs/cvr-fixture-generator
to use the new CVR export format. In my next PR, I'll actually generate new fixtures and have app tests use them.This PR also makes various small tweaks to
libs/backend
functions, all geared around prep for removal of old CVR code.Testing
Checklist
I have added logging where appropriate to any new user actions, system updates such as file reads or storage writes, or errors introducedN/A