From e40e82bd5c724675c26ca03a631171ecf6305cac Mon Sep 17 00:00:00 2001 From: Random-Liu Date: Thu, 7 Jul 2016 22:56:46 -0700 Subject: [PATCH] Make it possible to share test between e2e and node e2e, and make container probing test shared to validate. --- hack/verify-flags/known-flags.txt | 1 - test/e2e/{ => common}/container_probe.go | 42 +++++----------- test/e2e/common/util.go | 26 ++++++++++ test/e2e/downwardapi_volume.go | 4 +- test/e2e/e2e.go | 4 ++ test/e2e/framework/framework.go | 32 +++++++----- test/e2e/framework/pods.go | 60 +++++++++++++---------- test/e2e/framework/test_context.go | 2 +- test/e2e/kubelet_etc_hosts.go | 22 +-------- test/e2e/pods.go | 6 +-- test/e2e_node/cgroup_manager_test.go | 13 ++--- test/e2e_node/configmap.go | 11 +++-- test/e2e_node/container.go | 14 +++--- test/e2e_node/container_manager_test.go | 14 ++++-- test/e2e_node/downward_api_test.go | 5 +- test/e2e_node/e2e_node_suite_test.go | 4 ++ test/e2e_node/kubelet_test.go | 20 +++++--- test/e2e_node/mirror_pod_test.go | 2 +- test/e2e_node/privileged_test.go | 4 +- test/e2e_node/runtime_conformance_test.go | 8 +-- test/e2e_node/util.go | 16 ------ 21 files changed, 156 insertions(+), 154 deletions(-) rename test/e2e/{ => common}/container_probe.go (81%) create mode 100644 test/e2e/common/util.go diff --git a/hack/verify-flags/known-flags.txt b/hack/verify-flags/known-flags.txt index b2aa5e2920..c36bf14160 100644 --- a/hack/verify-flags/known-flags.txt +++ b/hack/verify-flags/known-flags.txt @@ -11,7 +11,6 @@ allow-privileged api-burst api-prefix api-rate -api-server-address api-server-port api-servers api-token diff --git a/test/e2e/container_probe.go b/test/e2e/common/container_probe.go similarity index 81% rename from test/e2e/container_probe.go rename to test/e2e/common/container_probe.go index 4e63962406..6cb945f45f 100644 --- a/test/e2e/container_probe.go +++ b/test/e2e/common/container_probe.go @@ -14,17 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -package e2e +package common import ( "fmt" "time" "k8s.io/kubernetes/pkg/api" - client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/intstr" - "k8s.io/kubernetes/pkg/util/wait" "k8s.io/kubernetes/test/e2e/framework" . "github.com/onsi/ginkgo" @@ -33,36 +31,23 @@ import ( const ( probTestContainerName = "test-webserver" - probTestInitialDelaySeconds = 30 + probTestInitialDelaySeconds = 15 ) var _ = framework.KubeDescribe("Probing container", func() { f := framework.NewDefaultFramework("container-probe") - var podClient client.PodInterface + var podClient *framework.PodClient probe := webserverProbeBuilder{} BeforeEach(func() { - podClient = f.Client.Pods(f.Namespace.Name) + podClient = f.PodClient() }) It("with readiness probe should not be ready before initial delay and never restart [Conformance]", func() { - p, err := podClient.Create(makePodSpec(probe.withInitialDelay().build(), nil)) - framework.ExpectNoError(err) + p := podClient.Create(makePodSpec(probe.withInitialDelay().build(), nil)) + f.WaitForPodReady(p.Name) - Expect(wait.Poll(framework.Poll, 240*time.Second, func() (bool, error) { - p, err := podClient.Get(p.Name) - if err != nil { - return false, err - } - ready := api.IsPodReady(p) - if !ready { - framework.Logf("pod is not yet ready; pod has phase %q.", p.Status.Phase) - return false, nil - } - return true, nil - })).NotTo(HaveOccurred(), "pod never became ready") - - p, err = podClient.Get(p.Name) + p, err := podClient.Get(p.Name) framework.ExpectNoError(err) isReady, err := framework.PodRunningReady(p) framework.ExpectNoError(err) @@ -86,21 +71,16 @@ var _ = framework.KubeDescribe("Probing container", func() { }) It("with readiness probe that fails should never be ready and never restart [Conformance]", func() { - p, err := podClient.Create(makePodSpec(probe.withFailing().build(), nil)) - framework.ExpectNoError(err) - - err = wait.Poll(framework.Poll, 180*time.Second, func() (bool, error) { + p := podClient.Create(makePodSpec(probe.withFailing().build(), nil)) + Consistently(func() (bool, error) { p, err := podClient.Get(p.Name) if err != nil { return false, err } return api.IsPodReady(p), nil - }) - if err != wait.ErrWaitTimeout { - framework.Failf("expecting wait timeout error but got: %v", err) - } + }, 1*time.Minute, 1*time.Second).ShouldNot(BeTrue(), "pod should not be ready") - p, err = podClient.Get(p.Name) + p, err := podClient.Get(p.Name) framework.ExpectNoError(err) isReady, err := framework.PodRunningReady(p) diff --git a/test/e2e/common/util.go b/test/e2e/common/util.go new file mode 100644 index 0000000000..67824d0661 --- /dev/null +++ b/test/e2e/common/util.go @@ -0,0 +1,26 @@ +/* +Copyright 2016 The Kubernetes Authors. + +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 common + +type Suite string + +const ( + E2E Suite = "e2e" + NodeE2E Suite = "node e2e" +) + +var CurrentSuite Suite diff --git a/test/e2e/downwardapi_volume.go b/test/e2e/downwardapi_volume.go index 76d898e7db..d37760c68d 100644 --- a/test/e2e/downwardapi_volume.go +++ b/test/e2e/downwardapi_volume.go @@ -81,7 +81,7 @@ var _ = framework.KubeDescribe("Downward API volume", func() { podLogTimeout, framework.Poll).Should(ContainSubstring("key1=\"value1\"\n")) //modify labels - f.UpdatePod(podName, func(pod *api.Pod) { + f.PodClient().Update(podName, func(pod *api.Pod) { pod.Labels["key3"] = "value3" }) @@ -116,7 +116,7 @@ var _ = framework.KubeDescribe("Downward API volume", func() { podLogTimeout, framework.Poll).Should(ContainSubstring("builder=\"bar\"\n")) //modify annotations - f.UpdatePod(podName, func(pod *api.Pod) { + f.PodClient().Update(podName, func(pod *api.Pod) { pod.Annotations["builder"] = "foo" }) diff --git a/test/e2e/e2e.go b/test/e2e/e2e.go index e0039cbb7f..67bf0c13d1 100644 --- a/test/e2e/e2e.go +++ b/test/e2e/e2e.go @@ -36,6 +36,7 @@ import ( gcecloud "k8s.io/kubernetes/pkg/cloudprovider/providers/gce" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util/runtime" + commontest "k8s.io/kubernetes/test/e2e/common" "k8s.io/kubernetes/test/e2e/framework" ) @@ -146,6 +147,9 @@ var _ = ginkgo.SynchronizedBeforeSuite(func() []byte { framework.LogContainersInPodsWithLabels(c, api.NamespaceSystem, framework.ImagePullerLabels, "nethealth") } + // Reference common test to make the import valid. + commontest.CurrentSuite = commontest.E2E + return nil }, func(data []byte) { diff --git a/test/e2e/framework/framework.go b/test/e2e/framework/framework.go index a7649e7c77..4c36e00a2b 100644 --- a/test/e2e/framework/framework.go +++ b/test/e2e/framework/framework.go @@ -32,6 +32,7 @@ import ( apierrs "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_2" "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_3" + "k8s.io/kubernetes/pkg/client/restclient" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" @@ -53,10 +54,9 @@ const ( type Framework struct { BaseName string - ClientConfigGetter ClientConfigGetter - Client *client.Client - Clientset_1_2 *release_1_2.Clientset - Clientset_1_3 *release_1_3.Clientset + Client *client.Client + Clientset_1_2 *release_1_2.Clientset + Clientset_1_3 *release_1_3.Clientset // TODO(mml): Remove this. We should generally use the versioned clientset. FederationClientset *federation_internalclientset.Clientset @@ -117,16 +117,11 @@ func NewDefaultFederatedFramework(baseName string) *Framework { } func NewFramework(baseName string, options FrameworkOptions, client *client.Client) *Framework { - return NewFrameworkWithConfigGetter(baseName, options, client, LoadConfig) -} - -func NewFrameworkWithConfigGetter(baseName string, options FrameworkOptions, client *client.Client, configGetter ClientConfigGetter) *Framework { f := &Framework{ BaseName: baseName, AddonResourceConstraints: make(map[string]ResourceConstraint), options: options, Client: client, - ClientConfigGetter: configGetter, } BeforeEach(f.BeforeEach) @@ -142,10 +137,21 @@ func (f *Framework) BeforeEach() { f.cleanupHandle = AddCleanupAction(f.AfterEach) if f.Client == nil { By("Creating a kubernetes client") - config, err := f.ClientConfigGetter() - Expect(err).NotTo(HaveOccurred()) - config.QPS = f.options.ClientQPS - config.Burst = f.options.ClientBurst + var config *restclient.Config + if TestContext.NodeName != "" { + // This is a node e2e test, apply the node e2e configuration + config = &restclient.Config{ + Host: TestContext.Host, + QPS: 100, + Burst: 100, + } + } else { + var err error + config, err = LoadConfig() + Expect(err).NotTo(HaveOccurred()) + config.QPS = f.options.ClientQPS + config.Burst = f.options.ClientBurst + } if TestContext.KubeAPIContentType != "" { config.ContentType = TestContext.KubeAPIContentType } diff --git a/test/e2e/framework/pods.go b/test/e2e/framework/pods.go index 5296689e66..6235243ede 100644 --- a/test/e2e/framework/pods.go +++ b/test/e2e/framework/pods.go @@ -29,43 +29,46 @@ import ( . "github.com/onsi/gomega" ) -// TODO: Consolidate pod-specific framework functions here. - // Convenience method for getting a pod client interface in the framework's namespace. -func (f *Framework) PodClient() unversioned.PodInterface { - return f.Client.Pods(f.Namespace.Name) +func (f *Framework) PodClient() *PodClient { + return &PodClient{ + f: f, + PodInterface: f.Client.Pods(f.Namespace.Name), + } } -// Create a new pod according to the framework specifications, and wait for it to start. -// Returns the server's representation of the pod. -func (f *Framework) CreatePod(pod *api.Pod) *api.Pod { - p := f.CreatePodAsync(pod) - ExpectNoError(f.WaitForPodRunning(p.Name)) - return p +type PodClient struct { + f *Framework + unversioned.PodInterface } -// Create a new pod according to the framework specifications (don't wait for it to start). -// Returns the server's representation of the pod. -func (f *Framework) CreatePodAsync(pod *api.Pod) *api.Pod { - f.MungePodSpec(pod) - p, err := f.PodClient().Create(pod) +// Create creates a new pod according to the framework specifications (don't wait for it to start). +func (c *PodClient) Create(pod *api.Pod) *api.Pod { + c.MungeSpec(pod) + p, err := c.PodInterface.Create(pod) ExpectNoError(err, "Error creating Pod") return p } -// Batch version of CreatePod. All pods are created before waiting. -// Returns a slice, in the same order as pods, containing the server's representations of the pods. -func (f *Framework) CreatePods(pods []*api.Pod) []*api.Pod { +// CreateSync creates a new pod according to the framework specifications, and wait for it to start. +func (c *PodClient) CreateSync(pod *api.Pod) *api.Pod { + p := c.Create(pod) + ExpectNoError(c.f.WaitForPodRunning(p.Name)) + return p +} + +// CreateBatch create a batch of pods. All pods are created before waiting. +func (c *PodClient) CreateBatch(pods []*api.Pod) []*api.Pod { ps := make([]*api.Pod, len(pods)) for i, pod := range pods { - ps[i] = f.CreatePodAsync(pod) + ps[i] = c.Create(pod) } var wg sync.WaitGroup for _, pod := range ps { wg.Add(1) podName := pod.Name go func() { - ExpectNoError(f.WaitForPodRunning(podName)) + ExpectNoError(c.f.WaitForPodRunning(podName)) wg.Done() }() } @@ -73,26 +76,27 @@ func (f *Framework) CreatePods(pods []*api.Pod) []*api.Pod { return ps } -// Apply test-suite specific transformations to the pod spec. -// TODO: figure out a nicer, more generic way to tie this to framework instances. -func (f *Framework) MungePodSpec(pod *api.Pod) { +// MungeSpec apply test-suite specific transformations to the pod spec. +// TODO: Refactor the framework to always use PodClient so that we can completely hide the munge logic +// in the PodClient. +func (c *PodClient) MungeSpec(pod *api.Pod) { if TestContext.NodeName != "" { Expect(pod.Spec.NodeName).To(Or(BeZero(), Equal(TestContext.NodeName)), "Test misconfigured") pod.Spec.NodeName = TestContext.NodeName } } -// UpdatePod updates the pod object. It retries if there is a conflict, throw out error if +// Update updates the pod object. It retries if there is a conflict, throw out error if // there is any other errors. name is the pod name, updateFn is the function updating the // pod object. -func (f *Framework) UpdatePod(name string, updateFn func(pod *api.Pod)) { +func (c *PodClient) Update(name string, updateFn func(pod *api.Pod)) { ExpectNoError(wait.Poll(time.Millisecond*500, time.Second*30, func() (bool, error) { - pod, err := f.PodClient().Get(name) + pod, err := c.PodInterface.Get(name) if err != nil { return false, fmt.Errorf("failed to get pod %q: %v", name, err) } updateFn(pod) - _, err = f.PodClient().Update(pod) + _, err = c.PodInterface.Update(pod) if err == nil { Logf("Successfully updated pod %q", name) return true, nil @@ -104,3 +108,5 @@ func (f *Framework) UpdatePod(name string, updateFn func(pod *api.Pod)) { return false, fmt.Errorf("failed to update pod %q: %v", name, err) })) } + +// TODO(random-liu): Move pod wait function into this file diff --git a/test/e2e/framework/test_context.go b/test/e2e/framework/test_context.go index 957fbe909b..0d41631671 100644 --- a/test/e2e/framework/test_context.go +++ b/test/e2e/framework/test_context.go @@ -104,6 +104,7 @@ func RegisterCommonFlags() { flag.BoolVar(&TestContext.GatherMetricsAfterTest, "gather-metrics-at-teardown", false, "If set to true framwork will gather metrics from all components after each test.") flag.StringVar(&TestContext.OutputPrintType, "output-print-type", "hr", "Comma separated list: 'hr' for human readable summaries 'json' for JSON ones.") flag.BoolVar(&TestContext.DumpLogsOnFailure, "dump-logs-on-failure", true, "If set to true test will dump data about the namespace in which test was running.") + flag.StringVar(&TestContext.Host, "host", "http://127.0.0.1:8080", "The host, or apiserver, to connect to") } // Register flags specific to the cluster e2e test suite. @@ -119,7 +120,6 @@ func RegisterClusterFlags() { flag.StringVar(&TestContext.KubeVolumeDir, "volume-dir", "/var/lib/kubelet", "Path to the directory containing the kubelet volumes.") flag.StringVar(&TestContext.CertDir, "cert-dir", "", "Path to the directory containing the certs. Default is empty, which doesn't use certs.") - flag.StringVar(&TestContext.Host, "host", "", "The host, or apiserver, to connect to") flag.StringVar(&TestContext.RepoRoot, "repo-root", "../../", "Root directory of kubernetes repository, for finding test files.") flag.StringVar(&TestContext.Provider, "provider", "", "The name of the Kubernetes provider (gce, gke, local, vagrant, etc.)") flag.StringVar(&TestContext.KubectlPath, "kubectl-path", "kubectl", "The kubectl binary to use. For development, you might use 'cluster/kubectl.sh' here.") diff --git a/test/e2e/kubelet_etc_hosts.go b/test/e2e/kubelet_etc_hosts.go index cd4e32da5c..b511bb0efd 100644 --- a/test/e2e/kubelet_etc_hosts.go +++ b/test/e2e/kubelet_etc_hosts.go @@ -24,7 +24,6 @@ import ( api "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/apimachinery/registered" - client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/test/e2e/framework" ) @@ -84,29 +83,12 @@ func (config *KubeletManagedHostConfig) setup() { func (config *KubeletManagedHostConfig) createPodWithoutHostNetwork() { podSpec := config.createPodSpec(kubeletEtcHostsPodName) - config.pod = config.createPod(podSpec) + config.pod = config.f.PodClient().CreateSync(podSpec) } func (config *KubeletManagedHostConfig) createPodWithHostNetwork() { podSpec := config.createPodSpecWithHostNetwork(kubeletEtcHostsHostNetworkPodName) - config.hostNetworkPod = config.createPod(podSpec) -} - -func (config *KubeletManagedHostConfig) createPod(podSpec *api.Pod) *api.Pod { - createdPod, err := config.getPodClient().Create(podSpec) - if err != nil { - framework.Failf("Failed to create %s pod: %v", podSpec.Name, err) - } - framework.ExpectNoError(config.f.WaitForPodRunning(podSpec.Name)) - createdPod, err = config.getPodClient().Get(podSpec.Name) - if err != nil { - framework.Failf("Failed to retrieve %s pod: %v", podSpec.Name, err) - } - return createdPod -} - -func (config *KubeletManagedHostConfig) getPodClient() client.PodInterface { - return config.f.Client.Pods(config.f.Namespace.Name) + config.hostNetworkPod = config.f.PodClient().CreateSync(podSpec) } func assertEtcHostsIsKubeletManaged(etcHostsContent string) { diff --git a/test/e2e/pods.go b/test/e2e/pods.go index e627fa7a53..392c462fd8 100644 --- a/test/e2e/pods.go +++ b/test/e2e/pods.go @@ -462,7 +462,7 @@ var _ = framework.KubeDescribe("Pods", func() { Expect(len(pods.Items)).To(Equal(1)) By("updating the pod") - f.UpdatePod(name, func(pod *api.Pod) { + f.PodClient().Update(name, func(pod *api.Pod) { value = strconv.Itoa(time.Now().Nanosecond()) pod.Labels["time"] = value }) @@ -530,7 +530,7 @@ var _ = framework.KubeDescribe("Pods", func() { Expect(len(pods.Items)).To(Equal(1)) By("updating the pod") - f.UpdatePod(name, func(pod *api.Pod) { + f.PodClient().Update(name, func(pod *api.Pod) { newDeadline := int64(5) pod.Spec.ActiveDeadlineSeconds = &newDeadline }) @@ -1309,7 +1309,7 @@ var _ = framework.KubeDescribe("Pods", func() { delay1, delay2 := startPodAndGetBackOffs(f, pod, podName, containerName, buildBackOffDuration) By("updating the image") - f.UpdatePod(podName, func(pod *api.Pod) { + f.PodClient().Update(podName, func(pod *api.Pod) { pod.Spec.Containers[0].Image = "gcr.io/google_containers/nginx-slim:0.7" }) diff --git a/test/e2e_node/cgroup_manager_test.go b/test/e2e_node/cgroup_manager_test.go index e0b7f840ed..125f94d617 100644 --- a/test/e2e_node/cgroup_manager_test.go +++ b/test/e2e_node/cgroup_manager_test.go @@ -26,7 +26,7 @@ import ( ) var _ = framework.KubeDescribe("Kubelet Cgroup Manager", func() { - f := NewDefaultFramework("kubelet-cgroup-manager") + f := framework.NewDefaultFramework("kubelet-cgroup-manager") Describe("QOS containers", func() { Context("On enabling QOS cgroup hierarchy", func() { It("Top level QoS containers should have been created", func() { @@ -35,8 +35,7 @@ var _ = framework.KubeDescribe("Kubelet Cgroup Manager", func() { contName := "qos-container" + string(util.NewUUID()) pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ - Name: podName, - Namespace: f.Namespace.Name, + Name: podName, }, Spec: api.PodSpec{ // Don't restart the Pod since it is expected to exit @@ -64,11 +63,9 @@ var _ = framework.KubeDescribe("Kubelet Cgroup Manager", func() { }, }, } - f.MungePodSpec(pod) - podClient := f.Client.Pods(f.Namespace.Name) - _, err := podClient.Create(pod) - Expect(err).NotTo(HaveOccurred()) - err = framework.WaitForPodSuccessInNamespace(f.Client, podName, contName, f.Namespace.Name) + podClient := f.PodClient() + podClient.Create(pod) + err := framework.WaitForPodSuccessInNamespace(f.Client, podName, contName, f.Namespace.Name) Expect(err).NotTo(HaveOccurred()) } }) diff --git a/test/e2e_node/configmap.go b/test/e2e_node/configmap.go index 1107b1648f..0e497f7e6a 100644 --- a/test/e2e_node/configmap.go +++ b/test/e2e_node/configmap.go @@ -30,7 +30,7 @@ import ( var _ = framework.KubeDescribe("ConfigMap", func() { - f := NewDefaultFramework("configmap") + f := framework.NewDefaultFramework("configmap") It("should be consumable from pods in volumpe [Conformance]", func() { doConfigMapE2EWithoutMappings(f, 0, 0) @@ -122,7 +122,7 @@ var _ = framework.KubeDescribe("ConfigMap", func() { } By("Creating the pod") - f.CreatePod(pod) + f.PodClient().CreateSync(pod) pollLogs := func() (string, error) { return framework.GetPodLogs(f.Client, f.Namespace.Name, pod.Name, containerName) @@ -179,7 +179,8 @@ var _ = framework.KubeDescribe("ConfigMap", func() { }, } - f.MungePodSpec(pod) + // TODO(random-liu): Change TestContainerOutput to use PodClient and avoid MungeSpec explicitly + f.PodClient().MungeSpec(pod) framework.TestContainerOutput("consume configMaps", f.Client, pod, 0, []string{ "CONFIG_DATA_1=value-1", @@ -260,7 +261,7 @@ func doConfigMapE2EWithoutMappings(f *framework.Framework, uid, fsGroup int64) { pod.Spec.SecurityContext.FSGroup = &fsGroup } - f.MungePodSpec(pod) + f.PodClient().MungeSpec(pod) framework.TestContainerOutput("consume configMaps", f.Client, pod, 0, []string{ "content of file \"/etc/configmap-volume/data-1\": value-1", @@ -333,7 +334,7 @@ func doConfigMapE2EWithMappings(f *framework.Framework, uid, fsGroup int64) { pod.Spec.SecurityContext.FSGroup = &fsGroup } - f.MungePodSpec(pod) + f.PodClient().MungeSpec(pod) framework.TestContainerOutput("consume configMaps", f.Client, pod, 0, []string{ "content of file \"/etc/configmap-volume/path/to/data-2\": value-2", diff --git a/test/e2e_node/container.go b/test/e2e_node/container.go index fa151f92a7..4fd638a6e5 100644 --- a/test/e2e_node/container.go +++ b/test/e2e_node/container.go @@ -28,12 +28,12 @@ import ( // One pod one container // TODO: This should be migrated to the e2e framework. type ConformanceContainer struct { - Framework *framework.Framework Container api.Container RestartPolicy api.RestartPolicy Volumes []api.Volume ImagePullSecrets []string + PodClient *framework.PodClient podName string PodSecurityContext *api.PodSecurityContext } @@ -58,15 +58,15 @@ func (cc *ConformanceContainer) Create() { ImagePullSecrets: imagePullSecrets, }, } - cc.Framework.CreatePodAsync(pod) + cc.PodClient.Create(pod) } func (cc *ConformanceContainer) Delete() error { - return cc.Framework.PodClient().Delete(cc.podName, api.NewDeleteOptions(0)) + return cc.PodClient.Delete(cc.podName, api.NewDeleteOptions(0)) } func (cc *ConformanceContainer) IsReady() (bool, error) { - pod, err := cc.Framework.PodClient().Get(cc.podName) + pod, err := cc.PodClient.Get(cc.podName) if err != nil { return false, err } @@ -74,7 +74,7 @@ func (cc *ConformanceContainer) IsReady() (bool, error) { } func (cc *ConformanceContainer) GetPhase() (api.PodPhase, error) { - pod, err := cc.Framework.PodClient().Get(cc.podName) + pod, err := cc.PodClient.Get(cc.podName) if err != nil { return api.PodUnknown, err } @@ -82,7 +82,7 @@ func (cc *ConformanceContainer) GetPhase() (api.PodPhase, error) { } func (cc *ConformanceContainer) GetStatus() (api.ContainerStatus, error) { - pod, err := cc.Framework.PodClient().Get(cc.podName) + pod, err := cc.PodClient.Get(cc.podName) if err != nil { return api.ContainerStatus{}, err } @@ -94,7 +94,7 @@ func (cc *ConformanceContainer) GetStatus() (api.ContainerStatus, error) { } func (cc *ConformanceContainer) Present() (bool, error) { - _, err := cc.Framework.PodClient().Get(cc.podName) + _, err := cc.PodClient.Get(cc.podName) if err == nil { return true, nil } diff --git a/test/e2e_node/container_manager_test.go b/test/e2e_node/container_manager_test.go index 029687e479..c5bafb080c 100644 --- a/test/e2e_node/container_manager_test.go +++ b/test/e2e_node/container_manager_test.go @@ -29,14 +29,20 @@ import ( ) var _ = framework.KubeDescribe("Kubelet Container Manager", func() { - f := NewDefaultFramework("kubelet-container-manager") + f := framework.NewDefaultFramework("kubelet-container-manager") + var podClient *framework.PodClient + + BeforeEach(func() { + podClient = f.PodClient() + }) + Describe("oom score adjusting", func() { Context("when scheduling a busybox command that always fails in a pod", func() { var podName string BeforeEach(func() { podName = "bin-false" + string(util.NewUUID()) - f.CreatePodAsync(&api.Pod{ + podClient.Create(&api.Pod{ ObjectMeta: api.ObjectMeta{ Name: podName, }, @@ -56,7 +62,7 @@ var _ = framework.KubeDescribe("Kubelet Container Manager", func() { It("should have an error terminated reason", func() { Eventually(func() error { - podData, err := f.PodClient().Get(podName) + podData, err := podClient.Get(podName) if err != nil { return err } @@ -75,7 +81,7 @@ var _ = framework.KubeDescribe("Kubelet Container Manager", func() { }) It("should be possible to delete", func() { - err := f.PodClient().Delete(podName, &api.DeleteOptions{}) + err := podClient.Delete(podName, &api.DeleteOptions{}) Expect(err).To(BeNil(), fmt.Sprintf("Error deleting Pod %v", err)) }) }) diff --git a/test/e2e_node/downward_api_test.go b/test/e2e_node/downward_api_test.go index a348c6beb0..41ffcf35d4 100644 --- a/test/e2e_node/downward_api_test.go +++ b/test/e2e_node/downward_api_test.go @@ -30,7 +30,7 @@ import ( // Ported from test/e2e/downard_api_test.go var _ = framework.KubeDescribe("Downward API", func() { - f := NewDefaultFramework("downward-api") + f := framework.NewDefaultFramework("downward-api") It("should provide pod name and namespace as env vars [Conformance]", func() { podName := "downward-api-" + string(util.NewUUID()) env := []api.EnvVar{ @@ -158,7 +158,8 @@ func testDownwardAPI(f *framework.Framework, podName string, env []api.EnvVar, e RestartPolicy: api.RestartPolicyNever, }, } - f.MungePodSpec(pod) + // TODO(random-liu): Change TestContainerOutputRegexp to use PodClient and avoid MungeSpec explicitly + f.PodClient().MungeSpec(pod) f.TestContainerOutputRegexp("downward api env vars", pod, 0, expectations) } diff --git a/test/e2e_node/e2e_node_suite_test.go b/test/e2e_node/e2e_node_suite_test.go index 635b57576c..1181fc84da 100644 --- a/test/e2e_node/e2e_node_suite_test.go +++ b/test/e2e_node/e2e_node_suite_test.go @@ -31,6 +31,7 @@ import ( "testing" "time" + commontest "k8s.io/kubernetes/test/e2e/common" "k8s.io/kubernetes/test/e2e/framework" "github.com/golang/glog" @@ -104,6 +105,9 @@ var _ = BeforeSuite(func() { } else { glog.Infof("Running tests without starting services.") } + + // Reference common test to make the import valid. + commontest.CurrentSuite = commontest.NodeE2E }) // Tear down the kubelet on the node diff --git a/test/e2e_node/kubelet_test.go b/test/e2e_node/kubelet_test.go index c98c51d630..df65f1004a 100644 --- a/test/e2e_node/kubelet_test.go +++ b/test/e2e_node/kubelet_test.go @@ -38,11 +38,15 @@ import ( ) var _ = framework.KubeDescribe("Kubelet", func() { - f := NewDefaultFramework("kubelet-test") + f := framework.NewDefaultFramework("kubelet-test") + var podClient *framework.PodClient + BeforeEach(func() { + podClient = f.PodClient() + }) Context("when scheduling a busybox command in a pod", func() { podName := "busybox-scheduling-" + string(util.NewUUID()) It("it should print the output to logs", func() { - f.CreatePod(&api.Pod{ + podClient.CreateSync(&api.Pod{ ObjectMeta: api.ObjectMeta{ Name: podName, }, @@ -60,7 +64,7 @@ var _ = framework.KubeDescribe("Kubelet", func() { }) Eventually(func() string { sinceTime := apiUnversioned.NewTime(time.Now().Add(time.Duration(-1 * time.Hour))) - rc, err := f.PodClient().GetLogs(podName, &api.PodLogOptions{SinceTime: &sinceTime}).Stream() + rc, err := podClient.GetLogs(podName, &api.PodLogOptions{SinceTime: &sinceTime}).Stream() if err != nil { return "" } @@ -76,7 +80,7 @@ var _ = framework.KubeDescribe("Kubelet", func() { podName := "busybox-readonly-fs" + string(util.NewUUID()) It("it should not write to root filesystem", func() { isReadOnly := true - f.CreatePod(&api.Pod{ + podClient.CreateSync(&api.Pod{ ObjectMeta: api.ObjectMeta{ Name: podName, }, @@ -96,7 +100,7 @@ var _ = framework.KubeDescribe("Kubelet", func() { }, }) Eventually(func() string { - rc, err := f.PodClient().GetLogs(podName, &api.PodLogOptions{}).Stream() + rc, err := podClient.GetLogs(podName, &api.PodLogOptions{}).Stream() if err != nil { return "" } @@ -112,7 +116,7 @@ var _ = framework.KubeDescribe("Kubelet", func() { It("it should report resource usage through the stats api", func() { podNamePrefix := "stats-busybox-" + string(util.NewUUID()) volumeNamePrefix := "test-empty-dir" - podNames, volumes := createSummaryTestPods(f, podNamePrefix, 2, volumeNamePrefix) + podNames, volumes := createSummaryTestPods(f.PodClient(), podNamePrefix, 2, volumeNamePrefix) By("Returning stats summary") summary := stats.Summary{} Eventually(func() error { @@ -152,7 +156,7 @@ const ( containerSuffix = "-c" ) -func createSummaryTestPods(f *framework.Framework, podNamePrefix string, count int, volumeNamePrefix string) (sets.String, sets.String) { +func createSummaryTestPods(podClient *framework.PodClient, podNamePrefix string, count int, volumeNamePrefix string) (sets.String, sets.String) { podNames := sets.NewString() volumes := sets.NewString(volumeNamePrefix) for i := 0; i < count; i++ { @@ -191,7 +195,7 @@ func createSummaryTestPods(f *framework.Framework, podNamePrefix string, count i }, }) } - f.CreatePods(pods) + podClient.CreateBatch(pods) return podNames, volumes } diff --git a/test/e2e_node/mirror_pod_test.go b/test/e2e_node/mirror_pod_test.go index ed3fc4797a..23a3240069 100644 --- a/test/e2e_node/mirror_pod_test.go +++ b/test/e2e_node/mirror_pod_test.go @@ -35,7 +35,7 @@ import ( ) var _ = framework.KubeDescribe("MirrorPod", func() { - f := NewDefaultFramework("mirror-pod") + f := framework.NewDefaultFramework("mirror-pod") Context("when create a mirror pod ", func() { var staticPodName, mirrorPodName string BeforeEach(func() { diff --git a/test/e2e_node/privileged_test.go b/test/e2e_node/privileged_test.go index 08939804c2..7ea8cf1e74 100644 --- a/test/e2e_node/privileged_test.go +++ b/test/e2e_node/privileged_test.go @@ -54,11 +54,13 @@ type PrivilegedPodTestConfig struct { privilegedPod *api.Pod } +// TODO(random-liu): Change the test to use framework and framework pod client. var _ = Describe("PrivilegedPod", func() { var c *client.Client - restClientConfig := &restclient.Config{Host: *apiServerAddress} + var restClientConfig *restclient.Config BeforeEach(func() { // Setup the apiserver client + restClientConfig = &restclient.Config{Host: framework.TestContext.Host} c = client.NewOrDie(restClientConfig) }) It("should test privileged pod", func() { diff --git a/test/e2e_node/runtime_conformance_test.go b/test/e2e_node/runtime_conformance_test.go index ec6b3565ac..26f33a3962 100644 --- a/test/e2e_node/runtime_conformance_test.go +++ b/test/e2e_node/runtime_conformance_test.go @@ -37,7 +37,7 @@ const ( ) var _ = framework.KubeDescribe("Container Runtime Conformance Test", func() { - f := NewDefaultFramework("runtime-conformance") + f := framework.NewDefaultFramework("runtime-conformance") Describe("container runtime conformance blackbox test", func() { Context("when starting a container that exits", func() { @@ -91,7 +91,7 @@ while true; do sleep 1; done testContainer.Name = testCase.Name testContainer.Command = []string{"sh", "-c", tmpCmd} terminateContainer := ConformanceContainer{ - Framework: f, + PodClient: f.PodClient(), Container: testContainer, RestartPolicy: testCase.RestartPolicy, Volumes: testVolumes, @@ -134,7 +134,7 @@ while true; do sleep 1; done terminationMessagePath := "/dev/termination-log" priv := true c := ConformanceContainer{ - Framework: f, + PodClient: f.PodClient(), Container: api.Container{ Image: ImageRegistry[busyBoxImage], Name: name, @@ -235,7 +235,7 @@ while true; do sleep 1; done name := "image-pull-test" command := []string{"/bin/sh", "-c", "while true; do sleep 1; done"} container := ConformanceContainer{ - Framework: f, + PodClient: f.PodClient(), Container: api.Container{ Name: name, Image: testCase.image, diff --git a/test/e2e_node/util.go b/test/e2e_node/util.go index acf07e8219..d09eea6770 100644 --- a/test/e2e_node/util.go +++ b/test/e2e_node/util.go @@ -18,27 +18,11 @@ package e2e_node import ( "flag" - - "k8s.io/kubernetes/pkg/client/restclient" - "k8s.io/kubernetes/test/e2e/framework" ) var kubeletAddress = flag.String("kubelet-address", "http://127.0.0.1:10255", "Host and port of the kubelet") -var apiServerAddress = flag.String("api-server-address", "http://127.0.0.1:8080", "Host and port of the api server") var disableKubenet = flag.Bool("disable-kubenet", false, "If true, start kubelet without kubenet") var buildServices = flag.Bool("build-services", true, "If true, build local executables") var startServices = flag.Bool("start-services", true, "If true, start local node services") var stopServices = flag.Bool("stop-services", true, "If true, stop local node services after running tests") - -func NewDefaultFramework(baseName string) *framework.Framework { - // Provides a client config for the framework to create a client. - f := func() (*restclient.Config, error) { - return &restclient.Config{Host: *apiServerAddress}, nil - } - return framework.NewFrameworkWithConfigGetter(baseName, - framework.FrameworkOptions{ - ClientQPS: 100, - ClientBurst: 100, - }, nil, f) -}