Update go dependencies
This commit is contained in:
parent
15ffb51394
commit
bb4d483837
1621 changed files with 86368 additions and 284392 deletions
32
vendor/k8s.io/apimachinery/pkg/api/equality/BUILD
generated
vendored
32
vendor/k8s.io/apimachinery/pkg/api/equality/BUILD
generated
vendored
|
|
@ -1,32 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["semantic.go"],
|
||||
importpath = "k8s.io/apimachinery/pkg/api/equality",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/fields:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
47
vendor/k8s.io/apimachinery/pkg/api/errors/BUILD
generated
vendored
47
vendor/k8s.io/apimachinery/pkg/api/errors/BUILD
generated
vendored
|
|
@ -1,47 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["errors_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"errors.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/api/errors",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
222
vendor/k8s.io/apimachinery/pkg/api/errors/errors_test.go
generated
vendored
222
vendor/k8s.io/apimachinery/pkg/api/errors/errors_test.go
generated
vendored
|
|
@ -1,222 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
func resource(resource string) schema.GroupResource {
|
||||
return schema.GroupResource{Group: "", Resource: resource}
|
||||
}
|
||||
func kind(kind string) schema.GroupKind {
|
||||
return schema.GroupKind{Group: "", Kind: kind}
|
||||
}
|
||||
|
||||
func TestErrorNew(t *testing.T) {
|
||||
err := NewAlreadyExists(resource("tests"), "1")
|
||||
if !IsAlreadyExists(err) {
|
||||
t.Errorf("expected to be %s", metav1.StatusReasonAlreadyExists)
|
||||
}
|
||||
if IsConflict(err) {
|
||||
t.Errorf("expected to not be %s", metav1.StatusReasonConflict)
|
||||
}
|
||||
if IsNotFound(err) {
|
||||
t.Errorf(fmt.Sprintf("expected to not be %s", metav1.StatusReasonNotFound))
|
||||
}
|
||||
if IsInvalid(err) {
|
||||
t.Errorf("expected to not be %s", metav1.StatusReasonInvalid)
|
||||
}
|
||||
if IsBadRequest(err) {
|
||||
t.Errorf("expected to not be %s", metav1.StatusReasonBadRequest)
|
||||
}
|
||||
if IsForbidden(err) {
|
||||
t.Errorf("expected to not be %s", metav1.StatusReasonForbidden)
|
||||
}
|
||||
if IsServerTimeout(err) {
|
||||
t.Errorf("expected to not be %s", metav1.StatusReasonServerTimeout)
|
||||
}
|
||||
if IsMethodNotSupported(err) {
|
||||
t.Errorf("expected to not be %s", metav1.StatusReasonMethodNotAllowed)
|
||||
}
|
||||
|
||||
if !IsConflict(NewConflict(resource("tests"), "2", errors.New("message"))) {
|
||||
t.Errorf("expected to be conflict")
|
||||
}
|
||||
if !IsNotFound(NewNotFound(resource("tests"), "3")) {
|
||||
t.Errorf("expected to be %s", metav1.StatusReasonNotFound)
|
||||
}
|
||||
if !IsInvalid(NewInvalid(kind("Test"), "2", nil)) {
|
||||
t.Errorf("expected to be %s", metav1.StatusReasonInvalid)
|
||||
}
|
||||
if !IsBadRequest(NewBadRequest("reason")) {
|
||||
t.Errorf("expected to be %s", metav1.StatusReasonBadRequest)
|
||||
}
|
||||
if !IsForbidden(NewForbidden(resource("tests"), "2", errors.New("reason"))) {
|
||||
t.Errorf("expected to be %s", metav1.StatusReasonForbidden)
|
||||
}
|
||||
if !IsUnauthorized(NewUnauthorized("reason")) {
|
||||
t.Errorf("expected to be %s", metav1.StatusReasonUnauthorized)
|
||||
}
|
||||
if !IsServerTimeout(NewServerTimeout(resource("tests"), "reason", 0)) {
|
||||
t.Errorf("expected to be %s", metav1.StatusReasonServerTimeout)
|
||||
}
|
||||
if !IsMethodNotSupported(NewMethodNotSupported(resource("foos"), "delete")) {
|
||||
t.Errorf("expected to be %s", metav1.StatusReasonMethodNotAllowed)
|
||||
}
|
||||
|
||||
if time, ok := SuggestsClientDelay(NewServerTimeout(resource("tests"), "doing something", 10)); time != 10 || !ok {
|
||||
t.Errorf("unexpected %d", time)
|
||||
}
|
||||
if time, ok := SuggestsClientDelay(NewServerTimeout(resource("tests"), "doing something", 0)); time != 0 || !ok {
|
||||
t.Errorf("unexpected %d", time)
|
||||
}
|
||||
if time, ok := SuggestsClientDelay(NewTimeoutError("test reason", 10)); time != 10 || !ok {
|
||||
t.Errorf("unexpected %d", time)
|
||||
}
|
||||
if time, ok := SuggestsClientDelay(NewTooManyRequests("doing something", 10)); time != 10 || !ok {
|
||||
t.Errorf("unexpected %d", time)
|
||||
}
|
||||
if time, ok := SuggestsClientDelay(NewTooManyRequests("doing something", 1)); time != 1 || !ok {
|
||||
t.Errorf("unexpected %d", time)
|
||||
}
|
||||
if time, ok := SuggestsClientDelay(NewGenericServerResponse(429, "get", resource("tests"), "test", "doing something", 10, true)); time != 10 || !ok {
|
||||
t.Errorf("unexpected %d", time)
|
||||
}
|
||||
if time, ok := SuggestsClientDelay(NewGenericServerResponse(500, "get", resource("tests"), "test", "doing something", 10, true)); time != 10 || !ok {
|
||||
t.Errorf("unexpected %d", time)
|
||||
}
|
||||
if time, ok := SuggestsClientDelay(NewGenericServerResponse(429, "get", resource("tests"), "test", "doing something", 0, true)); time != 0 || ok {
|
||||
t.Errorf("unexpected %d", time)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewInvalid(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Err *field.Error
|
||||
Details *metav1.StatusDetails
|
||||
}{
|
||||
{
|
||||
field.Duplicate(field.NewPath("field[0].name"), "bar"),
|
||||
&metav1.StatusDetails{
|
||||
Kind: "Kind",
|
||||
Name: "name",
|
||||
Causes: []metav1.StatusCause{{
|
||||
Type: metav1.CauseTypeFieldValueDuplicate,
|
||||
Field: "field[0].name",
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
field.Invalid(field.NewPath("field[0].name"), "bar", "detail"),
|
||||
&metav1.StatusDetails{
|
||||
Kind: "Kind",
|
||||
Name: "name",
|
||||
Causes: []metav1.StatusCause{{
|
||||
Type: metav1.CauseTypeFieldValueInvalid,
|
||||
Field: "field[0].name",
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
field.NotFound(field.NewPath("field[0].name"), "bar"),
|
||||
&metav1.StatusDetails{
|
||||
Kind: "Kind",
|
||||
Name: "name",
|
||||
Causes: []metav1.StatusCause{{
|
||||
Type: metav1.CauseTypeFieldValueNotFound,
|
||||
Field: "field[0].name",
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
field.NotSupported(field.NewPath("field[0].name"), "bar", nil),
|
||||
&metav1.StatusDetails{
|
||||
Kind: "Kind",
|
||||
Name: "name",
|
||||
Causes: []metav1.StatusCause{{
|
||||
Type: metav1.CauseTypeFieldValueNotSupported,
|
||||
Field: "field[0].name",
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
field.Required(field.NewPath("field[0].name"), ""),
|
||||
&metav1.StatusDetails{
|
||||
Kind: "Kind",
|
||||
Name: "name",
|
||||
Causes: []metav1.StatusCause{{
|
||||
Type: metav1.CauseTypeFieldValueRequired,
|
||||
Field: "field[0].name",
|
||||
}},
|
||||
},
|
||||
},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
vErr, expected := testCase.Err, testCase.Details
|
||||
expected.Causes[0].Message = vErr.ErrorBody()
|
||||
err := NewInvalid(kind("Kind"), "name", field.ErrorList{vErr})
|
||||
status := err.ErrStatus
|
||||
if status.Code != 422 || status.Reason != metav1.StatusReasonInvalid {
|
||||
t.Errorf("%d: unexpected status: %#v", i, status)
|
||||
}
|
||||
if !reflect.DeepEqual(expected, status.Details) {
|
||||
t.Errorf("%d: expected %#v, got %#v", i, expected, status.Details)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestReasonForError(t *testing.T) {
|
||||
if e, a := metav1.StatusReasonUnknown, ReasonForError(nil); e != a {
|
||||
t.Errorf("unexpected reason type: %#v", a)
|
||||
}
|
||||
}
|
||||
|
||||
type TestType struct{}
|
||||
|
||||
func (obj *TestType) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind }
|
||||
func (obj *TestType) DeepCopyObject() runtime.Object {
|
||||
if obj == nil {
|
||||
return nil
|
||||
}
|
||||
clone := *obj
|
||||
return &clone
|
||||
}
|
||||
|
||||
func TestFromObject(t *testing.T) {
|
||||
table := []struct {
|
||||
obj runtime.Object
|
||||
message string
|
||||
}{
|
||||
{&metav1.Status{Message: "foobar"}, "foobar"},
|
||||
{&TestType{}, "unexpected object: &{}"},
|
||||
}
|
||||
|
||||
for _, item := range table {
|
||||
if e, a := item.message, FromObject(item.obj).Error(); e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
72
vendor/k8s.io/apimachinery/pkg/api/meta/BUILD
generated
vendored
72
vendor/k8s.io/apimachinery/pkg/api/meta/BUILD
generated
vendored
|
|
@ -1,72 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"meta_test.go",
|
||||
"multirestmapper_test.go",
|
||||
"priority_test.go",
|
||||
"restmapper_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/github.com/google/gofuzz:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"errors.go",
|
||||
"firsthit_restmapper.go",
|
||||
"help.go",
|
||||
"interfaces.go",
|
||||
"lazy.go",
|
||||
"meta.go",
|
||||
"multirestmapper.go",
|
||||
"priority.go",
|
||||
"restmapper.go",
|
||||
"unstructured.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/api/meta",
|
||||
deps = [
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta/table:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
51
vendor/k8s.io/apimachinery/pkg/api/meta/meta_test.go
generated
vendored
51
vendor/k8s.io/apimachinery/pkg/api/meta/meta_test.go
generated
vendored
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
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 meta
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
|
||||
fuzz "github.com/google/gofuzz"
|
||||
)
|
||||
|
||||
func TestAsPartialObjectMetadata(t *testing.T) {
|
||||
f := fuzz.New().NilChance(.5).NumElements(0, 1).RandSource(rand.NewSource(1))
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
m := &metav1.ObjectMeta{}
|
||||
f.Fuzz(m)
|
||||
partial := AsPartialObjectMetadata(m)
|
||||
if !reflect.DeepEqual(&partial.ObjectMeta, m) {
|
||||
t.Fatalf("incomplete partial object metadata: %s", diff.ObjectReflectDiff(&partial.ObjectMeta, m))
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
m := &metav1beta1.PartialObjectMetadata{}
|
||||
f.Fuzz(&m.ObjectMeta)
|
||||
partial := AsPartialObjectMetadata(m)
|
||||
if !reflect.DeepEqual(&partial.ObjectMeta, &m.ObjectMeta) {
|
||||
t.Fatalf("incomplete partial object metadata: %s", diff.ObjectReflectDiff(&partial.ObjectMeta, &m.ObjectMeta))
|
||||
}
|
||||
}
|
||||
}
|
||||
391
vendor/k8s.io/apimachinery/pkg/api/meta/multirestmapper_test.go
generated
vendored
391
vendor/k8s.io/apimachinery/pkg/api/meta/multirestmapper_test.go
generated
vendored
|
|
@ -1,391 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 meta
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func TestMultiRESTMapperResourceFor(t *testing.T) {
|
||||
tcs := []struct {
|
||||
name string
|
||||
|
||||
mapper MultiRESTMapper
|
||||
input schema.GroupVersionResource
|
||||
result schema.GroupVersionResource
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
mapper: MultiRESTMapper{},
|
||||
input: schema.GroupVersionResource{Resource: "foo"},
|
||||
result: schema.GroupVersionResource{},
|
||||
err: &NoResourceMatchError{PartialResource: schema.GroupVersionResource{Resource: "foo"}},
|
||||
},
|
||||
{
|
||||
name: "ignore not found",
|
||||
mapper: MultiRESTMapper{fixedRESTMapper{err: &NoResourceMatchError{PartialResource: schema.GroupVersionResource{Resource: "IGNORE_THIS"}}}},
|
||||
input: schema.GroupVersionResource{Resource: "foo"},
|
||||
result: schema.GroupVersionResource{},
|
||||
err: &NoResourceMatchError{PartialResource: schema.GroupVersionResource{Resource: "foo"}},
|
||||
},
|
||||
{
|
||||
name: "accept first failure",
|
||||
mapper: MultiRESTMapper{fixedRESTMapper{err: errors.New("fail on this")}, fixedRESTMapper{resourcesFor: []schema.GroupVersionResource{{Resource: "unused"}}}},
|
||||
input: schema.GroupVersionResource{Resource: "foo"},
|
||||
result: schema.GroupVersionResource{},
|
||||
err: errors.New("fail on this"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
actualResult, actualErr := tc.mapper.ResourceFor(tc.input)
|
||||
if e, a := tc.result, actualResult; e != a {
|
||||
t.Errorf("%s: expected %v, got %v", tc.name, e, a)
|
||||
}
|
||||
switch {
|
||||
case tc.err == nil && actualErr == nil:
|
||||
case tc.err == nil:
|
||||
t.Errorf("%s: unexpected error: %v", tc.name, actualErr)
|
||||
case actualErr == nil:
|
||||
t.Errorf("%s: expected error: %v got nil", tc.name, tc.err)
|
||||
case tc.err.Error() != actualErr.Error():
|
||||
t.Errorf("%s: expected %v, got %v", tc.name, tc.err, actualErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiRESTMapperResourcesFor(t *testing.T) {
|
||||
tcs := []struct {
|
||||
name string
|
||||
|
||||
mapper MultiRESTMapper
|
||||
input schema.GroupVersionResource
|
||||
result []schema.GroupVersionResource
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
mapper: MultiRESTMapper{},
|
||||
input: schema.GroupVersionResource{Resource: "foo"},
|
||||
result: nil,
|
||||
err: &NoResourceMatchError{PartialResource: schema.GroupVersionResource{Resource: "foo"}},
|
||||
},
|
||||
{
|
||||
name: "ignore not found",
|
||||
mapper: MultiRESTMapper{fixedRESTMapper{err: &NoResourceMatchError{PartialResource: schema.GroupVersionResource{Resource: "IGNORE_THIS"}}}},
|
||||
input: schema.GroupVersionResource{Resource: "foo"},
|
||||
result: nil,
|
||||
err: &NoResourceMatchError{PartialResource: schema.GroupVersionResource{Resource: "foo"}},
|
||||
},
|
||||
{
|
||||
name: "accept first failure",
|
||||
mapper: MultiRESTMapper{fixedRESTMapper{err: errors.New("fail on this")}, fixedRESTMapper{resourcesFor: []schema.GroupVersionResource{{Resource: "unused"}}}},
|
||||
input: schema.GroupVersionResource{Resource: "foo"},
|
||||
result: nil,
|
||||
err: errors.New("fail on this"),
|
||||
},
|
||||
{
|
||||
name: "union and dedup",
|
||||
mapper: MultiRESTMapper{
|
||||
fixedRESTMapper{resourcesFor: []schema.GroupVersionResource{{Resource: "dupe"}, {Resource: "first"}}},
|
||||
fixedRESTMapper{resourcesFor: []schema.GroupVersionResource{{Resource: "dupe"}, {Resource: "second"}}},
|
||||
},
|
||||
input: schema.GroupVersionResource{Resource: "foo"},
|
||||
result: []schema.GroupVersionResource{{Resource: "dupe"}, {Resource: "first"}, {Resource: "second"}},
|
||||
},
|
||||
{
|
||||
name: "skip not and continue",
|
||||
mapper: MultiRESTMapper{
|
||||
fixedRESTMapper{err: &NoResourceMatchError{PartialResource: schema.GroupVersionResource{Resource: "IGNORE_THIS"}}},
|
||||
fixedRESTMapper{resourcesFor: []schema.GroupVersionResource{{Resource: "first"}, {Resource: "second"}}},
|
||||
},
|
||||
input: schema.GroupVersionResource{Resource: "foo"},
|
||||
result: []schema.GroupVersionResource{{Resource: "first"}, {Resource: "second"}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
actualResult, actualErr := tc.mapper.ResourcesFor(tc.input)
|
||||
if e, a := tc.result, actualResult; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%s: expected %v, got %v", tc.name, e, a)
|
||||
}
|
||||
switch {
|
||||
case tc.err == nil && actualErr == nil:
|
||||
case tc.err == nil:
|
||||
t.Errorf("%s: unexpected error: %v", tc.name, actualErr)
|
||||
case actualErr == nil:
|
||||
t.Errorf("%s: expected error: %v got nil", tc.name, tc.err)
|
||||
case tc.err.Error() != actualErr.Error():
|
||||
t.Errorf("%s: expected %v, got %v", tc.name, tc.err, actualErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiRESTMapperKindsFor(t *testing.T) {
|
||||
tcs := []struct {
|
||||
name string
|
||||
|
||||
mapper MultiRESTMapper
|
||||
input schema.GroupVersionResource
|
||||
result []schema.GroupVersionKind
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
mapper: MultiRESTMapper{},
|
||||
input: schema.GroupVersionResource{Resource: "foo"},
|
||||
result: nil,
|
||||
err: &NoResourceMatchError{PartialResource: schema.GroupVersionResource{Resource: "foo"}},
|
||||
},
|
||||
{
|
||||
name: "ignore not found",
|
||||
mapper: MultiRESTMapper{fixedRESTMapper{err: &NoResourceMatchError{PartialResource: schema.GroupVersionResource{Resource: "IGNORE_THIS"}}}},
|
||||
input: schema.GroupVersionResource{Resource: "foo"},
|
||||
result: nil,
|
||||
err: &NoResourceMatchError{PartialResource: schema.GroupVersionResource{Resource: "foo"}},
|
||||
},
|
||||
{
|
||||
name: "accept first failure",
|
||||
mapper: MultiRESTMapper{fixedRESTMapper{err: errors.New("fail on this")}, fixedRESTMapper{kindsFor: []schema.GroupVersionKind{{Kind: "unused"}}}},
|
||||
input: schema.GroupVersionResource{Resource: "foo"},
|
||||
result: nil,
|
||||
err: errors.New("fail on this"),
|
||||
},
|
||||
{
|
||||
name: "union and dedup",
|
||||
mapper: MultiRESTMapper{
|
||||
fixedRESTMapper{kindsFor: []schema.GroupVersionKind{{Kind: "dupe"}, {Kind: "first"}}},
|
||||
fixedRESTMapper{kindsFor: []schema.GroupVersionKind{{Kind: "dupe"}, {Kind: "second"}}},
|
||||
},
|
||||
input: schema.GroupVersionResource{Resource: "foo"},
|
||||
result: []schema.GroupVersionKind{{Kind: "dupe"}, {Kind: "first"}, {Kind: "second"}},
|
||||
},
|
||||
{
|
||||
name: "skip not and continue",
|
||||
mapper: MultiRESTMapper{
|
||||
fixedRESTMapper{err: &NoResourceMatchError{PartialResource: schema.GroupVersionResource{Resource: "IGNORE_THIS"}}},
|
||||
fixedRESTMapper{kindsFor: []schema.GroupVersionKind{{Kind: "first"}, {Kind: "second"}}},
|
||||
},
|
||||
input: schema.GroupVersionResource{Resource: "foo"},
|
||||
result: []schema.GroupVersionKind{{Kind: "first"}, {Kind: "second"}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
actualResult, actualErr := tc.mapper.KindsFor(tc.input)
|
||||
if e, a := tc.result, actualResult; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%s: expected %v, got %v", tc.name, e, a)
|
||||
}
|
||||
switch {
|
||||
case tc.err == nil && actualErr == nil:
|
||||
case tc.err == nil:
|
||||
t.Errorf("%s: unexpected error: %v", tc.name, actualErr)
|
||||
case actualErr == nil:
|
||||
t.Errorf("%s: expected error: %v got nil", tc.name, tc.err)
|
||||
case tc.err.Error() != actualErr.Error():
|
||||
t.Errorf("%s: expected %v, got %v", tc.name, tc.err, actualErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiRESTMapperKindFor(t *testing.T) {
|
||||
tcs := []struct {
|
||||
name string
|
||||
|
||||
mapper MultiRESTMapper
|
||||
input schema.GroupVersionResource
|
||||
result schema.GroupVersionKind
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
mapper: MultiRESTMapper{},
|
||||
input: schema.GroupVersionResource{Resource: "foo"},
|
||||
result: schema.GroupVersionKind{},
|
||||
err: &NoResourceMatchError{PartialResource: schema.GroupVersionResource{Resource: "foo"}},
|
||||
},
|
||||
{
|
||||
name: "ignore not found",
|
||||
mapper: MultiRESTMapper{fixedRESTMapper{err: &NoResourceMatchError{PartialResource: schema.GroupVersionResource{Resource: "IGNORE_THIS"}}}},
|
||||
input: schema.GroupVersionResource{Resource: "foo"},
|
||||
result: schema.GroupVersionKind{},
|
||||
err: &NoResourceMatchError{PartialResource: schema.GroupVersionResource{Resource: "foo"}},
|
||||
},
|
||||
{
|
||||
name: "accept first failure",
|
||||
mapper: MultiRESTMapper{fixedRESTMapper{err: errors.New("fail on this")}, fixedRESTMapper{kindsFor: []schema.GroupVersionKind{{Kind: "unused"}}}},
|
||||
input: schema.GroupVersionResource{Resource: "foo"},
|
||||
result: schema.GroupVersionKind{},
|
||||
err: errors.New("fail on this"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
actualResult, actualErr := tc.mapper.KindFor(tc.input)
|
||||
if e, a := tc.result, actualResult; e != a {
|
||||
t.Errorf("%s: expected %v, got %v", tc.name, e, a)
|
||||
}
|
||||
switch {
|
||||
case tc.err == nil && actualErr == nil:
|
||||
case tc.err == nil:
|
||||
t.Errorf("%s: unexpected error: %v", tc.name, actualErr)
|
||||
case actualErr == nil:
|
||||
t.Errorf("%s: expected error: %v got nil", tc.name, tc.err)
|
||||
case tc.err.Error() != actualErr.Error():
|
||||
t.Errorf("%s: expected %v, got %v", tc.name, tc.err, actualErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiRESTMapperRESTMappings(t *testing.T) {
|
||||
mapping1, mapping2 := &RESTMapping{}, &RESTMapping{}
|
||||
tcs := []struct {
|
||||
name string
|
||||
|
||||
mapper MultiRESTMapper
|
||||
groupKind schema.GroupKind
|
||||
versions []string
|
||||
result []*RESTMapping
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "empty with no versions",
|
||||
mapper: MultiRESTMapper{},
|
||||
groupKind: schema.GroupKind{Kind: "Foo"},
|
||||
result: nil,
|
||||
err: &NoKindMatchError{GroupKind: schema.GroupKind{Kind: "Foo"}},
|
||||
},
|
||||
{
|
||||
name: "empty with one version",
|
||||
mapper: MultiRESTMapper{},
|
||||
groupKind: schema.GroupKind{Kind: "Foo"},
|
||||
versions: []string{"v1beta"},
|
||||
result: nil,
|
||||
err: &NoKindMatchError{GroupKind: schema.GroupKind{Kind: "Foo"}, SearchedVersions: []string{"v1beta"}},
|
||||
},
|
||||
{
|
||||
name: "empty with multi(two) vesions",
|
||||
mapper: MultiRESTMapper{},
|
||||
groupKind: schema.GroupKind{Kind: "Foo"},
|
||||
versions: []string{"v1beta", "v2"},
|
||||
result: nil,
|
||||
err: &NoKindMatchError{GroupKind: schema.GroupKind{Kind: "Foo"}, SearchedVersions: []string{"v1beta", "v2"}},
|
||||
},
|
||||
{
|
||||
name: "ignore not found with kind not exist",
|
||||
mapper: MultiRESTMapper{fixedRESTMapper{err: &NoKindMatchError{GroupKind: schema.GroupKind{Kind: "IGNORE_THIS"}}}},
|
||||
groupKind: schema.GroupKind{Kind: "Foo"},
|
||||
versions: nil,
|
||||
result: nil,
|
||||
err: &NoKindMatchError{GroupKind: schema.GroupKind{Kind: "Foo"}},
|
||||
},
|
||||
{
|
||||
name: "ignore not found with version not exist",
|
||||
mapper: MultiRESTMapper{fixedRESTMapper{err: &NoKindMatchError{GroupKind: schema.GroupKind{Kind: "Foo"}, SearchedVersions: []string{"v1"}}}},
|
||||
groupKind: schema.GroupKind{Kind: "Foo"},
|
||||
versions: []string{"v1beta"},
|
||||
result: nil,
|
||||
err: &NoKindMatchError{GroupKind: schema.GroupKind{Kind: "Foo"}, SearchedVersions: []string{"v1beta"}},
|
||||
},
|
||||
{
|
||||
name: "ignore not found with multi versions not exist",
|
||||
mapper: MultiRESTMapper{fixedRESTMapper{err: &NoKindMatchError{GroupKind: schema.GroupKind{Kind: "Foo"}, SearchedVersions: []string{"v1"}}}},
|
||||
groupKind: schema.GroupKind{Kind: "Foo"},
|
||||
versions: []string{"v1beta", "v2"},
|
||||
result: nil,
|
||||
err: &NoKindMatchError{GroupKind: schema.GroupKind{Kind: "Foo"}, SearchedVersions: []string{"v1beta", "v2"}},
|
||||
},
|
||||
{
|
||||
name: "accept first failure",
|
||||
mapper: MultiRESTMapper{fixedRESTMapper{err: errors.New("fail on this")}, fixedRESTMapper{mappings: []*RESTMapping{mapping1}}},
|
||||
groupKind: schema.GroupKind{Kind: "Foo"},
|
||||
versions: []string{"v1beta"},
|
||||
result: nil,
|
||||
err: errors.New("fail on this"),
|
||||
},
|
||||
{
|
||||
name: "return both",
|
||||
mapper: MultiRESTMapper{fixedRESTMapper{mappings: []*RESTMapping{mapping1}}, fixedRESTMapper{mappings: []*RESTMapping{mapping2}}},
|
||||
groupKind: schema.GroupKind{Kind: "Foo"},
|
||||
versions: []string{"v1beta"},
|
||||
result: []*RESTMapping{mapping1, mapping2},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
actualResult, actualErr := tc.mapper.RESTMappings(tc.groupKind, tc.versions...)
|
||||
if e, a := tc.result, actualResult; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%s: expected %v, got %v", tc.name, e, a)
|
||||
}
|
||||
switch {
|
||||
case tc.err == nil && actualErr == nil:
|
||||
case tc.err == nil:
|
||||
t.Errorf("%s: unexpected error: %v", tc.name, actualErr)
|
||||
case actualErr == nil:
|
||||
t.Errorf("%s: expected error: %v got nil", tc.name, tc.err)
|
||||
case tc.err.Error() != actualErr.Error():
|
||||
t.Errorf("%s: expected %v, got %v", tc.name, tc.err, actualErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type fixedRESTMapper struct {
|
||||
resourcesFor []schema.GroupVersionResource
|
||||
kindsFor []schema.GroupVersionKind
|
||||
resourceFor schema.GroupVersionResource
|
||||
kindFor schema.GroupVersionKind
|
||||
mappings []*RESTMapping
|
||||
|
||||
err error
|
||||
}
|
||||
|
||||
func (m fixedRESTMapper) ResourceSingularizer(resource string) (singular string, err error) {
|
||||
return "", m.err
|
||||
}
|
||||
|
||||
func (m fixedRESTMapper) ResourcesFor(resource schema.GroupVersionResource) ([]schema.GroupVersionResource, error) {
|
||||
return m.resourcesFor, m.err
|
||||
}
|
||||
|
||||
func (m fixedRESTMapper) KindsFor(resource schema.GroupVersionResource) (gvk []schema.GroupVersionKind, err error) {
|
||||
return m.kindsFor, m.err
|
||||
}
|
||||
|
||||
func (m fixedRESTMapper) ResourceFor(resource schema.GroupVersionResource) (schema.GroupVersionResource, error) {
|
||||
return m.resourceFor, m.err
|
||||
}
|
||||
|
||||
func (m fixedRESTMapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) {
|
||||
return m.kindFor, m.err
|
||||
}
|
||||
|
||||
func (m fixedRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (mapping *RESTMapping, err error) {
|
||||
return nil, m.err
|
||||
}
|
||||
|
||||
func (m fixedRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) (mappings []*RESTMapping, err error) {
|
||||
return m.mappings, m.err
|
||||
}
|
||||
|
||||
func (m fixedRESTMapper) ResourceIsValid(resource schema.GroupVersionResource) bool {
|
||||
return false
|
||||
}
|
||||
346
vendor/k8s.io/apimachinery/pkg/api/meta/priority_test.go
generated
vendored
346
vendor/k8s.io/apimachinery/pkg/api/meta/priority_test.go
generated
vendored
|
|
@ -1,346 +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 meta
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func TestPriorityRESTMapperResourceForErrorHandling(t *testing.T) {
|
||||
tcs := []struct {
|
||||
name string
|
||||
|
||||
delegate RESTMapper
|
||||
resourcePatterns []schema.GroupVersionResource
|
||||
result schema.GroupVersionResource
|
||||
err string
|
||||
}{
|
||||
{
|
||||
name: "single hit",
|
||||
delegate: fixedRESTMapper{resourcesFor: []schema.GroupVersionResource{{Resource: "single-hit"}}},
|
||||
result: schema.GroupVersionResource{Resource: "single-hit"},
|
||||
},
|
||||
{
|
||||
name: "ambiguous match",
|
||||
delegate: fixedRESTMapper{resourcesFor: []schema.GroupVersionResource{
|
||||
{Group: "one", Version: "a", Resource: "first"},
|
||||
{Group: "two", Version: "b", Resource: "second"},
|
||||
}},
|
||||
err: "matches multiple resources",
|
||||
},
|
||||
{
|
||||
name: "group selection",
|
||||
delegate: fixedRESTMapper{resourcesFor: []schema.GroupVersionResource{
|
||||
{Group: "one", Version: "a", Resource: "first"},
|
||||
{Group: "two", Version: "b", Resource: "second"},
|
||||
}},
|
||||
resourcePatterns: []schema.GroupVersionResource{
|
||||
{Group: "one", Version: AnyVersion, Resource: AnyResource},
|
||||
},
|
||||
result: schema.GroupVersionResource{Group: "one", Version: "a", Resource: "first"},
|
||||
},
|
||||
{
|
||||
name: "empty match continues",
|
||||
delegate: fixedRESTMapper{resourcesFor: []schema.GroupVersionResource{
|
||||
{Group: "one", Version: "a", Resource: "first"},
|
||||
{Group: "two", Version: "b", Resource: "second"},
|
||||
}},
|
||||
resourcePatterns: []schema.GroupVersionResource{
|
||||
{Group: "fail", Version: AnyVersion, Resource: AnyResource},
|
||||
{Group: "one", Version: AnyVersion, Resource: AnyResource},
|
||||
},
|
||||
result: schema.GroupVersionResource{Group: "one", Version: "a", Resource: "first"},
|
||||
},
|
||||
{
|
||||
name: "group followed by version selection",
|
||||
delegate: fixedRESTMapper{resourcesFor: []schema.GroupVersionResource{
|
||||
{Group: "one", Version: "a", Resource: "first"},
|
||||
{Group: "two", Version: "b", Resource: "second"},
|
||||
{Group: "one", Version: "c", Resource: "third"},
|
||||
}},
|
||||
resourcePatterns: []schema.GroupVersionResource{
|
||||
{Group: "one", Version: AnyVersion, Resource: AnyResource},
|
||||
{Group: AnyGroup, Version: "a", Resource: AnyResource},
|
||||
},
|
||||
result: schema.GroupVersionResource{Group: "one", Version: "a", Resource: "first"},
|
||||
},
|
||||
{
|
||||
name: "resource selection",
|
||||
delegate: fixedRESTMapper{resourcesFor: []schema.GroupVersionResource{
|
||||
{Group: "one", Version: "a", Resource: "first"},
|
||||
{Group: "one", Version: "a", Resource: "second"},
|
||||
}},
|
||||
resourcePatterns: []schema.GroupVersionResource{
|
||||
{Group: AnyGroup, Version: AnyVersion, Resource: "second"},
|
||||
},
|
||||
result: schema.GroupVersionResource{Group: "one", Version: "a", Resource: "second"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
mapper := PriorityRESTMapper{Delegate: tc.delegate, ResourcePriority: tc.resourcePatterns}
|
||||
|
||||
actualResult, actualErr := mapper.ResourceFor(schema.GroupVersionResource{})
|
||||
if e, a := tc.result, actualResult; e != a {
|
||||
t.Errorf("%s: expected %v, got %v", tc.name, e, a)
|
||||
}
|
||||
if len(tc.err) == 0 && actualErr == nil {
|
||||
continue
|
||||
}
|
||||
if len(tc.err) > 0 && actualErr == nil {
|
||||
t.Errorf("%s: missing expected err: %v", tc.name, tc.err)
|
||||
continue
|
||||
}
|
||||
if !strings.Contains(actualErr.Error(), tc.err) {
|
||||
t.Errorf("%s: expected %v, got %v", tc.name, tc.err, actualErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPriorityRESTMapperKindForErrorHandling(t *testing.T) {
|
||||
tcs := []struct {
|
||||
name string
|
||||
|
||||
delegate RESTMapper
|
||||
kindPatterns []schema.GroupVersionKind
|
||||
result schema.GroupVersionKind
|
||||
err string
|
||||
}{
|
||||
{
|
||||
name: "single hit",
|
||||
delegate: fixedRESTMapper{kindsFor: []schema.GroupVersionKind{{Kind: "single-hit"}}},
|
||||
result: schema.GroupVersionKind{Kind: "single-hit"},
|
||||
},
|
||||
{
|
||||
name: "ambiguous match",
|
||||
delegate: fixedRESTMapper{kindsFor: []schema.GroupVersionKind{
|
||||
{Group: "one", Version: "a", Kind: "first"},
|
||||
{Group: "two", Version: "b", Kind: "second"},
|
||||
}},
|
||||
err: "matches multiple kinds",
|
||||
},
|
||||
{
|
||||
name: "group selection",
|
||||
delegate: fixedRESTMapper{kindsFor: []schema.GroupVersionKind{
|
||||
{Group: "one", Version: "a", Kind: "first"},
|
||||
{Group: "two", Version: "b", Kind: "second"},
|
||||
}},
|
||||
kindPatterns: []schema.GroupVersionKind{
|
||||
{Group: "one", Version: AnyVersion, Kind: AnyKind},
|
||||
},
|
||||
result: schema.GroupVersionKind{Group: "one", Version: "a", Kind: "first"},
|
||||
},
|
||||
{
|
||||
name: "empty match continues",
|
||||
delegate: fixedRESTMapper{kindsFor: []schema.GroupVersionKind{
|
||||
{Group: "one", Version: "a", Kind: "first"},
|
||||
{Group: "two", Version: "b", Kind: "second"},
|
||||
}},
|
||||
kindPatterns: []schema.GroupVersionKind{
|
||||
{Group: "fail", Version: AnyVersion, Kind: AnyKind},
|
||||
{Group: "one", Version: AnyVersion, Kind: AnyKind},
|
||||
},
|
||||
result: schema.GroupVersionKind{Group: "one", Version: "a", Kind: "first"},
|
||||
},
|
||||
{
|
||||
name: "group followed by version selection",
|
||||
delegate: fixedRESTMapper{kindsFor: []schema.GroupVersionKind{
|
||||
{Group: "one", Version: "a", Kind: "first"},
|
||||
{Group: "two", Version: "b", Kind: "second"},
|
||||
{Group: "one", Version: "c", Kind: "third"},
|
||||
}},
|
||||
kindPatterns: []schema.GroupVersionKind{
|
||||
{Group: "one", Version: AnyVersion, Kind: AnyKind},
|
||||
{Group: AnyGroup, Version: "a", Kind: AnyKind},
|
||||
},
|
||||
result: schema.GroupVersionKind{Group: "one", Version: "a", Kind: "first"},
|
||||
},
|
||||
{
|
||||
name: "kind selection",
|
||||
delegate: fixedRESTMapper{kindsFor: []schema.GroupVersionKind{
|
||||
{Group: "one", Version: "a", Kind: "first"},
|
||||
{Group: "one", Version: "a", Kind: "second"},
|
||||
}},
|
||||
kindPatterns: []schema.GroupVersionKind{
|
||||
{Group: AnyGroup, Version: AnyVersion, Kind: "second"},
|
||||
},
|
||||
result: schema.GroupVersionKind{Group: "one", Version: "a", Kind: "second"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
mapper := PriorityRESTMapper{Delegate: tc.delegate, KindPriority: tc.kindPatterns}
|
||||
|
||||
actualResult, actualErr := mapper.KindFor(schema.GroupVersionResource{})
|
||||
if e, a := tc.result, actualResult; e != a {
|
||||
t.Errorf("%s: expected %v, got %v", tc.name, e, a)
|
||||
}
|
||||
if len(tc.err) == 0 && actualErr == nil {
|
||||
continue
|
||||
}
|
||||
if len(tc.err) > 0 && actualErr == nil {
|
||||
t.Errorf("%s: missing expected err: %v", tc.name, tc.err)
|
||||
continue
|
||||
}
|
||||
if !strings.Contains(actualErr.Error(), tc.err) {
|
||||
t.Errorf("%s: expected %v, got %v", tc.name, tc.err, actualErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPriorityRESTMapperRESTMapping(t *testing.T) {
|
||||
mapping1 := &RESTMapping{
|
||||
GroupVersionKind: schema.GroupVersionKind{Kind: "Foo", Version: "v1alpha1"},
|
||||
}
|
||||
mapping2 := &RESTMapping{
|
||||
GroupVersionKind: schema.GroupVersionKind{Kind: "Foo", Version: "v1"},
|
||||
}
|
||||
mapping3 := &RESTMapping{
|
||||
GroupVersionKind: schema.GroupVersionKind{Group: "other", Kind: "Foo", Version: "v1"},
|
||||
}
|
||||
allMappers := MultiRESTMapper{
|
||||
fixedRESTMapper{mappings: []*RESTMapping{mapping1}},
|
||||
fixedRESTMapper{mappings: []*RESTMapping{mapping2}},
|
||||
fixedRESTMapper{mappings: []*RESTMapping{mapping3}},
|
||||
}
|
||||
tcs := []struct {
|
||||
name string
|
||||
|
||||
mapper PriorityRESTMapper
|
||||
input schema.GroupKind
|
||||
result *RESTMapping
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
mapper: PriorityRESTMapper{Delegate: MultiRESTMapper{}},
|
||||
input: schema.GroupKind{Kind: "Foo"},
|
||||
err: &NoKindMatchError{GroupKind: schema.GroupKind{Kind: "Foo"}},
|
||||
},
|
||||
{
|
||||
name: "ignore not found",
|
||||
mapper: PriorityRESTMapper{Delegate: MultiRESTMapper{fixedRESTMapper{err: &NoKindMatchError{GroupKind: schema.GroupKind{Kind: "IGNORE_THIS"}}}}},
|
||||
input: schema.GroupKind{Kind: "Foo"},
|
||||
err: &NoKindMatchError{GroupKind: schema.GroupKind{Kind: "Foo"}},
|
||||
},
|
||||
{
|
||||
name: "accept first failure",
|
||||
mapper: PriorityRESTMapper{Delegate: MultiRESTMapper{fixedRESTMapper{err: errors.New("fail on this")}, fixedRESTMapper{mappings: []*RESTMapping{mapping1}}}},
|
||||
input: schema.GroupKind{Kind: "Foo"},
|
||||
err: errors.New("fail on this"),
|
||||
},
|
||||
{
|
||||
name: "return error for ambiguous",
|
||||
mapper: PriorityRESTMapper{
|
||||
Delegate: allMappers,
|
||||
},
|
||||
input: schema.GroupKind{Kind: "Foo"},
|
||||
err: &AmbiguousKindError{
|
||||
PartialKind: schema.GroupVersionKind{Kind: "Foo"},
|
||||
MatchingKinds: []schema.GroupVersionKind{
|
||||
{Kind: "Foo", Version: "v1alpha1"},
|
||||
{Kind: "Foo", Version: "v1"},
|
||||
{Group: "other", Kind: "Foo", Version: "v1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "accept only item",
|
||||
mapper: PriorityRESTMapper{
|
||||
Delegate: fixedRESTMapper{mappings: []*RESTMapping{mapping1}},
|
||||
},
|
||||
input: schema.GroupKind{Kind: "Foo"},
|
||||
result: mapping1,
|
||||
},
|
||||
{
|
||||
name: "return single priority",
|
||||
mapper: PriorityRESTMapper{
|
||||
Delegate: allMappers,
|
||||
KindPriority: []schema.GroupVersionKind{{Version: "v1", Kind: AnyKind}, {Version: "v1alpha1", Kind: AnyKind}},
|
||||
},
|
||||
input: schema.GroupKind{Kind: "Foo"},
|
||||
result: mapping2,
|
||||
},
|
||||
{
|
||||
name: "return out of group match",
|
||||
mapper: PriorityRESTMapper{
|
||||
Delegate: allMappers,
|
||||
KindPriority: []schema.GroupVersionKind{{Group: AnyGroup, Version: "v1", Kind: AnyKind}, {Group: "other", Version: AnyVersion, Kind: AnyKind}},
|
||||
},
|
||||
input: schema.GroupKind{Kind: "Foo"},
|
||||
result: mapping3,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
actualResult, actualErr := tc.mapper.RESTMapping(tc.input)
|
||||
if e, a := tc.result, actualResult; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%s: expected %v, got %v", tc.name, e, a)
|
||||
}
|
||||
switch {
|
||||
case tc.err == nil && actualErr == nil:
|
||||
case tc.err == nil:
|
||||
t.Errorf("%s: unexpected error: %v", tc.name, actualErr)
|
||||
case actualErr == nil:
|
||||
t.Errorf("%s: expected error: %v got nil", tc.name, tc.err)
|
||||
case tc.err.Error() != actualErr.Error():
|
||||
t.Errorf("%s: expected %v, got %v", tc.name, tc.err, actualErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPriorityRESTMapperRESTMappingHonorsUserVersion(t *testing.T) {
|
||||
mappingV2alpha1 := &RESTMapping{
|
||||
GroupVersionKind: schema.GroupVersionKind{Group: "Bar", Kind: "Foo", Version: "v2alpha1"},
|
||||
}
|
||||
mappingV1 := &RESTMapping{
|
||||
GroupVersionKind: schema.GroupVersionKind{Group: "Bar", Kind: "Foo", Version: "v1"},
|
||||
}
|
||||
|
||||
allMappers := MultiRESTMapper{
|
||||
fixedRESTMapper{mappings: []*RESTMapping{mappingV2alpha1}},
|
||||
fixedRESTMapper{mappings: []*RESTMapping{mappingV1}},
|
||||
}
|
||||
|
||||
mapper := PriorityRESTMapper{
|
||||
Delegate: allMappers,
|
||||
KindPriority: []schema.GroupVersionKind{{Group: "Bar", Version: "v2alpha1", Kind: AnyKind}, {Group: "Bar", Version: AnyVersion, Kind: AnyKind}},
|
||||
}
|
||||
|
||||
outMapping1, err := mapper.RESTMapping(schema.GroupKind{Group: "Bar", Kind: "Foo"}, "v1")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if outMapping1 != mappingV1 {
|
||||
t.Errorf("asked for version %v, expected mapping for %v, got mapping for %v", "v1", mappingV1.GroupVersionKind, outMapping1.GroupVersionKind)
|
||||
}
|
||||
|
||||
outMapping2, err := mapper.RESTMapping(schema.GroupKind{Group: "Bar", Kind: "Foo"}, "v2alpha1")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if outMapping2 != mappingV2alpha1 {
|
||||
t.Errorf("asked for version %v, expected mapping for %v, got mapping for %v", "v2alpha1", mappingV2alpha1.GroupVersionKind, outMapping2.GroupVersionKind)
|
||||
}
|
||||
}
|
||||
751
vendor/k8s.io/apimachinery/pkg/api/meta/restmapper_test.go
generated
vendored
751
vendor/k8s.io/apimachinery/pkg/api/meta/restmapper_test.go
generated
vendored
|
|
@ -1,751 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 meta
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
type fakeConvertor struct{}
|
||||
|
||||
func (fakeConvertor) Convert(in, out, context interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fakeConvertor) ConvertToVersion(in runtime.Object, _ runtime.GroupVersioner) (runtime.Object, error) {
|
||||
return in, nil
|
||||
}
|
||||
|
||||
func (fakeConvertor) ConvertFieldLabel(version, kind, label, value string) (string, string, error) {
|
||||
return label, value, nil
|
||||
}
|
||||
|
||||
var validAccessor = resourceAccessor{}
|
||||
var validConvertor = fakeConvertor{}
|
||||
|
||||
func fakeInterfaces(version schema.GroupVersion) (*VersionInterfaces, error) {
|
||||
return &VersionInterfaces{ObjectConvertor: validConvertor, MetadataAccessor: validAccessor}, nil
|
||||
}
|
||||
|
||||
var unmatchedErr = errors.New("no version")
|
||||
|
||||
func unmatchedVersionInterfaces(version schema.GroupVersion) (*VersionInterfaces, error) {
|
||||
return nil, unmatchedErr
|
||||
}
|
||||
|
||||
func TestRESTMapperVersionAndKindForResource(t *testing.T) {
|
||||
testGroup := "test.group"
|
||||
testVersion := "test"
|
||||
testGroupVersion := schema.GroupVersion{Group: testGroup, Version: testVersion}
|
||||
|
||||
testCases := []struct {
|
||||
Resource schema.GroupVersionResource
|
||||
GroupVersionToRegister schema.GroupVersion
|
||||
ExpectedGVK schema.GroupVersionKind
|
||||
Err bool
|
||||
}{
|
||||
{Resource: schema.GroupVersionResource{Resource: "internalobjec"}, Err: true},
|
||||
{Resource: schema.GroupVersionResource{Resource: "internalObjec"}, Err: true},
|
||||
|
||||
{Resource: schema.GroupVersionResource{Resource: "internalobject"}, ExpectedGVK: testGroupVersion.WithKind("InternalObject")},
|
||||
{Resource: schema.GroupVersionResource{Resource: "internalobjects"}, ExpectedGVK: testGroupVersion.WithKind("InternalObject")},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
mapper := NewDefaultRESTMapper([]schema.GroupVersion{testGroupVersion}, fakeInterfaces)
|
||||
if len(testCase.ExpectedGVK.Kind) != 0 {
|
||||
mapper.Add(testCase.ExpectedGVK, RESTScopeNamespace)
|
||||
}
|
||||
actualGVK, err := mapper.KindFor(testCase.Resource)
|
||||
|
||||
hasErr := err != nil
|
||||
if hasErr != testCase.Err {
|
||||
t.Errorf("%d: unexpected error behavior %t: %v", i, testCase.Err, err)
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if actualGVK != testCase.ExpectedGVK {
|
||||
t.Errorf("%d: unexpected version and kind: e=%s a=%s", i, testCase.ExpectedGVK, actualGVK)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRESTMapperGroupForResource(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Resource schema.GroupVersionResource
|
||||
GroupVersionKind schema.GroupVersionKind
|
||||
Err bool
|
||||
}{
|
||||
{Resource: schema.GroupVersionResource{Resource: "myObject"}, GroupVersionKind: schema.GroupVersionKind{Group: "testapi", Version: "test", Kind: "MyObject"}},
|
||||
{Resource: schema.GroupVersionResource{Resource: "myobject"}, GroupVersionKind: schema.GroupVersionKind{Group: "testapi2", Version: "test", Kind: "MyObject"}},
|
||||
{Resource: schema.GroupVersionResource{Resource: "myObje"}, Err: true, GroupVersionKind: schema.GroupVersionKind{Group: "testapi", Version: "test", Kind: "MyObject"}},
|
||||
{Resource: schema.GroupVersionResource{Resource: "myobje"}, Err: true, GroupVersionKind: schema.GroupVersionKind{Group: "testapi", Version: "test", Kind: "MyObject"}},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
mapper := NewDefaultRESTMapper([]schema.GroupVersion{testCase.GroupVersionKind.GroupVersion()}, fakeInterfaces)
|
||||
mapper.Add(testCase.GroupVersionKind, RESTScopeNamespace)
|
||||
|
||||
actualGVK, err := mapper.KindFor(testCase.Resource)
|
||||
if testCase.Err {
|
||||
if err == nil {
|
||||
t.Errorf("%d: expected error", i)
|
||||
}
|
||||
} else if err != nil {
|
||||
t.Errorf("%d: unexpected error: %v", i, err)
|
||||
} else if actualGVK != testCase.GroupVersionKind {
|
||||
t.Errorf("%d: expected group %q, got %q", i, testCase.GroupVersionKind, actualGVK)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRESTMapperKindsFor(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Name string
|
||||
PreferredOrder []schema.GroupVersion
|
||||
KindsToRegister []schema.GroupVersionKind
|
||||
PartialResourceToRequest schema.GroupVersionResource
|
||||
|
||||
ExpectedKinds []schema.GroupVersionKind
|
||||
ExpectedKindErr string
|
||||
}{
|
||||
{
|
||||
// exact matches are preferred
|
||||
Name: "groups, with group exact",
|
||||
PreferredOrder: []schema.GroupVersion{
|
||||
{Group: "first-group-1", Version: "first-version"},
|
||||
{Group: "first-group", Version: "first-version"},
|
||||
},
|
||||
KindsToRegister: []schema.GroupVersionKind{
|
||||
{Group: "first-group-1", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
},
|
||||
PartialResourceToRequest: schema.GroupVersionResource{Group: "first-group", Resource: "my-kind"},
|
||||
|
||||
ExpectedKinds: []schema.GroupVersionKind{
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
// group prefixes work
|
||||
Name: "groups, with group prefix",
|
||||
PreferredOrder: []schema.GroupVersion{
|
||||
{Group: "second-group", Version: "first-version"},
|
||||
{Group: "first-group", Version: "first-version"},
|
||||
},
|
||||
KindsToRegister: []schema.GroupVersionKind{
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "second-group", Version: "first-version", Kind: "my-kind"},
|
||||
},
|
||||
PartialResourceToRequest: schema.GroupVersionResource{Group: "first", Resource: "my-kind"},
|
||||
|
||||
ExpectedKinds: []schema.GroupVersionKind{
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
// group prefixes can be ambiguous
|
||||
Name: "groups, with ambiguous group prefix",
|
||||
PreferredOrder: []schema.GroupVersion{
|
||||
{Group: "first-group-1", Version: "first-version"},
|
||||
{Group: "first-group", Version: "first-version"},
|
||||
},
|
||||
KindsToRegister: []schema.GroupVersionKind{
|
||||
{Group: "first-group-1", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
},
|
||||
PartialResourceToRequest: schema.GroupVersionResource{Group: "first", Resource: "my-kind"},
|
||||
|
||||
ExpectedKinds: []schema.GroupVersionKind{
|
||||
{Group: "first-group-1", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
},
|
||||
ExpectedKindErr: " matches multiple kinds ",
|
||||
},
|
||||
|
||||
{
|
||||
Name: "ambiguous groups, with preference order",
|
||||
PreferredOrder: []schema.GroupVersion{
|
||||
{Group: "second-group", Version: "first-version"},
|
||||
{Group: "first-group", Version: "first-version"},
|
||||
},
|
||||
KindsToRegister: []schema.GroupVersionKind{
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "first-group", Version: "first-version", Kind: "your-kind"},
|
||||
{Group: "second-group", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "second-group", Version: "first-version", Kind: "your-kind"},
|
||||
},
|
||||
PartialResourceToRequest: schema.GroupVersionResource{Resource: "my-kinds"},
|
||||
|
||||
ExpectedKinds: []schema.GroupVersionKind{
|
||||
{Group: "second-group", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
},
|
||||
ExpectedKindErr: " matches multiple kinds ",
|
||||
},
|
||||
|
||||
{
|
||||
Name: "ambiguous groups, with explicit group match",
|
||||
PreferredOrder: []schema.GroupVersion{
|
||||
{Group: "second-group", Version: "first-version"},
|
||||
{Group: "first-group", Version: "first-version"},
|
||||
},
|
||||
KindsToRegister: []schema.GroupVersionKind{
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "first-group", Version: "first-version", Kind: "your-kind"},
|
||||
{Group: "second-group", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "second-group", Version: "first-version", Kind: "your-kind"},
|
||||
},
|
||||
PartialResourceToRequest: schema.GroupVersionResource{Group: "first-group", Resource: "my-kinds"},
|
||||
|
||||
ExpectedKinds: []schema.GroupVersionKind{
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
Name: "ambiguous groups, with ambiguous version match",
|
||||
PreferredOrder: []schema.GroupVersion{
|
||||
{Group: "first-group", Version: "first-version"},
|
||||
{Group: "second-group", Version: "first-version"},
|
||||
},
|
||||
KindsToRegister: []schema.GroupVersionKind{
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "first-group", Version: "first-version", Kind: "your-kind"},
|
||||
{Group: "second-group", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "second-group", Version: "first-version", Kind: "your-kind"},
|
||||
},
|
||||
PartialResourceToRequest: schema.GroupVersionResource{Version: "first-version", Resource: "my-kinds"},
|
||||
|
||||
ExpectedKinds: []schema.GroupVersionKind{
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "second-group", Version: "first-version", Kind: "my-kind"},
|
||||
},
|
||||
ExpectedKindErr: " matches multiple kinds ",
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
tcName := testCase.Name
|
||||
mapper := NewDefaultRESTMapper(testCase.PreferredOrder, fakeInterfaces)
|
||||
for _, kind := range testCase.KindsToRegister {
|
||||
mapper.Add(kind, RESTScopeNamespace)
|
||||
}
|
||||
|
||||
actualKinds, err := mapper.KindsFor(testCase.PartialResourceToRequest)
|
||||
if err != nil {
|
||||
t.Errorf("%s: unexpected error: %v", tcName, err)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(testCase.ExpectedKinds, actualKinds) {
|
||||
t.Errorf("%s: expected %v, got %v", tcName, testCase.ExpectedKinds, actualKinds)
|
||||
}
|
||||
|
||||
singleKind, err := mapper.KindFor(testCase.PartialResourceToRequest)
|
||||
if err == nil && len(testCase.ExpectedKindErr) != 0 {
|
||||
t.Errorf("%s: expected error: %v", tcName, testCase.ExpectedKindErr)
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
if len(testCase.ExpectedKindErr) == 0 {
|
||||
t.Errorf("%s: unexpected error: %v", tcName, err)
|
||||
continue
|
||||
} else {
|
||||
if !strings.Contains(err.Error(), testCase.ExpectedKindErr) {
|
||||
t.Errorf("%s: expected %v, got %v", tcName, testCase.ExpectedKindErr, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if testCase.ExpectedKinds[0] != singleKind {
|
||||
t.Errorf("%s: expected %v, got %v", tcName, testCase.ExpectedKinds[0], singleKind)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRESTMapperResourcesFor(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Name string
|
||||
PreferredOrder []schema.GroupVersion
|
||||
KindsToRegister []schema.GroupVersionKind
|
||||
PluralPartialResourceToRequest schema.GroupVersionResource
|
||||
SingularPartialResourceToRequest schema.GroupVersionResource
|
||||
|
||||
ExpectedResources []schema.GroupVersionResource
|
||||
ExpectedResourceErr string
|
||||
}{
|
||||
{
|
||||
// exact matches are preferred
|
||||
Name: "groups, with group exact",
|
||||
PreferredOrder: []schema.GroupVersion{
|
||||
{Group: "first-group-1", Version: "first-version"},
|
||||
{Group: "first-group", Version: "first-version"},
|
||||
},
|
||||
KindsToRegister: []schema.GroupVersionKind{
|
||||
{Group: "first-group-1", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
},
|
||||
PluralPartialResourceToRequest: schema.GroupVersionResource{Group: "first-group", Resource: "my-kinds"},
|
||||
SingularPartialResourceToRequest: schema.GroupVersionResource{Group: "first-group", Resource: "my-kind"},
|
||||
|
||||
ExpectedResources: []schema.GroupVersionResource{
|
||||
{Group: "first-group", Version: "first-version", Resource: "my-kinds"},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
// group prefixes work
|
||||
Name: "groups, with group prefix",
|
||||
PreferredOrder: []schema.GroupVersion{
|
||||
{Group: "second-group", Version: "first-version"},
|
||||
{Group: "first-group", Version: "first-version"},
|
||||
},
|
||||
KindsToRegister: []schema.GroupVersionKind{
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "second-group", Version: "first-version", Kind: "my-kind"},
|
||||
},
|
||||
PluralPartialResourceToRequest: schema.GroupVersionResource{Group: "first", Resource: "my-kinds"},
|
||||
SingularPartialResourceToRequest: schema.GroupVersionResource{Group: "first", Resource: "my-kind"},
|
||||
|
||||
ExpectedResources: []schema.GroupVersionResource{
|
||||
{Group: "first-group", Version: "first-version", Resource: "my-kinds"},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
// group prefixes can be ambiguous
|
||||
Name: "groups, with ambiguous group prefix",
|
||||
PreferredOrder: []schema.GroupVersion{
|
||||
{Group: "first-group-1", Version: "first-version"},
|
||||
{Group: "first-group", Version: "first-version"},
|
||||
},
|
||||
KindsToRegister: []schema.GroupVersionKind{
|
||||
{Group: "first-group-1", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
},
|
||||
PluralPartialResourceToRequest: schema.GroupVersionResource{Group: "first", Resource: "my-kinds"},
|
||||
SingularPartialResourceToRequest: schema.GroupVersionResource{Group: "first", Resource: "my-kind"},
|
||||
|
||||
ExpectedResources: []schema.GroupVersionResource{
|
||||
{Group: "first-group-1", Version: "first-version", Resource: "my-kinds"},
|
||||
{Group: "first-group", Version: "first-version", Resource: "my-kinds"},
|
||||
},
|
||||
ExpectedResourceErr: " matches multiple resources ",
|
||||
},
|
||||
|
||||
{
|
||||
Name: "ambiguous groups, with preference order",
|
||||
PreferredOrder: []schema.GroupVersion{
|
||||
{Group: "second-group", Version: "first-version"},
|
||||
{Group: "first-group", Version: "first-version"},
|
||||
},
|
||||
KindsToRegister: []schema.GroupVersionKind{
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "first-group", Version: "first-version", Kind: "your-kind"},
|
||||
{Group: "second-group", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "second-group", Version: "first-version", Kind: "your-kind"},
|
||||
},
|
||||
PluralPartialResourceToRequest: schema.GroupVersionResource{Resource: "my-kinds"},
|
||||
SingularPartialResourceToRequest: schema.GroupVersionResource{Resource: "my-kind"},
|
||||
|
||||
ExpectedResources: []schema.GroupVersionResource{
|
||||
{Group: "second-group", Version: "first-version", Resource: "my-kinds"},
|
||||
{Group: "first-group", Version: "first-version", Resource: "my-kinds"},
|
||||
},
|
||||
ExpectedResourceErr: " matches multiple resources ",
|
||||
},
|
||||
|
||||
{
|
||||
Name: "ambiguous groups, with explicit group match",
|
||||
PreferredOrder: []schema.GroupVersion{
|
||||
{Group: "second-group", Version: "first-version"},
|
||||
{Group: "first-group", Version: "first-version"},
|
||||
},
|
||||
KindsToRegister: []schema.GroupVersionKind{
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "first-group", Version: "first-version", Kind: "your-kind"},
|
||||
{Group: "second-group", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "second-group", Version: "first-version", Kind: "your-kind"},
|
||||
},
|
||||
PluralPartialResourceToRequest: schema.GroupVersionResource{Group: "first-group", Resource: "my-kinds"},
|
||||
SingularPartialResourceToRequest: schema.GroupVersionResource{Group: "first-group", Resource: "my-kind"},
|
||||
|
||||
ExpectedResources: []schema.GroupVersionResource{
|
||||
{Group: "first-group", Version: "first-version", Resource: "my-kinds"},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
Name: "ambiguous groups, with ambiguous version match",
|
||||
PreferredOrder: []schema.GroupVersion{
|
||||
{Group: "first-group", Version: "first-version"},
|
||||
{Group: "second-group", Version: "first-version"},
|
||||
},
|
||||
KindsToRegister: []schema.GroupVersionKind{
|
||||
{Group: "first-group", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "first-group", Version: "first-version", Kind: "your-kind"},
|
||||
{Group: "second-group", Version: "first-version", Kind: "my-kind"},
|
||||
{Group: "second-group", Version: "first-version", Kind: "your-kind"},
|
||||
},
|
||||
PluralPartialResourceToRequest: schema.GroupVersionResource{Version: "first-version", Resource: "my-kinds"},
|
||||
SingularPartialResourceToRequest: schema.GroupVersionResource{Version: "first-version", Resource: "my-kind"},
|
||||
|
||||
ExpectedResources: []schema.GroupVersionResource{
|
||||
{Group: "first-group", Version: "first-version", Resource: "my-kinds"},
|
||||
{Group: "second-group", Version: "first-version", Resource: "my-kinds"},
|
||||
},
|
||||
ExpectedResourceErr: " matches multiple resources ",
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
tcName := testCase.Name
|
||||
|
||||
for _, partialResource := range []schema.GroupVersionResource{testCase.PluralPartialResourceToRequest, testCase.SingularPartialResourceToRequest} {
|
||||
mapper := NewDefaultRESTMapper(testCase.PreferredOrder, fakeInterfaces)
|
||||
for _, kind := range testCase.KindsToRegister {
|
||||
mapper.Add(kind, RESTScopeNamespace)
|
||||
}
|
||||
|
||||
actualResources, err := mapper.ResourcesFor(partialResource)
|
||||
if err != nil {
|
||||
t.Errorf("%s: unexpected error: %v", tcName, err)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(testCase.ExpectedResources, actualResources) {
|
||||
t.Errorf("%s: expected %v, got %v", tcName, testCase.ExpectedResources, actualResources)
|
||||
}
|
||||
|
||||
singleResource, err := mapper.ResourceFor(partialResource)
|
||||
if err == nil && len(testCase.ExpectedResourceErr) != 0 {
|
||||
t.Errorf("%s: expected error: %v", tcName, testCase.ExpectedResourceErr)
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
if len(testCase.ExpectedResourceErr) == 0 {
|
||||
t.Errorf("%s: unexpected error: %v", tcName, err)
|
||||
continue
|
||||
} else {
|
||||
if !strings.Contains(err.Error(), testCase.ExpectedResourceErr) {
|
||||
t.Errorf("%s: expected %v, got %v", tcName, testCase.ExpectedResourceErr, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if testCase.ExpectedResources[0] != singleResource {
|
||||
t.Errorf("%s: expected %v, got %v", tcName, testCase.ExpectedResources[0], singleResource)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestKindToResource(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Kind string
|
||||
Plural, Singular string
|
||||
}{
|
||||
{Kind: "Pod", Plural: "pods", Singular: "pod"},
|
||||
|
||||
{Kind: "ReplicationController", Plural: "replicationcontrollers", Singular: "replicationcontroller"},
|
||||
|
||||
// Add "ies" when ending with "y"
|
||||
{Kind: "ImageRepository", Plural: "imagerepositories", Singular: "imagerepository"},
|
||||
// Add "es" when ending with "s"
|
||||
{Kind: "miss", Plural: "misses", Singular: "miss"},
|
||||
// Add "s" otherwise
|
||||
{Kind: "lowercase", Plural: "lowercases", Singular: "lowercase"},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
version := schema.GroupVersion{}
|
||||
|
||||
plural, singular := UnsafeGuessKindToResource(version.WithKind(testCase.Kind))
|
||||
if singular != version.WithResource(testCase.Singular) || plural != version.WithResource(testCase.Plural) {
|
||||
t.Errorf("%d: unexpected plural and singular: %v %v", i, plural, singular)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRESTMapperResourceSingularizer(t *testing.T) {
|
||||
testGroupVersion := schema.GroupVersion{Group: "tgroup", Version: "test"}
|
||||
|
||||
testCases := []struct {
|
||||
Kind string
|
||||
Plural string
|
||||
Singular string
|
||||
}{
|
||||
{Kind: "Pod", Plural: "pods", Singular: "pod"},
|
||||
{Kind: "ReplicationController", Plural: "replicationcontrollers", Singular: "replicationcontroller"},
|
||||
{Kind: "ImageRepository", Plural: "imagerepositories", Singular: "imagerepository"},
|
||||
{Kind: "Status", Plural: "statuses", Singular: "status"},
|
||||
|
||||
{Kind: "lowercase", Plural: "lowercases", Singular: "lowercase"},
|
||||
// TODO this test is broken. This updates to reflect actual behavior. Kinds are expected to be singular
|
||||
// old (incorrect), comment: Don't add extra s if the original object is already plural
|
||||
{Kind: "lowercases", Plural: "lowercaseses", Singular: "lowercases"},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
mapper := NewDefaultRESTMapper([]schema.GroupVersion{testGroupVersion}, fakeInterfaces)
|
||||
// create singular/plural mapping
|
||||
mapper.Add(testGroupVersion.WithKind(testCase.Kind), RESTScopeNamespace)
|
||||
|
||||
singular, err := mapper.ResourceSingularizer(testCase.Plural)
|
||||
if err != nil {
|
||||
t.Errorf("%d: unexpected error: %v", i, err)
|
||||
}
|
||||
if singular != testCase.Singular {
|
||||
t.Errorf("%d: mismatched singular: got %v, expected %v", i, singular, testCase.Singular)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRESTMapperRESTMapping(t *testing.T) {
|
||||
testGroup := "tgroup"
|
||||
testGroupVersion := schema.GroupVersion{Group: testGroup, Version: "test"}
|
||||
internalGroupVersion := schema.GroupVersion{Group: testGroup, Version: "test"}
|
||||
|
||||
testCases := []struct {
|
||||
Kind string
|
||||
APIGroupVersions []schema.GroupVersion
|
||||
DefaultVersions []schema.GroupVersion
|
||||
|
||||
Resource string
|
||||
ExpectedGroupVersion *schema.GroupVersion
|
||||
Err bool
|
||||
}{
|
||||
{Kind: "Unknown", Err: true},
|
||||
{Kind: "InternalObject", Err: true},
|
||||
|
||||
{DefaultVersions: []schema.GroupVersion{testGroupVersion}, Kind: "Unknown", Err: true},
|
||||
|
||||
{DefaultVersions: []schema.GroupVersion{testGroupVersion}, Kind: "InternalObject", APIGroupVersions: []schema.GroupVersion{{Group: testGroup, Version: "test"}}, Resource: "internalobjects"},
|
||||
{DefaultVersions: []schema.GroupVersion{testGroupVersion}, Kind: "InternalObject", APIGroupVersions: []schema.GroupVersion{{Group: testGroup, Version: "test"}}, Resource: "internalobjects"},
|
||||
|
||||
{DefaultVersions: []schema.GroupVersion{testGroupVersion}, Kind: "InternalObject", APIGroupVersions: []schema.GroupVersion{{Group: testGroup, Version: "test"}}, Resource: "internalobjects"},
|
||||
|
||||
{DefaultVersions: []schema.GroupVersion{testGroupVersion}, Kind: "InternalObject", APIGroupVersions: []schema.GroupVersion{}, Resource: "internalobjects", ExpectedGroupVersion: &schema.GroupVersion{Group: testGroup, Version: "test"}},
|
||||
|
||||
{DefaultVersions: []schema.GroupVersion{testGroupVersion}, Kind: "InternalObject", APIGroupVersions: []schema.GroupVersion{{Group: testGroup, Version: "test"}}, Resource: "internalobjects"},
|
||||
|
||||
// TODO: add test for a resource that exists in one version but not another
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
mapper := NewDefaultRESTMapper(testCase.DefaultVersions, fakeInterfaces)
|
||||
mapper.Add(internalGroupVersion.WithKind("InternalObject"), RESTScopeNamespace)
|
||||
|
||||
preferredVersions := []string{}
|
||||
for _, gv := range testCase.APIGroupVersions {
|
||||
preferredVersions = append(preferredVersions, gv.Version)
|
||||
}
|
||||
gk := schema.GroupKind{Group: testGroup, Kind: testCase.Kind}
|
||||
|
||||
mapping, err := mapper.RESTMapping(gk, preferredVersions...)
|
||||
hasErr := err != nil
|
||||
if hasErr != testCase.Err {
|
||||
t.Errorf("%d: unexpected error behavior %t: %v", i, testCase.Err, err)
|
||||
}
|
||||
if hasErr {
|
||||
continue
|
||||
}
|
||||
if mapping.Resource != testCase.Resource {
|
||||
t.Errorf("%d: unexpected resource: %#v", i, mapping)
|
||||
}
|
||||
|
||||
if mapping.MetadataAccessor == nil || mapping.ObjectConvertor == nil {
|
||||
t.Errorf("%d: missing codec and accessor: %#v", i, mapping)
|
||||
}
|
||||
|
||||
groupVersion := testCase.ExpectedGroupVersion
|
||||
if groupVersion == nil {
|
||||
groupVersion = &testCase.APIGroupVersions[0]
|
||||
}
|
||||
if mapping.GroupVersionKind.GroupVersion() != *groupVersion {
|
||||
t.Errorf("%d: unexpected version: %#v", i, mapping)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestRESTMapperRESTMappingSelectsVersion(t *testing.T) {
|
||||
expectedGroupVersion1 := schema.GroupVersion{Group: "tgroup", Version: "test1"}
|
||||
expectedGroupVersion2 := schema.GroupVersion{Group: "tgroup", Version: "test2"}
|
||||
expectedGroupVersion3 := schema.GroupVersion{Group: "tgroup", Version: "test3"}
|
||||
internalObjectGK := schema.GroupKind{Group: "tgroup", Kind: "InternalObject"}
|
||||
otherObjectGK := schema.GroupKind{Group: "tgroup", Kind: "OtherObject"}
|
||||
|
||||
mapper := NewDefaultRESTMapper([]schema.GroupVersion{expectedGroupVersion1, expectedGroupVersion2}, fakeInterfaces)
|
||||
mapper.Add(expectedGroupVersion1.WithKind("InternalObject"), RESTScopeNamespace)
|
||||
mapper.Add(expectedGroupVersion2.WithKind("OtherObject"), RESTScopeNamespace)
|
||||
|
||||
// pick default matching object kind based on search order
|
||||
mapping, err := mapper.RESTMapping(otherObjectGK)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if mapping.Resource != "otherobjects" || mapping.GroupVersionKind.GroupVersion() != expectedGroupVersion2 {
|
||||
t.Errorf("unexpected mapping: %#v", mapping)
|
||||
}
|
||||
|
||||
mapping, err = mapper.RESTMapping(internalObjectGK)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if mapping.Resource != "internalobjects" || mapping.GroupVersionKind.GroupVersion() != expectedGroupVersion1 {
|
||||
t.Errorf("unexpected mapping: %#v", mapping)
|
||||
}
|
||||
|
||||
// mismatch of version
|
||||
mapping, err = mapper.RESTMapping(internalObjectGK, expectedGroupVersion2.Version)
|
||||
if err == nil {
|
||||
t.Errorf("unexpected non-error")
|
||||
}
|
||||
mapping, err = mapper.RESTMapping(otherObjectGK, expectedGroupVersion1.Version)
|
||||
if err == nil {
|
||||
t.Errorf("unexpected non-error")
|
||||
}
|
||||
|
||||
// not in the search versions
|
||||
mapping, err = mapper.RESTMapping(otherObjectGK, expectedGroupVersion3.Version)
|
||||
if err == nil {
|
||||
t.Errorf("unexpected non-error")
|
||||
}
|
||||
|
||||
// explicit search order
|
||||
mapping, err = mapper.RESTMapping(otherObjectGK, expectedGroupVersion3.Version, expectedGroupVersion1.Version)
|
||||
if err == nil {
|
||||
t.Errorf("unexpected non-error")
|
||||
}
|
||||
|
||||
mapping, err = mapper.RESTMapping(otherObjectGK, expectedGroupVersion3.Version, expectedGroupVersion2.Version)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if mapping.Resource != "otherobjects" || mapping.GroupVersionKind.GroupVersion() != expectedGroupVersion2 {
|
||||
t.Errorf("unexpected mapping: %#v", mapping)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRESTMapperRESTMappings(t *testing.T) {
|
||||
testGroup := "tgroup"
|
||||
testGroupVersion := schema.GroupVersion{Group: testGroup, Version: "v1"}
|
||||
|
||||
testCases := []struct {
|
||||
Kind string
|
||||
APIGroupVersions []schema.GroupVersion
|
||||
DefaultVersions []schema.GroupVersion
|
||||
AddGroupVersionKind []schema.GroupVersionKind
|
||||
|
||||
ExpectedRESTMappings []*RESTMapping
|
||||
Err bool
|
||||
}{
|
||||
{Kind: "Unknown", Err: true},
|
||||
{Kind: "InternalObject", Err: true},
|
||||
|
||||
{DefaultVersions: []schema.GroupVersion{testGroupVersion}, Kind: "Unknown", Err: true},
|
||||
|
||||
// ask for specific version - not available - thus error
|
||||
{DefaultVersions: []schema.GroupVersion{testGroupVersion}, Kind: "InternalObject", APIGroupVersions: []schema.GroupVersion{{Group: testGroup, Version: "v2"}}, Err: true},
|
||||
|
||||
// ask for specific version - available - check ExpectedRESTMappings
|
||||
{
|
||||
DefaultVersions: []schema.GroupVersion{testGroupVersion},
|
||||
Kind: "InternalObject",
|
||||
APIGroupVersions: []schema.GroupVersion{{Group: testGroup, Version: "v2"}},
|
||||
AddGroupVersionKind: []schema.GroupVersionKind{schema.GroupVersion{Group: testGroup, Version: "v2"}.WithKind("InternalObject")},
|
||||
ExpectedRESTMappings: []*RESTMapping{{Resource: "internalobjects", GroupVersionKind: schema.GroupVersionKind{Group: testGroup, Version: "v2", Kind: "InternalObject"}}},
|
||||
},
|
||||
|
||||
// ask for specific versions - only one available - check ExpectedRESTMappings
|
||||
{
|
||||
DefaultVersions: []schema.GroupVersion{testGroupVersion},
|
||||
Kind: "InternalObject",
|
||||
APIGroupVersions: []schema.GroupVersion{{Group: testGroup, Version: "v3"}, {Group: testGroup, Version: "v2"}},
|
||||
AddGroupVersionKind: []schema.GroupVersionKind{schema.GroupVersion{Group: testGroup, Version: "v2"}.WithKind("InternalObject")},
|
||||
ExpectedRESTMappings: []*RESTMapping{{Resource: "internalobjects", GroupVersionKind: schema.GroupVersionKind{Group: testGroup, Version: "v2", Kind: "InternalObject"}}},
|
||||
},
|
||||
|
||||
// do not ask for specific version - search through default versions - check ExpectedRESTMappings
|
||||
{
|
||||
DefaultVersions: []schema.GroupVersion{testGroupVersion, {Group: testGroup, Version: "v2"}},
|
||||
Kind: "InternalObject",
|
||||
AddGroupVersionKind: []schema.GroupVersionKind{schema.GroupVersion{Group: testGroup, Version: "v1"}.WithKind("InternalObject"), schema.GroupVersion{Group: testGroup, Version: "v2"}.WithKind("InternalObject")},
|
||||
ExpectedRESTMappings: []*RESTMapping{{Resource: "internalobjects", GroupVersionKind: schema.GroupVersionKind{Group: testGroup, Version: "v1", Kind: "InternalObject"}}, {Resource: "internalobjects", GroupVersionKind: schema.GroupVersionKind{Group: testGroup, Version: "v2", Kind: "InternalObject"}}},
|
||||
},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
mapper := NewDefaultRESTMapper(testCase.DefaultVersions, fakeInterfaces)
|
||||
for _, gvk := range testCase.AddGroupVersionKind {
|
||||
mapper.Add(gvk, RESTScopeNamespace)
|
||||
}
|
||||
|
||||
preferredVersions := []string{}
|
||||
for _, gv := range testCase.APIGroupVersions {
|
||||
preferredVersions = append(preferredVersions, gv.Version)
|
||||
}
|
||||
gk := schema.GroupKind{Group: testGroup, Kind: testCase.Kind}
|
||||
|
||||
mappings, err := mapper.RESTMappings(gk, preferredVersions...)
|
||||
hasErr := err != nil
|
||||
if hasErr != testCase.Err {
|
||||
t.Errorf("%d: unexpected error behavior %t: %v", i, testCase.Err, err)
|
||||
}
|
||||
if hasErr {
|
||||
continue
|
||||
}
|
||||
if len(mappings) != len(testCase.ExpectedRESTMappings) {
|
||||
t.Errorf("%d: unexpected number = %d of rest mappings was returned, expected = %d", i, len(mappings), len(testCase.ExpectedRESTMappings))
|
||||
}
|
||||
for j, mapping := range mappings {
|
||||
exp := testCase.ExpectedRESTMappings[j]
|
||||
if mapping.Resource != exp.Resource {
|
||||
t.Errorf("%d - %d: unexpected resource: %#v", i, j, mapping)
|
||||
}
|
||||
if mapping.MetadataAccessor == nil || mapping.ObjectConvertor == nil {
|
||||
t.Errorf("%d - %d: missing codec and accessor: %#v", i, j, mapping)
|
||||
}
|
||||
if mapping.GroupVersionKind != exp.GroupVersionKind {
|
||||
t.Errorf("%d - %d: unexpected GroupVersionKind: %#v", i, j, mapping)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRESTMapperReportsErrorOnBadVersion(t *testing.T) {
|
||||
expectedGroupVersion1 := schema.GroupVersion{Group: "tgroup", Version: "test1"}
|
||||
expectedGroupVersion2 := schema.GroupVersion{Group: "tgroup", Version: "test2"}
|
||||
internalObjectGK := schema.GroupKind{Group: "tgroup", Kind: "InternalObject"}
|
||||
|
||||
mapper := NewDefaultRESTMapper([]schema.GroupVersion{expectedGroupVersion1, expectedGroupVersion2}, unmatchedVersionInterfaces)
|
||||
mapper.Add(expectedGroupVersion1.WithKind("InternalObject"), RESTScopeNamespace)
|
||||
_, err := mapper.RESTMapping(internalObjectGK, expectedGroupVersion1.Version)
|
||||
if err == nil {
|
||||
t.Errorf("unexpected non-error")
|
||||
}
|
||||
}
|
||||
69
vendor/k8s.io/apimachinery/pkg/api/resource/BUILD
generated
vendored
69
vendor/k8s.io/apimachinery/pkg/api/resource/BUILD
generated
vendored
|
|
@ -1,69 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"amount_test.go",
|
||||
"math_test.go",
|
||||
"quantity_proto_test.go",
|
||||
"quantity_test.go",
|
||||
"scale_int_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/github.com/google/gofuzz:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/gopkg.in/inf.v0:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"amount.go",
|
||||
"generated.pb.go",
|
||||
"math.go",
|
||||
"quantity.go",
|
||||
"quantity_proto.go",
|
||||
"scale_int.go",
|
||||
"suffix.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/api/resource",
|
||||
deps = [
|
||||
"//vendor/github.com/gogo/protobuf/proto:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/gopkg.in/inf.v0:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_xtest",
|
||||
srcs = ["quantity_example_test.go"],
|
||||
deps = ["//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "go_default_library_protos",
|
||||
srcs = ["generated.proto"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
133
vendor/k8s.io/apimachinery/pkg/api/resource/amount_test.go
generated
vendored
133
vendor/k8s.io/apimachinery/pkg/api/resource/amount_test.go
generated
vendored
|
|
@ -1,133 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 resource
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInt64AmountAsInt64(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
value int64
|
||||
scale Scale
|
||||
result int64
|
||||
ok bool
|
||||
}{
|
||||
{100, 0, 100, true},
|
||||
{100, 1, 1000, true},
|
||||
{100, -5, 0, false},
|
||||
{100, 100, 0, false},
|
||||
} {
|
||||
r, ok := int64Amount{value: test.value, scale: test.scale}.AsInt64()
|
||||
if r != test.result {
|
||||
t.Errorf("%v: unexpected result: %d", test, r)
|
||||
}
|
||||
if ok != test.ok {
|
||||
t.Errorf("%v: unexpected ok: %t", test, ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInt64AmountAdd(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
a, b, c int64Amount
|
||||
ok bool
|
||||
}{
|
||||
{int64Amount{value: 100, scale: 1}, int64Amount{value: 10, scale: 2}, int64Amount{value: 200, scale: 1}, true},
|
||||
{int64Amount{value: 100, scale: 1}, int64Amount{value: 1, scale: 2}, int64Amount{value: 110, scale: 1}, true},
|
||||
{int64Amount{value: 100, scale: 1}, int64Amount{value: 1, scale: 100}, int64Amount{value: 1, scale: 100}, false},
|
||||
{int64Amount{value: -5, scale: 2}, int64Amount{value: 50, scale: 1}, int64Amount{value: 0, scale: 1}, true},
|
||||
{int64Amount{value: -5, scale: 2}, int64Amount{value: 5, scale: 2}, int64Amount{value: 0, scale: 2}, true},
|
||||
|
||||
{int64Amount{value: mostPositive, scale: -1}, int64Amount{value: 1, scale: -1}, int64Amount{value: 0, scale: -1}, false},
|
||||
{int64Amount{value: mostPositive, scale: -1}, int64Amount{value: 0, scale: -1}, int64Amount{value: mostPositive, scale: -1}, true},
|
||||
{int64Amount{value: mostPositive / 10, scale: 1}, int64Amount{value: 10, scale: 0}, int64Amount{value: mostPositive, scale: -1}, false},
|
||||
} {
|
||||
c := test.a
|
||||
ok := c.Add(test.b)
|
||||
if ok != test.ok {
|
||||
t.Errorf("%v: unexpected ok: %t", test, ok)
|
||||
}
|
||||
if ok {
|
||||
if c != test.c {
|
||||
t.Errorf("%v: unexpected result: %d", test, c)
|
||||
}
|
||||
} else {
|
||||
if c != test.a {
|
||||
t.Errorf("%v: overflow addition mutated source: %d", test, c)
|
||||
}
|
||||
}
|
||||
|
||||
// addition is commutative
|
||||
c = test.b
|
||||
if ok := c.Add(test.a); ok != test.ok {
|
||||
t.Errorf("%v: unexpected ok: %t", test, ok)
|
||||
}
|
||||
if ok {
|
||||
if c != test.c {
|
||||
t.Errorf("%v: unexpected result: %d", test, c)
|
||||
}
|
||||
} else {
|
||||
if c != test.b {
|
||||
t.Errorf("%v: overflow addition mutated source: %d", test, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestInt64AsCanonicalString(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
value int64
|
||||
scale Scale
|
||||
result string
|
||||
exponent int32
|
||||
}{
|
||||
{100, 0, "100", 0},
|
||||
{100, 1, "1", 3},
|
||||
{100, -1, "10", 0},
|
||||
{10800, -10, "1080", -9},
|
||||
} {
|
||||
r, exp := int64Amount{value: test.value, scale: test.scale}.AsCanonicalBytes(nil)
|
||||
if string(r) != test.result {
|
||||
t.Errorf("%v: unexpected result: %s", test, r)
|
||||
}
|
||||
if exp != test.exponent {
|
||||
t.Errorf("%v: unexpected exponent: %d", test, exp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAmountSign(t *testing.T) {
|
||||
table := []struct {
|
||||
i int64Amount
|
||||
expect int
|
||||
}{
|
||||
{int64Amount{value: -50, scale: 1}, -1},
|
||||
{int64Amount{value: 0, scale: 1}, 0},
|
||||
{int64Amount{value: 300, scale: 1}, 1},
|
||||
{int64Amount{value: -50, scale: -8}, -1},
|
||||
{int64Amount{value: 50, scale: -8}, 1},
|
||||
{int64Amount{value: 0, scale: -8}, 0},
|
||||
{int64Amount{value: -50, scale: 0}, -1},
|
||||
{int64Amount{value: 50, scale: 0}, 1},
|
||||
{int64Amount{value: 0, scale: 0}, 0},
|
||||
}
|
||||
for _, testCase := range table {
|
||||
if result := testCase.i.Sign(); result != testCase.expect {
|
||||
t.Errorf("i: %v, Expected: %v, Actual: %v", testCase.i, testCase.expect, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
211
vendor/k8s.io/apimachinery/pkg/api/resource/math_test.go
generated
vendored
211
vendor/k8s.io/apimachinery/pkg/api/resource/math_test.go
generated
vendored
|
|
@ -1,211 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 resource
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDetectOverflowAdd(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
a, b int64
|
||||
c int64
|
||||
ok bool
|
||||
}{
|
||||
{0, 0, 0, true},
|
||||
{-1, 1, 0, true},
|
||||
{0, 1, 1, true},
|
||||
{2, 2, 4, true},
|
||||
{2, -2, 0, true},
|
||||
{-2, -2, -4, true},
|
||||
|
||||
{mostNegative, -1, 0, false},
|
||||
{mostNegative, 1, mostNegative + 1, true},
|
||||
{mostPositive, -1, mostPositive - 1, true},
|
||||
{mostPositive, 1, 0, false},
|
||||
|
||||
{mostNegative, mostPositive, -1, true},
|
||||
{mostPositive, mostNegative, -1, true},
|
||||
{mostPositive, mostPositive, 0, false},
|
||||
{mostNegative, mostNegative, 0, false},
|
||||
|
||||
{-mostPositive, mostNegative, 0, false},
|
||||
{mostNegative, -mostPositive, 0, false},
|
||||
{-mostPositive, -mostPositive, 0, false},
|
||||
} {
|
||||
c, ok := int64Add(test.a, test.b)
|
||||
if c != test.c {
|
||||
t.Errorf("%v: unexpected result: %d", test, c)
|
||||
}
|
||||
if ok != test.ok {
|
||||
t.Errorf("%v: unexpected overflow: %t", test, ok)
|
||||
}
|
||||
// addition is commutative
|
||||
d, ok2 := int64Add(test.b, test.a)
|
||||
if c != d || ok != ok2 {
|
||||
t.Errorf("%v: not commutative: %d %t", test, d, ok2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectOverflowMultiply(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
a, b int64
|
||||
c int64
|
||||
ok bool
|
||||
}{
|
||||
{0, 0, 0, true},
|
||||
{-1, 1, -1, true},
|
||||
{-1, -1, 1, true},
|
||||
{1, 1, 1, true},
|
||||
{0, 1, 0, true},
|
||||
{1, 0, 0, true},
|
||||
{2, 2, 4, true},
|
||||
{2, -2, -4, true},
|
||||
{-2, -2, 4, true},
|
||||
|
||||
{mostNegative, -1, 0, false},
|
||||
{mostNegative, 1, mostNegative, true},
|
||||
{mostPositive, -1, -mostPositive, true},
|
||||
{mostPositive, 1, mostPositive, true},
|
||||
|
||||
{mostNegative, mostPositive, 0, false},
|
||||
{mostPositive, mostNegative, 0, false},
|
||||
{mostPositive, mostPositive, 1, false},
|
||||
{mostNegative, mostNegative, 0, false},
|
||||
|
||||
{-mostPositive, mostNegative, 0, false},
|
||||
{mostNegative, -mostPositive, 0, false},
|
||||
{-mostPositive, -mostPositive, 1, false},
|
||||
} {
|
||||
c, ok := int64Multiply(test.a, test.b)
|
||||
if c != test.c {
|
||||
t.Errorf("%v: unexpected result: %d", test, c)
|
||||
}
|
||||
if ok != test.ok {
|
||||
t.Errorf("%v: unexpected overflow: %t", test, ok)
|
||||
}
|
||||
// multiplication is commutative
|
||||
d, ok2 := int64Multiply(test.b, test.a)
|
||||
if c != d || ok != ok2 {
|
||||
t.Errorf("%v: not commutative: %d %t", test, d, ok2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectOverflowScale(t *testing.T) {
|
||||
for _, a := range []int64{0, -1, 1, 10, -10, mostPositive, mostNegative, -mostPositive} {
|
||||
for _, b := range []int64{1, 2, 10, 100, 1000, mostPositive} {
|
||||
expect, expectOk := int64Multiply(a, b)
|
||||
|
||||
c, ok := int64MultiplyScale(a, b)
|
||||
if c != expect {
|
||||
t.Errorf("%d*%d: unexpected result: %d", a, b, c)
|
||||
}
|
||||
if ok != expectOk {
|
||||
t.Errorf("%d*%d: unexpected overflow: %t", a, b, ok)
|
||||
}
|
||||
}
|
||||
for _, test := range []struct {
|
||||
base int64
|
||||
fn func(a int64) (int64, bool)
|
||||
}{
|
||||
{10, int64MultiplyScale10},
|
||||
{100, int64MultiplyScale100},
|
||||
{1000, int64MultiplyScale1000},
|
||||
} {
|
||||
expect, expectOk := int64Multiply(a, test.base)
|
||||
c, ok := test.fn(a)
|
||||
if c != expect {
|
||||
t.Errorf("%d*%d: unexpected result: %d", a, test.base, c)
|
||||
}
|
||||
if ok != expectOk {
|
||||
t.Errorf("%d*%d: unexpected overflow: %t", a, test.base, ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveInt64Factors(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
value int64
|
||||
max int64
|
||||
result int64
|
||||
scale int32
|
||||
}{
|
||||
{100, 10, 1, 2},
|
||||
{100, 10, 1, 2},
|
||||
{100, 100, 1, 1},
|
||||
{1, 10, 1, 0},
|
||||
} {
|
||||
r, s := removeInt64Factors(test.value, test.max)
|
||||
if r != test.result {
|
||||
t.Errorf("%v: unexpected result: %d", test, r)
|
||||
}
|
||||
if s != test.scale {
|
||||
t.Errorf("%v: unexpected scale: %d", test, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNegativeScaleInt64(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
base int64
|
||||
scale Scale
|
||||
result int64
|
||||
exact bool
|
||||
}{
|
||||
{1234567, 0, 1234567, true},
|
||||
{1234567, 1, 123457, false},
|
||||
{1234567, 2, 12346, false},
|
||||
{1234567, 3, 1235, false},
|
||||
{1234567, 4, 124, false},
|
||||
|
||||
{-1234567, 0, -1234567, true},
|
||||
{-1234567, 1, -123457, false},
|
||||
{-1234567, 2, -12346, false},
|
||||
{-1234567, 3, -1235, false},
|
||||
{-1234567, 4, -124, false},
|
||||
|
||||
{1000, 0, 1000, true},
|
||||
{1000, 1, 100, true},
|
||||
{1000, 2, 10, true},
|
||||
{1000, 3, 1, true},
|
||||
{1000, 4, 1, false},
|
||||
|
||||
{-1000, 0, -1000, true},
|
||||
{-1000, 1, -100, true},
|
||||
{-1000, 2, -10, true},
|
||||
{-1000, 3, -1, true},
|
||||
{-1000, 4, -1, false},
|
||||
|
||||
{0, 0, 0, true},
|
||||
{0, 1, 0, true},
|
||||
{0, 2, 0, true},
|
||||
|
||||
// negative scale is undefined behavior
|
||||
{1000, -1, 1000, true},
|
||||
} {
|
||||
result, exact := negativeScaleInt64(test.base, test.scale)
|
||||
if result != test.result {
|
||||
t.Errorf("%v: unexpected result: %d", test, result)
|
||||
}
|
||||
if exact != test.exact {
|
||||
t.Errorf("%v: unexpected exact: %t", test, exact)
|
||||
}
|
||||
}
|
||||
}
|
||||
59
vendor/k8s.io/apimachinery/pkg/api/resource/quantity_example_test.go
generated
vendored
59
vendor/k8s.io/apimachinery/pkg/api/resource/quantity_example_test.go
generated
vendored
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 resource_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
)
|
||||
|
||||
func ExampleFormat() {
|
||||
memorySize := resource.NewQuantity(5*1024*1024*1024, resource.BinarySI)
|
||||
fmt.Printf("memorySize = %v\n", memorySize)
|
||||
|
||||
diskSize := resource.NewQuantity(5*1000*1000*1000, resource.DecimalSI)
|
||||
fmt.Printf("diskSize = %v\n", diskSize)
|
||||
|
||||
cores := resource.NewMilliQuantity(5300, resource.DecimalSI)
|
||||
fmt.Printf("cores = %v\n", cores)
|
||||
|
||||
// Output:
|
||||
// memorySize = 5Gi
|
||||
// diskSize = 5G
|
||||
// cores = 5300m
|
||||
}
|
||||
|
||||
func ExampleMustParse() {
|
||||
memorySize := resource.MustParse("5Gi")
|
||||
fmt.Printf("memorySize = %v (%v)\n", memorySize.Value(), memorySize.Format)
|
||||
|
||||
diskSize := resource.MustParse("5G")
|
||||
fmt.Printf("diskSize = %v (%v)\n", diskSize.Value(), diskSize.Format)
|
||||
|
||||
cores := resource.MustParse("5300m")
|
||||
fmt.Printf("milliCores = %v (%v)\n", cores.MilliValue(), cores.Format)
|
||||
|
||||
cores2 := resource.MustParse("5.4")
|
||||
fmt.Printf("milliCores = %v (%v)\n", cores2.MilliValue(), cores2.Format)
|
||||
|
||||
// Output:
|
||||
// memorySize = 5368709120 (BinarySI)
|
||||
// diskSize = 5000000000 (DecimalSI)
|
||||
// milliCores = 5300 (DecimalSI)
|
||||
// milliCores = 5400 (DecimalSI)
|
||||
}
|
||||
103
vendor/k8s.io/apimachinery/pkg/api/resource/quantity_proto_test.go
generated
vendored
103
vendor/k8s.io/apimachinery/pkg/api/resource/quantity_proto_test.go
generated
vendored
|
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
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 resource
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
inf "gopkg.in/inf.v0"
|
||||
)
|
||||
|
||||
func TestQuantityProtoMarshal(t *testing.T) {
|
||||
// Test when d is nil
|
||||
table := []struct {
|
||||
quantity string
|
||||
expect Quantity
|
||||
}{
|
||||
{"0", Quantity{i: int64Amount{value: 0, scale: 0}, s: "0", Format: DecimalSI}},
|
||||
{"100m", Quantity{i: int64Amount{value: 100, scale: -3}, s: "100m", Format: DecimalSI}},
|
||||
{"50m", Quantity{i: int64Amount{value: 50, scale: -3}, s: "50m", Format: DecimalSI}},
|
||||
{"10000T", Quantity{i: int64Amount{value: 10000, scale: 12}, s: "10000T", Format: DecimalSI}},
|
||||
}
|
||||
for _, testCase := range table {
|
||||
q := MustParse(testCase.quantity)
|
||||
// Won't currently get an error as MarshalTo can't return one
|
||||
result, _ := q.Marshal()
|
||||
q.MarshalTo(result)
|
||||
if q.Cmp(testCase.expect) != 0 {
|
||||
t.Errorf("Expected: %v, Actual: %v", testCase.expect, q)
|
||||
}
|
||||
}
|
||||
// Test when i is {0,0}
|
||||
table2 := []struct {
|
||||
dec *inf.Dec
|
||||
expect Quantity
|
||||
}{
|
||||
{dec(0, 0).Dec, Quantity{i: int64Amount{value: 0, scale: 0}, d: infDecAmount{dec(0, 0).Dec}, s: "0", Format: DecimalSI}},
|
||||
{dec(10, 0).Dec, Quantity{i: int64Amount{value: 0, scale: 0}, d: infDecAmount{dec(10, 0).Dec}, s: "10", Format: DecimalSI}},
|
||||
{dec(-10, 0).Dec, Quantity{i: int64Amount{value: 0, scale: 0}, d: infDecAmount{dec(-10, 0).Dec}, s: "-10", Format: DecimalSI}},
|
||||
}
|
||||
for _, testCase := range table2 {
|
||||
q := Quantity{d: infDecAmount{testCase.dec}, Format: DecimalSI}
|
||||
// Won't currently get an error as MarshalTo can't return one
|
||||
result, _ := q.Marshal()
|
||||
q.Unmarshal(result)
|
||||
if q.Cmp(testCase.expect) != 0 {
|
||||
t.Errorf("Expected: %v, Actual: %v", testCase.expect, q)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestQuantityProtoUnmarshal(t *testing.T) {
|
||||
// Test when d is nil
|
||||
table := []struct {
|
||||
input Quantity
|
||||
expect string
|
||||
}{
|
||||
{Quantity{i: int64Amount{value: 0, scale: 0}, s: "0", Format: DecimalSI}, "0"},
|
||||
{Quantity{i: int64Amount{value: 100, scale: -3}, s: "100m", Format: DecimalSI}, "100m"},
|
||||
{Quantity{i: int64Amount{value: 50, scale: -3}, s: "50m", Format: DecimalSI}, "50m"},
|
||||
{Quantity{i: int64Amount{value: 10000, scale: 12}, s: "10000T", Format: DecimalSI}, "10000T"},
|
||||
}
|
||||
for _, testCase := range table {
|
||||
var inputQ Quantity
|
||||
expectQ := MustParse(testCase.expect)
|
||||
inputByteArray, _ := testCase.input.Marshal()
|
||||
inputQ.Unmarshal(inputByteArray)
|
||||
if inputQ.Cmp(expectQ) != 0 {
|
||||
t.Errorf("Expected: %v, Actual: %v", inputQ, expectQ)
|
||||
}
|
||||
}
|
||||
// Test when i is {0,0}
|
||||
table2 := []struct {
|
||||
input Quantity
|
||||
expect *inf.Dec
|
||||
}{
|
||||
{Quantity{i: int64Amount{value: 0, scale: 0}, d: infDecAmount{dec(0, 0).Dec}, s: "0", Format: DecimalSI}, dec(0, 0).Dec},
|
||||
{Quantity{i: int64Amount{value: 0, scale: 0}, d: infDecAmount{dec(10, 0).Dec}, s: "10", Format: DecimalSI}, dec(10, 0).Dec},
|
||||
{Quantity{i: int64Amount{value: 0, scale: 0}, d: infDecAmount{dec(-10, 0).Dec}, s: "-10", Format: DecimalSI}, dec(-10, 0).Dec},
|
||||
}
|
||||
for _, testCase := range table2 {
|
||||
var inputQ Quantity
|
||||
expectQ := Quantity{d: infDecAmount{testCase.expect}, Format: DecimalSI}
|
||||
inputByteArray, _ := testCase.input.Marshal()
|
||||
inputQ.Unmarshal(inputByteArray)
|
||||
if inputQ.Cmp(expectQ) != 0 {
|
||||
t.Errorf("Expected: %v, Actual: %v", inputQ, expectQ)
|
||||
}
|
||||
}
|
||||
}
|
||||
1368
vendor/k8s.io/apimachinery/pkg/api/resource/quantity_test.go
generated
vendored
1368
vendor/k8s.io/apimachinery/pkg/api/resource/quantity_test.go
generated
vendored
File diff suppressed because it is too large
Load diff
85
vendor/k8s.io/apimachinery/pkg/api/resource/scale_int_test.go
generated
vendored
85
vendor/k8s.io/apimachinery/pkg/api/resource/scale_int_test.go
generated
vendored
|
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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 resource
|
||||
|
||||
import (
|
||||
"math"
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestScaledValueInternal(t *testing.T) {
|
||||
tests := []struct {
|
||||
unscaled *big.Int
|
||||
scale int
|
||||
newScale int
|
||||
|
||||
want int64
|
||||
}{
|
||||
// remain scale
|
||||
{big.NewInt(1000), 0, 0, 1000},
|
||||
|
||||
// scale down
|
||||
{big.NewInt(1000), 0, -3, 1},
|
||||
{big.NewInt(1000), 3, 0, 1},
|
||||
{big.NewInt(0), 3, 0, 0},
|
||||
|
||||
// always round up
|
||||
{big.NewInt(999), 3, 0, 1},
|
||||
{big.NewInt(500), 3, 0, 1},
|
||||
{big.NewInt(499), 3, 0, 1},
|
||||
{big.NewInt(1), 3, 0, 1},
|
||||
// large scaled value does not lose precision
|
||||
{big.NewInt(0).Sub(maxInt64, bigOne), 1, 0, (math.MaxInt64-1)/10 + 1},
|
||||
// large intermediate result.
|
||||
{big.NewInt(1).Exp(big.NewInt(10), big.NewInt(100), nil), 100, 0, 1},
|
||||
|
||||
// scale up
|
||||
{big.NewInt(0), 0, 3, 0},
|
||||
{big.NewInt(1), 0, 3, 1000},
|
||||
{big.NewInt(1), -3, 0, 1000},
|
||||
{big.NewInt(1000), -3, 2, 100000000},
|
||||
{big.NewInt(0).Div(big.NewInt(math.MaxInt64), bigThousand), 0, 3,
|
||||
(math.MaxInt64 / 1000) * 1000},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
old := (&big.Int{}).Set(tt.unscaled)
|
||||
got := scaledValue(tt.unscaled, tt.scale, tt.newScale)
|
||||
if got != tt.want {
|
||||
t.Errorf("#%d: got = %v, want %v", i, got, tt.want)
|
||||
}
|
||||
if tt.unscaled.Cmp(old) != 0 {
|
||||
t.Errorf("#%d: unscaled = %v, want %v", i, tt.unscaled, old)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkScaledValueSmall(b *testing.B) {
|
||||
s := big.NewInt(1000)
|
||||
for i := 0; i < b.N; i++ {
|
||||
scaledValue(s, 3, 0)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkScaledValueLarge(b *testing.B) {
|
||||
s := big.NewInt(math.MaxInt64)
|
||||
s.Mul(s, big.NewInt(1000))
|
||||
for i := 0; i < b.N; i++ {
|
||||
scaledValue(s, 10, 0)
|
||||
}
|
||||
}
|
||||
53
vendor/k8s.io/apimachinery/pkg/api/validation/BUILD
generated
vendored
53
vendor/k8s.io/apimachinery/pkg/api/validation/BUILD
generated
vendored
|
|
@ -1,53 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["objectmeta_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"generic.go",
|
||||
"objectmeta.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/api/validation",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/validation/path:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
500
vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta_test.go
generated
vendored
500
vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta_test.go
generated
vendored
|
|
@ -1,500 +0,0 @@
|
|||
/*
|
||||
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 validation
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
const (
|
||||
maxLengthErrMsg = "must be no more than"
|
||||
namePartErrMsg = "name part must consist of"
|
||||
nameErrMsg = "a qualified name must consist of"
|
||||
)
|
||||
|
||||
// Ensure custom name functions are allowed
|
||||
func TestValidateObjectMetaCustomName(t *testing.T) {
|
||||
errs := ValidateObjectMeta(
|
||||
&metav1.ObjectMeta{Name: "test", GenerateName: "foo"},
|
||||
false,
|
||||
func(s string, prefix bool) []string {
|
||||
if s == "test" {
|
||||
return nil
|
||||
}
|
||||
return []string{"name-gen"}
|
||||
},
|
||||
field.NewPath("field"))
|
||||
if len(errs) != 1 {
|
||||
t.Fatalf("unexpected errors: %v", errs)
|
||||
}
|
||||
if !strings.Contains(errs[0].Error(), "name-gen") {
|
||||
t.Errorf("unexpected error message: %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure namespace names follow dns label format
|
||||
func TestValidateObjectMetaNamespaces(t *testing.T) {
|
||||
errs := ValidateObjectMeta(
|
||||
&metav1.ObjectMeta{Name: "test", Namespace: "foo.bar"},
|
||||
true,
|
||||
func(s string, prefix bool) []string {
|
||||
return nil
|
||||
},
|
||||
field.NewPath("field"))
|
||||
if len(errs) != 1 {
|
||||
t.Fatalf("unexpected errors: %v", errs)
|
||||
}
|
||||
if !strings.Contains(errs[0].Error(), `Invalid value: "foo.bar"`) {
|
||||
t.Errorf("unexpected error message: %v", errs)
|
||||
}
|
||||
maxLength := 63
|
||||
letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||
b := make([]rune, maxLength+1)
|
||||
for i := range b {
|
||||
b[i] = letters[rand.Intn(len(letters))]
|
||||
}
|
||||
errs = ValidateObjectMeta(
|
||||
&metav1.ObjectMeta{Name: "test", Namespace: string(b)},
|
||||
true,
|
||||
func(s string, prefix bool) []string {
|
||||
return nil
|
||||
},
|
||||
field.NewPath("field"))
|
||||
if len(errs) != 2 {
|
||||
t.Fatalf("unexpected errors: %v", errs)
|
||||
}
|
||||
if !strings.Contains(errs[0].Error(), "Invalid value") || !strings.Contains(errs[1].Error(), "Invalid value") {
|
||||
t.Errorf("unexpected error message: %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateObjectMetaOwnerReferences(t *testing.T) {
|
||||
trueVar := true
|
||||
falseVar := false
|
||||
testCases := []struct {
|
||||
description string
|
||||
ownerReferences []metav1.OwnerReference
|
||||
expectError bool
|
||||
expectedErrorMessage string
|
||||
}{
|
||||
{
|
||||
description: "simple success - third party extension.",
|
||||
ownerReferences: []metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: "customresourceVersion",
|
||||
Kind: "customresourceKind",
|
||||
Name: "name",
|
||||
UID: "1",
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
expectedErrorMessage: "",
|
||||
},
|
||||
{
|
||||
description: "simple failures - event shouldn't be set as an owner",
|
||||
ownerReferences: []metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: "v1",
|
||||
Kind: "Event",
|
||||
Name: "name",
|
||||
UID: "1",
|
||||
},
|
||||
},
|
||||
expectError: true,
|
||||
expectedErrorMessage: "is disallowed from being an owner",
|
||||
},
|
||||
{
|
||||
description: "simple controller ref success - one reference with Controller set",
|
||||
ownerReferences: []metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: "customresourceVersion",
|
||||
Kind: "customresourceKind",
|
||||
Name: "name",
|
||||
UID: "1",
|
||||
Controller: &falseVar,
|
||||
},
|
||||
{
|
||||
APIVersion: "customresourceVersion",
|
||||
Kind: "customresourceKind",
|
||||
Name: "name",
|
||||
UID: "2",
|
||||
Controller: &trueVar,
|
||||
},
|
||||
{
|
||||
APIVersion: "customresourceVersion",
|
||||
Kind: "customresourceKind",
|
||||
Name: "name",
|
||||
UID: "3",
|
||||
Controller: &falseVar,
|
||||
},
|
||||
{
|
||||
APIVersion: "customresourceVersion",
|
||||
Kind: "customresourceKind",
|
||||
Name: "name",
|
||||
UID: "4",
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
expectedErrorMessage: "",
|
||||
},
|
||||
{
|
||||
description: "simple controller ref failure - two references with Controller set",
|
||||
ownerReferences: []metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: "customresourceVersion",
|
||||
Kind: "customresourceKind",
|
||||
Name: "name",
|
||||
UID: "1",
|
||||
Controller: &falseVar,
|
||||
},
|
||||
{
|
||||
APIVersion: "customresourceVersion",
|
||||
Kind: "customresourceKind",
|
||||
Name: "name",
|
||||
UID: "2",
|
||||
Controller: &trueVar,
|
||||
},
|
||||
{
|
||||
APIVersion: "customresourceVersion",
|
||||
Kind: "customresourceKind",
|
||||
Name: "name",
|
||||
UID: "3",
|
||||
Controller: &trueVar,
|
||||
},
|
||||
{
|
||||
APIVersion: "customresourceVersion",
|
||||
Kind: "customresourceKind",
|
||||
Name: "name",
|
||||
UID: "4",
|
||||
},
|
||||
},
|
||||
expectError: true,
|
||||
expectedErrorMessage: "Only one reference can have Controller set to true",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
errs := ValidateObjectMeta(
|
||||
&metav1.ObjectMeta{Name: "test", Namespace: "test", OwnerReferences: tc.ownerReferences},
|
||||
true,
|
||||
func(s string, prefix bool) []string {
|
||||
return nil
|
||||
},
|
||||
field.NewPath("field"))
|
||||
if len(errs) != 0 && !tc.expectError {
|
||||
t.Errorf("unexpected error: %v in test case %v", errs, tc.description)
|
||||
}
|
||||
if len(errs) == 0 && tc.expectError {
|
||||
t.Errorf("expect error in test case %v", tc.description)
|
||||
}
|
||||
if len(errs) != 0 && !strings.Contains(errs[0].Error(), tc.expectedErrorMessage) {
|
||||
t.Errorf("unexpected error message: %v in test case %v", errs, tc.description)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateObjectMetaUpdateIgnoresCreationTimestamp(t *testing.T) {
|
||||
if errs := ValidateObjectMetaUpdate(
|
||||
&metav1.ObjectMeta{Name: "test", ResourceVersion: "1"},
|
||||
&metav1.ObjectMeta{Name: "test", ResourceVersion: "1", CreationTimestamp: metav1.NewTime(time.Unix(10, 0))},
|
||||
field.NewPath("field"),
|
||||
); len(errs) != 0 {
|
||||
t.Fatalf("unexpected errors: %v", errs)
|
||||
}
|
||||
if errs := ValidateObjectMetaUpdate(
|
||||
&metav1.ObjectMeta{Name: "test", ResourceVersion: "1", CreationTimestamp: metav1.NewTime(time.Unix(10, 0))},
|
||||
&metav1.ObjectMeta{Name: "test", ResourceVersion: "1"},
|
||||
field.NewPath("field"),
|
||||
); len(errs) != 0 {
|
||||
t.Fatalf("unexpected errors: %v", errs)
|
||||
}
|
||||
if errs := ValidateObjectMetaUpdate(
|
||||
&metav1.ObjectMeta{Name: "test", ResourceVersion: "1", CreationTimestamp: metav1.NewTime(time.Unix(10, 0))},
|
||||
&metav1.ObjectMeta{Name: "test", ResourceVersion: "1", CreationTimestamp: metav1.NewTime(time.Unix(11, 0))},
|
||||
field.NewPath("field"),
|
||||
); len(errs) != 0 {
|
||||
t.Fatalf("unexpected errors: %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateFinalizersUpdate(t *testing.T) {
|
||||
testcases := map[string]struct {
|
||||
Old metav1.ObjectMeta
|
||||
New metav1.ObjectMeta
|
||||
ExpectedErr string
|
||||
}{
|
||||
"invalid adding finalizers": {
|
||||
Old: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &metav1.Time{}, Finalizers: []string{"x/a"}},
|
||||
New: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &metav1.Time{}, Finalizers: []string{"x/a", "y/b"}},
|
||||
ExpectedErr: "y/b",
|
||||
},
|
||||
"invalid changing finalizers": {
|
||||
Old: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &metav1.Time{}, Finalizers: []string{"x/a"}},
|
||||
New: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &metav1.Time{}, Finalizers: []string{"x/b"}},
|
||||
ExpectedErr: "x/b",
|
||||
},
|
||||
"valid removing finalizers": {
|
||||
Old: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &metav1.Time{}, Finalizers: []string{"x/a", "y/b"}},
|
||||
New: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &metav1.Time{}, Finalizers: []string{"x/a"}},
|
||||
ExpectedErr: "",
|
||||
},
|
||||
"valid adding finalizers for objects not being deleted": {
|
||||
Old: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", Finalizers: []string{"x/a"}},
|
||||
New: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", Finalizers: []string{"x/a", "y/b"}},
|
||||
ExpectedErr: "",
|
||||
},
|
||||
}
|
||||
for name, tc := range testcases {
|
||||
errs := ValidateObjectMetaUpdate(&tc.New, &tc.Old, field.NewPath("field"))
|
||||
if len(errs) == 0 {
|
||||
if len(tc.ExpectedErr) != 0 {
|
||||
t.Errorf("case: %q, expected error to contain %q", name, tc.ExpectedErr)
|
||||
}
|
||||
} else if e, a := tc.ExpectedErr, errs.ToAggregate().Error(); !strings.Contains(a, e) {
|
||||
t.Errorf("case: %q, expected error to contain %q, got error %q", name, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateFinalizersPreventConflictingFinalizers(t *testing.T) {
|
||||
testcases := map[string]struct {
|
||||
ObjectMeta metav1.ObjectMeta
|
||||
ExpectedErr string
|
||||
}{
|
||||
"conflicting finalizers": {
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", Finalizers: []string{metav1.FinalizerOrphanDependents, metav1.FinalizerDeleteDependents}},
|
||||
ExpectedErr: "cannot be both set",
|
||||
},
|
||||
}
|
||||
for name, tc := range testcases {
|
||||
errs := ValidateObjectMeta(&tc.ObjectMeta, false, NameIsDNSSubdomain, field.NewPath("field"))
|
||||
if len(errs) == 0 {
|
||||
if len(tc.ExpectedErr) != 0 {
|
||||
t.Errorf("case: %q, expected error to contain %q", name, tc.ExpectedErr)
|
||||
}
|
||||
} else if e, a := tc.ExpectedErr, errs.ToAggregate().Error(); !strings.Contains(a, e) {
|
||||
t.Errorf("case: %q, expected error to contain %q, got error %q", name, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateObjectMetaUpdatePreventsDeletionFieldMutation(t *testing.T) {
|
||||
now := metav1.NewTime(time.Unix(1000, 0).UTC())
|
||||
later := metav1.NewTime(time.Unix(2000, 0).UTC())
|
||||
gracePeriodShort := int64(30)
|
||||
gracePeriodLong := int64(40)
|
||||
|
||||
testcases := map[string]struct {
|
||||
Old metav1.ObjectMeta
|
||||
New metav1.ObjectMeta
|
||||
ExpectedNew metav1.ObjectMeta
|
||||
ExpectedErrs []string
|
||||
}{
|
||||
"valid without deletion fields": {
|
||||
Old: metav1.ObjectMeta{Name: "test", ResourceVersion: "1"},
|
||||
New: metav1.ObjectMeta{Name: "test", ResourceVersion: "1"},
|
||||
ExpectedNew: metav1.ObjectMeta{Name: "test", ResourceVersion: "1"},
|
||||
ExpectedErrs: []string{},
|
||||
},
|
||||
"valid with deletion fields": {
|
||||
Old: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &now, DeletionGracePeriodSeconds: &gracePeriodShort},
|
||||
New: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &now, DeletionGracePeriodSeconds: &gracePeriodShort},
|
||||
ExpectedNew: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &now, DeletionGracePeriodSeconds: &gracePeriodShort},
|
||||
ExpectedErrs: []string{},
|
||||
},
|
||||
|
||||
"invalid set deletionTimestamp": {
|
||||
Old: metav1.ObjectMeta{Name: "test", ResourceVersion: "1"},
|
||||
New: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &now},
|
||||
ExpectedNew: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &now},
|
||||
ExpectedErrs: []string{"field.deletionTimestamp: Invalid value: 1970-01-01 00:16:40 +0000 UTC: field is immutable; may only be changed via deletion"},
|
||||
},
|
||||
"invalid clear deletionTimestamp": {
|
||||
Old: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &now},
|
||||
New: metav1.ObjectMeta{Name: "test", ResourceVersion: "1"},
|
||||
ExpectedNew: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &now},
|
||||
ExpectedErrs: []string{}, // no errors, validation copies the old value
|
||||
},
|
||||
"invalid change deletionTimestamp": {
|
||||
Old: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &now},
|
||||
New: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &later},
|
||||
ExpectedNew: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionTimestamp: &now},
|
||||
ExpectedErrs: []string{}, // no errors, validation copies the old value
|
||||
},
|
||||
|
||||
"invalid set deletionGracePeriodSeconds": {
|
||||
Old: metav1.ObjectMeta{Name: "test", ResourceVersion: "1"},
|
||||
New: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionGracePeriodSeconds: &gracePeriodShort},
|
||||
ExpectedNew: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionGracePeriodSeconds: &gracePeriodShort},
|
||||
ExpectedErrs: []string{"field.deletionGracePeriodSeconds: Invalid value: 30: field is immutable; may only be changed via deletion"},
|
||||
},
|
||||
"invalid clear deletionGracePeriodSeconds": {
|
||||
Old: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionGracePeriodSeconds: &gracePeriodShort},
|
||||
New: metav1.ObjectMeta{Name: "test", ResourceVersion: "1"},
|
||||
ExpectedNew: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionGracePeriodSeconds: &gracePeriodShort},
|
||||
ExpectedErrs: []string{}, // no errors, validation copies the old value
|
||||
},
|
||||
"invalid change deletionGracePeriodSeconds": {
|
||||
Old: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionGracePeriodSeconds: &gracePeriodShort},
|
||||
New: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionGracePeriodSeconds: &gracePeriodLong},
|
||||
ExpectedNew: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", DeletionGracePeriodSeconds: &gracePeriodLong},
|
||||
ExpectedErrs: []string{"field.deletionGracePeriodSeconds: Invalid value: 40: field is immutable; may only be changed via deletion"},
|
||||
},
|
||||
}
|
||||
|
||||
for k, tc := range testcases {
|
||||
errs := ValidateObjectMetaUpdate(&tc.New, &tc.Old, field.NewPath("field"))
|
||||
if len(errs) != len(tc.ExpectedErrs) {
|
||||
t.Logf("%s: Expected: %#v", k, tc.ExpectedErrs)
|
||||
t.Logf("%s: Got: %#v", k, errs)
|
||||
t.Errorf("%s: expected %d errors, got %d", k, len(tc.ExpectedErrs), len(errs))
|
||||
continue
|
||||
}
|
||||
for i := range errs {
|
||||
if errs[i].Error() != tc.ExpectedErrs[i] {
|
||||
t.Errorf("%s: error #%d: expected %q, got %q", k, i, tc.ExpectedErrs[i], errs[i].Error())
|
||||
}
|
||||
}
|
||||
if !reflect.DeepEqual(tc.New, tc.ExpectedNew) {
|
||||
t.Errorf("%s: Expected after validation:\n%#v\ngot\n%#v", k, tc.ExpectedNew, tc.New)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestObjectMetaGenerationUpdate(t *testing.T) {
|
||||
testcases := map[string]struct {
|
||||
Old metav1.ObjectMeta
|
||||
New metav1.ObjectMeta
|
||||
ExpectedErrs []string
|
||||
}{
|
||||
"invalid generation change - decremented": {
|
||||
Old: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", Generation: 5},
|
||||
New: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", Generation: 4},
|
||||
ExpectedErrs: []string{"field.generation: Invalid value: 4: must not be decremented"},
|
||||
},
|
||||
"valid generation change - incremented by one": {
|
||||
Old: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", Generation: 1},
|
||||
New: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", Generation: 2},
|
||||
ExpectedErrs: []string{},
|
||||
},
|
||||
"valid generation field - not updated": {
|
||||
Old: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", Generation: 5},
|
||||
New: metav1.ObjectMeta{Name: "test", ResourceVersion: "1", Generation: 5},
|
||||
ExpectedErrs: []string{},
|
||||
},
|
||||
}
|
||||
|
||||
for k, tc := range testcases {
|
||||
errList := []string{}
|
||||
errs := ValidateObjectMetaUpdate(&tc.New, &tc.Old, field.NewPath("field"))
|
||||
if len(errs) != len(tc.ExpectedErrs) {
|
||||
t.Logf("%s: Expected: %#v", k, tc.ExpectedErrs)
|
||||
for _, err := range errs {
|
||||
errList = append(errList, err.Error())
|
||||
}
|
||||
t.Logf("%s: Got: %#v", k, errList)
|
||||
t.Errorf("%s: expected %d errors, got %d", k, len(tc.ExpectedErrs), len(errs))
|
||||
continue
|
||||
}
|
||||
for i := range errList {
|
||||
if errList[i] != tc.ExpectedErrs[i] {
|
||||
t.Errorf("%s: error #%d: expected %q, got %q", k, i, tc.ExpectedErrs[i], errList[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure trailing slash is allowed in generate name
|
||||
func TestValidateObjectMetaTrimsTrailingSlash(t *testing.T) {
|
||||
errs := ValidateObjectMeta(
|
||||
&metav1.ObjectMeta{Name: "test", GenerateName: "foo-"},
|
||||
false,
|
||||
NameIsDNSSubdomain,
|
||||
field.NewPath("field"))
|
||||
if len(errs) != 0 {
|
||||
t.Fatalf("unexpected errors: %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateAnnotations(t *testing.T) {
|
||||
successCases := []map[string]string{
|
||||
{"simple": "bar"},
|
||||
{"now-with-dashes": "bar"},
|
||||
{"1-starts-with-num": "bar"},
|
||||
{"1234": "bar"},
|
||||
{"simple/simple": "bar"},
|
||||
{"now-with-dashes/simple": "bar"},
|
||||
{"now-with-dashes/now-with-dashes": "bar"},
|
||||
{"now.with.dots/simple": "bar"},
|
||||
{"now-with.dashes-and.dots/simple": "bar"},
|
||||
{"1-num.2-num/3-num": "bar"},
|
||||
{"1234/5678": "bar"},
|
||||
{"1.2.3.4/5678": "bar"},
|
||||
{"UpperCase123": "bar"},
|
||||
{"a": strings.Repeat("b", totalAnnotationSizeLimitB-1)},
|
||||
{
|
||||
"a": strings.Repeat("b", totalAnnotationSizeLimitB/2-1),
|
||||
"c": strings.Repeat("d", totalAnnotationSizeLimitB/2-1),
|
||||
},
|
||||
}
|
||||
for i := range successCases {
|
||||
errs := ValidateAnnotations(successCases[i], field.NewPath("field"))
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("case[%d] expected success, got %#v", i, errs)
|
||||
}
|
||||
}
|
||||
|
||||
nameErrorCases := []struct {
|
||||
annotations map[string]string
|
||||
expect string
|
||||
}{
|
||||
{map[string]string{"nospecialchars^=@": "bar"}, namePartErrMsg},
|
||||
{map[string]string{"cantendwithadash-": "bar"}, namePartErrMsg},
|
||||
{map[string]string{"only/one/slash": "bar"}, nameErrMsg},
|
||||
{map[string]string{strings.Repeat("a", 254): "bar"}, maxLengthErrMsg},
|
||||
}
|
||||
for i := range nameErrorCases {
|
||||
errs := ValidateAnnotations(nameErrorCases[i].annotations, field.NewPath("field"))
|
||||
if len(errs) != 1 {
|
||||
t.Errorf("case[%d]: expected failure", i)
|
||||
} else {
|
||||
if !strings.Contains(errs[0].Detail, nameErrorCases[i].expect) {
|
||||
t.Errorf("case[%d]: error details do not include %q: %q", i, nameErrorCases[i].expect, errs[0].Detail)
|
||||
}
|
||||
}
|
||||
}
|
||||
totalSizeErrorCases := []map[string]string{
|
||||
{"a": strings.Repeat("b", totalAnnotationSizeLimitB)},
|
||||
{
|
||||
"a": strings.Repeat("b", totalAnnotationSizeLimitB/2),
|
||||
"c": strings.Repeat("d", totalAnnotationSizeLimitB/2),
|
||||
},
|
||||
}
|
||||
for i := range totalSizeErrorCases {
|
||||
errs := ValidateAnnotations(totalSizeErrorCases[i], field.NewPath("field"))
|
||||
if len(errs) != 1 {
|
||||
t.Errorf("case[%d] expected failure", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
45
vendor/k8s.io/apimachinery/pkg/apimachinery/BUILD
generated
vendored
45
vendor/k8s.io/apimachinery/pkg/apimachinery/BUILD
generated
vendored
|
|
@ -1,45 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["types_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = ["//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"types.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/apimachinery",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apimachinery/announced:all-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apimachinery/registered:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
45
vendor/k8s.io/apimachinery/pkg/apimachinery/announced/BUILD
generated
vendored
45
vendor/k8s.io/apimachinery/pkg/apimachinery/announced/BUILD
generated
vendored
|
|
@ -1,45 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["announced_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = ["//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"announced.go",
|
||||
"group_factory.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/apimachinery/announced",
|
||||
deps = [
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery/registered:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
64
vendor/k8s.io/apimachinery/pkg/apimachinery/announced/announced_test.go
generated
vendored
64
vendor/k8s.io/apimachinery/pkg/apimachinery/announced/announced_test.go
generated
vendored
|
|
@ -1,64 +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 announced
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
)
|
||||
|
||||
func TestFactoryRegistry(t *testing.T) {
|
||||
regA := make(APIGroupFactoryRegistry)
|
||||
regB := make(APIGroupFactoryRegistry)
|
||||
|
||||
if err := regA.AnnounceGroup(&GroupMetaFactoryArgs{
|
||||
GroupName: "foo",
|
||||
VersionPreferenceOrder: []string{"v2", "v1"},
|
||||
RootScopedKinds: sets.NewString("namespaces"),
|
||||
}); err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
if err := regA.AnnounceGroupVersion(&GroupVersionFactoryArgs{
|
||||
GroupName: "foo",
|
||||
VersionName: "v1",
|
||||
}); err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
if err := regA.AnnounceGroupVersion(&GroupVersionFactoryArgs{
|
||||
GroupName: "foo",
|
||||
VersionName: "v2",
|
||||
}); err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if err := regB.AnnouncePreconstructedFactory(NewGroupMetaFactory(
|
||||
&GroupMetaFactoryArgs{
|
||||
GroupName: "foo",
|
||||
VersionPreferenceOrder: []string{"v2", "v1"},
|
||||
RootScopedKinds: sets.NewString("namespaces"),
|
||||
},
|
||||
VersionToSchemeFunc{"v1": nil, "v2": nil},
|
||||
)); err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(regA, regB) {
|
||||
t.Errorf("Expected both ways of registering to be equivalent, but they were not.\n\n%#v\n\n%#v\n", regA, regB)
|
||||
}
|
||||
}
|
||||
43
vendor/k8s.io/apimachinery/pkg/apimachinery/registered/BUILD
generated
vendored
43
vendor/k8s.io/apimachinery/pkg/apimachinery/registered/BUILD
generated
vendored
|
|
@ -1,43 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["registered_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["registered.go"],
|
||||
importpath = "k8s.io/apimachinery/pkg/apimachinery/registered",
|
||||
deps = [
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
71
vendor/k8s.io/apimachinery/pkg/apimachinery/registered/registered_test.go
generated
vendored
71
vendor/k8s.io/apimachinery/pkg/apimachinery/registered/registered_test.go
generated
vendored
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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 registered
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apimachinery"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func TestAllPreferredGroupVersions(t *testing.T) {
|
||||
testCases := []struct {
|
||||
groupMetas []apimachinery.GroupMeta
|
||||
expect string
|
||||
}{
|
||||
{
|
||||
groupMetas: []apimachinery.GroupMeta{
|
||||
{
|
||||
GroupVersion: schema.GroupVersion{Group: "group1", Version: "v1"},
|
||||
},
|
||||
{
|
||||
GroupVersion: schema.GroupVersion{Group: "group2", Version: "v2"},
|
||||
},
|
||||
{
|
||||
GroupVersion: schema.GroupVersion{Group: "", Version: "v1"},
|
||||
},
|
||||
},
|
||||
expect: "group1/v1,group2/v2,v1",
|
||||
},
|
||||
{
|
||||
groupMetas: []apimachinery.GroupMeta{
|
||||
{
|
||||
GroupVersion: schema.GroupVersion{Group: "", Version: "v1"},
|
||||
},
|
||||
},
|
||||
expect: "v1",
|
||||
},
|
||||
{
|
||||
groupMetas: []apimachinery.GroupMeta{},
|
||||
expect: "",
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
m, err := NewAPIRegistrationManager("")
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected failure to make a manager: %v", err)
|
||||
}
|
||||
for _, groupMeta := range testCase.groupMetas {
|
||||
m.RegisterGroup(groupMeta)
|
||||
}
|
||||
output := m.AllPreferredGroupVersions()
|
||||
if testCase.expect != output {
|
||||
t.Errorf("Error. expect: %s, got: %s", testCase.expect, output)
|
||||
}
|
||||
}
|
||||
}
|
||||
43
vendor/k8s.io/apimachinery/pkg/apimachinery/types_test.go
generated
vendored
43
vendor/k8s.io/apimachinery/pkg/apimachinery/types_test.go
generated
vendored
|
|
@ -1,43 +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 apimachinery
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func TestAdd(t *testing.T) {
|
||||
gm := GroupMeta{
|
||||
GroupVersion: schema.GroupVersion{
|
||||
Group: "test",
|
||||
Version: "v1",
|
||||
},
|
||||
GroupVersions: []schema.GroupVersion{{Group: "test", Version: "v1"}},
|
||||
}
|
||||
|
||||
gm.AddVersionInterfaces(schema.GroupVersion{Group: "test", Version: "v1"}, nil)
|
||||
if e, a := 1, len(gm.InterfacesByVersion); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
// GroupVersions is unchanged
|
||||
if e, a := 1, len(gm.GroupVersions); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
59
vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/BUILD
generated
vendored
59
vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/BUILD
generated
vendored
|
|
@ -1,59 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"register_test.go",
|
||||
"roundtrip_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/testing/roundtrip:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/fuzzer:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"conversion.go",
|
||||
"doc.go",
|
||||
"register.go",
|
||||
"types.go",
|
||||
"zz_generated.conversion.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/apis/meta/internalversion",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/fields:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
89
vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/register_test.go
generated
vendored
89
vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/register_test.go
generated
vendored
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
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 internalversion
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
)
|
||||
|
||||
func TestListOptions(t *testing.T) {
|
||||
// verify round trip conversion
|
||||
ten := int64(10)
|
||||
in := &metav1.ListOptions{
|
||||
LabelSelector: "a=1",
|
||||
FieldSelector: "b=1",
|
||||
ResourceVersion: "10",
|
||||
TimeoutSeconds: &ten,
|
||||
Watch: true,
|
||||
}
|
||||
out := &ListOptions{}
|
||||
if err := scheme.Convert(in, out, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
actual := &metav1.ListOptions{}
|
||||
if err := scheme.Convert(out, actual, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(in, actual) {
|
||||
t.Errorf("unexpected: %s", diff.ObjectReflectDiff(in, actual))
|
||||
}
|
||||
|
||||
// verify failing conversion
|
||||
for i, failingObject := range []*metav1.ListOptions{
|
||||
{LabelSelector: "a!!!"},
|
||||
{FieldSelector: "a!!!"},
|
||||
} {
|
||||
out = &ListOptions{}
|
||||
if err := scheme.Convert(failingObject, out, nil); err == nil {
|
||||
t.Errorf("%d: unexpected conversion: %#v", i, out)
|
||||
}
|
||||
}
|
||||
|
||||
// verify kind registration
|
||||
if gvks, unversioned, err := scheme.ObjectKinds(in); err != nil || unversioned || gvks[0] != metav1.SchemeGroupVersion.WithKind("ListOptions") {
|
||||
t.Errorf("unexpected: %v %v %v", gvks[0], unversioned, err)
|
||||
}
|
||||
if gvks, unversioned, err := scheme.ObjectKinds(out); err != nil || unversioned || gvks[0] != SchemeGroupVersion.WithKind("ListOptions") {
|
||||
t.Errorf("unexpected: %v %v %v", gvks[0], unversioned, err)
|
||||
}
|
||||
|
||||
actual = &metav1.ListOptions{}
|
||||
if err := ParameterCodec.DecodeParameters(url.Values{"watch": []string{"1"}}, metav1.SchemeGroupVersion, actual); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !actual.Watch {
|
||||
t.Errorf("unexpected watch decode: %#v", actual)
|
||||
}
|
||||
|
||||
// check ParameterCodec
|
||||
query, err := ParameterCodec.EncodeParameters(in, metav1.SchemeGroupVersion)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
actual = &metav1.ListOptions{}
|
||||
if err := ParameterCodec.DecodeParameters(query, metav1.SchemeGroupVersion, actual); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(in, actual) {
|
||||
t.Errorf("unexpected: %s", diff.ObjectReflectDiff(in, actual))
|
||||
}
|
||||
}
|
||||
28
vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/roundtrip_test.go
generated
vendored
28
vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion/roundtrip_test.go
generated
vendored
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
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 internalversion
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/testing/roundtrip"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/fuzzer"
|
||||
)
|
||||
|
||||
func TestRoundTrip(t *testing.T) {
|
||||
roundtrip.RoundTripTestForScheme(t, scheme, fuzzer.Funcs)
|
||||
}
|
||||
101
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/BUILD
generated
vendored
101
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/BUILD
generated
vendored
|
|
@ -1,101 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"controller_ref_test.go",
|
||||
"duration_test.go",
|
||||
"group_version_test.go",
|
||||
"helpers_test.go",
|
||||
"labels_test.go",
|
||||
"micro_time_test.go",
|
||||
"time_test.go",
|
||||
"types_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||
"//vendor/github.com/json-iterator/go:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"controller_ref.go",
|
||||
"conversion.go",
|
||||
"doc.go",
|
||||
"duration.go",
|
||||
"generated.pb.go",
|
||||
"group_version.go",
|
||||
"helpers.go",
|
||||
"labels.go",
|
||||
"meta.go",
|
||||
"micro_time.go",
|
||||
"micro_time_proto.go",
|
||||
"register.go",
|
||||
"time.go",
|
||||
"time_proto.go",
|
||||
"types.go",
|
||||
"types_swagger_doc_generated.go",
|
||||
"watch.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
"zz_generated.defaults.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
deps = [
|
||||
"//vendor/github.com/gogo/protobuf/proto:go_default_library",
|
||||
"//vendor/github.com/gogo/protobuf/sortkeys:go_default_library",
|
||||
"//vendor/github.com/google/gofuzz:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/fields:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/selection:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:all-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/validation:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "go_default_library_protos",
|
||||
srcs = ["generated.proto"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_xtest",
|
||||
srcs = ["conversion_test.go"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
],
|
||||
)
|
||||
133
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/controller_ref_test.go
generated
vendored
133
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/controller_ref_test.go
generated
vendored
|
|
@ -1,133 +0,0 @@
|
|||
/*
|
||||
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 v1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
type metaObj struct {
|
||||
ObjectMeta
|
||||
TypeMeta
|
||||
}
|
||||
|
||||
func TestNewControllerRef(t *testing.T) {
|
||||
gvk := schema.GroupVersionKind{
|
||||
Group: "group",
|
||||
Version: "v1",
|
||||
Kind: "Kind",
|
||||
}
|
||||
obj1 := &metaObj{
|
||||
ObjectMeta: ObjectMeta{
|
||||
Name: "name",
|
||||
UID: "uid1",
|
||||
},
|
||||
}
|
||||
controllerRef := NewControllerRef(obj1, gvk)
|
||||
if controllerRef.UID != obj1.UID {
|
||||
t.Errorf("Incorrect UID: %s", controllerRef.UID)
|
||||
}
|
||||
if controllerRef.Controller == nil || *controllerRef.Controller != true {
|
||||
t.Error("Controller must be set to true")
|
||||
}
|
||||
if controllerRef.BlockOwnerDeletion == nil || *controllerRef.BlockOwnerDeletion != true {
|
||||
t.Error("BlockOwnerDeletion must be set to true")
|
||||
}
|
||||
if controllerRef.APIVersion == "" ||
|
||||
controllerRef.Kind == "" ||
|
||||
controllerRef.Name == "" {
|
||||
t.Errorf("All controllerRef fields must be set: %v", controllerRef)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetControllerOf(t *testing.T) {
|
||||
gvk := schema.GroupVersionKind{
|
||||
Group: "group",
|
||||
Version: "v1",
|
||||
Kind: "Kind",
|
||||
}
|
||||
obj1 := &metaObj{
|
||||
ObjectMeta: ObjectMeta{
|
||||
UID: "uid1",
|
||||
Name: "name1",
|
||||
},
|
||||
}
|
||||
controllerRef := NewControllerRef(obj1, gvk)
|
||||
var falseRef = false
|
||||
obj2 := &metaObj{
|
||||
ObjectMeta: ObjectMeta{
|
||||
UID: "uid2",
|
||||
Name: "name1",
|
||||
OwnerReferences: []OwnerReference{
|
||||
{
|
||||
Name: "owner1",
|
||||
Controller: &falseRef,
|
||||
},
|
||||
*controllerRef,
|
||||
{
|
||||
Name: "owner2",
|
||||
Controller: &falseRef,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if GetControllerOf(obj1) != nil {
|
||||
t.Error("GetControllerOf must return null")
|
||||
}
|
||||
c := GetControllerOf(obj2)
|
||||
if c.Name != controllerRef.Name || c.UID != controllerRef.UID {
|
||||
t.Errorf("Incorrect result of GetControllerOf: %v", c)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsControlledBy(t *testing.T) {
|
||||
gvk := schema.GroupVersionKind{
|
||||
Group: "group",
|
||||
Version: "v1",
|
||||
Kind: "Kind",
|
||||
}
|
||||
obj1 := &metaObj{
|
||||
ObjectMeta: ObjectMeta{
|
||||
UID: "uid1",
|
||||
},
|
||||
}
|
||||
obj2 := &metaObj{
|
||||
ObjectMeta: ObjectMeta{
|
||||
UID: "uid2",
|
||||
OwnerReferences: []OwnerReference{
|
||||
*NewControllerRef(obj1, gvk),
|
||||
},
|
||||
},
|
||||
}
|
||||
obj3 := &metaObj{
|
||||
ObjectMeta: ObjectMeta{
|
||||
UID: "uid3",
|
||||
OwnerReferences: []OwnerReference{
|
||||
*NewControllerRef(obj2, gvk),
|
||||
},
|
||||
},
|
||||
}
|
||||
if !IsControlledBy(obj2, obj1) || !IsControlledBy(obj3, obj2) {
|
||||
t.Error("Incorrect IsControlledBy result: false")
|
||||
}
|
||||
if IsControlledBy(obj3, obj1) {
|
||||
t.Error("Incorrect IsControlledBy result: true")
|
||||
}
|
||||
}
|
||||
49
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/conversion_test.go
generated
vendored
49
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/conversion_test.go
generated
vendored
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
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 v1_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestMapToLabelSelectorRoundTrip(t *testing.T) {
|
||||
// We should be able to round-trip a map-only selector through LabelSelector.
|
||||
inputs := []map[string]string{
|
||||
nil,
|
||||
{},
|
||||
{"one": "foo"},
|
||||
{"one": "foo", "two": "bar"},
|
||||
}
|
||||
for _, in := range inputs {
|
||||
ls := &v1.LabelSelector{}
|
||||
if err := v1.Convert_map_to_unversioned_LabelSelector(&in, ls, nil); err != nil {
|
||||
t.Errorf("Convert_map_to_unversioned_LabelSelector(%#v): %v", in, err)
|
||||
continue
|
||||
}
|
||||
out := map[string]string{}
|
||||
if err := v1.Convert_unversioned_LabelSelector_to_map(ls, &out, nil); err != nil {
|
||||
t.Errorf("Convert_unversioned_LabelSelector_to_map(%#v): %v", ls, err)
|
||||
continue
|
||||
}
|
||||
if !apiequality.Semantic.DeepEqual(in, out) {
|
||||
t.Errorf("map-selector conversion round-trip failed: got %v; want %v", out, in)
|
||||
}
|
||||
}
|
||||
}
|
||||
153
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/duration_test.go
generated
vendored
153
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/duration_test.go
generated
vendored
|
|
@ -1,153 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
)
|
||||
|
||||
type DurationHolder struct {
|
||||
D Duration `json:"d"`
|
||||
}
|
||||
|
||||
func TestDurationMarshalYAML(t *testing.T) {
|
||||
cases := []struct {
|
||||
input Duration
|
||||
result string
|
||||
}{
|
||||
{Duration{5 * time.Second}, "d: 5s\n"},
|
||||
{Duration{2 * time.Minute}, "d: 2m0s\n"},
|
||||
{Duration{time.Hour + 3*time.Millisecond}, "d: 1h0m0.003s\n"},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
input := DurationHolder{c.input}
|
||||
result, err := yaml.Marshal(&input)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to marshal input: %q: %v", input, err)
|
||||
}
|
||||
if string(result) != c.result {
|
||||
t.Errorf("Failed to marshal input: %q: expected %q, got %q", input, c.result, string(result))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDurationUnmarshalYAML(t *testing.T) {
|
||||
cases := []struct {
|
||||
input string
|
||||
result Duration
|
||||
}{
|
||||
{"d: 0s\n", Duration{}},
|
||||
{"d: 5s\n", Duration{5 * time.Second}},
|
||||
{"d: 2m0s\n", Duration{2 * time.Minute}},
|
||||
{"d: 1h0m0.003s\n", Duration{time.Hour + 3*time.Millisecond}},
|
||||
|
||||
// Units with zero values can optionally be dropped
|
||||
{"d: 2m\n", Duration{2 * time.Minute}},
|
||||
{"d: 1h0.003s\n", Duration{time.Hour + 3*time.Millisecond}},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
var result DurationHolder
|
||||
if err := yaml.Unmarshal([]byte(c.input), &result); err != nil {
|
||||
t.Errorf("Failed to unmarshal input %q: %v", c.input, err)
|
||||
}
|
||||
if result.D != c.result {
|
||||
t.Errorf("Failed to unmarshal input %q: expected %q, got %q", c.input, c.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDurationMarshalJSON(t *testing.T) {
|
||||
cases := []struct {
|
||||
input Duration
|
||||
result string
|
||||
}{
|
||||
{Duration{5 * time.Second}, `{"d":"5s"}`},
|
||||
{Duration{2 * time.Minute}, `{"d":"2m0s"}`},
|
||||
{Duration{time.Hour + 3*time.Millisecond}, `{"d":"1h0m0.003s"}`},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
input := DurationHolder{c.input}
|
||||
result, err := json.Marshal(&input)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to marshal input: %q: %v", input, err)
|
||||
}
|
||||
if string(result) != c.result {
|
||||
t.Errorf("Failed to marshal input: %q: expected %q, got %q", input, c.result, string(result))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDurationUnmarshalJSON(t *testing.T) {
|
||||
cases := []struct {
|
||||
input string
|
||||
result Duration
|
||||
}{
|
||||
{`{"d":"0s"}`, Duration{}},
|
||||
{`{"d":"5s"}`, Duration{5 * time.Second}},
|
||||
{`{"d":"2m0s"}`, Duration{2 * time.Minute}},
|
||||
{`{"d":"1h0m0.003s"}`, Duration{time.Hour + 3*time.Millisecond}},
|
||||
|
||||
// Units with zero values can optionally be dropped
|
||||
{`{"d":"2m"}`, Duration{2 * time.Minute}},
|
||||
{`{"d":"1h0.003s"}`, Duration{time.Hour + 3*time.Millisecond}},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
var result DurationHolder
|
||||
if err := json.Unmarshal([]byte(c.input), &result); err != nil {
|
||||
t.Errorf("Failed to unmarshal input %q: %v", c.input, err)
|
||||
}
|
||||
if result.D != c.result {
|
||||
t.Errorf("Failed to unmarshal input %q: expected %q, got %q", c.input, c.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDurationMarshalJSONUnmarshalYAML(t *testing.T) {
|
||||
cases := []struct {
|
||||
input Duration
|
||||
}{
|
||||
{Duration{}},
|
||||
{Duration{5 * time.Second}},
|
||||
{Duration{2 * time.Minute}},
|
||||
{Duration{time.Hour + 3*time.Millisecond}},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
input := DurationHolder{c.input}
|
||||
jsonMarshalled, err := json.Marshal(&input)
|
||||
if err != nil {
|
||||
t.Errorf("%d-1: Failed to marshal input: '%v': %v", i, input, err)
|
||||
}
|
||||
|
||||
var result DurationHolder
|
||||
if err := yaml.Unmarshal(jsonMarshalled, &result); err != nil {
|
||||
t.Errorf("%d-2: Failed to unmarshal '%+v': %v", i, string(jsonMarshalled), err)
|
||||
}
|
||||
|
||||
if input.D != result.D {
|
||||
t.Errorf("%d-4: Failed to marshal input '%#v': got %#v", i, input, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
78
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/group_version_test.go
generated
vendored
78
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/group_version_test.go
generated
vendored
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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 v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
)
|
||||
|
||||
type GroupVersionHolder struct {
|
||||
GV GroupVersion `json:"val"`
|
||||
}
|
||||
|
||||
func TestGroupVersionUnmarshalJSON(t *testing.T) {
|
||||
cases := []struct {
|
||||
input []byte
|
||||
expect GroupVersion
|
||||
}{
|
||||
{[]byte(`{"val": "v1"}`), GroupVersion{"", "v1"}},
|
||||
{[]byte(`{"val": "extensions/v1beta1"}`), GroupVersion{"extensions", "v1beta1"}},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
var result GroupVersionHolder
|
||||
// test golang lib's JSON codec
|
||||
if err := json.Unmarshal([]byte(c.input), &result); err != nil {
|
||||
t.Errorf("JSON codec failed to unmarshal input '%v': %v", c.input, err)
|
||||
}
|
||||
if !reflect.DeepEqual(result.GV, c.expect) {
|
||||
t.Errorf("JSON codec failed to unmarshal input '%s': expected %+v, got %+v", c.input, c.expect, result.GV)
|
||||
}
|
||||
// test the json-iterator codec
|
||||
if err := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(c.input, &result); err != nil {
|
||||
t.Errorf("json-iterator codec failed to unmarshal input '%v': %v", c.input, err)
|
||||
}
|
||||
if !reflect.DeepEqual(result.GV, c.expect) {
|
||||
t.Errorf("json-iterator codec failed to unmarshal input '%s': expected %+v, got %+v", c.input, c.expect, result.GV)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGroupVersionMarshalJSON(t *testing.T) {
|
||||
cases := []struct {
|
||||
input GroupVersion
|
||||
expect []byte
|
||||
}{
|
||||
{GroupVersion{"", "v1"}, []byte(`{"val":"v1"}`)},
|
||||
{GroupVersion{"extensions", "v1beta1"}, []byte(`{"val":"extensions/v1beta1"}`)},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
input := GroupVersionHolder{c.input}
|
||||
result, err := json.Marshal(&input)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to marshal input '%v': %v", input, err)
|
||||
}
|
||||
if !reflect.DeepEqual(result, c.expect) {
|
||||
t.Errorf("Failed to marshal input '%+v': expected: %s, got: %s", input, c.expect, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
154
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/helpers_test.go
generated
vendored
154
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/helpers_test.go
generated
vendored
|
|
@ -1,154 +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 v1
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
func TestLabelSelectorAsSelector(t *testing.T) {
|
||||
matchLabels := map[string]string{"foo": "bar"}
|
||||
matchExpressions := []LabelSelectorRequirement{{
|
||||
Key: "baz",
|
||||
Operator: LabelSelectorOpIn,
|
||||
Values: []string{"qux", "norf"},
|
||||
}}
|
||||
mustParse := func(s string) labels.Selector {
|
||||
out, e := labels.Parse(s)
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
return out
|
||||
}
|
||||
tc := []struct {
|
||||
in *LabelSelector
|
||||
out labels.Selector
|
||||
expectErr bool
|
||||
}{
|
||||
{in: nil, out: labels.Nothing()},
|
||||
{in: &LabelSelector{}, out: labels.Everything()},
|
||||
{
|
||||
in: &LabelSelector{MatchLabels: matchLabels},
|
||||
out: mustParse("foo=bar"),
|
||||
},
|
||||
{
|
||||
in: &LabelSelector{MatchExpressions: matchExpressions},
|
||||
out: mustParse("baz in (norf,qux)"),
|
||||
},
|
||||
{
|
||||
in: &LabelSelector{MatchLabels: matchLabels, MatchExpressions: matchExpressions},
|
||||
out: mustParse("baz in (norf,qux),foo=bar"),
|
||||
},
|
||||
{
|
||||
in: &LabelSelector{
|
||||
MatchExpressions: []LabelSelectorRequirement{{
|
||||
Key: "baz",
|
||||
Operator: LabelSelectorOpExists,
|
||||
Values: []string{"qux", "norf"},
|
||||
}},
|
||||
},
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range tc {
|
||||
out, err := LabelSelectorAsSelector(tc.in)
|
||||
if err == nil && tc.expectErr {
|
||||
t.Errorf("[%v]expected error but got none.", i)
|
||||
}
|
||||
if err != nil && !tc.expectErr {
|
||||
t.Errorf("[%v]did not expect error but got: %v", i, err)
|
||||
}
|
||||
if !reflect.DeepEqual(out, tc.out) {
|
||||
t.Errorf("[%v]expected:\n\t%+v\nbut got:\n\t%+v", i, tc.out, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLabelSelectorAsMap(t *testing.T) {
|
||||
matchLabels := map[string]string{"foo": "bar"}
|
||||
matchExpressions := func(operator LabelSelectorOperator, values []string) []LabelSelectorRequirement {
|
||||
return []LabelSelectorRequirement{{
|
||||
Key: "baz",
|
||||
Operator: operator,
|
||||
Values: values,
|
||||
}}
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in *LabelSelector
|
||||
out map[string]string
|
||||
errString string
|
||||
}{
|
||||
{in: nil, out: nil},
|
||||
{
|
||||
in: &LabelSelector{MatchLabels: matchLabels},
|
||||
out: map[string]string{"foo": "bar"},
|
||||
},
|
||||
{
|
||||
in: &LabelSelector{MatchLabels: matchLabels, MatchExpressions: matchExpressions(LabelSelectorOpIn, []string{"norf"})},
|
||||
out: map[string]string{"foo": "bar", "baz": "norf"},
|
||||
},
|
||||
{
|
||||
in: &LabelSelector{MatchExpressions: matchExpressions(LabelSelectorOpIn, []string{"norf"})},
|
||||
out: map[string]string{"baz": "norf"},
|
||||
},
|
||||
{
|
||||
in: &LabelSelector{MatchLabels: matchLabels, MatchExpressions: matchExpressions(LabelSelectorOpIn, []string{"norf", "qux"})},
|
||||
out: map[string]string{"foo": "bar"},
|
||||
errString: "without a single value cannot be converted",
|
||||
},
|
||||
{
|
||||
in: &LabelSelector{MatchExpressions: matchExpressions(LabelSelectorOpNotIn, []string{"norf", "qux"})},
|
||||
out: map[string]string{},
|
||||
errString: "cannot be converted",
|
||||
},
|
||||
{
|
||||
in: &LabelSelector{MatchLabels: matchLabels, MatchExpressions: matchExpressions(LabelSelectorOpExists, []string{})},
|
||||
out: map[string]string{"foo": "bar"},
|
||||
errString: "cannot be converted",
|
||||
},
|
||||
{
|
||||
in: &LabelSelector{MatchExpressions: matchExpressions(LabelSelectorOpDoesNotExist, []string{})},
|
||||
out: map[string]string{},
|
||||
errString: "cannot be converted",
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range tests {
|
||||
out, err := LabelSelectorAsMap(tc.in)
|
||||
if err == nil && len(tc.errString) > 0 {
|
||||
t.Errorf("[%v]expected error but got none.", i)
|
||||
continue
|
||||
}
|
||||
if err != nil && len(tc.errString) == 0 {
|
||||
t.Errorf("[%v]did not expect error but got: %v", i, err)
|
||||
continue
|
||||
}
|
||||
if err != nil && len(tc.errString) > 0 && !strings.Contains(err.Error(), tc.errString) {
|
||||
t.Errorf("[%v]expected error with %q but got: %v", i, tc.errString, err)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(out, tc.out) {
|
||||
t.Errorf("[%v]expected:\n\t%+v\nbut got:\n\t%+v", i, tc.out, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
123
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/labels_test.go
generated
vendored
123
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/labels_test.go
generated
vendored
|
|
@ -1,123 +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 v1
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCloneSelectorAndAddLabel(t *testing.T) {
|
||||
labels := map[string]string{
|
||||
"foo1": "bar1",
|
||||
"foo2": "bar2",
|
||||
"foo3": "bar3",
|
||||
}
|
||||
matchExpressions := []LabelSelectorRequirement{
|
||||
{Key: "foo", Operator: LabelSelectorOpIn, Values: []string{"foo"}},
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
labels map[string]string
|
||||
labelKey string
|
||||
labelValue string
|
||||
want map[string]string
|
||||
}{
|
||||
{
|
||||
labels: labels,
|
||||
want: labels,
|
||||
},
|
||||
{
|
||||
labels: labels,
|
||||
labelKey: "foo4",
|
||||
labelValue: "89",
|
||||
want: map[string]string{
|
||||
"foo1": "bar1",
|
||||
"foo2": "bar2",
|
||||
"foo3": "bar3",
|
||||
"foo4": "89",
|
||||
},
|
||||
},
|
||||
{
|
||||
labels: nil,
|
||||
labelKey: "foo4",
|
||||
labelValue: "12",
|
||||
want: map[string]string{
|
||||
"foo4": "12",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
ls_in := LabelSelector{MatchLabels: tc.labels, MatchExpressions: matchExpressions}
|
||||
ls_out := LabelSelector{MatchLabels: tc.want, MatchExpressions: matchExpressions}
|
||||
|
||||
got := CloneSelectorAndAddLabel(&ls_in, tc.labelKey, tc.labelValue)
|
||||
if !reflect.DeepEqual(got, &ls_out) {
|
||||
t.Errorf("got %v, want %v", got, tc.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddLabelToSelector(t *testing.T) {
|
||||
labels := map[string]string{
|
||||
"foo1": "bar1",
|
||||
"foo2": "bar2",
|
||||
"foo3": "bar3",
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
labels map[string]string
|
||||
labelKey string
|
||||
labelValue string
|
||||
want map[string]string
|
||||
}{
|
||||
{
|
||||
labels: labels,
|
||||
want: labels,
|
||||
},
|
||||
{
|
||||
labels: labels,
|
||||
labelKey: "foo4",
|
||||
labelValue: "89",
|
||||
want: map[string]string{
|
||||
"foo1": "bar1",
|
||||
"foo2": "bar2",
|
||||
"foo3": "bar3",
|
||||
"foo4": "89",
|
||||
},
|
||||
},
|
||||
{
|
||||
labels: nil,
|
||||
labelKey: "foo4",
|
||||
labelValue: "12",
|
||||
want: map[string]string{
|
||||
"foo4": "12",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
ls_in := LabelSelector{MatchLabels: tc.labels}
|
||||
ls_out := LabelSelector{MatchLabels: tc.want}
|
||||
|
||||
got := AddLabelToSelector(&ls_in, tc.labelKey, tc.labelValue)
|
||||
if !reflect.DeepEqual(got, &ls_out) {
|
||||
t.Errorf("got %v, want %v", got, tc.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
139
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/micro_time_test.go
generated
vendored
139
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/micro_time_test.go
generated
vendored
|
|
@ -1,139 +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 v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
)
|
||||
|
||||
type MicroTimeHolder struct {
|
||||
T MicroTime `json:"t"`
|
||||
}
|
||||
|
||||
func TestMicroTimeMarshalYAML(t *testing.T) {
|
||||
cases := []struct {
|
||||
input MicroTime
|
||||
result string
|
||||
}{
|
||||
{MicroTime{}, "t: null\n"},
|
||||
{DateMicro(1998, time.May, 5, 1, 5, 5, 50, time.FixedZone("test", -4*60*60)), "t: 1998-05-05T05:05:05.000000Z\n"},
|
||||
{DateMicro(1998, time.May, 5, 5, 5, 5, 0, time.UTC), "t: 1998-05-05T05:05:05.000000Z\n"},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
input := MicroTimeHolder{c.input}
|
||||
result, err := yaml.Marshal(&input)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to marshal input: '%v': %v", input, err)
|
||||
}
|
||||
if string(result) != c.result {
|
||||
t.Errorf("Failed to marshal input: '%v': expected %+v, got %q", input, c.result, string(result))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMicroTimeUnmarshalYAML(t *testing.T) {
|
||||
cases := []struct {
|
||||
input string
|
||||
result MicroTime
|
||||
}{
|
||||
{"t: null\n", MicroTime{}},
|
||||
{"t: 1998-05-05T05:05:05.000000Z\n", MicroTime{Date(1998, time.May, 5, 5, 5, 5, 0, time.UTC).Local()}},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
var result MicroTimeHolder
|
||||
if err := yaml.Unmarshal([]byte(c.input), &result); err != nil {
|
||||
t.Errorf("Failed to unmarshal input '%v': %v", c.input, err)
|
||||
}
|
||||
if result.T != c.result {
|
||||
t.Errorf("Failed to unmarshal input '%v': expected %+v, got %+v", c.input, c.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMicroTimeMarshalJSON(t *testing.T) {
|
||||
cases := []struct {
|
||||
input MicroTime
|
||||
result string
|
||||
}{
|
||||
{MicroTime{}, "{\"t\":null}"},
|
||||
{DateMicro(1998, time.May, 5, 5, 5, 5, 50, time.UTC), "{\"t\":\"1998-05-05T05:05:05.000000Z\"}"},
|
||||
{DateMicro(1998, time.May, 5, 5, 5, 5, 0, time.UTC), "{\"t\":\"1998-05-05T05:05:05.000000Z\"}"},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
input := MicroTimeHolder{c.input}
|
||||
result, err := json.Marshal(&input)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to marshal input: '%v': %v", input, err)
|
||||
}
|
||||
if string(result) != c.result {
|
||||
t.Errorf("Failed to marshal input: '%v': expected %+v, got %q", input, c.result, string(result))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMicroTimeUnmarshalJSON(t *testing.T) {
|
||||
cases := []struct {
|
||||
input string
|
||||
result MicroTime
|
||||
}{
|
||||
{"{\"t\":null}", MicroTime{}},
|
||||
{"{\"t\":\"1998-05-05T05:05:05.000000Z\"}", MicroTime{Date(1998, time.May, 5, 5, 5, 5, 0, time.UTC).Local()}},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
var result MicroTimeHolder
|
||||
if err := json.Unmarshal([]byte(c.input), &result); err != nil {
|
||||
t.Errorf("Failed to unmarshal input '%v': %v", c.input, err)
|
||||
}
|
||||
if result.T != c.result {
|
||||
t.Errorf("Failed to unmarshal input '%v': expected %+v, got %+v", c.input, c.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMicroTimeProto(t *testing.T) {
|
||||
cases := []struct {
|
||||
input MicroTime
|
||||
}{
|
||||
{MicroTime{}},
|
||||
{DateMicro(1998, time.May, 5, 1, 5, 5, 50, time.Local)},
|
||||
{DateMicro(1998, time.May, 5, 5, 5, 5, 0, time.Local)},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
input := c.input
|
||||
data, err := input.Marshal()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to marshal input: '%v': %v", input, err)
|
||||
}
|
||||
time := MicroTime{}
|
||||
if err := time.Unmarshal(data); err != nil {
|
||||
t.Fatalf("Failed to unmarshal output: '%v': %v", input, err)
|
||||
}
|
||||
if !reflect.DeepEqual(input, time) {
|
||||
t.Errorf("Marshal->Unmarshal is not idempotent: '%v' vs '%v'", input, time)
|
||||
}
|
||||
}
|
||||
}
|
||||
197
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/time_test.go
generated
vendored
197
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/time_test.go
generated
vendored
|
|
@ -1,197 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
)
|
||||
|
||||
type TimeHolder struct {
|
||||
T Time `json:"t"`
|
||||
}
|
||||
|
||||
func TestTimeMarshalYAML(t *testing.T) {
|
||||
cases := []struct {
|
||||
input Time
|
||||
result string
|
||||
}{
|
||||
{Time{}, "t: null\n"},
|
||||
{Date(1998, time.May, 5, 1, 5, 5, 50, time.FixedZone("test", -4*60*60)), "t: 1998-05-05T05:05:05Z\n"},
|
||||
{Date(1998, time.May, 5, 5, 5, 5, 0, time.UTC), "t: 1998-05-05T05:05:05Z\n"},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
input := TimeHolder{c.input}
|
||||
result, err := yaml.Marshal(&input)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to marshal input: '%v': %v", input, err)
|
||||
}
|
||||
if string(result) != c.result {
|
||||
t.Errorf("Failed to marshal input: '%v': expected %+v, got %q", input, c.result, string(result))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimeUnmarshalYAML(t *testing.T) {
|
||||
cases := []struct {
|
||||
input string
|
||||
result Time
|
||||
}{
|
||||
{"t: null\n", Time{}},
|
||||
{"t: 1998-05-05T05:05:05Z\n", Time{Date(1998, time.May, 5, 5, 5, 5, 0, time.UTC).Local()}},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
var result TimeHolder
|
||||
if err := yaml.Unmarshal([]byte(c.input), &result); err != nil {
|
||||
t.Errorf("Failed to unmarshal input '%v': %v", c.input, err)
|
||||
}
|
||||
if result.T != c.result {
|
||||
t.Errorf("Failed to unmarshal input '%v': expected %+v, got %+v", c.input, c.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimeMarshalJSON(t *testing.T) {
|
||||
cases := []struct {
|
||||
input Time
|
||||
result string
|
||||
}{
|
||||
{Time{}, "{\"t\":null}"},
|
||||
{Date(1998, time.May, 5, 5, 5, 5, 50, time.UTC), "{\"t\":\"1998-05-05T05:05:05Z\"}"},
|
||||
{Date(1998, time.May, 5, 5, 5, 5, 0, time.UTC), "{\"t\":\"1998-05-05T05:05:05Z\"}"},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
input := TimeHolder{c.input}
|
||||
result, err := json.Marshal(&input)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to marshal input: '%v': %v", input, err)
|
||||
}
|
||||
if string(result) != c.result {
|
||||
t.Errorf("Failed to marshal input: '%v': expected %+v, got %q", input, c.result, string(result))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimeUnmarshalJSON(t *testing.T) {
|
||||
cases := []struct {
|
||||
input string
|
||||
result Time
|
||||
}{
|
||||
{"{\"t\":null}", Time{}},
|
||||
{"{\"t\":\"1998-05-05T05:05:05Z\"}", Time{Date(1998, time.May, 5, 5, 5, 5, 0, time.UTC).Local()}},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
var result TimeHolder
|
||||
if err := json.Unmarshal([]byte(c.input), &result); err != nil {
|
||||
t.Errorf("Failed to unmarshal input '%v': %v", c.input, err)
|
||||
}
|
||||
if result.T != c.result {
|
||||
t.Errorf("Failed to unmarshal input '%v': expected %+v, got %+v", c.input, c.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimeMarshalJSONUnmarshalYAML(t *testing.T) {
|
||||
cases := []struct {
|
||||
input Time
|
||||
}{
|
||||
{Time{}},
|
||||
{Date(1998, time.May, 5, 5, 5, 5, 50, time.Local).Rfc3339Copy()},
|
||||
{Date(1998, time.May, 5, 5, 5, 5, 0, time.Local).Rfc3339Copy()},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
input := TimeHolder{c.input}
|
||||
jsonMarshalled, err := json.Marshal(&input)
|
||||
if err != nil {
|
||||
t.Errorf("%d-1: Failed to marshal input: '%v': %v", i, input, err)
|
||||
}
|
||||
|
||||
var result TimeHolder
|
||||
err = yaml.Unmarshal(jsonMarshalled, &result)
|
||||
if err != nil {
|
||||
t.Errorf("%d-2: Failed to unmarshal '%+v': %v", i, string(jsonMarshalled), err)
|
||||
}
|
||||
|
||||
iN, iO := input.T.Zone()
|
||||
oN, oO := result.T.Zone()
|
||||
if iN != oN || iO != oO {
|
||||
t.Errorf("%d-3: Time zones differ before and after serialization %s:%d %s:%d", i, iN, iO, oN, oO)
|
||||
}
|
||||
|
||||
if input.T.UnixNano() != result.T.UnixNano() {
|
||||
t.Errorf("%d-4: Failed to marshal input '%#v': got %#v", i, input, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimeProto(t *testing.T) {
|
||||
cases := []struct {
|
||||
input Time
|
||||
}{
|
||||
{Time{}},
|
||||
{Date(1998, time.May, 5, 1, 5, 5, 0, time.Local)},
|
||||
{Date(1998, time.May, 5, 5, 5, 5, 0, time.Local)},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
input := c.input
|
||||
data, err := input.Marshal()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to marshal input: '%v': %v", input, err)
|
||||
}
|
||||
time := Time{}
|
||||
if err := time.Unmarshal(data); err != nil {
|
||||
t.Fatalf("Failed to unmarshal output: '%v': %v", input, err)
|
||||
}
|
||||
if !reflect.DeepEqual(input, time) {
|
||||
t.Errorf("Marshal->Unmarshal is not idempotent: '%v' vs '%v'", input, time)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimeEqual(t *testing.T) {
|
||||
t1 := NewTime(time.Now())
|
||||
cases := []struct {
|
||||
name string
|
||||
x *Time
|
||||
y *Time
|
||||
result bool
|
||||
}{
|
||||
{"nil =? nil", nil, nil, true},
|
||||
{"!nil =? !nil", &t1, &t1, true},
|
||||
{"nil =? !nil", nil, &t1, false},
|
||||
{"!nil =? nil", &t1, nil, false},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
result := c.x.Equal(c.y)
|
||||
if result != c.result {
|
||||
t.Errorf("Failed equality test for '%v', '%v': expected %+v, got %+v", c.x, c.y, c.result, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
134
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_test.go
generated
vendored
134
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/types_test.go
generated
vendored
|
|
@ -1,134 +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 v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
)
|
||||
|
||||
func TestVerbsUgorjiMarshalJSON(t *testing.T) {
|
||||
cases := []struct {
|
||||
input APIResource
|
||||
result string
|
||||
}{
|
||||
{APIResource{}, `{"name":"","singularName":"","namespaced":false,"kind":"","verbs":null}`},
|
||||
{APIResource{Verbs: Verbs([]string{})}, `{"name":"","singularName":"","namespaced":false,"kind":"","verbs":[]}`},
|
||||
{APIResource{Verbs: Verbs([]string{"delete"})}, `{"name":"","singularName":"","namespaced":false,"kind":"","verbs":["delete"]}`},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
result, err := json.Marshal(&c.input)
|
||||
if err != nil {
|
||||
t.Errorf("[%d] Failed to marshal input: '%v': %v", i, c.input, err)
|
||||
}
|
||||
if string(result) != c.result {
|
||||
t.Errorf("[%d] Failed to marshal input: '%v': expected '%v', got '%v'", i, c.input, c.result, string(result))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerbsUgorjiUnmarshalJSON(t *testing.T) {
|
||||
cases := []struct {
|
||||
input string
|
||||
result APIResource
|
||||
}{
|
||||
{`{}`, APIResource{}},
|
||||
{`{"verbs":null}`, APIResource{}},
|
||||
{`{"verbs":[]}`, APIResource{Verbs: Verbs([]string{})}},
|
||||
{`{"verbs":["delete"]}`, APIResource{Verbs: Verbs([]string{"delete"})}},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
var result APIResource
|
||||
if err := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal([]byte(c.input), &result); err != nil {
|
||||
t.Errorf("[%d] Failed to unmarshal input '%v': %v", i, c.input, err)
|
||||
}
|
||||
if !reflect.DeepEqual(result, c.result) {
|
||||
t.Errorf("[%d] Failed to unmarshal input '%v': expected %+v, got %+v", i, c.input, c.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestUgorjiMarshalJSONWithOmit tests that we don't have regressions regarding nil and empty slices with "omit"
|
||||
func TestUgorjiMarshalJSONWithOmit(t *testing.T) {
|
||||
cases := []struct {
|
||||
input LabelSelector
|
||||
result string
|
||||
}{
|
||||
{LabelSelector{}, `{}`},
|
||||
{LabelSelector{MatchExpressions: []LabelSelectorRequirement{}}, `{}`},
|
||||
{LabelSelector{MatchExpressions: []LabelSelectorRequirement{{}}}, `{"matchExpressions":[{"key":"","operator":""}]}`},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
result, err := json.Marshal(&c.input)
|
||||
if err != nil {
|
||||
t.Errorf("[%d] Failed to marshal input: '%v': %v", i, c.input, err)
|
||||
}
|
||||
if string(result) != c.result {
|
||||
t.Errorf("[%d] Failed to marshal input: '%v': expected '%v', got '%v'", i, c.input, c.result, string(result))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerbsUnmarshalJSON(t *testing.T) {
|
||||
cases := []struct {
|
||||
input string
|
||||
result APIResource
|
||||
}{
|
||||
{`{}`, APIResource{}},
|
||||
{`{"verbs":null}`, APIResource{}},
|
||||
{`{"verbs":[]}`, APIResource{Verbs: Verbs([]string{})}},
|
||||
{`{"verbs":["delete"]}`, APIResource{Verbs: Verbs([]string{"delete"})}},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
var result APIResource
|
||||
if err := json.Unmarshal([]byte(c.input), &result); err != nil {
|
||||
t.Errorf("[%d] Failed to unmarshal input '%v': %v", i, c.input, err)
|
||||
}
|
||||
if !reflect.DeepEqual(result, c.result) {
|
||||
t.Errorf("[%d] Failed to unmarshal input '%v': expected %+v, got %+v", i, c.input, c.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerbsProto(t *testing.T) {
|
||||
cases := []APIResource{
|
||||
{},
|
||||
{Verbs: Verbs([]string{})},
|
||||
{Verbs: Verbs([]string{"delete"})},
|
||||
}
|
||||
|
||||
for _, input := range cases {
|
||||
data, err := input.Marshal()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to marshal input: '%v': %v", input, err)
|
||||
}
|
||||
resource := APIResource{}
|
||||
if err := resource.Unmarshal(data); err != nil {
|
||||
t.Fatalf("Failed to unmarshal output: '%v': %v", input, err)
|
||||
}
|
||||
if !reflect.DeepEqual(input, resource) {
|
||||
t.Errorf("Marshal->Unmarshal is not idempotent: '%v' vs '%v'", input, resource)
|
||||
}
|
||||
}
|
||||
}
|
||||
53
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/BUILD
generated
vendored
53
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/BUILD
generated
vendored
|
|
@ -1,53 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"helpers_test.go",
|
||||
"unstructured_list_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/require:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"helpers.go",
|
||||
"unstructured.go",
|
||||
"unstructured_list.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/json:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
60
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/helpers_test.go
generated
vendored
60
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/helpers_test.go
generated
vendored
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
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 unstructured
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// TestCodecOfUnstructuredList tests that there are no data races in Encode().
|
||||
// i.e. that it does not mutate the object being encoded.
|
||||
func TestCodecOfUnstructuredList(t *testing.T) {
|
||||
var wg sync.WaitGroup
|
||||
concurrency := 10
|
||||
list := UnstructuredList{
|
||||
Object: map[string]interface{}{},
|
||||
}
|
||||
wg.Add(concurrency)
|
||||
for i := 0; i < concurrency; i++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
assert.NoError(t, UnstructuredJSONScheme.Encode(&list, ioutil.Discard))
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestRemoveNestedField(t *testing.T) {
|
||||
obj := map[string]interface{}{
|
||||
"x": map[string]interface{}{
|
||||
"y": 1,
|
||||
"a": "foo",
|
||||
},
|
||||
}
|
||||
RemoveNestedField(obj, "x", "a")
|
||||
assert.Len(t, obj["x"], 1)
|
||||
RemoveNestedField(obj, "x", "y")
|
||||
assert.Empty(t, obj["x"])
|
||||
RemoveNestedField(obj, "x")
|
||||
assert.Empty(t, obj)
|
||||
RemoveNestedField(obj, "x") // Remove of a non-existent field
|
||||
assert.Empty(t, obj)
|
||||
}
|
||||
86
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured_list_test.go
generated
vendored
86
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured_list_test.go
generated
vendored
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
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 unstructured
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestUnstructuredList(t *testing.T) {
|
||||
list := &UnstructuredList{
|
||||
Object: map[string]interface{}{"kind": "List", "apiVersion": "v1"},
|
||||
Items: []Unstructured{
|
||||
{Object: map[string]interface{}{"kind": "Pod", "apiVersion": "v1", "metadata": map[string]interface{}{"name": "test"}}},
|
||||
},
|
||||
}
|
||||
content := list.UnstructuredContent()
|
||||
items := content["items"].([]interface{})
|
||||
require.Len(t, items, 1)
|
||||
val, found, err := NestedFieldCopy(items[0].(map[string]interface{}), "metadata", "name")
|
||||
require.True(t, found)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "test", val)
|
||||
}
|
||||
|
||||
func TestNilDeletionTimestamp(t *testing.T) {
|
||||
var u Unstructured
|
||||
del := u.GetDeletionTimestamp()
|
||||
if del != nil {
|
||||
t.Errorf("unexpected non-nil deletion timestamp: %v", del)
|
||||
}
|
||||
u.SetDeletionTimestamp(u.GetDeletionTimestamp())
|
||||
del = u.GetDeletionTimestamp()
|
||||
if del != nil {
|
||||
t.Errorf("unexpected non-nil deletion timestamp: %v", del)
|
||||
}
|
||||
_, ok := u.Object["metadata"]
|
||||
assert.False(t, ok)
|
||||
|
||||
now := metav1.Now()
|
||||
u.SetDeletionTimestamp(&now)
|
||||
assert.Equal(t, now.Unix(), u.GetDeletionTimestamp().Unix())
|
||||
u.SetDeletionTimestamp(nil)
|
||||
metadata := u.Object["metadata"].(map[string]interface{})
|
||||
_, ok = metadata["deletionTimestamp"]
|
||||
assert.False(t, ok)
|
||||
}
|
||||
|
||||
func TestEmptyCreationTimestampIsOmitted(t *testing.T) {
|
||||
var u Unstructured
|
||||
now := metav1.Now()
|
||||
|
||||
// set an initial creationTimestamp and ensure the field exists
|
||||
u.SetCreationTimestamp(now)
|
||||
metadata := u.Object["metadata"].(map[string]interface{})
|
||||
creationTimestamp, exists := metadata["creationTimestamp"]
|
||||
if !exists {
|
||||
t.Fatalf("unexpected missing creationTimestamp")
|
||||
}
|
||||
|
||||
// set an empty timestamp and ensure the field no longer exists
|
||||
u.SetCreationTimestamp(metav1.Time{})
|
||||
metadata = u.Object["metadata"].(map[string]interface{})
|
||||
creationTimestamp, exists = metadata["creationTimestamp"]
|
||||
if exists {
|
||||
t.Errorf("unexpected creation timestamp field: %q", creationTimestamp)
|
||||
}
|
||||
}
|
||||
38
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/BUILD
generated
vendored
38
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/BUILD
generated
vendored
|
|
@ -1,38 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["validation_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = ["//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["validation.go"],
|
||||
importpath = "k8s.io/apimachinery/pkg/apis/meta/v1/validation",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
94
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation_test.go
generated
vendored
94
vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation/validation_test.go
generated
vendored
|
|
@ -1,94 +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 validation
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
func TestValidateLabels(t *testing.T) {
|
||||
successCases := []map[string]string{
|
||||
{"simple": "bar"},
|
||||
{"now-with-dashes": "bar"},
|
||||
{"1-starts-with-num": "bar"},
|
||||
{"1234": "bar"},
|
||||
{"simple/simple": "bar"},
|
||||
{"now-with-dashes/simple": "bar"},
|
||||
{"now-with-dashes/now-with-dashes": "bar"},
|
||||
{"now.with.dots/simple": "bar"},
|
||||
{"now-with.dashes-and.dots/simple": "bar"},
|
||||
{"1-num.2-num/3-num": "bar"},
|
||||
{"1234/5678": "bar"},
|
||||
{"1.2.3.4/5678": "bar"},
|
||||
{"UpperCaseAreOK123": "bar"},
|
||||
{"goodvalue": "123_-.BaR"},
|
||||
}
|
||||
for i := range successCases {
|
||||
errs := ValidateLabels(successCases[i], field.NewPath("field"))
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("case[%d] expected success, got %#v", i, errs)
|
||||
}
|
||||
}
|
||||
|
||||
namePartErrMsg := "name part must consist of"
|
||||
nameErrMsg := "a qualified name must consist of"
|
||||
labelErrMsg := "a valid label must be an empty string or consist of"
|
||||
maxLengthErrMsg := "must be no more than"
|
||||
|
||||
labelNameErrorCases := []struct {
|
||||
labels map[string]string
|
||||
expect string
|
||||
}{
|
||||
{map[string]string{"nospecialchars^=@": "bar"}, namePartErrMsg},
|
||||
{map[string]string{"cantendwithadash-": "bar"}, namePartErrMsg},
|
||||
{map[string]string{"only/one/slash": "bar"}, nameErrMsg},
|
||||
{map[string]string{strings.Repeat("a", 254): "bar"}, maxLengthErrMsg},
|
||||
}
|
||||
for i := range labelNameErrorCases {
|
||||
errs := ValidateLabels(labelNameErrorCases[i].labels, field.NewPath("field"))
|
||||
if len(errs) != 1 {
|
||||
t.Errorf("case[%d]: expected failure", i)
|
||||
} else {
|
||||
if !strings.Contains(errs[0].Detail, labelNameErrorCases[i].expect) {
|
||||
t.Errorf("case[%d]: error details do not include %q: %q", i, labelNameErrorCases[i].expect, errs[0].Detail)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
labelValueErrorCases := []struct {
|
||||
labels map[string]string
|
||||
expect string
|
||||
}{
|
||||
{map[string]string{"toolongvalue": strings.Repeat("a", 64)}, maxLengthErrMsg},
|
||||
{map[string]string{"backslashesinvalue": "some\\bad\\value"}, labelErrMsg},
|
||||
{map[string]string{"nocommasallowed": "bad,value"}, labelErrMsg},
|
||||
{map[string]string{"strangecharsinvalue": "?#$notsogood"}, labelErrMsg},
|
||||
}
|
||||
for i := range labelValueErrorCases {
|
||||
errs := ValidateLabels(labelValueErrorCases[i].labels, field.NewPath("field"))
|
||||
if len(errs) != 1 {
|
||||
t.Errorf("case[%d]: expected failure", i)
|
||||
} else {
|
||||
if !strings.Contains(errs[0].Detail, labelValueErrorCases[i].expect) {
|
||||
t.Errorf("case[%d]: error details do not include %q: %q", i, labelValueErrorCases[i].expect, errs[0].Detail)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
45
vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/BUILD
generated
vendored
45
vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/BUILD
generated
vendored
|
|
@ -1,45 +0,0 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
filegroup(
|
||||
name = "go_default_library_protos",
|
||||
srcs = ["generated.proto"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"conversion.go",
|
||||
"deepcopy.go",
|
||||
"doc.go",
|
||||
"generated.pb.go",
|
||||
"register.go",
|
||||
"types.go",
|
||||
"types_swagger_doc_generated.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
"zz_generated.defaults.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/apis/meta/v1beta1",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/gogo/protobuf/proto:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/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"],
|
||||
)
|
||||
49
vendor/k8s.io/apimachinery/pkg/conversion/BUILD
generated
vendored
49
vendor/k8s.io/apimachinery/pkg/conversion/BUILD
generated
vendored
|
|
@ -1,49 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"converter_test.go",
|
||||
"helper_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/github.com/google/gofuzz:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"converter.go",
|
||||
"deep_equal.go",
|
||||
"doc.go",
|
||||
"helper.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/conversion",
|
||||
deps = ["//vendor/k8s.io/apimachinery/third_party/forked/golang/reflect:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/conversion/queryparams:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
826
vendor/k8s.io/apimachinery/pkg/conversion/converter_test.go
generated
vendored
826
vendor/k8s.io/apimachinery/pkg/conversion/converter_test.go
generated
vendored
|
|
@ -1,826 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 conversion
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/gofuzz"
|
||||
flag "github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
)
|
||||
|
||||
var fuzzIters = flag.Int("fuzz-iters", 50, "How many fuzzing iterations to do.")
|
||||
|
||||
// Test a weird version/kind embedding format.
|
||||
type MyWeirdCustomEmbeddedVersionKindField struct {
|
||||
ID string `json:"ID,omitempty"`
|
||||
APIVersion string `json:"myVersionKey,omitempty"`
|
||||
ObjectKind string `json:"myKindKey,omitempty"`
|
||||
Z string `json:"Z,omitempty"`
|
||||
Y uint64 `json:"Y,omitempty"`
|
||||
}
|
||||
|
||||
type TestType1 struct {
|
||||
MyWeirdCustomEmbeddedVersionKindField `json:",inline"`
|
||||
A string `json:"A,omitempty"`
|
||||
B int `json:"B,omitempty"`
|
||||
C int8 `json:"C,omitempty"`
|
||||
D int16 `json:"D,omitempty"`
|
||||
E int32 `json:"E,omitempty"`
|
||||
F int64 `json:"F,omitempty"`
|
||||
G uint `json:"G,omitempty"`
|
||||
H uint8 `json:"H,omitempty"`
|
||||
I uint16 `json:"I,omitempty"`
|
||||
J uint32 `json:"J,omitempty"`
|
||||
K uint64 `json:"K,omitempty"`
|
||||
L bool `json:"L,omitempty"`
|
||||
M map[string]int `json:"M,omitempty"`
|
||||
N map[string]TestType2 `json:"N,omitempty"`
|
||||
O *TestType2 `json:"O,omitempty"`
|
||||
P []TestType2 `json:"Q,omitempty"`
|
||||
}
|
||||
|
||||
type TestType2 struct {
|
||||
A string `json:"A,omitempty"`
|
||||
B int `json:"B,omitempty"`
|
||||
}
|
||||
|
||||
type ExternalTestType2 struct {
|
||||
A string `json:"A,omitempty"`
|
||||
B int `json:"B,omitempty"`
|
||||
}
|
||||
type ExternalTestType1 struct {
|
||||
MyWeirdCustomEmbeddedVersionKindField `json:",inline"`
|
||||
A string `json:"A,omitempty"`
|
||||
B int `json:"B,omitempty"`
|
||||
C int8 `json:"C,omitempty"`
|
||||
D int16 `json:"D,omitempty"`
|
||||
E int32 `json:"E,omitempty"`
|
||||
F int64 `json:"F,omitempty"`
|
||||
G uint `json:"G,omitempty"`
|
||||
H uint8 `json:"H,omitempty"`
|
||||
I uint16 `json:"I,omitempty"`
|
||||
J uint32 `json:"J,omitempty"`
|
||||
K uint64 `json:"K,omitempty"`
|
||||
L bool `json:"L,omitempty"`
|
||||
M map[string]int `json:"M,omitempty"`
|
||||
N map[string]ExternalTestType2 `json:"N,omitempty"`
|
||||
O *ExternalTestType2 `json:"O,omitempty"`
|
||||
P []ExternalTestType2 `json:"Q,omitempty"`
|
||||
}
|
||||
|
||||
func testLogger(t *testing.T) DebugLogger {
|
||||
// We don't set logger to eliminate rubbish logs in tests.
|
||||
// If you want to switch it, simply switch it to: "return t"
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestConverter_byteSlice(t *testing.T) {
|
||||
c := NewConverter(DefaultNameFunc)
|
||||
src := []byte{1, 2, 3}
|
||||
dest := []byte{}
|
||||
err := c.Convert(&src, &dest, 0, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error")
|
||||
}
|
||||
if e, a := src, dest; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expected %#v, got %#v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConverter_MismatchedTypes(t *testing.T) {
|
||||
c := NewConverter(DefaultNameFunc)
|
||||
|
||||
err := c.RegisterConversionFunc(
|
||||
func(in *[]string, out *int, s Scope) error {
|
||||
if str, err := strconv.Atoi((*in)[0]); err != nil {
|
||||
return err
|
||||
} else {
|
||||
*out = str
|
||||
return nil
|
||||
}
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
src := []string{"5"}
|
||||
var dest *int
|
||||
err = c.Convert(&src, &dest, 0, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if e, a := 5, *dest; e != a {
|
||||
t.Errorf("expected %#v, got %#v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConverter_DefaultConvert(t *testing.T) {
|
||||
type A struct {
|
||||
Foo string
|
||||
Baz int
|
||||
}
|
||||
type B struct {
|
||||
Bar string
|
||||
Baz int
|
||||
}
|
||||
c := NewConverter(DefaultNameFunc)
|
||||
c.Debug = testLogger(t)
|
||||
c.nameFunc = func(t reflect.Type) string { return "MyType" }
|
||||
|
||||
// Ensure conversion funcs can call DefaultConvert to get default behavior,
|
||||
// then fixup remaining fields manually
|
||||
err := c.RegisterConversionFunc(func(in *A, out *B, s Scope) error {
|
||||
if err := s.DefaultConvert(in, out, IgnoreMissingFields); err != nil {
|
||||
return err
|
||||
}
|
||||
out.Bar = in.Foo
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
|
||||
x := A{"hello, intrepid test reader!", 3}
|
||||
y := B{}
|
||||
|
||||
err = c.Convert(&x, &y, 0, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
if e, a := x.Foo, y.Bar; e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := x.Baz, y.Baz; e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConverter_DeepCopy(t *testing.T) {
|
||||
type A struct {
|
||||
Foo *string
|
||||
Bar []string
|
||||
Baz interface{}
|
||||
Qux map[string]string
|
||||
}
|
||||
c := NewConverter(DefaultNameFunc)
|
||||
c.Debug = testLogger(t)
|
||||
|
||||
foo, baz := "foo", "baz"
|
||||
x := A{
|
||||
Foo: &foo,
|
||||
Bar: []string{"bar"},
|
||||
Baz: &baz,
|
||||
Qux: map[string]string{"qux": "qux"},
|
||||
}
|
||||
y := A{}
|
||||
|
||||
if err := c.Convert(&x, &y, 0, nil); err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
*x.Foo = "foo2"
|
||||
x.Bar[0] = "bar2"
|
||||
*x.Baz.(*string) = "baz2"
|
||||
x.Qux["qux"] = "qux2"
|
||||
if e, a := *x.Foo, *y.Foo; e == a {
|
||||
t.Errorf("expected difference between %v and %v", e, a)
|
||||
}
|
||||
if e, a := x.Bar, y.Bar; reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expected difference between %v and %v", e, a)
|
||||
}
|
||||
if e, a := *x.Baz.(*string), *y.Baz.(*string); e == a {
|
||||
t.Errorf("expected difference between %v and %v", e, a)
|
||||
}
|
||||
if e, a := x.Qux, y.Qux; reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expected difference between %v and %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConverter_CallsRegisteredFunctions(t *testing.T) {
|
||||
type A struct {
|
||||
Foo string
|
||||
Baz int
|
||||
}
|
||||
type B struct {
|
||||
Bar string
|
||||
Baz int
|
||||
}
|
||||
type C struct{}
|
||||
c := NewConverter(DefaultNameFunc)
|
||||
c.Debug = testLogger(t)
|
||||
err := c.RegisterConversionFunc(func(in *A, out *B, s Scope) error {
|
||||
out.Bar = in.Foo
|
||||
return s.Convert(&in.Baz, &out.Baz, 0)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
err = c.RegisterConversionFunc(func(in *B, out *A, s Scope) error {
|
||||
out.Foo = in.Bar
|
||||
return s.Convert(&in.Baz, &out.Baz, 0)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
|
||||
x := A{"hello, intrepid test reader!", 3}
|
||||
y := B{}
|
||||
|
||||
err = c.Convert(&x, &y, 0, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
if e, a := x.Foo, y.Bar; e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := x.Baz, y.Baz; e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
z := B{"all your test are belong to us", 42}
|
||||
w := A{}
|
||||
|
||||
err = c.Convert(&z, &w, 0, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
if e, a := z.Bar, w.Foo; e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := z.Baz, w.Baz; e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
|
||||
err = c.RegisterConversionFunc(func(in *A, out *C, s Scope) error {
|
||||
return fmt.Errorf("C can't store an A, silly")
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
err = c.Convert(&A{}, &C{}, 0, nil)
|
||||
if err == nil {
|
||||
t.Errorf("unexpected non-error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConverter_IgnoredConversion(t *testing.T) {
|
||||
type A struct{}
|
||||
type B struct{}
|
||||
|
||||
count := 0
|
||||
c := NewConverter(DefaultNameFunc)
|
||||
if err := c.RegisterConversionFunc(func(in *A, out *B, s Scope) error {
|
||||
count++
|
||||
return nil
|
||||
}); err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
if err := c.RegisterIgnoredConversion(&A{}, &B{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
a := A{}
|
||||
b := B{}
|
||||
if err := c.Convert(&a, &b, 0, nil); err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
if count != 0 {
|
||||
t.Errorf("unexpected number of conversion invocations")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConverter_IgnoredConversionNested(t *testing.T) {
|
||||
type C string
|
||||
type A struct {
|
||||
C C
|
||||
}
|
||||
type B struct {
|
||||
C C
|
||||
}
|
||||
|
||||
c := NewConverter(DefaultNameFunc)
|
||||
typed := C("")
|
||||
if err := c.RegisterIgnoredConversion(&typed, &typed); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
a := A{C: C("test")}
|
||||
b := B{C: C("other")}
|
||||
if err := c.Convert(&a, &b, AllowDifferentFieldTypeNames, nil); err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
if b.C != C("other") {
|
||||
t.Errorf("expected no conversion of field C: %#v", b)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConverter_GeneratedConversionOverriden(t *testing.T) {
|
||||
type A struct{}
|
||||
type B struct{}
|
||||
c := NewConverter(DefaultNameFunc)
|
||||
if err := c.RegisterConversionFunc(func(in *A, out *B, s Scope) error {
|
||||
return nil
|
||||
}); err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
if err := c.RegisterGeneratedConversionFunc(func(in *A, out *B, s Scope) error {
|
||||
return fmt.Errorf("generated function should be overridden")
|
||||
}); err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
|
||||
a := A{}
|
||||
b := B{}
|
||||
if err := c.Convert(&a, &b, 0, nil); err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConverter_WithConversionOverriden(t *testing.T) {
|
||||
type A struct{}
|
||||
type B struct{}
|
||||
c := NewConverter(DefaultNameFunc)
|
||||
if err := c.RegisterConversionFunc(func(in *A, out *B, s Scope) error {
|
||||
return fmt.Errorf("conversion function should be overridden")
|
||||
}); err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
if err := c.RegisterGeneratedConversionFunc(func(in *A, out *B, s Scope) error {
|
||||
return fmt.Errorf("generated function should be overridden")
|
||||
}); err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
|
||||
ext := NewConversionFuncs()
|
||||
ext.Add(func(in *A, out *B, s Scope) error {
|
||||
return nil
|
||||
})
|
||||
newc := c.WithConversions(ext)
|
||||
|
||||
a := A{}
|
||||
b := B{}
|
||||
if err := c.Convert(&a, &b, 0, nil); err == nil || err.Error() != "conversion function should be overridden" {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if err := newc.Convert(&a, &b, 0, nil); err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConverter_MapsStringArrays(t *testing.T) {
|
||||
type A struct {
|
||||
Foo string
|
||||
Baz int
|
||||
Other string
|
||||
}
|
||||
c := NewConverter(DefaultNameFunc)
|
||||
c.Debug = testLogger(t)
|
||||
if err := c.RegisterConversionFunc(func(input *[]string, out *string, s Scope) error {
|
||||
if len(*input) == 0 {
|
||||
*out = ""
|
||||
}
|
||||
*out = (*input)[0]
|
||||
return nil
|
||||
}); err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
|
||||
x := map[string][]string{
|
||||
"Foo": {"bar"},
|
||||
"Baz": {"1"},
|
||||
"Other": {"", "test"},
|
||||
"other": {"wrong"},
|
||||
}
|
||||
y := A{"test", 2, "something"}
|
||||
|
||||
if err := c.Convert(&x, &y, AllowDifferentFieldTypeNames, nil); err == nil {
|
||||
t.Error("unexpected non-error")
|
||||
}
|
||||
|
||||
if err := c.RegisterConversionFunc(func(input *[]string, out *int, s Scope) error {
|
||||
if len(*input) == 0 {
|
||||
*out = 0
|
||||
}
|
||||
str := (*input)[0]
|
||||
i, err := strconv.Atoi(str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*out = i
|
||||
return nil
|
||||
}); err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
|
||||
if err := c.Convert(&x, &y, AllowDifferentFieldTypeNames, nil); err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(y, A{"bar", 1, ""}) {
|
||||
t.Errorf("unexpected result: %#v", y)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConverter_MapsStringArraysWithMappingKey(t *testing.T) {
|
||||
type A struct {
|
||||
Foo string `json:"test"`
|
||||
Baz int
|
||||
Other string
|
||||
}
|
||||
c := NewConverter(DefaultNameFunc)
|
||||
c.Debug = testLogger(t)
|
||||
if err := c.RegisterConversionFunc(func(input *[]string, out *string, s Scope) error {
|
||||
if len(*input) == 0 {
|
||||
*out = ""
|
||||
}
|
||||
*out = (*input)[0]
|
||||
return nil
|
||||
}); err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
|
||||
x := map[string][]string{
|
||||
"Foo": {"bar"},
|
||||
"test": {"baz"},
|
||||
}
|
||||
y := A{"", 0, ""}
|
||||
|
||||
if err := c.Convert(&x, &y, AllowDifferentFieldTypeNames|IgnoreMissingFields, &Meta{}); err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(y, A{"bar", 0, ""}) {
|
||||
t.Errorf("unexpected result: %#v", y)
|
||||
}
|
||||
|
||||
mapping := func(key string, sourceTag, destTag reflect.StructTag) (source string, dest string) {
|
||||
if s := destTag.Get("json"); len(s) > 0 {
|
||||
return strings.SplitN(s, ",", 2)[0], key
|
||||
}
|
||||
return key, key
|
||||
}
|
||||
|
||||
if err := c.Convert(&x, &y, AllowDifferentFieldTypeNames|IgnoreMissingFields, &Meta{KeyNameMapping: mapping}); err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(y, A{"baz", 0, ""}) {
|
||||
t.Errorf("unexpected result: %#v", y)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConverter_fuzz(t *testing.T) {
|
||||
// Use the same types from the scheme test.
|
||||
table := []struct {
|
||||
from, to, check interface{}
|
||||
}{
|
||||
{&TestType1{}, &ExternalTestType1{}, &TestType1{}},
|
||||
{&ExternalTestType1{}, &TestType1{}, &ExternalTestType1{}},
|
||||
}
|
||||
|
||||
f := fuzz.New().NilChance(.5).NumElements(0, 100)
|
||||
c := NewConverter(DefaultNameFunc)
|
||||
c.nameFunc = func(t reflect.Type) string {
|
||||
// Hide the fact that we don't have separate packages for these things.
|
||||
return map[reflect.Type]string{
|
||||
reflect.TypeOf(TestType1{}): "TestType1",
|
||||
reflect.TypeOf(ExternalTestType1{}): "TestType1",
|
||||
reflect.TypeOf(TestType2{}): "TestType2",
|
||||
reflect.TypeOf(ExternalTestType2{}): "TestType2",
|
||||
}[t]
|
||||
}
|
||||
c.Debug = testLogger(t)
|
||||
|
||||
for i, item := range table {
|
||||
for j := 0; j < *fuzzIters; j++ {
|
||||
f.Fuzz(item.from)
|
||||
err := c.Convert(item.from, item.to, 0, nil)
|
||||
if err != nil {
|
||||
t.Errorf("(%v, %v): unexpected error: %v", i, j, err)
|
||||
continue
|
||||
}
|
||||
err = c.Convert(item.to, item.check, 0, nil)
|
||||
if err != nil {
|
||||
t.Errorf("(%v, %v): unexpected error: %v", i, j, err)
|
||||
continue
|
||||
}
|
||||
if e, a := item.from, item.check; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("(%v, %v): unexpected diff: %v", i, j, diff.ObjectDiff(e, a))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConverter_MapElemAddr(t *testing.T) {
|
||||
type Foo struct {
|
||||
A map[int]int
|
||||
}
|
||||
type Bar struct {
|
||||
A map[string]string
|
||||
}
|
||||
c := NewConverter(DefaultNameFunc)
|
||||
c.Debug = testLogger(t)
|
||||
err := c.RegisterConversionFunc(
|
||||
func(in *int, out *string, s Scope) error {
|
||||
*out = fmt.Sprintf("%v", *in)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
err = c.RegisterConversionFunc(
|
||||
func(in *string, out *int, s Scope) error {
|
||||
if str, err := strconv.Atoi(*in); err != nil {
|
||||
return err
|
||||
} else {
|
||||
*out = str
|
||||
return nil
|
||||
}
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
f := fuzz.New().NilChance(0).NumElements(3, 3)
|
||||
first := Foo{}
|
||||
second := Bar{}
|
||||
f.Fuzz(&first)
|
||||
err = c.Convert(&first, &second, AllowDifferentFieldTypeNames, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
third := Foo{}
|
||||
err = c.Convert(&second, &third, AllowDifferentFieldTypeNames, nil)
|
||||
if e, a := first, third; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Unexpected diff: %v", diff.ObjectDiff(e, a))
|
||||
}
|
||||
}
|
||||
|
||||
func TestConverter_tags(t *testing.T) {
|
||||
type Foo struct {
|
||||
A string `test:"foo"`
|
||||
}
|
||||
type Bar struct {
|
||||
A string `test:"bar"`
|
||||
}
|
||||
c := NewConverter(DefaultNameFunc)
|
||||
c.Debug = testLogger(t)
|
||||
err := c.RegisterConversionFunc(
|
||||
func(in *string, out *string, s Scope) error {
|
||||
if e, a := "foo", s.SrcTag().Get("test"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := "bar", s.DestTag().Get("test"); e != a {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
err = c.Convert(&Foo{}, &Bar{}, AllowDifferentFieldTypeNames, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConverter_meta(t *testing.T) {
|
||||
type Foo struct{ A string }
|
||||
type Bar struct{ A string }
|
||||
c := NewConverter(DefaultNameFunc)
|
||||
c.Debug = testLogger(t)
|
||||
checks := 0
|
||||
err := c.RegisterConversionFunc(
|
||||
func(in *Foo, out *Bar, s Scope) error {
|
||||
if s.Meta() == nil {
|
||||
t.Errorf("Meta did not get passed!")
|
||||
}
|
||||
checks++
|
||||
s.Convert(&in.A, &out.A, 0)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
err = c.RegisterConversionFunc(
|
||||
func(in *string, out *string, s Scope) error {
|
||||
if s.Meta() == nil {
|
||||
t.Errorf("Meta did not get passed a second time!")
|
||||
}
|
||||
checks++
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
err = c.Convert(&Foo{}, &Bar{}, 0, &Meta{})
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
if checks != 2 {
|
||||
t.Errorf("Registered functions did not get called.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConverter_flags(t *testing.T) {
|
||||
type Foo struct{ A string }
|
||||
type Bar struct{ A string }
|
||||
table := []struct {
|
||||
from, to interface{}
|
||||
flags FieldMatchingFlags
|
||||
shouldSucceed bool
|
||||
}{
|
||||
// Check that DestFromSource allows extra fields only in source.
|
||||
{
|
||||
from: &struct{ A string }{},
|
||||
to: &struct{ A, B string }{},
|
||||
flags: DestFromSource,
|
||||
shouldSucceed: false,
|
||||
}, {
|
||||
from: &struct{ A, B string }{},
|
||||
to: &struct{ A string }{},
|
||||
flags: DestFromSource,
|
||||
shouldSucceed: true,
|
||||
},
|
||||
|
||||
// Check that SourceToDest allows for extra fields only in dest.
|
||||
{
|
||||
from: &struct{ A string }{},
|
||||
to: &struct{ A, B string }{},
|
||||
flags: SourceToDest,
|
||||
shouldSucceed: true,
|
||||
}, {
|
||||
from: &struct{ A, B string }{},
|
||||
to: &struct{ A string }{},
|
||||
flags: SourceToDest,
|
||||
shouldSucceed: false,
|
||||
},
|
||||
|
||||
// Check that IgnoreMissingFields makes the above failure cases pass.
|
||||
{
|
||||
from: &struct{ A string }{},
|
||||
to: &struct{ A, B string }{},
|
||||
flags: DestFromSource | IgnoreMissingFields,
|
||||
shouldSucceed: true,
|
||||
}, {
|
||||
from: &struct{ A, B string }{},
|
||||
to: &struct{ A string }{},
|
||||
flags: SourceToDest | IgnoreMissingFields,
|
||||
shouldSucceed: true,
|
||||
},
|
||||
|
||||
// Check that the field type name must match unless
|
||||
// AllowDifferentFieldTypeNames is specified.
|
||||
{
|
||||
from: &struct{ A, B Foo }{},
|
||||
to: &struct{ A Bar }{},
|
||||
flags: DestFromSource,
|
||||
shouldSucceed: false,
|
||||
}, {
|
||||
from: &struct{ A Foo }{},
|
||||
to: &struct{ A, B Bar }{},
|
||||
flags: SourceToDest,
|
||||
shouldSucceed: false,
|
||||
}, {
|
||||
from: &struct{ A, B Foo }{},
|
||||
to: &struct{ A Bar }{},
|
||||
flags: DestFromSource | AllowDifferentFieldTypeNames,
|
||||
shouldSucceed: true,
|
||||
}, {
|
||||
from: &struct{ A Foo }{},
|
||||
to: &struct{ A, B Bar }{},
|
||||
flags: SourceToDest | AllowDifferentFieldTypeNames,
|
||||
shouldSucceed: true,
|
||||
},
|
||||
}
|
||||
f := fuzz.New().NilChance(.5).NumElements(0, 100)
|
||||
c := NewConverter(DefaultNameFunc)
|
||||
c.Debug = testLogger(t)
|
||||
|
||||
for i, item := range table {
|
||||
for j := 0; j < *fuzzIters; j++ {
|
||||
f.Fuzz(item.from)
|
||||
err := c.Convert(item.from, item.to, item.flags, nil)
|
||||
if item.shouldSucceed && err != nil {
|
||||
t.Errorf("(%v, %v): unexpected error: %v", i, j, err)
|
||||
continue
|
||||
}
|
||||
if !item.shouldSucceed && err == nil {
|
||||
t.Errorf("(%v, %v): unexpected non-error", i, j)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConverter_FieldRename(t *testing.T) {
|
||||
type WeirdMeta struct {
|
||||
Name string
|
||||
Type string
|
||||
}
|
||||
type NameMeta struct {
|
||||
Name string
|
||||
}
|
||||
type TypeMeta struct {
|
||||
Type string
|
||||
}
|
||||
type A struct {
|
||||
WeirdMeta
|
||||
}
|
||||
type B struct {
|
||||
TypeMeta
|
||||
NameMeta
|
||||
}
|
||||
|
||||
c := NewConverter(DefaultNameFunc)
|
||||
err := c.SetStructFieldCopy(WeirdMeta{}, "WeirdMeta", TypeMeta{}, "TypeMeta")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
err = c.SetStructFieldCopy(WeirdMeta{}, "WeirdMeta", NameMeta{}, "NameMeta")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
err = c.SetStructFieldCopy(TypeMeta{}, "TypeMeta", WeirdMeta{}, "WeirdMeta")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
err = c.SetStructFieldCopy(NameMeta{}, "NameMeta", WeirdMeta{}, "WeirdMeta")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
}
|
||||
c.Debug = testLogger(t)
|
||||
|
||||
aVal := &A{
|
||||
WeirdMeta: WeirdMeta{
|
||||
Name: "Foo",
|
||||
Type: "Bar",
|
||||
},
|
||||
}
|
||||
|
||||
bVal := &B{
|
||||
TypeMeta: TypeMeta{"Bar"},
|
||||
NameMeta: NameMeta{"Foo"},
|
||||
}
|
||||
|
||||
table := map[string]struct {
|
||||
from, to, expect interface{}
|
||||
flags FieldMatchingFlags
|
||||
}{
|
||||
"to": {
|
||||
aVal,
|
||||
&B{},
|
||||
bVal,
|
||||
AllowDifferentFieldTypeNames | SourceToDest | IgnoreMissingFields,
|
||||
},
|
||||
"from": {
|
||||
bVal,
|
||||
&A{},
|
||||
aVal,
|
||||
AllowDifferentFieldTypeNames | SourceToDest,
|
||||
},
|
||||
"toDestFirst": {
|
||||
aVal,
|
||||
&B{},
|
||||
bVal,
|
||||
AllowDifferentFieldTypeNames,
|
||||
},
|
||||
"fromDestFirst": {
|
||||
bVal,
|
||||
&A{},
|
||||
aVal,
|
||||
AllowDifferentFieldTypeNames | IgnoreMissingFields,
|
||||
},
|
||||
}
|
||||
|
||||
for name, item := range table {
|
||||
err := c.Convert(item.from, item.to, item.flags, nil)
|
||||
if err != nil {
|
||||
t.Errorf("%v: unexpected error: %v", name, err)
|
||||
continue
|
||||
}
|
||||
if e, a := item.expect, item.to; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%v: unexpected diff: %v", name, diff.ObjectDiff(e, a))
|
||||
}
|
||||
}
|
||||
}
|
||||
38
vendor/k8s.io/apimachinery/pkg/conversion/helper_test.go
generated
vendored
38
vendor/k8s.io/apimachinery/pkg/conversion/helper_test.go
generated
vendored
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 conversion
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestInvalidPtrValueKind(t *testing.T) {
|
||||
var simple interface{}
|
||||
switch obj := simple.(type) {
|
||||
default:
|
||||
_, err := EnforcePtr(obj)
|
||||
if err == nil {
|
||||
t.Errorf("Expected error on invalid kind")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnforceNilPtr(t *testing.T) {
|
||||
var nilPtr *struct{}
|
||||
_, err := EnforcePtr(nilPtr)
|
||||
if err == nil {
|
||||
t.Errorf("Expected error on nil pointer")
|
||||
}
|
||||
}
|
||||
39
vendor/k8s.io/apimachinery/pkg/conversion/queryparams/BUILD
generated
vendored
39
vendor/k8s.io/apimachinery/pkg/conversion/queryparams/BUILD
generated
vendored
|
|
@ -1,39 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"convert.go",
|
||||
"doc.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/conversion/queryparams",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_xtest",
|
||||
srcs = ["convert_test.go"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion/queryparams:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
215
vendor/k8s.io/apimachinery/pkg/conversion/queryparams/convert_test.go
generated
vendored
215
vendor/k8s.io/apimachinery/pkg/conversion/queryparams/convert_test.go
generated
vendored
|
|
@ -1,215 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 queryparams_test
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion/queryparams"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
type namedString string
|
||||
type namedBool bool
|
||||
|
||||
type bar struct {
|
||||
Float1 float32 `json:"float1"`
|
||||
Float2 float64 `json:"float2"`
|
||||
Int1 int64 `json:"int1,omitempty"`
|
||||
Int2 int32 `json:"int2,omitempty"`
|
||||
Int3 int16 `json:"int3,omitempty"`
|
||||
Str1 string `json:"str1,omitempty"`
|
||||
Ignored int
|
||||
Ignored2 string
|
||||
}
|
||||
|
||||
func (obj *bar) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind }
|
||||
|
||||
type foo struct {
|
||||
Str string `json:"str"`
|
||||
Integer int `json:"integer,omitempty"`
|
||||
Slice []string `json:"slice,omitempty"`
|
||||
Boolean bool `json:"boolean,omitempty"`
|
||||
NamedStr namedString `json:"namedStr,omitempty"`
|
||||
NamedBool namedBool `json:"namedBool,omitempty"`
|
||||
Foobar bar `json:"foobar,omitempty"`
|
||||
Testmap map[string]string `json:"testmap,omitempty"`
|
||||
}
|
||||
|
||||
func (obj *foo) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind }
|
||||
|
||||
type baz struct {
|
||||
Ptr *int `json:"ptr"`
|
||||
Bptr *bool `json:"bptr,omitempty"`
|
||||
}
|
||||
|
||||
func (obj *baz) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind }
|
||||
|
||||
// childStructs tests some of the types we serialize to query params for log API calls
|
||||
// notably, the nested time struct
|
||||
type childStructs struct {
|
||||
Container string `json:"container,omitempty"`
|
||||
Follow bool `json:"follow,omitempty"`
|
||||
Previous bool `json:"previous,omitempty"`
|
||||
SinceSeconds *int64 `json:"sinceSeconds,omitempty"`
|
||||
SinceTime *metav1.Time `json:"sinceTime,omitempty"`
|
||||
EmptyTime *metav1.Time `json:"emptyTime"`
|
||||
NonPointerTime metav1.Time `json:"nonPointerTime"`
|
||||
}
|
||||
|
||||
func (obj *childStructs) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind }
|
||||
|
||||
func validateResult(t *testing.T, input interface{}, actual, expected url.Values) {
|
||||
local := url.Values{}
|
||||
for k, v := range expected {
|
||||
local[k] = v
|
||||
}
|
||||
for k, v := range actual {
|
||||
if ev, ok := local[k]; !ok || !reflect.DeepEqual(ev, v) {
|
||||
if !ok {
|
||||
t.Errorf("%#v: actual value key %s not found in expected map", input, k)
|
||||
} else {
|
||||
t.Errorf("%#v: values don't match: actual: %#v, expected: %#v", input, v, ev)
|
||||
}
|
||||
}
|
||||
delete(local, k)
|
||||
}
|
||||
if len(local) > 0 {
|
||||
t.Errorf("%#v: expected map has keys that were not found in actual map: %#v", input, local)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvert(t *testing.T) {
|
||||
sinceSeconds := int64(123)
|
||||
sinceTime := metav1.Date(2000, 1, 1, 12, 34, 56, 0, time.UTC)
|
||||
|
||||
tests := []struct {
|
||||
input interface{}
|
||||
expected url.Values
|
||||
}{
|
||||
{
|
||||
input: &foo{
|
||||
Str: "hello",
|
||||
},
|
||||
expected: url.Values{"str": {"hello"}},
|
||||
},
|
||||
{
|
||||
input: &foo{
|
||||
Str: "test string",
|
||||
Slice: []string{"one", "two", "three"},
|
||||
Integer: 234,
|
||||
Boolean: true,
|
||||
},
|
||||
expected: url.Values{"str": {"test string"}, "slice": {"one", "two", "three"}, "integer": {"234"}, "boolean": {"true"}},
|
||||
},
|
||||
{
|
||||
input: &foo{
|
||||
Str: "named types",
|
||||
NamedStr: "value1",
|
||||
NamedBool: true,
|
||||
},
|
||||
expected: url.Values{"str": {"named types"}, "namedStr": {"value1"}, "namedBool": {"true"}},
|
||||
},
|
||||
{
|
||||
input: &foo{
|
||||
Str: "don't ignore embedded struct",
|
||||
Foobar: bar{
|
||||
Float1: 5.0,
|
||||
},
|
||||
},
|
||||
expected: url.Values{"str": {"don't ignore embedded struct"}, "float1": {"5"}, "float2": {"0"}},
|
||||
},
|
||||
{
|
||||
// Ignore untagged fields
|
||||
input: &bar{
|
||||
Float1: 23.5,
|
||||
Float2: 100.7,
|
||||
Int1: 1,
|
||||
Int2: 2,
|
||||
Int3: 3,
|
||||
Ignored: 1,
|
||||
Ignored2: "ignored",
|
||||
},
|
||||
expected: url.Values{"float1": {"23.5"}, "float2": {"100.7"}, "int1": {"1"}, "int2": {"2"}, "int3": {"3"}},
|
||||
},
|
||||
{
|
||||
// include fields that are not tagged omitempty
|
||||
input: &foo{
|
||||
NamedStr: "named str",
|
||||
},
|
||||
expected: url.Values{"str": {""}, "namedStr": {"named str"}},
|
||||
},
|
||||
{
|
||||
input: &baz{
|
||||
Ptr: intp(5),
|
||||
Bptr: boolp(true),
|
||||
},
|
||||
expected: url.Values{"ptr": {"5"}, "bptr": {"true"}},
|
||||
},
|
||||
{
|
||||
input: &baz{
|
||||
Bptr: boolp(true),
|
||||
},
|
||||
expected: url.Values{"ptr": {""}, "bptr": {"true"}},
|
||||
},
|
||||
{
|
||||
input: &baz{
|
||||
Ptr: intp(5),
|
||||
},
|
||||
expected: url.Values{"ptr": {"5"}},
|
||||
},
|
||||
{
|
||||
input: &childStructs{
|
||||
Container: "mycontainer",
|
||||
Follow: true,
|
||||
Previous: true,
|
||||
SinceSeconds: &sinceSeconds,
|
||||
SinceTime: &sinceTime, // test a custom marshaller
|
||||
EmptyTime: nil, // test a nil custom marshaller without omitempty
|
||||
NonPointerTime: sinceTime,
|
||||
},
|
||||
expected: url.Values{"container": {"mycontainer"}, "follow": {"true"}, "previous": {"true"}, "sinceSeconds": {"123"}, "sinceTime": {"2000-01-01T12:34:56Z"}, "emptyTime": {""}, "nonPointerTime": {"2000-01-01T12:34:56Z"}},
|
||||
},
|
||||
{
|
||||
input: &childStructs{
|
||||
Container: "mycontainer",
|
||||
Follow: true,
|
||||
Previous: true,
|
||||
SinceSeconds: &sinceSeconds,
|
||||
SinceTime: nil, // test a nil custom marshaller with omitempty
|
||||
NonPointerTime: sinceTime,
|
||||
},
|
||||
expected: url.Values{"container": {"mycontainer"}, "follow": {"true"}, "previous": {"true"}, "sinceSeconds": {"123"}, "emptyTime": {""}, "nonPointerTime": {"2000-01-01T12:34:56Z"}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
result, err := queryparams.Convert(test.input)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error while converting %#v: %v", test.input, err)
|
||||
}
|
||||
validateResult(t, test.input, result, test.expected)
|
||||
}
|
||||
}
|
||||
|
||||
func intp(n int) *int { return &n }
|
||||
|
||||
func boolp(b bool) *bool { return &b }
|
||||
41
vendor/k8s.io/apimachinery/pkg/fields/BUILD
generated
vendored
41
vendor/k8s.io/apimachinery/pkg/fields/BUILD
generated
vendored
|
|
@ -1,41 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"fields_test.go",
|
||||
"selector_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"fields.go",
|
||||
"requirements.go",
|
||||
"selector.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/fields",
|
||||
deps = ["//vendor/k8s.io/apimachinery/pkg/selection:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
57
vendor/k8s.io/apimachinery/pkg/fields/fields_test.go
generated
vendored
57
vendor/k8s.io/apimachinery/pkg/fields/fields_test.go
generated
vendored
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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 fields
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func matches(t *testing.T, ls Set, want string) {
|
||||
if ls.String() != want {
|
||||
t.Errorf("Expected '%s', but got '%s'", want, ls.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetString(t *testing.T) {
|
||||
matches(t, Set{"x": "y"}, "x=y")
|
||||
matches(t, Set{"foo": "bar"}, "foo=bar")
|
||||
matches(t, Set{"foo": "bar", "baz": "qup"}, "baz=qup,foo=bar")
|
||||
}
|
||||
|
||||
func TestFieldHas(t *testing.T) {
|
||||
fieldHasTests := []struct {
|
||||
Ls Fields
|
||||
Key string
|
||||
Has bool
|
||||
}{
|
||||
{Set{"x": "y"}, "x", true},
|
||||
{Set{"x": ""}, "x", true},
|
||||
{Set{"x": "y"}, "foo", false},
|
||||
}
|
||||
for _, lh := range fieldHasTests {
|
||||
if has := lh.Ls.Has(lh.Key); has != lh.Has {
|
||||
t.Errorf("%#v.Has(%#v) => %v, expected %v", lh.Ls, lh.Key, has, lh.Has)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldGet(t *testing.T) {
|
||||
ls := Set{"x": "y"}
|
||||
if ls.Get("x") != "y" {
|
||||
t.Errorf("Set.Get is broken")
|
||||
}
|
||||
}
|
||||
397
vendor/k8s.io/apimachinery/pkg/fields/selector_test.go
generated
vendored
397
vendor/k8s.io/apimachinery/pkg/fields/selector_test.go
generated
vendored
|
|
@ -1,397 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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 fields
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSplitTerms(t *testing.T) {
|
||||
testcases := map[string][]string{
|
||||
// Simple selectors
|
||||
`a`: {`a`},
|
||||
`a=avalue`: {`a=avalue`},
|
||||
`a=avalue,b=bvalue`: {`a=avalue`, `b=bvalue`},
|
||||
`a=avalue,b==bvalue,c!=cvalue`: {`a=avalue`, `b==bvalue`, `c!=cvalue`},
|
||||
|
||||
// Empty terms
|
||||
``: nil,
|
||||
`a=a,`: {`a=a`, ``},
|
||||
`,a=a`: {``, `a=a`},
|
||||
|
||||
// Escaped values
|
||||
`k=\,,k2=v2`: {`k=\,`, `k2=v2`}, // escaped comma in value
|
||||
`k=\\,k2=v2`: {`k=\\`, `k2=v2`}, // escaped backslash, unescaped comma
|
||||
`k=\\\,,k2=v2`: {`k=\\\,`, `k2=v2`}, // escaped backslash and comma
|
||||
`k=\a\b\`: {`k=\a\b\`}, // non-escape sequences
|
||||
`k=\`: {`k=\`}, // orphan backslash
|
||||
|
||||
// Multi-byte
|
||||
`함=수,목=록`: {`함=수`, `목=록`},
|
||||
}
|
||||
|
||||
for selector, expectedTerms := range testcases {
|
||||
if terms := splitTerms(selector); !reflect.DeepEqual(terms, expectedTerms) {
|
||||
t.Errorf("splitSelectors(`%s`): Expected\n%#v\ngot\n%#v", selector, expectedTerms, terms)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitTerm(t *testing.T) {
|
||||
testcases := map[string]struct {
|
||||
lhs string
|
||||
op string
|
||||
rhs string
|
||||
ok bool
|
||||
}{
|
||||
// Simple terms
|
||||
`a=value`: {lhs: `a`, op: `=`, rhs: `value`, ok: true},
|
||||
`b==value`: {lhs: `b`, op: `==`, rhs: `value`, ok: true},
|
||||
`c!=value`: {lhs: `c`, op: `!=`, rhs: `value`, ok: true},
|
||||
|
||||
// Empty or invalid terms
|
||||
``: {lhs: ``, op: ``, rhs: ``, ok: false},
|
||||
`a`: {lhs: ``, op: ``, rhs: ``, ok: false},
|
||||
|
||||
// Escaped values
|
||||
`k=\,`: {lhs: `k`, op: `=`, rhs: `\,`, ok: true},
|
||||
`k=\=`: {lhs: `k`, op: `=`, rhs: `\=`, ok: true},
|
||||
`k=\\\a\b\=\,\`: {lhs: `k`, op: `=`, rhs: `\\\a\b\=\,\`, ok: true},
|
||||
|
||||
// Multi-byte
|
||||
`함=수`: {lhs: `함`, op: `=`, rhs: `수`, ok: true},
|
||||
}
|
||||
|
||||
for term, expected := range testcases {
|
||||
lhs, op, rhs, ok := splitTerm(term)
|
||||
if lhs != expected.lhs || op != expected.op || rhs != expected.rhs || ok != expected.ok {
|
||||
t.Errorf(
|
||||
"splitTerm(`%s`): Expected\n%s,%s,%s,%v\nGot\n%s,%s,%s,%v",
|
||||
term,
|
||||
expected.lhs, expected.op, expected.rhs, expected.ok,
|
||||
lhs, op, rhs, ok,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEscapeValue(t *testing.T) {
|
||||
// map values to their normalized escaped values
|
||||
testcases := map[string]string{
|
||||
``: ``,
|
||||
`a`: `a`,
|
||||
`=`: `\=`,
|
||||
`,`: `\,`,
|
||||
`\`: `\\`,
|
||||
`\=\,\`: `\\\=\\\,\\`,
|
||||
}
|
||||
|
||||
for unescapedValue, escapedValue := range testcases {
|
||||
actualEscaped := EscapeValue(unescapedValue)
|
||||
if actualEscaped != escapedValue {
|
||||
t.Errorf("EscapeValue(%s): expected %s, got %s", unescapedValue, escapedValue, actualEscaped)
|
||||
}
|
||||
|
||||
actualUnescaped, err := UnescapeValue(escapedValue)
|
||||
if err != nil {
|
||||
t.Errorf("UnescapeValue(%s): unexpected error %v", escapedValue, err)
|
||||
}
|
||||
if actualUnescaped != unescapedValue {
|
||||
t.Errorf("UnescapeValue(%s): expected %s, got %s", escapedValue, unescapedValue, actualUnescaped)
|
||||
}
|
||||
}
|
||||
|
||||
// test invalid escape sequences
|
||||
invalidTestcases := []string{
|
||||
`\`, // orphan slash is invalid
|
||||
`\\\`, // orphan slash is invalid
|
||||
`\a`, // unrecognized escape sequence is invalid
|
||||
}
|
||||
for _, invalidValue := range invalidTestcases {
|
||||
_, err := UnescapeValue(invalidValue)
|
||||
if _, ok := err.(InvalidEscapeSequence); !ok || err == nil {
|
||||
t.Errorf("UnescapeValue(%s): expected invalid escape sequence error, got %#v", invalidValue, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelectorParse(t *testing.T) {
|
||||
testGoodStrings := []string{
|
||||
"x=a,y=b,z=c",
|
||||
"",
|
||||
"x!=a,y=b",
|
||||
`x=a||y\=b`,
|
||||
`x=a\=\=b`,
|
||||
}
|
||||
testBadStrings := []string{
|
||||
"x=a||y=b",
|
||||
"x==a==b",
|
||||
"x=a,b",
|
||||
"x in (a)",
|
||||
"x in (a,b,c)",
|
||||
"x",
|
||||
}
|
||||
for _, test := range testGoodStrings {
|
||||
lq, err := ParseSelector(test)
|
||||
if err != nil {
|
||||
t.Errorf("%v: error %v (%#v)\n", test, err, err)
|
||||
}
|
||||
if test != lq.String() {
|
||||
t.Errorf("%v restring gave: %v\n", test, lq.String())
|
||||
}
|
||||
}
|
||||
for _, test := range testBadStrings {
|
||||
_, err := ParseSelector(test)
|
||||
if err == nil {
|
||||
t.Errorf("%v: did not get expected error\n", test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeterministicParse(t *testing.T) {
|
||||
s1, err := ParseSelector("x=a,a=x")
|
||||
s2, err2 := ParseSelector("a=x,x=a")
|
||||
if err != nil || err2 != nil {
|
||||
t.Errorf("Unexpected parse error")
|
||||
}
|
||||
if s1.String() != s2.String() {
|
||||
t.Errorf("Non-deterministic parse")
|
||||
}
|
||||
}
|
||||
|
||||
func expectMatch(t *testing.T, selector string, ls Set) {
|
||||
lq, err := ParseSelector(selector)
|
||||
if err != nil {
|
||||
t.Errorf("Unable to parse %v as a selector\n", selector)
|
||||
return
|
||||
}
|
||||
if !lq.Matches(ls) {
|
||||
t.Errorf("Wanted %s to match '%s', but it did not.\n", selector, ls)
|
||||
}
|
||||
}
|
||||
|
||||
func expectNoMatch(t *testing.T, selector string, ls Set) {
|
||||
lq, err := ParseSelector(selector)
|
||||
if err != nil {
|
||||
t.Errorf("Unable to parse %v as a selector\n", selector)
|
||||
return
|
||||
}
|
||||
if lq.Matches(ls) {
|
||||
t.Errorf("Wanted '%s' to not match '%s', but it did.", selector, ls)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEverything(t *testing.T) {
|
||||
if !Everything().Matches(Set{"x": "y"}) {
|
||||
t.Errorf("Nil selector didn't match")
|
||||
}
|
||||
if !Everything().Empty() {
|
||||
t.Errorf("Everything was not empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelectorMatches(t *testing.T) {
|
||||
expectMatch(t, "", Set{"x": "y"})
|
||||
expectMatch(t, "x=y", Set{"x": "y"})
|
||||
expectMatch(t, "x=y,z=w", Set{"x": "y", "z": "w"})
|
||||
expectMatch(t, "x!=y,z!=w", Set{"x": "z", "z": "a"})
|
||||
expectMatch(t, "notin=in", Set{"notin": "in"}) // in and notin in exactMatch
|
||||
expectNoMatch(t, "x=y", Set{"x": "z"})
|
||||
expectNoMatch(t, "x=y,z=w", Set{"x": "w", "z": "w"})
|
||||
expectNoMatch(t, "x!=y,z!=w", Set{"x": "z", "z": "w"})
|
||||
|
||||
fieldset := Set{
|
||||
"foo": "bar",
|
||||
"baz": "blah",
|
||||
"complex": `=value\,\`,
|
||||
}
|
||||
expectMatch(t, "foo=bar", fieldset)
|
||||
expectMatch(t, "baz=blah", fieldset)
|
||||
expectMatch(t, "foo=bar,baz=blah", fieldset)
|
||||
expectMatch(t, `foo=bar,baz=blah,complex=\=value\\\,\\`, fieldset)
|
||||
expectNoMatch(t, "foo=blah", fieldset)
|
||||
expectNoMatch(t, "baz=bar", fieldset)
|
||||
expectNoMatch(t, "foo=bar,foobar=bar,baz=blah", fieldset)
|
||||
}
|
||||
|
||||
func TestOneTermEqualSelector(t *testing.T) {
|
||||
if !OneTermEqualSelector("x", "y").Matches(Set{"x": "y"}) {
|
||||
t.Errorf("No match when match expected.")
|
||||
}
|
||||
if OneTermEqualSelector("x", "y").Matches(Set{"x": "z"}) {
|
||||
t.Errorf("Match when none expected.")
|
||||
}
|
||||
}
|
||||
|
||||
func expectMatchDirect(t *testing.T, selector, ls Set) {
|
||||
if !SelectorFromSet(selector).Matches(ls) {
|
||||
t.Errorf("Wanted %s to match '%s', but it did not.\n", selector, ls)
|
||||
}
|
||||
}
|
||||
|
||||
func expectNoMatchDirect(t *testing.T, selector, ls Set) {
|
||||
if SelectorFromSet(selector).Matches(ls) {
|
||||
t.Errorf("Wanted '%s' to not match '%s', but it did.", selector, ls)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetMatches(t *testing.T) {
|
||||
labelset := Set{
|
||||
"foo": "bar",
|
||||
"baz": "blah",
|
||||
}
|
||||
expectMatchDirect(t, Set{}, labelset)
|
||||
expectMatchDirect(t, Set{"foo": "bar"}, labelset)
|
||||
expectMatchDirect(t, Set{"baz": "blah"}, labelset)
|
||||
expectMatchDirect(t, Set{"foo": "bar", "baz": "blah"}, labelset)
|
||||
expectNoMatchDirect(t, Set{"foo": "=blah"}, labelset)
|
||||
expectNoMatchDirect(t, Set{"baz": "=bar"}, labelset)
|
||||
expectNoMatchDirect(t, Set{"foo": "=bar", "foobar": "bar", "baz": "blah"}, labelset)
|
||||
}
|
||||
|
||||
func TestNilMapIsValid(t *testing.T) {
|
||||
selector := Set(nil).AsSelector()
|
||||
if selector == nil {
|
||||
t.Errorf("Selector for nil set should be Everything")
|
||||
}
|
||||
if !selector.Empty() {
|
||||
t.Errorf("Selector for nil set should be Empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetIsEmpty(t *testing.T) {
|
||||
if !(Set{}).AsSelector().Empty() {
|
||||
t.Errorf("Empty set should be empty")
|
||||
}
|
||||
if !(andTerm(nil)).Empty() {
|
||||
t.Errorf("Nil andTerm should be empty")
|
||||
}
|
||||
if (&hasTerm{}).Empty() {
|
||||
t.Errorf("hasTerm should not be empty")
|
||||
}
|
||||
if (¬HasTerm{}).Empty() {
|
||||
t.Errorf("notHasTerm should not be empty")
|
||||
}
|
||||
if !(andTerm{andTerm{}}).Empty() {
|
||||
t.Errorf("Nested andTerm should be empty")
|
||||
}
|
||||
if (andTerm{&hasTerm{"a", "b"}}).Empty() {
|
||||
t.Errorf("Nested andTerm should not be empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequiresExactMatch(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
S Selector
|
||||
Label string
|
||||
Value string
|
||||
Found bool
|
||||
}{
|
||||
"empty set": {Set{}.AsSelector(), "test", "", false},
|
||||
"empty hasTerm": {&hasTerm{}, "test", "", false},
|
||||
"skipped hasTerm": {&hasTerm{"a", "b"}, "test", "", false},
|
||||
"valid hasTerm": {&hasTerm{"test", "b"}, "test", "b", true},
|
||||
"valid hasTerm no value": {&hasTerm{"test", ""}, "test", "", true},
|
||||
"valid notHasTerm": {¬HasTerm{"test", "b"}, "test", "", false},
|
||||
"valid notHasTerm no value": {¬HasTerm{"test", ""}, "test", "", false},
|
||||
"nil andTerm": {andTerm(nil), "test", "", false},
|
||||
"empty andTerm": {andTerm{}, "test", "", false},
|
||||
"nested andTerm": {andTerm{andTerm{}}, "test", "", false},
|
||||
"nested andTerm matches": {andTerm{&hasTerm{"test", "b"}}, "test", "b", true},
|
||||
"andTerm with non-match": {andTerm{&hasTerm{}, &hasTerm{"test", "b"}}, "test", "b", true},
|
||||
}
|
||||
for k, v := range testCases {
|
||||
value, found := v.S.RequiresExactMatch(v.Label)
|
||||
if value != v.Value {
|
||||
t.Errorf("%s: expected value %s, got %s", k, v.Value, value)
|
||||
}
|
||||
if found != v.Found {
|
||||
t.Errorf("%s: expected found %t, got %t", k, v.Found, found)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTransform(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
selector string
|
||||
transform func(field, value string) (string, string, error)
|
||||
result string
|
||||
isEmpty bool
|
||||
}{
|
||||
{
|
||||
name: "empty selector",
|
||||
selector: "",
|
||||
transform: func(field, value string) (string, string, error) { return field, value, nil },
|
||||
result: "",
|
||||
isEmpty: true,
|
||||
},
|
||||
{
|
||||
name: "no-op transform",
|
||||
selector: "a=b,c=d",
|
||||
transform: func(field, value string) (string, string, error) { return field, value, nil },
|
||||
result: "a=b,c=d",
|
||||
isEmpty: false,
|
||||
},
|
||||
{
|
||||
name: "transform one field",
|
||||
selector: "a=b,c=d",
|
||||
transform: func(field, value string) (string, string, error) {
|
||||
if field == "a" {
|
||||
return "e", "f", nil
|
||||
}
|
||||
return field, value, nil
|
||||
},
|
||||
result: "e=f,c=d",
|
||||
isEmpty: false,
|
||||
},
|
||||
{
|
||||
name: "remove field to make empty",
|
||||
selector: "a=b",
|
||||
transform: func(field, value string) (string, string, error) { return "", "", nil },
|
||||
result: "",
|
||||
isEmpty: true,
|
||||
},
|
||||
{
|
||||
name: "remove only one field",
|
||||
selector: "a=b,c=d,e=f",
|
||||
transform: func(field, value string) (string, string, error) {
|
||||
if field == "c" {
|
||||
return "", "", nil
|
||||
}
|
||||
return field, value, nil
|
||||
},
|
||||
result: "a=b,e=f",
|
||||
isEmpty: false,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
result, err := ParseAndTransformSelector(tc.selector, tc.transform)
|
||||
if err != nil {
|
||||
t.Errorf("[%d] unexpected error during Transform: %v", i, err)
|
||||
}
|
||||
if result.Empty() != tc.isEmpty {
|
||||
t.Errorf("[%d] expected empty: %t, got: %t", i, tc.isEmpty, result.Empty())
|
||||
}
|
||||
if result.String() != tc.result {
|
||||
t.Errorf("[%d] unexpected result: %s", i, result.String())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
50
vendor/k8s.io/apimachinery/pkg/labels/BUILD
generated
vendored
50
vendor/k8s.io/apimachinery/pkg/labels/BUILD
generated
vendored
|
|
@ -1,50 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"labels_test.go",
|
||||
"selector_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/selection:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"labels.go",
|
||||
"selector.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/labels",
|
||||
deps = [
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/selection:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
231
vendor/k8s.io/apimachinery/pkg/labels/labels_test.go
generated
vendored
231
vendor/k8s.io/apimachinery/pkg/labels/labels_test.go
generated
vendored
|
|
@ -1,231 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 labels
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func matches(t *testing.T, ls Set, want string) {
|
||||
if ls.String() != want {
|
||||
t.Errorf("Expected '%s', but got '%s'", want, ls.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetString(t *testing.T) {
|
||||
matches(t, Set{"x": "y"}, "x=y")
|
||||
matches(t, Set{"foo": "bar"}, "foo=bar")
|
||||
matches(t, Set{"foo": "bar", "baz": "qup"}, "baz=qup,foo=bar")
|
||||
|
||||
// TODO: Make our label representation robust enough to handle labels
|
||||
// with ",=!" characters in their names.
|
||||
}
|
||||
|
||||
func TestLabelHas(t *testing.T) {
|
||||
labelHasTests := []struct {
|
||||
Ls Labels
|
||||
Key string
|
||||
Has bool
|
||||
}{
|
||||
{Set{"x": "y"}, "x", true},
|
||||
{Set{"x": ""}, "x", true},
|
||||
{Set{"x": "y"}, "foo", false},
|
||||
}
|
||||
for _, lh := range labelHasTests {
|
||||
if has := lh.Ls.Has(lh.Key); has != lh.Has {
|
||||
t.Errorf("%#v.Has(%#v) => %v, expected %v", lh.Ls, lh.Key, has, lh.Has)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLabelGet(t *testing.T) {
|
||||
ls := Set{"x": "y"}
|
||||
if ls.Get("x") != "y" {
|
||||
t.Errorf("Set.Get is broken")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLabelConflict(t *testing.T) {
|
||||
tests := []struct {
|
||||
labels1 map[string]string
|
||||
labels2 map[string]string
|
||||
conflict bool
|
||||
}{
|
||||
{
|
||||
labels1: map[string]string{},
|
||||
labels2: map[string]string{},
|
||||
conflict: false,
|
||||
},
|
||||
{
|
||||
labels1: map[string]string{"env": "test"},
|
||||
labels2: map[string]string{"infra": "true"},
|
||||
conflict: false,
|
||||
},
|
||||
{
|
||||
labels1: map[string]string{"env": "test"},
|
||||
labels2: map[string]string{"infra": "true", "env": "test"},
|
||||
conflict: false,
|
||||
},
|
||||
{
|
||||
labels1: map[string]string{"env": "test"},
|
||||
labels2: map[string]string{"env": "dev"},
|
||||
conflict: true,
|
||||
},
|
||||
{
|
||||
labels1: map[string]string{"env": "test", "infra": "false"},
|
||||
labels2: map[string]string{"infra": "true", "color": "blue"},
|
||||
conflict: true,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
conflict := Conflicts(Set(test.labels1), Set(test.labels2))
|
||||
if conflict != test.conflict {
|
||||
t.Errorf("expected: %v but got: %v", test.conflict, conflict)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLabelMerge(t *testing.T) {
|
||||
tests := []struct {
|
||||
labels1 map[string]string
|
||||
labels2 map[string]string
|
||||
mergedLabels map[string]string
|
||||
}{
|
||||
{
|
||||
labels1: map[string]string{},
|
||||
labels2: map[string]string{},
|
||||
mergedLabels: map[string]string{},
|
||||
},
|
||||
{
|
||||
labels1: map[string]string{"infra": "true"},
|
||||
labels2: map[string]string{},
|
||||
mergedLabels: map[string]string{"infra": "true"},
|
||||
},
|
||||
{
|
||||
labels1: map[string]string{"infra": "true"},
|
||||
labels2: map[string]string{"env": "test", "color": "blue"},
|
||||
mergedLabels: map[string]string{"infra": "true", "env": "test", "color": "blue"},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
mergedLabels := Merge(Set(test.labels1), Set(test.labels2))
|
||||
if !Equals(mergedLabels, test.mergedLabels) {
|
||||
t.Errorf("expected: %v but got: %v", test.mergedLabels, mergedLabels)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLabelSelectorParse(t *testing.T) {
|
||||
tests := []struct {
|
||||
selector string
|
||||
labels map[string]string
|
||||
valid bool
|
||||
}{
|
||||
{
|
||||
selector: "",
|
||||
labels: map[string]string{},
|
||||
valid: true,
|
||||
},
|
||||
{
|
||||
selector: "x=a",
|
||||
labels: map[string]string{"x": "a"},
|
||||
valid: true,
|
||||
},
|
||||
{
|
||||
selector: "x=a,y=b,z=c",
|
||||
labels: map[string]string{"x": "a", "y": "b", "z": "c"},
|
||||
valid: true,
|
||||
},
|
||||
{
|
||||
selector: " x = a , y = b , z = c ",
|
||||
labels: map[string]string{"x": "a", "y": "b", "z": "c"},
|
||||
valid: true,
|
||||
},
|
||||
{
|
||||
selector: "color=green,env=test,service=front",
|
||||
labels: map[string]string{"color": "green", "env": "test", "service": "front"},
|
||||
valid: true,
|
||||
},
|
||||
{
|
||||
selector: "color=green, env=test, service=front",
|
||||
labels: map[string]string{"color": "green", "env": "test", "service": "front"},
|
||||
valid: true,
|
||||
},
|
||||
{
|
||||
selector: ",",
|
||||
labels: map[string]string{},
|
||||
valid: false,
|
||||
},
|
||||
{
|
||||
selector: "x",
|
||||
labels: map[string]string{},
|
||||
valid: false,
|
||||
},
|
||||
{
|
||||
selector: "x,y",
|
||||
labels: map[string]string{},
|
||||
valid: false,
|
||||
},
|
||||
{
|
||||
selector: "x=$y",
|
||||
labels: map[string]string{},
|
||||
valid: false,
|
||||
},
|
||||
{
|
||||
selector: "x!=y",
|
||||
labels: map[string]string{},
|
||||
valid: false,
|
||||
},
|
||||
{
|
||||
selector: "x==y",
|
||||
labels: map[string]string{},
|
||||
valid: false,
|
||||
},
|
||||
{
|
||||
selector: "x=a||y=b",
|
||||
labels: map[string]string{},
|
||||
valid: false,
|
||||
},
|
||||
{
|
||||
selector: "x in (y)",
|
||||
labels: map[string]string{},
|
||||
valid: false,
|
||||
},
|
||||
{
|
||||
selector: "x notin (y)",
|
||||
labels: map[string]string{},
|
||||
valid: false,
|
||||
},
|
||||
{
|
||||
selector: "x y",
|
||||
labels: map[string]string{},
|
||||
valid: false,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
labels, err := ConvertSelectorToLabelsMap(test.selector)
|
||||
if test.valid && err != nil {
|
||||
t.Errorf("selector: %s, expected no error but got: %s", test.selector, err)
|
||||
} else if !test.valid && err == nil {
|
||||
t.Errorf("selector: %s, expected an error", test.selector)
|
||||
}
|
||||
|
||||
if !Equals(Set(labels), test.labels) {
|
||||
t.Errorf("expected: %s but got: %s", test.labels, labels)
|
||||
}
|
||||
}
|
||||
}
|
||||
575
vendor/k8s.io/apimachinery/pkg/labels/selector_test.go
generated
vendored
575
vendor/k8s.io/apimachinery/pkg/labels/selector_test.go
generated
vendored
|
|
@ -1,575 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 labels
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/selection"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
)
|
||||
|
||||
func TestSelectorParse(t *testing.T) {
|
||||
testGoodStrings := []string{
|
||||
"x=a,y=b,z=c",
|
||||
"",
|
||||
"x!=a,y=b",
|
||||
"x=",
|
||||
"x= ",
|
||||
"x=,z= ",
|
||||
"x= ,z= ",
|
||||
"!x",
|
||||
"x>1",
|
||||
"x>1,z<5",
|
||||
}
|
||||
testBadStrings := []string{
|
||||
"x=a||y=b",
|
||||
"x==a==b",
|
||||
"!x=a",
|
||||
"x<a",
|
||||
}
|
||||
for _, test := range testGoodStrings {
|
||||
lq, err := Parse(test)
|
||||
if err != nil {
|
||||
t.Errorf("%v: error %v (%#v)\n", test, err, err)
|
||||
}
|
||||
if strings.Replace(test, " ", "", -1) != lq.String() {
|
||||
t.Errorf("%v restring gave: %v\n", test, lq.String())
|
||||
}
|
||||
}
|
||||
for _, test := range testBadStrings {
|
||||
_, err := Parse(test)
|
||||
if err == nil {
|
||||
t.Errorf("%v: did not get expected error\n", test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeterministicParse(t *testing.T) {
|
||||
s1, err := Parse("x=a,a=x")
|
||||
s2, err2 := Parse("a=x,x=a")
|
||||
if err != nil || err2 != nil {
|
||||
t.Errorf("Unexpected parse error")
|
||||
}
|
||||
if s1.String() != s2.String() {
|
||||
t.Errorf("Non-deterministic parse")
|
||||
}
|
||||
}
|
||||
|
||||
func expectMatch(t *testing.T, selector string, ls Set) {
|
||||
lq, err := Parse(selector)
|
||||
if err != nil {
|
||||
t.Errorf("Unable to parse %v as a selector\n", selector)
|
||||
return
|
||||
}
|
||||
if !lq.Matches(ls) {
|
||||
t.Errorf("Wanted %s to match '%s', but it did not.\n", selector, ls)
|
||||
}
|
||||
}
|
||||
|
||||
func expectNoMatch(t *testing.T, selector string, ls Set) {
|
||||
lq, err := Parse(selector)
|
||||
if err != nil {
|
||||
t.Errorf("Unable to parse %v as a selector\n", selector)
|
||||
return
|
||||
}
|
||||
if lq.Matches(ls) {
|
||||
t.Errorf("Wanted '%s' to not match '%s', but it did.", selector, ls)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEverything(t *testing.T) {
|
||||
if !Everything().Matches(Set{"x": "y"}) {
|
||||
t.Errorf("Nil selector didn't match")
|
||||
}
|
||||
if !Everything().Empty() {
|
||||
t.Errorf("Everything was not empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelectorMatches(t *testing.T) {
|
||||
expectMatch(t, "", Set{"x": "y"})
|
||||
expectMatch(t, "x=y", Set{"x": "y"})
|
||||
expectMatch(t, "x=y,z=w", Set{"x": "y", "z": "w"})
|
||||
expectMatch(t, "x!=y,z!=w", Set{"x": "z", "z": "a"})
|
||||
expectMatch(t, "notin=in", Set{"notin": "in"}) // in and notin in exactMatch
|
||||
expectMatch(t, "x", Set{"x": "z"})
|
||||
expectMatch(t, "!x", Set{"y": "z"})
|
||||
expectMatch(t, "x>1", Set{"x": "2"})
|
||||
expectMatch(t, "x<1", Set{"x": "0"})
|
||||
expectNoMatch(t, "x=z", Set{})
|
||||
expectNoMatch(t, "x=y", Set{"x": "z"})
|
||||
expectNoMatch(t, "x=y,z=w", Set{"x": "w", "z": "w"})
|
||||
expectNoMatch(t, "x!=y,z!=w", Set{"x": "z", "z": "w"})
|
||||
expectNoMatch(t, "x", Set{"y": "z"})
|
||||
expectNoMatch(t, "!x", Set{"x": "z"})
|
||||
expectNoMatch(t, "x>1", Set{"x": "0"})
|
||||
expectNoMatch(t, "x<1", Set{"x": "2"})
|
||||
|
||||
labelset := Set{
|
||||
"foo": "bar",
|
||||
"baz": "blah",
|
||||
}
|
||||
expectMatch(t, "foo=bar", labelset)
|
||||
expectMatch(t, "baz=blah", labelset)
|
||||
expectMatch(t, "foo=bar,baz=blah", labelset)
|
||||
expectNoMatch(t, "foo=blah", labelset)
|
||||
expectNoMatch(t, "baz=bar", labelset)
|
||||
expectNoMatch(t, "foo=bar,foobar=bar,baz=blah", labelset)
|
||||
}
|
||||
|
||||
func expectMatchDirect(t *testing.T, selector, ls Set) {
|
||||
if !SelectorFromSet(selector).Matches(ls) {
|
||||
t.Errorf("Wanted %s to match '%s', but it did not.\n", selector, ls)
|
||||
}
|
||||
}
|
||||
|
||||
func expectNoMatchDirect(t *testing.T, selector, ls Set) {
|
||||
if SelectorFromSet(selector).Matches(ls) {
|
||||
t.Errorf("Wanted '%s' to not match '%s', but it did.", selector, ls)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetMatches(t *testing.T) {
|
||||
labelset := Set{
|
||||
"foo": "bar",
|
||||
"baz": "blah",
|
||||
}
|
||||
expectMatchDirect(t, Set{}, labelset)
|
||||
expectMatchDirect(t, Set{"foo": "bar"}, labelset)
|
||||
expectMatchDirect(t, Set{"baz": "blah"}, labelset)
|
||||
expectMatchDirect(t, Set{"foo": "bar", "baz": "blah"}, labelset)
|
||||
|
||||
//TODO: bad values not handled for the moment in SelectorFromSet
|
||||
//expectNoMatchDirect(t, Set{"foo": "=blah"}, labelset)
|
||||
//expectNoMatchDirect(t, Set{"baz": "=bar"}, labelset)
|
||||
//expectNoMatchDirect(t, Set{"foo": "=bar", "foobar": "bar", "baz": "blah"}, labelset)
|
||||
}
|
||||
|
||||
func TestNilMapIsValid(t *testing.T) {
|
||||
selector := Set(nil).AsSelector()
|
||||
if selector == nil {
|
||||
t.Errorf("Selector for nil set should be Everything")
|
||||
}
|
||||
if !selector.Empty() {
|
||||
t.Errorf("Selector for nil set should be Empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetIsEmpty(t *testing.T) {
|
||||
if !(Set{}).AsSelector().Empty() {
|
||||
t.Errorf("Empty set should be empty")
|
||||
}
|
||||
if !(NewSelector()).Empty() {
|
||||
t.Errorf("Nil Selector should be empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLexer(t *testing.T) {
|
||||
testcases := []struct {
|
||||
s string
|
||||
t Token
|
||||
}{
|
||||
{"", EndOfStringToken},
|
||||
{",", CommaToken},
|
||||
{"notin", NotInToken},
|
||||
{"in", InToken},
|
||||
{"=", EqualsToken},
|
||||
{"==", DoubleEqualsToken},
|
||||
{">", GreaterThanToken},
|
||||
{"<", LessThanToken},
|
||||
//Note that Lex returns the longest valid token found
|
||||
{"!", DoesNotExistToken},
|
||||
{"!=", NotEqualsToken},
|
||||
{"(", OpenParToken},
|
||||
{")", ClosedParToken},
|
||||
//Non-"special" characters are considered part of an identifier
|
||||
{"~", IdentifierToken},
|
||||
{"||", IdentifierToken},
|
||||
}
|
||||
for _, v := range testcases {
|
||||
l := &Lexer{s: v.s, pos: 0}
|
||||
token, lit := l.Lex()
|
||||
if token != v.t {
|
||||
t.Errorf("Got %d it should be %d for '%s'", token, v.t, v.s)
|
||||
}
|
||||
if v.t != ErrorToken && lit != v.s {
|
||||
t.Errorf("Got '%s' it should be '%s'", lit, v.s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func min(l, r int) (m int) {
|
||||
m = r
|
||||
if l < r {
|
||||
m = l
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func TestLexerSequence(t *testing.T) {
|
||||
testcases := []struct {
|
||||
s string
|
||||
t []Token
|
||||
}{
|
||||
{"key in ( value )", []Token{IdentifierToken, InToken, OpenParToken, IdentifierToken, ClosedParToken}},
|
||||
{"key notin ( value )", []Token{IdentifierToken, NotInToken, OpenParToken, IdentifierToken, ClosedParToken}},
|
||||
{"key in ( value1, value2 )", []Token{IdentifierToken, InToken, OpenParToken, IdentifierToken, CommaToken, IdentifierToken, ClosedParToken}},
|
||||
{"key", []Token{IdentifierToken}},
|
||||
{"!key", []Token{DoesNotExistToken, IdentifierToken}},
|
||||
{"()", []Token{OpenParToken, ClosedParToken}},
|
||||
{"x in (),y", []Token{IdentifierToken, InToken, OpenParToken, ClosedParToken, CommaToken, IdentifierToken}},
|
||||
{"== != (), = notin", []Token{DoubleEqualsToken, NotEqualsToken, OpenParToken, ClosedParToken, CommaToken, EqualsToken, NotInToken}},
|
||||
{"key>2", []Token{IdentifierToken, GreaterThanToken, IdentifierToken}},
|
||||
{"key<1", []Token{IdentifierToken, LessThanToken, IdentifierToken}},
|
||||
}
|
||||
for _, v := range testcases {
|
||||
var literals []string
|
||||
var tokens []Token
|
||||
l := &Lexer{s: v.s, pos: 0}
|
||||
for {
|
||||
token, lit := l.Lex()
|
||||
if token == EndOfStringToken {
|
||||
break
|
||||
}
|
||||
tokens = append(tokens, token)
|
||||
literals = append(literals, lit)
|
||||
}
|
||||
if len(tokens) != len(v.t) {
|
||||
t.Errorf("Bad number of tokens for '%s %d, %d", v.s, len(tokens), len(v.t))
|
||||
}
|
||||
for i := 0; i < min(len(tokens), len(v.t)); i++ {
|
||||
if tokens[i] != v.t[i] {
|
||||
t.Errorf("Test '%s': Mismatching in token type found '%v' it should be '%v'", v.s, tokens[i], v.t[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestParserLookahead(t *testing.T) {
|
||||
testcases := []struct {
|
||||
s string
|
||||
t []Token
|
||||
}{
|
||||
{"key in ( value )", []Token{IdentifierToken, InToken, OpenParToken, IdentifierToken, ClosedParToken, EndOfStringToken}},
|
||||
{"key notin ( value )", []Token{IdentifierToken, NotInToken, OpenParToken, IdentifierToken, ClosedParToken, EndOfStringToken}},
|
||||
{"key in ( value1, value2 )", []Token{IdentifierToken, InToken, OpenParToken, IdentifierToken, CommaToken, IdentifierToken, ClosedParToken, EndOfStringToken}},
|
||||
{"key", []Token{IdentifierToken, EndOfStringToken}},
|
||||
{"!key", []Token{DoesNotExistToken, IdentifierToken, EndOfStringToken}},
|
||||
{"()", []Token{OpenParToken, ClosedParToken, EndOfStringToken}},
|
||||
{"", []Token{EndOfStringToken}},
|
||||
{"x in (),y", []Token{IdentifierToken, InToken, OpenParToken, ClosedParToken, CommaToken, IdentifierToken, EndOfStringToken}},
|
||||
{"== != (), = notin", []Token{DoubleEqualsToken, NotEqualsToken, OpenParToken, ClosedParToken, CommaToken, EqualsToken, NotInToken, EndOfStringToken}},
|
||||
{"key>2", []Token{IdentifierToken, GreaterThanToken, IdentifierToken, EndOfStringToken}},
|
||||
{"key<1", []Token{IdentifierToken, LessThanToken, IdentifierToken, EndOfStringToken}},
|
||||
}
|
||||
for _, v := range testcases {
|
||||
p := &Parser{l: &Lexer{s: v.s, pos: 0}, position: 0}
|
||||
p.scan()
|
||||
if len(p.scannedItems) != len(v.t) {
|
||||
t.Errorf("Expected %d items found %d", len(v.t), len(p.scannedItems))
|
||||
}
|
||||
for {
|
||||
token, lit := p.lookahead(KeyAndOperator)
|
||||
|
||||
token2, lit2 := p.consume(KeyAndOperator)
|
||||
if token == EndOfStringToken {
|
||||
break
|
||||
}
|
||||
if token != token2 || lit != lit2 {
|
||||
t.Errorf("Bad values")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequirementConstructor(t *testing.T) {
|
||||
requirementConstructorTests := []struct {
|
||||
Key string
|
||||
Op selection.Operator
|
||||
Vals sets.String
|
||||
Success bool
|
||||
}{
|
||||
{"x", selection.In, nil, false},
|
||||
{"x", selection.NotIn, sets.NewString(), false},
|
||||
{"x", selection.In, sets.NewString("foo"), true},
|
||||
{"x", selection.NotIn, sets.NewString("foo"), true},
|
||||
{"x", selection.Exists, nil, true},
|
||||
{"x", selection.DoesNotExist, nil, true},
|
||||
{"1foo", selection.In, sets.NewString("bar"), true},
|
||||
{"1234", selection.In, sets.NewString("bar"), true},
|
||||
{"y", selection.GreaterThan, sets.NewString("1"), true},
|
||||
{"z", selection.LessThan, sets.NewString("6"), true},
|
||||
{"foo", selection.GreaterThan, sets.NewString("bar"), false},
|
||||
{"barz", selection.LessThan, sets.NewString("blah"), false},
|
||||
{strings.Repeat("a", 254), selection.Exists, nil, false}, //breaks DNS rule that len(key) <= 253
|
||||
}
|
||||
for _, rc := range requirementConstructorTests {
|
||||
if _, err := NewRequirement(rc.Key, rc.Op, rc.Vals.List()); err == nil && !rc.Success {
|
||||
t.Errorf("expected error with key:%#v op:%v vals:%v, got no error", rc.Key, rc.Op, rc.Vals)
|
||||
} else if err != nil && rc.Success {
|
||||
t.Errorf("expected no error with key:%#v op:%v vals:%v, got:%v", rc.Key, rc.Op, rc.Vals, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestToString(t *testing.T) {
|
||||
var req Requirement
|
||||
toStringTests := []struct {
|
||||
In *internalSelector
|
||||
Out string
|
||||
Valid bool
|
||||
}{
|
||||
|
||||
{&internalSelector{
|
||||
getRequirement("x", selection.In, sets.NewString("abc", "def"), t),
|
||||
getRequirement("y", selection.NotIn, sets.NewString("jkl"), t),
|
||||
getRequirement("z", selection.Exists, nil, t)},
|
||||
"x in (abc,def),y notin (jkl),z", true},
|
||||
{&internalSelector{
|
||||
getRequirement("x", selection.NotIn, sets.NewString("abc", "def"), t),
|
||||
getRequirement("y", selection.NotEquals, sets.NewString("jkl"), t),
|
||||
getRequirement("z", selection.DoesNotExist, nil, t)},
|
||||
"x notin (abc,def),y!=jkl,!z", true},
|
||||
{&internalSelector{
|
||||
getRequirement("x", selection.In, sets.NewString("abc", "def"), t),
|
||||
req}, // adding empty req for the trailing ','
|
||||
"x in (abc,def),", false},
|
||||
{&internalSelector{
|
||||
getRequirement("x", selection.NotIn, sets.NewString("abc"), t),
|
||||
getRequirement("y", selection.In, sets.NewString("jkl", "mno"), t),
|
||||
getRequirement("z", selection.NotIn, sets.NewString(""), t)},
|
||||
"x notin (abc),y in (jkl,mno),z notin ()", true},
|
||||
{&internalSelector{
|
||||
getRequirement("x", selection.Equals, sets.NewString("abc"), t),
|
||||
getRequirement("y", selection.DoubleEquals, sets.NewString("jkl"), t),
|
||||
getRequirement("z", selection.NotEquals, sets.NewString("a"), t),
|
||||
getRequirement("z", selection.Exists, nil, t)},
|
||||
"x=abc,y==jkl,z!=a,z", true},
|
||||
{&internalSelector{
|
||||
getRequirement("x", selection.GreaterThan, sets.NewString("2"), t),
|
||||
getRequirement("y", selection.LessThan, sets.NewString("8"), t),
|
||||
getRequirement("z", selection.Exists, nil, t)},
|
||||
"x>2,y<8,z", true},
|
||||
}
|
||||
for _, ts := range toStringTests {
|
||||
if out := ts.In.String(); out == "" && ts.Valid {
|
||||
t.Errorf("%#v.String() => '%v' expected no error", ts.In, out)
|
||||
} else if out != ts.Out {
|
||||
t.Errorf("%#v.String() => '%v' want '%v'", ts.In, out, ts.Out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequirementSelectorMatching(t *testing.T) {
|
||||
var req Requirement
|
||||
labelSelectorMatchingTests := []struct {
|
||||
Set Set
|
||||
Sel Selector
|
||||
Match bool
|
||||
}{
|
||||
{Set{"x": "foo", "y": "baz"}, &internalSelector{
|
||||
req,
|
||||
}, false},
|
||||
{Set{"x": "foo", "y": "baz"}, &internalSelector{
|
||||
getRequirement("x", selection.In, sets.NewString("foo"), t),
|
||||
getRequirement("y", selection.NotIn, sets.NewString("alpha"), t),
|
||||
}, true},
|
||||
{Set{"x": "foo", "y": "baz"}, &internalSelector{
|
||||
getRequirement("x", selection.In, sets.NewString("foo"), t),
|
||||
getRequirement("y", selection.In, sets.NewString("alpha"), t),
|
||||
}, false},
|
||||
{Set{"y": ""}, &internalSelector{
|
||||
getRequirement("x", selection.NotIn, sets.NewString(""), t),
|
||||
getRequirement("y", selection.Exists, nil, t),
|
||||
}, true},
|
||||
{Set{"y": ""}, &internalSelector{
|
||||
getRequirement("x", selection.DoesNotExist, nil, t),
|
||||
getRequirement("y", selection.Exists, nil, t),
|
||||
}, true},
|
||||
{Set{"y": ""}, &internalSelector{
|
||||
getRequirement("x", selection.NotIn, sets.NewString(""), t),
|
||||
getRequirement("y", selection.DoesNotExist, nil, t),
|
||||
}, false},
|
||||
{Set{"y": "baz"}, &internalSelector{
|
||||
getRequirement("x", selection.In, sets.NewString(""), t),
|
||||
}, false},
|
||||
{Set{"z": "2"}, &internalSelector{
|
||||
getRequirement("z", selection.GreaterThan, sets.NewString("1"), t),
|
||||
}, true},
|
||||
{Set{"z": "v2"}, &internalSelector{
|
||||
getRequirement("z", selection.GreaterThan, sets.NewString("1"), t),
|
||||
}, false},
|
||||
}
|
||||
for _, lsm := range labelSelectorMatchingTests {
|
||||
if match := lsm.Sel.Matches(lsm.Set); match != lsm.Match {
|
||||
t.Errorf("%+v.Matches(%#v) => %v, want %v", lsm.Sel, lsm.Set, match, lsm.Match)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetSelectorParser(t *testing.T) {
|
||||
setSelectorParserTests := []struct {
|
||||
In string
|
||||
Out Selector
|
||||
Match bool
|
||||
Valid bool
|
||||
}{
|
||||
{"", NewSelector(), true, true},
|
||||
{"\rx", internalSelector{
|
||||
getRequirement("x", selection.Exists, nil, t),
|
||||
}, true, true},
|
||||
{"this-is-a-dns.domain.com/key-with-dash", internalSelector{
|
||||
getRequirement("this-is-a-dns.domain.com/key-with-dash", selection.Exists, nil, t),
|
||||
}, true, true},
|
||||
{"this-is-another-dns.domain.com/key-with-dash in (so,what)", internalSelector{
|
||||
getRequirement("this-is-another-dns.domain.com/key-with-dash", selection.In, sets.NewString("so", "what"), t),
|
||||
}, true, true},
|
||||
{"0.1.2.domain/99 notin (10.10.100.1, tick.tack.clock)", internalSelector{
|
||||
getRequirement("0.1.2.domain/99", selection.NotIn, sets.NewString("10.10.100.1", "tick.tack.clock"), t),
|
||||
}, true, true},
|
||||
{"foo in (abc)", internalSelector{
|
||||
getRequirement("foo", selection.In, sets.NewString("abc"), t),
|
||||
}, true, true},
|
||||
{"x notin\n (abc)", internalSelector{
|
||||
getRequirement("x", selection.NotIn, sets.NewString("abc"), t),
|
||||
}, true, true},
|
||||
{"x notin \t (abc,def)", internalSelector{
|
||||
getRequirement("x", selection.NotIn, sets.NewString("abc", "def"), t),
|
||||
}, true, true},
|
||||
{"x in (abc,def)", internalSelector{
|
||||
getRequirement("x", selection.In, sets.NewString("abc", "def"), t),
|
||||
}, true, true},
|
||||
{"x in (abc,)", internalSelector{
|
||||
getRequirement("x", selection.In, sets.NewString("abc", ""), t),
|
||||
}, true, true},
|
||||
{"x in ()", internalSelector{
|
||||
getRequirement("x", selection.In, sets.NewString(""), t),
|
||||
}, true, true},
|
||||
{"x notin (abc,,def),bar,z in (),w", internalSelector{
|
||||
getRequirement("bar", selection.Exists, nil, t),
|
||||
getRequirement("w", selection.Exists, nil, t),
|
||||
getRequirement("x", selection.NotIn, sets.NewString("abc", "", "def"), t),
|
||||
getRequirement("z", selection.In, sets.NewString(""), t),
|
||||
}, true, true},
|
||||
{"x,y in (a)", internalSelector{
|
||||
getRequirement("y", selection.In, sets.NewString("a"), t),
|
||||
getRequirement("x", selection.Exists, nil, t),
|
||||
}, false, true},
|
||||
{"x=a", internalSelector{
|
||||
getRequirement("x", selection.Equals, sets.NewString("a"), t),
|
||||
}, true, true},
|
||||
{"x>1", internalSelector{
|
||||
getRequirement("x", selection.GreaterThan, sets.NewString("1"), t),
|
||||
}, true, true},
|
||||
{"x<7", internalSelector{
|
||||
getRequirement("x", selection.LessThan, sets.NewString("7"), t),
|
||||
}, true, true},
|
||||
{"x=a,y!=b", internalSelector{
|
||||
getRequirement("x", selection.Equals, sets.NewString("a"), t),
|
||||
getRequirement("y", selection.NotEquals, sets.NewString("b"), t),
|
||||
}, true, true},
|
||||
{"x=a,y!=b,z in (h,i,j)", internalSelector{
|
||||
getRequirement("x", selection.Equals, sets.NewString("a"), t),
|
||||
getRequirement("y", selection.NotEquals, sets.NewString("b"), t),
|
||||
getRequirement("z", selection.In, sets.NewString("h", "i", "j"), t),
|
||||
}, true, true},
|
||||
{"x=a||y=b", internalSelector{}, false, false},
|
||||
{"x,,y", nil, true, false},
|
||||
{",x,y", nil, true, false},
|
||||
{"x nott in (y)", nil, true, false},
|
||||
{"x notin ( )", internalSelector{
|
||||
getRequirement("x", selection.NotIn, sets.NewString(""), t),
|
||||
}, true, true},
|
||||
{"x notin (, a)", internalSelector{
|
||||
getRequirement("x", selection.NotIn, sets.NewString("", "a"), t),
|
||||
}, true, true},
|
||||
{"a in (xyz),", nil, true, false},
|
||||
{"a in (xyz)b notin ()", nil, true, false},
|
||||
{"a ", internalSelector{
|
||||
getRequirement("a", selection.Exists, nil, t),
|
||||
}, true, true},
|
||||
{"a in (x,y,notin, z,in)", internalSelector{
|
||||
getRequirement("a", selection.In, sets.NewString("in", "notin", "x", "y", "z"), t),
|
||||
}, true, true}, // operator 'in' inside list of identifiers
|
||||
{"a in (xyz abc)", nil, false, false}, // no comma
|
||||
{"a notin(", nil, true, false}, // bad formed
|
||||
{"a (", nil, false, false}, // cpar
|
||||
{"(", nil, false, false}, // opar
|
||||
}
|
||||
|
||||
for _, ssp := range setSelectorParserTests {
|
||||
if sel, err := Parse(ssp.In); err != nil && ssp.Valid {
|
||||
t.Errorf("Parse(%s) => %v expected no error", ssp.In, err)
|
||||
} else if err == nil && !ssp.Valid {
|
||||
t.Errorf("Parse(%s) => %+v expected error", ssp.In, sel)
|
||||
} else if ssp.Match && !reflect.DeepEqual(sel, ssp.Out) {
|
||||
t.Errorf("Parse(%s) => parse output '%#v' doesn't match '%#v' expected match", ssp.In, sel, ssp.Out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getRequirement(key string, op selection.Operator, vals sets.String, t *testing.T) Requirement {
|
||||
req, err := NewRequirement(key, op, vals.List())
|
||||
if err != nil {
|
||||
t.Errorf("NewRequirement(%v, %v, %v) resulted in error:%v", key, op, vals, err)
|
||||
return Requirement{}
|
||||
}
|
||||
return *req
|
||||
}
|
||||
|
||||
func TestAdd(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
sel Selector
|
||||
key string
|
||||
operator selection.Operator
|
||||
values []string
|
||||
refSelector Selector
|
||||
}{
|
||||
{
|
||||
"keyInOperator",
|
||||
internalSelector{},
|
||||
"key",
|
||||
selection.In,
|
||||
[]string{"value"},
|
||||
internalSelector{Requirement{"key", selection.In, []string{"value"}}},
|
||||
},
|
||||
{
|
||||
"keyEqualsOperator",
|
||||
internalSelector{Requirement{"key", selection.In, []string{"value"}}},
|
||||
"key2",
|
||||
selection.Equals,
|
||||
[]string{"value2"},
|
||||
internalSelector{
|
||||
Requirement{"key", selection.In, []string{"value"}},
|
||||
Requirement{"key2", selection.Equals, []string{"value2"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, ts := range testCases {
|
||||
req, err := NewRequirement(ts.key, ts.operator, ts.values)
|
||||
if err != nil {
|
||||
t.Errorf("%s - Unable to create labels.Requirement", ts.name)
|
||||
}
|
||||
ts.sel = ts.sel.Add(*req)
|
||||
if !reflect.DeepEqual(ts.sel, ts.refSelector) {
|
||||
t.Errorf("%s - Expected %v found %v", ts.name, ts.refSelector, ts.sel)
|
||||
}
|
||||
}
|
||||
}
|
||||
98
vendor/k8s.io/apimachinery/pkg/runtime/BUILD
generated
vendored
98
vendor/k8s.io/apimachinery/pkg/runtime/BUILD
generated
vendored
|
|
@ -1,98 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["swagger_doc_generator_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"codec.go",
|
||||
"codec_check.go",
|
||||
"conversion.go",
|
||||
"converter.go",
|
||||
"doc.go",
|
||||
"embedded.go",
|
||||
"error.go",
|
||||
"extension.go",
|
||||
"generated.pb.go",
|
||||
"helper.go",
|
||||
"interfaces.go",
|
||||
"register.go",
|
||||
"scheme.go",
|
||||
"scheme_builder.go",
|
||||
"swagger_doc_generator.go",
|
||||
"types.go",
|
||||
"types_proto.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/runtime",
|
||||
deps = [
|
||||
"//vendor/github.com/gogo/protobuf/proto:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion/queryparams:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/json:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_xtest",
|
||||
srcs = [
|
||||
"conversion_test.go",
|
||||
"converter_test.go",
|
||||
"embedded_test.go",
|
||||
"extension_test.go",
|
||||
"scheme_test.go",
|
||||
],
|
||||
deps = [
|
||||
"//vendor/github.com/google/gofuzz:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/require:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/testing:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/json:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:all-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:all-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/testing:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "go_default_library_protos",
|
||||
srcs = ["generated.proto"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
115
vendor/k8s.io/apimachinery/pkg/runtime/conversion_test.go
generated
vendored
115
vendor/k8s.io/apimachinery/pkg/runtime/conversion_test.go
generated
vendored
|
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 runtime_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
runtimetesting "k8s.io/apimachinery/pkg/runtime/testing"
|
||||
)
|
||||
|
||||
func TestStringMapConversion(t *testing.T) {
|
||||
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Group: "test.group", Version: "external"}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.Log(t)
|
||||
scheme.AddKnownTypeWithName(internalGV.WithKind("Complex"), &runtimetesting.InternalComplex{})
|
||||
scheme.AddKnownTypeWithName(externalGV.WithKind("Complex"), &runtimetesting.ExternalComplex{})
|
||||
|
||||
testCases := map[string]struct {
|
||||
input map[string][]string
|
||||
errFn func(error) bool
|
||||
expected runtime.Object
|
||||
}{
|
||||
"ignores omitempty": {
|
||||
input: map[string][]string{
|
||||
"String": {"not_used"},
|
||||
"string": {"value"},
|
||||
"int": {"1"},
|
||||
"Integer64": {"2"},
|
||||
},
|
||||
expected: &runtimetesting.ExternalComplex{String: "value", Integer: 1},
|
||||
},
|
||||
"returns error on bad int": {
|
||||
input: map[string][]string{
|
||||
"int": {"a"},
|
||||
},
|
||||
errFn: func(err error) bool { return err != nil },
|
||||
expected: &runtimetesting.ExternalComplex{},
|
||||
},
|
||||
"parses int64": {
|
||||
input: map[string][]string{
|
||||
"Int64": {"-1"},
|
||||
},
|
||||
expected: &runtimetesting.ExternalComplex{Int64: -1},
|
||||
},
|
||||
"returns error on bad int64": {
|
||||
input: map[string][]string{
|
||||
"Int64": {"a"},
|
||||
},
|
||||
errFn: func(err error) bool { return err != nil },
|
||||
expected: &runtimetesting.ExternalComplex{},
|
||||
},
|
||||
"parses boolean true": {
|
||||
input: map[string][]string{
|
||||
"bool": {"true"},
|
||||
},
|
||||
expected: &runtimetesting.ExternalComplex{Bool: true},
|
||||
},
|
||||
"parses boolean any value": {
|
||||
input: map[string][]string{
|
||||
"bool": {"foo"},
|
||||
},
|
||||
expected: &runtimetesting.ExternalComplex{Bool: true},
|
||||
},
|
||||
"parses boolean false": {
|
||||
input: map[string][]string{
|
||||
"bool": {"false"},
|
||||
},
|
||||
expected: &runtimetesting.ExternalComplex{Bool: false},
|
||||
},
|
||||
"parses boolean empty value": {
|
||||
input: map[string][]string{
|
||||
"bool": {""},
|
||||
},
|
||||
expected: &runtimetesting.ExternalComplex{Bool: true},
|
||||
},
|
||||
"parses boolean no value": {
|
||||
input: map[string][]string{
|
||||
"bool": {},
|
||||
},
|
||||
expected: &runtimetesting.ExternalComplex{Bool: false},
|
||||
},
|
||||
}
|
||||
|
||||
for k, tc := range testCases {
|
||||
out := &runtimetesting.ExternalComplex{}
|
||||
if err := scheme.Convert(&tc.input, out, nil); (tc.errFn == nil && err != nil) || (tc.errFn != nil && !tc.errFn(err)) {
|
||||
t.Errorf("%s: unexpected error: %v", k, err)
|
||||
continue
|
||||
} else if err != nil {
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(out, tc.expected) {
|
||||
t.Errorf("%s: unexpected output: %#v", k, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
597
vendor/k8s.io/apimachinery/pkg/runtime/converter_test.go
generated
vendored
597
vendor/k8s.io/apimachinery/pkg/runtime/converter_test.go
generated
vendored
|
|
@ -1,597 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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.
|
||||
*/
|
||||
|
||||
// These tests are in a separate package to break cyclic dependency in tests.
|
||||
// Unstructured type depends on unstructured converter package but we want to test how the converter handles
|
||||
// the Unstructured type so we need to import both.
|
||||
|
||||
package runtime_test
|
||||
|
||||
import (
|
||||
encodingjson "encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var simpleEquality = conversion.EqualitiesOrDie(
|
||||
func(a, b time.Time) bool {
|
||||
return a.UTC() == b.UTC()
|
||||
},
|
||||
)
|
||||
|
||||
// Definte a number of test types.
|
||||
type A struct {
|
||||
A int `json:"aa,omitempty"`
|
||||
B string `json:"ab,omitempty"`
|
||||
C bool `json:"ac,omitempty"`
|
||||
}
|
||||
|
||||
type B struct {
|
||||
A A `json:"ba"`
|
||||
B string `json:"bb"`
|
||||
C map[string]string `json:"bc"`
|
||||
D []string `json:"bd"`
|
||||
}
|
||||
|
||||
type C struct {
|
||||
A []A `json:"ca"`
|
||||
B `json:",inline"`
|
||||
C string `json:"cc"`
|
||||
D *int64 `json:"cd"`
|
||||
E map[string]int `json:"ce"`
|
||||
F []bool `json:"cf"`
|
||||
G []int `json:"cg"`
|
||||
H float32 `json:"ch"`
|
||||
I []interface{} `json:"ci"`
|
||||
}
|
||||
|
||||
type D struct {
|
||||
A []interface{} `json:"da"`
|
||||
}
|
||||
|
||||
type E struct {
|
||||
A interface{} `json:"ea"`
|
||||
}
|
||||
|
||||
type F struct {
|
||||
A string `json:"fa"`
|
||||
B map[string]string `json:"fb"`
|
||||
C []A `json:"fc"`
|
||||
D int `json:"fd"`
|
||||
E float32 `json:"fe"`
|
||||
F []string `json:"ff"`
|
||||
G []int `json:"fg"`
|
||||
H []bool `json:"fh"`
|
||||
I []float32 `json:"fi"`
|
||||
}
|
||||
|
||||
type G struct {
|
||||
CustomValue1 CustomValue `json:"customValue1"`
|
||||
CustomValue2 *CustomValue `json:"customValue2"`
|
||||
CustomPointer1 CustomPointer `json:"customPointer1"`
|
||||
CustomPointer2 *CustomPointer `json:"customPointer2"`
|
||||
}
|
||||
|
||||
type CustomValue struct {
|
||||
data []byte
|
||||
}
|
||||
|
||||
// MarshalJSON has a value receiver on this type.
|
||||
func (c CustomValue) MarshalJSON() ([]byte, error) {
|
||||
return c.data, nil
|
||||
}
|
||||
|
||||
type CustomPointer struct {
|
||||
data []byte
|
||||
}
|
||||
|
||||
// MarshalJSON has a pointer receiver on this type.
|
||||
func (c *CustomPointer) MarshalJSON() ([]byte, error) {
|
||||
return c.data, nil
|
||||
}
|
||||
|
||||
func doRoundTrip(t *testing.T, item interface{}) {
|
||||
data, err := json.Marshal(item)
|
||||
if err != nil {
|
||||
t.Errorf("Error when marshaling object: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
unstr := make(map[string]interface{})
|
||||
err = json.Unmarshal(data, &unstr)
|
||||
if err != nil {
|
||||
t.Errorf("Error when unmarshaling to unstructured: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
data, err = json.Marshal(unstr)
|
||||
if err != nil {
|
||||
t.Errorf("Error when marshaling unstructured: %v", err)
|
||||
return
|
||||
}
|
||||
unmarshalledObj := reflect.New(reflect.TypeOf(item).Elem()).Interface()
|
||||
err = json.Unmarshal(data, unmarshalledObj)
|
||||
if err != nil {
|
||||
t.Errorf("Error when unmarshaling to object: %v", err)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(item, unmarshalledObj) {
|
||||
t.Errorf("Object changed during JSON operations, diff: %v", diff.ObjectReflectDiff(item, unmarshalledObj))
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: should be using mismatch detection but fails due to another error
|
||||
newUnstr, err := runtime.DefaultUnstructuredConverter.ToUnstructured(item)
|
||||
if err != nil {
|
||||
t.Errorf("ToUnstructured failed: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
newObj := reflect.New(reflect.TypeOf(item).Elem()).Interface()
|
||||
err = runtime.NewTestUnstructuredConverter(simpleEquality).FromUnstructured(newUnstr, newObj)
|
||||
if err != nil {
|
||||
t.Errorf("FromUnstructured failed: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(item, newObj) {
|
||||
t.Errorf("Object changed, diff: %v", diff.ObjectReflectDiff(item, newObj))
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoundTrip(t *testing.T) {
|
||||
intVal := int64(42)
|
||||
testCases := []struct {
|
||||
obj interface{}
|
||||
}{
|
||||
{
|
||||
obj: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{
|
||||
"kind": "List",
|
||||
},
|
||||
// Not testing a list with nil Items because items is a non-optional field and hence
|
||||
// is always marshaled into an empty array which is not equal to nil when unmarshalled and will fail.
|
||||
// That is expected.
|
||||
Items: []unstructured.Unstructured{},
|
||||
},
|
||||
},
|
||||
{
|
||||
obj: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{
|
||||
"kind": "List",
|
||||
},
|
||||
Items: []unstructured.Unstructured{
|
||||
{
|
||||
Object: map[string]interface{}{
|
||||
"kind": "Pod",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
obj: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"kind": "Pod",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
obj: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Foo",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "foo1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// This (among others) tests nil map, slice and pointer.
|
||||
obj: &C{
|
||||
C: "ccc",
|
||||
},
|
||||
},
|
||||
{
|
||||
// This (among others) tests empty map and slice.
|
||||
obj: &C{
|
||||
A: []A{},
|
||||
C: "ccc",
|
||||
E: map[string]int{},
|
||||
I: []interface{}{},
|
||||
},
|
||||
},
|
||||
{
|
||||
obj: &C{
|
||||
A: []A{
|
||||
{
|
||||
A: 1,
|
||||
B: "11",
|
||||
C: true,
|
||||
},
|
||||
{
|
||||
A: 2,
|
||||
B: "22",
|
||||
C: false,
|
||||
},
|
||||
},
|
||||
B: B{
|
||||
A: A{
|
||||
A: 3,
|
||||
B: "33",
|
||||
},
|
||||
B: "bbb",
|
||||
C: map[string]string{
|
||||
"k1": "v1",
|
||||
"k2": "v2",
|
||||
},
|
||||
D: []string{"s1", "s2"},
|
||||
},
|
||||
C: "ccc",
|
||||
D: &intVal,
|
||||
E: map[string]int{
|
||||
"k1": 1,
|
||||
"k2": 2,
|
||||
},
|
||||
F: []bool{true, false, false},
|
||||
G: []int{1, 2, 5},
|
||||
H: 3.3,
|
||||
I: []interface{}{nil, nil, nil},
|
||||
},
|
||||
},
|
||||
{
|
||||
// Test slice of interface{} with empty slices.
|
||||
obj: &D{
|
||||
A: []interface{}{[]interface{}{}, []interface{}{}},
|
||||
},
|
||||
},
|
||||
{
|
||||
// Test slice of interface{} with different values.
|
||||
obj: &D{
|
||||
A: []interface{}{3.0, "3.0", nil},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i := range testCases {
|
||||
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
|
||||
doRoundTrip(t, testCases[i].obj)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Verifies that:
|
||||
// 1) serialized json -> object
|
||||
// 2) serialized json -> map[string]interface{} -> object
|
||||
// produces the same object.
|
||||
func doUnrecognized(t *testing.T, jsonData string, item interface{}, expectedErr error) {
|
||||
unmarshalledObj := reflect.New(reflect.TypeOf(item).Elem()).Interface()
|
||||
err := json.Unmarshal([]byte(jsonData), unmarshalledObj)
|
||||
if (err != nil) != (expectedErr != nil) {
|
||||
t.Errorf("Unexpected error when unmarshaling to object: %v, expected: %v", err, expectedErr)
|
||||
return
|
||||
}
|
||||
|
||||
unstr := make(map[string]interface{})
|
||||
err = json.Unmarshal([]byte(jsonData), &unstr)
|
||||
if err != nil {
|
||||
t.Errorf("Error when unmarshaling to unstructured: %v", err)
|
||||
return
|
||||
}
|
||||
newObj := reflect.New(reflect.TypeOf(item).Elem()).Interface()
|
||||
err = runtime.NewTestUnstructuredConverter(simpleEquality).FromUnstructured(unstr, newObj)
|
||||
if (err != nil) != (expectedErr != nil) {
|
||||
t.Errorf("Unexpected error in FromUnstructured: %v, expected: %v", err, expectedErr)
|
||||
}
|
||||
|
||||
if expectedErr == nil && !reflect.DeepEqual(unmarshalledObj, newObj) {
|
||||
t.Errorf("Object changed, diff: %v", diff.ObjectReflectDiff(unmarshalledObj, newObj))
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnrecognized(t *testing.T) {
|
||||
testCases := []struct {
|
||||
data string
|
||||
obj interface{}
|
||||
err error
|
||||
}{
|
||||
{
|
||||
data: "{\"da\":[3.0,\"3.0\",null]}",
|
||||
obj: &D{},
|
||||
},
|
||||
{
|
||||
data: "{\"ea\":[3.0,\"3.0\",null]}",
|
||||
obj: &E{},
|
||||
},
|
||||
{
|
||||
data: "{\"ea\":[null,null,null]}",
|
||||
obj: &E{},
|
||||
},
|
||||
{
|
||||
data: "{\"ea\":[[],[null]]}",
|
||||
obj: &E{},
|
||||
},
|
||||
{
|
||||
data: "{\"ea\":{\"a\":[],\"b\":null}}",
|
||||
obj: &E{},
|
||||
},
|
||||
{
|
||||
data: "{\"fa\":\"fa\",\"fb\":{\"a\":\"a\"}}",
|
||||
obj: &F{},
|
||||
},
|
||||
{
|
||||
data: "{\"fa\":\"fa\",\"fb\":{\"a\":null}}",
|
||||
obj: &F{},
|
||||
},
|
||||
{
|
||||
data: "{\"fc\":[null]}",
|
||||
obj: &F{},
|
||||
},
|
||||
{
|
||||
data: "{\"fc\":[{\"aa\":123,\"ab\":\"bbb\"}]}",
|
||||
obj: &F{},
|
||||
},
|
||||
{
|
||||
// Only unknown fields
|
||||
data: "{\"fx\":[{\"aa\":123,\"ab\":\"bbb\"}],\"fz\":123}",
|
||||
obj: &F{},
|
||||
},
|
||||
{
|
||||
data: "{\"fc\":[{\"aa\":\"aaa\",\"ab\":\"bbb\"}]}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal string into Go value of type int"),
|
||||
},
|
||||
{
|
||||
data: "{\"fd\":123,\"fe\":3.5}",
|
||||
obj: &F{},
|
||||
},
|
||||
{
|
||||
data: "{\"ff\":[\"abc\"],\"fg\":[123],\"fh\":[true,false]}",
|
||||
obj: &F{},
|
||||
},
|
||||
{
|
||||
// Invalid string data
|
||||
data: "{\"fa\":123}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal number into Go value of type string"),
|
||||
},
|
||||
{
|
||||
// Invalid string data
|
||||
data: "{\"fa\":13.5}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal number into Go value of type string"),
|
||||
},
|
||||
{
|
||||
// Invalid string data
|
||||
data: "{\"fa\":true}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal bool into Go value of type string"),
|
||||
},
|
||||
{
|
||||
// Invalid []string data
|
||||
data: "{\"ff\":123}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal number into Go value of type []string"),
|
||||
},
|
||||
{
|
||||
// Invalid []string data
|
||||
data: "{\"ff\":3.5}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal number into Go value of type []string"),
|
||||
},
|
||||
{
|
||||
// Invalid []string data
|
||||
data: "{\"ff\":[123,345]}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal number into Go value of type string"),
|
||||
},
|
||||
{
|
||||
// Invalid []int data
|
||||
data: "{\"fg\":123}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal number into Go value of type []int"),
|
||||
},
|
||||
{
|
||||
// Invalid []int data
|
||||
data: "{\"fg\":\"abc\"}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal string into Go value of type []int"),
|
||||
},
|
||||
{
|
||||
// Invalid []int data
|
||||
data: "{\"fg\":[\"abc\"]}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal string into Go value of type int"),
|
||||
},
|
||||
{
|
||||
// Invalid []int data
|
||||
data: "{\"fg\":[3.5]}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal number 3.5 into Go value of type int"),
|
||||
},
|
||||
{
|
||||
// Invalid []int data
|
||||
data: "{\"fg\":[true,false]}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal number 3.5 into Go value of type int"),
|
||||
},
|
||||
{
|
||||
// Invalid []bool data
|
||||
data: "{\"fh\":123}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal number into Go value of type []bool"),
|
||||
},
|
||||
{
|
||||
// Invalid []bool data
|
||||
data: "{\"fh\":\"abc\"}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal string into Go value of type []bool"),
|
||||
},
|
||||
{
|
||||
// Invalid []bool data
|
||||
data: "{\"fh\":[\"abc\"]}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal string into Go value of type bool"),
|
||||
},
|
||||
{
|
||||
// Invalid []bool data
|
||||
data: "{\"fh\":[3.5]}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal number into Go value of type bool"),
|
||||
},
|
||||
{
|
||||
// Invalid []bool data
|
||||
data: "{\"fh\":[123]}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal number into Go value of type bool"),
|
||||
},
|
||||
{
|
||||
// Invalid []float data
|
||||
data: "{\"fi\":123}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal number into Go value of type []float32"),
|
||||
},
|
||||
{
|
||||
// Invalid []float data
|
||||
data: "{\"fi\":\"abc\"}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal string into Go value of type []float32"),
|
||||
},
|
||||
{
|
||||
// Invalid []float data
|
||||
data: "{\"fi\":[\"abc\"]}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal string into Go value of type float32"),
|
||||
},
|
||||
{
|
||||
// Invalid []float data
|
||||
data: "{\"fi\":[true]}",
|
||||
obj: &F{},
|
||||
err: fmt.Errorf("json: cannot unmarshal bool into Go value of type float32"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.data, func(t *testing.T) {
|
||||
doUnrecognized(t, tc.data, tc.obj, tc.err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeepCopyJSON(t *testing.T) {
|
||||
src := map[string]interface{}{
|
||||
"a": nil,
|
||||
"b": int64(123),
|
||||
"c": map[string]interface{}{
|
||||
"a": "b",
|
||||
},
|
||||
"d": []interface{}{
|
||||
int64(1), int64(2),
|
||||
},
|
||||
"e": "estr",
|
||||
"f": true,
|
||||
"g": encodingjson.Number("123"),
|
||||
}
|
||||
deepCopy := runtime.DeepCopyJSON(src)
|
||||
assert.Equal(t, src, deepCopy)
|
||||
}
|
||||
|
||||
func TestFloatIntConversion(t *testing.T) {
|
||||
unstr := map[string]interface{}{"fd": float64(3)}
|
||||
|
||||
var obj F
|
||||
if err := runtime.NewTestUnstructuredConverter(simpleEquality).FromUnstructured(unstr, &obj); err != nil {
|
||||
t.Errorf("Unexpected error in FromUnstructured: %v", err)
|
||||
}
|
||||
|
||||
data, err := json.Marshal(unstr)
|
||||
if err != nil {
|
||||
t.Fatalf("Error when marshaling unstructured: %v", err)
|
||||
}
|
||||
var unmarshalled F
|
||||
if err := json.Unmarshal(data, &unmarshalled); err != nil {
|
||||
t.Fatalf("Error when unmarshaling to object: %v", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(obj, unmarshalled) {
|
||||
t.Errorf("Incorrect conversion, diff: %v", diff.ObjectReflectDiff(obj, unmarshalled))
|
||||
}
|
||||
}
|
||||
|
||||
func TestCustomToUnstructured(t *testing.T) {
|
||||
testcases := []struct {
|
||||
Data string
|
||||
Expected interface{}
|
||||
}{
|
||||
{Data: `null`, Expected: nil},
|
||||
{Data: `true`, Expected: true},
|
||||
{Data: `false`, Expected: false},
|
||||
{Data: `[]`, Expected: []interface{}{}},
|
||||
{Data: `[1]`, Expected: []interface{}{int64(1)}},
|
||||
{Data: `{}`, Expected: map[string]interface{}{}},
|
||||
{Data: `{"a":1}`, Expected: map[string]interface{}{"a": int64(1)}},
|
||||
{Data: `0`, Expected: int64(0)},
|
||||
{Data: `0.0`, Expected: float64(0)},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
tc := tc
|
||||
t.Run(tc.Data, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
result, err := runtime.NewTestUnstructuredConverter(simpleEquality).ToUnstructured(&G{
|
||||
CustomValue1: CustomValue{data: []byte(tc.Data)},
|
||||
CustomValue2: &CustomValue{data: []byte(tc.Data)},
|
||||
CustomPointer1: CustomPointer{data: []byte(tc.Data)},
|
||||
CustomPointer2: &CustomPointer{data: []byte(tc.Data)},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
for field, fieldResult := range result {
|
||||
assert.Equal(t, tc.Expected, fieldResult, field)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCustomToUnstructuredTopLevel(t *testing.T) {
|
||||
// Only objects are supported at the top level
|
||||
topLevelCases := []interface{}{
|
||||
&CustomValue{data: []byte(`{"a":1}`)},
|
||||
&CustomPointer{data: []byte(`{"a":1}`)},
|
||||
}
|
||||
expected := map[string]interface{}{"a": int64(1)}
|
||||
for i, obj := range topLevelCases {
|
||||
obj := obj
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
result, err := runtime.NewTestUnstructuredConverter(simpleEquality).ToUnstructured(obj)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
256
vendor/k8s.io/apimachinery/pkg/runtime/embedded_test.go
generated
vendored
256
vendor/k8s.io/apimachinery/pkg/runtime/embedded_test.go
generated
vendored
|
|
@ -1,256 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 runtime_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
runtimetesting "k8s.io/apimachinery/pkg/runtime/testing"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
)
|
||||
|
||||
func TestDecodeEmptyRawExtensionAsObject(t *testing.T) {
|
||||
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Group: "test.group", Version: "v1test"}
|
||||
externalGVK := externalGV.WithKind("ObjectTest")
|
||||
|
||||
s := runtime.NewScheme()
|
||||
s.AddKnownTypes(internalGV, &runtimetesting.ObjectTest{})
|
||||
s.AddKnownTypeWithName(externalGVK, &runtimetesting.ObjectTestExternal{})
|
||||
|
||||
codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV)
|
||||
|
||||
obj, gvk, err := codec.Decode([]byte(`{"kind":"`+externalGVK.Kind+`","apiVersion":"`+externalGV.String()+`","items":[{}]}`), nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
test := obj.(*runtimetesting.ObjectTest)
|
||||
if unk, ok := test.Items[0].(*runtime.Unknown); !ok || unk.Kind != "" || unk.APIVersion != "" || string(unk.Raw) != "{}" || unk.ContentType != runtime.ContentTypeJSON {
|
||||
t.Fatalf("unexpected object: %#v", test.Items[0])
|
||||
}
|
||||
if *gvk != externalGVK {
|
||||
t.Fatalf("unexpected kind: %#v", gvk)
|
||||
}
|
||||
|
||||
obj, gvk, err = codec.Decode([]byte(`{"kind":"`+externalGVK.Kind+`","apiVersion":"`+externalGV.String()+`","items":[{"kind":"Other","apiVersion":"v1"}]}`), nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
test = obj.(*runtimetesting.ObjectTest)
|
||||
if unk, ok := test.Items[0].(*runtime.Unknown); !ok || unk.Kind != "" || unk.APIVersion != "" || string(unk.Raw) != `{"kind":"Other","apiVersion":"v1"}` || unk.ContentType != runtime.ContentTypeJSON {
|
||||
t.Fatalf("unexpected object: %#v", test.Items[0])
|
||||
}
|
||||
if *gvk != externalGVK {
|
||||
t.Fatalf("unexpected kind: %#v", gvk)
|
||||
}
|
||||
}
|
||||
|
||||
func TestArrayOfRuntimeObject(t *testing.T) {
|
||||
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Group: "test.group", Version: "v1test"}
|
||||
|
||||
s := runtime.NewScheme()
|
||||
s.AddKnownTypes(internalGV, &runtimetesting.EmbeddedTest{})
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("EmbeddedTest"), &runtimetesting.EmbeddedTestExternal{})
|
||||
s.AddKnownTypes(internalGV, &runtimetesting.ObjectTest{})
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("ObjectTest"), &runtimetesting.ObjectTestExternal{})
|
||||
|
||||
codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV)
|
||||
|
||||
innerItems := []runtime.Object{
|
||||
&runtimetesting.EmbeddedTest{ID: "baz"},
|
||||
}
|
||||
items := []runtime.Object{
|
||||
&runtimetesting.EmbeddedTest{ID: "foo"},
|
||||
&runtimetesting.EmbeddedTest{ID: "bar"},
|
||||
// TODO: until YAML is removed, this JSON must be in ascending key order to ensure consistent roundtrip serialization
|
||||
&runtime.Unknown{
|
||||
Raw: []byte(`{"apiVersion":"unknown.group/unknown","foo":"bar","kind":"OtherTest"}`),
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
},
|
||||
&runtimetesting.ObjectTest{
|
||||
Items: runtime.NewEncodableList(codec, innerItems),
|
||||
},
|
||||
}
|
||||
internal := &runtimetesting.ObjectTest{
|
||||
Items: runtime.NewEncodableList(codec, items),
|
||||
}
|
||||
wire, err := runtime.Encode(codec, internal)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
t.Logf("Wire format is:\n%s\n", string(wire))
|
||||
|
||||
obj := &runtimetesting.ObjectTestExternal{}
|
||||
if err := json.Unmarshal(wire, obj); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
t.Logf("exact wire is: %s", string(obj.Items[0].Raw))
|
||||
|
||||
items[3] = &runtimetesting.ObjectTest{Items: innerItems}
|
||||
internal.Items = items
|
||||
|
||||
decoded, err := runtime.Decode(codec, wire)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
list, err := meta.ExtractList(decoded)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if errs := runtime.DecodeList(list, codec); len(errs) > 0 {
|
||||
t.Fatalf("unexpected error: %v", errs)
|
||||
}
|
||||
|
||||
list2, err := meta.ExtractList(list[3])
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if errs := runtime.DecodeList(list2, codec); len(errs) > 0 {
|
||||
t.Fatalf("unexpected error: %v", errs)
|
||||
}
|
||||
if err := meta.SetList(list[3], list2); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
// we want DecodeList to set type meta if possible, even on runtime.Unknown objects
|
||||
internal.Items[2].(*runtime.Unknown).TypeMeta = runtime.TypeMeta{Kind: "OtherTest", APIVersion: "unknown.group/unknown"}
|
||||
if e, a := internal.Items, list; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("mismatched decoded: %s", diff.ObjectGoPrintSideBySide(e, a))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNestedObject(t *testing.T) {
|
||||
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Group: "test.group", Version: "v1test"}
|
||||
embeddedTestExternalGVK := externalGV.WithKind("EmbeddedTest")
|
||||
|
||||
s := runtime.NewScheme()
|
||||
s.AddKnownTypes(internalGV, &runtimetesting.EmbeddedTest{})
|
||||
s.AddKnownTypeWithName(embeddedTestExternalGVK, &runtimetesting.EmbeddedTestExternal{})
|
||||
|
||||
codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV)
|
||||
|
||||
inner := &runtimetesting.EmbeddedTest{
|
||||
ID: "inner",
|
||||
}
|
||||
outer := &runtimetesting.EmbeddedTest{
|
||||
ID: "outer",
|
||||
Object: runtime.NewEncodable(codec, inner),
|
||||
}
|
||||
|
||||
wire, err := runtime.Encode(codec, outer)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected encode error '%v'", err)
|
||||
}
|
||||
|
||||
t.Logf("Wire format is:\n%v\n", string(wire))
|
||||
|
||||
decoded, err := runtime.Decode(codec, wire)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected decode error %v", err)
|
||||
}
|
||||
|
||||
// for later tests
|
||||
outer.Object = inner
|
||||
|
||||
if e, a := outer, decoded; reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected unequal %#v %#v", e, a)
|
||||
}
|
||||
|
||||
obj, err := runtime.Decode(codec, decoded.(*runtimetesting.EmbeddedTest).Object.(*runtime.Unknown).Raw)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
decoded.(*runtimetesting.EmbeddedTest).Object = obj
|
||||
if e, a := outer, decoded; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected equal %#v %#v", e, a)
|
||||
}
|
||||
|
||||
// test JSON decoding of the external object, which should preserve
|
||||
// raw bytes
|
||||
var externalViaJSON runtimetesting.EmbeddedTestExternal
|
||||
err = json.Unmarshal(wire, &externalViaJSON)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected decode error %v", err)
|
||||
}
|
||||
if externalViaJSON.Kind == "" || externalViaJSON.APIVersion == "" || externalViaJSON.ID != "outer" {
|
||||
t.Errorf("Expected objects to have type info set, got %#v", externalViaJSON)
|
||||
}
|
||||
if len(externalViaJSON.EmptyObject.Raw) > 0 {
|
||||
t.Errorf("Expected deserialization of empty nested objects into empty bytes, got %#v", externalViaJSON)
|
||||
}
|
||||
|
||||
// test JSON decoding, too, since Decode uses yaml unmarshalling.
|
||||
// Generic Unmarshalling of JSON cannot load the nested objects because there is
|
||||
// no default schema set. Consumers wishing to get direct JSON decoding must use
|
||||
// the external representation
|
||||
var decodedViaJSON runtimetesting.EmbeddedTest
|
||||
err = json.Unmarshal(wire, &decodedViaJSON)
|
||||
if err == nil {
|
||||
t.Fatal("Expeceted decode error")
|
||||
}
|
||||
if _, ok := err.(*json.UnmarshalTypeError); !ok {
|
||||
t.Fatalf("Unexpected decode error: %v", err)
|
||||
}
|
||||
if a := decodedViaJSON; a.Object != nil || a.EmptyObject != nil {
|
||||
t.Errorf("Expected embedded objects to be nil: %#v", a)
|
||||
}
|
||||
}
|
||||
|
||||
// TestDeepCopyOfRuntimeObject checks to make sure that runtime.Objects's can be passed through DeepCopy with fidelity
|
||||
func TestDeepCopyOfRuntimeObject(t *testing.T) {
|
||||
internalGV := schema.GroupVersion{Group: "test.group", Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Group: "test.group", Version: "v1test"}
|
||||
embeddedTestExternalGVK := externalGV.WithKind("EmbeddedTest")
|
||||
|
||||
s := runtime.NewScheme()
|
||||
s.AddKnownTypes(internalGV, &runtimetesting.EmbeddedTest{})
|
||||
s.AddKnownTypeWithName(embeddedTestExternalGVK, &runtimetesting.EmbeddedTestExternal{})
|
||||
|
||||
original := &runtimetesting.EmbeddedTest{
|
||||
ID: "outer",
|
||||
Object: &runtimetesting.EmbeddedTest{
|
||||
ID: "inner",
|
||||
},
|
||||
}
|
||||
|
||||
codec := serializer.NewCodecFactory(s).LegacyCodec(externalGV)
|
||||
|
||||
originalData, err := runtime.Encode(codec, original)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
t.Logf("originalRole = %v\n", string(originalData))
|
||||
|
||||
copyOfOriginal := original.DeepCopy()
|
||||
copiedData, err := runtime.Encode(codec, copyOfOriginal)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
t.Logf("copyOfRole = %v\n", string(copiedData))
|
||||
|
||||
if !reflect.DeepEqual(original, copyOfOriginal) {
|
||||
t.Errorf("expected \n%v\n, got \n%v", string(originalData), string(copiedData))
|
||||
}
|
||||
}
|
||||
113
vendor/k8s.io/apimachinery/pkg/runtime/extension_test.go
generated
vendored
113
vendor/k8s.io/apimachinery/pkg/runtime/extension_test.go
generated
vendored
|
|
@ -1,113 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 runtime_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
func TestEmbeddedRawExtensionMarshal(t *testing.T) {
|
||||
type test struct {
|
||||
Ext runtime.RawExtension
|
||||
}
|
||||
|
||||
extension := test{Ext: runtime.RawExtension{Raw: []byte(`{"foo":"bar"}`)}}
|
||||
data, err := json.Marshal(extension)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if string(data) != `{"Ext":{"foo":"bar"}}` {
|
||||
t.Errorf("unexpected data: %s", string(data))
|
||||
}
|
||||
}
|
||||
func TestEmbeddedRawExtensionUnmarshal(t *testing.T) {
|
||||
type test struct {
|
||||
Ext runtime.RawExtension
|
||||
}
|
||||
|
||||
testCases := map[string]struct {
|
||||
orig test
|
||||
}{
|
||||
"non-empty object": {
|
||||
orig: test{Ext: runtime.RawExtension{Raw: []byte(`{"foo":"bar"}`)}},
|
||||
},
|
||||
"empty object": {
|
||||
orig: test{Ext: runtime.RawExtension{}},
|
||||
},
|
||||
}
|
||||
|
||||
for k, tc := range testCases {
|
||||
new := test{}
|
||||
data, _ := json.Marshal(tc.orig)
|
||||
if err := json.Unmarshal(data, &new); err != nil {
|
||||
t.Errorf("%s: umarshal error: %v", k, err)
|
||||
}
|
||||
if !reflect.DeepEqual(tc.orig, new) {
|
||||
t.Errorf("%s: unmarshaled struct differs from original: %v %v", k, tc.orig, new)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmbeddedRawExtensionRoundTrip(t *testing.T) {
|
||||
type test struct {
|
||||
Ext runtime.RawExtension
|
||||
}
|
||||
|
||||
testCases := map[string]struct {
|
||||
orig test
|
||||
}{
|
||||
"non-empty object": {
|
||||
orig: test{Ext: runtime.RawExtension{Raw: []byte(`{"foo":"bar"}`)}},
|
||||
},
|
||||
"empty object": {
|
||||
orig: test{Ext: runtime.RawExtension{}},
|
||||
},
|
||||
}
|
||||
|
||||
for k, tc := range testCases {
|
||||
new1 := test{}
|
||||
new2 := test{}
|
||||
data, err := json.Marshal(tc.orig)
|
||||
if err != nil {
|
||||
t.Errorf("1st marshal error: %v", err)
|
||||
}
|
||||
if err = json.Unmarshal(data, &new1); err != nil {
|
||||
t.Errorf("1st unmarshal error: %v", err)
|
||||
}
|
||||
newData, err := json.Marshal(new1)
|
||||
if err != nil {
|
||||
t.Errorf("2st marshal error: %v", err)
|
||||
}
|
||||
if err = json.Unmarshal(newData, &new2); err != nil {
|
||||
t.Errorf("2nd unmarshal error: %v", err)
|
||||
}
|
||||
if !bytes.Equal(data, newData) {
|
||||
t.Errorf("%s: re-marshaled data differs from original: %v %v", k, data, newData)
|
||||
}
|
||||
if !reflect.DeepEqual(tc.orig, new1) {
|
||||
t.Errorf("%s: unmarshaled struct differs from original: %v %v", k, tc.orig, new1)
|
||||
}
|
||||
if !reflect.DeepEqual(new1, new2) {
|
||||
t.Errorf("%s: re-unmarshaled struct differs from original: %v %v", k, new1, new2)
|
||||
}
|
||||
}
|
||||
}
|
||||
43
vendor/k8s.io/apimachinery/pkg/runtime/schema/BUILD
generated
vendored
43
vendor/k8s.io/apimachinery/pkg/runtime/schema/BUILD
generated
vendored
|
|
@ -1,43 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["group_version_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"generated.pb.go",
|
||||
"group_version.go",
|
||||
"interfaces.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/runtime/schema",
|
||||
deps = ["//vendor/github.com/gogo/protobuf/proto:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "go_default_library_protos",
|
||||
srcs = ["generated.proto"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
136
vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version_test.go
generated
vendored
136
vendor/k8s.io/apimachinery/pkg/runtime/schema/group_version_test.go
generated
vendored
|
|
@ -1,136 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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 schema
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGroupVersionParse(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
out GroupVersion
|
||||
err func(error) bool
|
||||
}{
|
||||
{input: "v1", out: GroupVersion{Version: "v1"}},
|
||||
{input: "v2", out: GroupVersion{Version: "v2"}},
|
||||
{input: "/v1", out: GroupVersion{Version: "v1"}},
|
||||
{input: "v1/", out: GroupVersion{Group: "v1"}},
|
||||
{input: "/v1/", err: func(err error) bool { return err.Error() == "unexpected GroupVersion string: /v1/" }},
|
||||
{input: "v1/a", out: GroupVersion{Group: "v1", Version: "a"}},
|
||||
}
|
||||
for i, test := range tests {
|
||||
out, err := ParseGroupVersion(test.input)
|
||||
if test.err == nil && err != nil || err == nil && test.err != nil {
|
||||
t.Errorf("%d: unexpected error: %v", i, err)
|
||||
continue
|
||||
}
|
||||
if test.err != nil && !test.err(err) {
|
||||
t.Errorf("%d: unexpected error: %v", i, err)
|
||||
continue
|
||||
}
|
||||
if out != test.out {
|
||||
t.Errorf("%d: unexpected output: %#v", i, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGroupResourceParse(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
out GroupResource
|
||||
}{
|
||||
{input: "v1", out: GroupResource{Resource: "v1"}},
|
||||
{input: ".v1", out: GroupResource{Group: "v1"}},
|
||||
{input: "v1.", out: GroupResource{Resource: "v1"}},
|
||||
{input: "v1.a", out: GroupResource{Group: "a", Resource: "v1"}},
|
||||
{input: "b.v1.a", out: GroupResource{Group: "v1.a", Resource: "b"}},
|
||||
}
|
||||
for i, test := range tests {
|
||||
out := ParseGroupResource(test.input)
|
||||
if out != test.out {
|
||||
t.Errorf("%d: unexpected output: %#v", i, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseResourceArg(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
gvr *GroupVersionResource
|
||||
gr GroupResource
|
||||
}{
|
||||
{input: "v1", gr: GroupResource{Resource: "v1"}},
|
||||
{input: ".v1", gr: GroupResource{Group: "v1"}},
|
||||
{input: "v1.", gr: GroupResource{Resource: "v1"}},
|
||||
{input: "v1.a", gr: GroupResource{Group: "a", Resource: "v1"}},
|
||||
{input: "b.v1.a", gvr: &GroupVersionResource{Group: "a", Version: "v1", Resource: "b"}, gr: GroupResource{Group: "v1.a", Resource: "b"}},
|
||||
}
|
||||
for i, test := range tests {
|
||||
gvr, gr := ParseResourceArg(test.input)
|
||||
if (gvr != nil && test.gvr == nil) || (gvr == nil && test.gvr != nil) || (test.gvr != nil && *gvr != *test.gvr) {
|
||||
t.Errorf("%d: unexpected output: %#v", i, gvr)
|
||||
}
|
||||
if gr != test.gr {
|
||||
t.Errorf("%d: unexpected output: %#v", i, gr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestKindForGroupVersionKinds(t *testing.T) {
|
||||
gvks := GroupVersions{
|
||||
GroupVersion{Group: "batch", Version: "v1"},
|
||||
GroupVersion{Group: "batch", Version: "v2alpha1"},
|
||||
GroupVersion{Group: "policy", Version: "v1beta1"},
|
||||
}
|
||||
cases := []struct {
|
||||
input []GroupVersionKind
|
||||
target GroupVersionKind
|
||||
ok bool
|
||||
}{
|
||||
{
|
||||
input: []GroupVersionKind{{Group: "batch", Version: "v2alpha1", Kind: "ScheduledJob"}},
|
||||
target: GroupVersionKind{Group: "batch", Version: "v2alpha1", Kind: "ScheduledJob"},
|
||||
ok: true,
|
||||
},
|
||||
{
|
||||
input: []GroupVersionKind{{Group: "batch", Version: "v3alpha1", Kind: "CronJob"}},
|
||||
target: GroupVersionKind{Group: "batch", Version: "v1", Kind: "CronJob"},
|
||||
ok: true,
|
||||
},
|
||||
{
|
||||
input: []GroupVersionKind{{Group: "policy", Version: "v1beta1", Kind: "PodDisruptionBudget"}},
|
||||
target: GroupVersionKind{Group: "policy", Version: "v1beta1", Kind: "PodDisruptionBudget"},
|
||||
ok: true,
|
||||
},
|
||||
{
|
||||
input: []GroupVersionKind{{Group: "apps", Version: "v1alpha1", Kind: "StatefulSet"}},
|
||||
target: GroupVersionKind{},
|
||||
ok: false,
|
||||
},
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
target, ok := gvks.KindForGroupVersionKinds(c.input)
|
||||
if c.target != target {
|
||||
t.Errorf("%d: unexpected target: %v, expected %v", i, target, c.target)
|
||||
}
|
||||
if c.ok != ok {
|
||||
t.Errorf("%d: unexpected ok: %v, expected %v", i, ok, c.ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
1035
vendor/k8s.io/apimachinery/pkg/runtime/scheme_test.go
generated
vendored
1035
vendor/k8s.io/apimachinery/pkg/runtime/scheme_test.go
generated
vendored
File diff suppressed because it is too large
Load diff
64
vendor/k8s.io/apimachinery/pkg/runtime/serializer/BUILD
generated
vendored
64
vendor/k8s.io/apimachinery/pkg/runtime/serializer/BUILD
generated
vendored
|
|
@ -1,64 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["codec_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||
"//vendor/github.com/google/gofuzz:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/testing:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"codec_factory.go",
|
||||
"negotiated_codec.go",
|
||||
"protobuf_extension.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/runtime/serializer",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/json:all-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/protobuf:all-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/recognizer:all-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/streaming:all-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/testing:all-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning:all-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/yaml:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
339
vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_test.go
generated
vendored
339
vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_test.go
generated
vendored
|
|
@ -1,339 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 serializer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
serializertesting "k8s.io/apimachinery/pkg/runtime/serializer/testing"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/google/gofuzz"
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
var fuzzIters = flag.Int("fuzz-iters", 50, "How many fuzzing iterations to do.")
|
||||
|
||||
type testMetaFactory struct{}
|
||||
|
||||
func (testMetaFactory) Interpret(data []byte) (*schema.GroupVersionKind, error) {
|
||||
findKind := struct {
|
||||
APIVersion string `json:"myVersionKey,omitempty"`
|
||||
ObjectKind string `json:"myKindKey,omitempty"`
|
||||
}{}
|
||||
// yaml is a superset of json, so we use it to decode here. That way,
|
||||
// we understand both.
|
||||
if err := yaml.Unmarshal(data, &findKind); err != nil {
|
||||
return nil, fmt.Errorf("couldn't get version/kind: %v", err)
|
||||
}
|
||||
gv, err := schema.ParseGroupVersion(findKind.APIVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &schema.GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: findKind.ObjectKind}, nil
|
||||
}
|
||||
|
||||
// TestObjectFuzzer can randomly populate all the above objects.
|
||||
var TestObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 100).Funcs(
|
||||
func(j *serializertesting.MyWeirdCustomEmbeddedVersionKindField, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(j)
|
||||
j.APIVersion = ""
|
||||
j.ObjectKind = ""
|
||||
},
|
||||
)
|
||||
|
||||
// Returns a new Scheme set up with the test objects.
|
||||
func GetTestScheme() (*runtime.Scheme, runtime.Codec) {
|
||||
internalGV := schema.GroupVersion{Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Version: "v1"}
|
||||
externalGV2 := schema.GroupVersion{Version: "v2"}
|
||||
|
||||
s := runtime.NewScheme()
|
||||
// Ordinarily, we wouldn't add TestType2, but because this is a test and
|
||||
// both types are from the same package, we need to get it into the system
|
||||
// so that converter will match it with ExternalType2.
|
||||
s.AddKnownTypes(internalGV, &serializertesting.TestType1{}, &serializertesting.TestType2{}, &serializertesting.ExternalInternalSame{})
|
||||
s.AddKnownTypes(externalGV, &serializertesting.ExternalInternalSame{})
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("TestType1"), &serializertesting.ExternalTestType1{})
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("TestType2"), &serializertesting.ExternalTestType2{})
|
||||
s.AddKnownTypeWithName(internalGV.WithKind("TestType3"), &serializertesting.TestType1{})
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("TestType3"), &serializertesting.ExternalTestType1{})
|
||||
s.AddKnownTypeWithName(externalGV2.WithKind("TestType1"), &serializertesting.ExternalTestType1{})
|
||||
|
||||
s.AddUnversionedTypes(externalGV, &metav1.Status{})
|
||||
|
||||
cf := newCodecFactory(s, newSerializersForScheme(s, testMetaFactory{}))
|
||||
codec := cf.LegacyCodec(schema.GroupVersion{Version: "v1"})
|
||||
return s, codec
|
||||
}
|
||||
|
||||
var semantic = conversion.EqualitiesOrDie(
|
||||
func(a, b serializertesting.MyWeirdCustomEmbeddedVersionKindField) bool {
|
||||
a.APIVersion, a.ObjectKind = "", ""
|
||||
b.APIVersion, b.ObjectKind = "", ""
|
||||
return a == b
|
||||
},
|
||||
)
|
||||
|
||||
func runTest(t *testing.T, source interface{}) {
|
||||
name := reflect.TypeOf(source).Elem().Name()
|
||||
TestObjectFuzzer.Fuzz(source)
|
||||
|
||||
_, codec := GetTestScheme()
|
||||
data, err := runtime.Encode(codec, source.(runtime.Object))
|
||||
if err != nil {
|
||||
t.Errorf("%v: %v (%#v)", name, err, source)
|
||||
return
|
||||
}
|
||||
obj2, err := runtime.Decode(codec, data)
|
||||
if err != nil {
|
||||
t.Errorf("%v: %v (%v)", name, err, string(data))
|
||||
return
|
||||
}
|
||||
if !semantic.DeepEqual(source, obj2) {
|
||||
t.Errorf("1: %v: diff: %v", name, diff.ObjectGoPrintSideBySide(source, obj2))
|
||||
return
|
||||
}
|
||||
obj3 := reflect.New(reflect.TypeOf(source).Elem()).Interface()
|
||||
if err := runtime.DecodeInto(codec, data, obj3.(runtime.Object)); err != nil {
|
||||
t.Errorf("2: %v: %v", name, err)
|
||||
return
|
||||
}
|
||||
if !semantic.DeepEqual(source, obj3) {
|
||||
t.Errorf("3: %v: diff: %v", name, diff.ObjectDiff(source, obj3))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestTypes(t *testing.T) {
|
||||
table := []interface{}{
|
||||
&serializertesting.TestType1{},
|
||||
&serializertesting.ExternalInternalSame{},
|
||||
}
|
||||
for _, item := range table {
|
||||
// Try a few times, since runTest uses random values.
|
||||
for i := 0; i < *fuzzIters; i++ {
|
||||
runTest(t, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersionedEncoding(t *testing.T) {
|
||||
s, _ := GetTestScheme()
|
||||
cf := newCodecFactory(s, newSerializersForScheme(s, testMetaFactory{}))
|
||||
info, _ := runtime.SerializerInfoForMediaType(cf.SupportedMediaTypes(), runtime.ContentTypeJSON)
|
||||
encoder := info.Serializer
|
||||
|
||||
codec := cf.CodecForVersions(encoder, nil, schema.GroupVersion{Version: "v2"}, nil)
|
||||
out, err := runtime.Encode(codec, &serializertesting.TestType1{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(out) != `{"myVersionKey":"v2","myKindKey":"TestType1"}`+"\n" {
|
||||
t.Fatal(string(out))
|
||||
}
|
||||
|
||||
codec = cf.CodecForVersions(encoder, nil, schema.GroupVersion{Version: "v3"}, nil)
|
||||
_, err = runtime.Encode(codec, &serializertesting.TestType1{})
|
||||
if err == nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// unversioned encode with no versions is written directly to wire
|
||||
codec = cf.CodecForVersions(encoder, nil, runtime.InternalGroupVersioner, nil)
|
||||
out, err = runtime.Encode(codec, &serializertesting.TestType1{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(out) != `{}`+"\n" {
|
||||
t.Fatal(string(out))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultipleNames(t *testing.T) {
|
||||
_, codec := GetTestScheme()
|
||||
|
||||
obj, _, err := codec.Decode([]byte(`{"myKindKey":"TestType3","myVersionKey":"v1","A":"value"}`), nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
internal := obj.(*serializertesting.TestType1)
|
||||
if internal.A != "value" {
|
||||
t.Fatalf("unexpected decoded object: %#v", internal)
|
||||
}
|
||||
|
||||
out, err := runtime.Encode(codec, internal)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !strings.Contains(string(out), `"myKindKey":"TestType1"`) {
|
||||
t.Errorf("unexpected encoded output: %s", string(out))
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertTypesWhenDefaultNamesMatch(t *testing.T) {
|
||||
internalGV := schema.GroupVersion{Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Version: "v1"}
|
||||
|
||||
s := runtime.NewScheme()
|
||||
// create two names internally, with TestType1 being preferred
|
||||
s.AddKnownTypeWithName(internalGV.WithKind("TestType1"), &serializertesting.TestType1{})
|
||||
s.AddKnownTypeWithName(internalGV.WithKind("OtherType1"), &serializertesting.TestType1{})
|
||||
// create two names externally, with TestType1 being preferred
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("TestType1"), &serializertesting.ExternalTestType1{})
|
||||
s.AddKnownTypeWithName(externalGV.WithKind("OtherType1"), &serializertesting.ExternalTestType1{})
|
||||
|
||||
ext := &serializertesting.ExternalTestType1{}
|
||||
ext.APIVersion = "v1"
|
||||
ext.ObjectKind = "OtherType1"
|
||||
ext.A = "test"
|
||||
data, err := json.Marshal(ext)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
expect := &serializertesting.TestType1{A: "test"}
|
||||
|
||||
codec := newCodecFactory(s, newSerializersForScheme(s, testMetaFactory{})).LegacyCodec(schema.GroupVersion{Version: "v1"})
|
||||
|
||||
obj, err := runtime.Decode(codec, data)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !semantic.DeepEqual(expect, obj) {
|
||||
t.Errorf("unexpected object: %#v", obj)
|
||||
}
|
||||
|
||||
into := &serializertesting.TestType1{}
|
||||
if err := runtime.DecodeInto(codec, data, into); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !semantic.DeepEqual(expect, into) {
|
||||
t.Errorf("unexpected object: %#v", obj)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncode_Ptr(t *testing.T) {
|
||||
_, codec := GetTestScheme()
|
||||
tt := &serializertesting.TestType1{A: "I am a pointer object"}
|
||||
data, err := runtime.Encode(codec, tt)
|
||||
obj2, err2 := runtime.Decode(codec, data)
|
||||
if err != nil || err2 != nil {
|
||||
t.Fatalf("Failure: '%v' '%v'\n%s", err, err2, data)
|
||||
}
|
||||
if _, ok := obj2.(*serializertesting.TestType1); !ok {
|
||||
t.Fatalf("Got wrong type")
|
||||
}
|
||||
if !semantic.DeepEqual(obj2, tt) {
|
||||
t.Errorf("Expected:\n %#v,\n Got:\n %#v", tt, obj2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBadJSONRejection(t *testing.T) {
|
||||
log.SetOutput(os.Stderr)
|
||||
_, codec := GetTestScheme()
|
||||
badJSONs := [][]byte{
|
||||
[]byte(`{"myVersionKey":"v1"}`), // Missing kind
|
||||
[]byte(`{"myVersionKey":"v1","myKindKey":"bar"}`), // Unknown kind
|
||||
[]byte(`{"myVersionKey":"bar","myKindKey":"TestType1"}`), // Unknown version
|
||||
[]byte(`{"myKindKey":"TestType1"}`), // Missing version
|
||||
}
|
||||
for _, b := range badJSONs {
|
||||
if _, err := runtime.Decode(codec, b); err == nil {
|
||||
t.Errorf("Did not reject bad json: %s", string(b))
|
||||
}
|
||||
}
|
||||
badJSONKindMismatch := []byte(`{"myVersionKey":"v1","myKindKey":"ExternalInternalSame"}`)
|
||||
if err := runtime.DecodeInto(codec, badJSONKindMismatch, &serializertesting.TestType1{}); err == nil {
|
||||
t.Errorf("Kind is set but doesn't match the object type: %s", badJSONKindMismatch)
|
||||
}
|
||||
if err := runtime.DecodeInto(codec, []byte(``), &serializertesting.TestType1{}); err != nil {
|
||||
t.Errorf("Should allow empty decode: %v", err)
|
||||
}
|
||||
if _, _, err := codec.Decode([]byte(``), &schema.GroupVersionKind{Kind: "ExternalInternalSame"}, nil); err == nil {
|
||||
t.Errorf("Did not give error for empty data with only kind default")
|
||||
}
|
||||
if _, _, err := codec.Decode([]byte(`{"myVersionKey":"v1"}`), &schema.GroupVersionKind{Kind: "ExternalInternalSame"}, nil); err != nil {
|
||||
t.Errorf("Gave error for version and kind default")
|
||||
}
|
||||
if _, _, err := codec.Decode([]byte(`{"myKindKey":"ExternalInternalSame"}`), &schema.GroupVersionKind{Version: "v1"}, nil); err != nil {
|
||||
t.Errorf("Gave error for version and kind default")
|
||||
}
|
||||
if _, _, err := codec.Decode([]byte(``), &schema.GroupVersionKind{Kind: "ExternalInternalSame", Version: "v1"}, nil); err != nil {
|
||||
t.Errorf("Gave error for version and kind defaulted: %v", err)
|
||||
}
|
||||
if _, err := runtime.Decode(codec, []byte(``)); err == nil {
|
||||
t.Errorf("Did not give error for empty data")
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a new Scheme set up with the test objects needed by TestDirectCodec.
|
||||
func GetDirectCodecTestScheme() *runtime.Scheme {
|
||||
internalGV := schema.GroupVersion{Version: runtime.APIVersionInternal}
|
||||
externalGV := schema.GroupVersion{Version: "v1"}
|
||||
|
||||
s := runtime.NewScheme()
|
||||
// Ordinarily, we wouldn't add TestType2, but because this is a test and
|
||||
// both types are from the same package, we need to get it into the system
|
||||
// so that converter will match it with ExternalType2.
|
||||
s.AddKnownTypes(internalGV, &serializertesting.TestType1{})
|
||||
s.AddKnownTypes(externalGV, &serializertesting.ExternalTestType1{})
|
||||
|
||||
s.AddUnversionedTypes(externalGV, &metav1.Status{})
|
||||
return s
|
||||
}
|
||||
|
||||
func TestDirectCodec(t *testing.T) {
|
||||
s := GetDirectCodecTestScheme()
|
||||
cf := newCodecFactory(s, newSerializersForScheme(s, testMetaFactory{}))
|
||||
info, _ := runtime.SerializerInfoForMediaType(cf.SupportedMediaTypes(), runtime.ContentTypeJSON)
|
||||
serializer := info.Serializer
|
||||
df := DirectCodecFactory{cf}
|
||||
ignoredGV, err := schema.ParseGroupVersion("ignored group/ignored version")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
directEncoder := df.EncoderForVersion(serializer, ignoredGV)
|
||||
directDecoder := df.DecoderToVersion(serializer, ignoredGV)
|
||||
out, err := runtime.Encode(directEncoder, &serializertesting.ExternalTestType1{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(out) != `{"myVersionKey":"v1","myKindKey":"ExternalTestType1"}`+"\n" {
|
||||
t.Fatal(string(out))
|
||||
}
|
||||
a, _, err := directDecoder.Decode(out, nil, nil)
|
||||
e := &serializertesting.ExternalTestType1{
|
||||
MyWeirdCustomEmbeddedVersionKindField: serializertesting.MyWeirdCustomEmbeddedVersionKindField{
|
||||
APIVersion: "v1",
|
||||
ObjectKind: "ExternalTestType1",
|
||||
},
|
||||
}
|
||||
if !semantic.DeepEqual(e, a) {
|
||||
t.Fatalf("expect %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
55
vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/BUILD
generated
vendored
55
vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/BUILD
generated
vendored
|
|
@ -1,55 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["meta_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"json.go",
|
||||
"meta.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/runtime/serializer/json",
|
||||
deps = [
|
||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||
"//vendor/github.com/json-iterator/go:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/framer:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_xtest",
|
||||
srcs = ["json_test.go"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
293
vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json_test.go
generated
vendored
293
vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json_test.go
generated
vendored
|
|
@ -1,293 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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 json_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
)
|
||||
|
||||
type testDecodable struct {
|
||||
Other string
|
||||
Value int `json:"value"`
|
||||
gvk schema.GroupVersionKind
|
||||
}
|
||||
|
||||
func (d *testDecodable) GetObjectKind() schema.ObjectKind { return d }
|
||||
func (d *testDecodable) SetGroupVersionKind(gvk schema.GroupVersionKind) { d.gvk = gvk }
|
||||
func (d *testDecodable) GroupVersionKind() schema.GroupVersionKind { return d.gvk }
|
||||
func (d *testDecodable) DeepCopyObject() runtime.Object {
|
||||
panic("testDecodable does not support DeepCopy")
|
||||
}
|
||||
|
||||
func TestDecode(t *testing.T) {
|
||||
testCases := []struct {
|
||||
creater runtime.ObjectCreater
|
||||
typer runtime.ObjectTyper
|
||||
yaml bool
|
||||
pretty bool
|
||||
|
||||
data []byte
|
||||
defaultGVK *schema.GroupVersionKind
|
||||
into runtime.Object
|
||||
|
||||
errFn func(error) bool
|
||||
expectedObject runtime.Object
|
||||
expectedGVK *schema.GroupVersionKind
|
||||
}{
|
||||
{
|
||||
data: []byte("{}"),
|
||||
|
||||
expectedGVK: &schema.GroupVersionKind{},
|
||||
errFn: func(err error) bool { return strings.Contains(err.Error(), "Object 'Kind' is missing in") },
|
||||
},
|
||||
{
|
||||
data: []byte("{}"),
|
||||
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
creater: &mockCreater{err: fmt.Errorf("fake error")},
|
||||
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
errFn: func(err error) bool { return err.Error() == "fake error" },
|
||||
},
|
||||
{
|
||||
data: []byte("{}"),
|
||||
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
creater: &mockCreater{obj: &testDecodable{}},
|
||||
expectedObject: &testDecodable{},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
},
|
||||
|
||||
// version without group is not defaulted
|
||||
{
|
||||
data: []byte(`{"apiVersion":"blah"}`),
|
||||
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
creater: &mockCreater{obj: &testDecodable{}},
|
||||
expectedObject: &testDecodable{},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "", Version: "blah"},
|
||||
},
|
||||
// group without version is defaulted
|
||||
{
|
||||
data: []byte(`{"apiVersion":"other/"}`),
|
||||
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
creater: &mockCreater{obj: &testDecodable{}},
|
||||
expectedObject: &testDecodable{},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
},
|
||||
// group version, kind is defaulted
|
||||
{
|
||||
data: []byte(`{"apiVersion":"other1/blah1"}`),
|
||||
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
creater: &mockCreater{obj: &testDecodable{}},
|
||||
expectedObject: &testDecodable{},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other1", Version: "blah1"},
|
||||
},
|
||||
// gvk all provided then not defaulted at all
|
||||
{
|
||||
data: []byte(`{"kind":"Test","apiVersion":"other/blah"}`),
|
||||
defaultGVK: &schema.GroupVersionKind{Kind: "Test1", Group: "other1", Version: "blah1"},
|
||||
creater: &mockCreater{obj: &testDecodable{}},
|
||||
expectedObject: &testDecodable{},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
},
|
||||
//gvk defaulting if kind not provided in data and defaultGVK use into's kind
|
||||
{
|
||||
data: []byte(`{"apiVersion":"b1/c1"}`),
|
||||
into: &testDecodable{gvk: schema.GroupVersionKind{Kind: "a3", Group: "b1", Version: "c1"}},
|
||||
typer: &mockTyper{gvk: &schema.GroupVersionKind{Kind: "a3", Group: "b1", Version: "c1"}},
|
||||
defaultGVK: nil,
|
||||
creater: &mockCreater{obj: &testDecodable{}},
|
||||
expectedObject: &testDecodable{gvk: schema.GroupVersionKind{Kind: "a3", Group: "b1", Version: "c1"}},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "a3", Group: "b1", Version: "c1"},
|
||||
},
|
||||
|
||||
// accept runtime.Unknown as into and bypass creator
|
||||
{
|
||||
data: []byte(`{}`),
|
||||
into: &runtime.Unknown{},
|
||||
|
||||
expectedGVK: &schema.GroupVersionKind{},
|
||||
expectedObject: &runtime.Unknown{
|
||||
Raw: []byte(`{}`),
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
},
|
||||
},
|
||||
{
|
||||
data: []byte(`{"test":"object"}`),
|
||||
into: &runtime.Unknown{},
|
||||
|
||||
expectedGVK: &schema.GroupVersionKind{},
|
||||
expectedObject: &runtime.Unknown{
|
||||
Raw: []byte(`{"test":"object"}`),
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
},
|
||||
},
|
||||
{
|
||||
data: []byte(`{"test":"object"}`),
|
||||
into: &runtime.Unknown{},
|
||||
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
expectedObject: &runtime.Unknown{
|
||||
TypeMeta: runtime.TypeMeta{APIVersion: "other/blah", Kind: "Test"},
|
||||
Raw: []byte(`{"test":"object"}`),
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
},
|
||||
},
|
||||
|
||||
// unregistered objects can be decoded into directly
|
||||
{
|
||||
data: []byte(`{"kind":"Test","apiVersion":"other/blah","value":1,"Other":"test"}`),
|
||||
into: &testDecodable{},
|
||||
typer: &mockTyper{err: runtime.NewNotRegisteredErrForKind(schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"})},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
expectedObject: &testDecodable{
|
||||
Other: "test",
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
// registered types get defaulted by the into object kind
|
||||
{
|
||||
data: []byte(`{"value":1,"Other":"test"}`),
|
||||
into: &testDecodable{},
|
||||
typer: &mockTyper{gvk: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
expectedObject: &testDecodable{
|
||||
Other: "test",
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
// registered types get defaulted by the into object kind even without version, but return an error
|
||||
{
|
||||
data: []byte(`{"value":1,"Other":"test"}`),
|
||||
into: &testDecodable{},
|
||||
typer: &mockTyper{gvk: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: ""}},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: ""},
|
||||
errFn: func(err error) bool { return strings.Contains(err.Error(), "Object 'apiVersion' is missing in") },
|
||||
expectedObject: &testDecodable{
|
||||
Other: "test",
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
|
||||
// runtime.VersionedObjects are decoded
|
||||
{
|
||||
data: []byte(`{"value":1,"Other":"test"}`),
|
||||
into: &runtime.VersionedObjects{Objects: []runtime.Object{}},
|
||||
creater: &mockCreater{obj: &testDecodable{}},
|
||||
typer: &mockTyper{gvk: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}},
|
||||
defaultGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
expectedObject: &runtime.VersionedObjects{
|
||||
Objects: []runtime.Object{
|
||||
&testDecodable{
|
||||
Other: "test",
|
||||
Value: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
// runtime.VersionedObjects with an object are decoded into
|
||||
{
|
||||
data: []byte(`{"Other":"test"}`),
|
||||
into: &runtime.VersionedObjects{Objects: []runtime.Object{&testDecodable{Value: 2}}},
|
||||
typer: &mockTyper{gvk: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}},
|
||||
expectedGVK: &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"},
|
||||
expectedObject: &runtime.VersionedObjects{
|
||||
Objects: []runtime.Object{
|
||||
&testDecodable{
|
||||
Other: "test",
|
||||
Value: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range testCases {
|
||||
var s runtime.Serializer
|
||||
if test.yaml {
|
||||
s = json.NewYAMLSerializer(json.DefaultMetaFactory, test.creater, test.typer)
|
||||
} else {
|
||||
s = json.NewSerializer(json.DefaultMetaFactory, test.creater, test.typer, test.pretty)
|
||||
}
|
||||
obj, gvk, err := s.Decode([]byte(test.data), test.defaultGVK, test.into)
|
||||
|
||||
if !reflect.DeepEqual(test.expectedGVK, gvk) {
|
||||
t.Errorf("%d: unexpected GVK: %v", i, gvk)
|
||||
}
|
||||
|
||||
switch {
|
||||
case err == nil && test.errFn != nil:
|
||||
t.Errorf("%d: failed: %v", i, err)
|
||||
continue
|
||||
case err != nil && test.errFn == nil:
|
||||
t.Errorf("%d: failed: %v", i, err)
|
||||
continue
|
||||
case err != nil:
|
||||
if !test.errFn(err) {
|
||||
t.Errorf("%d: failed: %v", i, err)
|
||||
}
|
||||
if obj != nil {
|
||||
t.Errorf("%d: should have returned nil object", i)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if test.into != nil && test.into != obj {
|
||||
t.Errorf("%d: expected into to be returned: %v", i, obj)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(test.expectedObject, obj) {
|
||||
t.Errorf("%d: unexpected object:\n%s", i, diff.ObjectGoPrintSideBySide(test.expectedObject, obj))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type mockCreater struct {
|
||||
apiVersion string
|
||||
kind string
|
||||
err error
|
||||
obj runtime.Object
|
||||
}
|
||||
|
||||
func (c *mockCreater) New(kind schema.GroupVersionKind) (runtime.Object, error) {
|
||||
c.apiVersion, c.kind = kind.GroupVersion().String(), kind.Kind
|
||||
return c.obj, c.err
|
||||
}
|
||||
|
||||
type mockTyper struct {
|
||||
gvk *schema.GroupVersionKind
|
||||
err error
|
||||
}
|
||||
|
||||
func (t *mockTyper) ObjectKinds(obj runtime.Object) ([]schema.GroupVersionKind, bool, error) {
|
||||
if t.gvk == nil {
|
||||
return nil, false, t.err
|
||||
}
|
||||
return []schema.GroupVersionKind{*t.gvk}, false, t.err
|
||||
}
|
||||
|
||||
func (t *mockTyper) Recognizes(_ schema.GroupVersionKind) bool {
|
||||
return false
|
||||
}
|
||||
45
vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/meta_test.go
generated
vendored
45
vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/meta_test.go
generated
vendored
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 json
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestSimpleMetaFactoryInterpret(t *testing.T) {
|
||||
factory := SimpleMetaFactory{}
|
||||
gvk, err := factory.Interpret([]byte(`{"apiVersion":"1","kind":"object"}`))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if gvk.Version != "1" || gvk.Kind != "object" {
|
||||
t.Errorf("unexpected interpret: %#v", gvk)
|
||||
}
|
||||
|
||||
// no kind or version
|
||||
gvk, err = factory.Interpret([]byte(`{}`))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if gvk.Version != "" || gvk.Kind != "" {
|
||||
t.Errorf("unexpected interpret: %#v", gvk)
|
||||
}
|
||||
|
||||
// unparsable
|
||||
gvk, err = factory.Interpret([]byte(`{`))
|
||||
if err == nil {
|
||||
t.Errorf("unexpected non-error")
|
||||
}
|
||||
}
|
||||
35
vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/BUILD
generated
vendored
35
vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/BUILD
generated
vendored
|
|
@ -1,35 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"protobuf.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/runtime/serializer/protobuf",
|
||||
deps = [
|
||||
"//vendor/github.com/gogo/protobuf/proto:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/framer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
32
vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer/BUILD
generated
vendored
32
vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer/BUILD
generated
vendored
|
|
@ -1,32 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["recognizer.go"],
|
||||
importpath = "k8s.io/apimachinery/pkg/runtime/serializer/recognizer",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/recognizer/testing:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
41
vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/BUILD
generated
vendored
41
vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/BUILD
generated
vendored
|
|
@ -1,41 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["streaming_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/framer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["streaming.go"],
|
||||
importpath = "k8s.io/apimachinery/pkg/runtime/serializer/streaming",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
84
vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/streaming_test.go
generated
vendored
84
vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/streaming_test.go
generated
vendored
|
|
@ -1,84 +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 streaming
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/framer"
|
||||
)
|
||||
|
||||
type fakeDecoder struct {
|
||||
got []byte
|
||||
obj runtime.Object
|
||||
err error
|
||||
}
|
||||
|
||||
func (d *fakeDecoder) Decode(data []byte, gvk *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
|
||||
d.got = data
|
||||
return d.obj, nil, d.err
|
||||
}
|
||||
|
||||
func TestEmptyDecoder(t *testing.T) {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
d := &fakeDecoder{}
|
||||
_, _, err := NewDecoder(ioutil.NopCloser(buf), d).Decode(nil, nil)
|
||||
if err != io.EOF {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecoder(t *testing.T) {
|
||||
frames := [][]byte{
|
||||
make([]byte, 1025),
|
||||
make([]byte, 1024*5),
|
||||
make([]byte, 1024*1024*5),
|
||||
make([]byte, 1025),
|
||||
}
|
||||
pr, pw := io.Pipe()
|
||||
fw := framer.NewLengthDelimitedFrameWriter(pw)
|
||||
go func() {
|
||||
for i := range frames {
|
||||
fw.Write(frames[i])
|
||||
}
|
||||
pw.Close()
|
||||
}()
|
||||
|
||||
r := framer.NewLengthDelimitedFrameReader(pr)
|
||||
d := &fakeDecoder{}
|
||||
dec := NewDecoder(r, d)
|
||||
if _, _, err := dec.Decode(nil, nil); err != nil || !bytes.Equal(d.got, frames[0]) {
|
||||
t.Fatalf("unexpected %v %v", err, len(d.got))
|
||||
}
|
||||
if _, _, err := dec.Decode(nil, nil); err != nil || !bytes.Equal(d.got, frames[1]) {
|
||||
t.Fatalf("unexpected %v %v", err, len(d.got))
|
||||
}
|
||||
if _, _, err := dec.Decode(nil, nil); err != ErrObjectTooLarge || !bytes.Equal(d.got, frames[1]) {
|
||||
t.Fatalf("unexpected %v %v", err, len(d.got))
|
||||
}
|
||||
if _, _, err := dec.Decode(nil, nil); err != nil || !bytes.Equal(d.got, frames[3]) {
|
||||
t.Fatalf("unexpected %v %v", err, len(d.got))
|
||||
}
|
||||
if _, _, err := dec.Decode(nil, nil); err != io.EOF {
|
||||
t.Fatalf("unexpected %v %v", err, len(d.got))
|
||||
}
|
||||
}
|
||||
41
vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/BUILD
generated
vendored
41
vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/BUILD
generated
vendored
|
|
@ -1,41 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["versioning_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["versioning.go"],
|
||||
importpath = "k8s.io/apimachinery/pkg/runtime/serializer/versioning",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
381
vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning_test.go
generated
vendored
381
vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning_test.go
generated
vendored
|
|
@ -1,381 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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 versioning
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
)
|
||||
|
||||
type testDecodable struct {
|
||||
Other string
|
||||
Value int `json:"value"`
|
||||
gvk schema.GroupVersionKind
|
||||
}
|
||||
|
||||
func (d *testDecodable) GetObjectKind() schema.ObjectKind { return d }
|
||||
func (d *testDecodable) SetGroupVersionKind(gvk schema.GroupVersionKind) { d.gvk = gvk }
|
||||
func (d *testDecodable) GroupVersionKind() schema.GroupVersionKind { return d.gvk }
|
||||
func (d *testDecodable) DeepCopyObject() runtime.Object {
|
||||
// no real deepcopy because these tests check for pointer equality
|
||||
return d
|
||||
}
|
||||
|
||||
type testNestedDecodable struct {
|
||||
Other string
|
||||
Value int `json:"value"`
|
||||
|
||||
gvk schema.GroupVersionKind
|
||||
nestedCalled bool
|
||||
nestedErr error
|
||||
}
|
||||
|
||||
func (d *testNestedDecodable) GetObjectKind() schema.ObjectKind { return d }
|
||||
func (d *testNestedDecodable) SetGroupVersionKind(gvk schema.GroupVersionKind) { d.gvk = gvk }
|
||||
func (d *testNestedDecodable) GroupVersionKind() schema.GroupVersionKind { return d.gvk }
|
||||
func (d *testNestedDecodable) DeepCopyObject() runtime.Object {
|
||||
// no real deepcopy because these tests check for pointer equality
|
||||
return d
|
||||
}
|
||||
|
||||
func (d *testNestedDecodable) EncodeNestedObjects(e runtime.Encoder) error {
|
||||
d.nestedCalled = true
|
||||
return d.nestedErr
|
||||
}
|
||||
|
||||
func (d *testNestedDecodable) DecodeNestedObjects(_ runtime.Decoder) error {
|
||||
d.nestedCalled = true
|
||||
return d.nestedErr
|
||||
}
|
||||
|
||||
func TestNestedDecode(t *testing.T) {
|
||||
n := &testNestedDecodable{nestedErr: fmt.Errorf("unable to decode")}
|
||||
decoder := &mockSerializer{obj: n}
|
||||
codec := NewCodec(nil, decoder, nil, nil, nil, nil, nil, nil)
|
||||
if _, _, err := codec.Decode([]byte(`{}`), nil, n); err != n.nestedErr {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if !n.nestedCalled {
|
||||
t.Errorf("did not invoke nested decoder")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNestedEncode(t *testing.T) {
|
||||
n := &testNestedDecodable{nestedErr: fmt.Errorf("unable to decode")}
|
||||
n2 := &testNestedDecodable{nestedErr: fmt.Errorf("unable to decode 2")}
|
||||
encoder := &mockSerializer{obj: n}
|
||||
codec := NewCodec(
|
||||
encoder, nil,
|
||||
&checkConvertor{obj: n2, groupVersion: schema.GroupVersion{Group: "other"}},
|
||||
nil,
|
||||
&mockTyper{gvks: []schema.GroupVersionKind{{Kind: "test"}}},
|
||||
nil,
|
||||
schema.GroupVersion{Group: "other"}, nil,
|
||||
)
|
||||
if err := codec.Encode(n, ioutil.Discard); err != n2.nestedErr {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if n.nestedCalled || !n2.nestedCalled {
|
||||
t.Errorf("did not invoke correct nested decoder")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecode(t *testing.T) {
|
||||
gvk1 := &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"}
|
||||
decodable1 := &testDecodable{}
|
||||
decodable2 := &testDecodable{}
|
||||
decodable3 := &testDecodable{}
|
||||
versionedDecodable1 := &runtime.VersionedObjects{Objects: []runtime.Object{decodable1}}
|
||||
|
||||
testCases := []struct {
|
||||
serializer runtime.Serializer
|
||||
convertor runtime.ObjectConvertor
|
||||
creater runtime.ObjectCreater
|
||||
typer runtime.ObjectTyper
|
||||
defaulter runtime.ObjectDefaulter
|
||||
yaml bool
|
||||
pretty bool
|
||||
|
||||
encodes, decodes runtime.GroupVersioner
|
||||
|
||||
defaultGVK *schema.GroupVersionKind
|
||||
into runtime.Object
|
||||
|
||||
errFn func(error) bool
|
||||
expectedObject runtime.Object
|
||||
sameObject runtime.Object
|
||||
expectedGVK *schema.GroupVersionKind
|
||||
}{
|
||||
{
|
||||
serializer: &mockSerializer{actual: gvk1},
|
||||
convertor: &checkConvertor{groupVersion: schema.GroupVersion{Group: "other", Version: "__internal"}},
|
||||
expectedGVK: gvk1,
|
||||
decodes: schema.GroupVersion{Group: "other", Version: "__internal"},
|
||||
},
|
||||
{
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
convertor: &checkConvertor{in: decodable1, obj: decodable2, groupVersion: schema.GroupVersion{Group: "other", Version: "__internal"}},
|
||||
expectedGVK: gvk1,
|
||||
sameObject: decodable2,
|
||||
decodes: schema.GroupVersion{Group: "other", Version: "__internal"},
|
||||
},
|
||||
// defaultGVK.Group is allowed to force a conversion to the destination group
|
||||
{
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
defaultGVK: &schema.GroupVersionKind{Group: "force"},
|
||||
convertor: &checkConvertor{in: decodable1, obj: decodable2, groupVersion: schema.GroupVersion{Group: "force", Version: "__internal"}},
|
||||
expectedGVK: gvk1,
|
||||
sameObject: decodable2,
|
||||
decodes: schema.GroupVersion{Group: "force", Version: "__internal"},
|
||||
},
|
||||
// uses direct conversion for into when objects differ
|
||||
{
|
||||
into: decodable3,
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
convertor: &checkConvertor{in: decodable1, obj: decodable3, directConvert: true},
|
||||
expectedGVK: gvk1,
|
||||
sameObject: decodable3,
|
||||
},
|
||||
{
|
||||
into: versionedDecodable1,
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable3},
|
||||
convertor: &checkConvertor{in: decodable3, obj: decodable1, directConvert: true},
|
||||
expectedGVK: gvk1,
|
||||
sameObject: versionedDecodable1,
|
||||
},
|
||||
// returns directly when serializer returns into
|
||||
{
|
||||
into: decodable3,
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable3},
|
||||
expectedGVK: gvk1,
|
||||
sameObject: decodable3,
|
||||
},
|
||||
// returns directly when serializer returns into
|
||||
{
|
||||
into: versionedDecodable1,
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
expectedGVK: gvk1,
|
||||
sameObject: versionedDecodable1,
|
||||
},
|
||||
|
||||
// runtime.VersionedObjects are decoded
|
||||
{
|
||||
into: &runtime.VersionedObjects{Objects: []runtime.Object{}},
|
||||
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
convertor: &checkConvertor{in: decodable1, obj: decodable2, groupVersion: schema.GroupVersion{Group: "other", Version: "__internal"}},
|
||||
expectedGVK: gvk1,
|
||||
expectedObject: &runtime.VersionedObjects{Objects: []runtime.Object{decodable1, decodable2}},
|
||||
decodes: schema.GroupVersion{Group: "other", Version: "__internal"},
|
||||
},
|
||||
|
||||
// decode into the same version as the serialized object
|
||||
{
|
||||
decodes: schema.GroupVersions{gvk1.GroupVersion()},
|
||||
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
convertor: &checkConvertor{in: decodable1, obj: decodable1, groupVersion: schema.GroupVersions{{Group: "other", Version: "blah"}}},
|
||||
expectedGVK: gvk1,
|
||||
expectedObject: decodable1,
|
||||
},
|
||||
{
|
||||
into: &runtime.VersionedObjects{Objects: []runtime.Object{}},
|
||||
decodes: schema.GroupVersions{gvk1.GroupVersion()},
|
||||
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
convertor: &checkConvertor{in: decodable1, obj: decodable1, groupVersion: schema.GroupVersions{{Group: "other", Version: "blah"}}},
|
||||
expectedGVK: gvk1,
|
||||
expectedObject: &runtime.VersionedObjects{Objects: []runtime.Object{decodable1}},
|
||||
},
|
||||
|
||||
// codec with non matching version skips conversion altogether
|
||||
{
|
||||
decodes: schema.GroupVersions{{Group: "something", Version: "else"}},
|
||||
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
convertor: &checkConvertor{in: decodable1, obj: decodable1, groupVersion: schema.GroupVersions{{Group: "something", Version: "else"}}},
|
||||
expectedGVK: gvk1,
|
||||
expectedObject: decodable1,
|
||||
},
|
||||
{
|
||||
into: &runtime.VersionedObjects{Objects: []runtime.Object{}},
|
||||
decodes: schema.GroupVersions{{Group: "something", Version: "else"}},
|
||||
|
||||
serializer: &mockSerializer{actual: gvk1, obj: decodable1},
|
||||
convertor: &checkConvertor{in: decodable1, obj: decodable1, groupVersion: schema.GroupVersions{{Group: "something", Version: "else"}}},
|
||||
expectedGVK: gvk1,
|
||||
expectedObject: &runtime.VersionedObjects{Objects: []runtime.Object{decodable1}},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range testCases {
|
||||
t.Logf("%d", i)
|
||||
s := NewCodec(test.serializer, test.serializer, test.convertor, test.creater, test.typer, test.defaulter, test.encodes, test.decodes)
|
||||
obj, gvk, err := s.Decode([]byte(`{}`), test.defaultGVK, test.into)
|
||||
|
||||
if !reflect.DeepEqual(test.expectedGVK, gvk) {
|
||||
t.Errorf("%d: unexpected GVK: %v", i, gvk)
|
||||
}
|
||||
|
||||
switch {
|
||||
case err == nil && test.errFn != nil:
|
||||
t.Errorf("%d: failed: %v", i, err)
|
||||
continue
|
||||
case err != nil && test.errFn == nil:
|
||||
t.Errorf("%d: failed: %v", i, err)
|
||||
continue
|
||||
case err != nil:
|
||||
if !test.errFn(err) {
|
||||
t.Errorf("%d: failed: %v", i, err)
|
||||
}
|
||||
if obj != nil {
|
||||
t.Errorf("%d: should have returned nil object", i)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if test.into != nil && test.into != obj {
|
||||
t.Errorf("%d: expected into to be returned: %v", i, obj)
|
||||
continue
|
||||
}
|
||||
|
||||
switch {
|
||||
case test.expectedObject != nil:
|
||||
if !reflect.DeepEqual(test.expectedObject, obj) {
|
||||
t.Errorf("%d: unexpected object:\n%s", i, diff.ObjectGoPrintSideBySide(test.expectedObject, obj))
|
||||
}
|
||||
case test.sameObject != nil:
|
||||
if test.sameObject != obj {
|
||||
t.Errorf("%d: unexpected object:\n%s", i, diff.ObjectGoPrintSideBySide(test.sameObject, obj))
|
||||
}
|
||||
case obj != nil:
|
||||
t.Errorf("%d: unexpected object: %#v", i, obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type checkConvertor struct {
|
||||
err error
|
||||
in, obj runtime.Object
|
||||
groupVersion runtime.GroupVersioner
|
||||
directConvert bool
|
||||
}
|
||||
|
||||
func (c *checkConvertor) Convert(in, out, context interface{}) error {
|
||||
if !c.directConvert {
|
||||
return fmt.Errorf("unexpected call to Convert")
|
||||
}
|
||||
if c.in != nil && c.in != in {
|
||||
return fmt.Errorf("unexpected in: %s", in)
|
||||
}
|
||||
if c.obj != nil && c.obj != out {
|
||||
return fmt.Errorf("unexpected out: %s", out)
|
||||
}
|
||||
return c.err
|
||||
}
|
||||
func (c *checkConvertor) ConvertToVersion(in runtime.Object, outVersion runtime.GroupVersioner) (out runtime.Object, err error) {
|
||||
if c.directConvert {
|
||||
return nil, fmt.Errorf("unexpected call to ConvertToVersion")
|
||||
}
|
||||
if c.in != nil && c.in != in {
|
||||
return nil, fmt.Errorf("unexpected in: %s", in)
|
||||
}
|
||||
if !reflect.DeepEqual(c.groupVersion, outVersion) {
|
||||
return nil, fmt.Errorf("unexpected outversion: %s (%s)", outVersion, c.groupVersion)
|
||||
}
|
||||
return c.obj, c.err
|
||||
}
|
||||
func (c *checkConvertor) ConvertFieldLabel(version, kind, label, value string) (string, string, error) {
|
||||
return "", "", fmt.Errorf("unexpected call to ConvertFieldLabel")
|
||||
}
|
||||
|
||||
type mockSerializer struct {
|
||||
err error
|
||||
obj runtime.Object
|
||||
encodingObjGVK schema.GroupVersionKind
|
||||
|
||||
defaults, actual *schema.GroupVersionKind
|
||||
into runtime.Object
|
||||
}
|
||||
|
||||
func (s *mockSerializer) Decode(data []byte, defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
|
||||
s.defaults = defaults
|
||||
s.into = into
|
||||
return s.obj, s.actual, s.err
|
||||
}
|
||||
|
||||
func (s *mockSerializer) Encode(obj runtime.Object, w io.Writer) error {
|
||||
s.obj = obj
|
||||
s.encodingObjGVK = obj.GetObjectKind().GroupVersionKind()
|
||||
return s.err
|
||||
}
|
||||
|
||||
type mockCreater struct {
|
||||
err error
|
||||
obj runtime.Object
|
||||
}
|
||||
|
||||
func (c *mockCreater) New(kind schema.GroupVersionKind) (runtime.Object, error) {
|
||||
return c.obj, c.err
|
||||
}
|
||||
|
||||
type mockTyper struct {
|
||||
gvks []schema.GroupVersionKind
|
||||
unversioned bool
|
||||
err error
|
||||
}
|
||||
|
||||
func (t *mockTyper) ObjectKinds(obj runtime.Object) ([]schema.GroupVersionKind, bool, error) {
|
||||
return t.gvks, t.unversioned, t.err
|
||||
}
|
||||
|
||||
func (t *mockTyper) Recognizes(_ schema.GroupVersionKind) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func TestDirectCodecEncode(t *testing.T) {
|
||||
serializer := mockSerializer{}
|
||||
typer := mockTyper{
|
||||
gvks: []schema.GroupVersionKind{
|
||||
{
|
||||
Group: "wrong_group",
|
||||
Kind: "some_kind",
|
||||
},
|
||||
{
|
||||
Group: "expected_group",
|
||||
Kind: "some_kind",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
c := DirectEncoder{
|
||||
Version: schema.GroupVersion{Group: "expected_group"},
|
||||
Encoder: &serializer,
|
||||
ObjectTyper: &typer,
|
||||
}
|
||||
c.Encode(&testDecodable{}, ioutil.Discard)
|
||||
if e, a := "expected_group", serializer.encodingObjGVK.Group; e != a {
|
||||
t.Errorf("expected group to be %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
43
vendor/k8s.io/apimachinery/pkg/runtime/swagger_doc_generator_test.go
generated
vendored
43
vendor/k8s.io/apimachinery/pkg/runtime/swagger_doc_generator_test.go
generated
vendored
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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 runtime
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFmtRawDoc(t *testing.T) {
|
||||
tests := []struct {
|
||||
t, expected string
|
||||
}{
|
||||
{"aaa\n --- asd\n TODO: tooooodo\n toooodoooooo\n", "aaa"},
|
||||
{"aaa\nasd\n TODO: tooooodo\nbbbb\n --- toooodoooooo\n", "aaa asd bbbb"},
|
||||
{" TODO: tooooodo\n", ""},
|
||||
{"Par1\n\nPar2\n\n", "Par1\\n\\nPar2"},
|
||||
{"", ""},
|
||||
{" ", ""},
|
||||
{" \n", ""},
|
||||
{" \n\n ", ""},
|
||||
{"Example:\n\tl1\n\t\tl2\n", "Example:\\n\\tl1\\n\\t\\tl2"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
if o := fmtRawDoc(test.t); o != test.expected {
|
||||
t.Fatalf("Expected: %q, got %q", test.expected, o)
|
||||
}
|
||||
}
|
||||
}
|
||||
25
vendor/k8s.io/apimachinery/pkg/selection/BUILD
generated
vendored
25
vendor/k8s.io/apimachinery/pkg/selection/BUILD
generated
vendored
|
|
@ -1,25 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["operator.go"],
|
||||
importpath = "k8s.io/apimachinery/pkg/selection",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
31
vendor/k8s.io/apimachinery/pkg/types/BUILD
generated
vendored
31
vendor/k8s.io/apimachinery/pkg/types/BUILD
generated
vendored
|
|
@ -1,31 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"namespacedname.go",
|
||||
"nodename.go",
|
||||
"patch.go",
|
||||
"uid.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/types",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
43
vendor/k8s.io/apimachinery/pkg/util/cache/BUILD
generated
vendored
43
vendor/k8s.io/apimachinery/pkg/util/cache/BUILD
generated
vendored
|
|
@ -1,43 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"cache_test.go",
|
||||
"lruexpirecache_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/github.com/golang/groupcache/lru:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/clock:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"cache.go",
|
||||
"lruexpirecache.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/util/cache",
|
||||
deps = ["//vendor/github.com/hashicorp/golang-lru:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
90
vendor/k8s.io/apimachinery/pkg/util/cache/cache_test.go
generated
vendored
90
vendor/k8s.io/apimachinery/pkg/util/cache/cache_test.go
generated
vendored
|
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 cache
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
maxTestCacheSize int = shardsCount * 2
|
||||
)
|
||||
|
||||
func ExpectEntry(t *testing.T, cache Cache, index uint64, expectedValue interface{}) bool {
|
||||
elem, found := cache.Get(index)
|
||||
if !found {
|
||||
t.Errorf("Expected to find entry with key %d", index)
|
||||
return false
|
||||
} else if elem != expectedValue {
|
||||
t.Errorf("Expected to find %v, got %v", expectedValue, elem)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func TestBasic(t *testing.T) {
|
||||
cache := NewCache(maxTestCacheSize)
|
||||
cache.Add(1, "xxx")
|
||||
ExpectEntry(t, cache, 1, "xxx")
|
||||
}
|
||||
|
||||
func TestOverflow(t *testing.T) {
|
||||
cache := NewCache(maxTestCacheSize)
|
||||
for i := 0; i < maxTestCacheSize+1; i++ {
|
||||
cache.Add(uint64(i), "xxx")
|
||||
}
|
||||
foundIndexes := make([]uint64, 0)
|
||||
for i := 0; i < maxTestCacheSize+1; i++ {
|
||||
_, found := cache.Get(uint64(i))
|
||||
if found {
|
||||
foundIndexes = append(foundIndexes, uint64(i))
|
||||
}
|
||||
}
|
||||
if len(foundIndexes) != maxTestCacheSize {
|
||||
t.Errorf("Expect to find %d elements, got %d %v", maxTestCacheSize, len(foundIndexes), foundIndexes)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverwrite(t *testing.T) {
|
||||
cache := NewCache(maxTestCacheSize)
|
||||
cache.Add(1, "xxx")
|
||||
ExpectEntry(t, cache, 1, "xxx")
|
||||
cache.Add(1, "yyy")
|
||||
ExpectEntry(t, cache, 1, "yyy")
|
||||
}
|
||||
|
||||
// TestEvict this test will fail sporatically depending on what add()
|
||||
// selects for the randomKey to be evicted. Ensure that randomKey
|
||||
// is never the key we most recently added. Since the chance of failure
|
||||
// on each evict is 50%, if we do it 7 times, it should catch the problem
|
||||
// if it exists >99% of the time.
|
||||
func TestEvict(t *testing.T) {
|
||||
cache := NewCache(shardsCount)
|
||||
var found bool
|
||||
for retry := 0; retry < 7; retry++ {
|
||||
cache.Add(uint64(shardsCount), "xxx")
|
||||
found = ExpectEntry(t, cache, uint64(shardsCount), "xxx")
|
||||
if !found {
|
||||
break
|
||||
}
|
||||
cache.Add(0, "xxx")
|
||||
found = ExpectEntry(t, cache, 0, "xxx")
|
||||
if !found {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
68
vendor/k8s.io/apimachinery/pkg/util/cache/lruexpirecache_test.go
generated
vendored
68
vendor/k8s.io/apimachinery/pkg/util/cache/lruexpirecache_test.go
generated
vendored
|
|
@ -1,68 +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 cache
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/clock"
|
||||
|
||||
"github.com/golang/groupcache/lru"
|
||||
)
|
||||
|
||||
func expectEntry(t *testing.T, c *LRUExpireCache, key lru.Key, value interface{}) {
|
||||
result, ok := c.Get(key)
|
||||
if !ok || result != value {
|
||||
t.Errorf("Expected cache[%v]: %v, got %v", key, value, result)
|
||||
}
|
||||
}
|
||||
|
||||
func expectNotEntry(t *testing.T, c *LRUExpireCache, key lru.Key) {
|
||||
if result, ok := c.Get(key); ok {
|
||||
t.Errorf("Expected cache[%v] to be empty, got %v", key, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSimpleGet(t *testing.T) {
|
||||
c := NewLRUExpireCache(10)
|
||||
c.Add("long-lived", "12345", 10*time.Hour)
|
||||
expectEntry(t, c, "long-lived", "12345")
|
||||
}
|
||||
|
||||
func TestExpiredGet(t *testing.T) {
|
||||
fakeClock := clock.NewFakeClock(time.Now())
|
||||
c := NewLRUExpireCacheWithClock(10, fakeClock)
|
||||
c.Add("short-lived", "12345", 1*time.Millisecond)
|
||||
// ensure the entry expired
|
||||
fakeClock.Step(2 * time.Millisecond)
|
||||
expectNotEntry(t, c, "short-lived")
|
||||
}
|
||||
|
||||
func TestLRUOverflow(t *testing.T) {
|
||||
c := NewLRUExpireCache(4)
|
||||
c.Add("elem1", "1", 10*time.Hour)
|
||||
c.Add("elem2", "2", 10*time.Hour)
|
||||
c.Add("elem3", "3", 10*time.Hour)
|
||||
c.Add("elem4", "4", 10*time.Hour)
|
||||
c.Add("elem5", "5", 10*time.Hour)
|
||||
expectNotEntry(t, c, "elem1")
|
||||
expectEntry(t, c, "elem2", "2")
|
||||
expectEntry(t, c, "elem3", "3")
|
||||
expectEntry(t, c, "elem4", "4")
|
||||
expectEntry(t, c, "elem5", "5")
|
||||
}
|
||||
32
vendor/k8s.io/apimachinery/pkg/util/clock/BUILD
generated
vendored
32
vendor/k8s.io/apimachinery/pkg/util/clock/BUILD
generated
vendored
|
|
@ -1,32 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["clock_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["clock.go"],
|
||||
importpath = "k8s.io/apimachinery/pkg/util/clock",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
184
vendor/k8s.io/apimachinery/pkg/util/clock/clock_test.go
generated
vendored
184
vendor/k8s.io/apimachinery/pkg/util/clock/clock_test.go
generated
vendored
|
|
@ -1,184 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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 clock
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestFakeClock(t *testing.T) {
|
||||
startTime := time.Now()
|
||||
tc := NewFakeClock(startTime)
|
||||
tc.Step(time.Second)
|
||||
now := tc.Now()
|
||||
if now.Sub(startTime) != time.Second {
|
||||
t.Errorf("input: %s now=%s gap=%s expected=%s", startTime, now, now.Sub(startTime), time.Second)
|
||||
}
|
||||
|
||||
tt := tc.Now()
|
||||
tc.SetTime(tt.Add(time.Hour))
|
||||
if tc.Now().Sub(tt) != time.Hour {
|
||||
t.Errorf("input: %s now=%s gap=%s expected=%s", tt, tc.Now(), tc.Now().Sub(tt), time.Hour)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFakeClockSleep(t *testing.T) {
|
||||
startTime := time.Now()
|
||||
tc := NewFakeClock(startTime)
|
||||
tc.Sleep(time.Duration(1) * time.Hour)
|
||||
now := tc.Now()
|
||||
if now.Sub(startTime) != time.Hour {
|
||||
t.Errorf("Fake sleep failed, expected time to advance by one hour, instead, its %v", now.Sub(startTime))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFakeAfter(t *testing.T) {
|
||||
tc := NewFakeClock(time.Now())
|
||||
if tc.HasWaiters() {
|
||||
t.Errorf("unexpected waiter?")
|
||||
}
|
||||
oneSec := tc.After(time.Second)
|
||||
if !tc.HasWaiters() {
|
||||
t.Errorf("unexpected lack of waiter?")
|
||||
}
|
||||
|
||||
oneOhOneSec := tc.After(time.Second + time.Millisecond)
|
||||
twoSec := tc.After(2 * time.Second)
|
||||
select {
|
||||
case <-oneSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
case <-oneOhOneSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
case <-twoSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
default:
|
||||
}
|
||||
|
||||
tc.Step(999 * time.Millisecond)
|
||||
select {
|
||||
case <-oneSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
case <-oneOhOneSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
case <-twoSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
default:
|
||||
}
|
||||
|
||||
tc.Step(time.Millisecond)
|
||||
select {
|
||||
case <-oneSec:
|
||||
// Expected!
|
||||
case <-oneOhOneSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
case <-twoSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
default:
|
||||
t.Errorf("unexpected non-channel read")
|
||||
}
|
||||
tc.Step(time.Millisecond)
|
||||
select {
|
||||
case <-oneSec:
|
||||
// should not double-trigger!
|
||||
t.Errorf("unexpected channel read")
|
||||
case <-oneOhOneSec:
|
||||
// Expected!
|
||||
case <-twoSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
default:
|
||||
t.Errorf("unexpected non-channel read")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFakeTick(t *testing.T) {
|
||||
tc := NewFakeClock(time.Now())
|
||||
if tc.HasWaiters() {
|
||||
t.Errorf("unexpected waiter?")
|
||||
}
|
||||
oneSec := tc.Tick(time.Second)
|
||||
if !tc.HasWaiters() {
|
||||
t.Errorf("unexpected lack of waiter?")
|
||||
}
|
||||
|
||||
oneOhOneSec := tc.Tick(time.Second + time.Millisecond)
|
||||
twoSec := tc.Tick(2 * time.Second)
|
||||
select {
|
||||
case <-oneSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
case <-oneOhOneSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
case <-twoSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
default:
|
||||
}
|
||||
|
||||
tc.Step(999 * time.Millisecond) // t=.999
|
||||
select {
|
||||
case <-oneSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
case <-oneOhOneSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
case <-twoSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
default:
|
||||
}
|
||||
|
||||
tc.Step(time.Millisecond) // t=1.000
|
||||
select {
|
||||
case <-oneSec:
|
||||
// Expected!
|
||||
case <-oneOhOneSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
case <-twoSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
default:
|
||||
t.Errorf("unexpected non-channel read")
|
||||
}
|
||||
tc.Step(time.Millisecond) // t=1.001
|
||||
select {
|
||||
case <-oneSec:
|
||||
// should not double-trigger!
|
||||
t.Errorf("unexpected channel read")
|
||||
case <-oneOhOneSec:
|
||||
// Expected!
|
||||
case <-twoSec:
|
||||
t.Errorf("unexpected channel read")
|
||||
default:
|
||||
t.Errorf("unexpected non-channel read")
|
||||
}
|
||||
|
||||
tc.Step(time.Second) // t=2.001
|
||||
tc.Step(time.Second) // t=3.001
|
||||
tc.Step(time.Second) // t=4.001
|
||||
tc.Step(time.Second) // t=5.001
|
||||
|
||||
// The one second ticker should not accumulate ticks
|
||||
accumulatedTicks := 0
|
||||
drained := false
|
||||
for !drained {
|
||||
select {
|
||||
case <-oneSec:
|
||||
accumulatedTicks++
|
||||
default:
|
||||
drained = true
|
||||
}
|
||||
}
|
||||
if accumulatedTicks != 1 {
|
||||
t.Errorf("unexpected number of accumulated ticks: %d", accumulatedTicks)
|
||||
}
|
||||
}
|
||||
36
vendor/k8s.io/apimachinery/pkg/util/diff/BUILD
generated
vendored
36
vendor/k8s.io/apimachinery/pkg/util/diff/BUILD
generated
vendored
|
|
@ -1,36 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["diff_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["diff.go"],
|
||||
importpath = "k8s.io/apimachinery/pkg/util/diff",
|
||||
deps = [
|
||||
"//vendor/github.com/davecgh/go-spew/spew:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
96
vendor/k8s.io/apimachinery/pkg/util/diff/diff_test.go
generated
vendored
96
vendor/k8s.io/apimachinery/pkg/util/diff/diff_test.go
generated
vendored
|
|
@ -1,96 +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 diff
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestObjectReflectDiff(t *testing.T) {
|
||||
type struct1 struct{ A []int }
|
||||
|
||||
testCases := map[string]struct {
|
||||
a, b interface{}
|
||||
out string
|
||||
}{
|
||||
"map": {
|
||||
a: map[string]int{},
|
||||
b: map[string]int{},
|
||||
},
|
||||
"detect nil map": {
|
||||
a: map[string]int(nil),
|
||||
b: map[string]int{},
|
||||
out: `
|
||||
object:
|
||||
a: map[string]int(nil)
|
||||
b: map[string]int{}`,
|
||||
},
|
||||
"detect map changes": {
|
||||
a: map[string]int{"test": 1, "other": 2},
|
||||
b: map[string]int{"test": 2, "third": 3},
|
||||
out: `
|
||||
object[other]:
|
||||
a: 2
|
||||
b: <nil>
|
||||
object[test]:
|
||||
a: 1
|
||||
b: 2
|
||||
object[third]:
|
||||
a: <nil>
|
||||
b: 3`,
|
||||
},
|
||||
"nil slice": {a: struct1{A: nil}, b: struct1{A: nil}},
|
||||
"empty slice": {a: struct1{A: []int{}}, b: struct1{A: []int{}}},
|
||||
"detect slice changes 1": {a: struct1{A: []int{1}}, b: struct1{A: []int{2}}, out: `
|
||||
object.A[0]:
|
||||
a: 1
|
||||
b: 2`,
|
||||
},
|
||||
"detect slice changes 2": {a: struct1{A: []int{}}, b: struct1{A: []int{2}}, out: `
|
||||
object.A[0]:
|
||||
a: <nil>
|
||||
b: 2`,
|
||||
},
|
||||
"detect slice changes 3": {a: struct1{A: []int{1}}, b: struct1{A: []int{}}, out: `
|
||||
object.A[0]:
|
||||
a: 1
|
||||
b: <nil>`,
|
||||
},
|
||||
"detect nil vs empty slices": {a: struct1{A: nil}, b: struct1{A: []int{}}, out: `
|
||||
object.A:
|
||||
a: []int(nil)
|
||||
b: []int{}`,
|
||||
},
|
||||
}
|
||||
for name, test := range testCases {
|
||||
expect := test.out
|
||||
if len(expect) == 0 {
|
||||
expect = "<no diffs>"
|
||||
}
|
||||
if actual := ObjectReflectDiff(test.a, test.b); actual != expect {
|
||||
t.Errorf("%s: unexpected output: %s", name, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringDiff(t *testing.T) {
|
||||
diff := StringDiff("aaabb", "aaacc")
|
||||
expect := "aaa\n\nA: bb\n\nB: cc\n\n"
|
||||
if diff != expect {
|
||||
t.Errorf("diff returned %v", diff)
|
||||
}
|
||||
}
|
||||
35
vendor/k8s.io/apimachinery/pkg/util/errors/BUILD
generated
vendored
35
vendor/k8s.io/apimachinery/pkg/util/errors/BUILD
generated
vendored
|
|
@ -1,35 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["errors_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"errors.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/util/errors",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
368
vendor/k8s.io/apimachinery/pkg/util/errors/errors_test.go
generated
vendored
368
vendor/k8s.io/apimachinery/pkg/util/errors/errors_test.go
generated
vendored
|
|
@ -1,368 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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 errors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEmptyAggregate(t *testing.T) {
|
||||
var slice []error
|
||||
var agg Aggregate
|
||||
var err error
|
||||
|
||||
agg = NewAggregate(slice)
|
||||
if agg != nil {
|
||||
t.Errorf("expected nil, got %#v", agg)
|
||||
}
|
||||
err = NewAggregate(slice)
|
||||
if err != nil {
|
||||
t.Errorf("expected nil, got %#v", err)
|
||||
}
|
||||
|
||||
// This is not normally possible, but pedantry demands I test it.
|
||||
agg = aggregate(slice) // empty aggregate
|
||||
if s := agg.Error(); s != "" {
|
||||
t.Errorf("expected empty string, got %q", s)
|
||||
}
|
||||
if s := agg.Errors(); len(s) != 0 {
|
||||
t.Errorf("expected empty slice, got %#v", s)
|
||||
}
|
||||
err = agg.(error)
|
||||
if s := err.Error(); s != "" {
|
||||
t.Errorf("expected empty string, got %q", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAggregateWithNil(t *testing.T) {
|
||||
var slice []error
|
||||
slice = []error{nil}
|
||||
var agg Aggregate
|
||||
var err error
|
||||
|
||||
agg = NewAggregate(slice)
|
||||
if agg != nil {
|
||||
t.Errorf("expected nil, got %#v", agg)
|
||||
}
|
||||
err = NewAggregate(slice)
|
||||
if err != nil {
|
||||
t.Errorf("expected nil, got %#v", err)
|
||||
}
|
||||
|
||||
// Append a non-nil error
|
||||
slice = append(slice, fmt.Errorf("err"))
|
||||
agg = NewAggregate(slice)
|
||||
if agg == nil {
|
||||
t.Errorf("expected non-nil")
|
||||
}
|
||||
if s := agg.Error(); s != "err" {
|
||||
t.Errorf("expected 'err', got %q", s)
|
||||
}
|
||||
if s := agg.Errors(); len(s) != 1 {
|
||||
t.Errorf("expected one-element slice, got %#v", s)
|
||||
}
|
||||
if s := agg.Errors()[0].Error(); s != "err" {
|
||||
t.Errorf("expected 'err', got %q", s)
|
||||
}
|
||||
|
||||
err = agg.(error)
|
||||
if err == nil {
|
||||
t.Errorf("expected non-nil")
|
||||
}
|
||||
if s := err.Error(); s != "err" {
|
||||
t.Errorf("expected 'err', got %q", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSingularAggregate(t *testing.T) {
|
||||
var slice []error = []error{fmt.Errorf("err")}
|
||||
var agg Aggregate
|
||||
var err error
|
||||
|
||||
agg = NewAggregate(slice)
|
||||
if agg == nil {
|
||||
t.Errorf("expected non-nil")
|
||||
}
|
||||
if s := agg.Error(); s != "err" {
|
||||
t.Errorf("expected 'err', got %q", s)
|
||||
}
|
||||
if s := agg.Errors(); len(s) != 1 {
|
||||
t.Errorf("expected one-element slice, got %#v", s)
|
||||
}
|
||||
if s := agg.Errors()[0].Error(); s != "err" {
|
||||
t.Errorf("expected 'err', got %q", s)
|
||||
}
|
||||
|
||||
err = agg.(error)
|
||||
if err == nil {
|
||||
t.Errorf("expected non-nil")
|
||||
}
|
||||
if s := err.Error(); s != "err" {
|
||||
t.Errorf("expected 'err', got %q", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPluralAggregate(t *testing.T) {
|
||||
var slice []error = []error{fmt.Errorf("abc"), fmt.Errorf("123")}
|
||||
var agg Aggregate
|
||||
var err error
|
||||
|
||||
agg = NewAggregate(slice)
|
||||
if agg == nil {
|
||||
t.Errorf("expected non-nil")
|
||||
}
|
||||
if s := agg.Error(); s != "[abc, 123]" {
|
||||
t.Errorf("expected '[abc, 123]', got %q", s)
|
||||
}
|
||||
if s := agg.Errors(); len(s) != 2 {
|
||||
t.Errorf("expected two-elements slice, got %#v", s)
|
||||
}
|
||||
if s := agg.Errors()[0].Error(); s != "abc" {
|
||||
t.Errorf("expected '[abc, 123]', got %q", s)
|
||||
}
|
||||
|
||||
err = agg.(error)
|
||||
if err == nil {
|
||||
t.Errorf("expected non-nil")
|
||||
}
|
||||
if s := err.Error(); s != "[abc, 123]" {
|
||||
t.Errorf("expected '[abc, 123]', got %q", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterOut(t *testing.T) {
|
||||
testCases := []struct {
|
||||
err error
|
||||
filter []Matcher
|
||||
expected error
|
||||
}{
|
||||
{
|
||||
nil,
|
||||
[]Matcher{},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
aggregate{},
|
||||
[]Matcher{},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
aggregate{fmt.Errorf("abc")},
|
||||
[]Matcher{},
|
||||
aggregate{fmt.Errorf("abc")},
|
||||
},
|
||||
{
|
||||
aggregate{fmt.Errorf("abc")},
|
||||
[]Matcher{func(err error) bool { return false }},
|
||||
aggregate{fmt.Errorf("abc")},
|
||||
},
|
||||
{
|
||||
aggregate{fmt.Errorf("abc")},
|
||||
[]Matcher{func(err error) bool { return true }},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
aggregate{fmt.Errorf("abc")},
|
||||
[]Matcher{func(err error) bool { return false }, func(err error) bool { return false }},
|
||||
aggregate{fmt.Errorf("abc")},
|
||||
},
|
||||
{
|
||||
aggregate{fmt.Errorf("abc")},
|
||||
[]Matcher{func(err error) bool { return false }, func(err error) bool { return true }},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
aggregate{fmt.Errorf("abc"), fmt.Errorf("def"), fmt.Errorf("ghi")},
|
||||
[]Matcher{func(err error) bool { return err.Error() == "def" }},
|
||||
aggregate{fmt.Errorf("abc"), fmt.Errorf("ghi")},
|
||||
},
|
||||
{
|
||||
aggregate{aggregate{fmt.Errorf("abc")}},
|
||||
[]Matcher{},
|
||||
aggregate{aggregate{fmt.Errorf("abc")}},
|
||||
},
|
||||
{
|
||||
aggregate{aggregate{fmt.Errorf("abc"), aggregate{fmt.Errorf("def")}}},
|
||||
[]Matcher{},
|
||||
aggregate{aggregate{fmt.Errorf("abc"), aggregate{fmt.Errorf("def")}}},
|
||||
},
|
||||
{
|
||||
aggregate{aggregate{fmt.Errorf("abc"), aggregate{fmt.Errorf("def")}}},
|
||||
[]Matcher{func(err error) bool { return err.Error() == "def" }},
|
||||
aggregate{aggregate{fmt.Errorf("abc")}},
|
||||
},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
err := FilterOut(testCase.err, testCase.filter...)
|
||||
if !reflect.DeepEqual(testCase.expected, err) {
|
||||
t.Errorf("%d: expected %v, got %v", i, testCase.expected, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlatten(t *testing.T) {
|
||||
testCases := []struct {
|
||||
agg Aggregate
|
||||
expected Aggregate
|
||||
}{
|
||||
{
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
aggregate{},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
aggregate{fmt.Errorf("abc")},
|
||||
aggregate{fmt.Errorf("abc")},
|
||||
},
|
||||
{
|
||||
aggregate{fmt.Errorf("abc"), fmt.Errorf("def"), fmt.Errorf("ghi")},
|
||||
aggregate{fmt.Errorf("abc"), fmt.Errorf("def"), fmt.Errorf("ghi")},
|
||||
},
|
||||
{
|
||||
aggregate{aggregate{fmt.Errorf("abc")}},
|
||||
aggregate{fmt.Errorf("abc")},
|
||||
},
|
||||
{
|
||||
aggregate{aggregate{aggregate{fmt.Errorf("abc")}}},
|
||||
aggregate{fmt.Errorf("abc")},
|
||||
},
|
||||
{
|
||||
aggregate{aggregate{fmt.Errorf("abc"), aggregate{fmt.Errorf("def")}}},
|
||||
aggregate{fmt.Errorf("abc"), fmt.Errorf("def")},
|
||||
},
|
||||
{
|
||||
aggregate{aggregate{aggregate{fmt.Errorf("abc")}, fmt.Errorf("def"), aggregate{fmt.Errorf("ghi")}}},
|
||||
aggregate{fmt.Errorf("abc"), fmt.Errorf("def"), fmt.Errorf("ghi")},
|
||||
},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
agg := Flatten(testCase.agg)
|
||||
if !reflect.DeepEqual(testCase.expected, agg) {
|
||||
t.Errorf("%d: expected %v, got %v", i, testCase.expected, agg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateAggregateFromMessageCountMap(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
mcm MessageCountMap
|
||||
expected Aggregate
|
||||
}{
|
||||
{
|
||||
"input has single instance of one message",
|
||||
MessageCountMap{"abc": 1},
|
||||
aggregate{fmt.Errorf("abc")},
|
||||
},
|
||||
{
|
||||
"input has multiple messages",
|
||||
MessageCountMap{"abc": 2, "ghi": 1},
|
||||
aggregate{fmt.Errorf("abc (repeated 2 times)"), fmt.Errorf("ghi")},
|
||||
},
|
||||
{
|
||||
"input has multiple messages",
|
||||
MessageCountMap{"ghi": 1, "abc": 2},
|
||||
aggregate{fmt.Errorf("abc (repeated 2 times)"), fmt.Errorf("ghi")},
|
||||
},
|
||||
}
|
||||
|
||||
var expected, agg []error
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
if testCase.expected != nil {
|
||||
expected = testCase.expected.Errors()
|
||||
sort.Slice(expected, func(i, j int) bool { return expected[i].Error() < expected[j].Error() })
|
||||
}
|
||||
if testCase.mcm != nil {
|
||||
agg = CreateAggregateFromMessageCountMap(testCase.mcm).Errors()
|
||||
sort.Slice(agg, func(i, j int) bool { return agg[i].Error() < agg[j].Error() })
|
||||
}
|
||||
if !reflect.DeepEqual(expected, agg) {
|
||||
t.Errorf("expected %v, got %v", expected, agg)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAggregateGoroutines(t *testing.T) {
|
||||
testCases := []struct {
|
||||
errs []error
|
||||
expected map[string]bool // can't compare directly to Aggregate due to non-deterministic ordering
|
||||
}{
|
||||
{
|
||||
[]error{},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
[]error{nil},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
[]error{nil, nil},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
[]error{fmt.Errorf("1")},
|
||||
map[string]bool{"1": true},
|
||||
},
|
||||
{
|
||||
[]error{fmt.Errorf("1"), nil},
|
||||
map[string]bool{"1": true},
|
||||
},
|
||||
{
|
||||
[]error{fmt.Errorf("1"), fmt.Errorf("267")},
|
||||
map[string]bool{"1": true, "267": true},
|
||||
},
|
||||
{
|
||||
[]error{fmt.Errorf("1"), nil, fmt.Errorf("1234")},
|
||||
map[string]bool{"1": true, "1234": true},
|
||||
},
|
||||
{
|
||||
[]error{nil, fmt.Errorf("1"), nil, fmt.Errorf("1234"), fmt.Errorf("22")},
|
||||
map[string]bool{"1": true, "1234": true, "22": true},
|
||||
},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
funcs := make([]func() error, len(testCase.errs))
|
||||
for i := range testCase.errs {
|
||||
err := testCase.errs[i]
|
||||
funcs[i] = func() error { return err }
|
||||
}
|
||||
agg := AggregateGoroutines(funcs...)
|
||||
if agg == nil {
|
||||
if len(testCase.expected) > 0 {
|
||||
t.Errorf("%d: expected %v, got nil", i, testCase.expected)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if len(agg.Errors()) != len(testCase.expected) {
|
||||
t.Errorf("%d: expected %d errors in aggregate, got %v", i, len(testCase.expected), agg)
|
||||
continue
|
||||
}
|
||||
for _, err := range agg.Errors() {
|
||||
if !testCase.expected[err.Error()] {
|
||||
t.Errorf("%d: expected %v, got aggregate containing %v", i, testCase.expected, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
vendor/k8s.io/apimachinery/pkg/util/framer/BUILD
generated
vendored
32
vendor/k8s.io/apimachinery/pkg/util/framer/BUILD
generated
vendored
|
|
@ -1,32 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["framer_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["framer.go"],
|
||||
importpath = "k8s.io/apimachinery/pkg/util/framer",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
176
vendor/k8s.io/apimachinery/pkg/util/framer/framer_test.go
generated
vendored
176
vendor/k8s.io/apimachinery/pkg/util/framer/framer_test.go
generated
vendored
|
|
@ -1,176 +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 framer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRead(t *testing.T) {
|
||||
data := []byte{
|
||||
0x00, 0x00, 0x00, 0x04,
|
||||
0x01, 0x02, 0x03, 0x04,
|
||||
0x00, 0x00, 0x00, 0x03,
|
||||
0x05, 0x06, 0x07,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x08,
|
||||
}
|
||||
b := bytes.NewBuffer(data)
|
||||
r := NewLengthDelimitedFrameReader(ioutil.NopCloser(b))
|
||||
buf := make([]byte, 1)
|
||||
if n, err := r.Read(buf); err != io.ErrShortBuffer && n != 1 && bytes.Equal(buf, []byte{0x01}) {
|
||||
t.Fatalf("unexpected: %v %d %v", err, n, buf)
|
||||
}
|
||||
if n, err := r.Read(buf); err != io.ErrShortBuffer && n != 1 && bytes.Equal(buf, []byte{0x02}) {
|
||||
t.Fatalf("unexpected: %v %d %v", err, n, buf)
|
||||
}
|
||||
// read the remaining frame
|
||||
buf = make([]byte, 2)
|
||||
if n, err := r.Read(buf); err != nil && n != 2 && bytes.Equal(buf, []byte{0x03, 0x04}) {
|
||||
t.Fatalf("unexpected: %v %d %v", err, n, buf)
|
||||
}
|
||||
// read with buffer equal to frame
|
||||
buf = make([]byte, 3)
|
||||
if n, err := r.Read(buf); err != nil && n != 3 && bytes.Equal(buf, []byte{0x05, 0x06, 0x07}) {
|
||||
t.Fatalf("unexpected: %v %d %v", err, n, buf)
|
||||
}
|
||||
// read empty frame
|
||||
buf = make([]byte, 3)
|
||||
if n, err := r.Read(buf); err != nil && n != 0 && bytes.Equal(buf, []byte{}) {
|
||||
t.Fatalf("unexpected: %v %d %v", err, n, buf)
|
||||
}
|
||||
// read with larger buffer than frame
|
||||
buf = make([]byte, 3)
|
||||
if n, err := r.Read(buf); err != nil && n != 1 && bytes.Equal(buf, []byte{0x08}) {
|
||||
t.Fatalf("unexpected: %v %d %v", err, n, buf)
|
||||
}
|
||||
// read EOF
|
||||
if n, err := r.Read(buf); err != io.EOF && n != 0 {
|
||||
t.Fatalf("unexpected: %v %d", err, n)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadLarge(t *testing.T) {
|
||||
data := []byte{
|
||||
0x00, 0x00, 0x00, 0x04,
|
||||
0x01, 0x02, 0x03, 0x04,
|
||||
0x00, 0x00, 0x00, 0x03,
|
||||
0x05, 0x06, 0x07,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
0x08,
|
||||
}
|
||||
b := bytes.NewBuffer(data)
|
||||
r := NewLengthDelimitedFrameReader(ioutil.NopCloser(b))
|
||||
buf := make([]byte, 40)
|
||||
if n, err := r.Read(buf); err != nil && n != 4 && bytes.Equal(buf, []byte{0x01, 0x02, 0x03, 0x04}) {
|
||||
t.Fatalf("unexpected: %v %d %v", err, n, buf)
|
||||
}
|
||||
if n, err := r.Read(buf); err != nil && n != 3 && bytes.Equal(buf, []byte{0x05, 0x06, 0x7}) {
|
||||
t.Fatalf("unexpected: %v %d %v", err, n, buf)
|
||||
}
|
||||
if n, err := r.Read(buf); err != nil && n != 0 && bytes.Equal(buf, []byte{}) {
|
||||
t.Fatalf("unexpected: %v %d %v", err, n, buf)
|
||||
}
|
||||
if n, err := r.Read(buf); err != nil && n != 1 && bytes.Equal(buf, []byte{0x08}) {
|
||||
t.Fatalf("unexpected: %v %d %v", err, n, buf)
|
||||
}
|
||||
// read EOF
|
||||
if n, err := r.Read(buf); err != io.EOF && n != 0 {
|
||||
t.Fatalf("unexpected: %v %d", err, n)
|
||||
}
|
||||
}
|
||||
func TestReadInvalidFrame(t *testing.T) {
|
||||
data := []byte{
|
||||
0x00, 0x00, 0x00, 0x04,
|
||||
0x01, 0x02,
|
||||
}
|
||||
b := bytes.NewBuffer(data)
|
||||
r := NewLengthDelimitedFrameReader(ioutil.NopCloser(b))
|
||||
buf := make([]byte, 1)
|
||||
if n, err := r.Read(buf); err != io.ErrShortBuffer && n != 1 && bytes.Equal(buf, []byte{0x01}) {
|
||||
t.Fatalf("unexpected: %v %d %v", err, n, buf)
|
||||
}
|
||||
// read the remaining frame
|
||||
buf = make([]byte, 3)
|
||||
if n, err := r.Read(buf); err != io.ErrUnexpectedEOF && n != 1 && bytes.Equal(buf, []byte{0x02}) {
|
||||
t.Fatalf("unexpected: %v %d %v", err, n, buf)
|
||||
}
|
||||
// read EOF
|
||||
if n, err := r.Read(buf); err != io.EOF && n != 0 {
|
||||
t.Fatalf("unexpected: %v %d", err, n)
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONFrameReader(t *testing.T) {
|
||||
b := bytes.NewBufferString("{\"test\":true}\n1\n[\"a\"]")
|
||||
r := NewJSONFramedReader(ioutil.NopCloser(b))
|
||||
buf := make([]byte, 20)
|
||||
if n, err := r.Read(buf); err != nil || n != 13 || string(buf[:n]) != `{"test":true}` {
|
||||
t.Fatalf("unexpected: %v %d %q", err, n, buf)
|
||||
}
|
||||
if n, err := r.Read(buf); err != nil || n != 1 || string(buf[:n]) != `1` {
|
||||
t.Fatalf("unexpected: %v %d %q", err, n, buf)
|
||||
}
|
||||
if n, err := r.Read(buf); err != nil || n != 5 || string(buf[:n]) != `["a"]` {
|
||||
t.Fatalf("unexpected: %v %d %q", err, n, buf)
|
||||
}
|
||||
if n, err := r.Read(buf); err != io.EOF || n != 0 {
|
||||
t.Fatalf("unexpected: %v %d %q", err, n, buf)
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONFrameReaderShortBuffer(t *testing.T) {
|
||||
b := bytes.NewBufferString("{\"test\":true}\n1\n[\"a\"]")
|
||||
r := NewJSONFramedReader(ioutil.NopCloser(b))
|
||||
buf := make([]byte, 3)
|
||||
|
||||
if n, err := r.Read(buf); err != io.ErrShortBuffer || n != 3 || string(buf[:n]) != `{"t` {
|
||||
t.Fatalf("unexpected: %v %d %q", err, n, buf)
|
||||
}
|
||||
if n, err := r.Read(buf); err != io.ErrShortBuffer || n != 3 || string(buf[:n]) != `est` {
|
||||
t.Fatalf("unexpected: %v %d %q", err, n, buf)
|
||||
}
|
||||
if n, err := r.Read(buf); err != io.ErrShortBuffer || n != 3 || string(buf[:n]) != `":t` {
|
||||
t.Fatalf("unexpected: %v %d %q", err, n, buf)
|
||||
}
|
||||
if n, err := r.Read(buf); err != io.ErrShortBuffer || n != 3 || string(buf[:n]) != `rue` {
|
||||
t.Fatalf("unexpected: %v %d %q", err, n, buf)
|
||||
}
|
||||
if n, err := r.Read(buf); err != nil || n != 1 || string(buf[:n]) != `}` {
|
||||
t.Fatalf("unexpected: %v %d %q", err, n, buf)
|
||||
}
|
||||
|
||||
if n, err := r.Read(buf); err != nil || n != 1 || string(buf[:n]) != `1` {
|
||||
t.Fatalf("unexpected: %v %d %q", err, n, buf)
|
||||
}
|
||||
|
||||
if n, err := r.Read(buf); err != io.ErrShortBuffer || n != 3 || string(buf[:n]) != `["a` {
|
||||
t.Fatalf("unexpected: %v %d %q", err, n, buf)
|
||||
}
|
||||
if n, err := r.Read(buf); err != nil || n != 2 || string(buf[:n]) != `"]` {
|
||||
t.Fatalf("unexpected: %v %d %q", err, n, buf)
|
||||
}
|
||||
|
||||
if n, err := r.Read(buf); err != io.EOF || n != 0 {
|
||||
t.Fatalf("unexpected: %v %d %q", err, n, buf)
|
||||
}
|
||||
}
|
||||
38
vendor/k8s.io/apimachinery/pkg/util/httpstream/BUILD
generated
vendored
38
vendor/k8s.io/apimachinery/pkg/util/httpstream/BUILD
generated
vendored
|
|
@ -1,38 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["httpstream_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"httpstream.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/util/httpstream",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/httpstream/spdy:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
125
vendor/k8s.io/apimachinery/pkg/util/httpstream/httpstream_test.go
generated
vendored
125
vendor/k8s.io/apimachinery/pkg/util/httpstream/httpstream_test.go
generated
vendored
|
|
@ -1,125 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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 httpstream
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type responseWriter struct {
|
||||
header http.Header
|
||||
statusCode *int
|
||||
}
|
||||
|
||||
func newResponseWriter() *responseWriter {
|
||||
return &responseWriter{
|
||||
header: make(http.Header),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *responseWriter) Header() http.Header {
|
||||
return r.header
|
||||
}
|
||||
|
||||
func (r *responseWriter) WriteHeader(code int) {
|
||||
r.statusCode = &code
|
||||
}
|
||||
|
||||
func (r *responseWriter) Write([]byte) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func TestHandshake(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
clientProtocols []string
|
||||
serverProtocols []string
|
||||
expectedProtocol string
|
||||
expectError bool
|
||||
}{
|
||||
"no client protocols": {
|
||||
clientProtocols: []string{},
|
||||
serverProtocols: []string{"a", "b"},
|
||||
expectedProtocol: "",
|
||||
},
|
||||
"no common protocol": {
|
||||
clientProtocols: []string{"c"},
|
||||
serverProtocols: []string{"a", "b"},
|
||||
expectedProtocol: "",
|
||||
expectError: true,
|
||||
},
|
||||
"common protocol": {
|
||||
clientProtocols: []string{"b"},
|
||||
serverProtocols: []string{"a", "b"},
|
||||
expectedProtocol: "b",
|
||||
},
|
||||
}
|
||||
|
||||
for name, test := range tests {
|
||||
req, err := http.NewRequest("GET", "http://www.example.com/", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("%s: error creating request: %v", name, err)
|
||||
}
|
||||
|
||||
for _, p := range test.clientProtocols {
|
||||
req.Header.Add(HeaderProtocolVersion, p)
|
||||
}
|
||||
|
||||
w := newResponseWriter()
|
||||
negotiated, err := Handshake(req, w, test.serverProtocols)
|
||||
|
||||
// verify negotiated protocol
|
||||
if e, a := test.expectedProtocol, negotiated; e != a {
|
||||
t.Errorf("%s: protocol: expected %q, got %q", name, e, a)
|
||||
}
|
||||
|
||||
if test.expectError {
|
||||
if err == nil {
|
||||
t.Errorf("%s: expected error but did not get one", name)
|
||||
}
|
||||
if w.statusCode == nil {
|
||||
t.Errorf("%s: expected w.statusCode to be set", name)
|
||||
} else if e, a := http.StatusForbidden, *w.statusCode; e != a {
|
||||
t.Errorf("%s: w.statusCode: expected %d, got %d", name, e, a)
|
||||
}
|
||||
if e, a := test.serverProtocols, w.Header()[HeaderAcceptedProtocolVersions]; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%s: accepted server protocols: expected %v, got %v", name, e, a)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !test.expectError && err != nil {
|
||||
t.Errorf("%s: unexpected error: %v", name, err)
|
||||
continue
|
||||
}
|
||||
if w.statusCode != nil {
|
||||
t.Errorf("%s: unexpected non-nil w.statusCode: %d", name, w.statusCode)
|
||||
}
|
||||
|
||||
if len(test.expectedProtocol) == 0 {
|
||||
if len(w.Header()[HeaderProtocolVersion]) > 0 {
|
||||
t.Errorf("%s: unexpected protocol version response header: %s", name, w.Header()[HeaderProtocolVersion])
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// verify response headers
|
||||
if e, a := []string{test.expectedProtocol}, w.Header()[HeaderProtocolVersion]; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%s: protocol response header: expected %v, got %v", name, e, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
56
vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/BUILD
generated
vendored
56
vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/BUILD
generated
vendored
|
|
@ -1,56 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"connection_test.go",
|
||||
"roundtripper_test.go",
|
||||
"upgrade_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/github.com/elazarl/goproxy:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/httpstream:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"connection.go",
|
||||
"roundtripper.go",
|
||||
"upgrade.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/util/httpstream/spdy",
|
||||
deps = [
|
||||
"//vendor/github.com/docker/spdystream:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/httpstream:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/third_party/forked/golang/netutil:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
164
vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/connection_test.go
generated
vendored
164
vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/connection_test.go
generated
vendored
|
|
@ -1,164 +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 spdy
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/httpstream"
|
||||
)
|
||||
|
||||
func runProxy(t *testing.T, backendUrl string, proxyUrl chan<- string, proxyDone chan<- struct{}) {
|
||||
listener, err := net.Listen("tcp4", "localhost:0")
|
||||
if err != nil {
|
||||
t.Fatalf("error listening: %v", err)
|
||||
}
|
||||
defer listener.Close()
|
||||
|
||||
proxyUrl <- listener.Addr().String()
|
||||
|
||||
clientConn, err := listener.Accept()
|
||||
if err != nil {
|
||||
t.Errorf("proxy: error accepting client connection: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
backendConn, err := net.Dial("tcp4", backendUrl)
|
||||
if err != nil {
|
||||
t.Errorf("proxy: error dialing backend: %v", err)
|
||||
return
|
||||
}
|
||||
defer backendConn.Close()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
io.Copy(backendConn, clientConn)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
io.Copy(clientConn, backendConn)
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
|
||||
proxyDone <- struct{}{}
|
||||
}
|
||||
|
||||
func runServer(t *testing.T, backendUrl chan<- string, serverDone chan<- struct{}) {
|
||||
listener, err := net.Listen("tcp4", "localhost:0")
|
||||
if err != nil {
|
||||
t.Fatalf("server: error listening: %v", err)
|
||||
}
|
||||
defer listener.Close()
|
||||
|
||||
backendUrl <- listener.Addr().String()
|
||||
|
||||
conn, err := listener.Accept()
|
||||
if err != nil {
|
||||
t.Errorf("server: error accepting connection: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
streamChan := make(chan httpstream.Stream)
|
||||
replySentChan := make(chan (<-chan struct{}))
|
||||
spdyConn, err := NewServerConnection(conn, func(stream httpstream.Stream, replySent <-chan struct{}) error {
|
||||
streamChan <- stream
|
||||
replySentChan <- replySent
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Errorf("server: error creating spdy connection: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
stream := <-streamChan
|
||||
replySent := <-replySentChan
|
||||
<-replySent
|
||||
|
||||
buf := make([]byte, 1)
|
||||
_, err = stream.Read(buf)
|
||||
if err != io.EOF {
|
||||
t.Errorf("server: unexpected read error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
<-spdyConn.CloseChan()
|
||||
raw := spdyConn.(*connection).conn
|
||||
if err := raw.Wait(15 * time.Second); err != nil {
|
||||
t.Errorf("server: timed out waiting for connection closure: %v", err)
|
||||
}
|
||||
|
||||
serverDone <- struct{}{}
|
||||
}
|
||||
|
||||
func TestConnectionCloseIsImmediateThroughAProxy(t *testing.T) {
|
||||
serverDone := make(chan struct{})
|
||||
backendUrlChan := make(chan string)
|
||||
go runServer(t, backendUrlChan, serverDone)
|
||||
backendUrl := <-backendUrlChan
|
||||
|
||||
proxyDone := make(chan struct{})
|
||||
proxyUrlChan := make(chan string)
|
||||
go runProxy(t, backendUrl, proxyUrlChan, proxyDone)
|
||||
proxyUrl := <-proxyUrlChan
|
||||
|
||||
conn, err := net.Dial("tcp4", proxyUrl)
|
||||
if err != nil {
|
||||
t.Fatalf("client: error connecting to proxy: %v", err)
|
||||
}
|
||||
|
||||
spdyConn, err := NewClientConnection(conn)
|
||||
if err != nil {
|
||||
t.Fatalf("client: error creating spdy connection: %v", err)
|
||||
}
|
||||
|
||||
if _, err := spdyConn.CreateStream(http.Header{}); err != nil {
|
||||
t.Fatalf("client: error creating stream: %v", err)
|
||||
}
|
||||
|
||||
spdyConn.Close()
|
||||
raw := spdyConn.(*connection).conn
|
||||
if err := raw.Wait(15 * time.Second); err != nil {
|
||||
t.Fatalf("client: timed out waiting for connection closure: %v", err)
|
||||
}
|
||||
|
||||
expired := time.NewTimer(15 * time.Second)
|
||||
defer expired.Stop()
|
||||
i := 0
|
||||
for {
|
||||
select {
|
||||
case <-expired.C:
|
||||
t.Fatalf("timed out waiting for proxy and/or server closure")
|
||||
case <-serverDone:
|
||||
i++
|
||||
case <-proxyDone:
|
||||
i++
|
||||
}
|
||||
if i == 2 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
529
vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/roundtripper_test.go
generated
vendored
529
vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/roundtripper_test.go
generated
vendored
|
|
@ -1,529 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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 spdy
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
|
||||
"github.com/elazarl/goproxy"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/httpstream"
|
||||
)
|
||||
|
||||
// be sure to unset environment variable https_proxy (if exported) before testing, otherwise the testing will fail unexpectedly.
|
||||
func TestRoundTripAndNewConnection(t *testing.T) {
|
||||
for _, redirect := range []bool{false, true} {
|
||||
t.Run(fmt.Sprintf("redirect = %t", redirect), func(t *testing.T) {
|
||||
localhostPool := x509.NewCertPool()
|
||||
if !localhostPool.AppendCertsFromPEM(localhostCert) {
|
||||
t.Errorf("error setting up localhostCert pool")
|
||||
}
|
||||
|
||||
httpsServerInvalidHostname := func(h http.Handler) *httptest.Server {
|
||||
cert, err := tls.X509KeyPair(exampleCert, exampleKey)
|
||||
if err != nil {
|
||||
t.Errorf("https (invalid hostname): proxy_test: %v", err)
|
||||
}
|
||||
ts := httptest.NewUnstartedServer(h)
|
||||
ts.TLS = &tls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
}
|
||||
ts.StartTLS()
|
||||
return ts
|
||||
}
|
||||
|
||||
httpsServerValidHostname := func(h http.Handler) *httptest.Server {
|
||||
cert, err := tls.X509KeyPair(localhostCert, localhostKey)
|
||||
if err != nil {
|
||||
t.Errorf("https (valid hostname): proxy_test: %v", err)
|
||||
}
|
||||
ts := httptest.NewUnstartedServer(h)
|
||||
ts.TLS = &tls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
}
|
||||
ts.StartTLS()
|
||||
return ts
|
||||
}
|
||||
|
||||
testCases := map[string]struct {
|
||||
serverFunc func(http.Handler) *httptest.Server
|
||||
proxyServerFunc func(http.Handler) *httptest.Server
|
||||
proxyAuth *url.Userinfo
|
||||
clientTLS *tls.Config
|
||||
serverConnectionHeader string
|
||||
serverUpgradeHeader string
|
||||
serverStatusCode int
|
||||
shouldError bool
|
||||
}{
|
||||
"no headers": {
|
||||
serverFunc: httptest.NewServer,
|
||||
serverConnectionHeader: "",
|
||||
serverUpgradeHeader: "",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: true,
|
||||
},
|
||||
"no upgrade header": {
|
||||
serverFunc: httptest.NewServer,
|
||||
serverConnectionHeader: "Upgrade",
|
||||
serverUpgradeHeader: "",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: true,
|
||||
},
|
||||
"no connection header": {
|
||||
serverFunc: httptest.NewServer,
|
||||
serverConnectionHeader: "",
|
||||
serverUpgradeHeader: "SPDY/3.1",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: true,
|
||||
},
|
||||
"no switching protocol status code": {
|
||||
serverFunc: httptest.NewServer,
|
||||
serverConnectionHeader: "Upgrade",
|
||||
serverUpgradeHeader: "SPDY/3.1",
|
||||
serverStatusCode: http.StatusForbidden,
|
||||
shouldError: true,
|
||||
},
|
||||
"http": {
|
||||
serverFunc: httptest.NewServer,
|
||||
serverConnectionHeader: "Upgrade",
|
||||
serverUpgradeHeader: "SPDY/3.1",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: false,
|
||||
},
|
||||
"https (invalid hostname + InsecureSkipVerify)": {
|
||||
serverFunc: httpsServerInvalidHostname,
|
||||
clientTLS: &tls.Config{InsecureSkipVerify: true},
|
||||
serverConnectionHeader: "Upgrade",
|
||||
serverUpgradeHeader: "SPDY/3.1",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: false,
|
||||
},
|
||||
"https (invalid hostname + hostname verification)": {
|
||||
serverFunc: httpsServerInvalidHostname,
|
||||
clientTLS: &tls.Config{InsecureSkipVerify: false},
|
||||
serverConnectionHeader: "Upgrade",
|
||||
serverUpgradeHeader: "SPDY/3.1",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: true,
|
||||
},
|
||||
"https (valid hostname + RootCAs)": {
|
||||
serverFunc: httpsServerValidHostname,
|
||||
clientTLS: &tls.Config{RootCAs: localhostPool},
|
||||
serverConnectionHeader: "Upgrade",
|
||||
serverUpgradeHeader: "SPDY/3.1",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: false,
|
||||
},
|
||||
"proxied http->http": {
|
||||
serverFunc: httptest.NewServer,
|
||||
proxyServerFunc: httptest.NewServer,
|
||||
serverConnectionHeader: "Upgrade",
|
||||
serverUpgradeHeader: "SPDY/3.1",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: false,
|
||||
},
|
||||
"proxied https (invalid hostname + InsecureSkipVerify) -> http": {
|
||||
serverFunc: httptest.NewServer,
|
||||
proxyServerFunc: httpsServerInvalidHostname,
|
||||
clientTLS: &tls.Config{InsecureSkipVerify: true},
|
||||
serverConnectionHeader: "Upgrade",
|
||||
serverUpgradeHeader: "SPDY/3.1",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: false,
|
||||
},
|
||||
"proxied https with auth (invalid hostname + InsecureSkipVerify) -> http": {
|
||||
serverFunc: httptest.NewServer,
|
||||
proxyServerFunc: httpsServerInvalidHostname,
|
||||
proxyAuth: url.UserPassword("proxyuser", "proxypasswd"),
|
||||
clientTLS: &tls.Config{InsecureSkipVerify: true},
|
||||
serverConnectionHeader: "Upgrade",
|
||||
serverUpgradeHeader: "SPDY/3.1",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: false,
|
||||
},
|
||||
"proxied https (invalid hostname + hostname verification) -> http": {
|
||||
serverFunc: httptest.NewServer,
|
||||
proxyServerFunc: httpsServerInvalidHostname,
|
||||
clientTLS: &tls.Config{InsecureSkipVerify: false},
|
||||
serverConnectionHeader: "Upgrade",
|
||||
serverUpgradeHeader: "SPDY/3.1",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: true, // fails because the client doesn't trust the proxy
|
||||
},
|
||||
"proxied https (valid hostname + RootCAs) -> http": {
|
||||
serverFunc: httptest.NewServer,
|
||||
proxyServerFunc: httpsServerValidHostname,
|
||||
clientTLS: &tls.Config{RootCAs: localhostPool},
|
||||
serverConnectionHeader: "Upgrade",
|
||||
serverUpgradeHeader: "SPDY/3.1",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: false,
|
||||
},
|
||||
"proxied https with auth (valid hostname + RootCAs) -> http": {
|
||||
serverFunc: httptest.NewServer,
|
||||
proxyServerFunc: httpsServerValidHostname,
|
||||
proxyAuth: url.UserPassword("proxyuser", "proxypasswd"),
|
||||
clientTLS: &tls.Config{RootCAs: localhostPool},
|
||||
serverConnectionHeader: "Upgrade",
|
||||
serverUpgradeHeader: "SPDY/3.1",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: false,
|
||||
},
|
||||
"proxied https (invalid hostname + InsecureSkipVerify) -> https (invalid hostname)": {
|
||||
serverFunc: httpsServerInvalidHostname,
|
||||
proxyServerFunc: httpsServerInvalidHostname,
|
||||
clientTLS: &tls.Config{InsecureSkipVerify: true},
|
||||
serverConnectionHeader: "Upgrade",
|
||||
serverUpgradeHeader: "SPDY/3.1",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: false, // works because the test proxy ignores TLS errors
|
||||
},
|
||||
"proxied https with auth (invalid hostname + InsecureSkipVerify) -> https (invalid hostname)": {
|
||||
serverFunc: httpsServerInvalidHostname,
|
||||
proxyServerFunc: httpsServerInvalidHostname,
|
||||
proxyAuth: url.UserPassword("proxyuser", "proxypasswd"),
|
||||
clientTLS: &tls.Config{InsecureSkipVerify: true},
|
||||
serverConnectionHeader: "Upgrade",
|
||||
serverUpgradeHeader: "SPDY/3.1",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: false, // works because the test proxy ignores TLS errors
|
||||
},
|
||||
"proxied https (invalid hostname + hostname verification) -> https (invalid hostname)": {
|
||||
serverFunc: httpsServerInvalidHostname,
|
||||
proxyServerFunc: httpsServerInvalidHostname,
|
||||
clientTLS: &tls.Config{InsecureSkipVerify: false},
|
||||
serverConnectionHeader: "Upgrade",
|
||||
serverUpgradeHeader: "SPDY/3.1",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: true, // fails because the client doesn't trust the proxy
|
||||
},
|
||||
"proxied https (valid hostname + RootCAs) -> https (valid hostname + RootCAs)": {
|
||||
serverFunc: httpsServerValidHostname,
|
||||
proxyServerFunc: httpsServerValidHostname,
|
||||
clientTLS: &tls.Config{RootCAs: localhostPool},
|
||||
serverConnectionHeader: "Upgrade",
|
||||
serverUpgradeHeader: "SPDY/3.1",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: false,
|
||||
},
|
||||
"proxied https with auth (valid hostname + RootCAs) -> https (valid hostname + RootCAs)": {
|
||||
serverFunc: httpsServerValidHostname,
|
||||
proxyServerFunc: httpsServerValidHostname,
|
||||
proxyAuth: url.UserPassword("proxyuser", "proxypasswd"),
|
||||
clientTLS: &tls.Config{RootCAs: localhostPool},
|
||||
serverConnectionHeader: "Upgrade",
|
||||
serverUpgradeHeader: "SPDY/3.1",
|
||||
serverStatusCode: http.StatusSwitchingProtocols,
|
||||
shouldError: false,
|
||||
},
|
||||
}
|
||||
|
||||
for k, testCase := range testCases {
|
||||
server := testCase.serverFunc(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
if testCase.shouldError {
|
||||
if e, a := httpstream.HeaderUpgrade, req.Header.Get(httpstream.HeaderConnection); e != a {
|
||||
t.Fatalf("%s: Expected connection=upgrade header, got '%s", k, a)
|
||||
}
|
||||
|
||||
w.Header().Set(httpstream.HeaderConnection, testCase.serverConnectionHeader)
|
||||
w.Header().Set(httpstream.HeaderUpgrade, testCase.serverUpgradeHeader)
|
||||
w.WriteHeader(testCase.serverStatusCode)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
streamCh := make(chan httpstream.Stream)
|
||||
|
||||
responseUpgrader := NewResponseUpgrader()
|
||||
spdyConn := responseUpgrader.UpgradeResponse(w, req, func(s httpstream.Stream, replySent <-chan struct{}) error {
|
||||
streamCh <- s
|
||||
return nil
|
||||
})
|
||||
if spdyConn == nil {
|
||||
t.Fatalf("%s: unexpected nil spdyConn", k)
|
||||
}
|
||||
defer spdyConn.Close()
|
||||
|
||||
stream := <-streamCh
|
||||
io.Copy(stream, stream)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
serverURL, err := url.Parse(server.URL)
|
||||
if err != nil {
|
||||
t.Fatalf("%s: Error creating request: %s", k, err)
|
||||
}
|
||||
req, err := http.NewRequest("GET", server.URL, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("%s: Error creating request: %s", k, err)
|
||||
}
|
||||
|
||||
spdyTransport := NewSpdyRoundTripper(testCase.clientTLS, redirect)
|
||||
|
||||
var proxierCalled bool
|
||||
var proxyCalledWithHost string
|
||||
var proxyCalledWithAuth bool
|
||||
var proxyCalledWithAuthHeader string
|
||||
if testCase.proxyServerFunc != nil {
|
||||
proxyHandler := goproxy.NewProxyHttpServer()
|
||||
|
||||
proxyHandler.OnRequest().HandleConnectFunc(func(host string, ctx *goproxy.ProxyCtx) (*goproxy.ConnectAction, string) {
|
||||
proxyCalledWithHost = host
|
||||
|
||||
proxyAuthHeaderName := "Proxy-Authorization"
|
||||
_, proxyCalledWithAuth = ctx.Req.Header[proxyAuthHeaderName]
|
||||
proxyCalledWithAuthHeader = ctx.Req.Header.Get(proxyAuthHeaderName)
|
||||
return goproxy.OkConnect, host
|
||||
})
|
||||
|
||||
proxy := testCase.proxyServerFunc(proxyHandler)
|
||||
|
||||
spdyTransport.proxier = func(proxierReq *http.Request) (*url.URL, error) {
|
||||
proxierCalled = true
|
||||
proxyURL, err := url.Parse(proxy.URL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
proxyURL.User = testCase.proxyAuth
|
||||
return proxyURL, nil
|
||||
}
|
||||
defer proxy.Close()
|
||||
}
|
||||
|
||||
client := &http.Client{Transport: spdyTransport}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
var conn httpstream.Connection
|
||||
if err == nil {
|
||||
conn, err = spdyTransport.NewConnection(resp)
|
||||
}
|
||||
haveErr := err != nil
|
||||
if e, a := testCase.shouldError, haveErr; e != a {
|
||||
t.Fatalf("%s: shouldError=%t, got %t: %v", k, e, a, err)
|
||||
}
|
||||
if testCase.shouldError {
|
||||
continue
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusSwitchingProtocols {
|
||||
t.Fatalf("%s: expected http 101 switching protocols, got %d", k, resp.StatusCode)
|
||||
}
|
||||
|
||||
stream, err := conn.CreateStream(http.Header{})
|
||||
if err != nil {
|
||||
t.Fatalf("%s: error creating client stream: %s", k, err)
|
||||
}
|
||||
|
||||
n, err := stream.Write([]byte("hello"))
|
||||
if err != nil {
|
||||
t.Fatalf("%s: error writing to stream: %s", k, err)
|
||||
}
|
||||
if n != 5 {
|
||||
t.Fatalf("%s: Expected to write 5 bytes, but actually wrote %d", k, n)
|
||||
}
|
||||
|
||||
b := make([]byte, 5)
|
||||
n, err = stream.Read(b)
|
||||
if err != nil {
|
||||
t.Fatalf("%s: error reading from stream: %s", k, err)
|
||||
}
|
||||
if n != 5 {
|
||||
t.Fatalf("%s: Expected to read 5 bytes, but actually read %d", k, n)
|
||||
}
|
||||
if e, a := "hello", string(b[0:n]); e != a {
|
||||
t.Fatalf("%s: expected '%s', got '%s'", k, e, a)
|
||||
}
|
||||
|
||||
if testCase.proxyServerFunc != nil {
|
||||
if !proxierCalled {
|
||||
t.Fatalf("%s: Expected to use a proxy but proxier in SpdyRoundTripper wasn't called", k)
|
||||
}
|
||||
if proxyCalledWithHost != serverURL.Host {
|
||||
t.Fatalf("%s: Expected to see a call to the proxy for backend %q, got %q", k, serverURL.Host, proxyCalledWithHost)
|
||||
}
|
||||
}
|
||||
|
||||
var expectedProxyAuth string
|
||||
if testCase.proxyAuth != nil {
|
||||
encodedCredentials := base64.StdEncoding.EncodeToString([]byte(testCase.proxyAuth.String()))
|
||||
expectedProxyAuth = "Basic " + encodedCredentials
|
||||
}
|
||||
if len(expectedProxyAuth) == 0 && proxyCalledWithAuth {
|
||||
t.Fatalf("%s: Proxy authorization unexpected, got %q", k, proxyCalledWithAuthHeader)
|
||||
}
|
||||
if proxyCalledWithAuthHeader != expectedProxyAuth {
|
||||
t.Fatalf("%s: Expected to see a call to the proxy with credentials %q, got %q", k, testCase.proxyAuth, proxyCalledWithAuthHeader)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoundTripRedirects(t *testing.T) {
|
||||
tests := []struct {
|
||||
redirects int32
|
||||
expectSuccess bool
|
||||
}{
|
||||
{0, true},
|
||||
{1, true},
|
||||
{10, true},
|
||||
{11, false},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(fmt.Sprintf("with %d redirects", test.redirects), func(t *testing.T) {
|
||||
var redirects int32 = 0
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
if redirects < test.redirects {
|
||||
redirects = atomic.AddInt32(&redirects, 1)
|
||||
http.Redirect(w, req, "redirect", http.StatusFound)
|
||||
return
|
||||
}
|
||||
streamCh := make(chan httpstream.Stream)
|
||||
|
||||
responseUpgrader := NewResponseUpgrader()
|
||||
spdyConn := responseUpgrader.UpgradeResponse(w, req, func(s httpstream.Stream, replySent <-chan struct{}) error {
|
||||
streamCh <- s
|
||||
return nil
|
||||
})
|
||||
if spdyConn == nil {
|
||||
t.Fatalf("unexpected nil spdyConn")
|
||||
}
|
||||
defer spdyConn.Close()
|
||||
|
||||
stream := <-streamCh
|
||||
io.Copy(stream, stream)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
req, err := http.NewRequest("GET", server.URL, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating request: %s", err)
|
||||
}
|
||||
|
||||
spdyTransport := NewSpdyRoundTripper(nil, true)
|
||||
client := &http.Client{Transport: spdyTransport}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if test.expectSuccess {
|
||||
if err != nil {
|
||||
t.Fatalf("error calling Do: %v", err)
|
||||
}
|
||||
} else {
|
||||
if err == nil {
|
||||
t.Fatalf("expecting an error")
|
||||
} else if !strings.Contains(err.Error(), "too many redirects") {
|
||||
t.Fatalf("expecting too many redirects, got %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
conn, err := spdyTransport.NewConnection(resp)
|
||||
if err != nil {
|
||||
t.Fatalf("error calling NewConnection: %v", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusSwitchingProtocols {
|
||||
t.Fatalf("expected http 101 switching protocols, got %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
stream, err := conn.CreateStream(http.Header{})
|
||||
if err != nil {
|
||||
t.Fatalf("error creating client stream: %s", err)
|
||||
}
|
||||
|
||||
n, err := stream.Write([]byte("hello"))
|
||||
if err != nil {
|
||||
t.Fatalf("error writing to stream: %s", err)
|
||||
}
|
||||
if n != 5 {
|
||||
t.Fatalf("Expected to write 5 bytes, but actually wrote %d", n)
|
||||
}
|
||||
|
||||
b := make([]byte, 5)
|
||||
n, err = stream.Read(b)
|
||||
if err != nil {
|
||||
t.Fatalf("error reading from stream: %s", err)
|
||||
}
|
||||
if n != 5 {
|
||||
t.Fatalf("Expected to read 5 bytes, but actually read %d", n)
|
||||
}
|
||||
if e, a := "hello", string(b[0:n]); e != a {
|
||||
t.Fatalf("expected '%s', got '%s'", e, a)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// exampleCert was generated from crypto/tls/generate_cert.go with the following command:
|
||||
// go run generate_cert.go --rsa-bits 512 --host example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
|
||||
var exampleCert = []byte(`-----BEGIN CERTIFICATE-----
|
||||
MIIBdzCCASGgAwIBAgIRAOVTAdPnfbS5V85mfS90TfIwDQYJKoZIhvcNAQELBQAw
|
||||
EjEQMA4GA1UEChMHQWNtZSBDbzAgFw03MDAxMDEwMDAwMDBaGA8yMDg0MDEyOTE2
|
||||
MDAwMFowEjEQMA4GA1UEChMHQWNtZSBDbzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgC
|
||||
QQCoVSqeu8TBvF+70T7Jm4340YQNhds6IxjRoifenYodAO1dnKGrcbF266DJGunh
|
||||
nIjQH7B12tduhl0fLK4Ezf7/AgMBAAGjUDBOMA4GA1UdDwEB/wQEAwICpDATBgNV
|
||||
HSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MBYGA1UdEQQPMA2CC2V4
|
||||
YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA0EAk1kVa5uZ/AzwYDVcS9bpM/czwjjV
|
||||
xq3VeSCfmNa2uNjbFvodmCRwZOHUvipAMGCUCV6j5vMrJ8eMj8tCQ36W9A==
|
||||
-----END CERTIFICATE-----`)
|
||||
|
||||
var exampleKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOgIBAAJBAKhVKp67xMG8X7vRPsmbjfjRhA2F2zojGNGiJ96dih0A7V2coatx
|
||||
sXbroMka6eGciNAfsHXa126GXR8srgTN/v8CAwEAAQJASdzdD7vKsUwMIejGCUb1
|
||||
fAnLTPfAY3lFCa+CmR89nE22dAoRDv+5RbnBsZ58BazPNJHrsVPRlfXB3OQmSQr0
|
||||
SQIhANoJhs+xOJE/i8nJv0uAbzKyiD1YkvRkta0GpUOULyAVAiEAxaQus3E/SuqD
|
||||
P7y5NeJnE7X6XkyC35zrsJRkz7orE8MCIHdDjsI8pjyNDeGqwUCDWE/a6DrmIDwe
|
||||
emHSqMN2YvChAiEAnxLCM9NWaenOsaIoP+J1rDuvw+4499nJKVqGuVrSCRkCIEqK
|
||||
4KSchPMc3x8M/uhw9oWTtKFmjA/PPh0FsWCdKrEy
|
||||
-----END RSA PRIVATE KEY-----`)
|
||||
|
||||
// localhostCert was generated from crypto/tls/generate_cert.go with the following command:
|
||||
// go run generate_cert.go --rsa-bits 512 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
|
||||
var localhostCert = []byte(`-----BEGIN CERTIFICATE-----
|
||||
MIIBjzCCATmgAwIBAgIRAKpi2WmTcFrVjxrl5n5YDUEwDQYJKoZIhvcNAQELBQAw
|
||||
EjEQMA4GA1UEChMHQWNtZSBDbzAgFw03MDAxMDEwMDAwMDBaGA8yMDg0MDEyOTE2
|
||||
MDAwMFowEjEQMA4GA1UEChMHQWNtZSBDbzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgC
|
||||
QQC9fEbRszP3t14Gr4oahV7zFObBI4TfA5i7YnlMXeLinb7MnvT4bkfOJzE6zktn
|
||||
59zP7UiHs3l4YOuqrjiwM413AgMBAAGjaDBmMA4GA1UdDwEB/wQEAwICpDATBgNV
|
||||
HSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MC4GA1UdEQQnMCWCC2V4
|
||||
YW1wbGUuY29thwR/AAABhxAAAAAAAAAAAAAAAAAAAAABMA0GCSqGSIb3DQEBCwUA
|
||||
A0EAUsVE6KMnza/ZbodLlyeMzdo7EM/5nb5ywyOxgIOCf0OOLHsPS9ueGLQX9HEG
|
||||
//yjTXuhNcUugExIjM/AIwAZPQ==
|
||||
-----END CERTIFICATE-----`)
|
||||
|
||||
// localhostKey is the private key for localhostCert.
|
||||
var localhostKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBAL18RtGzM/e3XgavihqFXvMU5sEjhN8DmLtieUxd4uKdvsye9Phu
|
||||
R84nMTrOS2fn3M/tSIezeXhg66quOLAzjXcCAwEAAQJBAKcRxH9wuglYLBdI/0OT
|
||||
BLzfWPZCEw1vZmMR2FF1Fm8nkNOVDPleeVGTWoOEcYYlQbpTmkGSxJ6ya+hqRi6x
|
||||
goECIQDx3+X49fwpL6B5qpJIJMyZBSCuMhH4B7JevhGGFENi3wIhAMiNJN5Q3UkL
|
||||
IuSvv03kaPR5XVQ99/UeEetUgGvBcABpAiBJSBzVITIVCGkGc7d+RCf49KTCIklv
|
||||
bGWObufAR8Ni4QIgWpILjW8dkGg8GOUZ0zaNA6Nvt6TIv2UWGJ4v5PoV98kCIQDx
|
||||
rIiZs5QbKdycsv9gQJzwQAogC8o04X3Zz3dsoX+h4A==
|
||||
-----END RSA PRIVATE KEY-----`)
|
||||
93
vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/upgrade_test.go
generated
vendored
93
vendor/k8s.io/apimachinery/pkg/util/httpstream/spdy/upgrade_test.go
generated
vendored
|
|
@ -1,93 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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 spdy
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUpgradeResponse(t *testing.T) {
|
||||
testCases := []struct {
|
||||
connectionHeader string
|
||||
upgradeHeader string
|
||||
shouldError bool
|
||||
}{
|
||||
{
|
||||
connectionHeader: "",
|
||||
upgradeHeader: "",
|
||||
shouldError: true,
|
||||
},
|
||||
{
|
||||
connectionHeader: "Upgrade",
|
||||
upgradeHeader: "",
|
||||
shouldError: true,
|
||||
},
|
||||
{
|
||||
connectionHeader: "",
|
||||
upgradeHeader: "SPDY/3.1",
|
||||
shouldError: true,
|
||||
},
|
||||
{
|
||||
connectionHeader: "Upgrade",
|
||||
upgradeHeader: "SPDY/3.1",
|
||||
shouldError: false,
|
||||
},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
upgrader := NewResponseUpgrader()
|
||||
conn := upgrader.UpgradeResponse(w, req, nil)
|
||||
haveErr := conn == nil
|
||||
if e, a := testCase.shouldError, haveErr; e != a {
|
||||
t.Fatalf("%d: expected shouldErr=%t, got %t", i, testCase.shouldError, haveErr)
|
||||
}
|
||||
if haveErr {
|
||||
return
|
||||
}
|
||||
if conn == nil {
|
||||
t.Fatalf("%d: unexpected nil conn", i)
|
||||
}
|
||||
defer conn.Close()
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
req, err := http.NewRequest("GET", server.URL, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("%d: error creating request: %s", i, err)
|
||||
}
|
||||
|
||||
req.Header.Set("Connection", testCase.connectionHeader)
|
||||
req.Header.Set("Upgrade", testCase.upgradeHeader)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
t.Fatalf("%d: unexpected non-nil err from client.Do: %s", i, err)
|
||||
}
|
||||
|
||||
if testCase.shouldError {
|
||||
continue
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusSwitchingProtocols {
|
||||
t.Fatalf("%d: expected status 101 switching protocols, got %d", i, resp.StatusCode)
|
||||
}
|
||||
}
|
||||
}
|
||||
47
vendor/k8s.io/apimachinery/pkg/util/intstr/BUILD
generated
vendored
47
vendor/k8s.io/apimachinery/pkg/util/intstr/BUILD
generated
vendored
|
|
@ -1,47 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["intstr_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = ["//vendor/github.com/ghodss/yaml:go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"generated.pb.go",
|
||||
"intstr.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/util/intstr",
|
||||
deps = [
|
||||
"//vendor/github.com/gogo/protobuf/proto:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/google/gofuzz:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "go_default_library_protos",
|
||||
srcs = ["generated.proto"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
176
vendor/k8s.io/apimachinery/pkg/util/intstr/intstr_test.go
generated
vendored
176
vendor/k8s.io/apimachinery/pkg/util/intstr/intstr_test.go
generated
vendored
|
|
@ -1,176 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 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 intstr
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
)
|
||||
|
||||
func TestFromInt(t *testing.T) {
|
||||
i := FromInt(93)
|
||||
if i.Type != Int || i.IntVal != 93 {
|
||||
t.Errorf("Expected IntVal=93, got %+v", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFromString(t *testing.T) {
|
||||
i := FromString("76")
|
||||
if i.Type != String || i.StrVal != "76" {
|
||||
t.Errorf("Expected StrVal=\"76\", got %+v", i)
|
||||
}
|
||||
}
|
||||
|
||||
type IntOrStringHolder struct {
|
||||
IOrS IntOrString `json:"val"`
|
||||
}
|
||||
|
||||
func TestIntOrStringUnmarshalJSON(t *testing.T) {
|
||||
cases := []struct {
|
||||
input string
|
||||
result IntOrString
|
||||
}{
|
||||
{"{\"val\": 123}", FromInt(123)},
|
||||
{"{\"val\": \"123\"}", FromString("123")},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
var result IntOrStringHolder
|
||||
if err := json.Unmarshal([]byte(c.input), &result); err != nil {
|
||||
t.Errorf("Failed to unmarshal input '%v': %v", c.input, err)
|
||||
}
|
||||
if result.IOrS != c.result {
|
||||
t.Errorf("Failed to unmarshal input '%v': expected %+v, got %+v", c.input, c.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntOrStringMarshalJSON(t *testing.T) {
|
||||
cases := []struct {
|
||||
input IntOrString
|
||||
result string
|
||||
}{
|
||||
{FromInt(123), "{\"val\":123}"},
|
||||
{FromString("123"), "{\"val\":\"123\"}"},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
input := IntOrStringHolder{c.input}
|
||||
result, err := json.Marshal(&input)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to marshal input '%v': %v", input, err)
|
||||
}
|
||||
if string(result) != c.result {
|
||||
t.Errorf("Failed to marshal input '%v': expected: %+v, got %q", input, c.result, string(result))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntOrStringMarshalJSONUnmarshalYAML(t *testing.T) {
|
||||
cases := []struct {
|
||||
input IntOrString
|
||||
}{
|
||||
{FromInt(123)},
|
||||
{FromString("123")},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
input := IntOrStringHolder{c.input}
|
||||
jsonMarshalled, err := json.Marshal(&input)
|
||||
if err != nil {
|
||||
t.Errorf("1: Failed to marshal input: '%v': %v", input, err)
|
||||
}
|
||||
|
||||
var result IntOrStringHolder
|
||||
err = yaml.Unmarshal(jsonMarshalled, &result)
|
||||
if err != nil {
|
||||
t.Errorf("2: Failed to unmarshal '%+v': %v", string(jsonMarshalled), err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(input, result) {
|
||||
t.Errorf("3: Failed to marshal input '%+v': got %+v", input, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetValueFromIntOrPercent(t *testing.T) {
|
||||
tests := []struct {
|
||||
input IntOrString
|
||||
total int
|
||||
roundUp bool
|
||||
expectErr bool
|
||||
expectVal int
|
||||
}{
|
||||
{
|
||||
input: FromInt(123),
|
||||
expectErr: false,
|
||||
expectVal: 123,
|
||||
},
|
||||
{
|
||||
input: FromString("90%"),
|
||||
total: 100,
|
||||
roundUp: true,
|
||||
expectErr: false,
|
||||
expectVal: 90,
|
||||
},
|
||||
{
|
||||
input: FromString("90%"),
|
||||
total: 95,
|
||||
roundUp: true,
|
||||
expectErr: false,
|
||||
expectVal: 86,
|
||||
},
|
||||
{
|
||||
input: FromString("90%"),
|
||||
total: 95,
|
||||
roundUp: false,
|
||||
expectErr: false,
|
||||
expectVal: 85,
|
||||
},
|
||||
{
|
||||
input: FromString("%"),
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
input: FromString("90#"),
|
||||
expectErr: true,
|
||||
},
|
||||
{
|
||||
input: FromString("#%"),
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
t.Logf("test case %d", i)
|
||||
value, err := GetValueFromIntOrPercent(&test.input, test.total, test.roundUp)
|
||||
if test.expectErr && err == nil {
|
||||
t.Errorf("expected error, but got none")
|
||||
continue
|
||||
}
|
||||
if !test.expectErr && err != nil {
|
||||
t.Errorf("unexpected err: %v", err)
|
||||
continue
|
||||
}
|
||||
if test.expectVal != value {
|
||||
t.Errorf("expected %v, but got %v", test.expectVal, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
32
vendor/k8s.io/apimachinery/pkg/util/json/BUILD
generated
vendored
32
vendor/k8s.io/apimachinery/pkg/util/json/BUILD
generated
vendored
|
|
@ -1,32 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["json.go"],
|
||||
importpath = "k8s.io/apimachinery/pkg/util/json",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["json_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
319
vendor/k8s.io/apimachinery/pkg/util/json/json_test.go
generated
vendored
319
vendor/k8s.io/apimachinery/pkg/util/json/json_test.go
generated
vendored
|
|
@ -1,319 +0,0 @@
|
|||
// +build go1.8
|
||||
|
||||
/*
|
||||
Copyright 2015 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 json
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEvaluateTypes(t *testing.T) {
|
||||
testCases := []struct {
|
||||
In string
|
||||
Data interface{}
|
||||
Out string
|
||||
Err bool
|
||||
}{
|
||||
// Invalid syntaxes
|
||||
{
|
||||
In: `x`,
|
||||
Err: true,
|
||||
},
|
||||
{
|
||||
In: ``,
|
||||
Err: true,
|
||||
},
|
||||
|
||||
// Null
|
||||
{
|
||||
In: `null`,
|
||||
Data: nil,
|
||||
Out: `null`,
|
||||
},
|
||||
// Booleans
|
||||
{
|
||||
In: `true`,
|
||||
Data: true,
|
||||
Out: `true`,
|
||||
},
|
||||
{
|
||||
In: `false`,
|
||||
Data: false,
|
||||
Out: `false`,
|
||||
},
|
||||
|
||||
// Integers
|
||||
{
|
||||
In: `0`,
|
||||
Data: int64(0),
|
||||
Out: `0`,
|
||||
},
|
||||
{
|
||||
In: `-0`,
|
||||
Data: int64(-0),
|
||||
Out: `0`,
|
||||
},
|
||||
{
|
||||
In: `1`,
|
||||
Data: int64(1),
|
||||
Out: `1`,
|
||||
},
|
||||
{
|
||||
In: `2147483647`,
|
||||
Data: int64(math.MaxInt32),
|
||||
Out: `2147483647`,
|
||||
},
|
||||
{
|
||||
In: `-2147483648`,
|
||||
Data: int64(math.MinInt32),
|
||||
Out: `-2147483648`,
|
||||
},
|
||||
{
|
||||
In: `9223372036854775807`,
|
||||
Data: int64(math.MaxInt64),
|
||||
Out: `9223372036854775807`,
|
||||
},
|
||||
{
|
||||
In: `-9223372036854775808`,
|
||||
Data: int64(math.MinInt64),
|
||||
Out: `-9223372036854775808`,
|
||||
},
|
||||
|
||||
// Int overflow
|
||||
{
|
||||
In: `9223372036854775808`, // MaxInt64 + 1
|
||||
Data: float64(9223372036854775808),
|
||||
Out: `9223372036854776000`,
|
||||
},
|
||||
{
|
||||
In: `-9223372036854775809`, // MinInt64 - 1
|
||||
Data: float64(math.MinInt64),
|
||||
Out: `-9223372036854776000`,
|
||||
},
|
||||
|
||||
// Floats
|
||||
{
|
||||
In: `0.0`,
|
||||
Data: float64(0),
|
||||
Out: `0`,
|
||||
},
|
||||
{
|
||||
In: `-0.0`,
|
||||
Data: float64(-0.0),
|
||||
Out: `-0`,
|
||||
},
|
||||
{
|
||||
In: `0.5`,
|
||||
Data: float64(0.5),
|
||||
Out: `0.5`,
|
||||
},
|
||||
{
|
||||
In: `1e3`,
|
||||
Data: float64(1e3),
|
||||
Out: `1000`,
|
||||
},
|
||||
{
|
||||
In: `1.5`,
|
||||
Data: float64(1.5),
|
||||
Out: `1.5`,
|
||||
},
|
||||
{
|
||||
In: `-0.3`,
|
||||
Data: float64(-.3),
|
||||
Out: `-0.3`,
|
||||
},
|
||||
{
|
||||
// Largest representable float32
|
||||
In: `3.40282346638528859811704183484516925440e+38`,
|
||||
Data: float64(math.MaxFloat32),
|
||||
Out: strconv.FormatFloat(math.MaxFloat32, 'g', -1, 64),
|
||||
},
|
||||
{
|
||||
// Smallest float32 without losing precision
|
||||
In: `1.175494351e-38`,
|
||||
Data: float64(1.175494351e-38),
|
||||
Out: `1.175494351e-38`,
|
||||
},
|
||||
{
|
||||
// float32 closest to zero
|
||||
In: `1.401298464324817070923729583289916131280e-45`,
|
||||
Data: float64(math.SmallestNonzeroFloat32),
|
||||
Out: strconv.FormatFloat(math.SmallestNonzeroFloat32, 'g', -1, 64),
|
||||
},
|
||||
{
|
||||
// Largest representable float64
|
||||
In: `1.797693134862315708145274237317043567981e+308`,
|
||||
Data: float64(math.MaxFloat64),
|
||||
Out: strconv.FormatFloat(math.MaxFloat64, 'g', -1, 64),
|
||||
},
|
||||
{
|
||||
// Closest to zero without losing precision
|
||||
In: `2.2250738585072014e-308`,
|
||||
Data: float64(2.2250738585072014e-308),
|
||||
Out: `2.2250738585072014e-308`,
|
||||
},
|
||||
|
||||
{
|
||||
// float64 closest to zero
|
||||
In: `4.940656458412465441765687928682213723651e-324`,
|
||||
Data: float64(math.SmallestNonzeroFloat64),
|
||||
Out: strconv.FormatFloat(math.SmallestNonzeroFloat64, 'g', -1, 64),
|
||||
},
|
||||
|
||||
{
|
||||
// math.MaxFloat64 + 2 overflow
|
||||
In: `1.7976931348623159e+308`,
|
||||
Err: true,
|
||||
},
|
||||
|
||||
// Strings
|
||||
{
|
||||
In: `""`,
|
||||
Data: string(""),
|
||||
Out: `""`,
|
||||
},
|
||||
{
|
||||
In: `"0"`,
|
||||
Data: string("0"),
|
||||
Out: `"0"`,
|
||||
},
|
||||
{
|
||||
In: `"A"`,
|
||||
Data: string("A"),
|
||||
Out: `"A"`,
|
||||
},
|
||||
{
|
||||
In: `"Iñtërnâtiônàlizætiøn"`,
|
||||
Data: string("Iñtërnâtiônàlizætiøn"),
|
||||
Out: `"Iñtërnâtiônàlizætiøn"`,
|
||||
},
|
||||
|
||||
// Arrays
|
||||
{
|
||||
In: `[]`,
|
||||
Data: []interface{}{},
|
||||
Out: `[]`,
|
||||
},
|
||||
{
|
||||
In: `[` + strings.Join([]string{
|
||||
`null`,
|
||||
`true`,
|
||||
`false`,
|
||||
`0`,
|
||||
`9223372036854775807`,
|
||||
`0.0`,
|
||||
`0.5`,
|
||||
`1.0`,
|
||||
`1.797693134862315708145274237317043567981e+308`,
|
||||
`"0"`,
|
||||
`"A"`,
|
||||
`"Iñtërnâtiônàlizætiøn"`,
|
||||
`[null,true,1,1.0,1.5]`,
|
||||
`{"boolkey":true,"floatkey":1.0,"intkey":1,"nullkey":null}`,
|
||||
}, ",") + `]`,
|
||||
Data: []interface{}{
|
||||
nil,
|
||||
true,
|
||||
false,
|
||||
int64(0),
|
||||
int64(math.MaxInt64),
|
||||
float64(0.0),
|
||||
float64(0.5),
|
||||
float64(1.0),
|
||||
float64(math.MaxFloat64),
|
||||
string("0"),
|
||||
string("A"),
|
||||
string("Iñtërnâtiônàlizætiøn"),
|
||||
[]interface{}{nil, true, int64(1), float64(1.0), float64(1.5)},
|
||||
map[string]interface{}{"nullkey": nil, "boolkey": true, "intkey": int64(1), "floatkey": float64(1.0)},
|
||||
},
|
||||
Out: `[` + strings.Join([]string{
|
||||
`null`,
|
||||
`true`,
|
||||
`false`,
|
||||
`0`,
|
||||
`9223372036854775807`,
|
||||
`0`,
|
||||
`0.5`,
|
||||
`1`,
|
||||
strconv.FormatFloat(math.MaxFloat64, 'g', -1, 64),
|
||||
`"0"`,
|
||||
`"A"`,
|
||||
`"Iñtërnâtiônàlizætiøn"`,
|
||||
`[null,true,1,1,1.5]`,
|
||||
`{"boolkey":true,"floatkey":1,"intkey":1,"nullkey":null}`, // gets alphabetized by Marshal
|
||||
}, ",") + `]`,
|
||||
},
|
||||
|
||||
// Maps
|
||||
{
|
||||
In: `{}`,
|
||||
Data: map[string]interface{}{},
|
||||
Out: `{}`,
|
||||
},
|
||||
{
|
||||
In: `{"boolkey":true,"floatkey":1.0,"intkey":1,"nullkey":null}`,
|
||||
Data: map[string]interface{}{"nullkey": nil, "boolkey": true, "intkey": int64(1), "floatkey": float64(1.0)},
|
||||
Out: `{"boolkey":true,"floatkey":1,"intkey":1,"nullkey":null}`, // gets alphabetized by Marshal
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
inputJSON := fmt.Sprintf(`{"data":%s}`, tc.In)
|
||||
expectedJSON := fmt.Sprintf(`{"data":%s}`, tc.Out)
|
||||
m := map[string]interface{}{}
|
||||
err := Unmarshal([]byte(inputJSON), &m)
|
||||
if tc.Err && err != nil {
|
||||
// Expected error
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("%s: error decoding: %v", tc.In, err)
|
||||
continue
|
||||
}
|
||||
if tc.Err {
|
||||
t.Errorf("%s: expected error, got none", tc.In)
|
||||
continue
|
||||
}
|
||||
data, ok := m["data"]
|
||||
if !ok {
|
||||
t.Errorf("%s: decoded object missing data key: %#v", tc.In, m)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(tc.Data, data) {
|
||||
t.Errorf("%s: expected\n\t%#v (%v), got\n\t%#v (%v)", tc.In, tc.Data, reflect.TypeOf(tc.Data), data, reflect.TypeOf(data))
|
||||
continue
|
||||
}
|
||||
|
||||
outputJSON, err := Marshal(m)
|
||||
if err != nil {
|
||||
t.Errorf("%s: error encoding: %v", tc.In, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if expectedJSON != string(outputJSON) {
|
||||
t.Errorf("%s: expected\n\t%s, got\n\t%s", tc.In, expectedJSON, string(outputJSON))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
39
vendor/k8s.io/apimachinery/pkg/util/mergepatch/BUILD
generated
vendored
39
vendor/k8s.io/apimachinery/pkg/util/mergepatch/BUILD
generated
vendored
|
|
@ -1,39 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["util_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"errors.go",
|
||||
"util.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/util/mergepatch",
|
||||
deps = [
|
||||
"//vendor/github.com/davecgh/go-spew/spew:go_default_library",
|
||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
138
vendor/k8s.io/apimachinery/pkg/util/mergepatch/util_test.go
generated
vendored
138
vendor/k8s.io/apimachinery/pkg/util/mergepatch/util_test.go
generated
vendored
|
|
@ -1,138 +0,0 @@
|
|||
/*
|
||||
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 mergepatch
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHasConflicts(t *testing.T) {
|
||||
testCases := []struct {
|
||||
A interface{}
|
||||
B interface{}
|
||||
Ret bool
|
||||
}{
|
||||
{A: "hello", B: "hello", Ret: false},
|
||||
{A: "hello", B: "hell", Ret: true},
|
||||
{A: "hello", B: nil, Ret: true},
|
||||
{A: "hello", B: 1, Ret: true},
|
||||
{A: "hello", B: float64(1.0), Ret: true},
|
||||
{A: "hello", B: false, Ret: true},
|
||||
{A: 1, B: 1, Ret: false},
|
||||
{A: nil, B: nil, Ret: false},
|
||||
{A: false, B: false, Ret: false},
|
||||
{A: float64(3), B: float64(3), Ret: false},
|
||||
|
||||
{A: "hello", B: []interface{}{}, Ret: true},
|
||||
{A: []interface{}{1}, B: []interface{}{}, Ret: true},
|
||||
{A: []interface{}{}, B: []interface{}{}, Ret: false},
|
||||
{A: []interface{}{1}, B: []interface{}{1}, Ret: false},
|
||||
{A: map[string]interface{}{}, B: []interface{}{1}, Ret: true},
|
||||
|
||||
{A: map[string]interface{}{}, B: map[string]interface{}{"a": 1}, Ret: false},
|
||||
{A: map[string]interface{}{"a": 1}, B: map[string]interface{}{"a": 1}, Ret: false},
|
||||
{A: map[string]interface{}{"a": 1}, B: map[string]interface{}{"a": 2}, Ret: true},
|
||||
{A: map[string]interface{}{"a": 1}, B: map[string]interface{}{"b": 2}, Ret: false},
|
||||
|
||||
{
|
||||
A: map[string]interface{}{"a": []interface{}{1}},
|
||||
B: map[string]interface{}{"a": []interface{}{1}},
|
||||
Ret: false,
|
||||
},
|
||||
{
|
||||
A: map[string]interface{}{"a": []interface{}{1}},
|
||||
B: map[string]interface{}{"a": []interface{}{}},
|
||||
Ret: true,
|
||||
},
|
||||
{
|
||||
A: map[string]interface{}{"a": []interface{}{1}},
|
||||
B: map[string]interface{}{"a": 1},
|
||||
Ret: true,
|
||||
},
|
||||
|
||||
// Maps and lists with multiple entries.
|
||||
{
|
||||
A: map[string]interface{}{"a": 1, "b": 2},
|
||||
B: map[string]interface{}{"a": 1, "b": 0},
|
||||
Ret: true,
|
||||
},
|
||||
{
|
||||
A: map[string]interface{}{"a": 1, "b": 2},
|
||||
B: map[string]interface{}{"a": 1, "b": 2},
|
||||
Ret: false,
|
||||
},
|
||||
{
|
||||
A: map[string]interface{}{"a": 1, "b": 2},
|
||||
B: map[string]interface{}{"a": 1, "b": 0, "c": 3},
|
||||
Ret: true,
|
||||
},
|
||||
{
|
||||
A: map[string]interface{}{"a": 1, "b": 2},
|
||||
B: map[string]interface{}{"a": 1, "b": 2, "c": 3},
|
||||
Ret: false,
|
||||
},
|
||||
{
|
||||
A: map[string]interface{}{"a": []interface{}{1, 2}},
|
||||
B: map[string]interface{}{"a": []interface{}{1, 0}},
|
||||
Ret: true,
|
||||
},
|
||||
{
|
||||
A: map[string]interface{}{"a": []interface{}{1, 2}},
|
||||
B: map[string]interface{}{"a": []interface{}{1, 2}},
|
||||
Ret: false,
|
||||
},
|
||||
|
||||
// Numeric types are not interchangeable.
|
||||
// Callers are expected to ensure numeric types are consistent in 'left' and 'right'.
|
||||
{A: int(0), B: int64(0), Ret: true},
|
||||
{A: int(0), B: float64(0), Ret: true},
|
||||
{A: int64(0), B: float64(0), Ret: true},
|
||||
// Other types are not interchangeable.
|
||||
{A: int(0), B: "0", Ret: true},
|
||||
{A: int(0), B: nil, Ret: true},
|
||||
{A: int(0), B: false, Ret: true},
|
||||
{A: "true", B: true, Ret: true},
|
||||
{A: "null", B: nil, Ret: true},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
testStr := fmt.Sprintf("A = %#v, B = %#v", testCase.A, testCase.B)
|
||||
// Run each test case multiple times if it passes because HasConflicts()
|
||||
// uses map iteration, which returns keys in nondeterministic order.
|
||||
for try := 0; try < 10; try++ {
|
||||
out, err := HasConflicts(testCase.A, testCase.B)
|
||||
if err != nil {
|
||||
t.Errorf("%v: unexpected error: %v", testStr, err)
|
||||
break
|
||||
}
|
||||
if out != testCase.Ret {
|
||||
t.Errorf("%v: expected %t got %t", testStr, testCase.Ret, out)
|
||||
break
|
||||
}
|
||||
out, err = HasConflicts(testCase.B, testCase.A)
|
||||
if err != nil {
|
||||
t.Errorf("%v: unexpected error: %v", testStr, err)
|
||||
break
|
||||
}
|
||||
if out != testCase.Ret {
|
||||
t.Errorf("%v: expected reversed %t got %t", testStr, testCase.Ret, out)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
50
vendor/k8s.io/apimachinery/pkg/util/net/BUILD
generated
vendored
50
vendor/k8s.io/apimachinery/pkg/util/net/BUILD
generated
vendored
|
|
@ -1,50 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"http_test.go",
|
||||
"interface_test.go",
|
||||
"port_range_test.go",
|
||||
"port_split_test.go",
|
||||
"util_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = ["//vendor/github.com/spf13/pflag:go_default_library"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"http.go",
|
||||
"interface.go",
|
||||
"port_range.go",
|
||||
"port_split.go",
|
||||
"util.go",
|
||||
],
|
||||
importpath = "k8s.io/apimachinery/pkg/util/net",
|
||||
deps = [
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/golang.org/x/net/http2:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
3
vendor/k8s.io/apimachinery/pkg/util/net/http.go
generated
vendored
3
vendor/k8s.io/apimachinery/pkg/util/net/http.go
generated
vendored
|
|
@ -61,6 +61,9 @@ func JoinPreservingTrailingSlash(elem ...string) string {
|
|||
// differentiate probable errors in connection behavior between normal "this is
|
||||
// disconnected" should use the method.
|
||||
func IsProbableEOF(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
if uerr, ok := err.(*url.Error); ok {
|
||||
err = uerr.Err
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue