Merge pull request #108055 from liggitt/api-compatibility

Catch unused API compatibility fixtures
This commit is contained in:
Kubernetes Prow Robot 2022-02-10 17:50:18 -08:00 committed by GitHub
commit 438c3a51e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 44 additions and 8611 deletions

View File

@ -26,6 +26,9 @@ kube::golang::setup_env
# run in module mode to match test command in readme.md
export GO111MODULE=on
# Nuke old files so we don't accidentally carry stuff forward.
rm -f staging/src/k8s.io/api/testdata/HEAD/*.{yaml,json,pb}
# UPDATE_COMPATIBILITY_FIXTURE_DATA=true regenerates fixture data if needed.
# -run //HEAD only runs the test cases comparing against testdata for HEAD.
# We suppress the output because we are expecting to have changes.

View File

@ -33,6 +33,7 @@ import (
authorizationv1 "k8s.io/api/authorization/v1"
authorizationv1beta1 "k8s.io/api/authorization/v1beta1"
autoscalingv1 "k8s.io/api/autoscaling/v1"
autoscalingv2 "k8s.io/api/autoscaling/v2"
autoscalingv2beta1 "k8s.io/api/autoscaling/v2beta1"
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
batchv1 "k8s.io/api/batch/v1"
@ -89,6 +90,7 @@ var groups = []runtime.SchemeBuilder{
authorizationv1beta1.SchemeBuilder,
authorizationv1.SchemeBuilder,
autoscalingv1.SchemeBuilder,
autoscalingv2.SchemeBuilder,
autoscalingv2beta1.SchemeBuilder,
autoscalingv2beta2.SchemeBuilder,
batchv1beta1.SchemeBuilder,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,318 +0,0 @@
{
"kind": "EphemeralContainers",
"apiVersion": "v1",
"metadata": {
"name": "2",
"generateName": "3",
"namespace": "4",
"selfLink": "5",
"uid": "7",
"resourceVersion": "11042405498087606203",
"generation": 8071137005907523419,
"creationTimestamp": null,
"deletionGracePeriodSeconds": -4955867275792137171,
"labels": {
"7": "8"
},
"annotations": {
"9": "10"
},
"ownerReferences": [
{
"apiVersion": "11",
"kind": "12",
"name": "13",
"uid": "Dz廔ȇ{sŊƏp",
"controller": false,
"blockOwnerDeletion": true
}
],
"finalizers": [
"14"
],
"clusterName": "15",
"managedFields": [
{
"manager": "16",
"operation": "鐊唊飙Ş-U圴÷a/ɔ}摁(湗Ć]",
"apiVersion": "17",
"fieldsType": "18",
"subresource": "19"
}
]
},
"ephemeralContainers": [
{
"name": "20",
"image": "21",
"command": [
"22"
],
"args": [
"23"
],
"workingDir": "24",
"ports": [
{
"name": "25",
"hostPort": 1305381319,
"containerPort": -1300313567,
"hostIP": "26"
}
],
"envFrom": [
{
"prefix": "27",
"configMapRef": {
"name": "28",
"optional": false
},
"secretRef": {
"name": "29",
"optional": false
}
}
],
"env": [
{
"name": "30",
"value": "31",
"valueFrom": {
"fieldRef": {
"apiVersion": "32",
"fieldPath": "33"
},
"resourceFieldRef": {
"containerName": "34",
"resource": "35",
"divisor": "12"
},
"configMapKeyRef": {
"name": "36",
"key": "37",
"optional": false
},
"secretKeyRef": {
"name": "38",
"key": "39",
"optional": false
}
}
}
],
"resources": {
"limits": {
"V夸eɑeʤ": "420"
},
"requests": {
"Ƣ6/ʕVŚ(ĿȊ甞": "776"
}
},
"volumeMounts": [
{
"name": "40",
"mountPath": "41",
"subPath": "42",
"mountPropagation": "憍峕?狱³-Ǐ忄*",
"subPathExpr": "43"
}
],
"volumeDevices": [
{
"name": "44",
"devicePath": "45"
}
],
"livenessProbe": {
"exec": {
"command": [
"46"
]
},
"httpGet": {
"path": "47",
"port": "48",
"host": "49",
"scheme": "亞螩B峅x4%a鯿rŎǀ朲^苣fƼ@h",
"httpHeaders": [
{
"name": "50",
"value": "51"
}
]
},
"tcpSocket": {
"port": 1366345526,
"host": "52"
},
"initialDelaySeconds": 1392988974,
"timeoutSeconds": 1563658126,
"periodSeconds": -1771047449,
"successThreshold": -1280107919,
"failureThreshold": -54954325,
"terminationGracePeriodSeconds": 8559948711650432497
},
"readinessProbe": {
"exec": {
"command": [
"53"
]
},
"httpGet": {
"path": "54",
"port": -1395989138,
"host": "55",
"scheme": "斎AO6ĴC浔Ű壝ž",
"httpHeaders": [
{
"name": "56",
"value": "57"
}
]
},
"tcpSocket": {
"port": 180803110,
"host": "58"
},
"initialDelaySeconds": -2014231015,
"timeoutSeconds": 1488277679,
"periodSeconds": -1679907303,
"successThreshold": -1051545416,
"failureThreshold": 1305372099,
"terminationGracePeriodSeconds": -1220632347188845753
},
"startupProbe": {
"exec": {
"command": [
"59"
]
},
"httpGet": {
"path": "60",
"port": 1229400382,
"host": "61",
"scheme": "3ƆìQ喞艋涽託仭",
"httpHeaders": [
{
"name": "62",
"value": "63"
}
]
},
"tcpSocket": {
"port": "64",
"host": "65"
},
"initialDelaySeconds": 2076966617,
"timeoutSeconds": 202362764,
"periodSeconds": -560446848,
"successThreshold": -1098992377,
"failureThreshold": -1009864962,
"terminationGracePeriodSeconds": 2618170937706035036
},
"lifecycle": {
"postStart": {
"exec": {
"command": [
"66"
]
},
"httpGet": {
"path": "67",
"port": -503563033,
"host": "68",
"scheme": "趕ã/鈱$-议}ȧ外ĺ稥氹Ç|¶鎚¡ ",
"httpHeaders": [
{
"name": "69",
"value": "70"
}
]
},
"tcpSocket": {
"port": "71",
"host": "72"
}
},
"preStop": {
"exec": {
"command": [
"73"
]
},
"httpGet": {
"path": "74",
"port": 991085362,
"host": "75",
"scheme": "磩窮秳ķ蟒苾h^樅燴壩卄",
"httpHeaders": [
{
"name": "76",
"value": "77"
}
]
},
"tcpSocket": {
"port": -479087071,
"host": "78"
}
}
},
"terminationMessagePath": "79",
"terminationMessagePolicy": "?讦ĭÐ",
"imagePullPolicy": "/C龷ȪÆl殛瓷雼浢Ü礽绅",
"securityContext": {
"capabilities": {
"add": [
"\"ŵw^Ü郀叚Fi皬择,Q"
],
"drop": [
"ȸ{+"
]
},
"privileged": false,
"seLinuxOptions": {
"user": "80",
"role": "81",
"type": "82",
"level": "83"
},
"windowsOptions": {
"gmsaCredentialSpecName": "84",
"gmsaCredentialSpec": "85",
"runAsUserName": "86"
},
"runAsUser": -1466062763730980131,
"runAsGroup": 8360795821384820753,
"runAsNonRoot": false,
"readOnlyRootFilesystem": true,
"allowPrivilegeEscalation": true,
"procMount": "Ƙq/",
"seccompProfile": {
"type": " u衲\u003c¿燥",
"localhostProfile": "87"
}
},
"tty": true,
"targetContainerName": "88"
"gmsaCredentialSpecName": "86",
"gmsaCredentialSpec": "87",
"runAsUserName": "88",
"hostProcess": false
},
"runAsUser": -3031446704001093654,
"runAsGroup": 7608666948531988994,
"runAsNonRoot": true,
"readOnlyRootFilesystem": true,
"allowPrivilegeEscalation": true,
"procMount": "Ðl恕ɍȇ廄裭4懙鏮嵒ƫS",
"seccompProfile": {
"type": "ɷD¡轫n(鲼ƳÐƣKʘń",
"localhostProfile": "89"
}
},
"stdinOnce": true,
"targetContainerName": "90"
}
]
}

View File

@ -1,227 +0,0 @@
apiVersion: v1
ephemeralContainers:
- args:
- "23"
command:
- "22"
env:
- name: "30"
value: "31"
valueFrom:
configMapKeyRef:
key: "37"
name: "36"
optional: false
fieldRef:
apiVersion: "32"
fieldPath: "33"
resourceFieldRef:
containerName: "34"
divisor: "12"
resource: "35"
secretKeyRef:
key: "39"
name: "38"
optional: false
envFrom:
- configMapRef:
name: "28"
optional: false
prefix: "27"
secretRef:
name: "29"
optional: false
image: "21"
imagePullPolicy: /C龷ȪÆl殛瓷雼浢Ü礽绅
lifecycle:
postStart:
exec:
command:
- "66"
httpGet:
host: "68"
httpHeaders:
- name: "69"
value: "70"
path: "67"
port: -503563033
scheme: '趕ã/鈱$-议}ȧ外ĺ稥氹Ç|¶鎚¡ '
tcpSocket:
host: "72"
port: "71"
preStop:
exec:
command:
- "73"
httpGet:
host: "75"
httpHeaders:
- name: "76"
value: "77"
path: "74"
port: 991085362
scheme: 磩窮秳ķ蟒苾h^樅燴壩卄
tcpSocket:
host: "78"
port: -479087071
livenessProbe:
exec:
command:
- "46"
failureThreshold: -54954325
httpGet:
host: "49"
httpHeaders:
- name: "50"
value: "51"
path: "47"
port: "48"
scheme: 亞螩B峅x4%a鯿rŎǀ朲^苣fƼ@h
initialDelaySeconds: 1392988974
periodSeconds: -1771047449
successThreshold: -1280107919
tcpSocket:
host: "52"
port: 1366345526
terminationGracePeriodSeconds: 8559948711650432497
timeoutSeconds: 1563658126
name: "20"
ports:
- containerPort: -1300313567
hostIP: "26"
hostPort: 1305381319
name: "25"
readinessProbe:
exec:
command:
- "53"
failureThreshold: 1305372099
httpGet:
host: "55"
httpHeaders:
- name: "56"
value: "57"
path: "54"
port: -1395989138
scheme: 斎AO6ĴC浔Ű壝ž
initialDelaySeconds: -2014231015
periodSeconds: -1679907303
successThreshold: -1051545416
tcpSocket:
host: "58"
port: 180803110
terminationGracePeriodSeconds: -1220632347188845753
timeoutSeconds: 1488277679
resources:
limits:
V夸eɑ: "420"
requests:
Ƣ6/ʕVŚ(ĿȊ甞: "776"
securityContext:
allowPrivilegeEscalation: true
capabilities:
add:
- '"ŵw^Ü郀叚Fi皬择,Q'
drop:
- ȸ{+
privileged: false
procMount: Ƙq/
readOnlyRootFilesystem: true
runAsGroup: 8360795821384820753
runAsNonRoot: false
runAsUser: -1466062763730980131
procMount: Ðl恕ɍȇ廄裭4懙鏮嵒ƫS
readOnlyRootFilesystem: true
runAsGroup: 7608666948531988994
runAsNonRoot: true
runAsUser: -3031446704001093654
seLinuxOptions:
level: "83"
role: "81"
type: "82"
user: "80"
seccompProfile:
localhostProfile: "87"
type: ' u衲<¿燥'
windowsOptions:
gmsaCredentialSpec: "85"
gmsaCredentialSpecName: "84"
runAsUserName: "86"
localhostProfile: "89"
type: ɷD¡轫n(鲼ƳÐƣKʘń
windowsOptions:
gmsaCredentialSpec: "87"
gmsaCredentialSpecName: "86"
hostProcess: false
runAsUserName: "88"
startupProbe:
exec:
command:
- "59"
failureThreshold: -1009864962
httpGet:
host: "61"
httpHeaders:
- name: "62"
value: "63"
path: "60"
port: 1229400382
scheme: 3ƆìQ喞艋涽託仭
initialDelaySeconds: 2076966617
periodSeconds: -560446848
successThreshold: -1098992377
tcpSocket:
host: "65"
port: "64"
terminationGracePeriodSeconds: 2618170937706035036
timeoutSeconds: 202362764
targetContainerName: "88"
terminationMessagePath: "79"
terminationMessagePolicy: ?讦ĭÐ
tty: true
timeoutSeconds: 1229400382
stdinOnce: true
targetContainerName: "90"
terminationMessagePath: "81"
terminationMessagePolicy: ң
volumeDevices:
- devicePath: "45"
name: "44"
volumeMounts:
- mountPath: "41"
mountPropagation: 憍峕?狱³-Ǐ忄*
name: "40"
subPath: "42"
subPathExpr: "43"
workingDir: "24"
kind: EphemeralContainers
metadata:
annotations:
"9": "10"
clusterName: "15"
creationTimestamp: null
deletionGracePeriodSeconds: -4955867275792137171
finalizers:
- "14"
generateName: "3"
generation: 8071137005907523419
labels:
"7": "8"
managedFields:
- apiVersion: "17"
fieldsType: "18"
manager: "16"
operation: 鐊唊飙Ş-U圴÷a/ɔ}摁(湗Ć]
subresource: "19"
name: "2"
namespace: "4"
ownerReferences:
- apiVersion: "11"
blockOwnerDeletion: true
controller: false
kind: "12"
name: "13"
uid: Dz廔ȇ{sŊƏp
resourceVersion: "11042405498087606203"
selfLink: "5"
uid: "7"

View File

@ -1,6 +0,0 @@
{
"kind": "ExportOptions",
"apiVersion": "v1",
"export": true,
"exact": false
}

View File

@ -1,4 +0,0 @@
apiVersion: v1
exact: false
export: true
kind: ExportOptions

View File

@ -1,78 +0,0 @@
{
"kind": "EndpointSlice",
"apiVersion": "discovery.k8s.io/v1alpha1",
"metadata": {
"name": "2",
"generateName": "3",
"namespace": "4",
"selfLink": "5",
"uid": "7",
"resourceVersion": "11042405498087606203",
"generation": 8071137005907523419,
"creationTimestamp": null,
"deletionGracePeriodSeconds": -4955867275792137171,
"labels": {
"7": "8"
},
"annotations": {
"9": "10"
},
"ownerReferences": [
{
"apiVersion": "11",
"kind": "12",
"name": "13",
"uid": "Dz廔ȇ{sŊƏp",
"controller": false,
"blockOwnerDeletion": true
}
],
"finalizers": [
"14"
],
"clusterName": "15",
"managedFields": [
{
"manager": "16",
"operation": "鐊唊飙Ş-U圴÷a/ɔ}摁(湗Ć]",
"apiVersion": "17",
"fieldsType": "18"
}
]
},
"addressType": "īqJ枊a8衍`Ĩɘ.蘯",
"endpoints": [
{
"addresses": [
"19"
],
"conditions": {
"ready": false,
"serving": false,
"terminating": false
},
"hostname": "20",
"targetRef": {
"kind": "21",
"namespace": "22",
"name": "23",
"uid": "ɑ",
"apiVersion": "24",
"resourceVersion": "25",
"fieldPath": "26"
},
"topology": {
"27": "28"
},
"nodeName": "29"
}
],
"ports": [
{
"name": "30",
"protocol": "脽ěĂ凗蓏Ŋ蛊ĉy緅縕",
"port": -591435092,
"appProtocol": "31"
}
]
}

View File

@ -1,56 +0,0 @@
addressType: īqJ枊a8衍`Ĩɘ.蘯
apiVersion: discovery.k8s.io/v1alpha1
endpoints:
- addresses:
- "19"
conditions:
ready: false
serving: false
terminating: false
hostname: "20"
nodeName: "29"
targetRef:
apiVersion: "24"
fieldPath: "26"
kind: "21"
name: "23"
namespace: "22"
resourceVersion: "25"
uid: ɑ
topology:
"27": "28"
kind: EndpointSlice
metadata:
annotations:
"9": "10"
clusterName: "15"
creationTimestamp: null
deletionGracePeriodSeconds: -4955867275792137171
finalizers:
- "14"
generateName: "3"
generation: 8071137005907523419
labels:
"7": "8"
managedFields:
- apiVersion: "17"
fieldsType: "18"
manager: "16"
operation: 鐊唊飙Ş-U圴÷a/ɔ}摁(湗Ć]
name: "2"
namespace: "4"
ownerReferences:
- apiVersion: "11"
blockOwnerDeletion: true
controller: false
kind: "12"
name: "13"
uid: Dz廔ȇ{sŊƏp
resourceVersion: "11042405498087606203"
selfLink: "5"
uid: "7"
ports:
- appProtocol: "31"
name: "30"
port: -591435092
protocol: 脽ěĂ凗蓏Ŋ蛊ĉy緅縕

View File

@ -268,28 +268,46 @@ func CompatibilityTestFuzzer(scheme *runtime.Scheme, fuzzFuncs []interface{}) *f
}
func (c *CompatibilityTestOptions) Run(t *testing.T) {
usedHEADFixtures := sets.NewString()
for _, gvk := range c.Kinds {
t.Run(makeName(gvk), func(t *testing.T) {
t.Run("HEAD", func(t *testing.T) {
c.runCurrentVersionTest(t, gvk)
c.runCurrentVersionTest(t, gvk, usedHEADFixtures)
})
for _, previousVersionDir := range c.TestDataDirsPreviousVersions {
t.Run(filepath.Base(previousVersionDir), func(t *testing.T) {
c.runPreviousVersionTest(t, gvk, previousVersionDir)
c.runPreviousVersionTest(t, gvk, previousVersionDir, nil)
})
}
})
}
// Check for unused HEAD fixtures
t.Run("unused_fixtures", func(t *testing.T) {
files, err := os.ReadDir(c.TestDataDirCurrentVersion)
if err != nil {
t.Fatal(err)
}
allFixtures := sets.NewString()
for _, file := range files {
allFixtures.Insert(file.Name())
}
if unused := allFixtures.Difference(usedHEADFixtures); len(unused) > 0 {
t.Fatalf("remove unused fixtures from %s:\n%s", c.TestDataDirCurrentVersion, strings.Join(unused.List(), "\n"))
}
})
}
func (c *CompatibilityTestOptions) runCurrentVersionTest(t *testing.T, gvk schema.GroupVersionKind) {
func (c *CompatibilityTestOptions) runCurrentVersionTest(t *testing.T, gvk schema.GroupVersionKind, usedFiles sets.String) {
expectedObject := c.FuzzedObjects[gvk]
expectedJSON, expectedYAML, expectedProto := c.encode(t, expectedObject)
actualJSON, actualYAML, actualProto, err := read(c.TestDataDirCurrentVersion, gvk, "")
actualJSON, actualYAML, actualProto, err := read(c.TestDataDirCurrentVersion, gvk, "", usedFiles)
if err != nil && !os.IsNotExist(err) {
t.Fatal(err)
}
@ -387,10 +405,18 @@ func (c *CompatibilityTestOptions) encode(t *testing.T, obj runtime.Object) (jso
return jsonBytes.Bytes(), yamlBytes.Bytes(), protoBytes.Bytes()
}
func read(dir string, gvk schema.GroupVersionKind, suffix string) (json, yaml, proto []byte, err error) {
actualJSON, jsonErr := ioutil.ReadFile(filepath.Join(dir, makeName(gvk)+suffix+".json"))
actualYAML, yamlErr := ioutil.ReadFile(filepath.Join(dir, makeName(gvk)+suffix+".yaml"))
actualProto, protoErr := ioutil.ReadFile(filepath.Join(dir, makeName(gvk)+suffix+".pb"))
func read(dir string, gvk schema.GroupVersionKind, suffix string, usedFiles sets.String) (json, yaml, proto []byte, err error) {
jsonFilename := makeName(gvk) + suffix + ".json"
actualJSON, jsonErr := ioutil.ReadFile(filepath.Join(dir, jsonFilename))
yamlFilename := makeName(gvk) + suffix + ".yaml"
actualYAML, yamlErr := ioutil.ReadFile(filepath.Join(dir, yamlFilename))
protoFilename := makeName(gvk) + suffix + ".pb"
actualProto, protoErr := ioutil.ReadFile(filepath.Join(dir, protoFilename))
if usedFiles != nil {
usedFiles.Insert(jsonFilename)
usedFiles.Insert(yamlFilename)
usedFiles.Insert(protoFilename)
}
if jsonErr != nil {
return actualJSON, actualYAML, actualProto, jsonErr
}
@ -412,8 +438,8 @@ func writeFile(t *testing.T, dir string, gvk schema.GroupVersionKind, suffix, ex
}
}
func (c *CompatibilityTestOptions) runPreviousVersionTest(t *testing.T, gvk schema.GroupVersionKind, previousVersionDir string) {
jsonBeforeRoundTrip, yamlBeforeRoundTrip, protoBeforeRoundTrip, err := read(previousVersionDir, gvk, "")
func (c *CompatibilityTestOptions) runPreviousVersionTest(t *testing.T, gvk schema.GroupVersionKind, previousVersionDir string, usedFiles sets.String) {
jsonBeforeRoundTrip, yamlBeforeRoundTrip, protoBeforeRoundTrip, err := read(previousVersionDir, gvk, "", usedFiles)
if os.IsNotExist(err) || (len(jsonBeforeRoundTrip) == 0 && len(yamlBeforeRoundTrip) == 0 && len(protoBeforeRoundTrip) == 0) {
t.SkipNow()
return
@ -470,7 +496,7 @@ func (c *CompatibilityTestOptions) runPreviousVersionTest(t *testing.T, gvk sche
}
protoAfterRoundTrip := protoBytes.Bytes()
expectedJSONAfterRoundTrip, expectedYAMLAfterRoundTrip, expectedProtoAfterRoundTrip, _ := read(previousVersionDir, gvk, ".after_roundtrip")
expectedJSONAfterRoundTrip, expectedYAMLAfterRoundTrip, expectedProtoAfterRoundTrip, _ := read(previousVersionDir, gvk, ".after_roundtrip", usedFiles)
if len(expectedJSONAfterRoundTrip) == 0 {
expectedJSONAfterRoundTrip = jsonBeforeRoundTrip
}