github.com/secure-build/gitlab-runner@v12.5.0+incompatible/executors/kubernetes/exec_test.go (about)

     1  /*
     2  Copyright 2014 The Kubernetes Authors All rights reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package kubernetes
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"io"
    23  	"net/http"
    24  	"net/url"
    25  	"testing"
    26  
    27  	api "k8s.io/api/core/v1"
    28  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    29  	restclient "k8s.io/client-go/rest"
    30  	"k8s.io/client-go/rest/fake"
    31  )
    32  
    33  type fakeRemoteExecutor struct {
    34  	method  string
    35  	url     *url.URL
    36  	execErr error
    37  }
    38  
    39  func (f *fakeRemoteExecutor) Execute(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) error {
    40  	f.method = method
    41  	f.url = url
    42  	return f.execErr
    43  }
    44  
    45  func TestExec(t *testing.T) {
    46  	version, codec := testVersionAndCodec()
    47  	tests := []struct {
    48  		name, version, podPath, execPath string
    49  		pod                              *api.Pod
    50  		tty, execErr                     bool
    51  	}{
    52  		{
    53  			name:     "pod exec",
    54  			version:  version,
    55  			podPath:  "/api/" + version + "/namespaces/test/pods/foo",
    56  			execPath: "/api/" + version + "/namespaces/test/pods/foo/exec",
    57  			pod:      execPod(),
    58  		},
    59  		{
    60  			name:     "pod exec with tty",
    61  			version:  version,
    62  			podPath:  "/api/" + version + "/namespaces/test/pods/foo",
    63  			execPath: "/api/" + version + "/namespaces/test/pods/foo/exec",
    64  			pod:      execPod(),
    65  			tty:      true,
    66  		},
    67  		{
    68  			name:     "pod exec error",
    69  			version:  version,
    70  			podPath:  "/api/" + version + "/namespaces/test/pods/foo",
    71  			execPath: "/api/" + version + "/namespaces/test/pods/foo/exec",
    72  			pod:      execPod(),
    73  			execErr:  true,
    74  		},
    75  	}
    76  
    77  	for _, test := range tests {
    78  		// Create a fake kubeClient
    79  		fakeClient := fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
    80  			switch p, m := req.URL.Path, req.Method; {
    81  			case p == test.podPath && m == "GET":
    82  				body := objBody(codec, test.pod)
    83  				return &http.Response{StatusCode: http.StatusOK, Body: body, Header: map[string][]string{
    84  					"Content-Type": []string{"application/json"},
    85  				}}, nil
    86  			default:
    87  				// Ensures no GET is performed when deleting by name
    88  				t.Errorf("%s: unexpected request: %s %#v\n%#v", test.name, req.Method, req.URL, req)
    89  				return nil, fmt.Errorf("unexpected request")
    90  			}
    91  		})
    92  		c := testKubernetesClient(version, fakeClient)
    93  
    94  		ex := &fakeRemoteExecutor{}
    95  		if test.execErr {
    96  			ex.execErr = fmt.Errorf("exec error")
    97  		}
    98  
    99  		bufOut := bytes.NewBuffer([]byte{})
   100  		bufErr := bytes.NewBuffer([]byte{})
   101  		bufIn := bytes.NewBuffer([]byte{})
   102  
   103  		params := &ExecOptions{
   104  			PodName:       "foo",
   105  			ContainerName: "bar",
   106  			Namespace:     "test",
   107  			Command:       []string{"command"},
   108  			In:            bufIn,
   109  			Out:           bufOut,
   110  			Err:           bufErr,
   111  			Stdin:         true,
   112  			Executor:      ex,
   113  			Client:        c,
   114  		}
   115  		err := params.Run()
   116  		if test.execErr && err != ex.execErr {
   117  			t.Errorf("%s: Unexpected exec error: %v", test.name, err)
   118  			continue
   119  		}
   120  		if !test.execErr && err != nil {
   121  			t.Errorf("%s: Unexpected error: %v", test.name, err)
   122  			continue
   123  		}
   124  		if test.execErr {
   125  			continue
   126  		}
   127  		if ex.url.Path != test.execPath {
   128  			t.Errorf("%s: Did not get expected path for exec request", test.name)
   129  			continue
   130  		}
   131  		if ex.method != "POST" {
   132  			t.Errorf("%s: Did not get method for exec request: %s", test.name, ex.method)
   133  		}
   134  	}
   135  }
   136  
   137  func execPod() *api.Pod {
   138  	return &api.Pod{
   139  		ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10"},
   140  		Spec: api.PodSpec{
   141  			RestartPolicy: api.RestartPolicyAlways,
   142  			DNSPolicy:     api.DNSClusterFirst,
   143  			Containers: []api.Container{
   144  				{
   145  					Name: "bar",
   146  				},
   147  			},
   148  		},
   149  		Status: api.PodStatus{
   150  			Phase: api.PodRunning,
   151  		},
   152  	}
   153  }