Random unrelated vendor

This commit is contained in:
Antoine Pelisse 2019-01-16 21:14:58 -08:00
parent 0e1d50e70f
commit 7e4cc38401
4 changed files with 340 additions and 31 deletions

6
vendor/BUILD vendored
View File

@ -467,6 +467,7 @@ filegroup(
"//vendor/k8s.io/kube-openapi/pkg/common:all-srcs", "//vendor/k8s.io/kube-openapi/pkg/common:all-srcs",
"//vendor/k8s.io/kube-openapi/pkg/generators:all-srcs", "//vendor/k8s.io/kube-openapi/pkg/generators:all-srcs",
"//vendor/k8s.io/kube-openapi/pkg/handler:all-srcs", "//vendor/k8s.io/kube-openapi/pkg/handler:all-srcs",
"//vendor/k8s.io/kube-openapi/pkg/schemaconv:all-srcs",
"//vendor/k8s.io/kube-openapi/pkg/util:all-srcs", "//vendor/k8s.io/kube-openapi/pkg/util:all-srcs",
"//vendor/k8s.io/repo-infra/kazel:all-srcs", "//vendor/k8s.io/repo-infra/kazel:all-srcs",
"//vendor/k8s.io/utils/buffer:all-srcs", "//vendor/k8s.io/utils/buffer:all-srcs",
@ -481,6 +482,11 @@ filegroup(
"//vendor/k8s.io/utils/pointer:all-srcs", "//vendor/k8s.io/utils/pointer:all-srcs",
"//vendor/k8s.io/utils/strings:all-srcs", "//vendor/k8s.io/utils/strings:all-srcs",
"//vendor/k8s.io/utils/trace:all-srcs", "//vendor/k8s.io/utils/trace:all-srcs",
"//vendor/sigs.k8s.io/structured-merge-diff/fieldpath:all-srcs",
"//vendor/sigs.k8s.io/structured-merge-diff/merge:all-srcs",
"//vendor/sigs.k8s.io/structured-merge-diff/schema:all-srcs",
"//vendor/sigs.k8s.io/structured-merge-diff/typed:all-srcs",
"//vendor/sigs.k8s.io/structured-merge-diff/value:all-srcs",
"//vendor/sigs.k8s.io/yaml:all-srcs", "//vendor/sigs.k8s.io/yaml:all-srcs",
"//vendor/vbom.ml/util/sortorder:all-srcs", "//vendor/vbom.ml/util/sortorder:all-srcs",
], ],

View File

@ -34,21 +34,27 @@ type Fuzzer struct {
nilChance float64 nilChance float64
minElements int minElements int
maxElements int maxElements int
maxDepth int
} }
// New returns a new Fuzzer. Customize your Fuzzer further by calling Funcs, // New returns a new Fuzzer. Customize your Fuzzer further by calling Funcs,
// RandSource, NilChance, or NumElements in any order. // RandSource, NilChance, or NumElements in any order.
func New() *Fuzzer { func New() *Fuzzer {
return NewWithSeed(time.Now().UnixNano())
}
func NewWithSeed(seed int64) *Fuzzer {
f := &Fuzzer{ f := &Fuzzer{
defaultFuzzFuncs: fuzzFuncMap{ defaultFuzzFuncs: fuzzFuncMap{
reflect.TypeOf(&time.Time{}): reflect.ValueOf(fuzzTime), reflect.TypeOf(&time.Time{}): reflect.ValueOf(fuzzTime),
}, },
fuzzFuncs: fuzzFuncMap{}, fuzzFuncs: fuzzFuncMap{},
r: rand.New(rand.NewSource(time.Now().UnixNano())), r: rand.New(rand.NewSource(seed)),
nilChance: .2, nilChance: .2,
minElements: 1, minElements: 1,
maxElements: 10, maxElements: 10,
maxDepth: 100,
} }
return f return f
} }
@ -136,6 +142,14 @@ func (f *Fuzzer) genShouldFill() bool {
return f.r.Float64() > f.nilChance return f.r.Float64() > f.nilChance
} }
// MaxDepth sets the maximum number of recursive fuzz calls that will be made
// before stopping. This includes struct members, pointers, and map and slice
// elements.
func (f *Fuzzer) MaxDepth(d int) *Fuzzer {
f.maxDepth = d
return f
}
// Fuzz recursively fills all of obj's fields with something random. First // Fuzz recursively fills all of obj's fields with something random. First
// this tries to find a custom fuzz function (see Funcs). If there is no // this tries to find a custom fuzz function (see Funcs). If there is no
// custom function this tests whether the object implements fuzz.Interface and, // custom function this tests whether the object implements fuzz.Interface and,
@ -144,17 +158,19 @@ func (f *Fuzzer) genShouldFill() bool {
// fails, this will generate random values for all primitive fields and then // fails, this will generate random values for all primitive fields and then
// recurse for all non-primitives. // recurse for all non-primitives.
// //
// Not safe for cyclic or tree-like structs! // This is safe for cyclic or tree-like structs, up to a limit. Use the
// MaxDepth method to adjust how deep you need it to recurse.
// //
// obj must be a pointer. Only exported (public) fields can be set (thanks, golang :/ ) // obj must be a pointer. Only exported (public) fields can be set (thanks,
// Intended for tests, so will panic on bad input or unimplemented fields. // golang :/ ) Intended for tests, so will panic on bad input or unimplemented
// fields.
func (f *Fuzzer) Fuzz(obj interface{}) { func (f *Fuzzer) Fuzz(obj interface{}) {
v := reflect.ValueOf(obj) v := reflect.ValueOf(obj)
if v.Kind() != reflect.Ptr { if v.Kind() != reflect.Ptr {
panic("needed ptr!") panic("needed ptr!")
} }
v = v.Elem() v = v.Elem()
f.doFuzz(v, 0) f.fuzzWithContext(v, 0)
} }
// FuzzNoCustom is just like Fuzz, except that any custom fuzz function for // FuzzNoCustom is just like Fuzz, except that any custom fuzz function for
@ -170,7 +186,7 @@ func (f *Fuzzer) FuzzNoCustom(obj interface{}) {
panic("needed ptr!") panic("needed ptr!")
} }
v = v.Elem() v = v.Elem()
f.doFuzz(v, flagNoCustomFuzz) f.fuzzWithContext(v, flagNoCustomFuzz)
} }
const ( const (
@ -178,69 +194,87 @@ const (
flagNoCustomFuzz uint64 = 1 << iota flagNoCustomFuzz uint64 = 1 << iota
) )
func (f *Fuzzer) doFuzz(v reflect.Value, flags uint64) { func (f *Fuzzer) fuzzWithContext(v reflect.Value, flags uint64) {
fc := &fuzzerContext{fuzzer: f}
fc.doFuzz(v, flags)
}
// fuzzerContext carries context about a single fuzzing run, which lets Fuzzer
// be thread-safe.
type fuzzerContext struct {
fuzzer *Fuzzer
curDepth int
}
func (fc *fuzzerContext) doFuzz(v reflect.Value, flags uint64) {
if fc.curDepth >= fc.fuzzer.maxDepth {
return
}
fc.curDepth++
defer func() { fc.curDepth-- }()
if !v.CanSet() { if !v.CanSet() {
return return
} }
if flags&flagNoCustomFuzz == 0 { if flags&flagNoCustomFuzz == 0 {
// Check for both pointer and non-pointer custom functions. // Check for both pointer and non-pointer custom functions.
if v.CanAddr() && f.tryCustom(v.Addr()) { if v.CanAddr() && fc.tryCustom(v.Addr()) {
return return
} }
if f.tryCustom(v) { if fc.tryCustom(v) {
return return
} }
} }
if fn, ok := fillFuncMap[v.Kind()]; ok { if fn, ok := fillFuncMap[v.Kind()]; ok {
fn(v, f.r) fn(v, fc.fuzzer.r)
return return
} }
switch v.Kind() { switch v.Kind() {
case reflect.Map: case reflect.Map:
if f.genShouldFill() { if fc.fuzzer.genShouldFill() {
v.Set(reflect.MakeMap(v.Type())) v.Set(reflect.MakeMap(v.Type()))
n := f.genElementCount() n := fc.fuzzer.genElementCount()
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
key := reflect.New(v.Type().Key()).Elem() key := reflect.New(v.Type().Key()).Elem()
f.doFuzz(key, 0) fc.doFuzz(key, 0)
val := reflect.New(v.Type().Elem()).Elem() val := reflect.New(v.Type().Elem()).Elem()
f.doFuzz(val, 0) fc.doFuzz(val, 0)
v.SetMapIndex(key, val) v.SetMapIndex(key, val)
} }
return return
} }
v.Set(reflect.Zero(v.Type())) v.Set(reflect.Zero(v.Type()))
case reflect.Ptr: case reflect.Ptr:
if f.genShouldFill() { if fc.fuzzer.genShouldFill() {
v.Set(reflect.New(v.Type().Elem())) v.Set(reflect.New(v.Type().Elem()))
f.doFuzz(v.Elem(), 0) fc.doFuzz(v.Elem(), 0)
return return
} }
v.Set(reflect.Zero(v.Type())) v.Set(reflect.Zero(v.Type()))
case reflect.Slice: case reflect.Slice:
if f.genShouldFill() { if fc.fuzzer.genShouldFill() {
n := f.genElementCount() n := fc.fuzzer.genElementCount()
v.Set(reflect.MakeSlice(v.Type(), n, n)) v.Set(reflect.MakeSlice(v.Type(), n, n))
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
f.doFuzz(v.Index(i), 0) fc.doFuzz(v.Index(i), 0)
} }
return return
} }
v.Set(reflect.Zero(v.Type())) v.Set(reflect.Zero(v.Type()))
case reflect.Array: case reflect.Array:
if f.genShouldFill() { if fc.fuzzer.genShouldFill() {
n := v.Len() n := v.Len()
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
f.doFuzz(v.Index(i), 0) fc.doFuzz(v.Index(i), 0)
} }
return return
} }
v.Set(reflect.Zero(v.Type())) v.Set(reflect.Zero(v.Type()))
case reflect.Struct: case reflect.Struct:
for i := 0; i < v.NumField(); i++ { for i := 0; i < v.NumField(); i++ {
f.doFuzz(v.Field(i), 0) fc.doFuzz(v.Field(i), 0)
} }
case reflect.Chan: case reflect.Chan:
fallthrough fallthrough
@ -255,20 +289,20 @@ func (f *Fuzzer) doFuzz(v reflect.Value, flags uint64) {
// tryCustom searches for custom handlers, and returns true iff it finds a match // tryCustom searches for custom handlers, and returns true iff it finds a match
// and successfully randomizes v. // and successfully randomizes v.
func (f *Fuzzer) tryCustom(v reflect.Value) bool { func (fc *fuzzerContext) tryCustom(v reflect.Value) bool {
// First: see if we have a fuzz function for it. // First: see if we have a fuzz function for it.
doCustom, ok := f.fuzzFuncs[v.Type()] doCustom, ok := fc.fuzzer.fuzzFuncs[v.Type()]
if !ok { if !ok {
// Second: see if it can fuzz itself. // Second: see if it can fuzz itself.
if v.CanInterface() { if v.CanInterface() {
intf := v.Interface() intf := v.Interface()
if fuzzable, ok := intf.(Interface); ok { if fuzzable, ok := intf.(Interface); ok {
fuzzable.Fuzz(Continue{f: f, Rand: f.r}) fuzzable.Fuzz(Continue{fc: fc, Rand: fc.fuzzer.r})
return true return true
} }
} }
// Finally: see if there is a default fuzz function. // Finally: see if there is a default fuzz function.
doCustom, ok = f.defaultFuzzFuncs[v.Type()] doCustom, ok = fc.fuzzer.defaultFuzzFuncs[v.Type()]
if !ok { if !ok {
return false return false
} }
@ -294,8 +328,8 @@ func (f *Fuzzer) tryCustom(v reflect.Value) bool {
} }
doCustom.Call([]reflect.Value{v, reflect.ValueOf(Continue{ doCustom.Call([]reflect.Value{v, reflect.ValueOf(Continue{
f: f, fc: fc,
Rand: f.r, Rand: fc.fuzzer.r,
})}) })})
return true return true
} }
@ -310,7 +344,7 @@ type Interface interface {
// Continue can be passed to custom fuzzing functions to allow them to use // Continue can be passed to custom fuzzing functions to allow them to use
// the correct source of randomness and to continue fuzzing their members. // the correct source of randomness and to continue fuzzing their members.
type Continue struct { type Continue struct {
f *Fuzzer fc *fuzzerContext
// For convenience, Continue implements rand.Rand via embedding. // For convenience, Continue implements rand.Rand via embedding.
// Use this for generating any randomness if you want your fuzzing // Use this for generating any randomness if you want your fuzzing
@ -325,7 +359,7 @@ func (c Continue) Fuzz(obj interface{}) {
panic("needed ptr!") panic("needed ptr!")
} }
v = v.Elem() v = v.Elem()
c.f.doFuzz(v, 0) c.fc.doFuzz(v, 0)
} }
// FuzzNoCustom continues fuzzing obj, except that any custom fuzz function for // FuzzNoCustom continues fuzzing obj, except that any custom fuzz function for
@ -338,7 +372,7 @@ func (c Continue) FuzzNoCustom(obj interface{}) {
panic("needed ptr!") panic("needed ptr!")
} }
v = v.Elem() v = v.Elem()
c.f.doFuzz(v, flagNoCustomFuzz) c.fc.doFuzz(v, flagNoCustomFuzz)
} }
// RandString makes a random string up to 20 characters long. The returned string // RandString makes a random string up to 20 characters long. The returned string

27
vendor/k8s.io/kube-openapi/pkg/schemaconv/BUILD generated vendored Normal file
View File

@ -0,0 +1,27 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["smd.go"],
importmap = "k8s.io/kubernetes/vendor/k8s.io/kube-openapi/pkg/schemaconv",
importpath = "k8s.io/kube-openapi/pkg/schemaconv",
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
"//vendor/sigs.k8s.io/structured-merge-diff/schema:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

242
vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go generated vendored Normal file
View File

@ -0,0 +1,242 @@
/*
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 schemaconv
import (
"errors"
"fmt"
"path"
"strings"
"k8s.io/kube-openapi/pkg/util/proto"
"sigs.k8s.io/structured-merge-diff/schema"
)
// ToSchema converts openapi definitions into a schema suitable for structured
// merge (i.e. kubectl apply v2).
func ToSchema(models proto.Models) (*schema.Schema, error) {
c := convert{
input: models,
output: &schema.Schema{},
}
if err := c.convertAll(); err != nil {
return nil, err
}
return c.output, nil
}
type convert struct {
input proto.Models
output *schema.Schema
currentName string
current *schema.Atom
errorMessages []string
}
func (c *convert) push(name string, a *schema.Atom) *convert {
return &convert{
input: c.input,
output: c.output,
currentName: name,
current: a,
}
}
func (c *convert) top() *schema.Atom { return c.current }
func (c *convert) pop(c2 *convert) {
c.errorMessages = append(c.errorMessages, c2.errorMessages...)
}
func (c *convert) convertAll() error {
for _, name := range c.input.ListModels() {
model := c.input.LookupModel(name)
c.insertTypeDef(name, model)
}
if len(c.errorMessages) > 0 {
return errors.New(strings.Join(c.errorMessages, "\n"))
}
return nil
}
func (c *convert) reportError(format string, args ...interface{}) {
c.errorMessages = append(c.errorMessages,
c.currentName+": "+fmt.Sprintf(format, args...),
)
}
func (c *convert) insertTypeDef(name string, model proto.Schema) {
def := schema.TypeDef{
Name: name,
}
c2 := c.push(name, &def.Atom)
model.Accept(c2)
c.pop(c2)
if def.Atom == (schema.Atom{}) {
// This could happen if there were a top-level reference.
return
}
c.output.Types = append(c.output.Types, def)
}
func (c *convert) makeRef(model proto.Schema) schema.TypeRef {
var tr schema.TypeRef
if r, ok := model.(*proto.Ref); ok {
// reference a named type
_, n := path.Split(r.Reference())
tr.NamedType = &n
} else {
// compute the type inline
c2 := c.push("inlined in "+c.currentName, &tr.Inlined)
model.Accept(c2)
c.pop(c2)
if tr == (schema.TypeRef{}) {
// emit warning?
tr.Inlined.Untyped = &schema.Untyped{}
}
}
return tr
}
func (c *convert) VisitKind(k *proto.Kind) {
a := c.top()
a.Struct = &schema.Struct{}
for _, name := range k.FieldOrder {
member := k.Fields[name]
tr := c.makeRef(member)
a.Struct.Fields = append(a.Struct.Fields, schema.StructField{
Name: name,
Type: tr,
})
}
// TODO: Get element relationship when we start adding it to the spec.
}
func toStringSlice(o interface{}) (out []string, ok bool) {
switch t := o.(type) {
case []interface{}:
for _, v := range t {
switch vt := v.(type) {
case string:
out = append(out, vt)
}
}
return out, true
}
return nil, false
}
func (c *convert) VisitArray(a *proto.Array) {
atom := c.top()
atom.List = &schema.List{
ElementRelationship: schema.Atomic,
}
l := atom.List
l.ElementType = c.makeRef(a.SubType)
ext := a.GetExtensions()
if val, ok := ext["x-kubernetes-list-type"]; ok {
if val == "atomic" {
l.ElementRelationship = schema.Atomic
} else if val == "set" {
l.ElementRelationship = schema.Associative
} else if val == "map" {
l.ElementRelationship = schema.Associative
if keys, ok := ext["x-kubernetes-list-map-keys"]; ok {
if keyNames, ok := toStringSlice(keys); ok {
l.Keys = keyNames
} else {
c.reportError("uninterpreted map keys: %#v", keys)
}
} else {
c.reportError("missing map keys")
}
} else {
c.reportError("unknown list type %v", val)
l.ElementRelationship = schema.Atomic
}
} else if val, ok := ext["x-kubernetes-patch-strategy"]; ok {
if val == "merge" || val == "merge,retainKeys" {
l.ElementRelationship = schema.Associative
if key, ok := ext["x-kubernetes-patch-merge-key"]; ok {
if keyName, ok := key.(string); ok {
l.Keys = []string{keyName}
} else {
c.reportError("uninterpreted merge key: %#v", key)
}
} else {
// It's not an error for this to be absent, it
// means it's a set.
}
} else if val == "retainKeys" {
} else {
c.reportError("unknown patch strategy %v", val)
l.ElementRelationship = schema.Atomic
}
}
}
func (c *convert) VisitMap(m *proto.Map) {
a := c.top()
a.Map = &schema.Map{}
a.Map.ElementType = c.makeRef(m.SubType)
// TODO: Get element relationship when we start putting it into the
// spec.
}
func (c *convert) VisitPrimitive(p *proto.Primitive) {
a := c.top()
ptr := func(s schema.Scalar) *schema.Scalar { return &s }
switch p.Type {
case proto.Integer:
a.Scalar = ptr(schema.Numeric)
case proto.Number:
a.Scalar = ptr(schema.Numeric)
case proto.String:
switch p.Format {
case "":
a.Scalar = ptr(schema.String)
case "byte":
// byte really means []byte and is encoded as a string.
a.Scalar = ptr(schema.String)
case "int-or-string":
a.Untyped = &schema.Untyped{}
case "date-time":
a.Untyped = &schema.Untyped{}
default:
a.Untyped = &schema.Untyped{}
}
case proto.Boolean:
a.Scalar = ptr(schema.Boolean)
default:
a.Untyped = &schema.Untyped{}
}
}
func (c *convert) VisitArbitrary(a *proto.Arbitrary) {
c.top().Untyped = &schema.Untyped{}
}
func (c *convert) VisitReference(proto.Reference) {
// Do nothing, we handle references specially
}