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

pod: add unit test for executor #602

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 25 additions & 7 deletions pkg/pod/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"

Expand All @@ -28,6 +29,12 @@ import (
"github.com/openshift-kni/eco-goinfra/pkg/msg"
)

// GetRestURL Function to use to get the Executor REST URL.
var GetRestURL = getRestExecutorURL

// NewSPDYExecutor Function to use for the pod remote executor.
var NewSPDYExecutor = remotecommand.NewSPDYExecutor

// Builder provides a struct for pod object from the cluster and a pod definition.
type Builder struct {
// Pod definition, used to create the pod object.
Expand Down Expand Up @@ -463,15 +470,14 @@ func (builder *Builder) WaitUntilCondition(condition corev1.PodConditionType, ti
})
}

// ExecCommand runs command in the pod and returns the buffer output.
func (builder *Builder) ExecCommand(command []string, containerName ...string) (bytes.Buffer, error) {
// getRestExecutorURL Gets a executor REST URL in the real cluster.
func getRestExecutorURL(builder *Builder, command []string, containerName ...string) (*url.URL, error) {
if valid, err := builder.validate(); !valid {
return bytes.Buffer{}, err
return &url.URL{}, err
}

var (
buffer bytes.Buffer
cName string
cName string
)

if len(containerName) > 0 {
Expand All @@ -498,10 +504,22 @@ func (builder *Builder) ExecCommand(command []string, containerName ...string) (
TTY: true,
}, scheme.ParameterCodec)

exec, err := remotecommand.NewSPDYExecutor(builder.apiClient.Config, "POST", req.URL())
return req.URL(), nil
}

// ExecCommand runs command in the pod and returns the buffer output.
func (builder *Builder) ExecCommand(command []string, containerName ...string) (bytes.Buffer, error) {
url, err := GetRestURL(builder, command, containerName...)
if err != nil {
return buffer, err
return bytes.Buffer{}, err
}

var buffer bytes.Buffer

exec, err := NewSPDYExecutor(builder.apiClient.Config, "POST", url)

if err != nil {
return bytes.Buffer{}, err
}

err = exec.StreamWithContext(context.TODO(), remotecommand.StreamOptions{
Expand Down
88 changes: 88 additions & 0 deletions pkg/pod/pod_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package pod

import (
"bytes"
"context"
"net/url"
"reflect"
"testing"
"time"

Expand All @@ -10,6 +14,8 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/runtime"
k8sfake "k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/remotecommand"
)

func buildValidContainterBuilder() *ContainerBuilder {
Expand Down Expand Up @@ -240,3 +246,85 @@ func getErrorString(err error) string {

return err.Error()
}

func TestBuilder_ExecCommand(t *testing.T) {
type args struct {
command []string
containerName []string
}

tests := []struct {
name string
args args
pod *corev1.Pod
want bytes.Buffer
wantErr bool
}{
{
name: "ok",
args: args{
command: []string{"ls"},
containerName: []string{"test"},
},
pod: generateTestPod("test1", "ns1", corev1.PodRunning, corev1.PodReady, false),
want: *bytes.NewBufferString("Command fake output"),
wantErr: false,
},
}
for _, testcase := range tests {
t.Run(testcase.name, func(t *testing.T) {
var runtimeObjects []runtime.Object
runtimeObjects = append(runtimeObjects, testcase.pod)
builder, err := buildPodTestBuilderWithFakeObjects(runtimeObjects, testcase.pod.Name, testcase.pod.Namespace)
assert.Nil(t, err)

NewSPDYExecutor = fakeNewSPDYExecutor
GetRestURL = getFakeRestURL
got, err := builder.ExecCommand(testcase.args.command, testcase.args.containerName...)

if (err != nil) != testcase.wantErr {
t.Errorf("Builder.ExecCommand() error = %v, wantErr %v", err, testcase.wantErr)

return
}

if !reflect.DeepEqual(got, testcase.want) {
t.Errorf("Builder.ExecCommand() = %v, want %v", got, testcase.want)
}
})
}
}

func getFakeRestURL(builder *Builder, command []string, containerName ...string) (*url.URL, error) {
if valid, err := builder.validate(); !valid {
return &url.URL{}, err
}

return &url.URL{}, nil
}

var fakeNewSPDYExecutor = func(config *rest.Config, method string, url *url.URL) (remotecommand.Executor, error) {
return &fakeExecutor{method: method, url: url}, nil
}

type fakeExecutor struct {
method string
url *url.URL
}

func (f *fakeExecutor) StreamWithContext(ctx context.Context, options remotecommand.StreamOptions) error {
if options.Stdout != nil {
buf := new(bytes.Buffer)
buf.WriteString("Command fake output")

if _, err := options.Stdout.Write(buf.Bytes()); err != nil {
return err
}
}

return nil
}

func (f *fakeExecutor) Stream(options remotecommand.StreamOptions) error {
return nil
}
Loading