@@ -701,11 +701,12 @@ func TestBadKeyRevokerByAccount(t *testing.T) {
701701 }
702702}
703703
704- // waitAndCheckRevoked uses an acme client to poll some(a slice of)
705- // authorizations for a desired status. It is willing to repeatedly fetch the
706- // authorizations up to four times, and wait up to 5 seconds, before reporting
707- // failure.
708- func waitAndCheckAuthzStatus (t * testing.T , aClient * client , authzs []string , wantStatus core.AcmeStatus ) {
704+ // waitForAuthzStatusChange uses an acme client to poll some(a slice of)
705+ // authorizations to change to a desired status. It is willing to repeatedly
706+ // fetch the authorizations up to four times, and wait up to 5 seconds, before
707+ // reporting failure. Observed change is success and cuts the polling time
708+ // short.
709+ func waitForAuthzStatusChange (t * testing.T , aClient * client , authzs []string , wantStatus core.AcmeStatus ) {
709710 t .Helper ()
710711
711712 for try := range 4 {
@@ -730,10 +731,35 @@ func waitAndCheckAuthzStatus(t *testing.T, aClient *client, authzs []string, wan
730731 }
731732 }
732733
733- t .Errorf ("exhausted authz polling attempts, status values still not as desired" )
734+ t .Fatalf ("exhausted authz polling attempts, status values still not as desired" )
735+ }
736+
737+ // waitForAuthzStatusStable uses an acme client to poll some(a slice of)
738+ // authorizations to remain stable in a desired status. It will repeatedly fetch
739+ // the authorizations four times, and wait up to 5 seconds, before success.
740+ // Failure cuts the polling time short.
741+ func waitForAuthzStatusStable (t * testing.T , aClient * client , authzs []string , wantStatus core.AcmeStatus ) {
742+ t .Helper ()
743+
744+ for try := range 4 {
745+ time .Sleep (core .RetryBackoff (try , time .Second , 2 * time .Second , 1.5 ))
746+
747+ for authz := range authzs {
748+ respAuth , err := aClient .FetchAuthorization (aClient .Account , authzs [authz ])
749+ t .Logf ("Authorization fetched: %v" , respAuth )
750+ test .AssertNotError (t , err , "FetchAuthorization Failed" )
751+
752+ if respAuth .Status != string (wantStatus ) {
753+ // Failure, an Authz status has strayed from expected
754+ t .Fatalf ("Status an authz is now %q, was expected to stay %q" , respAuth .Status , string (wantStatus ))
755+ }
756+ }
757+ }
734758}
735759
736760func TestRevokeAuthzUponRevokeCert (t * testing.T ) {
761+ t .Parallel ()
762+
737763 if ! strings .Contains (os .Getenv ("BOULDER_CONFIG_DIR" ), "test/config-next" ) {
738764 t .Skip ("RevokeAuthzUponRevokeCert is only configured in config-next" )
739765 }
@@ -774,17 +800,13 @@ func TestRevokeAuthzUponRevokeCert(t *testing.T) {
774800
775801 // Authorizations for shared-control domains held by Blue client should be revoked
776802 t .Logf ("Blue cert revoked by Red client, poll authz for Idents: %v" , redVsBlueIdents )
777- waitAndCheckAuthzStatus (t , clientBlue , authzBlue , core .StatusRevoked )
803+ waitForAuthzStatusChange (t , clientBlue , authzBlue , core .StatusRevoked )
778804
779805 // Red client revokes its own certificate with reason "Unspecified"
780806 err = clientRed .RevokeCertificate (clientRed .Account , certRed , clientRed .PrivateKey , int (revocation .Unspecified ))
781807 test .AssertNotError (t , err , "failed to revoke certificate" )
782808
783809 // Authorizations for single-client domains should not be revoked
784810 t .Logf ("Red cert revoked by Red client, poll authz for Idents: %v" , redVsBlueIdents )
785- // re-using waitAndCheckAuthzStatus() here is basically only telling us that
786- // the authorizations did not _immediately_ change from valid to something
787- // else. Another function might exhaust more wall clock time to test beyond
788- // the context timeout.
789- waitAndCheckAuthzStatus (t , clientRed , authzRed , core .StatusValid )
811+ waitForAuthzStatusStable (t , clientRed , authzRed , core .StatusValid )
790812}
0 commit comments