Merge pull request #5659 from mohamedawnallah/unitTestWaitAPIClient

operator/pkg/util/apiclient: unit test wait
This commit is contained in:
karmada-bot 2024-10-17 20:41:29 +08:00 committed by GitHub
commit 0d55eadb89
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 1026 additions and 6 deletions

View File

@ -36,6 +36,18 @@ const (
APICallRetryInterval = 500 * time.Millisecond
)
var (
// initialBackoffDuration defines the initial duration for the backoff mechanism,
// set to 5 seconds. This value is used to determine the wait time before retrying
// a failed command.
initialBackoffDuration = 5 * time.Second
// backoffTimeoutFactor is the factor by which the backoff duration is multiplied
// after each failure. In this case, it is set to 2, meaning the wait time will
// double with each consecutive failure.
backoffTimeoutFactor float64 = 2
)
// Waiter is an interface for waiting for criteria in Karmada to happen
type Waiter interface {
// WaitForAPI waits for the API Server's /healthz endpoint to become "ok"
@ -79,9 +91,13 @@ func (w *KarmadaWaiter) WaitForAPI() error {
})
}
var aggregateClientFromConfigBuilder = func(karmadaConfig *rest.Config) (aggregator.Interface, error) {
return aggregator.NewForConfig(karmadaConfig)
}
// WaitForAPIService waits for the APIService condition to become "true"
func (w *KarmadaWaiter) WaitForAPIService(name string) error {
aggregateClient, err := aggregator.NewForConfig(w.karmadaConfig)
aggregateClient, err := aggregateClientFromConfigBuilder(w.karmadaConfig)
if err != nil {
return err
}
@ -162,20 +178,21 @@ func (w *KarmadaWaiter) SetTimeout(timeout time.Duration) {
w.timeout = timeout
}
// TryRunCommand runs a function a maximum of failureThreshold times, and retries on error. If failureThreshold is hit; the last error is returned
// TryRunCommand runs a function a maximum of failureThreshold times, and
// retries on error. If failureThreshold is hit; the last error is returned.
func TryRunCommand(f func() error, failureThreshold int) error {
backoff := wait.Backoff{
Duration: 5 * time.Second,
Factor: 2, // double the timeout for every failure
Duration: initialBackoffDuration,
Factor: backoffTimeoutFactor,
Steps: failureThreshold,
}
return wait.ExponentialBackoff(backoff, func() (bool, error) {
err := f()
if err != nil {
// Retry until the timeout
// Retry until the timeout.
return false, nil
}
// The last f() call was a success, return cleanly
// The last f() call was a success, return cleanly.
return true, nil
})
}

View File

@ -0,0 +1,446 @@
/*
Copyright 2024 The Karmada 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 apiclient
import (
"context"
"errors"
"fmt"
"net/http"
"testing"
"time"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
clientset "k8s.io/client-go/kubernetes"
fakeclientset "k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/rest"
fakerest "k8s.io/client-go/rest/fake"
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
aggregator "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
fakeAggregator "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake"
"github.com/karmada-io/karmada/operator/pkg/constants"
)
func TestWaitForAPI(t *testing.T) {
tests := []struct {
name string
karmadaWriter *KarmadaWaiter
wantErr bool
}{
{
name: "WaitForAPI_WaitingForAPIServerHealthyStatus_Timeout",
karmadaWriter: &KarmadaWaiter{
karmadaConfig: &rest.Config{},
client: &MockK8SRESTClient{
RESTClientConnector: &fakerest.RESTClient{
NegotiatedSerializer: runtime.NewSimpleNegotiatedSerializer(runtime.SerializerInfo{}),
Client: fakerest.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
return nil, fmt.Errorf("unexpected error, endpoint %s does not exist", req.URL.Path)
}),
},
},
timeout: time.Second,
},
wantErr: true,
},
{
name: "WaitForAPI_WaitingForAPIServerHealthyStatus_APIServerIsHealthy",
karmadaWriter: &KarmadaWaiter{
karmadaConfig: &rest.Config{},
client: &MockK8SRESTClient{
RESTClientConnector: &fakerest.RESTClient{
NegotiatedSerializer: runtime.NewSimpleNegotiatedSerializer(runtime.SerializerInfo{}),
Client: fakerest.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
if req.URL.Path == "/healthz" {
// Return a fake 200 OK response.
return &http.Response{
StatusCode: http.StatusOK,
Body: http.NoBody,
}, nil
}
return nil, fmt.Errorf("unexpected error, endpoint %s does not exist", req.URL.Path)
}),
},
},
timeout: time.Millisecond,
},
wantErr: false,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
err := test.karmadaWriter.WaitForAPI()
if err == nil && test.wantErr {
t.Errorf("expected an error, but got none")
}
if err != nil && !test.wantErr {
t.Errorf("unexpected error, got: %v", err)
}
})
}
}
func TestWaitForAPIService(t *testing.T) {
name := "karmada-demo-apiservice"
tests := []struct {
name string
karmadaWriter *KarmadaWaiter
apiService *apiregistrationv1.APIService
client aggregator.Interface
prep func(aggregator.Interface, *apiregistrationv1.APIService) error
wantErr bool
}{
{
name: "WaitForAPIService_WaitingForKarmadaAPIServiceAvailableStatus_Timeout",
karmadaWriter: &KarmadaWaiter{
karmadaConfig: &rest.Config{},
timeout: time.Second,
},
apiService: &apiregistrationv1.APIService{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: apiregistrationv1.APIServiceSpec{
Service: &apiregistrationv1.ServiceReference{
Name: "karmada-demo-service",
Namespace: "test",
},
Version: "v1beta1",
},
},
client: fakeAggregator.NewSimpleClientset(),
prep: func(client aggregator.Interface, _ *apiregistrationv1.APIService) error {
aggregateClientFromConfigBuilder = func(*rest.Config) (aggregator.Interface, error) {
return client, nil
}
return nil
},
wantErr: true,
},
{
name: "WaitForAPIService_WaitingForKarmadaAPIServiceAvailableStatus_KarmadaAPIServiceIsAvailable",
karmadaWriter: &KarmadaWaiter{
karmadaConfig: &rest.Config{},
timeout: time.Millisecond,
},
apiService: &apiregistrationv1.APIService{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: apiregistrationv1.APIServiceSpec{
Service: &apiregistrationv1.ServiceReference{
Name: "karmada-demo-service",
Namespace: "test",
},
Version: "v1beta1",
},
},
client: fakeAggregator.NewSimpleClientset(),
prep: func(client aggregator.Interface, apiService *apiregistrationv1.APIService) error {
apiServiceCreated, err := client.ApiregistrationV1().APIServices().Create(context.TODO(), apiService, metav1.CreateOptions{})
if err != nil {
return fmt.Errorf("faield to create api service %s, got err: %v", apiService.Name, err)
}
apiServiceCreated.Status = apiregistrationv1.APIServiceStatus{
Conditions: []apiregistrationv1.APIServiceCondition{
{
Type: apiregistrationv1.Available,
Status: apiregistrationv1.ConditionTrue,
},
},
}
if _, err = client.ApiregistrationV1().APIServices().Update(context.TODO(), apiServiceCreated, metav1.UpdateOptions{}); err != nil {
return fmt.Errorf("failed to update api service with available status, got err: %v", err)
}
aggregateClientFromConfigBuilder = func(*rest.Config) (aggregator.Interface, error) {
return client, nil
}
return nil
},
wantErr: false,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if err := test.prep(test.client, test.apiService); err != nil {
t.Errorf("failed to prep waiting for Karmada API Service, got err: %v", err)
}
err := test.karmadaWriter.WaitForAPIService(name)
if err == nil && test.wantErr {
t.Errorf("expected an error, but got none")
}
if err != nil && !test.wantErr {
t.Errorf("unexpected error, got: %v", err)
}
})
}
}
func TestWaitForPods(t *testing.T) {
name, namespace := "karmada-demo-apiserver", "test"
karmadaAPIServerLabels := labels.Set{"karmada-app": constants.KarmadaAPIServer}
var replicas int32 = 2
tests := []struct {
name string
karmadaWriter *KarmadaWaiter
prep func(client clientset.Interface) error
wantErr bool
}{
{
name: "WaitForPods_WaitingForAllKarmadaAPIServerPods_Timeout",
karmadaWriter: &KarmadaWaiter{
karmadaConfig: &rest.Config{},
client: fakeclientset.NewSimpleClientset(),
timeout: time.Second,
},
prep: func(client clientset.Interface) error {
_, err := CreatePods(client, namespace, name, replicas, karmadaAPIServerLabels, false)
if err != nil {
return fmt.Errorf("failed to create pods, got err: %v", err)
}
return nil
},
wantErr: true,
},
{
name: "WaitForPods_WaitingForAllKarmadaAPIServerPods_AllAreUpAndRunning",
karmadaWriter: &KarmadaWaiter{
karmadaConfig: &rest.Config{},
client: fakeclientset.NewSimpleClientset(),
timeout: time.Second * 2,
},
prep: func(client clientset.Interface) error {
pods, err := CreatePods(client, namespace, name, replicas, karmadaAPIServerLabels, false)
if err != nil {
return fmt.Errorf("failed to create pods, got err: %v", err)
}
time.AfterFunc(time.Second, func() {
for _, pod := range pods {
if err := UpdatePodStatus(client, pod); err != nil {
fmt.Printf("failed to update pod status, got err: %v", err)
return
}
}
})
return nil
},
wantErr: false,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if err := test.prep(test.karmadaWriter.client); err != nil {
t.Errorf("failed to prep before waiting for all Karmada APIServer pods , got err: %v", err)
}
err := test.karmadaWriter.WaitForPods(karmadaAPIServerLabels.String(), namespace)
if err == nil && test.wantErr {
t.Errorf("expected an error, but got none")
}
if err != nil && !test.wantErr {
t.Errorf("unexpected error, got: %v", err)
}
})
}
}
func TestWaitForSomePods(t *testing.T) {
name, namespace := "karmada-demo-apiserver", "test"
karmadaAPIServerLabels := labels.Set{"karmada-app": constants.KarmadaAPIServer}
var replicas int32 = 2
tests := []struct {
name string
karmadaWriter *KarmadaWaiter
prep func(client clientset.Interface) error
wantErr bool
}{
{
name: "WaitForSomePods_WaitingForSomeKarmadaAPIServerPods_Timeout",
karmadaWriter: &KarmadaWaiter{
karmadaConfig: &rest.Config{},
client: fakeclientset.NewSimpleClientset(),
timeout: time.Second,
},
prep: func(client clientset.Interface) error {
_, err := CreatePods(client, namespace, name, replicas, karmadaAPIServerLabels, false)
if err != nil {
return fmt.Errorf("failed to create pods, got err: %v", err)
}
return nil
},
wantErr: true,
},
{
name: "WaitForSomePods_WaitingForSomeKarmadaAPIServerPods_SomeAreUpAndRunning",
karmadaWriter: &KarmadaWaiter{
karmadaConfig: &rest.Config{},
client: fakeclientset.NewSimpleClientset(),
timeout: time.Millisecond,
},
prep: func(client clientset.Interface) error {
pods, err := CreatePods(client, namespace, name, replicas, karmadaAPIServerLabels, false)
if err != nil {
return fmt.Errorf("failed to create pods, got err: %v", err)
}
for _, pod := range pods[:1] {
if err := UpdatePodStatus(client, pod); err != nil {
return fmt.Errorf("failed to update pod status, got err: %v", err)
}
}
return nil
},
wantErr: false,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if err := test.prep(test.karmadaWriter.client); err != nil {
t.Errorf("failed to prep before waiting for some Karmada APIServer pods , got err: %v", err)
}
err := test.karmadaWriter.WaitForSomePods(karmadaAPIServerLabels.String(), namespace, 1)
if err == nil && test.wantErr {
t.Errorf("expected an error, but got none")
}
if err != nil && !test.wantErr {
t.Errorf("unexpected error, got: %v", err)
}
})
}
}
func TestTryRunCommand(t *testing.T) {
tests := []struct {
name string
failureThreshold int
targetFunc func() error
prep func() error
wantErr bool
}{
{
name: "TryRunCommand_HitTheFailureThreshold_CommandTimedOut",
failureThreshold: 2,
targetFunc: func() error {
return errors.New("unexpected error")
},
prep: func() error {
initialBackoffDuration = time.Millisecond
return nil
},
wantErr: true,
},
{
name: "TryRunCommand_BelowFailureThreshold_CommandRunSuccessfully",
failureThreshold: 2,
targetFunc: func() error { return nil },
prep: func() error {
initialBackoffDuration = time.Millisecond
return nil
},
wantErr: false,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if err := test.prep(); err != nil {
t.Errorf("failed to prep before trying to running command, got err: %v", err)
}
err := TryRunCommand(test.targetFunc, test.failureThreshold)
if err == nil && test.wantErr {
t.Errorf("expected an error, but got none")
}
if err != nil && !test.wantErr {
t.Errorf("unexpected error, got: %v", err)
}
})
}
}
func TestIsPodRunning(t *testing.T) {
tests := []struct {
name string
pod *corev1.Pod
want bool
}{
{
name: "IsPodRunning_PodInPendingState_PodIsNotRunningYet",
pod: &corev1.Pod{
Status: corev1.PodStatus{
Phase: corev1.PodPending,
},
},
want: false,
},
{
name: "IsPodRunning_WithDeletionTimestamp_PodIsNotRunningYet",
pod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
DeletionTimestamp: &metav1.Time{Time: time.Now()},
},
Status: corev1.PodStatus{
Phase: corev1.PodRunning,
},
},
want: false,
},
{
name: "IsPodRunning_PodReadyConditionReadinessIsFalse_PodIsNotRunningYet",
pod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
DeletionTimestamp: nil,
},
Status: corev1.PodStatus{
Phase: corev1.PodRunning,
Conditions: []corev1.PodCondition{
{
Type: corev1.PodReady,
Status: corev1.ConditionFalse,
},
},
},
},
want: false,
},
{
name: "IsPodRunning_PodSatisfyAllRunningConditions_PodIsAlreadyRunning",
pod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
DeletionTimestamp: nil,
},
Status: corev1.PodStatus{
Phase: corev1.PodRunning,
Conditions: []corev1.PodCondition{
{
Type: corev1.PodReady,
Status: corev1.ConditionTrue,
},
},
},
},
want: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if got := isPodRunning(*test.pod); got != test.want {
t.Errorf("expected pod running status %t, but got %t", test.want, got)
}
})
}
}

View File

@ -0,0 +1,92 @@
/*
Copyright 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.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/discovery"
fakediscovery "k8s.io/client-go/discovery/fake"
"k8s.io/client-go/testing"
clientset "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
apiregistrationv1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1"
fakeapiregistrationv1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake"
apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1"
fakeapiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake"
)
// NewSimpleClientset returns a clientset that will respond with the provided objects.
// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
// without applying any validations and/or defaults. It shouldn't be considered a replacement
// for a real clientset and is mostly useful in simple unit tests.
func NewSimpleClientset(objects ...runtime.Object) *Clientset {
o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())
for _, obj := range objects {
if err := o.Add(obj); err != nil {
panic(err)
}
}
cs := &Clientset{tracker: o}
cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake}
cs.AddReactor("*", "*", testing.ObjectReaction(o))
cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
gvr := action.GetResource()
ns := action.GetNamespace()
watch, err := o.Watch(gvr, ns)
if err != nil {
return false, nil, err
}
return true, watch, nil
})
return cs
}
// Clientset implements clientset.Interface. Meant to be embedded into a
// struct to get a default implementation. This makes faking out just the method
// you want to test easier.
type Clientset struct {
testing.Fake
discovery *fakediscovery.FakeDiscovery
tracker testing.ObjectTracker
}
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
return c.discovery
}
func (c *Clientset) Tracker() testing.ObjectTracker {
return c.tracker
}
var (
_ clientset.Interface = &Clientset{}
_ testing.FakeClient = &Clientset{}
)
// ApiregistrationV1 retrieves the ApiregistrationV1Client
func (c *Clientset) ApiregistrationV1() apiregistrationv1.ApiregistrationV1Interface {
return &fakeapiregistrationv1.FakeApiregistrationV1{Fake: &c.Fake}
}
// ApiregistrationV1beta1 retrieves the ApiregistrationV1beta1Client
func (c *Clientset) ApiregistrationV1beta1() apiregistrationv1beta1.ApiregistrationV1beta1Interface {
return &fakeapiregistrationv1beta1.FakeApiregistrationV1beta1{Fake: &c.Fake}
}

View File

@ -0,0 +1,20 @@
/*
Copyright 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.
*/
// Code generated by client-gen. DO NOT EDIT.
// This package has the automatically generated fake clientset.
package fake

View File

@ -0,0 +1,58 @@
/*
Copyright 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.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
schema "k8s.io/apimachinery/pkg/runtime/schema"
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1"
)
var scheme = runtime.NewScheme()
var codecs = serializer.NewCodecFactory(scheme)
var localSchemeBuilder = runtime.SchemeBuilder{
apiregistrationv1.AddToScheme,
apiregistrationv1beta1.AddToScheme,
}
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
// of clientsets, like in:
//
// import (
// "k8s.io/client-go/kubernetes"
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
// )
//
// kclientset, _ := kubernetes.NewForConfig(c)
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
//
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
// correctly.
var AddToScheme = localSchemeBuilder.AddToScheme
func init() {
v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"})
utilruntime.Must(AddToScheme(scheme))
}

View File

@ -0,0 +1,20 @@
/*
Copyright 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.
*/
// Code generated by client-gen. DO NOT EDIT.
// Package fake has the automatically generated clients.
package fake

View File

@ -0,0 +1,40 @@
/*
Copyright 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.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
rest "k8s.io/client-go/rest"
testing "k8s.io/client-go/testing"
v1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1"
)
type FakeApiregistrationV1 struct {
*testing.Fake
}
func (c *FakeApiregistrationV1) APIServices() v1.APIServiceInterface {
return &FakeAPIServices{c}
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *FakeApiregistrationV1) RESTClient() rest.Interface {
var ret *rest.RESTClient
return ret
}

View File

@ -0,0 +1,132 @@
/*
Copyright 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.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
"context"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
v1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
)
// FakeAPIServices implements APIServiceInterface
type FakeAPIServices struct {
Fake *FakeApiregistrationV1
}
var apiservicesResource = v1.SchemeGroupVersion.WithResource("apiservices")
var apiservicesKind = v1.SchemeGroupVersion.WithKind("APIService")
// Get takes name of the aPIService, and returns the corresponding aPIService object, and an error if there is any.
func (c *FakeAPIServices) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.APIService, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootGetAction(apiservicesResource, name), &v1.APIService{})
if obj == nil {
return nil, err
}
return obj.(*v1.APIService), err
}
// List takes label and field selectors, and returns the list of APIServices that match those selectors.
func (c *FakeAPIServices) List(ctx context.Context, opts metav1.ListOptions) (result *v1.APIServiceList, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootListAction(apiservicesResource, apiservicesKind, opts), &v1.APIServiceList{})
if obj == nil {
return nil, err
}
label, _, _ := testing.ExtractFromListOptions(opts)
if label == nil {
label = labels.Everything()
}
list := &v1.APIServiceList{ListMeta: obj.(*v1.APIServiceList).ListMeta}
for _, item := range obj.(*v1.APIServiceList).Items {
if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item)
}
}
return list, err
}
// Watch returns a watch.Interface that watches the requested aPIServices.
func (c *FakeAPIServices) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(testing.NewRootWatchAction(apiservicesResource, opts))
}
// Create takes the representation of a aPIService and creates it. Returns the server's representation of the aPIService, and an error, if there is any.
func (c *FakeAPIServices) Create(ctx context.Context, aPIService *v1.APIService, opts metav1.CreateOptions) (result *v1.APIService, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootCreateAction(apiservicesResource, aPIService), &v1.APIService{})
if obj == nil {
return nil, err
}
return obj.(*v1.APIService), err
}
// Update takes the representation of a aPIService and updates it. Returns the server's representation of the aPIService, and an error, if there is any.
func (c *FakeAPIServices) Update(ctx context.Context, aPIService *v1.APIService, opts metav1.UpdateOptions) (result *v1.APIService, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootUpdateAction(apiservicesResource, aPIService), &v1.APIService{})
if obj == nil {
return nil, err
}
return obj.(*v1.APIService), err
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeAPIServices) UpdateStatus(ctx context.Context, aPIService *v1.APIService, opts metav1.UpdateOptions) (*v1.APIService, error) {
obj, err := c.Fake.
Invokes(testing.NewRootUpdateSubresourceAction(apiservicesResource, "status", aPIService), &v1.APIService{})
if obj == nil {
return nil, err
}
return obj.(*v1.APIService), err
}
// Delete takes name of the aPIService and deletes it. Returns an error if one occurs.
func (c *FakeAPIServices) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewRootDeleteActionWithOptions(apiservicesResource, name, opts), &v1.APIService{})
return err
}
// DeleteCollection deletes a collection of objects.
func (c *FakeAPIServices) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
action := testing.NewRootDeleteCollectionAction(apiservicesResource, listOpts)
_, err := c.Fake.Invokes(action, &v1.APIServiceList{})
return err
}
// Patch applies the patch and returns the patched aPIService.
func (c *FakeAPIServices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.APIService, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootPatchSubresourceAction(apiservicesResource, name, pt, data, subresources...), &v1.APIService{})
if obj == nil {
return nil, err
}
return obj.(*v1.APIService), err
}

View File

@ -0,0 +1,20 @@
/*
Copyright 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.
*/
// Code generated by client-gen. DO NOT EDIT.
// Package fake has the automatically generated clients.
package fake

View File

@ -0,0 +1,40 @@
/*
Copyright 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.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
rest "k8s.io/client-go/rest"
testing "k8s.io/client-go/testing"
v1beta1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1"
)
type FakeApiregistrationV1beta1 struct {
*testing.Fake
}
func (c *FakeApiregistrationV1beta1) APIServices() v1beta1.APIServiceInterface {
return &FakeAPIServices{c}
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *FakeApiregistrationV1beta1) RESTClient() rest.Interface {
var ret *rest.RESTClient
return ret
}

View File

@ -0,0 +1,132 @@
/*
Copyright 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.
*/
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
"context"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
v1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1"
)
// FakeAPIServices implements APIServiceInterface
type FakeAPIServices struct {
Fake *FakeApiregistrationV1beta1
}
var apiservicesResource = v1beta1.SchemeGroupVersion.WithResource("apiservices")
var apiservicesKind = v1beta1.SchemeGroupVersion.WithKind("APIService")
// Get takes name of the aPIService, and returns the corresponding aPIService object, and an error if there is any.
func (c *FakeAPIServices) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.APIService, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootGetAction(apiservicesResource, name), &v1beta1.APIService{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.APIService), err
}
// List takes label and field selectors, and returns the list of APIServices that match those selectors.
func (c *FakeAPIServices) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.APIServiceList, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootListAction(apiservicesResource, apiservicesKind, opts), &v1beta1.APIServiceList{})
if obj == nil {
return nil, err
}
label, _, _ := testing.ExtractFromListOptions(opts)
if label == nil {
label = labels.Everything()
}
list := &v1beta1.APIServiceList{ListMeta: obj.(*v1beta1.APIServiceList).ListMeta}
for _, item := range obj.(*v1beta1.APIServiceList).Items {
if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item)
}
}
return list, err
}
// Watch returns a watch.Interface that watches the requested aPIServices.
func (c *FakeAPIServices) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(testing.NewRootWatchAction(apiservicesResource, opts))
}
// Create takes the representation of a aPIService and creates it. Returns the server's representation of the aPIService, and an error, if there is any.
func (c *FakeAPIServices) Create(ctx context.Context, aPIService *v1beta1.APIService, opts v1.CreateOptions) (result *v1beta1.APIService, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootCreateAction(apiservicesResource, aPIService), &v1beta1.APIService{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.APIService), err
}
// Update takes the representation of a aPIService and updates it. Returns the server's representation of the aPIService, and an error, if there is any.
func (c *FakeAPIServices) Update(ctx context.Context, aPIService *v1beta1.APIService, opts v1.UpdateOptions) (result *v1beta1.APIService, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootUpdateAction(apiservicesResource, aPIService), &v1beta1.APIService{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.APIService), err
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeAPIServices) UpdateStatus(ctx context.Context, aPIService *v1beta1.APIService, opts v1.UpdateOptions) (*v1beta1.APIService, error) {
obj, err := c.Fake.
Invokes(testing.NewRootUpdateSubresourceAction(apiservicesResource, "status", aPIService), &v1beta1.APIService{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.APIService), err
}
// Delete takes name of the aPIService and deletes it. Returns an error if one occurs.
func (c *FakeAPIServices) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewRootDeleteActionWithOptions(apiservicesResource, name, opts), &v1beta1.APIService{})
return err
}
// DeleteCollection deletes a collection of objects.
func (c *FakeAPIServices) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
action := testing.NewRootDeleteCollectionAction(apiservicesResource, listOpts)
_, err := c.Fake.Invokes(action, &v1beta1.APIServiceList{})
return err
}
// Patch applies the patch and returns the patched aPIService.
func (c *FakeAPIServices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.APIService, err error) {
obj, err := c.Fake.
Invokes(testing.NewRootPatchSubresourceAction(apiservicesResource, name, pt, data, subresources...), &v1beta1.APIService{})
if obj == nil {
return nil, err
}
return obj.(*v1beta1.APIService), err
}

3
vendor/modules.txt vendored
View File

@ -1629,9 +1629,12 @@ k8s.io/kube-aggregator/pkg/apis/apiregistration/validation
k8s.io/kube-aggregator/pkg/apiserver
k8s.io/kube-aggregator/pkg/apiserver/scheme
k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset
k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/fake
k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme
k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1
k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake
k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1
k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake
k8s.io/kube-aggregator/pkg/client/informers/externalversions
k8s.io/kube-aggregator/pkg/client/informers/externalversions/apiregistration
k8s.io/kube-aggregator/pkg/client/informers/externalversions/apiregistration/v1