func BuildTestPodName(name, testName string) string {
	return strings.ToLower("capstan-" + name + "-" + testName)
}
BuildTestPodName builds the name of test pod.
package workload
import (
	"bytes"
	"fmt"
	"strings"
	"text/template"
	"time"
	"github.com/ZJU-SEL/capstan/pkg/util"
	"github.com/pkg/errors"
	v1 "k8s.io/api/core/v1"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	apismetav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	kuberuntime "k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/kubernetes/scheme"
)
func ParseTemplate(strtmpl string, obj interface{}) ([]byte, error) {
	var buf bytes.Buffer
	tmpl, err := template.New("template").Parse(strtmpl)
	if err != nil {
		return nil, errors.Wrap(err, "error when parsing template")
	}
	err = tmpl.Execute(&buf, obj)
	if err != nil {
		return nil, errors.Wrap(err, "error when executing template")
	}
	return buf.Bytes(), nil
}
func CreatePod(kubeClient kubernetes.Interface, podBytes []byte) error {
	pod := &v1.Pod{}
	if err := kuberuntime.DecodeInto(scheme.Codecs.UniversalDecoder(), podBytes, pod); err != nil {
		return errors.Wrap(err, "unable to decode pod")
	}
	_, err := kubeClient.CoreV1().Pods(Namespace).Create(pod)
	if err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func DeletePod(kubeClient kubernetes.Interface, name string) error {
	if err := kubeClient.CoreV1().Pods(Namespace).Delete(name, apismetav1.NewDeleteOptions(0)); err != nil {
		return errors.Wrapf(err, "failed to delete pod %v", name)
	}
	err := wait.Poll(500*time.Millisecond, 60*time.Second, func() (bool, error) {
		_, err := kubeClient.CoreV1().Pods(Namespace).Get(name, apismetav1.GetOptions{})
		if err != nil {
			if apierrors.IsNotFound(err) {
				return true, nil
			}
			return false, err
		}
		return false, nil
	})
	if err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func IsPodFailing(pod *v1.Pod) (bool, error) {
	for _, cond := range pod.Status.Conditions {
		if cond.Reason == "Unschedulable" {
			return true, errors.Errorf("Can't schedule pod: %v", cond.Message)
		}
	}
	for _, cstatus := range pod.Status.ContainerStatuses {
		if cstatus.RestartCount > 2 {
			return true, errors.Errorf("Container %v has restarted unsuccessfully %v times", cstatus.Name, cstatus.RestartCount)
		}
		if waiting := cstatus.State.Waiting; waiting != nil {
			if waiting.Reason == "ImagePullBackOff" || waiting.Reason == "ErrImagePull" {
				return true, errors.Errorf("Container %v is in state %v", cstatus.Name, waiting.Reason)
			}
		}
	}
	return false, nil
}
func CheckWorkloadAvailable(kubeClient kubernetes.Interface, tool Tool) error {
	switch tool.GetWorkload().Name {
	case "nginx":
		return checkDeployment(kubeClient, tool.GetWorkload().Helm.Name+"-"+tool.GetWorkload().Name)
	case "mysql":
		return checkDeployment(kubeClient, tool.GetWorkload().Helm.Name+"-"+tool.GetWorkload().Name)
	case "iperf3":
		return checkDeployment(kubeClient, tool.GetWorkload().Helm.Name+"-"+tool.GetWorkload().Name)
	case "spark":
		return checkDeployment(kubeClient, tool.GetWorkload().Helm.Name+"-"+"master")
	case "kubeflow":
		err := checkDeployment(kubeClient, tool.GetWorkload().Helm.Name+"-"+tool.GetWorkload().Name+"-"+"tf-job-operator")
		if err != nil {
			return err
		}
		err = checkDeployment(kubeClient, tool.GetWorkload().Helm.Name+"-"+tool.GetWorkload().Name+"-"+"spartakus-volunteer")
		if err != nil {
			return err
		}
		return checkDeployment(kubeClient, tool.GetWorkload().Helm.Name+"-"+tool.GetWorkload().Name+"-"+"ambassador")
	case "wordpress":
		return checkDeployment(kubeClient, tool.GetWorkload().Helm.Name+"-"+tool.GetWorkload().Name)
	}
	return errors.Errorf("Not meet any rules to check the workload available or not")
}
func checkDeployment(kubeClient kubernetes.Interface, name string) error {
	n := 0
	for {
		time.Sleep(30 * time.Second)
		deployment, err := kubeClient.AppsV1().Deployments(Namespace).Get(name, apismetav1.GetOptions{})
		if err != nil {
			return errors.WithStack(err)
		}
		if deployment.Status.AvailableReplicas == *(deployment.Spec.Replicas) {
			return nil
		}
		if n > 5 {
			return errors.Errorf("deployment %q not available for 60 seconds", name)
		}
		n++
	}
}
func FomatArgs(agrs string) string {
	ss := strings.Split(agrs, " ")
	var str string
	for i, s := range ss {
		if i == len(ss)-1 {
			str = str + fmt.Sprintf("\"%s\"", s)
		} else {
			str = str + fmt.Sprintf("\"%s\",", s)
		}
	}
	return str
}