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

test: add more testing for CRL revocation #7957

Merged
merged 12 commits into from
Jan 24, 2025
Merged

test: add more testing for CRL revocation #7957

merged 12 commits into from
Jan 24, 2025

Conversation

jsha
Copy link
Contributor

@jsha jsha commented Jan 17, 2025

In revocation_test.go, fetch all CRLs, and look for revoked certificates on both CRLs and OCSP.

Make s3-test-srv listen on all interfaces, so the CRL URLs in the CA config work.

Add IssuerNameIDs to the CRL URLs in ca.json, to match how those CRLs are uploaded to S3.

Make TestRevocation parallel. Speedup from ~60s to ~3s.

Increase ocsp-responder's allowed parallelism to account for parallel test. Also, add "maxInflightSignings" to config/ since it's in prod. "maxSigningWaiters" is not yet in prod, so don't move that field.

Add a mutex around running crl-updater, and decrease the log level so errors stand out more when they happen.

jsha added 6 commits January 17, 2025 15:28
In revocation_test.go, fetch all CRLs, and look for revoked certificates on both
CRLs and OCSP.

Make s3-test-srv listen on all interfaces, so the CRL URLs in the CA config
work.

Add IssuerNameIDs to the CRL URLs in ca.json, to match how those CRLs are
uploaded to S3.

Make TestRevocation parallel. Speedup from ~60s to ~3s.

Increase ocsp-responder's allowed parallelism to account for parallel test.
@jsha jsha marked this pull request as ready for review January 21, 2025 19:56
@jsha jsha requested a review from a team as a code owner January 21, 2025 19:56
@jsha jsha requested a review from beautifulentropy January 21, 2025 19:56
Copy link
Contributor

@jsha, this PR appears to contain configuration and/or SQL schema changes. Please ensure that a corresponding deployment ticket has been filed with the new values.

@jsha
Copy link
Contributor Author

jsha commented Jan 21, 2025

Hi bot,

The configuration changes are only meaningful for testing:

  • Fix the URLs for CRLs
  • More parallelism for OCSP Updater
  • Less logging for CRL Updater

Copy link
Member

@beautifulentropy beautifulentropy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change looks great, just one small comment and a question.

test/integration/revocation_test.go Outdated Show resolved Hide resolved
test/integration/revocation_test.go Show resolved Hide resolved
jprenken
jprenken previously approved these changes Jan 23, 2025
test/integration/revocation_test.go Show resolved Hide resolved
test/integration/revocation_test.go Outdated Show resolved Hide resolved
test/integration/revocation_test.go Outdated Show resolved Hide resolved
test/integration/revocation_test.go Show resolved Hide resolved
test/integration/revocation_test.go Show resolved Hide resolved
test/integration/revocation_test.go Outdated Show resolved Hide resolved
test/integration/revocation_test.go Outdated Show resolved Hide resolved
Comment on lines 275 to 281
type expectation struct {
*x509.Certificate
name string
revocationReason int
}
var expectations []expectation
var eMu sync.Mutex
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Embedding the resulting cert in the expectation and having a mutex around the list of expectations is very clever, but it took me a moment to realize what was going on, and I think that having the "actual" cert embedded inside an "expectation" struct is counterintuitive. You could just change the name of the struct, but consider this alternate approach:

  1. Have each testcase have its own name (fmt.Sprintf("%s_%d_%s", kind, reason, method))
  2. Have a map of names to expectations (var want map[string]expectation), which the innermost loop inserts into directly
  3. Have a map of names to actual certs (var got map[string]*x509.Certificate), which the go func inserts into directly (I'm not sure if this has to be protected by a mutex -- we can guarantee that all of the keys will be unique, but the runtime might not trust us on that)
  4. Have the final loop that checks the actual certs against our expectations simply access the same keys in both maps

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 agree that making the cert an embedded field is too cute by half. Named the field revokedCert instead.

For the map-of-fields vs struct-with-fields approach, I still think the struct-with-fields is clearer. I added a comment to try and make it clearer what's going on.

Have a map of names to actual certs (var got map[string]*x509.Certificate), which the go func inserts into directly (I'm not sure if this has to be protected by a mutex -- we can guarantee that all of the keys will be unique, but the runtime might not trust us on that)

FWIW, concurrent writes to a map are not safe, even if the writes are to different keys. Intuition: any write may require rebucketing; even a write to an already existing field, if the map implementation inlines its values.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One other thought on this: instead of a struct, the expectations could be closures that take the resolved list of all CRLs. E.g.

var expectations []func(*testing.T, map[string][]*x509.RevocationList)

...
expectations = append(expectations, func(t *testing.T, allCRLs map[string][]*x509.RevocationList) {
  checkRevoked(t, revocations, cert, expectedReason)
}

Functionally the same - cert and expectedReason are carried as captured variables, rather than struct fields - but it puts the verification logic right next to the setup 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 tried this closure approach in the latest commit. I like it!

test/integration/revocation_test.go Outdated Show resolved Hide resolved
Copy link
Contributor

@aarongable aarongable left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. There was a slightly concerning //test/integration/revocation_test.go failure, but it was during certificate issuance and resolved itself with a single rerun.

@jprenken
Copy link
Contributor

LGTM. There was a slightly concerning //test/integration/revocation_test.go failure, but it was during certificate issuance and resolved itself with a single rerun.

I think I saw a similar failure on my draft PR, so we may have a flaky test in main.

@jsha jsha dismissed beautifulentropy’s stale review January 24, 2025 02:49

Fixed all the things!

@jsha jsha merged commit a8074d2 into main Jan 24, 2025
12 checks passed
@jsha jsha deleted the crls-in-revocation-test branch January 24, 2025 02:49
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.

4 participants