mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Convert basic.sh e2e test to Go
This commit is contained in:
		@@ -49,6 +49,10 @@ ENABLE_NODE_MONITORING=true
 | 
				
			|||||||
ENABLE_NODE_LOGGING=true
 | 
					ENABLE_NODE_LOGGING=true
 | 
				
			||||||
LOGGING_DESTINATION=elasticsearch # options: elasticsearch, gcp
 | 
					LOGGING_DESTINATION=elasticsearch # options: elasticsearch, gcp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Optional: When set to true, Elasticsearch and Kibana will be setup as part of the cluster bring up.
 | 
				
			||||||
 | 
					ENABLE_CLUSTER_LOGGING=false
 | 
				
			||||||
 | 
					ELASTICSEARCH_LOGGING_REPLICAS=1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENABLE_CLUSTER_MONITORING=false
 | 
					ENABLE_CLUSTER_MONITORING=false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Don't require https for registries in our local RFC1918 network
 | 
					# Don't require https for registries in our local RFC1918 network
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										714
									
								
								cmd/e2e/e2e.go
									
									
									
									
									
								
							
							
						
						
									
										714
									
								
								cmd/e2e/e2e.go
									
									
									
									
									
								
							@@ -17,24 +17,11 @@ limitations under the License.
 | 
				
			|||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"io/ioutil"
 | 
					 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"path/filepath"
 | 
					 | 
				
			||||||
	goruntime "runtime"
 | 
						goruntime "runtime"
 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
					 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
 | 
					 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
					 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth"
 | 
					 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
 | 
					 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
 | 
					 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
 | 
				
			||||||
	"github.com/golang/glog"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/test/e2e"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	flag "github.com/spf13/pflag"
 | 
						flag "github.com/spf13/pflag"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -45,705 +32,8 @@ var (
 | 
				
			|||||||
	repoRoot   = flag.String("repo_root", "./", "Root directory of kubernetes repository, for finding test files. Default assumes working directory is repository root")
 | 
						repoRoot   = flag.String("repo_root", "./", "Root directory of kubernetes repository, for finding test files. Default assumes working directory is repository root")
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func waitForPodRunning(c *client.Client, id string) {
 | 
					 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		time.Sleep(5 * time.Second)
 | 
					 | 
				
			||||||
		pod, err := c.Pods(api.NamespaceDefault).Get(id)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			glog.Warningf("Get pod failed: %v", err)
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if pod.Status.Phase == api.PodRunning {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		glog.Infof("Waiting for pod status to be %q (found %q)", api.PodRunning, pod.Status.Phase)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// waitForPodSuccess returns true if the pod reached state success, or false if it reached failure or ran too long.
 | 
					 | 
				
			||||||
func waitForPodSuccess(c *client.Client, podName string, contName string) bool {
 | 
					 | 
				
			||||||
	for i := 0; i < 10; i++ {
 | 
					 | 
				
			||||||
		if i > 0 {
 | 
					 | 
				
			||||||
			time.Sleep(5 * time.Second)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		pod, err := c.Pods(api.NamespaceDefault).Get(podName)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			glog.Warningf("Get pod failed: %v", err)
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// Cannot use pod.Status.Phase == api.PodSucceeded/api.PodFailed due to #2632
 | 
					 | 
				
			||||||
		ci, ok := pod.Status.Info[contName]
 | 
					 | 
				
			||||||
		if !ok {
 | 
					 | 
				
			||||||
			glog.Infof("No Status.Info for container %s in pod %s yet", contName, podName)
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			if ci.State.Termination != nil {
 | 
					 | 
				
			||||||
				if ci.State.Termination.ExitCode == 0 {
 | 
					 | 
				
			||||||
					glog.Infof("Saw pod success")
 | 
					 | 
				
			||||||
					return true
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					glog.Infof("Saw pod failure: %+v", ci.State.Termination)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				glog.Infof("Waiting for pod %q status to be success or failure", podName)
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				glog.Infof("Nil State.Termination for container %s in pod %s so far", contName, podName)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	glog.Warningf("Gave up waiting for pod %q status to be success or failure", podName)
 | 
					 | 
				
			||||||
	return false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// assetPath returns a path to the requested file; safe on all
 | 
					 | 
				
			||||||
// OSes. NOTE: If you use an asset in this test, you MUST add it to
 | 
					 | 
				
			||||||
// the KUBE_TEST_PORTABLE array in hack/lib/golang.sh.
 | 
					 | 
				
			||||||
func assetPath(pathElements ...string) string {
 | 
					 | 
				
			||||||
	return filepath.Join(*repoRoot, filepath.Join(pathElements...))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func loadObjectOrDie(filePath string) runtime.Object {
 | 
					 | 
				
			||||||
	data, err := ioutil.ReadFile(filePath)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Fatalf("Failed to read object: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return decodeObjectOrDie(data)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func decodeObjectOrDie(data []byte) runtime.Object {
 | 
					 | 
				
			||||||
	obj, err := latest.Codec.Decode(data)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Fatalf("Failed to decode object: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return obj
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func loadPodOrDie(filePath string) *api.Pod {
 | 
					 | 
				
			||||||
	obj := loadObjectOrDie(filePath)
 | 
					 | 
				
			||||||
	pod, ok := obj.(*api.Pod)
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		glog.Fatalf("Failed to load pod: %v", obj)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return pod
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func loadClientOrDie() *client.Client {
 | 
					 | 
				
			||||||
	config := client.Config{
 | 
					 | 
				
			||||||
		Host: *host,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	info, err := clientauth.LoadFromFile(*authConfig)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Fatalf("Error loading auth: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// If the certificate directory is provided, set the cert paths to be there.
 | 
					 | 
				
			||||||
	if *certDir != "" {
 | 
					 | 
				
			||||||
		glog.Infof("Expecting certs in %v.", *certDir)
 | 
					 | 
				
			||||||
		info.CAFile = filepath.Join(*certDir, "ca.crt")
 | 
					 | 
				
			||||||
		info.CertFile = filepath.Join(*certDir, "kubecfg.crt")
 | 
					 | 
				
			||||||
		info.KeyFile = filepath.Join(*certDir, "kubecfg.key")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	config, err = info.MergeWithConfig(config)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Fatalf("Error creating client")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	c, err := client.New(&config)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Fatalf("Error creating client")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return c
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func parsePodOrDie(json string) *api.Pod {
 | 
					 | 
				
			||||||
	obj := decodeObjectOrDie([]byte(json))
 | 
					 | 
				
			||||||
	pod, ok := obj.(*api.Pod)
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		glog.Fatalf("Failed to cast pod: %v", obj)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return pod
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func parseServiceOrDie(json string) *api.Service {
 | 
					 | 
				
			||||||
	obj := decodeObjectOrDie([]byte(json))
 | 
					 | 
				
			||||||
	service, ok := obj.(*api.Service)
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		glog.Fatalf("Failed to cast service: %v", obj)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return service
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestKubernetesROService(c *client.Client) bool {
 | 
					 | 
				
			||||||
	svc := api.ServiceList{}
 | 
					 | 
				
			||||||
	err := c.Get().
 | 
					 | 
				
			||||||
		Namespace("default").
 | 
					 | 
				
			||||||
		AbsPath("/api/v1beta1/proxy/services/kubernetes-ro/api/v1beta1/services").
 | 
					 | 
				
			||||||
		Do().
 | 
					 | 
				
			||||||
		Into(&svc)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("unexpected error listing services using ro service: %v", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var foundRW, foundRO bool
 | 
					 | 
				
			||||||
	for i := range svc.Items {
 | 
					 | 
				
			||||||
		if svc.Items[i].Name == "kubernetes" {
 | 
					 | 
				
			||||||
			foundRW = true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if svc.Items[i].Name == "kubernetes-ro" {
 | 
					 | 
				
			||||||
			foundRO = true
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !foundRW {
 | 
					 | 
				
			||||||
		glog.Error("no RW service found")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !foundRO {
 | 
					 | 
				
			||||||
		glog.Error("no RO service found")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !foundRW || !foundRO {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestPodUpdate(c *client.Client) bool {
 | 
					 | 
				
			||||||
	podClient := c.Pods(api.NamespaceDefault)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pod := loadPodOrDie(assetPath("api", "examples", "pod.json"))
 | 
					 | 
				
			||||||
	value := strconv.Itoa(time.Now().Nanosecond())
 | 
					 | 
				
			||||||
	pod.Labels["time"] = value
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_, err := podClient.Create(pod)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to create pod: %v", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer podClient.Delete(pod.Name)
 | 
					 | 
				
			||||||
	waitForPodRunning(c, pod.Name)
 | 
					 | 
				
			||||||
	pods, err := podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value})))
 | 
					 | 
				
			||||||
	if len(pods.Items) != 1 {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to find the correct pod")
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	podOut, err := podClient.Get(pod.Name)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to get pod: %v", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	value = "time" + value
 | 
					 | 
				
			||||||
	pod.Labels["time"] = value
 | 
					 | 
				
			||||||
	pod.ResourceVersion = podOut.ResourceVersion
 | 
					 | 
				
			||||||
	pod.UID = podOut.UID
 | 
					 | 
				
			||||||
	pod, err = podClient.Update(pod)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to update pod: %v", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	waitForPodRunning(c, pod.Name)
 | 
					 | 
				
			||||||
	pods, err = podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value})))
 | 
					 | 
				
			||||||
	if len(pods.Items) != 1 {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to find the correct pod after update.")
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	glog.Infof("pod update OK")
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TestImportantURLs validates that URLs that people depend on haven't moved.
 | 
					 | 
				
			||||||
// ***IMPORTANT*** Do *not* fix this test just by changing the path.  If you moved a URL
 | 
					 | 
				
			||||||
// you can break upstream dependencies.
 | 
					 | 
				
			||||||
func TestImportantURLs(c *client.Client) bool {
 | 
					 | 
				
			||||||
	tests := []struct {
 | 
					 | 
				
			||||||
		path string
 | 
					 | 
				
			||||||
	}{
 | 
					 | 
				
			||||||
		{path: "/validate"},
 | 
					 | 
				
			||||||
		{path: "/healthz"},
 | 
					 | 
				
			||||||
		// TODO: test proxy links here
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ok := true
 | 
					 | 
				
			||||||
	for _, test := range tests {
 | 
					 | 
				
			||||||
		glog.Infof("testing: %s", test.path)
 | 
					 | 
				
			||||||
		data, err := c.RESTClient.Get().
 | 
					 | 
				
			||||||
			AbsPath(test.path).
 | 
					 | 
				
			||||||
			Do().
 | 
					 | 
				
			||||||
			Raw()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			glog.Errorf("Failed: %v\nBody: %s", err, string(data))
 | 
					 | 
				
			||||||
			ok = false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ok
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TestKubeletSendsEvent checks that kubelets and scheduler send events about pods scheduling and running.
 | 
					 | 
				
			||||||
func TestKubeletSendsEvent(c *client.Client) bool {
 | 
					 | 
				
			||||||
	provider := os.Getenv("KUBERNETES_PROVIDER")
 | 
					 | 
				
			||||||
	if len(provider) > 0 && provider != "gce" && provider != "gke" {
 | 
					 | 
				
			||||||
		glog.Infof("skipping TestKubeletSendsEvent on cloud provider %s", provider)
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if provider == "" {
 | 
					 | 
				
			||||||
		glog.Info("KUBERNETES_PROVIDER is unset; assuming \"gce\"")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	podClient := c.Pods(api.NamespaceDefault)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pod := loadPodOrDie(assetPath("cmd", "e2e", "pod.json"))
 | 
					 | 
				
			||||||
	value := strconv.Itoa(time.Now().Nanosecond())
 | 
					 | 
				
			||||||
	pod.Labels["time"] = value
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_, err := podClient.Create(pod)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to create pod: %v", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer podClient.Delete(pod.Name)
 | 
					 | 
				
			||||||
	waitForPodRunning(c, pod.Name)
 | 
					 | 
				
			||||||
	pods, err := podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value})))
 | 
					 | 
				
			||||||
	if len(pods.Items) != 1 {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to find the correct pod")
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	podWithUid, err := podClient.Get(pod.Name)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to get pod: %v", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Check for scheduler event about the pod.
 | 
					 | 
				
			||||||
	glog.Infof("%+v", podWithUid)
 | 
					 | 
				
			||||||
	events, err := c.Events(api.NamespaceDefault).List(
 | 
					 | 
				
			||||||
		labels.Everything(),
 | 
					 | 
				
			||||||
		labels.Set{
 | 
					 | 
				
			||||||
			"involvedObject.kind":      "Pod",
 | 
					 | 
				
			||||||
			"involvedObject.uid":       string(podWithUid.UID),
 | 
					 | 
				
			||||||
			"involvedObject.namespace": api.NamespaceDefault,
 | 
					 | 
				
			||||||
			"source":                   "scheduler",
 | 
					 | 
				
			||||||
		}.AsSelector(),
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Error("Error while listing events:", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(events.Items) == 0 {
 | 
					 | 
				
			||||||
		glog.Error("Didn't see any scheduler events even though pod was running.")
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	glog.Info("Saw scheduler event for our pod.")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Check for kubelet event about the pod.
 | 
					 | 
				
			||||||
	events, err = c.Events(api.NamespaceDefault).List(
 | 
					 | 
				
			||||||
		labels.Everything(),
 | 
					 | 
				
			||||||
		labels.Set{
 | 
					 | 
				
			||||||
			"involvedObject.uid":       string(podWithUid.UID),
 | 
					 | 
				
			||||||
			"involvedObject.kind":      "BoundPod",
 | 
					 | 
				
			||||||
			"involvedObject.namespace": api.NamespaceDefault,
 | 
					 | 
				
			||||||
			"source":                   "kubelet",
 | 
					 | 
				
			||||||
		}.AsSelector(),
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Error("Error while listing events:", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(events.Items) == 0 {
 | 
					 | 
				
			||||||
		glog.Error("Didn't see any kubelet events even though pod was running.")
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	glog.Info("Saw kubelet event for our pod.")
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestNetwork(c *client.Client) bool {
 | 
					 | 
				
			||||||
	ns := api.NamespaceDefault
 | 
					 | 
				
			||||||
	svc, err := c.Services(ns).Create(loadObjectOrDie(assetPath(
 | 
					 | 
				
			||||||
		"contrib", "for-tests", "network-tester", "service.json",
 | 
					 | 
				
			||||||
	)).(*api.Service))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("unable to create test service: %v", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Clean up service
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		if err = c.Services(ns).Delete(svc.Name); err != nil {
 | 
					 | 
				
			||||||
			glog.Errorf("unable to delete svc %v: %v", svc.Name, err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rc, err := c.ReplicationControllers(ns).Create(loadObjectOrDie(assetPath(
 | 
					 | 
				
			||||||
		"contrib", "for-tests", "network-tester", "rc.json",
 | 
					 | 
				
			||||||
	)).(*api.ReplicationController))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("unable to create test rc: %v", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Clean up rc
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		rc.Spec.Replicas = 0
 | 
					 | 
				
			||||||
		rc, err = c.ReplicationControllers(ns).Update(rc)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			glog.Errorf("unable to modify replica count for rc %v: %v", rc.Name, err)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if err = c.ReplicationControllers(ns).Delete(rc.Name); err != nil {
 | 
					 | 
				
			||||||
			glog.Errorf("unable to delete rc %v: %v", rc.Name, err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	const maxAttempts = 60
 | 
					 | 
				
			||||||
	for i := 0; i < maxAttempts; i++ {
 | 
					 | 
				
			||||||
		time.Sleep(time.Second)
 | 
					 | 
				
			||||||
		body, err := c.Get().Prefix("proxy").Resource("services").Name(svc.Name).Suffix("status").Do().Raw()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			glog.Infof("Attempt %v/%v: service/pod still starting. (error: '%v')", i, maxAttempts, err)
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		switch string(body) {
 | 
					 | 
				
			||||||
		case "pass":
 | 
					 | 
				
			||||||
			glog.Infof("Passed on attempt %v. Cleaning up.", i)
 | 
					 | 
				
			||||||
			return true
 | 
					 | 
				
			||||||
		case "running":
 | 
					 | 
				
			||||||
			glog.Infof("Attempt %v/%v: test still running", i, maxAttempts)
 | 
					 | 
				
			||||||
		case "fail":
 | 
					 | 
				
			||||||
			if body, err := c.Get().Prefix("proxy").Resource("services").Name(svc.Name).Suffix("read").Do().Raw(); err != nil {
 | 
					 | 
				
			||||||
				glog.Infof("Failed on attempt %v. Cleaning up. Error reading details: %v", i, err)
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				glog.Infof("Failed on attempt %v. Cleaning up. Details:\n%v", i, string(body))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if body, err := c.Get().Prefix("proxy").Resource("services").Name(svc.Name).Suffix("read").Do().Raw(); err != nil {
 | 
					 | 
				
			||||||
		glog.Infof("Timed out. Cleaning up. Error reading details: %v", err)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		glog.Infof("Timed out. Cleaning up. Details:\n%v", string(body))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return false
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type TestSpec struct {
 | 
					 | 
				
			||||||
	// The test to run
 | 
					 | 
				
			||||||
	test func(c *client.Client) bool
 | 
					 | 
				
			||||||
	// The human readable name of this test
 | 
					 | 
				
			||||||
	name string
 | 
					 | 
				
			||||||
	// The id for this test.  It should be constant for the life of the test.
 | 
					 | 
				
			||||||
	id int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type TestInfo struct {
 | 
					 | 
				
			||||||
	passed bool
 | 
					 | 
				
			||||||
	spec   TestSpec
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Output a summary in the TAP (test anything protocol) format for automated processing.
 | 
					 | 
				
			||||||
// See http://testanything.org/ for more info
 | 
					 | 
				
			||||||
func outputTAPSummary(infoList []TestInfo) {
 | 
					 | 
				
			||||||
	glog.Infof("1..%d", len(infoList))
 | 
					 | 
				
			||||||
	for _, info := range infoList {
 | 
					 | 
				
			||||||
		if info.passed {
 | 
					 | 
				
			||||||
			glog.Infof("ok %d - %s", info.spec.id, info.spec.name)
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			glog.Infof("not ok %d - %s", info.spec.id, info.spec.name)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TestClusterDNS checks that cluster DNS works.
 | 
					 | 
				
			||||||
func TestClusterDNS(c *client.Client) bool {
 | 
					 | 
				
			||||||
	// TODO:
 | 
					 | 
				
			||||||
	// https://github.com/GoogleCloudPlatform/kubernetes/issues/3305
 | 
					 | 
				
			||||||
	// (but even if it's fixed, this will need a version check for
 | 
					 | 
				
			||||||
	// skewed version tests)
 | 
					 | 
				
			||||||
	if os.Getenv("KUBERNETES_PROVIDER") == "gke" {
 | 
					 | 
				
			||||||
		glog.Infof("skipping TestClusterDNS on gke")
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	podClient := c.Pods(api.NamespaceDefault)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//TODO: Wait for skyDNS
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// All the names we need to be able to resolve.
 | 
					 | 
				
			||||||
	namesToResolve := []string{
 | 
					 | 
				
			||||||
		"kubernetes-ro",
 | 
					 | 
				
			||||||
		"kubernetes-ro.default",
 | 
					 | 
				
			||||||
		"kubernetes-ro.default.kubernetes.local",
 | 
					 | 
				
			||||||
		"google.com",
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	probeCmd := "for i in `seq 1 600`; do "
 | 
					 | 
				
			||||||
	for _, name := range namesToResolve {
 | 
					 | 
				
			||||||
		probeCmd += fmt.Sprintf("wget -O /dev/null %s && echo OK > /results/%s;", name, name)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	probeCmd += "sleep 1; done"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Run a pod which probes DNS and exposes the results by HTTP.
 | 
					 | 
				
			||||||
	pod := &api.Pod{
 | 
					 | 
				
			||||||
		TypeMeta: api.TypeMeta{
 | 
					 | 
				
			||||||
			Kind:       "Pod",
 | 
					 | 
				
			||||||
			APIVersion: "v1beta1",
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		ObjectMeta: api.ObjectMeta{
 | 
					 | 
				
			||||||
			Name: "dns-test",
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		Spec: api.PodSpec{
 | 
					 | 
				
			||||||
			Volumes: []api.Volume{
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					Name: "results",
 | 
					 | 
				
			||||||
					Source: &api.VolumeSource{
 | 
					 | 
				
			||||||
						EmptyDir: &api.EmptyDir{},
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			Containers: []api.Container{
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					Name:  "webserver",
 | 
					 | 
				
			||||||
					Image: "kubernetes/test-webserver",
 | 
					 | 
				
			||||||
					VolumeMounts: []api.VolumeMount{
 | 
					 | 
				
			||||||
						{
 | 
					 | 
				
			||||||
							Name:      "results",
 | 
					 | 
				
			||||||
							MountPath: "/results",
 | 
					 | 
				
			||||||
						},
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					Name:    "pinger",
 | 
					 | 
				
			||||||
					Image:   "busybox",
 | 
					 | 
				
			||||||
					Command: []string{"sh", "-c", probeCmd},
 | 
					 | 
				
			||||||
					VolumeMounts: []api.VolumeMount{
 | 
					 | 
				
			||||||
						{
 | 
					 | 
				
			||||||
							Name:      "results",
 | 
					 | 
				
			||||||
							MountPath: "/results",
 | 
					 | 
				
			||||||
						},
 | 
					 | 
				
			||||||
					},
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	_, err := podClient.Create(pod)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to create dns-test pod: %v", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer podClient.Delete(pod.Name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	waitForPodRunning(c, pod.Name)
 | 
					 | 
				
			||||||
	pod, err = podClient.Get(pod.Name)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to get pod: %v", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Try to find results for each expected name.
 | 
					 | 
				
			||||||
	var failed []string
 | 
					 | 
				
			||||||
	for try := 1; try < 100; try++ {
 | 
					 | 
				
			||||||
		failed = []string{}
 | 
					 | 
				
			||||||
		for _, name := range namesToResolve {
 | 
					 | 
				
			||||||
			_, err := c.Get().
 | 
					 | 
				
			||||||
				Prefix("proxy").
 | 
					 | 
				
			||||||
				Resource("pods").
 | 
					 | 
				
			||||||
				Namespace("default").
 | 
					 | 
				
			||||||
				Name(pod.Name).
 | 
					 | 
				
			||||||
				Suffix("results", name).
 | 
					 | 
				
			||||||
				Do().Raw()
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				failed = append(failed, name)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if len(failed) == 0 {
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		glog.Infof("lookups failed for: %v", failed)
 | 
					 | 
				
			||||||
		time.Sleep(3 * time.Second)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(failed) != 0 {
 | 
					 | 
				
			||||||
		glog.Errorf("DNS failed for: %v", failed)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// TODO: probe from the host, too.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	glog.Info("DNS probes succeeded")
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// TestPodHasServiceEnvVars checks that kubelets and scheduler send events about pods scheduling and running.
 | 
					 | 
				
			||||||
func TestPodHasServiceEnvVars(c *client.Client) bool {
 | 
					 | 
				
			||||||
	// Make a pod that will be a service.
 | 
					 | 
				
			||||||
	// This pod serves its hostname via HTTP.
 | 
					 | 
				
			||||||
	serverPod := parsePodOrDie(`{
 | 
					 | 
				
			||||||
	  "kind": "Pod",
 | 
					 | 
				
			||||||
	  "apiVersion": "v1beta1",
 | 
					 | 
				
			||||||
	  "id": "srv",
 | 
					 | 
				
			||||||
	  "desiredState": {
 | 
					 | 
				
			||||||
		"manifest": {
 | 
					 | 
				
			||||||
		  "version": "v1beta1",
 | 
					 | 
				
			||||||
		  "id": "srv",
 | 
					 | 
				
			||||||
		  "containers": [{
 | 
					 | 
				
			||||||
			"name": "srv",
 | 
					 | 
				
			||||||
			"image": "kubernetes/serve_hostname",
 | 
					 | 
				
			||||||
			"ports": [{
 | 
					 | 
				
			||||||
			  "containerPort": 80,
 | 
					 | 
				
			||||||
			  "hostPort": 8080
 | 
					 | 
				
			||||||
			}]
 | 
					 | 
				
			||||||
		  }]
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	  },
 | 
					 | 
				
			||||||
	  "labels": {
 | 
					 | 
				
			||||||
		"name": "srv"
 | 
					 | 
				
			||||||
	  }
 | 
					 | 
				
			||||||
	}`)
 | 
					 | 
				
			||||||
	_, err := c.Pods(api.NamespaceDefault).Create(serverPod)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to create serverPod: %v", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer c.Pods(api.NamespaceDefault).Delete(serverPod.Name)
 | 
					 | 
				
			||||||
	waitForPodRunning(c, serverPod.Name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// This service exposes pod p's port 8080 as a service on port 8765
 | 
					 | 
				
			||||||
	svc := parseServiceOrDie(`{
 | 
					 | 
				
			||||||
	  "id": "fooservice",
 | 
					 | 
				
			||||||
	  "kind": "Service",
 | 
					 | 
				
			||||||
	  "apiVersion": "v1beta1",
 | 
					 | 
				
			||||||
	  "port": 8765,
 | 
					 | 
				
			||||||
	  "containerPort": 8080,
 | 
					 | 
				
			||||||
	  "selector": {
 | 
					 | 
				
			||||||
		"name": "p"
 | 
					 | 
				
			||||||
	  }
 | 
					 | 
				
			||||||
	}`)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to delete service: %v", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	time.Sleep(2)
 | 
					 | 
				
			||||||
	_, err = c.Services(api.NamespaceDefault).Create(svc)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to create service: %v", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer c.Services(api.NamespaceDefault).Delete(svc.Name)
 | 
					 | 
				
			||||||
	// TODO: we don't have a way to wait for a service to be "running".
 | 
					 | 
				
			||||||
	// If this proves flaky, then we will need to retry the clientPod or insert a sleep.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Make a client pod that verifies that it has the service environment variables.
 | 
					 | 
				
			||||||
	clientPod := parsePodOrDie(`{
 | 
					 | 
				
			||||||
	  "apiVersion": "v1beta1",
 | 
					 | 
				
			||||||
	  "kind": "Pod",
 | 
					 | 
				
			||||||
	  "id": "env3",
 | 
					 | 
				
			||||||
	  "desiredState": {
 | 
					 | 
				
			||||||
		"manifest": {
 | 
					 | 
				
			||||||
		  "version": "v1beta1",
 | 
					 | 
				
			||||||
		  "id": "env3",
 | 
					 | 
				
			||||||
		  "restartPolicy": { "never": {} },
 | 
					 | 
				
			||||||
		  "containers": [{
 | 
					 | 
				
			||||||
			"name": "env3cont",
 | 
					 | 
				
			||||||
			"image": "busybox",
 | 
					 | 
				
			||||||
			"command": ["sh", "-c", "env"]
 | 
					 | 
				
			||||||
		  }]
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	  },
 | 
					 | 
				
			||||||
	  "labels": { "name": "env3" }
 | 
					 | 
				
			||||||
	}`)
 | 
					 | 
				
			||||||
	_, err = c.Pods(api.NamespaceDefault).Create(clientPod)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to create pod: %v", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer c.Pods(api.NamespaceDefault).Delete(clientPod.Name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Wait for client pod to complete.
 | 
					 | 
				
			||||||
	success := waitForPodSuccess(c, clientPod.Name, clientPod.Spec.Containers[0].Name)
 | 
					 | 
				
			||||||
	if !success {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to run client pod to detect service env vars.")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Grab its logs.  Get host first.
 | 
					 | 
				
			||||||
	clientPodStatus, err := c.Pods(api.NamespaceDefault).Get(clientPod.Name)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to get clientPod to know host: %v", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	glog.Infof("Trying to get logs from host %s pod %s container %s: %v",
 | 
					 | 
				
			||||||
		clientPodStatus.Status.Host, clientPodStatus.Name, clientPodStatus.Spec.Containers[0].Name, err)
 | 
					 | 
				
			||||||
	logs, err := c.Get().
 | 
					 | 
				
			||||||
		Prefix("proxy").
 | 
					 | 
				
			||||||
		Resource("minions").
 | 
					 | 
				
			||||||
		Name(clientPodStatus.Status.Host).
 | 
					 | 
				
			||||||
		Suffix("containerLogs", api.NamespaceDefault, clientPodStatus.Name, clientPodStatus.Spec.Containers[0].Name).
 | 
					 | 
				
			||||||
		Do().
 | 
					 | 
				
			||||||
		Raw()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Errorf("Failed to get logs from host %s pod %s container %s: %v",
 | 
					 | 
				
			||||||
			clientPodStatus.Status.Host, clientPodStatus.Name, clientPodStatus.Spec.Containers[0].Name, err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	glog.Info("clientPod logs:", string(logs))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	toFind := []string{
 | 
					 | 
				
			||||||
		"FOOSERVICE_SERVICE_HOST=",
 | 
					 | 
				
			||||||
		"FOOSERVICE_SERVICE_PORT=",
 | 
					 | 
				
			||||||
		"FOOSERVICE_PORT=",
 | 
					 | 
				
			||||||
		"FOOSERVICE_PORT_8765_TCP_PORT=",
 | 
					 | 
				
			||||||
		"FOOSERVICE_PORT_8765_TCP_PROTO=",
 | 
					 | 
				
			||||||
		"FOOSERVICE_PORT_8765_TCP=",
 | 
					 | 
				
			||||||
		"FOOSERVICE_PORT_8765_TCP_ADDR=",
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, m := range toFind {
 | 
					 | 
				
			||||||
		if !strings.Contains(string(logs), m) {
 | 
					 | 
				
			||||||
			glog.Errorf("Unable to find env var %q in client env vars.", m)
 | 
					 | 
				
			||||||
			success = false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// We could try a wget the service from the client pod.  But services.sh e2e test covers that pretty well.
 | 
					 | 
				
			||||||
	return success
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
	util.InitFlags()
 | 
						util.InitFlags()
 | 
				
			||||||
	goruntime.GOMAXPROCS(goruntime.NumCPU())
 | 
						goruntime.GOMAXPROCS(goruntime.NumCPU())
 | 
				
			||||||
	util.ReallyCrash = true
 | 
						e2e.RunE2ETests(*authConfig, *certDir, *host, *repoRoot)
 | 
				
			||||||
	util.InitLogs()
 | 
					 | 
				
			||||||
	defer util.FlushLogs()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	go func() {
 | 
					 | 
				
			||||||
		defer util.FlushLogs()
 | 
					 | 
				
			||||||
		time.Sleep(5 * time.Minute)
 | 
					 | 
				
			||||||
		glog.Fatalf("This test has timed out. Cleanup not guaranteed.")
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	c := loadClientOrDie()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Define the tests.  Important: for a clean test grid, please keep ids for a test constant.
 | 
					 | 
				
			||||||
	tests := []TestSpec{
 | 
					 | 
				
			||||||
		{TestKubernetesROService, "TestKubernetesROService", 1},
 | 
					 | 
				
			||||||
		{TestKubeletSendsEvent, "TestKubeletSendsEvent", 2},
 | 
					 | 
				
			||||||
		{TestImportantURLs, "TestImportantURLs", 3},
 | 
					 | 
				
			||||||
		{TestPodUpdate, "TestPodUpdate", 4},
 | 
					 | 
				
			||||||
		{TestNetwork, "TestNetwork", 5},
 | 
					 | 
				
			||||||
		{TestClusterDNS, "TestClusterDNS", 6},
 | 
					 | 
				
			||||||
		{TestPodHasServiceEnvVars, "TestPodHasServiceEnvVars", 7},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	info := []TestInfo{}
 | 
					 | 
				
			||||||
	passed := true
 | 
					 | 
				
			||||||
	for i, test := range tests {
 | 
					 | 
				
			||||||
		glog.Infof("Running test %d", i+1)
 | 
					 | 
				
			||||||
		testPassed := test.test(c)
 | 
					 | 
				
			||||||
		if !testPassed {
 | 
					 | 
				
			||||||
			glog.Infof("        test %d failed", i+1)
 | 
					 | 
				
			||||||
			passed = false
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			glog.Infof("        test %d passed", i+1)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// TODO: clean up objects created during a test after the test, so cases
 | 
					 | 
				
			||||||
		// are independent.
 | 
					 | 
				
			||||||
		info = append(info, TestInfo{testPassed, test})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	outputTAPSummary(info)
 | 
					 | 
				
			||||||
	if !passed {
 | 
					 | 
				
			||||||
		glog.Fatalf("At least one test failed")
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		glog.Infof("All tests pass")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,7 +52,7 @@ readonly KUBE_TEST_BINARIES=("${KUBE_TEST_TARGETS[@]##*/}")
 | 
				
			|||||||
readonly KUBE_TEST_BINARIES_WIN=("${KUBE_TEST_BINARIES[@]/%/.exe}")
 | 
					readonly KUBE_TEST_BINARIES_WIN=("${KUBE_TEST_BINARIES[@]/%/.exe}")
 | 
				
			||||||
readonly KUBE_TEST_PORTABLE=(
 | 
					readonly KUBE_TEST_PORTABLE=(
 | 
				
			||||||
  api/examples/pod.json
 | 
					  api/examples/pod.json
 | 
				
			||||||
  cmd/e2e/pod.json
 | 
					  test/e2e/pod.json
 | 
				
			||||||
  contrib/for-tests/network-tester/rc.json
 | 
					  contrib/for-tests/network-tester/rc.json
 | 
				
			||||||
  contrib/for-tests/network-tester/service.json
 | 
					  contrib/for-tests/network-tester/service.json
 | 
				
			||||||
  hack/e2e.go
 | 
					  hack/e2e.go
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										154
									
								
								test/e2e/basic.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								test/e2e/basic.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,154 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package e2e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"io/ioutil"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
 | 
				
			||||||
 | 
						"github.com/golang/glog"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestBasic(c *client.Client) bool {
 | 
				
			||||||
 | 
						ns := api.NamespaceDefault
 | 
				
			||||||
 | 
						name := "my-hostname"
 | 
				
			||||||
 | 
						replicas := 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Attmept to delete a controller that might have been
 | 
				
			||||||
 | 
						// left lying around from a previously aborted test.
 | 
				
			||||||
 | 
						controllers, err := c.ReplicationControllers(ns).List(labels.Everything())
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Infof("Failed to list replication controllers: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, cnt := range controllers.Items {
 | 
				
			||||||
 | 
							if cnt.Name == name {
 | 
				
			||||||
 | 
								glog.Infof("Found a straggler %s controller", name)
 | 
				
			||||||
 | 
								// Delete any pods controlled by this replicaiton controller.
 | 
				
			||||||
 | 
								cnt.Spec.Replicas = 0
 | 
				
			||||||
 | 
								c.ReplicationControllers(ns).Update(&cnt)
 | 
				
			||||||
 | 
								// Delete the controller
 | 
				
			||||||
 | 
								c.ReplicationControllers(ns).Delete(name)
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Create a replication controller  for a service
 | 
				
			||||||
 | 
						// that serves its hostname on port 8080.
 | 
				
			||||||
 | 
						// The source for the Docker containter kubernetes/serve_hostname is
 | 
				
			||||||
 | 
						// in contrib/for-demos/serve_hostname
 | 
				
			||||||
 | 
						controller, err := c.ReplicationControllers(ns).Create(&api.ReplicationController{
 | 
				
			||||||
 | 
							ObjectMeta: api.ObjectMeta{
 | 
				
			||||||
 | 
								Name: name,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							Spec: api.ReplicationControllerSpec{
 | 
				
			||||||
 | 
								Replicas: replicas,
 | 
				
			||||||
 | 
								Selector: map[string]string{
 | 
				
			||||||
 | 
									"name": name,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								Template: &api.PodTemplateSpec{
 | 
				
			||||||
 | 
									ObjectMeta: api.ObjectMeta{
 | 
				
			||||||
 | 
										Labels: map[string]string{"name": name},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									Spec: api.PodSpec{
 | 
				
			||||||
 | 
										Containers: []api.Container{
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												Name:  name,
 | 
				
			||||||
 | 
												Image: "kubernetes/serve_hostname",
 | 
				
			||||||
 | 
												Ports: []api.Port{{ContainerPort: 9376, HostPort: 8080}},
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Infof("Failed to create replication controller for %s: %v", name, err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// List the pods.
 | 
				
			||||||
 | 
						// pods, err := c.Pods(ns).List(labels.Set{"name": name}.AsSelector())
 | 
				
			||||||
 | 
						pods, err := c.Pods(ns).List(labels.SelectorFromSet(labels.Set(map[string]string{"name": name})))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to list pods before wait for running check: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for i, pod := range pods.Items {
 | 
				
			||||||
 | 
							glog.Infof("Replica %d: %s\n", i+1, pod.Name)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Wait for the pods to enter the running state. Waiting loops until the pods
 | 
				
			||||||
 | 
						// are running so non-running pods cause a timeout for this test.
 | 
				
			||||||
 | 
						for _, pod := range pods.Items {
 | 
				
			||||||
 | 
							waitForPodRunning(c, pod.Name)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// List the pods again to get the host IP information.
 | 
				
			||||||
 | 
						pods, err = c.Pods(ns).List(labels.SelectorFromSet(labels.Set(map[string]string{"name": name})))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to list pods after wait for running check: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Verify that something is listening.
 | 
				
			||||||
 | 
						for i, pod := range pods.Items {
 | 
				
			||||||
 | 
							glog.Infof("Pod %s hostIP %s", pod.Name, pod.Status.HostIP)
 | 
				
			||||||
 | 
							resp, err := http.Get(fmt.Sprintf("http://%s:8080", pod.Status.HostIP))
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								glog.Errorf("Failed to GET from replica %d: %v", i+1, err)
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							defer resp.Body.Close()
 | 
				
			||||||
 | 
							if resp.StatusCode != http.StatusOK {
 | 
				
			||||||
 | 
								glog.Errorf("Expected OK status code for replica %d but got %d", i+1, resp.StatusCode)
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							body, err := ioutil.ReadAll(resp.Body)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								glog.Errorf("Failed to read the body of the GET response from replica %d: %v", i+1, err)
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// The body should be the pod name although we may need to skip a newline
 | 
				
			||||||
 | 
							// character at the end of the response.
 | 
				
			||||||
 | 
							if !strings.HasPrefix(string(body), pod.Name) {
 | 
				
			||||||
 | 
								glog.Errorf("From replica %d expected response %s but got %s", i+1, pod.Name, string(body))
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							glog.Infof("Got expected result from replica %d: %s", i+1, string(body))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Resize the replication controller to zero to get rid of pods.
 | 
				
			||||||
 | 
						controller.Spec.Replicas = 0
 | 
				
			||||||
 | 
						if _, err = c.ReplicationControllers(ns).Update(controller); err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to resize replication controllert to zero: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Delete the replication controller.
 | 
				
			||||||
 | 
						if err = c.ReplicationControllers(ns).Delete(name); err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to delete replication controller %s: %v", name, err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										146
									
								
								test/e2e/cluster_dns.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								test/e2e/cluster_dns.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,146 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package e2e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
				
			||||||
 | 
						"github.com/golang/glog"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TestClusterDNS checks that cluster DNS works.
 | 
				
			||||||
 | 
					func TestClusterDNS(c *client.Client) bool {
 | 
				
			||||||
 | 
						// TODO:
 | 
				
			||||||
 | 
						// https://github.com/GoogleCloudPlatform/kubernetes/issues/3305
 | 
				
			||||||
 | 
						// (but even if it's fixed, this will need a version check for
 | 
				
			||||||
 | 
						// skewed version tests)
 | 
				
			||||||
 | 
						if os.Getenv("KUBERNETES_PROVIDER") == "gke" {
 | 
				
			||||||
 | 
							glog.Infof("skipping TestClusterDNS on gke")
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						podClient := c.Pods(api.NamespaceDefault)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//TODO: Wait for skyDNS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// All the names we need to be able to resolve.
 | 
				
			||||||
 | 
						namesToResolve := []string{
 | 
				
			||||||
 | 
							"kubernetes-ro",
 | 
				
			||||||
 | 
							"kubernetes-ro.default",
 | 
				
			||||||
 | 
							"kubernetes-ro.default.kubernetes.local",
 | 
				
			||||||
 | 
							"google.com",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						probeCmd := "for i in `seq 1 600`; do "
 | 
				
			||||||
 | 
						for _, name := range namesToResolve {
 | 
				
			||||||
 | 
							probeCmd += fmt.Sprintf("wget -O /dev/null %s && echo OK > /results/%s;", name, name)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						probeCmd += "sleep 1; done"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Run a pod which probes DNS and exposes the results by HTTP.
 | 
				
			||||||
 | 
						pod := &api.Pod{
 | 
				
			||||||
 | 
							TypeMeta: api.TypeMeta{
 | 
				
			||||||
 | 
								Kind:       "Pod",
 | 
				
			||||||
 | 
								APIVersion: "v1beta1",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							ObjectMeta: api.ObjectMeta{
 | 
				
			||||||
 | 
								Name: "dns-test",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							Spec: api.PodSpec{
 | 
				
			||||||
 | 
								Volumes: []api.Volume{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name: "results",
 | 
				
			||||||
 | 
										Source: &api.VolumeSource{
 | 
				
			||||||
 | 
											EmptyDir: &api.EmptyDir{},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								Containers: []api.Container{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:  "webserver",
 | 
				
			||||||
 | 
										Image: "kubernetes/test-webserver",
 | 
				
			||||||
 | 
										VolumeMounts: []api.VolumeMount{
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												Name:      "results",
 | 
				
			||||||
 | 
												MountPath: "/results",
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:    "pinger",
 | 
				
			||||||
 | 
										Image:   "busybox",
 | 
				
			||||||
 | 
										Command: []string{"sh", "-c", probeCmd},
 | 
				
			||||||
 | 
										VolumeMounts: []api.VolumeMount{
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												Name:      "results",
 | 
				
			||||||
 | 
												MountPath: "/results",
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, err := podClient.Create(pod)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to create dns-test pod: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer podClient.Delete(pod.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						waitForPodRunning(c, pod.Name)
 | 
				
			||||||
 | 
						pod, err = podClient.Get(pod.Name)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to get pod: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Try to find results for each expected name.
 | 
				
			||||||
 | 
						var failed []string
 | 
				
			||||||
 | 
						for try := 1; try < 100; try++ {
 | 
				
			||||||
 | 
							failed = []string{}
 | 
				
			||||||
 | 
							for _, name := range namesToResolve {
 | 
				
			||||||
 | 
								_, err := c.Get().
 | 
				
			||||||
 | 
									Prefix("proxy").
 | 
				
			||||||
 | 
									Resource("pods").
 | 
				
			||||||
 | 
									Namespace("default").
 | 
				
			||||||
 | 
									Name(pod.Name).
 | 
				
			||||||
 | 
									Suffix("results", name).
 | 
				
			||||||
 | 
									Do().Raw()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									failed = append(failed, name)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if len(failed) == 0 {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							glog.Infof("lookups failed for: %v", failed)
 | 
				
			||||||
 | 
							time.Sleep(3 * time.Second)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(failed) != 0 {
 | 
				
			||||||
 | 
							glog.Errorf("DNS failed for: %v", failed)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO: probe from the host, too.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						glog.Info("DNS probes succeeded")
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										101
									
								
								test/e2e/driver.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								test/e2e/driver.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,101 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package e2e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
 | 
				
			||||||
 | 
						"github.com/golang/glog"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type testSpec struct {
 | 
				
			||||||
 | 
						// The test to run
 | 
				
			||||||
 | 
						test func(c *client.Client) bool
 | 
				
			||||||
 | 
						// The human readable name of this test
 | 
				
			||||||
 | 
						name string
 | 
				
			||||||
 | 
						// The id for this test.  It should be constant for the life of the test.
 | 
				
			||||||
 | 
						id int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type testInfo struct {
 | 
				
			||||||
 | 
						passed bool
 | 
				
			||||||
 | 
						spec   testSpec
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Output a summary in the TAP (test anything protocol) format for automated processing.
 | 
				
			||||||
 | 
					// See http://testanything.org/ for more info
 | 
				
			||||||
 | 
					func outputTAPSummary(infoList []testInfo) {
 | 
				
			||||||
 | 
						glog.Infof("1..%d", len(infoList))
 | 
				
			||||||
 | 
						for _, info := range infoList {
 | 
				
			||||||
 | 
							if info.passed {
 | 
				
			||||||
 | 
								glog.Infof("ok %d - %s", info.spec.id, info.spec.name)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								glog.Infof("not ok %d - %s", info.spec.id, info.spec.name)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func RunE2ETests(authConfig, certDir, host, repoRoot string) {
 | 
				
			||||||
 | 
						testContext = testContextType{authConfig, certDir, host, repoRoot}
 | 
				
			||||||
 | 
						util.ReallyCrash = true
 | 
				
			||||||
 | 
						util.InitLogs()
 | 
				
			||||||
 | 
						defer util.FlushLogs()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						go func() {
 | 
				
			||||||
 | 
							defer util.FlushLogs()
 | 
				
			||||||
 | 
							time.Sleep(5 * time.Minute)
 | 
				
			||||||
 | 
							glog.Fatalf("This test has timed out. Cleanup not guaranteed.")
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						c := loadClientOrDie()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Define the tests.  Important: for a clean test grid, please keep ids for a test constant.
 | 
				
			||||||
 | 
						tests := []testSpec{
 | 
				
			||||||
 | 
							{TestKubernetesROService, "TestKubernetesROService", 1},
 | 
				
			||||||
 | 
							{TestKubeletSendsEvent, "TestKubeletSendsEvent", 2},
 | 
				
			||||||
 | 
							{TestImportantURLs, "TestImportantURLs", 3},
 | 
				
			||||||
 | 
							{TestPodUpdate, "TestPodUpdate", 4},
 | 
				
			||||||
 | 
							{TestNetwork, "TestNetwork", 5},
 | 
				
			||||||
 | 
							{TestClusterDNS, "TestClusterDNS", 6},
 | 
				
			||||||
 | 
							{TestPodHasServiceEnvVars, "TestPodHasServiceEnvVars", 7},
 | 
				
			||||||
 | 
							{TestBasic, "TestBasic", 8},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						info := []testInfo{}
 | 
				
			||||||
 | 
						passed := true
 | 
				
			||||||
 | 
						for i, test := range tests {
 | 
				
			||||||
 | 
							glog.Infof("Running test %d %s", i+1, test.name)
 | 
				
			||||||
 | 
							testPassed := test.test(c)
 | 
				
			||||||
 | 
							if !testPassed {
 | 
				
			||||||
 | 
								glog.Infof("        test %d failed", i+1)
 | 
				
			||||||
 | 
								passed = false
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								glog.Infof("        test %d passed", i+1)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// TODO: clean up objects created during a test after the test, so cases
 | 
				
			||||||
 | 
							// are independent.
 | 
				
			||||||
 | 
							info = append(info, testInfo{testPassed, test})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						outputTAPSummary(info)
 | 
				
			||||||
 | 
						if !passed {
 | 
				
			||||||
 | 
							glog.Fatalf("At least one test failed")
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							glog.Infof("All tests pass")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										48
									
								
								test/e2e/important_urls.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								test/e2e/important_urls.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package e2e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
				
			||||||
 | 
						"github.com/golang/glog"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TestImportantURLs validates that URLs that people depend on haven't moved.
 | 
				
			||||||
 | 
					// ***IMPORTANT*** Do *not* fix this test just by changing the path.  If you moved a URL
 | 
				
			||||||
 | 
					// you can break upstream dependencies.
 | 
				
			||||||
 | 
					func TestImportantURLs(c *client.Client) bool {
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							path string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{path: "/validate"},
 | 
				
			||||||
 | 
							{path: "/healthz"},
 | 
				
			||||||
 | 
							// TODO: test proxy links here
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ok := true
 | 
				
			||||||
 | 
						for _, test := range tests {
 | 
				
			||||||
 | 
							glog.Infof("testing: %s", test.path)
 | 
				
			||||||
 | 
							data, err := c.RESTClient.Get().
 | 
				
			||||||
 | 
								AbsPath(test.path).
 | 
				
			||||||
 | 
								Do().
 | 
				
			||||||
 | 
								Raw()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								glog.Errorf("Failed: %v\nBody: %s", err, string(data))
 | 
				
			||||||
 | 
								ok = false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ok
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										107
									
								
								test/e2e/kubelet_sends_events.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								test/e2e/kubelet_sends_events.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package e2e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
 | 
				
			||||||
 | 
						"github.com/golang/glog"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TestKubeletSendsEvent checks that kubelets and scheduler send events about pods scheduling and running.
 | 
				
			||||||
 | 
					func TestKubeletSendsEvent(c *client.Client) bool {
 | 
				
			||||||
 | 
						provider := os.Getenv("KUBERNETES_PROVIDER")
 | 
				
			||||||
 | 
						if len(provider) > 0 && provider != "gce" && provider != "gke" {
 | 
				
			||||||
 | 
							glog.Infof("skipping TestKubeletSendsEvent on cloud provider %s", provider)
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if provider == "" {
 | 
				
			||||||
 | 
							glog.Info("KUBERNETES_PROVIDER is unset; assuming \"gce\"")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						podClient := c.Pods(api.NamespaceDefault)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pod := loadPodOrDie(assetPath("test", "e2e", "pod.json"))
 | 
				
			||||||
 | 
						value := strconv.Itoa(time.Now().Nanosecond())
 | 
				
			||||||
 | 
						pod.Labels["time"] = value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err := podClient.Create(pod)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to create pod: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer podClient.Delete(pod.Name)
 | 
				
			||||||
 | 
						waitForPodRunning(c, pod.Name)
 | 
				
			||||||
 | 
						pods, err := podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value})))
 | 
				
			||||||
 | 
						if len(pods.Items) != 1 {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to find the correct pod")
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						podWithUid, err := podClient.Get(pod.Name)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to get pod: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check for scheduler event about the pod.
 | 
				
			||||||
 | 
						glog.Infof("%+v", podWithUid)
 | 
				
			||||||
 | 
						events, err := c.Events(api.NamespaceDefault).List(
 | 
				
			||||||
 | 
							labels.Everything(),
 | 
				
			||||||
 | 
							labels.Set{
 | 
				
			||||||
 | 
								"involvedObject.kind":      "Pod",
 | 
				
			||||||
 | 
								"involvedObject.uid":       string(podWithUid.UID),
 | 
				
			||||||
 | 
								"involvedObject.namespace": api.NamespaceDefault,
 | 
				
			||||||
 | 
								"source":                   "scheduler",
 | 
				
			||||||
 | 
							}.AsSelector(),
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Error("Error while listing events:", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(events.Items) == 0 {
 | 
				
			||||||
 | 
							glog.Error("Didn't see any scheduler events even though pod was running.")
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						glog.Info("Saw scheduler event for our pod.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check for kubelet event about the pod.
 | 
				
			||||||
 | 
						events, err = c.Events(api.NamespaceDefault).List(
 | 
				
			||||||
 | 
							labels.Everything(),
 | 
				
			||||||
 | 
							labels.Set{
 | 
				
			||||||
 | 
								"involvedObject.uid":       string(podWithUid.UID),
 | 
				
			||||||
 | 
								"involvedObject.kind":      "BoundPod",
 | 
				
			||||||
 | 
								"involvedObject.namespace": api.NamespaceDefault,
 | 
				
			||||||
 | 
								"source":                   "kubelet",
 | 
				
			||||||
 | 
							}.AsSelector(),
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Error("Error while listing events:", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(events.Items) == 0 {
 | 
				
			||||||
 | 
							glog.Error("Didn't see any kubelet events even though pod was running.")
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						glog.Info("Saw kubelet event for our pod.")
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										93
									
								
								test/e2e/network.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								test/e2e/network.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,93 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package e2e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
				
			||||||
 | 
						"github.com/golang/glog"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestNetwork(c *client.Client) bool {
 | 
				
			||||||
 | 
						ns := api.NamespaceDefault
 | 
				
			||||||
 | 
						svc, err := c.Services(ns).Create(loadObjectOrDie(assetPath(
 | 
				
			||||||
 | 
							"contrib", "for-tests", "network-tester", "service.json",
 | 
				
			||||||
 | 
						)).(*api.Service))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("unable to create test service: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Clean up service
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
 | 
							if err = c.Services(ns).Delete(svc.Name); err != nil {
 | 
				
			||||||
 | 
								glog.Errorf("unable to delete svc %v: %v", svc.Name, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rc, err := c.ReplicationControllers(ns).Create(loadObjectOrDie(assetPath(
 | 
				
			||||||
 | 
							"contrib", "for-tests", "network-tester", "rc.json",
 | 
				
			||||||
 | 
						)).(*api.ReplicationController))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("unable to create test rc: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Clean up rc
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
 | 
							rc.Spec.Replicas = 0
 | 
				
			||||||
 | 
							rc, err = c.ReplicationControllers(ns).Update(rc)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								glog.Errorf("unable to modify replica count for rc %v: %v", rc.Name, err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if err = c.ReplicationControllers(ns).Delete(rc.Name); err != nil {
 | 
				
			||||||
 | 
								glog.Errorf("unable to delete rc %v: %v", rc.Name, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
						const maxAttempts = 60
 | 
				
			||||||
 | 
						for i := 0; i < maxAttempts; i++ {
 | 
				
			||||||
 | 
							time.Sleep(time.Second)
 | 
				
			||||||
 | 
							body, err := c.Get().Prefix("proxy").Resource("services").Name(svc.Name).Suffix("status").Do().Raw()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								glog.Infof("Attempt %v/%v: service/pod still starting. (error: '%v')", i, maxAttempts, err)
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							switch string(body) {
 | 
				
			||||||
 | 
							case "pass":
 | 
				
			||||||
 | 
								glog.Infof("Passed on attempt %v. Cleaning up.", i)
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							case "running":
 | 
				
			||||||
 | 
								glog.Infof("Attempt %v/%v: test still running", i, maxAttempts)
 | 
				
			||||||
 | 
							case "fail":
 | 
				
			||||||
 | 
								if body, err := c.Get().Prefix("proxy").Resource("services").Name(svc.Name).Suffix("read").Do().Raw(); err != nil {
 | 
				
			||||||
 | 
									glog.Infof("Failed on attempt %v. Cleaning up. Error reading details: %v", i, err)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									glog.Infof("Failed on attempt %v. Cleaning up. Details:\n%v", i, string(body))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if body, err := c.Get().Prefix("proxy").Resource("services").Name(svc.Name).Suffix("read").Do().Raw(); err != nil {
 | 
				
			||||||
 | 
							glog.Infof("Timed out. Cleaning up. Error reading details: %v", err)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							glog.Infof("Timed out. Cleaning up. Details:\n%v", string(body))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										161
									
								
								test/e2e/pod_has_service_env_vars.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								test/e2e/pod_has_service_env_vars.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,161 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package e2e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
				
			||||||
 | 
						"github.com/golang/glog"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TestPodHasServiceEnvVars checks that kubelets and scheduler send events about pods scheduling and running.
 | 
				
			||||||
 | 
					func TestPodHasServiceEnvVars(c *client.Client) bool {
 | 
				
			||||||
 | 
						// Make a pod that will be a service.
 | 
				
			||||||
 | 
						// This pod serves its hostname via HTTP.
 | 
				
			||||||
 | 
						serverPod := parsePodOrDie(`{
 | 
				
			||||||
 | 
						  "kind": "Pod",
 | 
				
			||||||
 | 
						  "apiVersion": "v1beta1",
 | 
				
			||||||
 | 
						  "id": "srv",
 | 
				
			||||||
 | 
						  "desiredState": {
 | 
				
			||||||
 | 
							"manifest": {
 | 
				
			||||||
 | 
							  "version": "v1beta1",
 | 
				
			||||||
 | 
							  "id": "srv",
 | 
				
			||||||
 | 
							  "containers": [{
 | 
				
			||||||
 | 
								"name": "srv",
 | 
				
			||||||
 | 
								"image": "kubernetes/serve_hostname",
 | 
				
			||||||
 | 
								"ports": [{
 | 
				
			||||||
 | 
								  "containerPort": 9376,
 | 
				
			||||||
 | 
								  "hostPort": 8080
 | 
				
			||||||
 | 
								}]
 | 
				
			||||||
 | 
							  }]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						  },
 | 
				
			||||||
 | 
						  "labels": {
 | 
				
			||||||
 | 
							"name": "srv"
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
						}`)
 | 
				
			||||||
 | 
						_, err := c.Pods(api.NamespaceDefault).Create(serverPod)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to create serverPod: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer c.Pods(api.NamespaceDefault).Delete(serverPod.Name)
 | 
				
			||||||
 | 
						waitForPodRunning(c, serverPod.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// This service exposes pod p's port 8080 as a service on port 8765
 | 
				
			||||||
 | 
						svc := parseServiceOrDie(`{
 | 
				
			||||||
 | 
						  "id": "fooservice",
 | 
				
			||||||
 | 
						  "kind": "Service",
 | 
				
			||||||
 | 
						  "apiVersion": "v1beta1",
 | 
				
			||||||
 | 
						  "port": 8765,
 | 
				
			||||||
 | 
						  "containerPort": 8080,
 | 
				
			||||||
 | 
						  "selector": {
 | 
				
			||||||
 | 
							"name": "p"
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
						}`)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to delete service: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						time.Sleep(2)
 | 
				
			||||||
 | 
						_, err = c.Services(api.NamespaceDefault).Create(svc)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to create service: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer c.Services(api.NamespaceDefault).Delete(svc.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO: we don't have a way to wait for a service to be "running".
 | 
				
			||||||
 | 
						// If this proves flaky, then we will need to retry the clientPod or insert a sleep.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Make a client pod that verifies that it has the service environment variables.
 | 
				
			||||||
 | 
						clientPod := parsePodOrDie(`{
 | 
				
			||||||
 | 
						  "apiVersion": "v1beta1",
 | 
				
			||||||
 | 
						  "kind": "Pod",
 | 
				
			||||||
 | 
						  "id": "env3",
 | 
				
			||||||
 | 
						  "desiredState": {
 | 
				
			||||||
 | 
							"manifest": {
 | 
				
			||||||
 | 
							  "version": "v1beta1",
 | 
				
			||||||
 | 
							  "id": "env3",
 | 
				
			||||||
 | 
							  "restartPolicy": { "never": {} },
 | 
				
			||||||
 | 
							  "containers": [{
 | 
				
			||||||
 | 
								"name": "env3cont",
 | 
				
			||||||
 | 
								"image": "busybox",
 | 
				
			||||||
 | 
								"command": ["sh", "-c", "env"]
 | 
				
			||||||
 | 
							  }]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						  },
 | 
				
			||||||
 | 
						  "labels": { "name": "env3" }
 | 
				
			||||||
 | 
						}`)
 | 
				
			||||||
 | 
						_, err = c.Pods(api.NamespaceDefault).Create(clientPod)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to create pod: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer c.Pods(api.NamespaceDefault).Delete(clientPod.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Wait for client pod to complete.
 | 
				
			||||||
 | 
						success := waitForPodSuccess(c, clientPod.Name, clientPod.Spec.Containers[0].Name)
 | 
				
			||||||
 | 
						if !success {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to run client pod to detect service env vars.")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Grab its logs.  Get host first.
 | 
				
			||||||
 | 
						clientPodStatus, err := c.Pods(api.NamespaceDefault).Get(clientPod.Name)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to get clientPod to know host: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						glog.Infof("Trying to get logs from host %s pod %s container %s: %v",
 | 
				
			||||||
 | 
							clientPodStatus.Status.Host, clientPodStatus.Name, clientPodStatus.Spec.Containers[0].Name, err)
 | 
				
			||||||
 | 
						logs, err := c.Get().
 | 
				
			||||||
 | 
							Prefix("proxy").
 | 
				
			||||||
 | 
							Resource("minions").
 | 
				
			||||||
 | 
							Name(clientPodStatus.Status.Host).
 | 
				
			||||||
 | 
							Suffix("containerLogs", api.NamespaceDefault, clientPodStatus.Name, clientPodStatus.Spec.Containers[0].Name).
 | 
				
			||||||
 | 
							Do().
 | 
				
			||||||
 | 
							Raw()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to get logs from host %s pod %s container %s: %v",
 | 
				
			||||||
 | 
								clientPodStatus.Status.Host, clientPodStatus.Name, clientPodStatus.Spec.Containers[0].Name, err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						glog.Info("clientPod logs:", string(logs))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						toFind := []string{
 | 
				
			||||||
 | 
							"FOOSERVICE_SERVICE_HOST=",
 | 
				
			||||||
 | 
							"FOOSERVICE_SERVICE_PORT=",
 | 
				
			||||||
 | 
							"FOOSERVICE_PORT=",
 | 
				
			||||||
 | 
							"FOOSERVICE_PORT_8765_TCP_PORT=",
 | 
				
			||||||
 | 
							"FOOSERVICE_PORT_8765_TCP_PROTO=",
 | 
				
			||||||
 | 
							"FOOSERVICE_PORT_8765_TCP=",
 | 
				
			||||||
 | 
							"FOOSERVICE_PORT_8765_TCP_ADDR=",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, m := range toFind {
 | 
				
			||||||
 | 
							if !strings.Contains(string(logs), m) {
 | 
				
			||||||
 | 
								glog.Errorf("Unable to find env var %q in client env vars.", m)
 | 
				
			||||||
 | 
								success = false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// We could try a wget the service from the client pod.  But services.sh e2e test covers that pretty well.
 | 
				
			||||||
 | 
						return success
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										71
									
								
								test/e2e/pod_update.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								test/e2e/pod_update.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package e2e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
 | 
				
			||||||
 | 
						"github.com/golang/glog"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestPodUpdate(c *client.Client) bool {
 | 
				
			||||||
 | 
						podClient := c.Pods(api.NamespaceDefault)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pod := loadPodOrDie(assetPath("api", "examples", "pod.json"))
 | 
				
			||||||
 | 
						value := strconv.Itoa(time.Now().Nanosecond())
 | 
				
			||||||
 | 
						pod.Labels["time"] = value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err := podClient.Create(pod)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to create pod: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer podClient.Delete(pod.Name)
 | 
				
			||||||
 | 
						waitForPodRunning(c, pod.Name)
 | 
				
			||||||
 | 
						pods, err := podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value})))
 | 
				
			||||||
 | 
						if len(pods.Items) != 1 {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to find the correct pod")
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						podOut, err := podClient.Get(pod.Name)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to get pod: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						value = "time" + value
 | 
				
			||||||
 | 
						pod.Labels["time"] = value
 | 
				
			||||||
 | 
						pod.ResourceVersion = podOut.ResourceVersion
 | 
				
			||||||
 | 
						pod.UID = podOut.UID
 | 
				
			||||||
 | 
						pod, err = podClient.Update(pod)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to update pod: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						waitForPodRunning(c, pod.Name)
 | 
				
			||||||
 | 
						pods, err = podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value})))
 | 
				
			||||||
 | 
						if len(pods.Items) != 1 {
 | 
				
			||||||
 | 
							glog.Errorf("Failed to find the correct pod after update.")
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						glog.Infof("pod update OK")
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										55
									
								
								test/e2e/roservice.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								test/e2e/roservice.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package e2e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
				
			||||||
 | 
						"github.com/golang/glog"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestKubernetesROService(c *client.Client) bool {
 | 
				
			||||||
 | 
						svc := api.ServiceList{}
 | 
				
			||||||
 | 
						err := c.Get().
 | 
				
			||||||
 | 
							Namespace("default").
 | 
				
			||||||
 | 
							AbsPath("/api/v1beta1/proxy/services/kubernetes-ro/api/v1beta1/services").
 | 
				
			||||||
 | 
							Do().
 | 
				
			||||||
 | 
							Into(&svc)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Errorf("unexpected error listing services using ro service: %v", err)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var foundRW, foundRO bool
 | 
				
			||||||
 | 
						for i := range svc.Items {
 | 
				
			||||||
 | 
							if svc.Items[i].Name == "kubernetes" {
 | 
				
			||||||
 | 
								foundRW = true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if svc.Items[i].Name == "kubernetes-ro" {
 | 
				
			||||||
 | 
								foundRO = true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if !foundRW {
 | 
				
			||||||
 | 
							glog.Error("no RW service found")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if !foundRO {
 | 
				
			||||||
 | 
							glog.Error("no RO service found")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if !foundRW || !foundRO {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										163
									
								
								test/e2e/util.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								test/e2e/util.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,163 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 Google Inc. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					limitations under the License.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package e2e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"io/ioutil"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
 | 
				
			||||||
 | 
						"github.com/golang/glog"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type testContextType struct {
 | 
				
			||||||
 | 
						authConfig string
 | 
				
			||||||
 | 
						certDir    string
 | 
				
			||||||
 | 
						host       string
 | 
				
			||||||
 | 
						repoRoot   string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var testContext testContextType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func waitForPodRunning(c *client.Client, id string) {
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							time.Sleep(5 * time.Second)
 | 
				
			||||||
 | 
							pod, err := c.Pods(api.NamespaceDefault).Get(id)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								glog.Warningf("Get pod %s failed: %v", id, err)
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if pod.Status.Phase == api.PodRunning {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							glog.Infof("Waiting for pod %s status to be %q (found %q)", id, api.PodRunning, pod.Status.Phase)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// waitForPodSuccess returns true if the pod reached state success, or false if it reached failure or ran too long.
 | 
				
			||||||
 | 
					func waitForPodSuccess(c *client.Client, podName string, contName string) bool {
 | 
				
			||||||
 | 
						for i := 0; i < 10; i++ {
 | 
				
			||||||
 | 
							if i > 0 {
 | 
				
			||||||
 | 
								time.Sleep(5 * time.Second)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							pod, err := c.Pods(api.NamespaceDefault).Get(podName)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								glog.Warningf("Get pod failed: %v", err)
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// Cannot use pod.Status.Phase == api.PodSucceeded/api.PodFailed due to #2632
 | 
				
			||||||
 | 
							ci, ok := pod.Status.Info[contName]
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								glog.Infof("No Status.Info for container %s in pod %s yet", contName, podName)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								if ci.State.Termination != nil {
 | 
				
			||||||
 | 
									if ci.State.Termination.ExitCode == 0 {
 | 
				
			||||||
 | 
										glog.Infof("Saw pod success")
 | 
				
			||||||
 | 
										return true
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										glog.Infof("Saw pod failure: %+v", ci.State.Termination)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									glog.Infof("Waiting for pod %q status to be success or failure", podName)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									glog.Infof("Nil State.Termination for container %s in pod %s so far", contName, podName)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						glog.Warningf("Gave up waiting for pod %q status to be success or failure", podName)
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// assetPath returns a path to the requested file; safe on all
 | 
				
			||||||
 | 
					// OSes. NOTE: If you use an asset in this test, you MUST add it to
 | 
				
			||||||
 | 
					// the KUBE_TEST_PORTABLE array in hack/lib/golang.sh.
 | 
				
			||||||
 | 
					func assetPath(pathElements ...string) string {
 | 
				
			||||||
 | 
						return filepath.Join(testContext.repoRoot, filepath.Join(pathElements...))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func loadObjectOrDie(filePath string) runtime.Object {
 | 
				
			||||||
 | 
						data, err := ioutil.ReadFile(filePath)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Fatalf("Failed to read object: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return decodeObjectOrDie(data)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func decodeObjectOrDie(data []byte) runtime.Object {
 | 
				
			||||||
 | 
						obj, err := latest.Codec.Decode(data)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Fatalf("Failed to decode object: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return obj
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func loadPodOrDie(filePath string) *api.Pod {
 | 
				
			||||||
 | 
						obj := loadObjectOrDie(filePath)
 | 
				
			||||||
 | 
						pod, ok := obj.(*api.Pod)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							glog.Fatalf("Failed to load pod: %v", obj)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return pod
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func loadClientOrDie() *client.Client {
 | 
				
			||||||
 | 
						config := client.Config{
 | 
				
			||||||
 | 
							Host: testContext.host,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						info, err := clientauth.LoadFromFile(testContext.authConfig)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Fatalf("Error loading auth: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// If the certificate directory is provided, set the cert paths to be there.
 | 
				
			||||||
 | 
						if testContext.certDir != "" {
 | 
				
			||||||
 | 
							glog.Infof("Expecting certs in %v.", testContext.certDir)
 | 
				
			||||||
 | 
							info.CAFile = filepath.Join(testContext.certDir, "ca.crt")
 | 
				
			||||||
 | 
							info.CertFile = filepath.Join(testContext.certDir, "kubecfg.crt")
 | 
				
			||||||
 | 
							info.KeyFile = filepath.Join(testContext.certDir, "kubecfg.key")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						config, err = info.MergeWithConfig(config)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Fatalf("Error creating client")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						c, err := client.New(&config)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							glog.Fatalf("Error creating client")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return c
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parsePodOrDie(json string) *api.Pod {
 | 
				
			||||||
 | 
						obj := decodeObjectOrDie([]byte(json))
 | 
				
			||||||
 | 
						pod, ok := obj.(*api.Pod)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							glog.Fatalf("Failed to cast pod: %v", obj)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return pod
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseServiceOrDie(json string) *api.Service {
 | 
				
			||||||
 | 
						obj := decodeObjectOrDie([]byte(json))
 | 
				
			||||||
 | 
						service, ok := obj.(*api.Service)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							glog.Fatalf("Failed to cast service: %v", obj)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return service
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user