mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 02:43:36 +00:00
60
vendor/k8s.io/client-go/testing/BUILD
generated
vendored
60
vendor/k8s.io/client-go/testing/BUILD
generated
vendored
@ -1,60 +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 = [
|
||||
"actions.go",
|
||||
"fake.go",
|
||||
"fixture.go",
|
||||
],
|
||||
importpath = "k8s.io/client-go/testing",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors: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/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/version:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
|
||||
"//vendor/k8s.io/client-go/pkg/version:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"fixture_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//vendor/github.com/stretchr/testify/assert: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/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/watch:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
185
vendor/k8s.io/client-go/testing/actions.go
generated
vendored
185
vendor/k8s.io/client-go/testing/actions.go
generated
vendored
@ -26,6 +26,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
func NewRootGetAction(resource schema.GroupVersionResource, name string) GetActionImpl {
|
||||
@ -58,6 +59,16 @@ func NewGetSubresourceAction(resource schema.GroupVersionResource, namespace, su
|
||||
return action
|
||||
}
|
||||
|
||||
func NewRootGetSubresourceAction(resource schema.GroupVersionResource, subresource, name string) GetActionImpl {
|
||||
action := GetActionImpl{}
|
||||
action.Verb = "get"
|
||||
action.Resource = resource
|
||||
action.Subresource = subresource
|
||||
action.Name = name
|
||||
|
||||
return action
|
||||
}
|
||||
|
||||
func NewRootListAction(resource schema.GroupVersionResource, kind schema.GroupVersionKind, opts interface{}) ListActionImpl {
|
||||
action := ListActionImpl{}
|
||||
action.Verb = "list"
|
||||
@ -81,20 +92,6 @@ func NewListAction(resource schema.GroupVersionResource, kind schema.GroupVersio
|
||||
return action
|
||||
}
|
||||
|
||||
func NewListSubresourceAction(resource schema.GroupVersionResource, name, subresource string, kind schema.GroupVersionKind, namespace string, opts interface{}) ListActionImpl {
|
||||
action := ListActionImpl{}
|
||||
action.Verb = "list"
|
||||
action.Resource = resource
|
||||
action.Subresource = subresource
|
||||
action.Kind = kind
|
||||
action.Namespace = namespace
|
||||
action.Name = name
|
||||
labelSelector, fieldSelector, _ := ExtractFromListOptions(opts)
|
||||
action.ListRestrictions = ListRestrictions{labelSelector, fieldSelector}
|
||||
|
||||
return action
|
||||
}
|
||||
|
||||
func NewRootCreateAction(resource schema.GroupVersionResource, object runtime.Object) CreateActionImpl {
|
||||
action := CreateActionImpl{}
|
||||
action.Verb = "create"
|
||||
@ -114,12 +111,23 @@ func NewCreateAction(resource schema.GroupVersionResource, namespace string, obj
|
||||
return action
|
||||
}
|
||||
|
||||
func NewCreateSubresourceAction(resource schema.GroupVersionResource, name, subresource string, namespace string, object runtime.Object) CreateActionImpl {
|
||||
func NewRootCreateSubresourceAction(resource schema.GroupVersionResource, name, subresource string, object runtime.Object) CreateActionImpl {
|
||||
action := CreateActionImpl{}
|
||||
action.Verb = "create"
|
||||
action.Resource = resource
|
||||
action.Subresource = subresource
|
||||
action.Name = name
|
||||
action.Object = object
|
||||
|
||||
return action
|
||||
}
|
||||
|
||||
func NewCreateSubresourceAction(resource schema.GroupVersionResource, name, subresource, namespace string, object runtime.Object) CreateActionImpl {
|
||||
action := CreateActionImpl{}
|
||||
action.Verb = "create"
|
||||
action.Resource = resource
|
||||
action.Namespace = namespace
|
||||
action.Subresource = subresource
|
||||
action.Name = name
|
||||
action.Object = object
|
||||
|
||||
@ -145,45 +153,49 @@ func NewUpdateAction(resource schema.GroupVersionResource, namespace string, obj
|
||||
return action
|
||||
}
|
||||
|
||||
func NewRootPatchAction(resource schema.GroupVersionResource, name string, patch []byte) PatchActionImpl {
|
||||
func NewRootPatchAction(resource schema.GroupVersionResource, name string, pt types.PatchType, patch []byte) PatchActionImpl {
|
||||
action := PatchActionImpl{}
|
||||
action.Verb = "patch"
|
||||
action.Resource = resource
|
||||
action.Name = name
|
||||
action.PatchType = pt
|
||||
action.Patch = patch
|
||||
|
||||
return action
|
||||
}
|
||||
|
||||
func NewPatchAction(resource schema.GroupVersionResource, namespace string, name string, patch []byte) PatchActionImpl {
|
||||
func NewPatchAction(resource schema.GroupVersionResource, namespace string, name string, pt types.PatchType, patch []byte) PatchActionImpl {
|
||||
action := PatchActionImpl{}
|
||||
action.Verb = "patch"
|
||||
action.Resource = resource
|
||||
action.Namespace = namespace
|
||||
action.Name = name
|
||||
action.PatchType = pt
|
||||
action.Patch = patch
|
||||
|
||||
return action
|
||||
}
|
||||
|
||||
func NewRootPatchSubresourceAction(resource schema.GroupVersionResource, name string, patch []byte, subresources ...string) PatchActionImpl {
|
||||
func NewRootPatchSubresourceAction(resource schema.GroupVersionResource, name string, pt types.PatchType, patch []byte, subresources ...string) PatchActionImpl {
|
||||
action := PatchActionImpl{}
|
||||
action.Verb = "patch"
|
||||
action.Resource = resource
|
||||
action.Subresource = path.Join(subresources...)
|
||||
action.Name = name
|
||||
action.PatchType = pt
|
||||
action.Patch = patch
|
||||
|
||||
return action
|
||||
}
|
||||
|
||||
func NewPatchSubresourceAction(resource schema.GroupVersionResource, namespace, name string, patch []byte, subresources ...string) PatchActionImpl {
|
||||
func NewPatchSubresourceAction(resource schema.GroupVersionResource, namespace, name string, pt types.PatchType, patch []byte, subresources ...string) PatchActionImpl {
|
||||
action := PatchActionImpl{}
|
||||
action.Verb = "patch"
|
||||
action.Resource = resource
|
||||
action.Subresource = path.Join(subresources...)
|
||||
action.Namespace = namespace
|
||||
action.Name = name
|
||||
action.PatchType = pt
|
||||
action.Patch = patch
|
||||
|
||||
return action
|
||||
@ -218,6 +230,16 @@ func NewRootDeleteAction(resource schema.GroupVersionResource, name string) Dele
|
||||
return action
|
||||
}
|
||||
|
||||
func NewRootDeleteSubresourceAction(resource schema.GroupVersionResource, subresource string, name string) DeleteActionImpl {
|
||||
action := DeleteActionImpl{}
|
||||
action.Verb = "delete"
|
||||
action.Resource = resource
|
||||
action.Subresource = subresource
|
||||
action.Name = name
|
||||
|
||||
return action
|
||||
}
|
||||
|
||||
func NewDeleteAction(resource schema.GroupVersionResource, namespace, name string) DeleteActionImpl {
|
||||
action := DeleteActionImpl{}
|
||||
action.Verb = "delete"
|
||||
@ -228,6 +250,17 @@ func NewDeleteAction(resource schema.GroupVersionResource, namespace, name strin
|
||||
return action
|
||||
}
|
||||
|
||||
func NewDeleteSubresourceAction(resource schema.GroupVersionResource, subresource, namespace, name string) DeleteActionImpl {
|
||||
action := DeleteActionImpl{}
|
||||
action.Verb = "delete"
|
||||
action.Resource = resource
|
||||
action.Subresource = subresource
|
||||
action.Namespace = namespace
|
||||
action.Name = name
|
||||
|
||||
return action
|
||||
}
|
||||
|
||||
func NewRootDeleteCollectionAction(resource schema.GroupVersionResource, opts interface{}) DeleteCollectionActionImpl {
|
||||
action := DeleteCollectionActionImpl{}
|
||||
action.Verb = "delete-collection"
|
||||
@ -324,6 +357,10 @@ type Action interface {
|
||||
GetResource() schema.GroupVersionResource
|
||||
GetSubresource() string
|
||||
Matches(verb, resource string) bool
|
||||
|
||||
// DeepCopy is used to copy an action to avoid any risk of accidental mutation. Most people never need to call this
|
||||
// because the invocation logic deep copies before calls to storage and reactors.
|
||||
DeepCopy() Action
|
||||
}
|
||||
|
||||
type GenericAction interface {
|
||||
@ -364,6 +401,7 @@ type DeleteCollectionAction interface {
|
||||
type PatchAction interface {
|
||||
Action
|
||||
GetName() string
|
||||
GetPatchType() types.PatchType
|
||||
GetPatch() []byte
|
||||
}
|
||||
|
||||
@ -404,6 +442,10 @@ func (a ActionImpl) Matches(verb, resource string) bool {
|
||||
return strings.ToLower(verb) == strings.ToLower(a.Verb) &&
|
||||
strings.ToLower(resource) == strings.ToLower(a.Resource.Resource)
|
||||
}
|
||||
func (a ActionImpl) DeepCopy() Action {
|
||||
ret := a
|
||||
return ret
|
||||
}
|
||||
|
||||
type GenericActionImpl struct {
|
||||
ActionImpl
|
||||
@ -414,6 +456,14 @@ func (a GenericActionImpl) GetValue() interface{} {
|
||||
return a.Value
|
||||
}
|
||||
|
||||
func (a GenericActionImpl) DeepCopy() Action {
|
||||
return GenericActionImpl{
|
||||
ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
|
||||
// TODO this is wrong, but no worse than before
|
||||
Value: a.Value,
|
||||
}
|
||||
}
|
||||
|
||||
type GetActionImpl struct {
|
||||
ActionImpl
|
||||
Name string
|
||||
@ -423,6 +473,13 @@ func (a GetActionImpl) GetName() string {
|
||||
return a.Name
|
||||
}
|
||||
|
||||
func (a GetActionImpl) DeepCopy() Action {
|
||||
return GetActionImpl{
|
||||
ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
|
||||
Name: a.Name,
|
||||
}
|
||||
}
|
||||
|
||||
type ListActionImpl struct {
|
||||
ActionImpl
|
||||
Kind schema.GroupVersionKind
|
||||
@ -438,6 +495,18 @@ func (a ListActionImpl) GetListRestrictions() ListRestrictions {
|
||||
return a.ListRestrictions
|
||||
}
|
||||
|
||||
func (a ListActionImpl) DeepCopy() Action {
|
||||
return ListActionImpl{
|
||||
ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
|
||||
Kind: a.Kind,
|
||||
Name: a.Name,
|
||||
ListRestrictions: ListRestrictions{
|
||||
Labels: a.ListRestrictions.Labels.DeepCopySelector(),
|
||||
Fields: a.ListRestrictions.Fields.DeepCopySelector(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type CreateActionImpl struct {
|
||||
ActionImpl
|
||||
Name string
|
||||
@ -448,6 +517,14 @@ func (a CreateActionImpl) GetObject() runtime.Object {
|
||||
return a.Object
|
||||
}
|
||||
|
||||
func (a CreateActionImpl) DeepCopy() Action {
|
||||
return CreateActionImpl{
|
||||
ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
|
||||
Name: a.Name,
|
||||
Object: a.Object.DeepCopyObject(),
|
||||
}
|
||||
}
|
||||
|
||||
type UpdateActionImpl struct {
|
||||
ActionImpl
|
||||
Object runtime.Object
|
||||
@ -457,10 +534,18 @@ func (a UpdateActionImpl) GetObject() runtime.Object {
|
||||
return a.Object
|
||||
}
|
||||
|
||||
func (a UpdateActionImpl) DeepCopy() Action {
|
||||
return UpdateActionImpl{
|
||||
ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
|
||||
Object: a.Object.DeepCopyObject(),
|
||||
}
|
||||
}
|
||||
|
||||
type PatchActionImpl struct {
|
||||
ActionImpl
|
||||
Name string
|
||||
Patch []byte
|
||||
Name string
|
||||
PatchType types.PatchType
|
||||
Patch []byte
|
||||
}
|
||||
|
||||
func (a PatchActionImpl) GetName() string {
|
||||
@ -471,6 +556,21 @@ func (a PatchActionImpl) GetPatch() []byte {
|
||||
return a.Patch
|
||||
}
|
||||
|
||||
func (a PatchActionImpl) GetPatchType() types.PatchType {
|
||||
return a.PatchType
|
||||
}
|
||||
|
||||
func (a PatchActionImpl) DeepCopy() Action {
|
||||
patch := make([]byte, len(a.Patch))
|
||||
copy(patch, a.Patch)
|
||||
return PatchActionImpl{
|
||||
ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
|
||||
Name: a.Name,
|
||||
PatchType: a.PatchType,
|
||||
Patch: patch,
|
||||
}
|
||||
}
|
||||
|
||||
type DeleteActionImpl struct {
|
||||
ActionImpl
|
||||
Name string
|
||||
@ -480,6 +580,13 @@ func (a DeleteActionImpl) GetName() string {
|
||||
return a.Name
|
||||
}
|
||||
|
||||
func (a DeleteActionImpl) DeepCopy() Action {
|
||||
return DeleteActionImpl{
|
||||
ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
|
||||
Name: a.Name,
|
||||
}
|
||||
}
|
||||
|
||||
type DeleteCollectionActionImpl struct {
|
||||
ActionImpl
|
||||
ListRestrictions ListRestrictions
|
||||
@ -489,6 +596,16 @@ func (a DeleteCollectionActionImpl) GetListRestrictions() ListRestrictions {
|
||||
return a.ListRestrictions
|
||||
}
|
||||
|
||||
func (a DeleteCollectionActionImpl) DeepCopy() Action {
|
||||
return DeleteCollectionActionImpl{
|
||||
ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
|
||||
ListRestrictions: ListRestrictions{
|
||||
Labels: a.ListRestrictions.Labels.DeepCopySelector(),
|
||||
Fields: a.ListRestrictions.Fields.DeepCopySelector(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type WatchActionImpl struct {
|
||||
ActionImpl
|
||||
WatchRestrictions WatchRestrictions
|
||||
@ -498,6 +615,17 @@ func (a WatchActionImpl) GetWatchRestrictions() WatchRestrictions {
|
||||
return a.WatchRestrictions
|
||||
}
|
||||
|
||||
func (a WatchActionImpl) DeepCopy() Action {
|
||||
return WatchActionImpl{
|
||||
ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
|
||||
WatchRestrictions: WatchRestrictions{
|
||||
Labels: a.WatchRestrictions.Labels.DeepCopySelector(),
|
||||
Fields: a.WatchRestrictions.Fields.DeepCopySelector(),
|
||||
ResourceVersion: a.WatchRestrictions.ResourceVersion,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type ProxyGetActionImpl struct {
|
||||
ActionImpl
|
||||
Scheme string
|
||||
@ -526,3 +654,18 @@ func (a ProxyGetActionImpl) GetPath() string {
|
||||
func (a ProxyGetActionImpl) GetParams() map[string]string {
|
||||
return a.Params
|
||||
}
|
||||
|
||||
func (a ProxyGetActionImpl) DeepCopy() Action {
|
||||
params := map[string]string{}
|
||||
for k, v := range a.Params {
|
||||
params[k] = v
|
||||
}
|
||||
return ProxyGetActionImpl{
|
||||
ActionImpl: a.ActionImpl.DeepCopy().(ActionImpl),
|
||||
Scheme: a.Scheme,
|
||||
Name: a.Name,
|
||||
Port: a.Port,
|
||||
Path: a.Path,
|
||||
Params: params,
|
||||
}
|
||||
}
|
||||
|
58
vendor/k8s.io/client-go/testing/fake.go
generated
vendored
58
vendor/k8s.io/client-go/testing/fake.go
generated
vendored
@ -22,10 +22,7 @@ import (
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/version"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
kubeversion "k8s.io/client-go/pkg/version"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
@ -134,13 +131,13 @@ func (c *Fake) Invokes(action Action, defaultReturnObj runtime.Object) (runtime.
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
c.actions = append(c.actions, action)
|
||||
c.actions = append(c.actions, action.DeepCopy())
|
||||
for _, reactor := range c.ReactionChain {
|
||||
if !reactor.Handles(action) {
|
||||
continue
|
||||
}
|
||||
|
||||
handled, ret, err := reactor.React(action)
|
||||
handled, ret, err := reactor.React(action.DeepCopy())
|
||||
if !handled {
|
||||
continue
|
||||
}
|
||||
@ -157,13 +154,13 @@ func (c *Fake) InvokesWatch(action Action) (watch.Interface, error) {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
c.actions = append(c.actions, action)
|
||||
c.actions = append(c.actions, action.DeepCopy())
|
||||
for _, reactor := range c.WatchReactionChain {
|
||||
if !reactor.Handles(action) {
|
||||
continue
|
||||
}
|
||||
|
||||
handled, ret, err := reactor.React(action)
|
||||
handled, ret, err := reactor.React(action.DeepCopy())
|
||||
if !handled {
|
||||
continue
|
||||
}
|
||||
@ -180,13 +177,13 @@ func (c *Fake) InvokesProxy(action Action) restclient.ResponseWrapper {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
c.actions = append(c.actions, action)
|
||||
c.actions = append(c.actions, action.DeepCopy())
|
||||
for _, reactor := range c.ProxyReactionChain {
|
||||
if !reactor.Handles(action) {
|
||||
continue
|
||||
}
|
||||
|
||||
handled, ret, err := reactor.React(action)
|
||||
handled, ret, err := reactor.React(action.DeepCopy())
|
||||
if !handled || err != nil {
|
||||
continue
|
||||
}
|
||||
@ -214,46 +211,3 @@ func (c *Fake) Actions() []Action {
|
||||
copy(fa, c.actions)
|
||||
return fa
|
||||
}
|
||||
|
||||
// TODO: this probably should be moved to somewhere else.
|
||||
type FakeDiscovery struct {
|
||||
*Fake
|
||||
}
|
||||
|
||||
func (c *FakeDiscovery) ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error) {
|
||||
action := ActionImpl{
|
||||
Verb: "get",
|
||||
Resource: schema.GroupVersionResource{Resource: "resource"},
|
||||
}
|
||||
c.Invokes(action, nil)
|
||||
for _, rl := range c.Resources {
|
||||
if rl.GroupVersion == groupVersion {
|
||||
return rl, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("GroupVersion %q not found", groupVersion)
|
||||
}
|
||||
|
||||
func (c *FakeDiscovery) ServerResources() ([]*metav1.APIResourceList, error) {
|
||||
action := ActionImpl{
|
||||
Verb: "get",
|
||||
Resource: schema.GroupVersionResource{Resource: "resource"},
|
||||
}
|
||||
c.Invokes(action, nil)
|
||||
return c.Resources, nil
|
||||
}
|
||||
|
||||
func (c *FakeDiscovery) ServerGroups() (*metav1.APIGroupList, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *FakeDiscovery) ServerVersion() (*version.Info, error) {
|
||||
action := ActionImpl{}
|
||||
action.Verb = "get"
|
||||
action.Resource = schema.GroupVersionResource{Resource: "version"}
|
||||
|
||||
c.Invokes(action, nil)
|
||||
versionInfo := kubeversion.Get()
|
||||
return &versionInfo, nil
|
||||
}
|
||||
|
74
vendor/k8s.io/client-go/testing/fixture.go
generated
vendored
74
vendor/k8s.io/client-go/testing/fixture.go
generated
vendored
@ -20,20 +20,19 @@ import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/evanphx/json-patch"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// FakeWatchBufferSize is the max num of watch event can be buffered in the
|
||||
// watch channel. Note that when watch event overflows or exceed this buffer
|
||||
// size, manipulations via fake client may be blocked.
|
||||
const FakeWatchBufferSize = 128
|
||||
|
||||
// ObjectTracker keeps track of objects. It is intended to be used to
|
||||
// fake calls to a server by returning objects based on their kind,
|
||||
// namespace and name.
|
||||
@ -77,7 +76,6 @@ func ObjectReaction(tracker ObjectTracker) ReactionFunc {
|
||||
return func(action Action) (bool, runtime.Object, error) {
|
||||
ns := action.GetNamespace()
|
||||
gvr := action.GetResource()
|
||||
|
||||
// Here and below we need to switch on implementation types,
|
||||
// not on interfaces, as some interfaces are identical
|
||||
// (e.g. UpdateAction and CreateAction), so if we use them,
|
||||
@ -130,6 +128,49 @@ func ObjectReaction(tracker ObjectTracker) ReactionFunc {
|
||||
}
|
||||
return true, nil, nil
|
||||
|
||||
case PatchActionImpl:
|
||||
obj, err := tracker.Get(gvr, ns, action.GetName())
|
||||
if err != nil {
|
||||
// object is not registered
|
||||
return false, nil, err
|
||||
}
|
||||
|
||||
old, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
return true, nil, err
|
||||
}
|
||||
// Only supports strategic merge patch and JSONPatch as coded.
|
||||
switch action.GetPatchType() {
|
||||
case types.JSONPatchType:
|
||||
patch, err := jsonpatch.DecodePatch(action.GetPatch())
|
||||
if err != nil {
|
||||
return true, nil, err
|
||||
}
|
||||
modified, err := patch.Apply(old)
|
||||
if err != nil {
|
||||
return true, nil, err
|
||||
}
|
||||
if err = json.Unmarshal(modified, obj); err != nil {
|
||||
return true, nil, err
|
||||
}
|
||||
case types.StrategicMergePatchType:
|
||||
mergedByte, err := strategicpatch.StrategicMergePatch(old, action.GetPatch(), obj)
|
||||
if err != nil {
|
||||
return true, nil, err
|
||||
}
|
||||
if err = json.Unmarshal(mergedByte, obj); err != nil {
|
||||
return true, nil, err
|
||||
}
|
||||
default:
|
||||
return true, nil, fmt.Errorf("PatchType is not supported")
|
||||
}
|
||||
|
||||
if err = tracker.Update(gvr, obj, ns); err != nil {
|
||||
return true, nil, err
|
||||
}
|
||||
|
||||
return true, obj, nil
|
||||
|
||||
default:
|
||||
return false, nil, fmt.Errorf("no reaction implemented for %s", action)
|
||||
}
|
||||
@ -142,12 +183,11 @@ type tracker struct {
|
||||
lock sync.RWMutex
|
||||
objects map[schema.GroupVersionResource][]runtime.Object
|
||||
// The value type of watchers is a map of which the key is either a namespace or
|
||||
// all/non namespace aka "" and its value is list of fake watchers. Each of
|
||||
// fake watcher holds a buffered channel of size "FakeWatchBufferSize" which
|
||||
// is default to 128. Manipulations on resources will broadcast the notification
|
||||
// events into the watchers' channel and note that too many unhandled event may
|
||||
// potentially block the tracker.
|
||||
watchers map[schema.GroupVersionResource]map[string][]*watch.FakeWatcher
|
||||
// all/non namespace aka "" and its value is list of fake watchers.
|
||||
// Manipulations on resources will broadcast the notification events into the
|
||||
// watchers' channel. Note that too many unhandled events (currently 100,
|
||||
// see apimachinery/pkg/watch.DefaultChanSize) will cause a panic.
|
||||
watchers map[schema.GroupVersionResource]map[string][]*watch.RaceFreeFakeWatcher
|
||||
}
|
||||
|
||||
var _ ObjectTracker = &tracker{}
|
||||
@ -159,7 +199,7 @@ func NewObjectTracker(scheme ObjectScheme, decoder runtime.Decoder) ObjectTracke
|
||||
scheme: scheme,
|
||||
decoder: decoder,
|
||||
objects: make(map[schema.GroupVersionResource][]runtime.Object),
|
||||
watchers: make(map[schema.GroupVersionResource]map[string][]*watch.FakeWatcher),
|
||||
watchers: make(map[schema.GroupVersionResource]map[string][]*watch.RaceFreeFakeWatcher),
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,10 +246,10 @@ func (t *tracker) Watch(gvr schema.GroupVersionResource, ns string) (watch.Inter
|
||||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
|
||||
fakewatcher := watch.NewFakeWithChanSize(FakeWatchBufferSize, true)
|
||||
fakewatcher := watch.NewRaceFreeFake()
|
||||
|
||||
if _, exists := t.watchers[gvr]; !exists {
|
||||
t.watchers[gvr] = make(map[string][]*watch.FakeWatcher)
|
||||
t.watchers[gvr] = make(map[string][]*watch.RaceFreeFakeWatcher)
|
||||
}
|
||||
t.watchers[gvr][ns] = append(t.watchers[gvr][ns], fakewatcher)
|
||||
return fakewatcher, nil
|
||||
@ -293,8 +333,8 @@ func (t *tracker) Update(gvr schema.GroupVersionResource, obj runtime.Object, ns
|
||||
return t.add(gvr, obj, ns, true)
|
||||
}
|
||||
|
||||
func (t *tracker) getWatches(gvr schema.GroupVersionResource, ns string) []*watch.FakeWatcher {
|
||||
watches := []*watch.FakeWatcher{}
|
||||
func (t *tracker) getWatches(gvr schema.GroupVersionResource, ns string) []*watch.RaceFreeFakeWatcher {
|
||||
watches := []*watch.RaceFreeFakeWatcher{}
|
||||
if t.watchers[gvr] != nil {
|
||||
if w := t.watchers[gvr][ns]; w != nil {
|
||||
watches = append(watches, w...)
|
||||
|
43
vendor/k8s.io/client-go/testing/fixture_test.go
generated
vendored
43
vendor/k8s.io/client-go/testing/fixture_test.go
generated
vendored
@ -63,6 +63,9 @@ func TestWatchCallNonNamespace(t *testing.T) {
|
||||
codecs := serializer.NewCodecFactory(scheme)
|
||||
o := NewObjectTracker(scheme, codecs.UniversalDecoder())
|
||||
watch, err := o.Watch(testResource, ns)
|
||||
if err != nil {
|
||||
t.Fatalf("test resource watch failed in %s: %v ", ns, err)
|
||||
}
|
||||
go func() {
|
||||
err := o.Create(testResource, testObj, ns)
|
||||
if err != nil {
|
||||
@ -85,7 +88,13 @@ func TestWatchCallAllNamespace(t *testing.T) {
|
||||
codecs := serializer.NewCodecFactory(scheme)
|
||||
o := NewObjectTracker(scheme, codecs.UniversalDecoder())
|
||||
w, err := o.Watch(testResource, "test_namespace")
|
||||
if err != nil {
|
||||
t.Fatalf("test resource watch failed in test_namespace: %v", err)
|
||||
}
|
||||
wAll, err := o.Watch(testResource, "")
|
||||
if err != nil {
|
||||
t.Fatalf("test resource watch failed in all namespaces: %v", err)
|
||||
}
|
||||
go func() {
|
||||
err := o.Create(testResource, testObj, ns)
|
||||
assert.NoError(t, err, "test resource creation failed")
|
||||
@ -161,6 +170,9 @@ func TestWatchCallMultipleInvocation(t *testing.T) {
|
||||
for idx, watchNamespace := range watchNamespaces {
|
||||
i := idx
|
||||
w, err := o.Watch(testResource, watchNamespace)
|
||||
if err != nil {
|
||||
t.Fatalf("test resource watch failed in %s: %v", watchNamespace, err)
|
||||
}
|
||||
go func() {
|
||||
assert.NoError(t, err, "watch invocation failed")
|
||||
for _, c := range cases {
|
||||
@ -190,3 +202,34 @@ func TestWatchCallMultipleInvocation(t *testing.T) {
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestWatchAddAfterStop(t *testing.T) {
|
||||
testResource := schema.GroupVersionResource{Group: "", Version: "test_version", Resource: "test_kind"}
|
||||
testObj := getArbitraryResource(testResource, "test_name", "test_namespace")
|
||||
accessor, err := meta.Accessor(testObj)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
ns := accessor.GetNamespace()
|
||||
scheme := runtime.NewScheme()
|
||||
codecs := serializer.NewCodecFactory(scheme)
|
||||
o := NewObjectTracker(scheme, codecs.UniversalDecoder())
|
||||
watch, err := o.Watch(testResource, ns)
|
||||
if err != nil {
|
||||
t.Errorf("watch creation failed: %v", err)
|
||||
}
|
||||
|
||||
// When the watch is stopped it should ignore later events without panicking.
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Errorf("Watch panicked when it should have ignored create after stop: %v", r)
|
||||
}
|
||||
}()
|
||||
|
||||
watch.Stop()
|
||||
err = o.Create(testResource, testObj, ns)
|
||||
if err != nil {
|
||||
t.Errorf("test resource creation failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user