Skip to content

Commit

Permalink
Add mock tests for the dynamic client
Browse files Browse the repository at this point in the history
  • Loading branch information
priyshar01 committed Aug 6, 2020
1 parent 980a6a9 commit ad1adea
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
| Fix exit code for `kn service delete` and `kn revision delete` failures
| https://github.com/knative/client/pull/971[#971]

| 🎁
| Add mock test client for dynamic client
| https://github.com/knative/client/pull/972[#972]
|===

## v0.16.0 (2020-07-14)
Expand Down
122 changes: 122 additions & 0 deletions pkg/dynamic/client_mock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Copyright © 2019 The Knative 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 dynamic

import (
"testing"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
"knative.dev/client/pkg/util/mock"
)

// MockKnDynamicClient is a combine of test object and recorder
type MockKnDynamicClient struct {
t *testing.T
recorder *ClientRecorder
namespace string
}

// NewMockKnDyanmicClient returns a new mock instance which you need to record for
func NewMockKnDyanmicClient(t *testing.T, ns ...string) *MockKnDynamicClient {
namespace := "default"
if len(ns) > 0 {
namespace = ns[0]
}
return &MockKnDynamicClient{
t: t,
recorder: &ClientRecorder{mock.NewRecorder(t, namespace)},
}
}

// Ensure that the interface is implemented
var _ KnDynamicClient = &MockKnDynamicClient{}

// ClientRecorder is recorder for eventing objects
type ClientRecorder struct {
r *mock.Recorder
}

// Recorder returns the recorder for registering API calls
func (c *MockKnDynamicClient) Recorder() *ClientRecorder {
return c.recorder
}

// Namespace of this client
func (c *MockKnDynamicClient) Namespace() string {
return c.recorder.r.Namespace()
}

// ListCRDs returns list of installed CRDs in the cluster and filters based on the given options
func (dr *ClientRecorder) ListCRDs(options interface{}, ulist *unstructured.UnstructuredList, err error) {
dr.r.Add("ListCRDs", []interface{}{options}, []interface{}{ulist, err})
}

// ListCRDs returns list of installed CRDs in the cluster and filters based on the given options
func (c *MockKnDynamicClient) ListCRDs(options metav1.ListOptions) (*unstructured.UnstructuredList, error) {
call := c.recorder.r.VerifyCall("ListCRDs", options)
return call.Result[0].(*unstructured.UnstructuredList), mock.ErrorOrNil(call.Result[1])
}

// ListSourcesTypes returns installed knative eventing sources CRDs
func (dr *ClientRecorder) ListSourcesTypes(ulist *unstructured.UnstructuredList, err error) {
dr.r.Add("ListSourcesTypes", []interface{}{}, []interface{}{ulist, err})
}

// ListSourcesTypes returns installed knative eventing sources CRDs
func (c *MockKnDynamicClient) ListSourcesTypes() (*unstructured.UnstructuredList, error) {
call := c.recorder.r.VerifyCall("ListSourcesTypes")
return call.Result[0].(*unstructured.UnstructuredList), mock.ErrorOrNil(call.Result[1])
}

// ListSources returns list of available sources objects
func (dr *ClientRecorder) ListSources(types interface{}, ulist *unstructured.UnstructuredList, err error) {
dr.r.Add("ListSources", []interface{}{types}, []interface{}{ulist, err})
}

// ListSources returns list of available sources objects
func (c *MockKnDynamicClient) ListSources(types ...WithType) (*unstructured.UnstructuredList, error) {
call := c.recorder.r.VerifyCall("ListSources")
return call.Result[0].(*unstructured.UnstructuredList), mock.ErrorOrNil(call.Result[1])
}

// RawClient creates a client
func (dr *ClientRecorder) RawClient(dynamicInterface dynamic.Interface) {
dr.r.Add("RawClient", []interface{}{}, []interface{}{dynamicInterface})
}

// RawClient creates a client
func (c *MockKnDynamicClient) RawClient() (dynamicInterface dynamic.Interface) {
call := c.recorder.r.VerifyCall("RawClient")
return call.Result[0].(dynamic.Interface)
}

// ListSourcesUsingGVKs returns list of available source objects using given list of GVKs
func (dr *ClientRecorder) ListSourcesUsingGVKs(gvks interface{}, types interface{}, ulist *unstructured.UnstructuredList, err error) {
dr.r.Add("ListSourcesUsingGVKs", []interface{}{gvks, types}, []interface{}{ulist, err})
}

// ListSourcesUsingGVKs returns list of available source objects using given list of GVKs
func (c *MockKnDynamicClient) ListSourcesUsingGVKs(gvks *[]schema.GroupVersionKind, types ...WithType) (*unstructured.UnstructuredList, error) {
call := c.recorder.r.VerifyCall("ListSourcesUsingGVKs")
return call.Result[0].(*unstructured.UnstructuredList), mock.ErrorOrNil(call.Result[1])
}

// Validate validates whether every recorded action has been called
func (dr *ClientRecorder) Validate() {
dr.r.CheckThatAllRecordedMethodsHaveBeenCalled()
}
45 changes: 45 additions & 0 deletions pkg/dynamic/client_mock_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright © 2019 The Knative 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 dynamic

import (
"testing"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic/fake"
"knative.dev/client/pkg/util/mock"
)

func TestMockKnDynamicClient(t *testing.T) {

client := NewMockKnDyanmicClient(t)

recorder := client.Recorder()

recorder.ListCRDs(mock.Any(), nil, nil)
recorder.ListSourcesTypes(nil, nil)
recorder.ListSources(mock.Any(), nil, nil)
recorder.RawClient(&fake.FakeDynamicClient{})
recorder.ListSourcesUsingGVKs(mock.Any(), mock.Any(), nil, nil)

client.ListCRDs(metav1.ListOptions{})
client.ListSourcesTypes()
client.ListSources(WithTypeFilter("blub"))
client.RawClient()
client.ListSourcesUsingGVKs(&[]schema.GroupVersionKind{}, WithTypeFilter("blub"))
// Validate
recorder.Validate()
}

0 comments on commit ad1adea

Please sign in to comment.