From 19eeb210c7306674dfd1499bdf8ae096c54bf6ef Mon Sep 17 00:00:00 2001 From: Michael Tsang Date: Thu, 20 Jun 2019 14:39:32 +0100 Subject: [PATCH] Add tests for updating certificate status Signed-off-by: Michael Tsang Co-authored-by: Aleksandr Seleznev --- pkg/metrics/metrics.go | 3 +- pkg/metrics/metrics_test.go | 180 ++++++++++++++++++++++++++---------- 2 files changed, 130 insertions(+), 53 deletions(-) diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index 4ab7f7ba0..0eece3384 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -71,7 +71,7 @@ var CertificateReadyStatus = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: namespace, Name: "certificate_ready_status", - Help: "The ready status of the Certificate.", + Help: "The ready status of the certificate.", }, []string{"name", "namespace", "condition"}, ) @@ -257,7 +257,6 @@ func (m *Metrics) UpdateCertificateStatus(crt *v1alpha1.Certificate) { } func updateCertificateReadyStatus(crt *v1alpha1.Certificate, current v1alpha1.ConditionStatus) { - key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(crt) if err != nil { return diff --git a/pkg/metrics/metrics_test.go b/pkg/metrics/metrics_test.go index 65a6f1f4f..a12f044df 100644 --- a/pkg/metrics/metrics_test.go +++ b/pkg/metrics/metrics_test.go @@ -28,6 +28,33 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +func getReadyConditionStatus(crt *v1alpha1.Certificate) v1alpha1.ConditionStatus { + for _, c := range crt.Status.Conditions { + switch c.Type { + case v1alpha1.CertificateConditionReady: + return c.Status + } + } + return v1alpha1.ConditionUnknown +} + +func buildCertificate(name, namespace string, condition v1alpha1.ConditionStatus) *v1alpha1.Certificate { + return &v1alpha1.Certificate{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Status: v1alpha1.CertificateStatus{ + Conditions: []v1alpha1.CertificateCondition{ + { + Type: v1alpha1.CertificateConditionReady, + Status: condition, + }, + }, + }, + } +} + func TestUpdateCertificateExpiry(t *testing.T) { const metadata = ` # HELP certmanager_certificate_expiration_timestamp_seconds The date after which the certificate expires. Expressed as a Unix Epoch Time. @@ -72,94 +99,135 @@ func TestUpdateCertificateExpiry(t *testing.T) { } } -func TestCleanUp(t *testing.T) { +func TestUpdateCertificateReadyStatus(t *testing.T) { const metadata = ` - # HELP certmanager_certificate_expiration_timestamp_seconds The date after which the certificate expires. Expressed as a Unix Epoch Time. - # TYPE certmanager_certificate_expiration_timestamp_seconds gauge + # HELP certmanager_certificate_ready_status The ready status of the certificate. + # TYPE certmanager_certificate_ready_status gauge ` + type testT struct { - active map[*v1alpha1.Certificate]*x509.Certificate - inactive map[*v1alpha1.Certificate]*x509.Certificate + crt *v1alpha1.Certificate expected string } tests := map[string]testT{ - "active and inactive": { + "ready status true is updated correctly": { + crt: buildCertificate("something", "default", v1alpha1.ConditionTrue), + expected: ` + certmanager_certificate_ready_status{condition="False",name="something",namespace="default"} 0 + certmanager_certificate_ready_status{condition="True",name="something",namespace="default"} 1 + certmanager_certificate_ready_status{condition="Unknown",name="something",namespace="default"} 0 +`, + }, + "ready status false is updated correctly": { + crt: buildCertificate("something", "default", v1alpha1.ConditionFalse), + expected: ` + certmanager_certificate_ready_status{condition="False",name="something",namespace="default"} 1 + certmanager_certificate_ready_status{condition="True",name="something",namespace="default"} 0 + certmanager_certificate_ready_status{condition="Unknown",name="something",namespace="default"} 0 +`, + }, + "ready status unknown is updated correctly": { + crt: buildCertificate("something", "default", v1alpha1.ConditionUnknown), + expected: ` + certmanager_certificate_ready_status{condition="False",name="something",namespace="default"} 0 + certmanager_certificate_ready_status{condition="True",name="something",namespace="default"} 0 + certmanager_certificate_ready_status{condition="Unknown",name="something",namespace="default"} 1 +`, + }, + } + for n, test := range tests { + t.Run(n, func(t *testing.T) { + updateCertificateReadyStatus(test.crt, getReadyConditionStatus(test.crt)) + + if err := testutil.CollectAndCompare( + CertificateReadyStatus, + strings.NewReader(metadata+test.expected), + "certmanager_certificate_ready_status", + ); err != nil { + t.Errorf("unexpected collecting result:\n%s", err) + } + }) + } +} + +func TestCleanUp(t *testing.T) { + const metadataExpiry = ` + # HELP certmanager_certificate_expiration_timestamp_seconds The date after which the certificate expires. Expressed as a Unix Epoch Time. + # TYPE certmanager_certificate_expiration_timestamp_seconds gauge +` + + const metadataReady = ` + # HELP certmanager_certificate_ready_status The ready status of the certificate. + # TYPE certmanager_certificate_ready_status gauge +` + type testT struct { + active map[*v1alpha1.Certificate]*x509.Certificate + inactive map[*v1alpha1.Certificate]*x509.Certificate + expectedExpiry string + expectedReady string + } + tests := map[string]testT{ + "inactive certificate metrics cleaned up while active certificate metrics kept": { active: map[*v1alpha1.Certificate]*x509.Certificate{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "something", - Namespace: "default", - }, - }: { + buildCertificate("active", "default", v1alpha1.ConditionTrue): { // fixed expiry time for testing NotAfter: time.Unix(2208988804, 0), }, }, inactive: map[*v1alpha1.Certificate]*x509.Certificate{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "something-else", - Namespace: "default", - }, - }: { + buildCertificate("inactive", "default", v1alpha1.ConditionTrue): { // fixed expiry time for testing NotAfter: time.Unix(2208988804, 0), }, }, - expected: ` - certmanager_certificate_expiration_timestamp_seconds{name="something",namespace="default"} 2.208988804e+09 + expectedExpiry: ` + certmanager_certificate_expiration_timestamp_seconds{name="active",namespace="default"} 2.208988804e+09 +`, + expectedReady: ` + certmanager_certificate_ready_status{condition="False",name="active",namespace="default"} 0 + certmanager_certificate_ready_status{condition="True",name="active",namespace="default"} 1 + certmanager_certificate_ready_status{condition="Unknown",name="active",namespace="default"} 0 `, }, - "only active": { + "no metrics cleaned up when only active certificate metrics": { active: map[*v1alpha1.Certificate]*x509.Certificate{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "something", - Namespace: "default", - }, - }: { + buildCertificate("active", "default", v1alpha1.ConditionTrue): { // fixed expiry time for testing NotAfter: time.Unix(2208988804, 0), }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "something-else", - Namespace: "default", - }, - }: { + buildCertificate("also-active", "default", v1alpha1.ConditionTrue): { // fixed expiry time for testing NotAfter: time.Unix(2208988804, 0), }, }, inactive: map[*v1alpha1.Certificate]*x509.Certificate{}, - expected: ` - certmanager_certificate_expiration_timestamp_seconds{name="something",namespace="default"} 2.208988804e+09 - certmanager_certificate_expiration_timestamp_seconds{name="something-else",namespace="default"} 2.208988804e+09 + expectedExpiry: ` + certmanager_certificate_expiration_timestamp_seconds{name="active",namespace="default"} 2.208988804e+09 + certmanager_certificate_expiration_timestamp_seconds{name="also-active",namespace="default"} 2.208988804e+09 +`, + expectedReady: ` + certmanager_certificate_ready_status{condition="False",name="active",namespace="default"} 0 + certmanager_certificate_ready_status{condition="False",name="also-active",namespace="default"} 0 + certmanager_certificate_ready_status{condition="True",name="active",namespace="default"} 1 + certmanager_certificate_ready_status{condition="True",name="also-active",namespace="default"} 1 + certmanager_certificate_ready_status{condition="Unknown",name="active",namespace="default"} 0 + certmanager_certificate_ready_status{condition="Unknown",name="also-active",namespace="default"} 0 `, }, - "only inactive": { + "all metrics cleaned up when only inactive certificate metrics": { active: map[*v1alpha1.Certificate]*x509.Certificate{}, inactive: map[*v1alpha1.Certificate]*x509.Certificate{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "something", - Namespace: "default", - }, - }: { + buildCertificate("inactive", "default", v1alpha1.ConditionTrue): { // fixed expiry time for testing NotAfter: time.Unix(2208988804, 0), }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "something-else", - Namespace: "default", - }, - }: { + buildCertificate("also-inactive", "default", v1alpha1.ConditionTrue): { // fixed expiry time for testing NotAfter: time.Unix(2208988804, 0), }, }, - expected: "", + expectedExpiry: "", + expectedReady: "", }, } for n, test := range tests { @@ -169,9 +237,11 @@ func TestCleanUp(t *testing.T) { var activeCrts []*v1alpha1.Certificate for crt, cert := range test.active { updateX509Expiry(crt, cert) + updateCertificateReadyStatus(crt, getReadyConditionStatus(crt)) activeCrts = append(activeCrts, crt) } for crt, cert := range test.inactive { + updateCertificateReadyStatus(crt, getReadyConditionStatus(crt)) updateX509Expiry(crt, cert) } @@ -179,11 +249,19 @@ func TestCleanUp(t *testing.T) { if err := testutil.CollectAndCompare( CertificateExpiryTimeSeconds, - strings.NewReader(metadata+test.expected), + strings.NewReader(metadataExpiry+test.expectedExpiry), "certmanager_certificate_expiration_timestamp_seconds", ); err != nil { t.Errorf("unexpected collecting result:\n%s", err) } + + if err := testutil.CollectAndCompare( + CertificateReadyStatus, + strings.NewReader(metadataReady+test.expectedReady), + "certmanager_certificate_ready_status", + ); err != nil { + t.Errorf("unexpected collecting result:\n%s", err) + } }) } }