Skip to content

Commit

Permalink
fix test
Browse files Browse the repository at this point in the history
  • Loading branch information
Gekko0114 committed Oct 31, 2023
1 parent f5b92e2 commit 02eb28d
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 29 deletions.
4 changes: 3 additions & 1 deletion guest/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,6 @@ type NodeInfo interface {
Node() proto.Node
}

type NodeToStatusMap map[string]*Status
type NodeToStatusMap interface {
NodeToStatusMap() map[string]*Status
}
7 changes: 7 additions & 0 deletions guest/internal/imports/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,10 @@ func Pod(updater func([]byte) error) error {
return k8sApiPod(ptr, limit)
}, updater)
}

func NodeToStatusMap(updater func([]byte) error) error {
// Wrap to avoid TinyGo 0.28: cannot use an exported function as value
return mem.Update(func(ptr uint32, limit mem.BufLimit) (len uint32) {
return k8sApiNodeToStatusMap(ptr, limit)
}, updater)
}
3 changes: 3 additions & 0 deletions guest/internal/imports/imports.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,8 @@ func k8sApiNodeName(ptr uint32, limit mem.BufLimit) (len uint32)
//go:wasmimport k8s.io/api pod
func k8sApiPod(ptr uint32, limit mem.BufLimit) (len uint32)

//go:wasmimport k8s.io/api nodeToStatusMap
func k8sApiNodeToStatusMap(ptr uint32, limit mem.BufLimit) (len uint32)

//go:wasmimport k8s.io/scheduler result.status_reason
func k8sSchedulerResultStatusReason(ptr, size uint32)
3 changes: 3 additions & 0 deletions guest/internal/imports/imports_stub.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,8 @@ func k8sApiNodeName(uint32, mem.BufLimit) (len uint32) { return }
// k8sApiPod is stubbed for compilation outside TinyGo.
func k8sApiPod(uint32, mem.BufLimit) (len uint32) { return }

// k8sApiNodeToStatusMap is stubbed for compilation outside TinyGo.
func k8sApiNodeToStatusMap(uint32, mem.BufLimit) (len uint32) { return }

// k8sSchedulerResultStatusReason is stubbed for compilation outside TinyGo.
func k8sSchedulerResultStatusReason(uint32, uint32) {}
2 changes: 1 addition & 1 deletion guest/plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import (
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/api"
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/enqueue"
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/filter"
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/internal/postfilter"
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/internal/prefilter"
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/postfilter"
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/prescore"
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/score"
)
Expand Down
25 changes: 24 additions & 1 deletion guest/postfilter/postfilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import (
"unsafe"

"sigs.k8s.io/kube-scheduler-wasm-extension/guest/api"
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/internal/cyclestate"
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/internal/imports"
"sigs.k8s.io/kube-scheduler-wasm-extension/guest/internal/plugin"
internalproto "sigs.k8s.io/kube-scheduler-wasm-extension/guest/internal/proto"
)

// postfilter is the current plugin assigned with SetPlugin.
Expand Down Expand Up @@ -71,9 +75,10 @@ func _postfilter() uint64 { //nolint
return 0
}

// TODO: fix PostFilter
// The parameters passed are lazy with regard to host functions. This means
// a no-op plugin should not have any unmarshal penalty.
nominatedNodeName, nominatingMode, status := postfilter.PostFilter(CycleState, Pod, nil)
nominatedNodeName, nominatingMode, status := postfilter.PostFilter(cyclestate.Values, cyclestate.Pod, nil)

cString := []byte(nominatedNodeName)
if cString != nil {
Expand All @@ -85,3 +90,21 @@ func _postfilter() uint64 { //nolint

return (uint64(nominatingMode) << uint64(32)) | uint64(imports.StatusToCode(status))
}

type nodeToStatusMap struct {
statusMap map[string]*api.Status
}

func (n *nodeToStatusMap) NodeToStatusMap() map[string]*api.Status {
return n.lazyNodeToStatusMap()
}

// lazyNodeToStatusMap returns NodeToStatusMap from imports.NodeToStatusMap.
func (n *nodeToStatusMap) lazyNodeToStatusMap() map[string]*api.Status {
var msg api.NodeToStatusMap
if err := imports.NodeToStatusMap(msg.UnmarshalVT); err != nil {
panic(err.Error())
}
n.statusMap = &internalproto.NodeToStatusMap{Msg: &msg}
return n.statusMap
}
16 changes: 16 additions & 0 deletions scheduler/plugin/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const (
k8sApiNodeList = "nodeList"
k8sApiNodeName = "nodeName"
k8sApiPod = "pod"
k8sApiNodeToStatusMap = "nodeToStatusMap"
k8sKlog = "k8s.io/klog"
k8sKlogLog = "log"
k8sKlogLogs = "logs"
Expand All @@ -60,6 +61,9 @@ func instantiateHostApi(ctx context.Context, runtime wazero.Runtime) (wazeroapi.
NewFunctionBuilder().
WithGoModuleFunction(wazeroapi.GoModuleFunc(k8sApiPodFn), []wazeroapi.ValueType{i32, i32}, []wazeroapi.ValueType{i32}).
WithParameterNames("buf", "buf_limit").Export(k8sApiPod).
NewFunctionBuilder().
WithGoModuleFunction(wazeroapi.GoModuleFunc(k8sApiNodeToStatusMapFn), []wazeroapi.ValueType{i32, i32}, []wazeroapi.ValueType{i32}).
WithParameterNames("buf", "buf_limit").Export(k8sApiNodeToStatusMap).
Instantiate(ctx)
}

Expand Down Expand Up @@ -126,6 +130,9 @@ type stack struct {
// pod is used by guest.filterFn and guest.scoreFn
pod *v1.Pod

// nodeToStatusMap is used by guest.postfilterFn
nodeToStatusMap map[string]*framework.Status

// resultClusterEvents is returned by guest.enqueueFn
resultClusterEvents []framework.ClusterEvent

Expand Down Expand Up @@ -186,6 +193,15 @@ func k8sApiPodFn(ctx context.Context, mod wazeroapi.Module, stack []uint64) {
stack[0] = uint64(marshalIfUnderLimit(mod.Memory(), pod, buf, bufLimit))
}

// TODO: fix
func k8sApiNodeToStatusMapFn(ctx context.Context, mod wazeroapi.Module, stack []uint64) {
buf := uint32(stack[0])
bufLimit := bufLimit(stack[1])

// nodeToStatusMap := paramsFromContext(ctx).nodeToStatusMap
stack[0] = uint64(marshalIfUnderLimit(mod.Memory(), nil, buf, bufLimit))
}

type host struct {
guestConfig string
logSeverity int32
Expand Down
1 change: 0 additions & 1 deletion scheduler/plugin/mask.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ func maskInterfaces(plugin *wasmPlugin) (framework.Plugin, error) {
iPreBindPlugin |
iPostBindPlugin)

// TODO: ask about PostFilter
switch i {
case iFilterPlugin:
type filter interface {
Expand Down
46 changes: 21 additions & 25 deletions scheduler/plugin/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ func TestPostFilter(t *testing.T) {
expectedStatusMessage string
}{
{
name: "scored: nodeName equals spec.NodeName",
name: "success: nodeName equals spec.NodeName",
args: []string{"test", "score"},
pod: test.PodSmall,
nodeName: test.PodSmall.Spec.NodeName,
Expand All @@ -588,63 +588,59 @@ func TestPostFilter(t *testing.T) {
expectedStatusCode: framework.Success,
},
{
name: "most negative score",
name: "min statusCode",
guestURL: test.URLTestPostFilterFromGlobal,
pod: test.PodSmall,
nodeName: test.NodeSmall.Name,
globals: map[string]int32{"score": math.MinInt32},
expectedStatusCode: framework.Success,
globals: map[string]int32{"status_code": math.MinInt32},
expectedResult: &framework.PostFilterResult{NominatingInfo: &framework.NominatingInfo{NominatedNodeName: "", NominatingMode: 0}},
expectedStatusCode: math.MinInt32,
},
{
name: "min score",
name: "max statusCode",
guestURL: test.URLTestPostFilterFromGlobal,
pod: test.PodSmall,
nodeName: test.NodeSmall.Name,
globals: map[string]int32{"score": math.MinInt32},
expectedStatusCode: framework.Success,
globals: map[string]int32{"status_code": math.MaxInt32},
expectedResult: &framework.PostFilterResult{NominatingInfo: &framework.NominatingInfo{NominatedNodeName: "", NominatingMode: 0}},
expectedStatusCode: math.MaxInt32,
},
{
name: "max score",
name: "min nominatingMode",
guestURL: test.URLTestPostFilterFromGlobal,
pod: test.PodSmall,
nodeName: test.NodeSmall.Name,
globals: map[string]int32{"score": math.MaxInt32},
globals: map[string]int32{"nominating_mode": math.MinInt32},
expectedResult: &framework.PostFilterResult{NominatingInfo: &framework.NominatingInfo{NominatedNodeName: "", NominatingMode: math.MinInt32}},
expectedStatusCode: framework.Success,
},
{
name: "min statusCode",
name: "max nominatingMode",
guestURL: test.URLTestPostFilterFromGlobal,
pod: test.PodSmall,
nodeName: test.NodeSmall.Name,
globals: map[string]int32{"status_code": math.MinInt32},
expectedStatusCode: math.MinInt32,
},
{
name: "max statusCode",
guestURL: test.URLTestPostFilterFromGlobal,
pod: test.PodSmall,
nodeName: test.NodeSmall.Name,
globals: map[string]int32{"status_code": math.MaxInt32},
expectedStatusCode: math.MaxInt32,
globals: map[string]int32{"nominating_mode": math.MaxInt32},
expectedResult: &framework.PostFilterResult{NominatingInfo: &framework.NominatingInfo{NominatedNodeName: "", NominatingMode: math.MaxInt32}},
expectedStatusCode: framework.Success,
},
{
name: "panic",
guestURL: test.URLErrorPanicOnPostFilter,
pod: test.PodSmall,
nodeName: test.NodeSmall.Name,
expectedStatusCode: framework.Error,
expectedStatusMessage: `wasm: score error: panic!
expectedStatusMessage: `wasm: postfilter error: panic!
wasm error: unreachable
wasm stack trace:
panic_on_score.$1() i64`,
panic_on_postfilter.$1() i64`,
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
guestURL := tc.guestURL
if guestURL == "" {
guestURL = test.URLTestPostFilterFromGlobal
guestURL = test.URLTestFilter
}

p, err := wasm.NewFromConfig(ctx, wasm.PluginConfig{GuestURL: guestURL, Args: tc.args})
Expand All @@ -659,8 +655,8 @@ wasm stack trace:
}

result, status := p.(framework.PostFilterPlugin).PostFilter(ctx, nil, tc.pod, nil)
if want, have := tc.expectedResult, result; want != have {
t.Fatalf("unexpected score: want %v, have %v", want, have)
if want, have := tc.expectedResult, result; !reflect.DeepEqual(want, have) {
t.Fatalf("unexpected result: want %v, have %v", want, have)
}
if want, have := tc.expectedStatusCode, status.Code(); want != have {
t.Fatalf("unexpected status code: want %v, have %v", want, have)
Expand Down
Binary file modified scheduler/test/testdata/error/panic_on_postfilter.wasm
Binary file not shown.
3 changes: 3 additions & 0 deletions scheduler/test/testdata/error/panic_on_postfilter.wat
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,7 @@

;; Issue the unreachable instruction instead of returning a code
(unreachable))

;; We require exporting filter with postfilter
(func (export "filter") (result i32) (unreachable))
)
Binary file modified scheduler/test/testdata/test/postfilter_from_global.wasm
Binary file not shown.
3 changes: 3 additions & 0 deletions scheduler/test/testdata/test/postfilter_from_global.wat
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,7 @@
(i64.or
(i64.shl (i64.extend_i32_u (local.get $nominating_mode)) (i64.const 32))
(i64.extend_i32_u (local.get $status_code)))))

;; We require exporting filter with postfilter
(func (export "filter") (result i32) (unreachable))
)

0 comments on commit 02eb28d

Please sign in to comment.