Merge pull request #78656 from liggitt/compatibility-test-cleanup

Add helper script to regenerate API compatibility data, testdata README
This commit is contained in:
Kubernetes Prow Robot 2019-06-14 11:53:15 -07:00 committed by GitHub
commit 9f1548cdd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 160 additions and 0 deletions

View File

@ -48,6 +48,7 @@ BASH_TARGETS="
update-codegen
update-generated-runtime
update-generated-device-plugin
update-generated-api-compatibility-data
update-generated-docs
update-generated-swagger-docs
update-openapi-spec

View File

@ -0,0 +1,33 @@
#!/usr/bin/env bash
# Copyright 2019 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -o errexit
set -o nounset
set -o pipefail
KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
source "${KUBE_ROOT}/hack/lib/init.sh"
kube::golang::setup_env
# 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.
# We suppress the test failure that occurs when there are changes.
UPDATE_COMPATIBILITY_FIXTURE_DATA=true go test ./vendor/k8s.io/api -run //HEAD >/dev/null 2>&1 || true
# Now that we have regenerated data at HEAD, run the test without suppressing output or failures
go test ./vendor/k8s.io/api -run //HEAD -count=1

View File

@ -0,0 +1,126 @@
# API serialization compatibility tests
This directory tree contains serialized API objects in json, yaml, and protobuf formats.
## Current version
The `HEAD` subdirectory contains serialized API objects generated from the current commit:
```
HEAD/
<group>.<version>.<kind>.[json|yaml|pb]
```
To run serialization tests just for the current version:
```sh
go test ./vendor/k8s.io/api -run //HEAD
```
All three formats of a given group/version/kind are expected to decode successfully to identical objects,
and to round-trip back to serialized form with identical bytes.
Adding new fields or API types *is* expected to modify these fixtures. To regenerate them, run:
```sh
UPDATE_COMPATIBILITY_FIXTURE_DATA=true go test ./vendor/k8s.io/api -run //HEAD
```
## Previous versions
The vX.Y.Z subdirectories contain serialized API objects from previous releases:
```
vX.Y.Z/
<group>.<version>.<kind>.[json|yaml|pb]
```
All three formats of a given group/version/kind are expected to decode successfully to identical objects,
and to round-trip back to serialized form with identical bytes.
Adding new fields to existing API types is *not* expected to require modifications to these fixtures.
This requires making optional scalar and struct fields pointers so that protobuf serialization omits them when not present.
To run serialization tests just for a previous version, like `v1.14.0`:
```sh
go test ./vendor/k8s.io/api -run //v1.14.0
```
To run serialization tests for a particular group/version/kind, like `apps/v1` `Deployment`:
```sh
go test ./vendor/k8s.io/api -run /apps.v1.Deployment/
```
Failures to decode, to round-trip identical bytes, or to decode identical objects from json/yaml/protobuf,
will output detailed errors about the differences encountered. Detailed errors about protobuf differences
requires `protoc` to be available on your `$PATH`.
In exceptional cases, new non-pointer fields were added to existing API types that serialized zero values,
resulting in additional fields being output when round-tripping data from previous releases, and failing round-trip tests.
To resolve this, a `<group>.<version>.<kind>_after_roundtrip.[json|yaml|pb]` file containing the
expected data after roundtripping can be placed beside the serialized data file from a previous release.
These `after_roundtrip` files are generated by running the failing round-trip tests with `UPDATE_COMPATIBILITY_FIXTURE_DATA=true` set.
The detailed diff from the test failure should be included in the commit message, along with a reference
to the change that caused the failure. Updates to these files is exceptional, and requires extremely close review
to ensure we are not breaking backwards compatibility with serialized data from previous releases.
To see the diff between the original JSON/YAML data and the `...after_roundtrip...` files:
```sh
cd vendor/k8s.io/api/testdata/v1.14.0/
diff -u admission.k8s.io.v1beta1.AdmissionReview.json admission.k8s.io.v1beta1.AdmissionReview.after_roundtrip.json
diff -u admission.k8s.io.v1beta1.AdmissionReview.yaml admission.k8s.io.v1beta1.AdmissionReview.after_roundtrip.yaml
```
> ```diff
> --- admission.k8s.io.v1beta1.AdmissionReview.json 2019-06-02 20:21:03.000000000 -0400
> +++ admission.k8s.io.v1beta1.AdmissionReview.after_roundtrip.json 2019-06-02 20:21:03.000000000 -0400
> @@ -31,7 +31,8 @@
> },
> "object": {"apiVersion":"example.com/v1","kind":"CustomType","spec":{"replicas":1},"status":{"available":1}},
> "oldObject": {"apiVersion":"example.com/v1","kind":"CustomType","spec":{"replicas":1},"status":{"available":1}},
> - "dryRun": true
> + "dryRun": true,
> + "options": null
> },
> "response": {
> "uid": "爟¼ªov鈶",
> ```
> ```diff
> --- admission.k8s.io.v1beta1.AdmissionReview.yaml 2019-06-02 20:21:03.000000000 -0400
> +++ admission.k8s.io.v1beta1.AdmissionReview.after_roundtrip.yaml 2019-06-02 20:21:03.000000000 -0400
> @@ -23,6 +23,7 @@
> status:
> available: 1
> operation: 祈¡ıŵDz廔ȇ{sŊƏp饏姥呄鐊
> + options: null
> resource:
> group: "5"
> resource: "7"
> ```
To see the diff between the original proto data and the `...after_roundtrip...` file, you must have `protoc` available,
and strip off the leading four-byte kubernetes protobuf header to get standard protobuf that can be decoded:
```sh
cd vendor/k8s.io/api/testdata/v1.14.0/
diff -u \
<(tail -c +5 admission.k8s.io.v1beta1.AdmissionReview.pb | protoc --decode_raw) \
<(tail -c +5 admission.k8s.io.v1beta1.AdmissionReview.after_roundtrip.pb | protoc --decode_raw)
```
> ```diff
> --- /dev/fd/63 2019-06-03 11:56:12.000000000 -0400
> +++ /dev/fd/62 2019-06-03 11:56:12.000000000 -0400
> @@ -37,6 +37,8 @@
> 1: "{\"apiVersion\":\"example.com/v1\",\"kind\":\"CustomType\",\"spec\":{\"replicas\":1},\"status\":{\"available\":1}}"
> }
> 11: 1
> + 12: ""
> + 15: ""
> }
> 2 {
> 1: "\347\210\237\302\274\302\252ov\351\210\266"
> ```