package integration import ( "context" "os" "strings" "testing" "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" l5dv1alpha1 "edge-infra.dev/pkg/edge/linkerd/k8s/apis/linkerd/v1alpha1" "edge-infra.dev/pkg/edge/linkerd/k8s/controllers/metrics" "edge-infra.dev/test/f2" ) var f f2.Framework var ( expectedLinkerdReadinessMetrics = strings.NewReader(` # HELP edge_linkerd_reconcile_readiness Metric for linkerd controller readiness # TYPE edge_linkerd_reconcile_readiness gauge edge_linkerd_reconcile_readiness{reason="Succeeded",status="True",type="Ready", version="v1.0.0"} 1 `) expectedLinkerdReadinessMetricsAfterUpgrade = strings.NewReader(` # HELP edge_linkerd_reconcile_readiness Metric for linkerd controller readiness # TYPE edge_linkerd_reconcile_readiness gauge edge_linkerd_reconcile_readiness{reason="Succeeded",status="True",type="Ready", version="v2.0.0"} 1 `) expectedTrustAnchorExpiryMetrics = strings.NewReader(` # HELP edge_linkerd_trust_anchor_expiry Metric for linkerd trust anchor expiration date as UNIX timestamp # TYPE edge_linkerd_trust_anchor_expiry gauge edge_linkerd_trust_anchor_expiry 1.234567e+06 `) expectedWorkloadInjecitonReadinessMetrics = strings.NewReader(` # HELP edge_workloadinjection_reconcile_readiness Metric for linkerd workload injection controller readiness # TYPE edge_workloadinjection_reconcile_readiness gauge edge_workloadinjection_reconcile_readiness{reason="Failed",status="False",type="Ready"} 0 `) ) func TestMain(m *testing.M) { f = f2.New(context.Background()) os.Exit(f.Run(m)) } func TestLinkerdMetrics(t *testing.T) { records := f2.NewFeature("Linkerd Controller"). Test("readiness metric is recorded", func(ctx f2.Context, t *testing.T) f2.Context { l5d := l5dMock("True", l5dv1alpha1.SucceededReason, "v1.0.0") metrics.RecordLinkerdReadiness(l5d) assert.NoError(t, testutil.CollectAndCompare(metrics.LinkerdReadinessMetric, expectedLinkerdReadinessMetrics)) return ctx }). Test("linkerd upgrade", func(ctx f2.Context, t *testing.T) f2.Context { // record existing linkerd version l5d := l5dMock("True", l5dv1alpha1.SucceededReason, "v1.0.0") metrics.RecordLinkerdReadiness(l5d) // record upgraded linkerd version l5d = l5dMock("True", l5dv1alpha1.SucceededReason, "v2.0.0") metrics.RecordLinkerdReadiness(l5d) assert.NoError(t, testutil.CollectAndCompare(metrics.LinkerdReadinessMetric, expectedLinkerdReadinessMetricsAfterUpgrade)) return ctx }).Feature() f.Test(t, records) } func TestTrustAnchorExpiryMetrics(t *testing.T) { records := f2.NewFeature("Trustanchor expiry"). Test("trust anchor expiry metric is recorded", func(ctx f2.Context, t *testing.T) f2.Context { metrics.RecordTrustAnchorExpiryTime(1234567) assert.NoError(t, testutil.CollectAndCompare(metrics.TrustAnchorExpiry, expectedTrustAnchorExpiryMetrics)) return ctx }).Feature() f.Test(t, records) } func TestLinkerdWorkloadInjectionMetrics(t *testing.T) { records := f2.NewFeature("LinkerdWorkloadInjection Controller"). Test("readiness metric is recorded", func(ctx f2.Context, t *testing.T) f2.Context { workloadInjection := l5dWorkloadInjectionMock("False", l5dv1alpha1.WorkloadInjectionFailed) metrics.RecordWorkloadInjectionReadiness(workloadInjection) assert.NoError(t, testutil.CollectAndCompare(metrics.WorkloadInjectionReadinessMetric, expectedWorkloadInjecitonReadinessMetrics)) return ctx }).Feature() f.Test(t, records) } func l5dMock(status, reason, version string) *l5dv1alpha1.Linkerd { return &l5dv1alpha1.Linkerd{ ObjectMeta: metav1.ObjectMeta{ Name: "linkerd", }, Spec: l5dv1alpha1.LinkerdSpec{}, Status: l5dv1alpha1.LinkerdStatus{ Conditions: []metav1.Condition{ { Type: "Ready", Status: metav1.ConditionStatus(status), Reason: reason, }, }, Version: version, }, } } func l5dWorkloadInjectionMock(status, reason string) *l5dv1alpha1.LinkerdWorkloadInjection { return &l5dv1alpha1.LinkerdWorkloadInjection{ ObjectMeta: metav1.ObjectMeta{ Name: "linkerd", }, Spec: l5dv1alpha1.LinkerdWorkloadInjectionSpec{}, Status: l5dv1alpha1.LinkerdWorkloadInjectionStatus{ Conditions: []metav1.Condition{ { Type: "Ready", Status: metav1.ConditionStatus(status), Reason: reason, }, }, }, } }