Skip to content

Commit 084d6c4

Browse files
authored
Merge pull request kubernetes#125699 from pohly/scheduler-framework-logging
scheduler: fix klog.KObjSlice when applied to []*NodeInfo
2 parents e073148 + 719a49c commit 084d6c4

File tree

5 files changed

+46
-1
lines changed

5 files changed

+46
-1
lines changed

pkg/scheduler/framework/types.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,21 @@ type NodeInfo struct {
591591
Generation int64
592592
}
593593

594+
// NodeInfo implements KMetadata, so for example klog.KObjSlice(nodes) works
595+
// when nodes is a []*NodeInfo.
596+
var _ klog.KMetadata = &NodeInfo{}
597+
598+
func (n *NodeInfo) GetName() string {
599+
if n == nil {
600+
return "<nil>"
601+
}
602+
if n.node == nil {
603+
return "<no node>"
604+
}
605+
return n.node.Name
606+
}
607+
func (n *NodeInfo) GetNamespace() string { return "" }
608+
594609
// nextGeneration: Let's make sure history never forgets the name...
595610
// Increments the generation number monotonically ensuring that generation numbers never collide.
596611
// Collision of the generation numbers would be particularly problematic if a node was deleted and

pkg/scheduler/framework/types_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package framework
1919
import (
2020
"fmt"
2121
"reflect"
22+
"strings"
2223
"testing"
2324

2425
"github.com/google/go-cmp/cmp"
@@ -29,9 +30,11 @@ import (
2930
"k8s.io/apimachinery/pkg/util/sets"
3031
utilfeature "k8s.io/apiserver/pkg/util/feature"
3132
featuregatetesting "k8s.io/component-base/featuregate/testing"
33+
"k8s.io/klog/v2"
3234
"k8s.io/kubernetes/pkg/features"
3335
st "k8s.io/kubernetes/pkg/scheduler/testing"
3436
"k8s.io/kubernetes/test/utils/ktesting"
37+
"k8s.io/kubernetes/test/utils/ktesting/initoption"
3538
)
3639

3740
func TestNewResource(t *testing.T) {
@@ -1657,3 +1660,17 @@ func TestCloudEvent_Match(t *testing.T) {
16571660
})
16581661
}
16591662
}
1663+
1664+
func TestNodeInfoKMetadata(t *testing.T) {
1665+
tCtx := ktesting.Init(t, initoption.BufferLogs(true))
1666+
logger := tCtx.Logger()
1667+
logger.Info("Some NodeInfo slice", "nodes", klog.KObjSlice([]*NodeInfo{nil, {}, {node: &v1.Node{}}, {node: &v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "worker"}}}}))
1668+
1669+
output := logger.GetSink().(ktesting.Underlier).GetBuffer().String()
1670+
1671+
// The initial nil entry gets turned into empty ObjectRef by klog,
1672+
// which becomes an empty string during output formatting.
1673+
if !strings.Contains(output, `Some NodeInfo slice nodes=["","<no node>","","worker"]`) {
1674+
tCtx.Fatalf("unexpected output:\n%s", output)
1675+
}
1676+
}

test/utils/ktesting/initoption/initoption.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,13 @@ func PerTestOutput(enabled bool) InitOption {
2828
c.PerTestOutput = enabled
2929
}
3030
}
31+
32+
// BufferLogs controls whether log entries are captured in memory in addition
33+
// to being printed. Off by default. Unit tests that want to verify that
34+
// log entries are emitted as expected can turn this on and then retrieve
35+
// the captured log through the Underlier LogSink interface.
36+
func BufferLogs(enabled bool) InitOption {
37+
return func(c *internal.InitConfig) {
38+
c.BufferLogs = enabled
39+
}
40+
}

test/utils/ktesting/internal/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ package internal
1818

1919
type InitConfig struct {
2020
PerTestOutput bool
21+
BufferLogs bool
2122
}

test/utils/ktesting/tcontext.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ import (
3636
)
3737

3838
// Underlier is the additional interface implemented by the per-test LogSink
39-
// behind [TContext.Logger].
39+
// behind [TContext.Logger]. Together with [initoption.BufferLogs] it can be
40+
// used to capture log output in memory to check it in tests.
4041
type Underlier = ktesting.Underlier
4142

4243
// CleanupGracePeriod is the time that a [TContext] gets canceled before the
@@ -245,6 +246,7 @@ func Init(tb TB, opts ...InitOption) TContext {
245246
}),
246247
ktesting.VerbosityFlagName("v"),
247248
ktesting.VModuleFlagName("vmodule"),
249+
ktesting.BufferLogs(c.BufferLogs),
248250
)
249251

250252
// Copy klog settings instead of making the ktesting logger

0 commit comments

Comments
 (0)