github.com/docker/compose-on-kubernetes@v0.5.0/e2e/e2e_suite_test.go (about)

     1  package e2e
     2  
     3  import (
     4  	"encoding/json"
     5  	"flag"
     6  	"fmt"
     7  	"io"
     8  	"math/rand"
     9  	"os"
    10  	"path"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/docker/compose-on-kubernetes/internal/e2e/compose"
    15  	homedir "github.com/mitchellh/go-homedir"
    16  	// Import ginkgo to simplify test code
    17  	. "github.com/onsi/ginkgo"
    18  	ginkgocfg "github.com/onsi/ginkgo/config"
    19  	"github.com/onsi/ginkgo/reporters"
    20  	// Import gomega to simplify test code
    21  	. "github.com/onsi/gomega"
    22  	apiv1 "k8s.io/api/core/v1"
    23  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    24  	"k8s.io/client-go/kubernetes/typed/core/v1"
    25  	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
    26  	"k8s.io/client-go/rest"
    27  	"k8s.io/client-go/tools/clientcmd"
    28  )
    29  
    30  var config *rest.Config
    31  
    32  var (
    33  	kubeconfig           = envString{defaultValue: "~/.kube/config", envVarName: "KUBECONFIG"}
    34  	outputDir            = flag.String("outputDir", os.Getenv("PWD"), "Test result output directory")
    35  	fryNamespace         = flag.String("namespace", "e2e", "Namespace to use for the test")
    36  	tag                  = flag.String("tag", "latest", "Image tag to use for the test")
    37  	pullSecret           = flag.String("pull-secret", "", "Docker Hub secret for pulling image")
    38  	skipProvisioning     = flag.Bool("skip-provisioning", false, "Skip deployment/cleanup of compose fry and tiller service")
    39  	publishedServiceType = flag.String("published-service-type", "LoadBalancer", "Service type for published ports (LoadBalancer|NodePort)")
    40  )
    41  
    42  func TestE2E(t *testing.T) {
    43  	flag.Var(&kubeconfig, "kubeconfig", "Path to a kube config. Only required if out-of-cluster. (default is ~/.kube/config, and can be overridden with ${KUBECONFIG})")
    44  	flag.Parse()
    45  	junitReporter := reporters.NewJUnitReporter(fmt.Sprintf(path.Join(*outputDir, "junit_%d.xml"), ginkgocfg.GinkgoConfig.ParallelNode))
    46  	RegisterFailHandler(Fail)
    47  	RunSpecsWithDefaultAndCustomReporters(t, "Compose E2E Test Suite", []Reporter{junitReporter})
    48  }
    49  
    50  var (
    51  	cleanup       func()
    52  	tillerCleanup func()
    53  )
    54  
    55  var _ = SynchronizedBeforeSuite(func() []byte {
    56  	if !*skipProvisioning {
    57  		setupConfig()
    58  		client, err := v1.NewForConfig(config)
    59  		Expect(err).NotTo(HaveOccurred())
    60  		if _, err := client.Namespaces().Get(*fryNamespace, metav1.GetOptions{}); err == nil {
    61  			Expect(err).To(HaveOccurred())
    62  		}
    63  
    64  		cleanup, err = compose.Install(config, *fryNamespace, *tag, *pullSecret)
    65  		Expect(err).NotTo(HaveOccurred())
    66  	}
    67  	SetDefaultEventuallyTimeout(2 * time.Minute)
    68  	SetDefaultEventuallyPollingInterval(1 * time.Second)
    69  	return nil
    70  }, func(_ []byte) {
    71  	setupConfig()
    72  	rand.Seed(time.Now().UTC().UnixNano())
    73  })
    74  
    75  func setupConfig() {
    76  	configFile, err := homedir.Expand(kubeconfig.String())
    77  	Expect(err).NotTo(HaveOccurred())
    78  	config, err = clientcmd.BuildConfigFromFlags("", configFile)
    79  	Expect(err).NotTo(HaveOccurred())
    80  }
    81  
    82  var _ = SynchronizedAfterSuite(func() {},
    83  	func() {
    84  		// check for restarts
    85  		fmt.Printf("Checking for restarts in %s\n", *fryNamespace)
    86  		client, err := v1.NewForConfig(config)
    87  		Expect(err).NotTo(HaveOccurred())
    88  		pods, err := client.Pods(*fryNamespace).List(metav1.ListOptions{})
    89  		Expect(err).NotTo(HaveOccurred())
    90  		for _, pod := range pods.Items {
    91  			for _, cont := range pod.Status.ContainerStatuses {
    92  				if cont.RestartCount != 0 {
    93  					// dump previous container logs
    94  					fmt.Fprintf(os.Stderr, "\nPrevious logs for %s/%s\n", pod.Name, cont.Name)
    95  					data, err := client.Pods(*fryNamespace).GetLogs(pod.Name, &apiv1.PodLogOptions{Container: cont.Name, Previous: true}).Stream()
    96  					Expect(err).NotTo(HaveOccurred())
    97  					io.Copy(os.Stderr, data)
    98  				}
    99  				fmt.Fprintf(os.Stderr, "\nCurrent logs for %s/%s\n", pod.Name, cont.Name)
   100  				data, err := client.Pods(*fryNamespace).GetLogs(pod.Name, &apiv1.PodLogOptions{Container: cont.Name}).Stream()
   101  				Expect(err).NotTo(HaveOccurred())
   102  				io.Copy(os.Stderr, data)
   103  			}
   104  		}
   105  		fmt.Fprintln(os.Stderr, "\nPods details:")
   106  		podsJSON, err := json.MarshalIndent(pods, "", "  ")
   107  		Expect(err).NotTo(HaveOccurred())
   108  		os.Stderr.Write(podsJSON)
   109  		if cleanup != nil {
   110  			cleanup()
   111  		}
   112  		if tillerCleanup != nil {
   113  			tillerCleanup()
   114  		}
   115  	})
   116  
   117  type envString struct {
   118  	isSet         bool
   119  	defaultValue  string
   120  	explicitValue string
   121  	envVarName    string
   122  }
   123  
   124  func (v *envString) String() string {
   125  	if v.isSet {
   126  		return v.explicitValue
   127  	}
   128  	if envValue, ok := os.LookupEnv(v.envVarName); ok {
   129  		return envValue
   130  	}
   131  	return v.defaultValue
   132  }
   133  
   134  func (v *envString) Set(value string) error {
   135  	v.isSet = true
   136  	v.explicitValue = value
   137  	return nil
   138  }