Merge pull request #41439 from deads2k/apiserver-12-sample-fuzz

Automatic merge from submit-queue (batch tested with PRs 41104, 41245, 40722, 41439, 41502)

add sample fuzzing tests

Make fuzzing tests as simple as possible from both the API installer and the scheme, so its easy to add for api groups and so that I can build a scheme and then make sure I got it right.

@kubernetes/sig-api-machinery-pr-reviews @sttts @mikedanese
pull/6/head
Kubernetes Submit Queue 2017-02-15 16:28:11 -08:00 committed by GitHub
commit 92360ffc5f
16 changed files with 191 additions and 100 deletions

View File

@ -5,7 +5,6 @@ licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
@ -13,11 +12,14 @@ go_library(
srcs = [
"doc.go",
"env.go",
"fuzzer.go",
"register.go",
"types.go",
],
tags = ["automanaged"],
deps = [
"//vendor:github.com/google/gofuzz",
"//vendor:k8s.io/apimachinery/pkg/api/testing",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
@ -41,18 +43,3 @@ filegroup(
],
tags = ["automanaged"],
)
go_test(
name = "go_default_xtest",
srcs = ["serialization_test.go"],
tags = ["automanaged"],
deps = [
"//cmd/kubeadm/app/apis/kubeadm/install:go_default_library",
"//pkg/api/testing:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/testing",
"//vendor:k8s.io/apimachinery/pkg/apimachinery/announced",
"//vendor:k8s.io/apimachinery/pkg/apimachinery/registered",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/runtime/serializer",
],
)

View File

@ -0,0 +1,37 @@
/*
Copyright 2017 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.
*/
package kubeadm
import (
"github.com/google/gofuzz"
apitesting "k8s.io/apimachinery/pkg/api/testing"
)
func KubeadmFuzzerFuncs(t apitesting.TestingCommon) []interface{} {
return []interface{}{
func(obj *MasterConfiguration, c fuzz.Continue) {
c.FuzzNoCustom(obj)
obj.KubernetesVersion = "v10"
obj.API.Port = 20
obj.Networking.ServiceSubnet = "foo"
obj.Networking.DNSDomain = "foo"
obj.AuthorizationMode = "foo"
obj.Discovery.Token = &TokenDiscovery{}
},
}
}

View File

@ -5,6 +5,7 @@ licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
@ -36,3 +37,14 @@ filegroup(
srcs = [":package-srcs"],
tags = ["automanaged"],
)
go_test(
name = "go_default_test",
srcs = ["install_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/testing",
],
)

View File

@ -1,5 +1,5 @@
/*
Copyright 2016 The Kubernetes Authors.
Copyright 2017 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.
@ -14,16 +14,15 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
package install
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/pkg/api"
"testing"
apitesting "k8s.io/apimachinery/pkg/api/testing"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
)
func addConversionFuncs(scheme *runtime.Scheme) error {
// Add non-generated conversion functions
return scheme.AddConversionFuncs(
api.Convert_v1_TypeMeta_To_v1_TypeMeta,
)
func TestRoundTripTypes(t *testing.T) {
apitesting.RoundTripTestForAPIGroup(t, Install, kubeadm.KubeadmFuzzerFuncs(t))
}

View File

@ -50,7 +50,3 @@ func addKnownTypes(scheme *runtime.Scheme) error {
)
return nil
}
func (obj *MasterConfiguration) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *NodeConfiguration) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *ClusterInfo) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }

View File

@ -1,47 +0,0 @@
/*
Copyright 2016 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.
*/
package kubeadm_test
import (
"math/rand"
"testing"
apitesting "k8s.io/apimachinery/pkg/api/testing"
"k8s.io/apimachinery/pkg/apimachinery/announced"
"k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/install"
kapitesting "k8s.io/kubernetes/pkg/api/testing"
)
const (
seed = 1
)
func TestRoundTripTypes(t *testing.T) {
groupFactoryRegistry := make(announced.APIGroupFactoryRegistry)
registry := registered.NewOrDie("")
scheme := runtime.NewScheme()
codecs := serializer.NewCodecFactory(scheme)
install.Install(groupFactoryRegistry, registry, scheme)
// TODO: once we've pulled kubeadm types of the main scheme, we should
// move the fuzzers funcs here
fuzzer := apitesting.FuzzerFor(kapitesting.FuzzerFuncs(t, codecs), rand.NewSource(seed))
apitesting.RoundTripTypesWithoutProtobuf(t, scheme, codecs, fuzzer, nil)
}

View File

@ -10,7 +10,6 @@ load(
go_library(
name = "go_default_library",
srcs = [
"conversion.go",
"defaults.go",
"doc.go",
"register.go",
@ -22,7 +21,6 @@ go_library(
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/client-go/pkg/api",
],
)

View File

@ -29,7 +29,7 @@ const GroupName = "kubeadm.k8s.io"
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
var (
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes, addDefaultingFuncs, addConversionFuncs)
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes, addDefaultingFuncs)
AddToScheme = SchemeBuilder.AddToScheme
)
@ -52,7 +52,3 @@ func addKnownTypes(scheme *runtime.Scheme) error {
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}
func (obj *MasterConfiguration) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *NodeConfiguration) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *ClusterInfo) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }

View File

@ -16,7 +16,6 @@ cmd/kube-controller-manager/app/options
cmd/kube-discovery
cmd/kube-proxy
cmd/kubeadm
cmd/kubeadm/app/apis/kubeadm
cmd/kubeadm/app/apis/kubeadm/install
cmd/kubeadm/app/phases/apiconfig
cmd/kubeadm/app/phases/certs

View File

@ -70,6 +70,9 @@ kube::test::find_dirs() {
find ./staging/src/k8s.io/kube-aggregator -name '*_test.go' \
-name '*_test.go' -print0 | xargs -0n1 dirname | sed 's|^\./staging/src/|./vendor/|' | LC_ALL=C sort -u
find ./staging/src/k8s.io/sample-apiserver -name '*_test.go' \
-name '*_test.go' -print0 | xargs -0n1 dirname | sed 's|^\./staging/src/|./vendor/|' | LC_ALL=C sort -u
)
}

View File

@ -610,20 +610,6 @@ func rbacFuncs(t apitesting.TestingCommon) []interface{} {
}
}
func kubeAdmFuncs(t apitesting.TestingCommon) []interface{} {
return []interface{}{
func(obj *kubeadm.MasterConfiguration, c fuzz.Continue) {
c.FuzzNoCustom(obj)
obj.KubernetesVersion = "v10"
obj.API.Port = 20
obj.Networking.ServiceSubnet = "foo"
obj.Networking.DNSDomain = "foo"
obj.AuthorizationMode = "foo"
obj.Discovery.Token = &kubeadm.TokenDiscovery{}
},
}
}
func policyFuncs(t apitesting.TestingCommon) []interface{} {
return []interface{}{
func(s *policy.PodDisruptionBudgetStatus, c fuzz.Continue) {
@ -651,7 +637,7 @@ func FuzzerFuncs(t apitesting.TestingCommon, codecs runtimeserializer.CodecFacto
batchFuncs(t),
autoscalingFuncs(t),
rbacFuncs(t),
kubeAdmFuncs(t),
kubeadm.KubeadmFuzzerFuncs(t),
policyFuncs(t),
certificateFuncs(t),
)

View File

@ -24,11 +24,11 @@ import (
"github.com/google/gofuzz"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/api/resource"
)
func GenericFuzzerFuncs(t TestingCommon, codecs runtimeserializer.CodecFactory) []interface{} {
@ -159,3 +159,16 @@ func MergeFuzzerFuncs(t TestingCommon, funcLists ...[]interface{}) []interface{}
}
return result
}
func DefaultFuzzers(t TestingCommon, codecFactory runtimeserializer.CodecFactory, fuzzerFuncs []interface{}) *fuzz.Fuzzer {
seed := rand.Int63()
return FuzzerFor(
MergeFuzzerFuncs(t,
GenericFuzzerFuncs(t, codecFactory),
fuzzerFuncs,
),
rand.NewSource(seed),
)
}

View File

@ -31,6 +31,8 @@ import (
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apimachinery/announced"
"k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
@ -38,6 +40,44 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
)
type InstallFunc func(groupFactoryRegistry announced.APIGroupFactoryRegistry, registry *registered.APIRegistrationManager, scheme *runtime.Scheme)
// RoundTripTestForAPIGroup is convenient to call from your install package to make sure that a "bare" install of your group provides
// enough information to round trip
func RoundTripTestForAPIGroup(t *testing.T, installFn InstallFunc, fuzzingFuncs []interface{}) {
groupFactoryRegistry := make(announced.APIGroupFactoryRegistry)
registry := registered.NewOrDie("")
scheme := runtime.NewScheme()
installFn(groupFactoryRegistry, registry, scheme)
RoundTripTestForScheme(t, scheme, fuzzingFuncs)
}
// RoundTripTestForScheme is convenient to call if you already have a scheme and want to make sure that its well-formed
func RoundTripTestForScheme(t *testing.T, scheme *runtime.Scheme, fuzzingFuncs []interface{}) {
codecFactory := runtimeserializer.NewCodecFactory(scheme)
fuzzer := DefaultFuzzers(t, codecFactory, fuzzingFuncs)
RoundTripTypesWithoutProtobuf(t, scheme, codecFactory, fuzzer, nil)
}
// RoundTripProtobufTestForAPIGroup is convenient to call from your install package to make sure that a "bare" install of your group provides
// enough information to round trip
func RoundTripProtobufTestForAPIGroup(t *testing.T, installFn InstallFunc, fuzzingFuncs []interface{}) {
groupFactoryRegistry := make(announced.APIGroupFactoryRegistry)
registry := registered.NewOrDie("")
scheme := runtime.NewScheme()
installFn(groupFactoryRegistry, registry, scheme)
RoundTripProtobufTestForScheme(t, scheme, fuzzingFuncs)
}
// RoundTripProtobufTestForScheme is convenient to call if you already have a scheme and want to make sure that its well-formed
func RoundTripProtobufTestForScheme(t *testing.T, scheme *runtime.Scheme, fuzzingFuncs []interface{}) {
codecFactory := runtimeserializer.NewCodecFactory(scheme)
fuzzer := DefaultFuzzers(t, codecFactory, fuzzingFuncs)
RoundTripTypes(t, scheme, codecFactory, fuzzer, nil)
}
var FuzzIters = flag.Int("fuzz-iters", 20, "How many fuzzing iterations to do.")
// globalNonRoundTrippableTypes are kinds that are effectively reserved across all GroupVersions

View File

@ -0,0 +1,27 @@
/*
Copyright 2017 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.
*/
package install
import (
"testing"
apitesting "k8s.io/apimachinery/pkg/api/testing"
)
func TestRoundTripTypes(t *testing.T) {
apitesting.RoundTripTestForAPIGroup(t, Install, nil)
}

View File

@ -0,0 +1,27 @@
/*
Copyright 2017 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.
*/
package apiserver
import (
"testing"
apitesting "k8s.io/apimachinery/pkg/api/testing"
)
func TestRoundTripTypes(t *testing.T) {
apitesting.RoundTripTestForScheme(t, Scheme, nil)
}

18
vendor/BUILD vendored
View File

@ -13861,6 +13861,8 @@ go_library(
"//vendor:k8s.io/apimachinery/pkg/api/equality",
"//vendor:k8s.io/apimachinery/pkg/api/meta",
"//vendor:k8s.io/apimachinery/pkg/api/resource",
"//vendor:k8s.io/apimachinery/pkg/apimachinery/announced",
"//vendor:k8s.io/apimachinery/pkg/apimachinery/registered",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
@ -16879,3 +16881,19 @@ go_library(
"//vendor:k8s.io/apiserver/pkg/storage/storagebackend",
],
)
go_test(
name = "k8s.io/sample-apiserver/pkg/apis/wardle/install_test",
srcs = ["k8s.io/sample-apiserver/pkg/apis/wardle/install/install_test.go"],
library = ":k8s.io/sample-apiserver/pkg/apis/wardle/install",
tags = ["automanaged"],
deps = ["//vendor:k8s.io/apimachinery/pkg/api/testing"],
)
go_test(
name = "k8s.io/sample-apiserver/pkg/apiserver_test",
srcs = ["k8s.io/sample-apiserver/pkg/apiserver/scheme_test.go"],
library = ":k8s.io/sample-apiserver/pkg/apiserver",
tags = ["automanaged"],
deps = ["//vendor:k8s.io/apimachinery/pkg/api/testing"],
)