Skip to content

Commit

Permalink
add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Daisy Guo committed Oct 22, 2020
1 parent 06d5822 commit 9239aa6
Show file tree
Hide file tree
Showing 8 changed files with 191 additions and 20 deletions.
2 changes: 1 addition & 1 deletion pkg/kn/commands/source/container/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
func NewContainerSourceCommand(p *commands.KnParams) *cobra.Command {
containerSourceCmd := &cobra.Command{
Use: "container COMMAND",
Short: "Manage Kubernetes container sources",
Short: "Manage container sources",
}
containerSourceCmd.AddCommand(NewContainerCreateCommand(p))
containerSourceCmd.AddCommand(NewContainerDeleteCommand(p))
Expand Down
92 changes: 92 additions & 0 deletions pkg/kn/commands/source/container/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,95 @@ limitations under the License.
*/

package container

import (
"bytes"

corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/tools/clientcmd"
v1alpha2 "knative.dev/eventing/pkg/apis/sources/v1alpha2"
duckv1 "knative.dev/pkg/apis/duck/v1"

kndynamic "knative.dev/client/pkg/dynamic"
clientv1alpha2 "knative.dev/client/pkg/sources/v1alpha2"

"knative.dev/client/pkg/kn/commands"
)

var blankConfig clientcmd.ClientConfig

// TODO: Remove that blankConfig hack for tests in favor of overwriting GetConfig()
func init() {
var err error
blankConfig, err = clientcmd.NewClientConfigFromBytes([]byte(`kind: Config
version: v1
users:
- name: u
clusters:
- name: c
cluster:
server: example.com
contexts:
- name: x
context:
user: u
cluster: c
current-context: x
`))
if err != nil {
panic(err)
}
}

func executeContainerSourceCommand(containerSourceClient clientv1alpha2.KnContainerSourcesClient, dynamicClient kndynamic.KnDynamicClient, args ...string) (string, error) {
knParams := &commands.KnParams{}
knParams.ClientConfig = blankConfig

output := new(bytes.Buffer)
knParams.Output = output
knParams.NewDynamicClient = func(namespace string) (kndynamic.KnDynamicClient, error) {
return dynamicClient, nil
}

cmd := NewContainerSourceCommand(knParams)
cmd.SetArgs(args)
cmd.SetOutput(output)

containerSourceClientFactory = func(config clientcmd.ClientConfig, namespace string) (clientv1alpha2.KnContainerSourcesClient, error) {
return containerSourceClient, nil
}
defer cleanupContainerServerMockClient()

err := cmd.Execute()

return output.String(), err
}

func cleanupContainerServerMockClient() {
containerSourceClientFactory = nil
}

func createContainerSource(name, image string, sink duckv1.Destination) *v1alpha2.ContainerSource {
return clientv1alpha2.NewContainerSourceBuilder(name).
PodSpec(corev1.PodSpec{
Containers: []corev1.Container{{
Image: image,
Resources: corev1.ResourceRequirements{
Limits: corev1.ResourceList{},
Requests: corev1.ResourceList{},
},
}}}).
Sink(sink).
Build()
}

func createSinkv1(serviceName, namespace string) duckv1.Destination {
return duckv1.Destination{
Ref: &duckv1.KReference{
Kind: "Service",
Name: serviceName,
APIVersion: "serving.knative.dev/v1",
Namespace: namespace,
},
}
}
15 changes: 5 additions & 10 deletions pkg/kn/commands/source/container/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ import (
"knative.dev/client/pkg/kn/commands/flags"
knflags "knative.dev/client/pkg/kn/flags"

corev1 "k8s.io/api/core/v1"
"knative.dev/client/pkg/kn/commands"
"knative.dev/client/pkg/sources/v1alpha2"
eventingv2 "knative.dev/eventing/pkg/apis/sources/v1alpha2"
)

// NewContainerCreateCommand for creating source
Expand Down Expand Up @@ -59,29 +59,24 @@ func NewContainerCreateCommand(p *commands.KnParams) *cobra.Command {
if err != nil {
return err
}

objectRef, err := sinkFlags.ResolveSink(dynamicClient, namespace)
if err != nil {
return fmt.Errorf(
"cannot create ContainerSource '%s' in namespace '%s' "+
"because: %s", name, namespace, err)
}

var containerSource *eventingv2.ContainerSource
podSpec := containerSource.Spec.Template.Spec

err = podFlags.ResolvePodSpec(cmd, &podSpec)
podSpec := &corev1.PodSpec{Containers: []corev1.Container{{}}}
err = podFlags.ResolvePodSpec(podSpec, cmd)
if err != nil {
return fmt.Errorf(
"cannot create ContainerSource '%s' in namespace '%s' "+
"because: %s", name, namespace, err)
}

b := v1alpha2.NewContainerSourceBuilder(name).
PodSpec(podSpec).
Sink(*objectRef)

b := v1alpha2.NewContainerSourceBuilder(name).Sink(*objectRef).PodSpec(*podSpec)
err = srcClient.CreateContainerSource(b.Build())

if err != nil {
return fmt.Errorf(
"cannot create ContainerSource '%s' in namespace '%s' "+
Expand Down
45 changes: 45 additions & 0 deletions pkg/kn/commands/source/container/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,48 @@ limitations under the License.
*/

package container

import (
"testing"

"gotest.tools/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
servingv1 "knative.dev/serving/pkg/apis/serving/v1"

dynamicfake "knative.dev/client/pkg/dynamic/fake"
"knative.dev/client/pkg/sources/v1alpha2"
"knative.dev/client/pkg/util"
)

func TestCreateContainerSource(t *testing.T) {
testsvc := &servingv1.Service{
TypeMeta: metav1.TypeMeta{Kind: "Service", APIVersion: "serving.knative.dev/v1"},
ObjectMeta: metav1.ObjectMeta{Name: "testsvc", Namespace: "default"},
}
dynamicClient := dynamicfake.CreateFakeKnDynamicClient("default", testsvc)
containerClient := v1alpha2.NewMockKnContainerSourceClient(t)

containerRecorder := containerClient.Recorder()
containerRecorder.CreateContainerSource(createContainerSource("testsource", "docker.io/test/testimg", createSinkv1("testsvc", "default")), nil)

out, err := executeContainerSourceCommand(containerClient, dynamicClient, "create", "testsource", "--image", "docker.io/test/testimg", "--sink", "ksvc:testsvc")
assert.NilError(t, err, "Container source should be created")
assert.Assert(t, util.ContainsAll(out, "created", "default", "testsource"))

containerRecorder.Validate()
}

func TestSinkNotFoundError(t *testing.T) {
dynamicClient := dynamicfake.CreateFakeKnDynamicClient("default")
containerClient := v1alpha2.NewMockKnContainerSourceClient(t)
errorMsg := "cannot create ContainerSource 'testsource' in namespace 'default' because: services.serving.knative.dev \"testsvc\" not found"
out, err := executeContainerSourceCommand(containerClient, dynamicClient, "create", "testsource", "--image", "docker.io/test/testimg", "--sink", "ksvc:testsvc")
assert.Error(t, err, errorMsg)
assert.Assert(t, util.ContainsAll(out, errorMsg, "Usage"))
}

func TestNoSinkError(t *testing.T) {
containerClient := v1alpha2.NewMockKnContainerSourceClient(t)
_, err := executeContainerSourceCommand(containerClient, nil, "create", "testsource", "--image", "docker.io/test/testimg")
assert.ErrorContains(t, err, "required flag(s)", "sink", "not set")
}
38 changes: 38 additions & 0 deletions pkg/kn/commands/source/container/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,41 @@ limitations under the License.
*/

package container

import (
"errors"
"testing"

"gotest.tools/assert"

"knative.dev/client/pkg/sources/v1alpha2"
"knative.dev/client/pkg/util"
)

func TestContainerSourceDelete(t *testing.T) {

containerClient := v1alpha2.NewMockKnContainerSourceClient(t, "testns")
containerRecorder := containerClient.Recorder()

containerRecorder.DeleteContainerSource("testsource", nil)

out, err := executeContainerSourceCommand(containerClient, nil, "delete", "testsource")
assert.NilError(t, err)
assert.Assert(t, util.ContainsAll(out, "deleted", "default", "testsource"))

containerRecorder.Validate()
}

func TestDeleteWithError(t *testing.T) {

containerClient := v1alpha2.NewMockKnContainerSourceClient(t, "mynamespace")
containerRecorder := containerClient.Recorder()

containerRecorder.DeleteContainerSource("testsource", errors.New("container source testsource not found"))

out, err := executeContainerSourceCommand(containerClient, nil, "delete", "testsource")
assert.ErrorContains(t, err, "testsource")
assert.Assert(t, util.ContainsAll(out, "container", "source", "testsource", "not found"))

containerRecorder.Validate()
}
12 changes: 7 additions & 5 deletions pkg/sources/v1alpha2/container_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.
package v1alpha2

import (
"context"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -68,7 +70,7 @@ func newKnContainerSourcesClient(client clientv1alpha2.ContainerSourceInterface,

//GetContainerSource returns containerSrc object if present
func (c *containerSourcesClient) GetContainerSource(name string) (*v1alpha2.ContainerSource, error) {
containerSrc, err := c.client.Get(name, metav1.GetOptions{})
containerSrc, err := c.client.Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
return nil, knerrors.GetError(err)
}
Expand All @@ -78,7 +80,7 @@ func (c *containerSourcesClient) GetContainerSource(name string) (*v1alpha2.Cont

//CreateContainerSource is used to create an instance of ContainerSource
func (c *containerSourcesClient) CreateContainerSource(containerSrc *v1alpha2.ContainerSource) error {
_, err := c.client.Create(containerSrc)
_, err := c.client.Create(context.TODO(), containerSrc, metav1.CreateOptions{})
if err != nil {
return knerrors.GetError(err)
}
Expand All @@ -88,7 +90,7 @@ func (c *containerSourcesClient) CreateContainerSource(containerSrc *v1alpha2.Co

//UpdateContainerSource is used to update an instance of ContainerSource
func (c *containerSourcesClient) UpdateContainerSource(containerSrc *v1alpha2.ContainerSource) error {
_, err := c.client.Update(containerSrc)
_, err := c.client.Update(context.TODO(), containerSrc, metav1.UpdateOptions{})
if err != nil {
return knerrors.GetError(err)
}
Expand All @@ -98,7 +100,7 @@ func (c *containerSourcesClient) UpdateContainerSource(containerSrc *v1alpha2.Co

//DeleteContainerSource is used to create an instance of ContainerSource
func (c *containerSourcesClient) DeleteContainerSource(name string) error {
err := c.client.Delete(name, &metav1.DeleteOptions{})
err := c.client.Delete(context.TODO(), name, metav1.DeleteOptions{})
return err
}

Expand All @@ -109,7 +111,7 @@ func (c *containerSourcesClient) Namespace() string {

// ListContainerSource returns the available container sources
func (c *containerSourcesClient) ListContainerSources() (*v1alpha2.ContainerSourceList, error) {
sourceList, err := c.client.List(metav1.ListOptions{})
sourceList, err := c.client.List(context.TODO(), metav1.ListOptions{})
if err != nil {
return nil, knerrors.GetError(err)
}
Expand Down
5 changes: 3 additions & 2 deletions pkg/sources/v1alpha2/container_client_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ func NewMockKnContainerSourceClient(t *testing.T, ns ...string) *MockKnContainer
namespace = ns[0]
}
return &MockKnContainerSourceClient{
t: t,
recorder: &ConainterSourceRecorder{mock.NewRecorder(t, namespace)},
t: t,
recorder: &ConainterSourceRecorder{mock.NewRecorder(t, namespace)},
namespace: namespace,
}
}

Expand Down
2 changes: 0 additions & 2 deletions pkg/sources/v1alpha2/container_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ import (
duckv1 "knative.dev/pkg/apis/duck/v1"
)

var testContainerSourceNamespace = "test-cs"

func setupFakeContainerSourcesClient() (fakeSvr fake.FakeSourcesV1alpha2, client KnContainerSourcesClient) {
fakeE := fake.FakeSourcesV1alpha2{Fake: &clienttesting.Fake{}}
cli := NewKnSourcesClient(&fakeE, "test-ns").ContainerSourcesClient()
Expand Down

0 comments on commit 9239aa6

Please sign in to comment.