@@ -27,7 +27,7 @@ import (
2727)
2828
2929func TestMetricsWatcher_BasicSendReceive (t * testing.T ) {
30- w := newMetricsWatcher ("" , labels .Everything (), resourceTypePod )
30+ w := newMetricsWatcher ("" , labels .Everything (), resourceTypePod , nil )
3131 defer w .Stop ()
3232
3333 // Send an event
@@ -51,7 +51,7 @@ func TestMetricsWatcher_BasicSendReceive(t *testing.T) {
5151}
5252
5353func TestMetricsWatcher_StopClosesChannel (t * testing.T ) {
54- w := newMetricsWatcher ("" , labels .Everything (), resourceTypePod )
54+ w := newMetricsWatcher ("" , labels .Everything (), resourceTypePod , nil )
5555
5656 // Stop the watcher
5757 w .Stop ()
@@ -75,7 +75,7 @@ func TestMetricsWatcher_StopClosesChannel(t *testing.T) {
7575}
7676
7777func TestMetricsWatcher_NamespaceFilter (t * testing.T ) {
78- w := newMetricsWatcher ("test-ns" , labels .Everything (), resourceTypePod )
78+ w := newMetricsWatcher ("test-ns" , labels .Everything (), resourceTypePod , nil )
7979 defer w .Stop ()
8080
8181 // Event in matching namespace
@@ -113,7 +113,7 @@ func TestMetricsWatcher_NamespaceFilter(t *testing.T) {
113113
114114func TestMetricsWatcher_LabelSelectorFilter (t * testing.T ) {
115115 selector , _ := labels .Parse ("app=myapp" )
116- w := newMetricsWatcher ("" , selector , resourceTypeNode )
116+ w := newMetricsWatcher ("" , selector , resourceTypeNode , nil )
117117 defer w .Stop ()
118118
119119 // Event with matching labels
@@ -150,7 +150,7 @@ func TestMetricsWatcher_LabelSelectorFilter(t *testing.T) {
150150}
151151
152152func TestMetricsWatcher_SendInitialEvents (t * testing.T ) {
153- w := newMetricsWatcher ("" , labels .Everything (), resourceTypePod )
153+ w := newMetricsWatcher ("" , labels .Everything (), resourceTypePod , nil )
154154 defer w .Stop ()
155155
156156 // Create some initial objects
@@ -202,7 +202,7 @@ func TestMetricsWatcher_SendInitialEvents(t *testing.T) {
202202}
203203
204204func TestMetricsWatcher_SlowConsumer (t * testing.T ) {
205- w := newMetricsWatcher ("" , labels .Everything (), resourceTypePod )
205+ w := newMetricsWatcher ("" , labels .Everything (), resourceTypePod , nil )
206206 defer w .Stop ()
207207
208208 event := WatchEvent {
@@ -239,7 +239,7 @@ func TestMetricsWatcher_ContextCancellation(t *testing.T) {
239239 allMetrics : []metrics.PodMetrics {},
240240 }
241241
242- helper := NewPodMetricsWatchHelper (storage )
242+ helper := NewPodMetricsWatchHelper (storage , nil )
243243
244244 w , err := helper .Watch (ctx , "" , labels .Everything (), false )
245245 if err != nil {
@@ -281,7 +281,7 @@ func TestPodMetricsWatchHelper_WatchWithInitialEvents(t *testing.T) {
281281 allMetrics : []metrics.PodMetrics {pod1 , pod2 },
282282 }
283283
284- helper := NewPodMetricsWatchHelper (storage )
284+ helper := NewPodMetricsWatchHelper (storage , nil )
285285 ctx , cancel := context .WithCancel (context .Background ())
286286 defer cancel ()
287287
@@ -329,7 +329,7 @@ func TestNodeMetricsWatchHelper_WatchWithInitialEvents(t *testing.T) {
329329 allMetrics : []metrics.NodeMetrics {node1 , node2 },
330330 }
331331
332- helper := NewNodeMetricsWatchHelper (storage )
332+ helper := NewNodeMetricsWatchHelper (storage , nil )
333333 ctx , cancel := context .WithCancel (context .Background ())
334334 defer cancel ()
335335
@@ -368,7 +368,7 @@ func TestNodeMetricsWatchHelper_WatchWithInitialEvents(t *testing.T) {
368368func TestMetricsWatcher_BookmarkType (t * testing.T ) {
369369 // Test that pod watchers get PodMetrics bookmarks
370370 t .Run ("pod watcher gets PodMetrics bookmark" , func (t * testing.T ) {
371- w := newMetricsWatcher ("" , labels .Everything (), resourceTypePod )
371+ w := newMetricsWatcher ("" , labels .Everything (), resourceTypePod , nil )
372372 defer w .Stop ()
373373
374374 // Send bookmark directly - it goes to result channel
@@ -393,7 +393,7 @@ func TestMetricsWatcher_BookmarkType(t *testing.T) {
393393
394394 // Test that node watchers get NodeMetrics bookmarks
395395 t .Run ("node watcher gets NodeMetrics bookmark" , func (t * testing.T ) {
396- w := newMetricsWatcher ("" , labels .Everything (), resourceTypeNode )
396+ w := newMetricsWatcher ("" , labels .Everything (), resourceTypeNode , nil )
397397 defer w .Stop ()
398398
399399 ok := w .sendBookmark ("456" )
@@ -416,6 +416,58 @@ func TestMetricsWatcher_BookmarkType(t *testing.T) {
416416 })
417417}
418418
419+ func TestMetricsWatcher_LabelEnrichment (t * testing.T ) {
420+ // Simulate: storage events have no labels, but labelLookup provides them
421+ lookup := func (namespace , name string ) map [string ]string {
422+ if name == "pod1" {
423+ return map [string ]string {"app" : "myapp" }
424+ }
425+ if name == "pod2" {
426+ return map [string ]string {"app" : "other" }
427+ }
428+ return nil
429+ }
430+
431+ selector , _ := labels .Parse ("app=myapp" )
432+ w := newMetricsWatcher ("" , selector , resourceTypePod , lookup )
433+ defer w .Stop ()
434+
435+ // Send events WITHOUT labels (as storage does)
436+ pod1 := metrics.PodMetrics {}
437+ pod1 .Name = "pod1"
438+ pod1 .Namespace = "default"
439+ // Note: no Labels set
440+
441+ pod2 := metrics.PodMetrics {}
442+ pod2 .Name = "pod2"
443+ pod2 .Namespace = "default"
444+
445+ w .Send (WatchEvent {Type : watch .Modified , Object : pod1 })
446+ w .Send (WatchEvent {Type : watch .Modified , Object : pod2 })
447+
448+ // Should receive pod1 (labels enriched from lookup → matches selector)
449+ select {
450+ case event := <- w .ResultChan ():
451+ pm := event .Object .(* metrics.PodMetrics )
452+ if pm .Name != "pod1" {
453+ t .Errorf ("Expected pod1, got %s" , pm .Name )
454+ }
455+ if pm .Labels ["app" ] != "myapp" {
456+ t .Errorf ("Expected enriched labels, got %v" , pm .Labels )
457+ }
458+ case <- time .After (time .Second ):
459+ t .Fatal ("Timeout waiting for enriched event" )
460+ }
461+
462+ // pod2 should be filtered out (labels enriched → doesn't match selector)
463+ select {
464+ case event := <- w .ResultChan ():
465+ t .Errorf ("Unexpected event: %v" , event )
466+ case <- time .After (100 * time .Millisecond ):
467+ // Expected
468+ }
469+ }
470+
419471// fakeWatchablePodStorage implements WatchablePodMetricsGetter for testing
420472type fakeWatchablePodStorage struct {
421473 currentRV string
0 commit comments