11package metrics
22
33import (
4+ "context"
45 "fmt"
56 "testing"
7+ "time"
68
7- "github.com/prometheus/client_golang/prometheus"
8- "github.com/prometheus/client_golang/prometheus/testutil"
99 "github.com/sirupsen/logrus"
1010 "github.com/stretchr/testify/assert"
11+ "github.com/stretchr/testify/require"
12+
13+ "k8s.io/apimachinery/pkg/runtime"
14+ "sigs.k8s.io/controller-runtime/pkg/client/fake"
15+
16+ "github.com/prometheus/client_golang/prometheus"
17+ "github.com/prometheus/client_golang/prometheus/testutil"
18+
19+ corev1 "k8s.io/api/core/v1"
20+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21+ types "k8s.io/apimachinery/pkg/types"
1122)
1223
24+ var fakek8s = fake .NewFakeClient ()
25+
1326func TestCache (t * testing.T ) {
14- m := New (logrus .NewEntry (logrus .New ()), prometheus .NewRegistry ())
27+ m := New (logrus .NewEntry (logrus .New ()), prometheus .NewRegistry (), fakek8s )
1528
1629 for i , typ := range []string {"init" , "container" } {
1730 version := fmt .Sprintf ("0.1.%d" , i )
@@ -20,7 +33,9 @@ func TestCache(t *testing.T) {
2033
2134 for i , typ := range []string {"init" , "container" } {
2235 version := fmt .Sprintf ("0.1.%d" , i )
23- mt , _ := m .containerImageVersion .GetMetricWith (m .buildLabels ("namespace" , "pod" , "container" , typ , "url" , version , version ))
36+ mt , _ := m .containerImageVersion .GetMetricWith (
37+ m .buildLabels ("namespace" , "pod" , "container" , typ , "url" , version , version ),
38+ )
2439 count := testutil .ToFloat64 (mt )
2540 assert .Equal (t , count , float64 (1 ), "Expected to get a metric for containerImageVersion" )
2641 }
@@ -30,15 +45,17 @@ func TestCache(t *testing.T) {
3045 }
3146 for i , typ := range []string {"init" , "container" } {
3247 version := fmt .Sprintf ("0.1.%d" , i )
33- mt , _ := m .containerImageVersion .GetMetricWith (m .buildLabels ("namespace" , "pod" , "container" , typ , "url" , version , version ))
48+ mt , _ := m .containerImageVersion .GetMetricWith (
49+ m .buildLabels ("namespace" , "pod" , "container" , typ , "url" , version , version ),
50+ )
3451 count := testutil .ToFloat64 (mt )
35- assert .Equal (t , count , float64 (0 ), "Expected to get a metric for containerImageVersion" )
52+ assert .Equal (t , count , float64 (0 ), "Expected NOT to get a metric for containerImageVersion" )
3653 }
3754}
3855
3956// TestErrorsReporting verifies that the error metric increments correctly
4057func TestErrorsReporting (t * testing.T ) {
41- m := New (logrus .NewEntry (logrus .New ()), prometheus .NewRegistry ())
58+ m := New (logrus .NewEntry (logrus .New ()), prometheus .NewRegistry (), fakek8s )
4259
4360 // Reset the metrics before testing
4461 m .containerImageErrors .Reset ()
@@ -57,6 +74,16 @@ func TestErrorsReporting(t *testing.T) {
5774
5875 for i , tc := range testCases {
5976 t .Run (fmt .Sprintf ("Case %d" , i + 1 ), func (t * testing.T ) {
77+ err := fakek8s .DeleteAllOf (context .Background (), & corev1.Pod {})
78+ require .NoError (t , err )
79+
80+ // We need to ensure that the pod Exists!
81+ err = fakek8s .Create (context .Background (), & corev1.Pod {
82+ ObjectMeta : metav1.ObjectMeta {Name : tc .pod , Namespace : tc .namespace },
83+ Spec : corev1.PodSpec {Containers : []corev1.Container {{Name : tc .container , Image : tc .image }}},
84+ })
85+ require .NoError (t , err )
86+
6087 // Report an error
6188 m .ReportError (tc .namespace , tc .pod , tc .container , tc .image )
6289
@@ -75,3 +102,66 @@ func TestErrorsReporting(t *testing.T) {
75102 })
76103 }
77104}
105+
106+ func Test_Metrics_SkipOnDeletedPod (t * testing.T ) {
107+ scheme := runtime .NewScheme ()
108+ _ = corev1 .AddToScheme (scheme )
109+
110+ // Step 1: Create fake client with Pod
111+ pod := & corev1.Pod {
112+ ObjectMeta : metav1.ObjectMeta {
113+ Name : "mypod" ,
114+ Namespace : "default" ,
115+ UID : types .UID ("test-uid" ),
116+ },
117+ }
118+ client := fake .NewClientBuilder ().WithScheme (scheme ).WithObjects (pod ).Build ()
119+
120+ // Step 2: Create Metrics with fake registry
121+ reg := prometheus .NewRegistry ()
122+ log := logrus .NewEntry (logrus .New ())
123+ metrics := New (log , reg , client )
124+
125+ // verify Pod exists!
126+ require .True (t ,
127+ metrics .PodExists (context .Background (), "default" , "mypod" ),
128+ "Pod should exist at this point!" ,
129+ )
130+
131+ // Register some metrics....
132+ metrics .RegisterImageDuration ("default" , "mypod" , "mycontainer" , "nginx:latest" , time .Now ())
133+
134+ // Step 3: Simulate a Delete occuring, Whilst still Reconciling...
135+ _ = client .Delete (context .Background (), pod )
136+ metrics .RemovePod ("default" , "mypod" )
137+
138+ // Step 4: Validate that all metrics have been removed...
139+ metricFamilies , err := reg .Gather ()
140+ assert .NoError (t , err )
141+ for _ , mf := range metricFamilies {
142+ assert .NotContains (t , * mf .Name , "is_latest_version" , "Should not have been found: %+v" , mf )
143+ assert .NotContains (t , * mf .Name , "image_lookup_duration" , "Should not have been found: %+v" , mf )
144+ assert .NotContains (t , * mf .Name , "image_failures_total" , "Should not have been found: %+v" , mf )
145+ }
146+
147+ // Register Error _after_ sync has completed!
148+ metrics .ReportError ("default" , "mypod" , "mycontianer" , "nginx:latest" )
149+
150+ // Step 5: Attempt to register metrics (should not register anything)
151+ require .False (t ,
152+ metrics .PodExists (context .Background (), "default" , "mypod" ),
153+ "Pod should NOT exist at this point!" ,
154+ )
155+
156+ metrics .RegisterImageDuration ("default" , "mypod" , "mycontainer" , "nginx:latest" , time .Now ())
157+ metrics .ReportError ("default" , "mypod" , "mycontianer" , "nginx:latest" )
158+
159+ // Step 6: Gather metrics and assert none were registered
160+ metricFamilies , err = reg .Gather ()
161+ assert .NoError (t , err )
162+ for _ , mf := range metricFamilies {
163+ assert .NotContains (t , * mf .Name , "is_latest_version" , "Should not have been found: %+v" , mf )
164+ assert .NotContains (t , * mf .Name , "image_lookup_duration" , "Should not have been found: %+v" , mf )
165+ assert .NotContains (t , * mf .Name , "image_failures_total" , "Should not have been found: %+v" , mf )
166+ }
167+ }
0 commit comments