github.com/Mirantis/virtlet@v1.5.2-0.20191204181327-1659b8a48e9b/pkg/tools/command_test.go (about)

     1  /*
     2  Copyright 2018 Mirantis
     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 tools
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"io"
    23  	"sort"
    24  	"strings"
    25  	"testing"
    26  
    27  	"github.com/spf13/cobra"
    28  	v1 "k8s.io/api/core/v1"
    29  )
    30  
    31  type fakeKubeClient struct {
    32  	t                       *testing.T
    33  	virtletPods             map[string]string
    34  	vmPods                  map[string]VMPodInfo
    35  	expectedCommands        map[string]string
    36  	expectedPortForwards    []string
    37  	portForwardStopChannels []chan struct{}
    38  	logs                    map[string]string
    39  }
    40  
    41  var _ KubeClient = &fakeKubeClient{}
    42  
    43  func (c *fakeKubeClient) GetVirtletPodAndNodeNames() ([]string, []string, error) {
    44  	var nodeNames []string
    45  	for nodeName := range c.virtletPods {
    46  		nodeNames = append(nodeNames, nodeName)
    47  	}
    48  	sort.Strings(nodeNames)
    49  
    50  	var podNames []string
    51  	for _, nodeName := range nodeNames {
    52  		podNames = append(podNames, c.virtletPods[nodeName])
    53  	}
    54  
    55  	return podNames, nodeNames, nil
    56  }
    57  
    58  func (c *fakeKubeClient) GetVirtletPodNameForNode(nodeName string) (string, error) {
    59  	if podName, found := c.virtletPods[nodeName]; found {
    60  		return podName, nil
    61  	}
    62  	return "", fmt.Errorf("no Virtlet pod on the node %q", nodeName)
    63  }
    64  
    65  func (c *fakeKubeClient) GetVMPodInfo(podName string) (*VMPodInfo, error) {
    66  	if podInfo, found := c.vmPods[podName]; found {
    67  		return &podInfo, nil
    68  	}
    69  	return nil, fmt.Errorf("VM pod not found: %q", podName)
    70  }
    71  
    72  func (c *fakeKubeClient) ExecInContainer(podName, containerName, namespace string,
    73  	stdin io.Reader, stdout, stderr io.Writer,
    74  	command []string) (int, error) {
    75  	key := fmt.Sprintf("%s/%s/%s: %s", podName, containerName, namespace, strings.Join(command, " "))
    76  	out, found := c.expectedCommands[key]
    77  	if !found {
    78  		c.t.Errorf("Unexpected command: %s", key)
    79  		return 0, fmt.Errorf("unexpected command: %s", key)
    80  	}
    81  	delete(c.expectedCommands, key)
    82  	if stdout != nil {
    83  		if _, err := io.WriteString(stdout, out); err != nil {
    84  			return 0, fmt.Errorf("WriteString(): %v", err)
    85  		}
    86  	}
    87  	return 0, nil
    88  }
    89  
    90  func (c *fakeKubeClient) ForwardPorts(podName, namespace string, ports []*ForwardedPort) (stopCh chan struct{}, err error) {
    91  	var portStrs []string
    92  	for n, p := range ports {
    93  		portStrs = append(portStrs, p.String())
    94  		if p.LocalPort == 0 {
    95  			p.LocalPort = 4242 + uint16(n)
    96  		}
    97  	}
    98  	if namespace == "" {
    99  		namespace = "default"
   100  	}
   101  	key := fmt.Sprintf("%s/%s: %s", podName, namespace, strings.Join(portStrs, " "))
   102  	var pfs []string
   103  	found := false
   104  	for _, pf := range c.expectedPortForwards {
   105  		if pf == key {
   106  			found = true
   107  		} else {
   108  			pfs = append(pfs, pf)
   109  		}
   110  	}
   111  	if !found {
   112  		c.t.Errorf("unexpected portforward: %q", key)
   113  	}
   114  	c.expectedPortForwards = pfs
   115  	stopCh = make(chan struct{})
   116  	c.portForwardStopChannels = append(c.portForwardStopChannels, stopCh)
   117  	return stopCh, nil
   118  }
   119  
   120  func (c *fakeKubeClient) PodLogs(podName, containerName, namespace string, tailLines int64) ([]byte, error) {
   121  	key := fmt.Sprintf("%s/%s/%s", podName, containerName, namespace)
   122  	l, found := c.logs[key]
   123  	if !found {
   124  		c.t.Errorf("no logs specified for %q", key)
   125  		return []byte{}, nil
   126  	}
   127  	return []byte(l), nil
   128  }
   129  
   130  func (c *fakeKubeClient) GetNamesOfNodesMarkedForVirtlet() ([]string, error) {
   131  	return nil, errors.New("not implemented")
   132  }
   133  
   134  func (c *fakeKubeClient) CreatePod(pod *v1.Pod) (*v1.Pod, error) {
   135  	return nil, errors.New("not implemented")
   136  }
   137  
   138  func (c *fakeKubeClient) GetPod(name, namespace string) (*v1.Pod, error) {
   139  	return nil, errors.New("not implemented")
   140  }
   141  
   142  func (c *fakeKubeClient) DeletePod(pod, namespace string) error {
   143  	return errors.New("not implemented")
   144  }
   145  
   146  func fakeCobraCommand() *cobra.Command {
   147  	topCmd := &cobra.Command{
   148  		Use:               "topcmd",
   149  		Short:             "Topmost command",
   150  		Long:              "Lorem ipsum dolor sit amet",
   151  		DisableAutoGenTag: true,
   152  	}
   153  	var a string
   154  	var b, c int
   155  	topCmd.Flags().StringVarP(&a, "someflag", "f", "someflagvalue", "a flag")
   156  	topCmd.Flags().IntVar(&b, "anotherflag", 42, "another flag")
   157  
   158  	fooCmd := &cobra.Command{
   159  		Use:     "foo",
   160  		Short:   "Foo command",
   161  		Long:    "Consectetur adipiscing elit",
   162  		Example: "kubectl plugin topcmd foo",
   163  		// make command "runnable" so gendocs works for it
   164  		Run: func(*cobra.Command, []string) {},
   165  	}
   166  	fooCmd.Flags().IntVar(&c, "fooflag", 4242, "foo flag")
   167  	topCmd.AddCommand(fooCmd)
   168  
   169  	barCmd := &cobra.Command{
   170  		Use:   "bar",
   171  		Short: "Bar command",
   172  		Long:  "Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua",
   173  		Run:   func(*cobra.Command, []string) {},
   174  	}
   175  	topCmd.AddCommand(barCmd)
   176  
   177  	return topCmd
   178  }