Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
0a743531
Commit
0a743531
authored
Feb 09, 2017
by
deads2k
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
make round trip testing generic
parent
46becf2c
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
269 additions
and
176 deletions
+269
-176
BUILD
pkg/api/BUILD
+0
-2
copy_test.go
pkg/api/copy_test.go
+2
-2
defaulting_test.go
pkg/api/defaulting_test.go
+2
-1
serialization_proto_test.go
pkg/api/serialization_proto_test.go
+0
-16
serialization_test.go
pkg/api/serialization_test.go
+10
-155
roundtrip.go
staging/src/k8s.io/apimachinery/pkg/api/testing/roundtrip.go
+246
-0
BUILD
vendor/BUILD
+9
-0
No files found.
pkg/api/BUILD
View file @
0a743531
...
@@ -84,11 +84,9 @@ go_test(
...
@@ -84,11 +84,9 @@ go_test(
"//pkg/apis/batch/v2alpha1:go_default_library",
"//pkg/apis/batch/v2alpha1:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/apis/extensions/v1beta1:go_default_library",
"//pkg/apis/extensions/v1beta1:go_default_library",
"//vendor:github.com/davecgh/go-spew/spew",
"//vendor:github.com/gogo/protobuf/proto",
"//vendor:github.com/gogo/protobuf/proto",
"//vendor:github.com/golang/protobuf/proto",
"//vendor:github.com/golang/protobuf/proto",
"//vendor:github.com/google/gofuzz",
"//vendor:github.com/google/gofuzz",
"//vendor:github.com/spf13/pflag",
"//vendor:github.com/ugorji/go/codec",
"//vendor:github.com/ugorji/go/codec",
"//vendor:k8s.io/apimachinery/pkg/api/equality",
"//vendor:k8s.io/apimachinery/pkg/api/equality",
"//vendor:k8s.io/apimachinery/pkg/api/meta",
"//vendor:k8s.io/apimachinery/pkg/api/meta",
...
...
pkg/api/copy_test.go
View file @
0a743531
...
@@ -33,7 +33,7 @@ import (
...
@@ -33,7 +33,7 @@ import (
)
)
func
TestDeepCopyApiObjects
(
t
*
testing
.
T
)
{
func
TestDeepCopyApiObjects
(
t
*
testing
.
T
)
{
for
i
:=
0
;
i
<
*
f
uzzIters
;
i
++
{
for
i
:=
0
;
i
<
*
apitesting
.
F
uzzIters
;
i
++
{
for
_
,
version
:=
range
[]
schema
.
GroupVersion
{
testapi
.
Default
.
InternalGroupVersion
(),
api
.
Registry
.
GroupOrDie
(
api
.
GroupName
)
.
GroupVersion
}
{
for
_
,
version
:=
range
[]
schema
.
GroupVersion
{
testapi
.
Default
.
InternalGroupVersion
(),
api
.
Registry
.
GroupOrDie
(
api
.
GroupName
)
.
GroupVersion
}
{
f
:=
apitesting
.
FuzzerFor
(
kapitesting
.
FuzzerFuncs
(
t
,
api
.
Codecs
),
rand
.
NewSource
(
rand
.
Int63
()))
f
:=
apitesting
.
FuzzerFor
(
kapitesting
.
FuzzerFuncs
(
t
,
api
.
Codecs
),
rand
.
NewSource
(
rand
.
Int63
()))
for
kind
:=
range
api
.
Scheme
.
KnownTypes
(
version
)
{
for
kind
:=
range
api
.
Scheme
.
KnownTypes
(
version
)
{
...
@@ -82,7 +82,7 @@ func doDeepCopyTest(t *testing.T, kind schema.GroupVersionKind, f *fuzz.Fuzzer)
...
@@ -82,7 +82,7 @@ func doDeepCopyTest(t *testing.T, kind schema.GroupVersionKind, f *fuzz.Fuzzer)
}
}
func
TestDeepCopySingleType
(
t
*
testing
.
T
)
{
func
TestDeepCopySingleType
(
t
*
testing
.
T
)
{
for
i
:=
0
;
i
<
*
f
uzzIters
;
i
++
{
for
i
:=
0
;
i
<
*
apitesting
.
F
uzzIters
;
i
++
{
for
_
,
version
:=
range
[]
schema
.
GroupVersion
{
testapi
.
Default
.
InternalGroupVersion
(),
api
.
Registry
.
GroupOrDie
(
api
.
GroupName
)
.
GroupVersion
}
{
for
_
,
version
:=
range
[]
schema
.
GroupVersion
{
testapi
.
Default
.
InternalGroupVersion
(),
api
.
Registry
.
GroupOrDie
(
api
.
GroupName
)
.
GroupVersion
}
{
f
:=
apitesting
.
FuzzerFor
(
kapitesting
.
FuzzerFuncs
(
t
,
api
.
Codecs
),
rand
.
NewSource
(
rand
.
Int63
()))
f
:=
apitesting
.
FuzzerFor
(
kapitesting
.
FuzzerFuncs
(
t
,
api
.
Codecs
),
rand
.
NewSource
(
rand
.
Int63
()))
doDeepCopyTest
(
t
,
version
.
WithKind
(
"Pod"
),
f
)
doDeepCopyTest
(
t
,
version
.
WithKind
(
"Pod"
),
f
)
...
...
pkg/api/defaulting_test.go
View file @
0a743531
...
@@ -24,6 +24,7 @@ import (
...
@@ -24,6 +24,7 @@ import (
"github.com/google/gofuzz"
"github.com/google/gofuzz"
apitesting
"k8s.io/apimachinery/pkg/api/testing"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/schema"
...
@@ -149,7 +150,7 @@ func TestDefaulting(t *testing.T) {
...
@@ -149,7 +150,7 @@ func TestDefaulting(t *testing.T) {
iter
:=
0
iter
:=
0
changedOnce
:=
false
changedOnce
:=
false
for
{
for
{
if
iter
>
*
f
uzzIters
{
if
iter
>
*
apitesting
.
F
uzzIters
{
if
!
expectedChanged
||
changedOnce
{
if
!
expectedChanged
||
changedOnce
{
break
break
}
}
...
...
pkg/api/serialization_proto_test.go
View file @
0a743531
...
@@ -30,29 +30,13 @@ import (
...
@@ -30,29 +30,13 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer/protobuf"
"k8s.io/apimachinery/pkg/runtime/serializer/protobuf"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
kapitesting
"k8s.io/kubernetes/pkg/api/testing"
kapitesting
"k8s.io/kubernetes/pkg/api/testing"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/api/v1"
_
"k8s.io/kubernetes/pkg/apis/extensions"
_
"k8s.io/kubernetes/pkg/apis/extensions"
_
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
_
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
)
)
var
nonProtobaleAPIGroups
=
sets
.
NewString
(
"kubeadm.k8s.io"
,
)
func
init
()
{
codecsToTest
=
append
(
codecsToTest
,
func
(
version
schema
.
GroupVersion
,
item
runtime
.
Object
)
(
runtime
.
Codec
,
bool
,
error
)
{
if
nonProtobaleAPIGroups
.
Has
(
version
.
Group
)
{
return
nil
,
false
,
nil
}
s
:=
protobuf
.
NewSerializer
(
api
.
Scheme
,
api
.
Scheme
,
"application/arbitrary.content.type"
)
return
api
.
Codecs
.
CodecForVersions
(
s
,
s
,
testapi
.
ExternalGroupVersions
(),
nil
),
true
,
nil
})
}
func
TestUniversalDeserializer
(
t
*
testing
.
T
)
{
func
TestUniversalDeserializer
(
t
*
testing
.
T
)
{
expected
:=
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"test"
}}
expected
:=
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"test"
}}
d
:=
api
.
Codecs
.
UniversalDeserializer
()
d
:=
api
.
Codecs
.
UniversalDeserializer
()
...
...
pkg/api/serialization_test.go
View file @
0a743531
...
@@ -20,16 +20,13 @@ import (
...
@@ -20,16 +20,13 @@ import (
"bytes"
"bytes"
"encoding/hex"
"encoding/hex"
"encoding/json"
"encoding/json"
"fmt"
"io/ioutil"
"io/ioutil"
"math/rand"
"math/rand"
"reflect"
"reflect"
"strings"
"strings"
"testing"
"testing"
"github.com/davecgh/go-spew/spew"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/proto"
flag
"github.com/spf13/pflag"
"github.com/ugorji/go/codec"
"github.com/ugorji/go/codec"
apiequality
"k8s.io/apimachinery/pkg/api/equality"
apiequality
"k8s.io/apimachinery/pkg/api/equality"
...
@@ -51,17 +48,6 @@ import (
...
@@ -51,17 +48,6 @@ import (
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
)
)
var
fuzzIters
=
flag
.
Int
(
"fuzz-iters"
,
20
,
"How many fuzzing iterations to do."
)
// codecsToTest is a list of functions that yield the codecs to use to test a
// particular runtime object.
var
codecsToTest
=
[]
func
(
version
schema
.
GroupVersion
,
item
runtime
.
Object
)
(
runtime
.
Codec
,
bool
,
error
){
func
(
version
schema
.
GroupVersion
,
item
runtime
.
Object
)
(
runtime
.
Codec
,
bool
,
error
)
{
c
,
err
:=
testapi
.
GetCodecForObject
(
item
)
return
c
,
true
,
err
},
}
// fuzzInternalObject fuzzes an arbitrary runtime object using the appropriate
// fuzzInternalObject fuzzes an arbitrary runtime object using the appropriate
// fuzzer registered with the apitesting package.
// fuzzer registered with the apitesting package.
func
fuzzInternalObject
(
t
*
testing
.
T
,
forVersion
schema
.
GroupVersion
,
item
runtime
.
Object
,
seed
int64
)
runtime
.
Object
{
func
fuzzInternalObject
(
t
*
testing
.
T
,
forVersion
schema
.
GroupVersion
,
item
runtime
.
Object
,
seed
int64
)
runtime
.
Object
{
...
@@ -152,26 +138,12 @@ func TestSetControllerConversion(t *testing.T) {
...
@@ -152,26 +138,12 @@ func TestSetControllerConversion(t *testing.T) {
func
TestSpecificKind
(
t
*
testing
.
T
)
{
func
TestSpecificKind
(
t
*
testing
.
T
)
{
// Uncomment the following line to enable logging of which conversions
// Uncomment the following line to enable logging of which conversions
// api.scheme.Log(t)
// api.scheme.Log(t)
internalGVK
:=
schema
.
GroupVersionKind
{
Group
:
"extensions"
,
Version
:
runtime
.
APIVersionInternal
,
Kind
:
"DaemonSet"
}
kind
:=
"DaemonSet"
seed
:=
rand
.
Int63
()
for
i
:=
0
;
i
<
*
fuzzIters
;
i
++
{
fuzzer
:=
apitesting
.
FuzzerFor
(
kapitesting
.
FuzzerFuncs
(
t
,
api
.
Codecs
),
rand
.
NewSource
(
seed
))
doRoundTripTest
(
testapi
.
Groups
[
"extensions"
],
kind
,
t
)
if
t
.
Failed
()
{
break
}
}
}
// TestList applies the round-trip test to the List kind, which may hold
apitesting
.
RoundTripSpecificKind
(
t
,
internalGVK
,
api
.
Scheme
,
api
.
Codecs
,
fuzzer
,
nil
)
// objects of heterogenous unknown types.
func
TestList
(
t
*
testing
.
T
)
{
kind
:=
"List"
item
,
err
:=
api
.
Scheme
.
New
(
api
.
SchemeGroupVersion
.
WithKind
(
kind
))
if
err
!=
nil
{
t
.
Errorf
(
"Couldn't make a %v? %v"
,
kind
,
err
)
return
}
roundTripSame
(
t
,
testapi
.
Default
,
item
)
}
}
var
nonRoundTrippableTypes
=
sets
.
NewString
(
var
nonRoundTrippableTypes
=
sets
.
NewString
(
...
@@ -225,136 +197,19 @@ func TestCommonKindsRegistered(t *testing.T) {
...
@@ -225,136 +197,19 @@ func TestCommonKindsRegistered(t *testing.T) {
}
}
}
}
var
nonInternalRoundTrippableTypes
=
sets
.
NewString
(
"List"
,
"ListOptions"
,
"ExportOptions"
)
var
nonRoundTrippableTypesByVersion
=
map
[
string
][]
string
{}
// TestRoundTripTypes applies the round-trip test to all round-trippable Kinds
// TestRoundTripTypes applies the round-trip test to all round-trippable Kinds
// in all of the API groups registered for test in the testapi package.
// in all of the API groups registered for test in the testapi package.
func
TestRoundTripTypes
(
t
*
testing
.
T
)
{
func
TestRoundTripTypes
(
t
*
testing
.
T
)
{
for
groupKey
,
group
:=
range
testapi
.
Groups
{
for
kind
:=
range
group
.
InternalTypes
()
{
t
.
Logf
(
"working on %v in %v"
,
kind
,
groupKey
)
if
nonRoundTrippableTypes
.
Has
(
kind
)
{
continue
}
// Try a few times, since runTest uses random values.
for
i
:=
0
;
i
<
*
fuzzIters
;
i
++
{
doRoundTripTest
(
group
,
kind
,
t
)
if
t
.
Failed
()
{
break
}
}
}
}
}
func
doRoundTripTest
(
group
testapi
.
TestGroup
,
kind
string
,
t
*
testing
.
T
)
{
object
,
err
:=
api
.
Scheme
.
New
(
group
.
InternalGroupVersion
()
.
WithKind
(
kind
))
if
err
!=
nil
{
t
.
Fatalf
(
"Couldn't make a %v? %v"
,
kind
,
err
)
}
if
_
,
err
:=
meta
.
TypeAccessor
(
object
);
err
!=
nil
{
t
.
Fatalf
(
"%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableTypes: %v"
,
kind
,
err
)
}
if
api
.
Scheme
.
Recognizes
(
group
.
GroupVersion
()
.
WithKind
(
kind
))
{
roundTripSame
(
t
,
group
,
object
,
nonRoundTrippableTypesByVersion
[
kind
]
...
)
}
if
!
nonInternalRoundTrippableTypes
.
Has
(
kind
)
&&
api
.
Scheme
.
Recognizes
(
group
.
GroupVersion
()
.
WithKind
(
kind
))
{
roundTrip
(
t
,
group
.
Codec
(),
fuzzInternalObject
(
t
,
group
.
InternalGroupVersion
(),
object
,
rand
.
Int63
()))
}
}
// roundTripSame verifies the same source object is tested in all API versions
// yielded by codecsToTest
func
roundTripSame
(
t
*
testing
.
T
,
group
testapi
.
TestGroup
,
item
runtime
.
Object
,
except
...
string
)
{
set
:=
sets
.
NewString
(
except
...
)
seed
:=
rand
.
Int63
()
seed
:=
rand
.
Int63
()
fuzz
InternalObject
(
t
,
group
.
InternalGroupVersion
(),
item
,
seed
)
fuzz
er
:=
apitesting
.
FuzzerFor
(
kapitesting
.
FuzzerFuncs
(
t
,
api
.
Codecs
),
rand
.
NewSource
(
seed
)
)
version
:=
*
group
.
GroupVersion
()
nonRoundTrippableTypes
:=
map
[
schema
.
GroupVersionKind
]
bool
{
codecs
:=
[]
runtime
.
Codec
{}
{
Group
:
"componentconfig"
,
Version
:
runtime
.
APIVersionInternal
,
Kind
:
"KubeletConfiguration"
}
:
true
,
for
_
,
fn
:=
range
codecsToTest
{
{
Group
:
"componentconfig"
,
Version
:
runtime
.
APIVersionInternal
,
Kind
:
"KubeProxyConfiguration"
}
:
true
,
codec
,
ok
,
err
:=
fn
(
version
,
item
)
{
Group
:
"componentconfig"
,
Version
:
runtime
.
APIVersionInternal
,
Kind
:
"KubeSchedulerConfiguration"
}
:
true
,
if
err
!=
nil
{
t
.
Errorf
(
"unable to get codec: %v"
,
err
)
return
}
if
!
ok
{
continue
}
codecs
=
append
(
codecs
,
codec
)
}
}
if
!
set
.
Has
(
version
.
String
())
{
apitesting
.
RoundTripTypes
(
t
,
api
.
Scheme
,
api
.
Codecs
,
fuzzer
,
nonRoundTrippableTypes
)
fuzzInternalObject
(
t
,
version
,
item
,
seed
)
for
_
,
codec
:=
range
codecs
{
roundTrip
(
t
,
codec
,
item
)
}
}
}
// roundTrip applies a single round-trip test to the given runtime object
// using the given codec. The round-trip test ensures that an object can be
// deep-copied and converted from internal -> versioned -> internal without
// loss of data.
func
roundTrip
(
t
*
testing
.
T
,
codec
runtime
.
Codec
,
item
runtime
.
Object
)
{
printer
:=
spew
.
ConfigState
{
DisableMethods
:
true
}
original
:=
item
// deep copy the original object
copied
,
err
:=
api
.
Scheme
.
DeepCopy
(
item
)
if
err
!=
nil
{
panic
(
fmt
.
Sprintf
(
"unable to copy: %v"
,
err
))
}
item
=
copied
.
(
runtime
.
Object
)
name
:=
reflect
.
TypeOf
(
item
)
.
Elem
()
.
Name
()
// encode (serialize) the deep copy using the provided codec
data
,
err
:=
runtime
.
Encode
(
codec
,
item
)
if
err
!=
nil
{
if
runtime
.
IsNotRegisteredError
(
err
)
{
t
.
Logf
(
"%v: not registered: %v (%s)"
,
name
,
err
,
printer
.
Sprintf
(
"%#v"
,
item
))
}
else
{
t
.
Errorf
(
"%v: %v (%s)"
,
name
,
err
,
printer
.
Sprintf
(
"%#v"
,
item
))
}
return
}
// ensure that the deep copy is equal to the original; neither the deep
// copy or conversion should alter the object
if
!
apiequality
.
Semantic
.
DeepEqual
(
original
,
item
)
{
t
.
Errorf
(
"0: %v: encode altered the object, diff: %v"
,
name
,
diff
.
ObjectReflectDiff
(
original
,
item
))
return
}
// decode (deserialize) the encoded data back into an object
obj2
,
err
:=
runtime
.
Decode
(
codec
,
data
)
if
err
!=
nil
{
t
.
Errorf
(
"0: %v: %v
\n
Codec: %#v
\n
Data: %s
\n
Source: %#v"
,
name
,
err
,
codec
,
dataAsString
(
data
),
printer
.
Sprintf
(
"%#v"
,
item
))
panic
(
"failed"
)
}
// ensure that the object produced from decoding the encoded data is equal
// to the original object
if
!
apiequality
.
Semantic
.
DeepEqual
(
original
,
obj2
)
{
t
.
Errorf
(
"
\n
1: %v: diff: %v
\n
Codec: %#v
\n
Source:
\n\n
%#v
\n\n
Encoded:
\n\n
%s
\n\n
Final:
\n\n
%#v"
,
name
,
diff
.
ObjectReflectDiff
(
item
,
obj2
),
codec
,
printer
.
Sprintf
(
"%#v"
,
item
),
dataAsString
(
data
),
printer
.
Sprintf
(
"%#v"
,
obj2
))
return
}
// decode the encoded data into a new object (instead of letting the codec
// create a new object)
obj3
:=
reflect
.
New
(
reflect
.
TypeOf
(
item
)
.
Elem
())
.
Interface
()
.
(
runtime
.
Object
)
if
err
:=
runtime
.
DecodeInto
(
codec
,
data
,
obj3
);
err
!=
nil
{
t
.
Errorf
(
"2: %v: %v"
,
name
,
err
)
return
}
// ensure that the new runtime object is equal to the original after being
// decoded into
if
!
apiequality
.
Semantic
.
DeepEqual
(
item
,
obj3
)
{
t
.
Errorf
(
"3: %v: diff: %v
\n
Codec: %#v"
,
name
,
diff
.
ObjectReflectDiff
(
item
,
obj3
),
codec
)
return
}
}
}
// TestEncodePtr tests that a pointer to a golang type can be encoded and
// TestEncodePtr tests that a pointer to a golang type can be encoded and
...
...
staging/src/k8s.io/apimachinery/pkg/api/testing/roundtrip.go
0 → 100644
View file @
0a743531
/*
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
testing
import
(
"encoding/hex"
"fmt"
"reflect"
"strings"
"testing"
"github.com/davecgh/go-spew/spew"
"github.com/golang/protobuf/proto"
"github.com/google/gofuzz"
flag
"github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/runtime/serializer/protobuf"
apiequality
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
runtimeserializer
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/util/sets"
)
var
FuzzIters
=
flag
.
Int
(
"fuzz-iters"
,
20
,
"How many fuzzing iterations to do."
)
// nonRoundTrippableTypes are kinds that are effectively reserved across all GroupVersions
// They don't roundtrip
var
globalNonRoundTrippableTypes
=
sets
.
NewString
(
"ExportOptions"
,
"GetOptions"
,
// WatchEvent does not include kind and version and can only be deserialized
// implicitly (if the caller expects the specific object). The watch call defines
// the schema by content type, rather than via kind/version included in each
// object.
"WatchEvent"
,
// ListOptions is now part of the meta group
"ListOptions"
,
// Delete options is only read in metav1
"DeleteOptions"
,
)
// RoundTripTypes applies the round-trip test to all round-trippable Kinds
// in the scheme. It will skip all the GroupVersionKinds in the skip list.
func
RoundTripTypesWithoutProtobuf
(
t
*
testing
.
T
,
scheme
*
runtime
.
Scheme
,
codecFactory
runtimeserializer
.
CodecFactory
,
fuzzer
*
fuzz
.
Fuzzer
,
nonRoundTrippableTypes
map
[
schema
.
GroupVersionKind
]
bool
)
{
roundTripTypes
(
t
,
scheme
,
codecFactory
,
fuzzer
,
nonRoundTrippableTypes
,
true
)
}
func
RoundTripTypes
(
t
*
testing
.
T
,
scheme
*
runtime
.
Scheme
,
codecFactory
runtimeserializer
.
CodecFactory
,
fuzzer
*
fuzz
.
Fuzzer
,
nonRoundTrippableTypes
map
[
schema
.
GroupVersionKind
]
bool
)
{
roundTripTypes
(
t
,
scheme
,
codecFactory
,
fuzzer
,
nonRoundTrippableTypes
,
false
)
}
func
roundTripTypes
(
t
*
testing
.
T
,
scheme
*
runtime
.
Scheme
,
codecFactory
runtimeserializer
.
CodecFactory
,
fuzzer
*
fuzz
.
Fuzzer
,
nonRoundTrippableTypes
map
[
schema
.
GroupVersionKind
]
bool
,
skipProtobuf
bool
)
{
for
_
,
group
:=
range
groupsFromScheme
(
scheme
)
{
t
.
Logf
(
"starting group %q"
,
group
)
internalVersion
:=
schema
.
GroupVersion
{
Group
:
group
,
Version
:
runtime
.
APIVersionInternal
}
internalKindToGoType
:=
scheme
.
KnownTypes
(
internalVersion
)
for
kind
:=
range
internalKindToGoType
{
if
globalNonRoundTrippableTypes
.
Has
(
kind
)
{
continue
}
internalGVK
:=
internalVersion
.
WithKind
(
kind
)
roundTripSpecificKind
(
t
,
internalGVK
,
scheme
,
codecFactory
,
fuzzer
,
nonRoundTrippableTypes
,
skipProtobuf
)
}
t
.
Logf
(
"finished group %q"
,
group
)
}
}
func
RoundTripSpecificKindWithoutProtobuf
(
t
*
testing
.
T
,
internalGVK
schema
.
GroupVersionKind
,
scheme
*
runtime
.
Scheme
,
codecFactory
runtimeserializer
.
CodecFactory
,
fuzzer
*
fuzz
.
Fuzzer
,
nonRoundTrippableTypes
map
[
schema
.
GroupVersionKind
]
bool
)
{
roundTripSpecificKind
(
t
,
internalGVK
,
scheme
,
codecFactory
,
fuzzer
,
nonRoundTrippableTypes
,
true
)
}
func
RoundTripSpecificKind
(
t
*
testing
.
T
,
internalGVK
schema
.
GroupVersionKind
,
scheme
*
runtime
.
Scheme
,
codecFactory
runtimeserializer
.
CodecFactory
,
fuzzer
*
fuzz
.
Fuzzer
,
nonRoundTrippableTypes
map
[
schema
.
GroupVersionKind
]
bool
)
{
roundTripSpecificKind
(
t
,
internalGVK
,
scheme
,
codecFactory
,
fuzzer
,
nonRoundTrippableTypes
,
false
)
}
func
roundTripSpecificKind
(
t
*
testing
.
T
,
internalGVK
schema
.
GroupVersionKind
,
scheme
*
runtime
.
Scheme
,
codecFactory
runtimeserializer
.
CodecFactory
,
fuzzer
*
fuzz
.
Fuzzer
,
nonRoundTrippableTypes
map
[
schema
.
GroupVersionKind
]
bool
,
skipProtobuf
bool
)
{
if
nonRoundTrippableTypes
[
internalGVK
]
{
t
.
Logf
(
"skipping %v"
,
internalGVK
)
return
}
t
.
Logf
(
"round tripping %v"
,
internalGVK
)
// Try a few times, since runTest uses random values.
for
i
:=
0
;
i
<
*
FuzzIters
;
i
++
{
roundTripToAllExternalVersions
(
t
,
scheme
,
codecFactory
,
fuzzer
,
internalGVK
,
nonRoundTrippableTypes
,
skipProtobuf
)
if
t
.
Failed
()
{
break
}
}
}
// fuzzInternalObject fuzzes an arbitrary runtime object using the appropriate
// fuzzer registered with the apitesting package.
func
fuzzInternalObject
(
t
*
testing
.
T
,
fuzzer
*
fuzz
.
Fuzzer
,
object
runtime
.
Object
)
runtime
.
Object
{
fuzzer
.
Fuzz
(
object
)
j
,
err
:=
meta
.
TypeAccessor
(
object
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error %v for %#v"
,
err
,
object
)
}
j
.
SetKind
(
""
)
j
.
SetAPIVersion
(
""
)
return
object
}
func
groupsFromScheme
(
scheme
*
runtime
.
Scheme
)
[]
string
{
ret
:=
sets
.
String
{}
for
gvk
:=
range
scheme
.
AllKnownTypes
()
{
ret
.
Insert
(
gvk
.
Group
)
}
return
ret
.
List
()
}
func
roundTripToAllExternalVersions
(
t
*
testing
.
T
,
scheme
*
runtime
.
Scheme
,
codecFactory
runtimeserializer
.
CodecFactory
,
fuzzer
*
fuzz
.
Fuzzer
,
internalGVK
schema
.
GroupVersionKind
,
nonRoundTrippableTypes
map
[
schema
.
GroupVersionKind
]
bool
,
skipProtobuf
bool
)
{
object
,
err
:=
scheme
.
New
(
internalGVK
)
if
err
!=
nil
{
t
.
Fatalf
(
"Couldn't make a %v? %v"
,
internalGVK
,
err
)
}
if
_
,
err
:=
meta
.
TypeAccessor
(
object
);
err
!=
nil
{
t
.
Fatalf
(
"%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableInternalTypes: %v"
,
internalGVK
,
err
)
}
fuzzInternalObject
(
t
,
fuzzer
,
object
)
// find all potential serializations in the scheme.
// TODO fix this up to handle kinds that cross registered with different names.
for
externalGVK
,
externalGoType
:=
range
scheme
.
AllKnownTypes
()
{
if
externalGVK
.
Version
==
runtime
.
APIVersionInternal
{
continue
}
if
externalGVK
.
GroupKind
()
!=
internalGVK
.
GroupKind
()
{
continue
}
if
nonRoundTrippableTypes
[
externalGVK
]
{
t
.
Logf
(
"
\t
skipping %v %v"
,
externalGVK
,
externalGoType
)
continue
}
t
.
Logf
(
"
\t
round tripping to %v %v"
,
externalGVK
,
externalGoType
)
roundTrip
(
t
,
scheme
,
TestCodec
(
codecFactory
,
externalGVK
.
GroupVersion
()),
object
)
// TODO remove this hack after we're past the intermediate steps
if
!
skipProtobuf
&&
externalGVK
.
Group
!=
"kubeadm.k8s.io"
{
s
:=
protobuf
.
NewSerializer
(
scheme
,
scheme
,
"application/arbitrary.content.type"
)
protobufCodec
:=
codecFactory
.
CodecForVersions
(
s
,
s
,
externalGVK
.
GroupVersion
(),
nil
)
roundTrip
(
t
,
scheme
,
protobufCodec
,
object
)
}
}
}
// roundTrip applies a single round-trip test to the given runtime object
// using the given codec. The round-trip test ensures that an object can be
// deep-copied and converted from internal -> versioned -> internal without
// loss of data.
func
roundTrip
(
t
*
testing
.
T
,
scheme
*
runtime
.
Scheme
,
codec
runtime
.
Codec
,
object
runtime
.
Object
)
{
printer
:=
spew
.
ConfigState
{
DisableMethods
:
true
}
original
:=
object
// deep copy the original object
copied
,
err
:=
scheme
.
DeepCopy
(
object
)
if
err
!=
nil
{
panic
(
fmt
.
Sprintf
(
"unable to copy: %v"
,
err
))
}
object
=
copied
.
(
runtime
.
Object
)
name
:=
reflect
.
TypeOf
(
object
)
.
Elem
()
.
Name
()
// encode (serialize) the deep copy using the provided codec
data
,
err
:=
runtime
.
Encode
(
codec
,
object
)
if
err
!=
nil
{
if
runtime
.
IsNotRegisteredError
(
err
)
{
t
.
Logf
(
"%v: not registered: %v (%s)"
,
name
,
err
,
printer
.
Sprintf
(
"%#v"
,
object
))
}
else
{
t
.
Errorf
(
"%v: %v (%s)"
,
name
,
err
,
printer
.
Sprintf
(
"%#v"
,
object
))
}
return
}
// ensure that the deep copy is equal to the original; neither the deep
// copy or conversion should alter the object
// TODO eliminate this global
if
!
apiequality
.
Semantic
.
DeepEqual
(
original
,
object
)
{
t
.
Errorf
(
"0: %v: encode altered the object, diff: %v"
,
name
,
diff
.
ObjectReflectDiff
(
original
,
object
))
return
}
// decode (deserialize) the encoded data back into an object
obj2
,
err
:=
runtime
.
Decode
(
codec
,
data
)
if
err
!=
nil
{
t
.
Errorf
(
"0: %v: %v
\n
Codec: %#v
\n
Data: %s
\n
Source: %#v"
,
name
,
err
,
codec
,
dataAsString
(
data
),
printer
.
Sprintf
(
"%#v"
,
object
))
panic
(
"failed"
)
}
// ensure that the object produced from decoding the encoded data is equal
// to the original object
if
!
apiequality
.
Semantic
.
DeepEqual
(
original
,
obj2
)
{
t
.
Errorf
(
"
\n
1: %v: diff: %v
\n
Codec: %#v
\n
Source:
\n\n
%#v
\n\n
Encoded:
\n\n
%s
\n\n
Final:
\n\n
%#v"
,
name
,
diff
.
ObjectReflectDiff
(
object
,
obj2
),
codec
,
printer
.
Sprintf
(
"%#v"
,
object
),
dataAsString
(
data
),
printer
.
Sprintf
(
"%#v"
,
obj2
))
return
}
// decode the encoded data into a new object (instead of letting the codec
// create a new object)
obj3
:=
reflect
.
New
(
reflect
.
TypeOf
(
object
)
.
Elem
())
.
Interface
()
.
(
runtime
.
Object
)
if
err
:=
runtime
.
DecodeInto
(
codec
,
data
,
obj3
);
err
!=
nil
{
t
.
Errorf
(
"2: %v: %v"
,
name
,
err
)
return
}
// ensure that the new runtime object is equal to the original after being
// decoded into
if
!
apiequality
.
Semantic
.
DeepEqual
(
object
,
obj3
)
{
t
.
Errorf
(
"3: %v: diff: %v
\n
Codec: %#v"
,
name
,
diff
.
ObjectReflectDiff
(
object
,
obj3
),
codec
)
return
}
}
// dataAsString returns the given byte array as a string; handles detecting
// protocol buffers.
func
dataAsString
(
data
[]
byte
)
string
{
dataString
:=
string
(
data
)
if
!
strings
.
HasPrefix
(
dataString
,
"{"
)
{
dataString
=
"
\n
"
+
hex
.
Dump
(
data
)
proto
.
NewBuffer
(
make
([]
byte
,
0
,
1024
))
.
DebugPrint
(
"decoded object"
,
data
)
}
return
dataString
}
vendor/BUILD
View file @
0a743531
...
@@ -13834,17 +13834,26 @@ go_library(
...
@@ -13834,17 +13834,26 @@ go_library(
srcs = [
srcs = [
"k8s.io/apimachinery/pkg/api/testing/codec.go",
"k8s.io/apimachinery/pkg/api/testing/codec.go",
"k8s.io/apimachinery/pkg/api/testing/fuzzer.go",
"k8s.io/apimachinery/pkg/api/testing/fuzzer.go",
"k8s.io/apimachinery/pkg/api/testing/roundtrip.go",
],
],
tags = ["automanaged"],
tags = ["automanaged"],
deps = [
deps = [
"//vendor:github.com/davecgh/go-spew/spew",
"//vendor:github.com/golang/protobuf/proto",
"//vendor:github.com/google/gofuzz",
"//vendor:github.com/google/gofuzz",
"//vendor:github.com/spf13/pflag",
"//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/api/resource",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apimachinery/pkg/runtime/serializer",
"//vendor:k8s.io/apimachinery/pkg/runtime/serializer",
"//vendor:k8s.io/apimachinery/pkg/runtime/serializer/protobuf",
"//vendor:k8s.io/apimachinery/pkg/runtime/serializer/recognizer",
"//vendor:k8s.io/apimachinery/pkg/runtime/serializer/recognizer",
"//vendor:k8s.io/apimachinery/pkg/types",
"//vendor:k8s.io/apimachinery/pkg/types",
"//vendor:k8s.io/apimachinery/pkg/util/diff",
"//vendor:k8s.io/apimachinery/pkg/util/sets",
],
],
)
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment