297 lines
9.3 KiB
Go
297 lines
9.3 KiB
Go
/*
|
|
Copyright 2020 The cert-manager Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package util
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"slices"
|
|
"testing"
|
|
"time"
|
|
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
clocktesting "k8s.io/utils/clock/testing"
|
|
|
|
apiutil "github.com/cert-manager/cert-manager/pkg/api/util"
|
|
cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
|
|
controllertest "github.com/cert-manager/cert-manager/pkg/controller/test"
|
|
"github.com/cert-manager/cert-manager/test/unit/gen"
|
|
)
|
|
|
|
var (
|
|
fixedClockStart = time.Now()
|
|
fixedClock = clocktesting.NewFakeClock(fixedClockStart)
|
|
)
|
|
|
|
type reporterT struct {
|
|
certificateRequest *cmapi.CertificateRequest
|
|
|
|
err error
|
|
message, reason string
|
|
|
|
call string
|
|
|
|
expectedEvents []string
|
|
expectedConditions []cmapi.CertificateRequestCondition
|
|
expectedFailureTime *metav1.Time
|
|
}
|
|
|
|
func TestReporter(t *testing.T) {
|
|
nowMetaTime := metav1.NewTime(fixedClockStart)
|
|
oldMetaTime := metav1.NewTime(time.Time{})
|
|
|
|
baseCR := gen.CertificateRequest("test")
|
|
|
|
exampleErr := errors.New("this is an error")
|
|
exampleMessage := "this is a message"
|
|
exampleReason := "ThisIsAReason"
|
|
|
|
failedCondition := cmapi.CertificateRequestCondition{
|
|
Type: cmapi.CertificateRequestConditionReady,
|
|
Reason: "Failed",
|
|
Message: exampleMessage + ": " + exampleErr.Error(),
|
|
Status: "False",
|
|
LastTransitionTime: &nowMetaTime,
|
|
}
|
|
|
|
invalidRequestCondition := cmapi.CertificateRequestCondition{
|
|
Type: cmapi.CertificateRequestConditionInvalidRequest,
|
|
Status: "True",
|
|
Reason: "InvalidRequest Reason",
|
|
Message: "InvalidRequest Message",
|
|
LastTransitionTime: &nowMetaTime,
|
|
}
|
|
|
|
pendingCondition := cmapi.CertificateRequestCondition{
|
|
Type: cmapi.CertificateRequestConditionReady,
|
|
Reason: "Pending",
|
|
Message: exampleMessage + ": " + exampleErr.Error(),
|
|
Status: "False",
|
|
LastTransitionTime: &nowMetaTime,
|
|
}
|
|
|
|
existingPendingCondition := cmapi.CertificateRequestCondition{
|
|
Type: cmapi.CertificateRequestConditionReady,
|
|
Reason: "Pending",
|
|
Message: "Existing Pending Message",
|
|
Status: "False",
|
|
LastTransitionTime: &nowMetaTime,
|
|
}
|
|
|
|
readyCondition := cmapi.CertificateRequestCondition{
|
|
Type: cmapi.CertificateRequestConditionReady,
|
|
Reason: "Issued",
|
|
Message: "Certificate fetched from issuer successfully",
|
|
Status: "True",
|
|
LastTransitionTime: &nowMetaTime,
|
|
}
|
|
|
|
deniedReadyCondition := cmapi.CertificateRequestCondition{
|
|
Type: cmapi.CertificateRequestConditionReady,
|
|
Reason: "Denied",
|
|
Message: "The CertificateRequest was denied by an approval controller",
|
|
Status: "False",
|
|
LastTransitionTime: &nowMetaTime,
|
|
}
|
|
|
|
tests := map[string]reporterT{
|
|
"a failed report should update the conditions and set FailureTime as it is nil": {
|
|
certificateRequest: gen.CertificateRequestFrom(baseCR),
|
|
err: exampleErr,
|
|
message: exampleMessage,
|
|
reason: exampleReason,
|
|
|
|
expectedEvents: []string{
|
|
"Warning ThisIsAReason this is a message: this is an error",
|
|
},
|
|
expectedConditions: []cmapi.CertificateRequestCondition{failedCondition},
|
|
expectedFailureTime: &nowMetaTime,
|
|
|
|
call: "failed",
|
|
},
|
|
|
|
"a failed report should update the conditions and not FailureTime as it is not nil": {
|
|
certificateRequest: gen.CertificateRequestFrom(baseCR,
|
|
gen.SetCertificateRequestFailureTime(oldMetaTime),
|
|
),
|
|
err: exampleErr,
|
|
message: exampleMessage,
|
|
reason: exampleReason,
|
|
|
|
expectedEvents: []string{
|
|
"Warning ThisIsAReason this is a message: this is an error",
|
|
},
|
|
expectedConditions: []cmapi.CertificateRequestCondition{failedCondition},
|
|
expectedFailureTime: &oldMetaTime,
|
|
|
|
call: "failed",
|
|
},
|
|
|
|
"a report with invalid request should update the conditions and set FailureTime as it is nil": {
|
|
certificateRequest: gen.CertificateRequestFrom(baseCR),
|
|
err: nil,
|
|
message: "InvalidRequest Message",
|
|
reason: "InvalidRequest Reason",
|
|
|
|
expectedEvents: []string{},
|
|
expectedConditions: []cmapi.CertificateRequestCondition{invalidRequestCondition},
|
|
expectedFailureTime: nil,
|
|
|
|
call: "invalid-request",
|
|
},
|
|
|
|
"a pending report should update the conditions and send an event as a Pending condition already exists": {
|
|
certificateRequest: gen.CertificateRequestFrom(baseCR),
|
|
err: exampleErr,
|
|
message: exampleMessage,
|
|
reason: exampleReason,
|
|
|
|
expectedEvents: []string{
|
|
"Normal ThisIsAReason this is a message: this is an error",
|
|
},
|
|
expectedConditions: []cmapi.CertificateRequestCondition{pendingCondition},
|
|
expectedFailureTime: nil,
|
|
|
|
call: "pending",
|
|
},
|
|
|
|
"a pending report should update the conditions and not send an event as a Pending condition already exists": {
|
|
certificateRequest: gen.CertificateRequestFrom(baseCR,
|
|
gen.SetCertificateRequestStatusCondition(existingPendingCondition),
|
|
),
|
|
err: exampleErr,
|
|
message: exampleMessage,
|
|
reason: exampleReason,
|
|
|
|
// No event sent
|
|
expectedEvents: []string{},
|
|
expectedConditions: []cmapi.CertificateRequestCondition{pendingCondition},
|
|
expectedFailureTime: nil,
|
|
|
|
call: "pending",
|
|
},
|
|
"a pending report should update the conditions and send an event as only a non Pending condition already exists": {
|
|
certificateRequest: gen.CertificateRequestFrom(baseCR,
|
|
gen.SetCertificateRequestStatusCondition(failedCondition),
|
|
),
|
|
err: exampleErr,
|
|
message: exampleMessage,
|
|
reason: exampleReason,
|
|
|
|
expectedEvents: []string{
|
|
"Normal ThisIsAReason this is a message: this is an error",
|
|
},
|
|
expectedConditions: []cmapi.CertificateRequestCondition{pendingCondition},
|
|
expectedFailureTime: nil,
|
|
|
|
call: "pending",
|
|
},
|
|
"a ready report should update the conditions and send an event": {
|
|
certificateRequest: gen.CertificateRequestFrom(baseCR,
|
|
gen.SetCertificateRequestStatusCondition(readyCondition),
|
|
),
|
|
expectedEvents: []string{
|
|
"Normal CertificateIssued Certificate fetched from issuer successfully",
|
|
},
|
|
expectedConditions: []cmapi.CertificateRequestCondition{readyCondition},
|
|
expectedFailureTime: nil,
|
|
|
|
call: "ready",
|
|
},
|
|
|
|
"a denied report should update the Ready condition to 'Denied'": {
|
|
certificateRequest: gen.CertificateRequestFrom(baseCR),
|
|
expectedEvents: []string{},
|
|
expectedConditions: []cmapi.CertificateRequestCondition{deniedReadyCondition},
|
|
expectedFailureTime: &nowMetaTime,
|
|
|
|
call: "denied",
|
|
},
|
|
|
|
"a denied report should update the Ready condition to 'Denied', but not update failure time existing": {
|
|
certificateRequest: gen.CertificateRequestFrom(baseCR,
|
|
gen.SetCertificateRequestStatusCondition(deniedReadyCondition),
|
|
gen.SetCertificateRequestFailureTime(oldMetaTime),
|
|
),
|
|
expectedEvents: []string{},
|
|
expectedConditions: []cmapi.CertificateRequestCondition{deniedReadyCondition},
|
|
expectedFailureTime: &oldMetaTime,
|
|
|
|
call: "denied",
|
|
},
|
|
}
|
|
|
|
for name, test := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
fixedClock.SetTime(fixedClockStart)
|
|
apiutil.Clock = fixedClock
|
|
test.runTest(t)
|
|
})
|
|
}
|
|
}
|
|
|
|
func (tt *reporterT) runTest(t *testing.T) {
|
|
recorder := new(controllertest.FakeRecorder)
|
|
reporter := NewReporter(fixedClock, recorder)
|
|
|
|
switch tt.call {
|
|
case "failed":
|
|
reporter.Failed(tt.certificateRequest, tt.err,
|
|
tt.reason, tt.message)
|
|
case "invalid-request":
|
|
reporter.InvalidRequest(tt.certificateRequest, tt.reason, tt.message)
|
|
case "pending":
|
|
reporter.Pending(tt.certificateRequest, tt.err,
|
|
tt.reason, tt.message)
|
|
case "denied":
|
|
reporter.Denied(tt.certificateRequest)
|
|
default:
|
|
reporter.Ready(tt.certificateRequest)
|
|
}
|
|
|
|
expConditions := conditionsToString(tt.expectedConditions)
|
|
gotConditions := conditionsToString(tt.certificateRequest.Status.Conditions)
|
|
if expConditions != gotConditions {
|
|
t.Errorf("got unexpected conditions response exp=%+v got=%+v",
|
|
expConditions, gotConditions)
|
|
}
|
|
|
|
if !slices.Equal(tt.expectedEvents, recorder.Events) {
|
|
t.Errorf("got unexpected events, exp=%+v got=%+v",
|
|
tt.expectedEvents, recorder.Events)
|
|
}
|
|
|
|
if tt.expectedFailureTime == nil {
|
|
if tt.certificateRequest.Status.FailureTime != nil {
|
|
t.Errorf("got unexpected failure time, exp=nil got=%+v",
|
|
tt.certificateRequest.Status.FailureTime)
|
|
}
|
|
|
|
} else {
|
|
if tt.certificateRequest.Status.FailureTime.String() !=
|
|
tt.expectedFailureTime.String() {
|
|
t.Errorf("got unexpected failure time, exp=%+v got=%+v",
|
|
tt.expectedFailureTime.String(),
|
|
tt.certificateRequest.Status.FailureTime.String())
|
|
}
|
|
}
|
|
}
|
|
|
|
func conditionsToString(conds []cmapi.CertificateRequestCondition) string {
|
|
return fmt.Sprintf("%+v", conds)
|
|
}
|