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 }