Skip to content

Commit e398302

Browse files
committed
Add OWNERS and testing to external extender/v1 api
1 parent 18ffaf5 commit e398302

File tree

6 files changed

+146
-1
lines changed

6 files changed

+146
-1
lines changed

staging/publishing/import-restrictions.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@
194194

195195
- baseImportPath: "./vendor/k8s.io/kube-scheduler/"
196196
allowedImports:
197+
- k8s.io/api
197198
- k8s.io/apimachinery
198199
- k8s.io/component-base
199200
- k8s.io/klog
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# See the OWNERS docs at https://go.k8s.io/owners
2+
3+
# Disable inheritance as this is an api owners file
4+
options:
5+
no_parent_owners: true
6+
approvers:
7+
- api-approvers
8+
reviewers:
9+
- api-reviewers
10+
- sig-scheduling
11+
labels:
12+
- kind/api-change
13+
- sig/scheduling

staging/src/k8s.io/kube-scheduler/extender/v1/BUILD

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
load("@io_bazel_rules_go//go:def.bzl", "go_library")
1+
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
22

33
go_library(
44
name = "go_default_library",
@@ -29,3 +29,15 @@ filegroup(
2929
tags = ["automanaged"],
3030
visibility = ["//visibility:public"],
3131
)
32+
33+
go_test(
34+
name = "go_default_test",
35+
srcs = ["types_test.go"],
36+
embed = [":go_default_library"],
37+
deps = [
38+
"//staging/src/k8s.io/api/core/v1:go_default_library",
39+
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
40+
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
41+
"//vendor/github.com/google/go-cmp/cmp:go_default_library",
42+
],
43+
)
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1
18+
19+
import (
20+
"encoding/json"
21+
"reflect"
22+
"strings"
23+
"testing"
24+
25+
"github.com/google/go-cmp/cmp"
26+
27+
corev1 "k8s.io/api/core/v1"
28+
v1 "k8s.io/api/core/v1"
29+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
30+
"k8s.io/apimachinery/pkg/types"
31+
)
32+
33+
// TestCompatibility verifies that the types in extender/v1 can be successfully encoded to json and decoded back, even when lowercased,
34+
// since these types were written around JSON tags and we need to enforce consistency on them now.
35+
// @TODO(88634): v2 of these types should be defined with proper JSON tags to enforce field casing to a single approach
36+
func TestCompatibility(t *testing.T) {
37+
testcases := []struct {
38+
emptyObj interface{}
39+
obj interface{}
40+
expectJSON string
41+
}{
42+
{
43+
emptyObj: &ExtenderPreemptionResult{},
44+
obj: &ExtenderPreemptionResult{
45+
NodeNameToMetaVictims: map[string]*MetaVictims{"foo": {Pods: []*MetaPod{{UID: "myuid"}}, NumPDBViolations: 1}},
46+
},
47+
expectJSON: `{"NodeNameToMetaVictims":{"foo":{"Pods":[{"UID":"myuid"}],"NumPDBViolations":1}}}`,
48+
},
49+
{
50+
emptyObj: &ExtenderPreemptionArgs{},
51+
obj: &ExtenderPreemptionArgs{
52+
Pod: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "podname"}},
53+
NodeNameToVictims: map[string]*Victims{"foo": {Pods: []*v1.Pod{&corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "podname"}}}, NumPDBViolations: 1}},
54+
NodeNameToMetaVictims: map[string]*MetaVictims{"foo": {Pods: []*MetaPod{{UID: "myuid"}}, NumPDBViolations: 1}},
55+
},
56+
expectJSON: `{"Pod":{"metadata":{"name":"podname","creationTimestamp":null},"spec":{"containers":null},"status":{}},"NodeNameToVictims":{"foo":{"Pods":[{"metadata":{"name":"podname","creationTimestamp":null},"spec":{"containers":null},"status":{}}],"NumPDBViolations":1}},"NodeNameToMetaVictims":{"foo":{"Pods":[{"UID":"myuid"}],"NumPDBViolations":1}}}`,
57+
},
58+
{
59+
emptyObj: &ExtenderArgs{},
60+
obj: &ExtenderArgs{
61+
Pod: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "podname"}},
62+
Nodes: &corev1.NodeList{Items: []corev1.Node{{ObjectMeta: metav1.ObjectMeta{Name: "nodename"}}}},
63+
NodeNames: &[]string{"node1"},
64+
},
65+
expectJSON: `{"Pod":{"metadata":{"name":"podname","creationTimestamp":null},"spec":{"containers":null},"status":{}},"Nodes":{"metadata":{},"items":[{"metadata":{"name":"nodename","creationTimestamp":null},"spec":{},"status":{"daemonEndpoints":{"kubeletEndpoint":{"Port":0}},"nodeInfo":{"machineID":"","systemUUID":"","bootID":"","kernelVersion":"","osImage":"","containerRuntimeVersion":"","kubeletVersion":"","kubeProxyVersion":"","operatingSystem":"","architecture":""}}}]},"NodeNames":["node1"]}`,
66+
},
67+
{
68+
emptyObj: &ExtenderFilterResult{},
69+
obj: &ExtenderFilterResult{
70+
Nodes: &corev1.NodeList{Items: []corev1.Node{{ObjectMeta: metav1.ObjectMeta{Name: "nodename"}}}},
71+
NodeNames: &[]string{"node1"},
72+
FailedNodes: FailedNodesMap{"foo": "bar"},
73+
Error: "myerror",
74+
},
75+
expectJSON: `{"Nodes":{"metadata":{},"items":[{"metadata":{"name":"nodename","creationTimestamp":null},"spec":{},"status":{"daemonEndpoints":{"kubeletEndpoint":{"Port":0}},"nodeInfo":{"machineID":"","systemUUID":"","bootID":"","kernelVersion":"","osImage":"","containerRuntimeVersion":"","kubeletVersion":"","kubeProxyVersion":"","operatingSystem":"","architecture":""}}}]},"NodeNames":["node1"],"FailedNodes":{"foo":"bar"},"Error":"myerror"}`,
76+
},
77+
{
78+
emptyObj: &ExtenderBindingArgs{},
79+
obj: &ExtenderBindingArgs{
80+
PodName: "mypodname",
81+
PodNamespace: "mypodnamespace",
82+
PodUID: types.UID("mypoduid"),
83+
Node: "mynode",
84+
},
85+
expectJSON: `{"PodName":"mypodname","PodNamespace":"mypodnamespace","PodUID":"mypoduid","Node":"mynode"}`,
86+
},
87+
{
88+
emptyObj: &ExtenderBindingResult{},
89+
obj: &ExtenderBindingResult{Error: "myerror"},
90+
expectJSON: `{"Error":"myerror"}`,
91+
},
92+
{
93+
emptyObj: &HostPriority{},
94+
obj: &HostPriority{Host: "myhost", Score: 1},
95+
expectJSON: `{"Host":"myhost","Score":1}`,
96+
},
97+
}
98+
99+
for _, tc := range testcases {
100+
t.Run(reflect.TypeOf(tc.obj).String(), func(t *testing.T) {
101+
data, err := json.Marshal(tc.obj)
102+
if err != nil {
103+
t.Fatal(err)
104+
}
105+
if string(data) != tc.expectJSON {
106+
t.Fatalf("expected %s, got %s", tc.expectJSON, string(data))
107+
}
108+
if err := json.Unmarshal([]byte(strings.ToLower(string(data))), tc.emptyObj); err != nil {
109+
t.Fatal(err)
110+
}
111+
if !reflect.DeepEqual(tc.emptyObj, tc.obj) {
112+
t.Fatalf("round-tripped case-insensitive diff: %s", cmp.Diff(tc.obj, tc.emptyObj))
113+
}
114+
})
115+
}
116+
}

staging/src/k8s.io/kube-scheduler/go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ module k8s.io/kube-scheduler
55
go 1.13
66

77
require (
8+
github.com/google/go-cmp v0.3.0
9+
k8s.io/api v0.0.0
810
k8s.io/apimachinery v0.0.0
911
k8s.io/component-base v0.0.0
1012
)

vendor/modules.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,6 +1777,7 @@ k8s.io/kube-proxy/config/v1alpha1
17771777
k8s.io/kube-scheduler/config/v1
17781778
k8s.io/kube-scheduler/config/v1alpha1
17791779
k8s.io/kube-scheduler/config/v1alpha2
1780+
k8s.io/kube-scheduler/extender/v1
17801781
# k8s.io/kubectl v0.0.0 => ./staging/src/k8s.io/kubectl
17811782
k8s.io/kubectl/pkg/apps
17821783
k8s.io/kubectl/pkg/cmd

0 commit comments

Comments
 (0)