github.com/oam-dev/kubevela@v1.9.11/e2e/cli.go (about)

     1  /*
     2  Copyright 2021 The KubeVela Authors.
     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 e2e
    18  
    19  import (
    20  	"os"
    21  	"os/exec"
    22  	"path"
    23  	"strings"
    24  	"time"
    25  
    26  	"github.com/Netflix/go-expect"
    27  	"github.com/hinshun/vt10x"
    28  	"github.com/onsi/ginkgo/v2"
    29  	"github.com/onsi/gomega"
    30  	"github.com/onsi/gomega/gexec"
    31  )
    32  
    33  var rudrPath = GetCliBinary()
    34  
    35  // GetCliBinary is to build kubevela binary.
    36  func GetCliBinary() string {
    37  	cwd, _ := os.Getwd()
    38  	return path.Join(cwd, "../..", "./bin")
    39  }
    40  
    41  // Exec executes a command
    42  func Exec(cli string) (string, error) {
    43  	var output []byte
    44  	session, err := asyncExec(cli)
    45  	if err != nil {
    46  		return string(output), err
    47  	}
    48  	s := session.Wait(60 * time.Second)
    49  	return string(s.Out.Contents()) + string(s.Err.Contents()), nil
    50  }
    51  
    52  // ExecAndTerminate executes a long-running command and terminate it after 3s
    53  func ExecAndTerminate(cli string) (string, error) {
    54  	var output []byte
    55  	session, err := asyncExec(cli)
    56  	if err != nil {
    57  		return string(output), err
    58  	}
    59  	time.Sleep(3 * time.Second)
    60  	s := session.Terminate()
    61  	return string(s.Out.Contents()) + string(s.Err.Contents()), nil
    62  }
    63  
    64  // LongTimeExec executes a long-running command and wait it exits by itself
    65  func LongTimeExec(cli string, timeout time.Duration) (string, error) {
    66  	var output []byte
    67  	session, err := asyncExec(cli)
    68  	if err != nil {
    69  		return string(output), err
    70  	}
    71  	s := session.Wait(timeout)
    72  	return string(s.Out.Contents()) + string(s.Err.Contents()), nil
    73  }
    74  
    75  func asyncExec(cli string) (*gexec.Session, error) {
    76  	c := strings.Fields(cli)
    77  	commandName := path.Join(rudrPath, c[0])
    78  	command := exec.Command(commandName, c[1:]...)
    79  	session, err := gexec.Start(command, ginkgo.GinkgoWriter, ginkgo.GinkgoWriter)
    80  	return session, err
    81  }
    82  
    83  func LongTimeExecWithEnv(cli string, timeout time.Duration, env []string) (string, error) {
    84  	var output []byte
    85  	c := strings.Fields(cli)
    86  	commandName := path.Join(rudrPath, c[0])
    87  	command := exec.Command(commandName, c[1:]...)
    88  	command.Env = os.Environ()
    89  	command.Env = append(command.Env, env...)
    90  
    91  	session, err := gexec.Start(command, ginkgo.GinkgoWriter, ginkgo.GinkgoWriter)
    92  	if err != nil {
    93  		return string(output), err
    94  	}
    95  	s := session.Wait(timeout)
    96  	return string(s.Out.Contents()) + string(s.Err.Contents()), nil
    97  }
    98  
    99  // InteractiveExec executes a command with interactive input
   100  func InteractiveExec(cli string, consoleFn func(*expect.Console)) (string, error) {
   101  	var output []byte
   102  	console, _, err := vt10x.NewVT10XConsole(expect.WithStdout(ginkgo.GinkgoWriter))
   103  	gomega.Expect(err).NotTo(gomega.HaveOccurred())
   104  	defer console.Close()
   105  	doneC := make(chan struct{})
   106  
   107  	go func() {
   108  		defer ginkgo.GinkgoRecover()
   109  		defer close(doneC)
   110  		consoleFn(console)
   111  	}()
   112  
   113  	c := strings.Fields(cli)
   114  	commandName := path.Join(rudrPath, c[0])
   115  	command := exec.Command(commandName, c[1:]...)
   116  	command.Stdin = console.Tty()
   117  
   118  	session, err := gexec.Start(command, console.Tty(), console.Tty())
   119  	if err != nil {
   120  		return string(output), err
   121  	}
   122  	s := session.Wait(300 * time.Second)
   123  	err = console.Tty().Close()
   124  	if err != nil {
   125  		return string(output), err
   126  	}
   127  	<-doneC
   128  	if err != nil {
   129  		return string(output), err
   130  	}
   131  	return string(s.Out.Contents()) + string(s.Err.Contents()), nil
   132  }
   133  
   134  func BeforeSuit() {
   135  	// sync capabilities from cluster into local
   136  	_, _ = Exec("vela workloads")
   137  }