Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
### Added
- Added the option to disable prometheus service monitor creation [#810](https://github.com/NVIDIA/KAI-Scheduler/pull/810) [itsomri](https://github.com/itsomri)

### Fixed
- Fixed pod controller logging to use request namespace/name instead of empty pod object fields when pod is not found

## [v0.12.0] - 2025-12-24

### Added
Expand Down
2 changes: 1 addition & 1 deletion pkg/podgrouper/pod_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (r *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R
err := r.Client.Get(ctx, types.NamespacedName{Namespace: req.Namespace, Name: req.Name}, &pod)
if err != nil {
if errors.IsNotFound(err) {
logger.V(1).Info(fmt.Sprintf("Pod %s/%s not found, was probably deleted", pod.Namespace, pod.Name))
logger.V(1).Info(fmt.Sprintf("Pod %s/%s not found, was probably deleted", req.Namespace, req.Name))
return ctrl.Result{}, nil
}

Expand Down
68 changes: 68 additions & 0 deletions pkg/podgrouper/pod_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
package controllers

import (
"bytes"
"context"
"fmt"
"testing"

"github.com/go-logr/logr"
"github.com/stretchr/testify/assert"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -18,11 +20,39 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/log"

"github.com/NVIDIA/KAI-scheduler/pkg/common/constants"
"github.com/NVIDIA/KAI-scheduler/pkg/podgrouper/podgroup"
)

type testLogSink struct {
buffer *bytes.Buffer
}

func (s *testLogSink) Init(info logr.RuntimeInfo) {}
func (s *testLogSink) Enabled(level int) bool { return true }
func (s *testLogSink) Info(level int, msg string, keysAndValues ...interface{}) {
s.buffer.WriteString(fmt.Sprintf("[%d] %s", level, msg))
for i := 0; i < len(keysAndValues); i += 2 {
if i+1 < len(keysAndValues) {
s.buffer.WriteString(fmt.Sprintf(" %v=%v", keysAndValues[i], keysAndValues[i+1]))
}
}
s.buffer.WriteString("\n")
}
func (s *testLogSink) Error(err error, msg string, keysAndValues ...interface{}) {
s.buffer.WriteString(fmt.Sprintf("ERROR %s: %v", msg, err))
for i := 0; i < len(keysAndValues); i += 2 {
if i+1 < len(keysAndValues) {
s.buffer.WriteString(fmt.Sprintf(" %v=%v", keysAndValues[i], keysAndValues[i+1]))
}
}
s.buffer.WriteString("\n")
}
func (s *testLogSink) WithValues(keysAndValues ...interface{}) logr.LogSink { return s }
func (s *testLogSink) WithName(name string) logr.LogSink { return s }

const nodePoolKey = "kai.scheduler/node-pool"

func TestAddNodePoolLabel(t *testing.T) {
Expand Down Expand Up @@ -284,3 +314,41 @@ func TestLabelsMatch(t *testing.T) {
})
}
}

func TestReconcilePodNotFound(t *testing.T) {
testNamespace := "test-namespace"
testPodName := "test-pod"

var logBuffer bytes.Buffer
ctx := log.IntoContext(context.TODO(), logr.New(&testLogSink{buffer: &logBuffer}))
fakeClient := fake.NewClientBuilder().Build()

reconciler := PodReconciler{
Client: fakeClient,
Scheme: scheme.Scheme,
podGrouper: &fakePodGrouper{},
PodGroupHandler: nil,
configs: Configs{
SchedulerName: "kai-scheduler",
},
eventRecorder: record.NewFakeRecorder(10),
}

result, err := reconciler.Reconcile(ctx, ctrl.Request{
NamespacedName: types.NamespacedName{
Namespace: testNamespace,
Name: testPodName,
},
})

assert.NoError(t, err)
assert.Equal(t, ctrl.Result{}, result)

logOutput := logBuffer.String()
expectedPattern := fmt.Sprintf("Pod %s/%s not found", testNamespace, testPodName)

assert.Contains(t, logOutput, expectedPattern,
"Log should contain correct namespace/name from req, got: %s", logOutput)
assert.NotContains(t, logOutput, "Pod / not found",
"Log should not contain empty namespace/name pattern")
}
Loading