Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the possibility to set return values for the FakeDiscovery implementation #51130

Merged
merged 2 commits into from
Sep 3, 2017

Conversation

luxas
Copy link
Member

@luxas luxas commented Aug 22, 2017

What this PR does / why we need it:

As an user of the fake clientset (with the fake discovery), I want to be able to set the fake server's version on demand like this for example:

func TestFakingServerVersion(t *testing.T) {
	client := fakeclientset.NewSimpleClientset()
	fakeDiscovery, ok := client.Discovery().(*fakediscovery.FakeDiscovery)
	if !ok {
		t.Fatalf("couldn't convert Discovery() to *FakeDiscovery")
	}

	testGitCommit := "v1.0.0"
	fakeDiscovery.FakedServerVersion = &version.Info{
		GitCommit: testGitCommit,
	}

	sv, err := client.Discovery().ServerVersion()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if sv.GitCommit != testGitCommit {
		t.Fatalf("unexpected faked discovery return value: %q", sv.GitCommit)
	}
}

This PR makes that possible, in wait for a more sophisticated FakeDiscovery implementation generally.

Which issue this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close that issue when PR gets merged): fixes #

Special notes for your reviewer:

Release note:

NONE

@kubernetes/sig-api-machinery-pr-reviews

@luxas luxas assigned ncdc and sttts Aug 22, 2017
@k8s-ci-robot k8s-ci-robot added sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Aug 22, 2017
@k8s-github-robot k8s-github-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. release-note-none Denotes a PR that doesn't merit a release note. labels Aug 22, 2017
@@ -67,7 +80,11 @@ func (c *FakeDiscovery) ServerPreferredNamespacedResources() ([]*metav1.APIResou
}

func (c *FakeDiscovery) ServerGroups() (*metav1.APIGroupList, error) {
return nil, nil
return c.serverGroups, nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be building the layer the wrong location. It seems like you want a simple skin on the *testing.Fake which setups up the "proper" handling for the various Invokes calls by the PrependReactor methods. That way you can use the normal check of Actions if you need to.

I'm fine with making it easier to set those, but I'd like to see these calls making their proper remote calls. That may require refactoring the DiscoveryClient itself to separate the accessors from the helpers, but I think that is more productive than doing it like this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@luxas without looking into details, what @deads2k suggests was what you tried?

@caesarxuchao
Copy link
Member

/assign @caesarxuchao

@luxas
Copy link
Member Author

luxas commented Aug 24, 2017

@caesarxuchao @sttts @deads2k Current proposal:
Usage (passing):

/*
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 foo

import (
	"testing"

	fakediscovery "k8s.io/client-go/discovery/fake"
	fakeclientset "k8s.io/client-go/kubernetes/fake"
	apimachineryversion "k8s.io/apimachinery/pkg/version"
)

func TestSettingFakeServerVersion(t *testing.T) {
	client := fakeclientset.NewSimpleClientset()
	fakeDiscovery, ok := client.Discovery().(*fakediscovery.FakeDiscovery)
	if !ok {
		t.Fatalf("couldn't convert")
	}

	testGitCommit := "v2.0.0"
	fakeDiscovery.FakedServerVersion = &apimachineryversion.Info{
		GitCommit: testGitCommit,
	}
	sv, err := client.Discovery().ServerVersion()
	if err != nil {
		t.Fatalf("unexpected err: %v", err)
	}
	if sv.GitCommit != testGitCommit {
		t.Fatalf("unexpected gitcommit: %q, %v", sv.GitCommit, *sv)
	}
}

Changes:

diff --git a/staging/src/k8s.io/client-go/discovery/fake/discovery.go b/staging/src/k8s.io/client-go/discovery/fake/discovery.go
index 02e77cfe71..aae63da3e3 100644
--- a/staging/src/k8s.io/client-go/discovery/fake/discovery.go
+++ b/staging/src/k8s.io/client-go/discovery/fake/discovery.go
@@ -33,6 +33,7 @@ import (
 
 type FakeDiscovery struct {
        *testing.Fake
+       FakedServerVersion *version.Info
 }
 
 func (c *FakeDiscovery) ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error) {
@@ -76,6 +77,11 @@ func (c *FakeDiscovery) ServerVersion() (*version.Info, error) {
        action.Resource = schema.GroupVersionResource{Resource: "version"}
 
        c.Invokes(action, nil)
+
+       if c.FakedServerVersion != nil {
+               return c.FakedServerVersion, nil
+       }
+
        versionInfo := kubeversion.Get()
        return &versionInfo, nil
 }
diff --git a/staging/src/k8s.io/client-go/kubernetes/fake/clientset_generated.go b/staging/src/k8s.io/client-go/kubernetes/fake/clientset_generated.go
index 5569e92b7d..22937ccecd 100644
--- a/staging/src/k8s.io/client-go/kubernetes/fake/clientset_generated.go
+++ b/staging/src/k8s.io/client-go/kubernetes/fake/clientset_generated.go
@@ -87,10 +87,9 @@ func NewSimpleClientset(objects ...runtime.Object) *Clientset {
 
        fakePtr := testing.Fake{}
        fakePtr.AddReactor("*", "*", testing.ObjectReaction(o))
-
        fakePtr.AddWatchReactor("*", testing.DefaultWatchReactor(watch.NewFake(), nil))
 
-       return &Clientset{fakePtr}
+       return &Clientset{fakePtr, &fakediscovery.FakeDiscovery{Fake: &fakePtr}}
 }
 
 // Clientset implements clientset.Interface. Meant to be embedded into a
@@ -98,10 +97,11 @@ func NewSimpleClientset(objects ...runtime.Object) *Clientset {
 // you want to test easier.
 type Clientset struct {
        testing.Fake
+       discovery *fakediscovery.FakeDiscovery
 }
 
 func (c *Clientset) Discovery() discovery.DiscoveryInterface {
-       return &fakediscovery.FakeDiscovery{Fake: &c.Fake}
+       return c.discovery
 }
 
 var _ clientset.Interface = &Clientset{}

WDYT? Can implement for the other methods as well...

@caesarxuchao
Copy link
Member

The apiserver fixture uses GroupVersionResource as keys, but our discovery API aren't mapping to resources. @luxas's proposal is making up non-existing resources to represent the discovery request, e.g., action.Resource = schema.GroupVersionResource{Resource: "version"}.

How do you plan to represent request sent to "/apis", "apis/extension", or "apis/extensions/v1beta1"?

discovery.DiscoveryInterface
SetServerGroups(*metav1.APIGroupList)
SetServerVersion(*version.Info)
SetRESTClient(restclient.Interface)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the rest client?

@luxas
Copy link
Member Author

luxas commented Aug 25, 2017

@deads2k @caesarxuchao @sttts PTAL at the latest version. WDYT?

fakePtr.AddWatchReactor("*", testing.DefaultWatchReactor(watch.NewFake(), nil))

return &Clientset{fakePtr}
return &Clientset{fakePtr, &fakediscovery.FakeDiscovery{Fake: &fakePtr}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this must go into the generator

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What generator are you talking about?

type FakeDiscovery struct {
*testing.Fake
FakedServerVersion *version.Info
FakedRESTClient restclient.Interface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't notice this one in the comment in your diff. Can we avoid it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before this; RESTClient() always returned nil. With this, the user can set this field if they want to make client.Discovery().RESTClient() for a faked clientset to work, but it will still default to nil.
WDYT?

@deads2k
Copy link
Contributor

deads2k commented Aug 25, 2017

One comment on a field that I think is unused right now, then @sttts comment and this lgtm.

@luxas luxas added this to the v1.8 milestone Aug 25, 2017
@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Aug 25, 2017
@caesarxuchao
Copy link
Member

lgtm

@caesarxuchao
Copy link
Member

Both @deads2k and @sttts 's comments are addressed. Adding the label.

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 25, 2017
@k8s-github-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: caesarxuchao, luxas
We suggest the following additional approver: lavalamp

Assign the PR to them by writing /assign @lavalamp in a comment when ready.

No associated issue. Update pull-request body to add a reference to an issue, or get approval with /approve no-issue

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these OWNERS Files:

You can indicate your approval by writing /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@k8s-github-robot k8s-github-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 25, 2017
@luxas
Copy link
Member Author

luxas commented Aug 25, 2017

@caesarxuchao just updated bazel as I noticed I didn't do that before.

@luxas luxas added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 25, 2017
@luxas
Copy link
Member Author

luxas commented Aug 25, 2017

I think this needs @smarterclayton's or @lavalamp's approval though.
Please look at this, should be pretty straightforward
(needed for --dry-run in #48899 to work correctly)

@k8s-github-robot k8s-github-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 27, 2017
@luxas
Copy link
Member Author

luxas commented Aug 27, 2017

Should hopefully fix small verification failure...

@luxas luxas added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 27, 2017
@luxas
Copy link
Member Author

luxas commented Aug 27, 2017

/retest

@caesarxuchao
Copy link
Member

/assign @lavalamp

for approval.

@caesarxuchao
Copy link
Member

/retest

1 similar comment
@caesarxuchao
Copy link
Member

/retest

@caesarxuchao
Copy link
Member

I'm going to manually approve this one. It's lgtm'ed long ago, I don't want it to slip the code freeze.

@caesarxuchao caesarxuchao added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Sep 1, 2017
@luxas
Copy link
Member Author

luxas commented Sep 1, 2017

/retest

Thank you @caesarxuchao, yeah, this is pretty trivial in any case so it's much more about review bandwidth than someone not wanting to approve this PR.

@luxas
Copy link
Member Author

luxas commented Sep 2, 2017 via email

@CaoShuFeng
Copy link
Contributor

/test pull-kubernetes-verify

@luxas
Copy link
Member Author

luxas commented Sep 2, 2017

/retest

1 similar comment
@luxas
Copy link
Member Author

luxas commented Sep 2, 2017

/retest

@k8s-ci-robot
Copy link
Contributor

@luxas: The following test failed, say /retest to rerun them all:

Test name Commit Details Rerun command
pull-kubernetes-e2e-kops-aws e1cff67 link /test pull-kubernetes-e2e-kops-aws

Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@k8s-github-robot
Copy link

Automatic merge from submit-queue (batch tested with PRs 51335, 51364, 51130, 48075, 50920)

@k8s-github-robot k8s-github-robot merged commit 94d9457 into kubernetes:master Sep 3, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note-none Denotes a PR that doesn't merit a release note. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants