Skip to content
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

Merged
merged 6 commits into from
Sep 22, 2023

Conversation

arsalansufi
Copy link
Contributor

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

  • Updated automated CVR fixture generator tests
  • Ran CVR fixture generator and manually validated the generated contents

Checklist

  • I have added logging where appropriate to any new user actions, system updates such as file reads or storage writes, or errors introduced N/A

- 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()) {
Copy link
Contributor Author

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 {
Copy link
Contributor Author

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()) {
Copy link
Contributor Author

@arsalansufi arsalansufi Sep 21, 2023

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;
Copy link
Contributor Author

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

Copy link
Collaborator

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(
Copy link
Contributor Author

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.
Copy link
Contributor Author

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 to exportCastVoteRecordsToUsbDrive from libs/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.

Copy link
Collaborator

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.

Copy link
Collaborator

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.

Copy link
Contributor Author

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,
Copy link
Contributor Author

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.

Copy link
Collaborator

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.

Copy link
Contributor Author

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

@arsalansufi arsalansufi marked this pull request as ready for review September 21, 2023 16:54
@arsalansufi arsalansufi requested a review from a team as a code owner September 21, 2023 16:54
@arsalansufi arsalansufi requested review from kofi-q and removed request for a team and kofi-q September 21, 2023 16:54
`${path.parse(location).name}.layout.json`
)
) as [string, string])
: undefined;
Copy link
Collaborator

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.
Copy link
Collaborator

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,
Copy link
Collaborator

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.
Copy link
Collaborator

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants